why below code return ["Why?", [true, false]]?
ts playground link
export type StartsWith<S extends string, SearchString extends string> = S extends `${SearchString}${infer T}` ? true : false;
export type IsNegative<N extends number> = StartsWith<`${N}`, '-'>;
export type Sub<A extends number, B extends number> = [IsNegative<A>, IsNegative<B>] extends infer R
? R extends [false, false]
? ['Why?', R]
: 'Expected'
: never;
type T0 = [IsNegative<-15>, IsNegative<90>]; // [true, false]
type T1 = Sub<-15, 90>; // ["Why?", [true, false]] /* Why [true, false] extends [false, false] ??? */
It seems that TypeScript is lazily evaluating IsNegative, or it isn't evaluating it completely...? If we expand IsNegative to its full form:
type Sub<A extends number, B extends number> = [`${A}` extends `${"-"}${infer T}` ? true : false, `${B}` extends `${"-"}${infer T}` ? true : false] extends infer R
Then you will get "Expected".
Also, if you change the definition of IsNegative to this:
type IsNegative<N extends number> = `${N}` extends `-${number}` ? true : false;
it will also work.
So my takeaway is that TypeScript is being lazy, and "summarizes" IsNegative to true | false (basically, boolean), and then when needed, expands and evaluates the type...? At least, that's what I imagine what TypeScript is doing.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With