为什么对mapped type做索引操作能够保留类型窄化效果?
映射类型索引窄化技巧的生效原理
你写的NarrowDataPayload本质是生成了可辨识联合类型(Discriminated Union),TS正是基于可辨识联合的特性实现了key和fn参数类型的绑定匹配,具体推导过程分两步:
第一步:映射类型生成键值绑定的中间对象
当你传入的T是示例中的MyData时,首先执行映射类型逻辑:
{ [K in keyof T]: { key: K; fn: (data: T[K]) => void; } }
这一步会遍历T的所有键,为每个键K生成专属的对象类型,最终得到的中间类型是:
{ a: { key: "a", fn: (data: { alpha: string }) => void }, b: { key: "b", fn: (data: { beta: number }) => void } }
第二步:索引访问生成可辨识联合
后面拼接的[keyof T]是对上述中间对象执行索引访问,作用是取出对象所有属性值的类型做联合,最终得到的NarrowDataPayload<MyData>等价于:
| { key: "a", fn: (data: { alpha: string }) => void } | { key: "b", fn: (data: { beta: number }) => void }
这个联合类型的每个分支都有字面量类型的共同属性key,key就是这个联合的辨识符。
类型窄化的触发逻辑
当你调用acceptsMTVTFunction2时传入的参数是{ key: "a", fn: (data) => {} },TS的控制流分析会识别到key的字面量值是"a",直接命中联合类型中key: "a"的分支,自然就能推导出fn的参数类型是对应的{ alpha: string },实现了key和对应值类型的绑定。
对比你写的NotNarrowPayload,它的key和fn是两个独立的联合类型,没有绑定关系,所以TS无法通过key的值窄化fn的参数类型。
内容的提问来源于stack exchange,提问作者dwjohnston
相关产品推荐
相关产品推荐

