TypeScript类型收窄疑问:是否与泛型分配性相关?
问题解答
你的猜想完全正确,这正是问题的核心原因:
D<C>的实际类型解析
当泛型D传入联合类型C(即'a' | 'b')时,TypeScript会直接将泛型参数替换为整个联合类型,得到{ prop: 'a' | 'b' }——这是一个单一对象类型,它的prop属性是联合类型,而非{ prop: 'a' } | { prop: 'b' }这种对象联合类型。类型收窄的局限性
TypeScript的类型收窄只能针对被检查的属性本身:当你判断something.prop === 'a'时,它只会把something.prop的类型收窄为'a',但无法自动将整个something的类型从{ prop: 'a' | 'b' }升级为{ prop: 'a' }。只有当对象本身是对象联合类型时,TypeScript才能通过属性检查收窄整个对象的类型。
修正方案1:直接使用对象联合类型
将something的类型声明为D<'a'> | D<'b'>,此时TypeScript能正确识别属性与对象类型的关联:
type C = 'a' | 'b'; type D<T extends C> = { prop: T, } const something: D<'a'> | D<'b'> = { prop: 'a' }; function funA(arg: D<'a'>) { } function funB(arg: D<'b'>) { } if (something.prop === 'a') { funA(something); // 不再报错 }
修正方案2:利用分布式条件类型改造泛型
通过分布式条件类型,让D<C>自动解析为对象联合类型(泛型在条件类型中遇到联合类型时会自动分发):
type C = 'a' | 'b'; // 利用条件类型触发分布式解析 type D<T extends C> = T extends T ? { prop: T } : never; const something: D<C> = { prop: 'a' }; // 此时D<C>等价于{ prop: 'a' } | { prop: 'b' } function funA(arg: D<'a'>) { } function funB(arg: D<'b'>) { } if (something.prop === 'a') { funA(something); // 不再报错 }
内容的提问来源于stack exchange,提问作者Page not found
相关产品推荐
相关产品推荐

