Microsoft/TypeScript

Homomorphic mapped types with arrays doesn't work well with recursive arrays

クローズ

#61,868 opened on 2025/06/14

 (10 件のコメント) (0 件のリアクション) (0 人の担当者)TypeScript (13,395 件のフォーク)batch import
Domain: Mapped TypesHelp WantedPossible Improvement

Repository metrics

Stars
 (108,860 個のスター)
PR merge metrics
 (平均マージ 6d 17h) (30d で 9 merged PRs)

説明

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?

コントリビューターガイド