TypeScript条件分支用联合类型报错,求原因及解决方法
问题原因解析
你的问题核心在于TypeScript无法对宽泛的string类型完成类型窄化,导致联合类型的类型判断失效,具体拆解如下:
1. 联合类型的访问规则
联合类型Actions = Increment | Decrement表示变量action要么是Increment类型,要么是Decrement类型,而非“包含两种类型所有属性”的混合类型。TypeScript对联合类型的属性访问有严格限制:只能访问所有子类型共有的属性。incStep只存在于Increment中,decStep只存在于Decrement中,所以直接访问这两个属性会触发报错,除非能明确当前action属于对应的子类型。
2. 为什么当前type: string的写法不生效
你定义的Increment和Decrement中,type字段是宽泛的string类型,而非具体的字面量值。这意味着:
- TypeScript无法区分
Increment和Decrement的type字段有什么本质区别,因为两者的type都是任意字符串,理论上Decrement的type也可能等于'Inc'。 - 当你写
if(action.type == 'Inc')时,TS无法通过这个条件确定当前action一定是Increment类型,自然不允许你访问只有Increment才有的incStep属性。
3. 字面量类型能解决的原因
如果把type定义为字面量类型(比如type: 'Inc'和type: 'Dec'),Increment和Decrement就变成了带有唯一标识的不同类型。此时action.type == 'Inc'会触发TypeScript的类型窄化机制,TS能明确判断进入该分支时,action就是Increment类型,因此可以安全访问incStep。
修正后的示例代码
type Increment = { type: 'Inc', // 改为字面量类型 incStep: number } type Decrement = { type: 'Dec', // 改为字面量类型 decStep: number } type State = { count: number } type Actions = Increment | Decrement const reducer = (state: State, action: Actions) : State => { if(action.type == 'Inc') { return {count: state.count + action.incStep } // 不再报错 } else if(action.type == 'Dec') { return {count: state.count - action.decStep} // 不再报错 } return state }
内容的提问来源于stack exchange,提问作者Amit Dhaterwal
相关产品推荐
相关产品推荐

