Closed
Description
I'm playing around with conditional types and observing the behavior I don't quite understand.
Playground link (ts.version: 2.8.0-insiders.20180320
).
// building on top of
// https://gist.github.com/utatti/c411d0939094ba490ce6dd78c92ffe4c
type Nat = 0 | { succ: Nat };
type Succ<T extends Nat> = { succ: T };
type Add<X extends Nat, Y extends Nat> =
X extends Succ<infer R> ? { succ: Add<R, Y> } : Y;
type N0 = 0;
type N1 = Succ<N0>;
type N2 = Succ<N1>;
type N3 = Succ<N2>;
type N4 = Succ<N3>;
type N5 = Succ<N4>;
type N6 = Succ<N5>;
type N7 = Succ<N6>;
type N8 = Succ<N7>;
type N9 = Succ<N8>;
type ToType<K> =
K extends 0 ? N0 :
K extends 1 ? N1 :
K extends 2 ? N2 :
K extends 3 ? N3 :
K extends 4 ? N4 :
K extends 5 ? N5 :
K extends 6 ? N6 :
K extends 7 ? N7 :
K extends 8 ? N8 :
K extends 9 ? N9 : never;
type ToNumber<N> =
N extends N0 ? 0 :
N extends N1 ? 1 :
N extends N2 ? 2 :
N extends N3 ? 3 :
N extends N4 ? 4 :
N extends N5 ? 5 :
N extends N6 ? 6 :
N extends N7 ? 7 :
N extends N8 ? 8 :
N extends N9 ? 9 : never;
declare function add<
XK extends number,
YK extends number,
>(x: XK, y: YK): ToNumber<Add<ToType<XK>, ToType<YK>>>;
// try commenting out this block, next block will show error
{
const res: 6 = add(2, 4)
}
{
const res: 8 = add(1, 7)
}
It seems that there is a recursion limit for infer
keyword. However if the type expression was already calculated, it goes in the cache.
Is this expected behavior?