为何TypeScript在这段多类型输入代码中报错?代码看似类型安全
TypeScript联合类型调用报错原因解析
报错代码
type ContentA = string type ContentB = number type InputA = { name: 'method_a' content: ContentA } type InputB = { name: 'method_b' content: ContentB } type Input = InputA | InputB const my_methods = { method_a: (content: ContentA) => { // ... }, method_b: (content: ContentB) => { // ... } } function foo(input: Input) { return my_methods[input.name](input.content); // 报错:Argument of type 'string | number' is not assignable to parameter of type 'never'. Type 'string' is not assignable to type 'never'. }
核心疑问
这段代码逻辑上是安全的:Input类型只能是InputA或InputB,若为InputA则input.name是'method_a',对应的my_methods.method_a参数类型和input.content的string类型完全匹配;若为InputB同理。为什么TypeScript还会报错?
原因解析
问题出在TypeScript对联合类型的关联性处理限制:
- 当
input是InputA | InputB联合类型时,TypeScript无法自动关联input.name和input.content的类型关系。它会把这两个属性当成独立的联合类型:input.name是'method_a' | 'method_b',input.content是string | number。 - 当你通过
my_methods[input.name]获取方法时,TypeScript会计算所有可能方法的参数类型的交集:ContentA & ContentB也就是string & number,而这两种类型没有交集,结果就是never类型。 - 此时你传入
input.content(类型是string | number),自然会触发“无法赋值给never类型”的报错——因为TS无法确认当前选中的方法和传入的参数类型是匹配的。
简单来说,TS在这个场景下没办法理解“name和content是绑定在一起的成对属性”,它只会单独检查每个属性的联合类型,从而导致逻辑上安全的代码被判定为类型不兼容。
内容的提问来源于stack exchange,提问作者user20294494
相关产品推荐
相关产品推荐

