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

TypeScript如何通过对象映射判别联合接口且不使用switch语句

类型安全的React组件对象映射实现方案

问题核心原因

类型推导失效有两个核心问题:

  1. Cat、Dog接口的_type字段定义为宽泛的AnimalType联合类型,没有使用字面量类型,TS无法通过_type值区分两个接口
  2. AnimalMap类型没有建立映射key和对应组件Props的关联,同时resolveAnimal返回值写死为React.Component<Animal>,丢失了具体类型信息

完整实现代码

第一步:修正基础类型定义

import type React from 'react';

// 判别类型联合
type AnimalType = 'cat' | 'dog'

interface Cat {
  _type: 'cat'; // 必须写具体字面量,不要用AnimalType
  name: string;
  onMeow: () => void;
}

interface Dog {
  _type: 'dog'; // 必须写具体字面量,不要用AnimalType
  name: string;
  onBark: () => void;
}

type Animal = Cat | Dog;

// 建立key到对应组件类型的映射关系
type AnimalMap = {
  [K in Animal['_type']]: React.ComponentType<Extract<Animal, { _type: K }>>;
};

第二步:定义组件与映射关系

// 业务组件保持原有写法
const CatComponent = ({ name, onMeow }: Cat) => <div>I'm a cat! My name is {name}</div>;
const DogComponent = ({ name, onBark }: Dog) => <div>I'm a dog! My name is {name}</div>;

// 用satisfies做类型校验,同时保留对象的精确类型(TS >= 4.9支持)
const animalMap = {
  cat: CatComponent,
  dog: DogComponent,
} satisfies AnimalMap;

// 泛型函数:根据传入的_type值推导返回的具体组件类型
function resolveAnimal<T extends AnimalType>(_type: T) {
  return animalMap[_type];
}

第三步:业务使用(自动类型推导)

function App() {
  // 自动推导为ComponentType<Dog>,有完整的Props类型提示
  const ResolvedDogComponent = resolveAnimal('dog');
  // 自动推导为ComponentType<Cat>,传入不属于Cat的Props会直接报类型错误
  const ResolvedCatComponent = resolveAnimal('cat');

  return (
    <div>
      <ResolvedDogComponent name="Buddy" onBark={() => console.log('Bark!')} />
      <ResolvedCatComponent name="Mimi" onMeow={() => console.log('Meow!')} />
    </div>
  );
}

关键注意点

  • 判别联合的核心要求:每个类型成员的判别字段(这里是_type)必须是唯一的字面量类型,不能使用宽泛的联合类型,否则TS无法做类型收窄
  • Extract<Animal, { _type: K }>是TS内置工具类型,作用是从Animal联合类型中筛选出_type等于当前遍历值K的子类型,以此建立映射key和组件Props的强绑定
  • 不要直接给animalMap标注AnimalMap类型,那样会把每个key对应的组件类型拓宽为统一的联合类型,丢失精确推导能力;用satisfies既能做类型合规校验,又能保留对象字面量的原始精确类型
  • resolveAnimal必须用泛型捕获传入_type的字面量类型,才能返回对应类型的组件,写死返回值类型会让所有推导失效
  • 如果项目TS版本低于4.9无法使用satisfies,可以直接给animalMap标注AnimalMap类型,基础类型推导能力不受影响,只是部分场景下类型精度稍差

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 12:01:05