funtion(a: string | number) {
double(a) // return type is string | number
}
// here is how it distributes over union
(string | number) extends string ? string : number
-> (string extends string ? string : number) |
(number extends string ? string : number) |
-> string | number
However, there is an issue in this case:
type Comparable<T> =
T extends Date ? Date | number :
T extends number ? number :
T extends string ? string : never;
declare function isLessThan<T>(a: T, b: Comparable<T>): boolean;
let dateOrStr = Math.random() < 0.5 ? new Date() : 'A'; // ^? let dateOrStr: Date | string
isLessThan(dateOrStr, 'B') // ok, but should be an error
// The type [A] is assignable to [B] if and only if A is assignable to B. This does not change the semantics of Comparable therefore. However, as [T] is a tuple now and not bare T, therefore the rule of distributing over union is not applied.
type Comparable<T> =
[T] extends [Date] ? Date | number :
[T] extends [number] ? number :
[T] extends [string] ? string : never;
Is this true? The statement However, as [T] is a tuple now and not bare T, therefore the rule of distributing over union is not applied.?
Or i misunderstand it?
In this case the T is substituted with Date | string and we get [Date | string] extends [Date] ? .... getting never?