为什么TypeScript的DeepReadonly可对string类型生效并映射为readonly?
你对T[P] extends Function的判断逻辑理解完全正确,X['b']是string类型,确实不满足extends Function的条件,会进入DeepReadonly<T[P]>的分支,最终能符合预期的核心原因是TypeScript映射类型对原始类型的内置处理逻辑:
- 首先拆解
X['b']的处理流程:
- 遍历类型X的属性b时,首先会给属性b加上
readonly修饰符,这是readonly [P in keyof T]这部分语法的作用:不管属性值是什么类型,当前层级的属性本身的只读修饰符都会被统一加上。 - 接下来处理属性值的类型:
string extends Function结果为false,所以递归调用DeepReadonly<string>。
- 然后看
DeepReadonly<string>的计算结果:DeepReadonly本质是映射类型,TypeScript的类型系统内置规则规定:映射类型作用于string、number、boolean、symbol这类原始类型时,会直接返回原始类型本身,不会生成新的对象结构,也不会修改原类型的行为。
所以DeepReadonly<string>的计算结果就是string,完全符合预期。
额外补充:
这个实现里单独对Function类型做判断直接返回原类型,主要是为了减少不必要的递归计算,实际上哪怕你去掉Function判断,直接统一写DeepReadonly<T[P]>,函数类型也会和原始类型一样被映射类型透传,最终效果一致。
内容的提问来源于stack exchange,提问作者Tanger9292
相关产品推荐
相关产品推荐

