如何在TypeScript中正确为Action Types添加类型?
问题解决:TypeScript联合类型属性访问错误
错误根源
你遇到的Property 'update' does not exist on type 'ActionDelete'错误,本质是两个问题:
updateProduct的类型ActionProps将action定义为可选的联合类型(ActionUpdate | ActionDelete | undefined),TypeScript无法确定函数内部的action一定是ActionUpdate类型,直接访问action.update会触发类型检查错误。- 你的
Reducer函数调用updateProduct时,没有传递当前的action参数,导致updateProduct里的action可能是undefined。
解决方案
方案1:为updateProduct定义精确类型
既然updateProduct只处理update类型的action,就不要复用通用的ActionProps,单独给它定义精确的类型:
// 替换原有的ActionProps,为updateProduct单独定义类型 interface UpdateProductProps { ( product: Product, value: Value, cart: Cart, action: ActionUpdate // 明确限定为ActionUpdate类型 ): void; } const updateProduct: UpdateProductProps = (product, value, cart, action) => { cart.name = action.update; // 此时TypeScript能确定action有update属性 }; // 同时修复Reducer中调用updateProduct的代码,传递action参数 const Reducer = ( product: Product, value: Value, cart: Cart, action: Action, ) => { switch (action.type) { case ActionTypes.update: // 优先使用枚举值,避免字符串硬编码 updateProduct(product, value, cart, action); break; default: { throw new Error('Unknown type'); } } };
方案2:在函数内部做类型窄化
如果需要保留ActionProps的通用性,可以在updateProduct内部通过类型守卫窄化action的类型:
const updateProduct: ActionProps = (product, value, cart, action) => { // 先判断action存在且为update类型 if (!action || action.type !== ActionTypes.update) { return; // 或根据业务需求抛出错误 } // 经过类型守卫,TypeScript会推断出action是ActionUpdate类型 cart.name = action.update; }; // 同样需要修复Reducer的调用,传递action参数 const Reducer = ( product: Product, value: Value, cart: Cart, action: Action, ) => { switch (action.type) { case ActionTypes.update: updateProduct(product, value, cart, action); break; default: { throw new Error('Unknown type'); } } };
额外优化建议
- 尽量使用枚举值(
ActionTypes.update)而非字符串字面量('update')进行类型判断,避免拼写错误,提升代码可维护性。 - 对于不同类型的action处理函数,建议各自定义对应的参数类型,避免联合类型带来的类型歧义。
内容的提问来源于stack exchange,提问作者FD3
相关产品推荐
相关产品推荐

