9
type TestAny = any extends 'a' ? 1 : 2 // => 1 | 2  why??? how to understand?
type TestUnknown = unknown extends 'a' ? 1 : 2 // => 2
type TestStringA = 'a' extends 'a' ? 1 : 2 // => 1

type SomeUnion = 'a' | 'b'
type UnionDistribute<T> = T extends 'a' ? 1 : 2
type t0 = UnionDistribute<SomeUnion>  // => 1 | 2  // any work like an union

Why any extends 'a' ? 1: 2 give 1 | 2, this work as a union. I tried to google to find some explanation but failed.

palyground

avocadoLambda
  • 1,332
  • 7
  • 16
  • 33
huanguolin
  • 101
  • 1
  • 2
  • 6

1 Answers1

7

See microsoft/TypeScript#40049 for an authoritative answer to this question, although it doesn't in my opinion shed much light on the underlying reason.

Specifically this comment:

@jack-williams commented on Aug 14, 2020:

This isn't especially well-documented outside of the source-code, but in the checker you'll find in the relevant place:

// Return union of trueType and falseType for 'any' since it matches anything
if (checkType.flags & TypeFlags.Any) {

So any is treated like a wildcard that matches both branches.

Currently you can find the code on line 15239 (GitHub won't let you link to specific lines in files as big as this one), and it was introduced in this commit inside microsoft/TypeScript#21316, the pull request that implemented conditional types in the first place. So it's been this way as long as conditional types have existed.

That's the closest you'll get to "why" this happens. The official answer is "since it matches anything".

jcalz
  • 264,269
  • 27
  • 359
  • 360