Microsoft/TypeScript

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

已关闭

#61,868 创建于 2025年6月14日

 (10 条评论) (0 个反应) (0 位负责人)TypeScript (13,395 个派生)batch import
Domain: Mapped TypesHelp WantedPossible Improvement

仓库指标

星标
 (108,860 个星标)
PR 合并指标
 (平均合并 6天 17小时) (30 天内合并 9 个 PR)

描述

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?

贡献者指南