Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

why `[true, false] extends [false, false]` in typescript, sometimes it's right, and sometime it's not?

Tags:

typescript

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] ??? */
like image 377
Max Avatar asked Nov 04 '25 22:11

Max


1 Answers

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.

like image 163
catgirlkelly Avatar answered Nov 06 '25 16:11

catgirlkelly



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!