Bug Report
π Search Terms
generic types, deferred conditional types
π Version & Regression Information
- This is the behavior in every version I tried, and I reviewed the FAQ for entries about
Common "Bugs" That Aren't Bugs, Generics
β― Playground Link
Playground link with relevant code
or: a much more minimal example of the error, that does not appear in 4.9.4 but does appear in earlier playground versions
π» Code
type Or<A extends boolean, B extends boolean> = [A, B] extends [false, false] ? false : true
type And<A extends boolean, B extends boolean> = [A, B] extends [true, true] ? true : false
type Not<T extends boolean> = T extends true ? false : true
type Extends<A, B> = A extends B ? true : false
type IsStringLiteral<T> = false // type definition omitted and set to `false` (bug still appears)
type IsNumberLiteral<T> =
And<
Extends<T, number>,
Not<Extends<number, T>>
>
// !!!!!!!!!!!
type IsLiteral<T> = Or<IsStringLiteral<T>, IsNumberLiteral<T>>
// ^?type IsLiteral<T> = true
or much more minimal example of error for playground versions <4.9:
type Or<A extends boolean, B extends boolean> = [A, B] extends [false, false] ? false : true
type IsString<T> = T extends string ? true : false
// ?????
type IsString2<T> = Or<IsString<T>, false>
// ^?type IsString2<T> = false
// `Or` existing doesn't seem to be the problem
type IsString3<T> = [IsString<T>, false] extends [false, false] ? false : true
// ^?type IsString3<T> = false
π Actual behavior
The IsLiteral<T> type is always true, which is unexpected. I'd expect it to be computable only when type parameter T is passed in, as the value of T can change which branch of the conditional type to follow. For instance, expanding IsLiteral<T> for a given T, e.g. type IsStringTypeStringLiteral = Or<IsStringLiteral<string>, IsNumberLiteral<string>> gives the expected and "proper" result.
A comment from user xor_01 on the TS discord:
This is just my guess as to what's going on here:
instead of "calculate" actual type of IsNumberLiteral compiler decides for some reason to replace it with boolean and your implementation of Or returns true for boolean
π Expected behavior
IsLiteral<T> shouldn't be replaced with true. Since the type parameter can affect the outcome of the conditional type, TS shouldn't determine the type to always follow some given condition.
Bug Report
π Search Terms
generic types, deferred conditional types
π Version & Regression Information
Common "Bugs" That Aren't Bugs,Genericsβ― Playground Link
Playground link with relevant code
or: a much more minimal example of the error, that does not appear in 4.9.4 but does appear in earlier playground versions
π» Code
or much more minimal example of error for playground versions <4.9:
π Actual behavior
The
IsLiteral<T>type is alwaystrue, which is unexpected. I'd expect it to be computable only when type parameterTis passed in, as the value ofTcan change which branch of the conditional type to follow. For instance, expandingIsLiteral<T>for a givenT, e.g.type IsStringTypeStringLiteral = Or<IsStringLiteral<string>, IsNumberLiteral<string>>gives the expected and "proper" result.A comment from user
xor_01on the TS discord:π Expected behavior
IsLiteral<T>shouldn't be replaced withtrue. Since the type parameter can affect the outcome of the conditional type, TS shouldn't determine the type to always follow some given condition.