You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在TypeScript中实现Reducer对联合类型Action的类型收窄?

如何用TypeScript实现Reducer中Action类型的自动识别?

你需要处理两种不同类型的Action,并且希望TypeScript能在判断后自动识别对应的属性,其实核心是利用TypeScript的**判别式联合类型(Discriminated Unions)**特性,加上类型缩小逻辑来实现。下面是具体的实现步骤:

1. 先明确Action的类型定义

首先把两种Action类型和它们的联合类型定义好,注意每个Action都要有一个唯一的type字面量属性,这是TypeScript能自动识别类型的关键:

// 处理todo项的Action
interface ItemAction {
  type: 'ADD_TODO' | 'DELETE_TODO' | 'TOGGLE_TODO';
  id: number;
}

// 处理搜索查询的Action
interface QueryAction {
  type: 'SET_QUERY';
  query: string;
}

// 合并成联合类型,作为Reducer的Action参数类型
type AppAction = ItemAction | QueryAction;

2. 实现Reducer中的类型自动识别

有两种常用的方式来实现你想要的逻辑:

方式一:直接通过type属性做分支判断

因为每个Action的type是字面量类型,TypeScript会自动根据type的值缩小变量的类型范围:

function todoReducer(state: any, action: AppAction) {
  if (action.type === 'ADD_TODO' || action.type === 'DELETE_TODO' || action.type === 'TOGGLE_TODO') {
    // 这里TypeScript会自动识别action为ItemAction,id属性可以直接访问
    console.log(action.id);
  } else {
    // 剩下的只有SET_QUERY类型,TypeScript自动识别为QueryAction,query属性可用
    console.log(action.query);
  }
}

如果用switch语句会更清晰,尤其当Action类型较多时:

function todoReducer(state: any, action: AppAction) {
  switch (action.type) {
    case 'ADD_TODO':
    case 'DELETE_TODO':
    case 'TOGGLE_TODO':
      // 这里action被自动缩小为ItemAction
      console.log(action.id);
      break;
    case 'SET_QUERY':
      // 这里action被自动缩小为QueryAction
      console.log(action.query);
      break;
    default:
      // 处理未知类型,避免遗漏
      throw new Error(`Unknown action type: ${action.type}`);
  }
}

方式二:自定义类型守卫函数

如果觉得多个type判断太繁琐,可以写一个自定义类型守卫函数,把判断逻辑封装起来:

// 自定义类型守卫,返回值`action is ItemAction`告诉TypeScript:如果函数返回true,action就是ItemAction类型
function isItemAction(action: AppAction): action is ItemAction {
  return ['ADD_TODO', 'DELETE_TODO', 'TOGGLE_TODO'].includes(action.type);
}

function todoReducer(state: any, action: AppAction) {
  if (isItemAction(action)) {
    // TypeScript自动识别为ItemAction,id属性可用
    console.log(action.id);
  } else {
    // 自动识别为QueryAction,query属性可用
    console.log(action.query);
  }
}

原理说明

这里的核心是判别式联合类型:当多个接口有一个共同的属性(这里是type),且该属性的值是字面量类型时,TypeScript可以通过这个属性的值来精确判断变量的具体类型,从而实现类型自动缩小,不需要手动用as做类型断言。

内容的提问来源于stack exchange,提问作者vasily

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 11:32:28