Open
Description
Acknowledgement
- I acknowledge that issues using this template may be closed without further explanation at the maintainer's discretion.
Comment
Consider this homomorphic mapped type:
type DeepReadonly<T> = { readonly [P in keyof T]: DeepReadonly<T[P]> };
Now, consider its instantiation with a recursive type:
type StringNode = string | { node: StringNode };
type T1 = DeepReadonly<StringNode>;
// ^? type T1 = string | DeepReadonly<{ node: StringNode; }>
const t1: T1 = { node: { node: 'A' } };
Everything works fine. Playground: https://tsplay.dev/wRDrQm.
However, if the type is instantiated with an array, I start getting "Type instantiation is excessively deep and possibly infinite" error.
type StringNode = string | StringNode[];
type T1 = DeepReadonly<StringNode>;
// errors
Updating the implementation to this makes the error go away, but this doesn't work with tuples.
type DeepReadonly<T> =
T extends ReadonlyArray<infer V>
? ReadonlyArray<DeepReadonly<V>>
: { readonly [P in keyof T]: DeepReadonly<T[P]> };
type StringNode = string | StringNode[];
type T1 = DeepReadonly<StringNode>;
const t1: T1 = [['foo']];
type StringNodeTuple = string | [StringNodeTuple];
type T2 = DeepReadonly<StringNode>;
const t2: T2 = [['foo', 'bar']]; // doesn't error
If the mapped type works with objects it should have worked with arrays as well. Is there something that I am missing?