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

如何让TypeScript在动态调度器中自动推断类型?

TypeScript动态调度器类型匹配错误解决

我尝试构建一个根据动物类型自动调用对应行为函数的动态调度器,代码如下:

enum AnimalType {
  Rabbit = 'Rabbit',
  Duck = 'Duck',
}

interface RabbitInput {
  animalType: AnimalType.Rabbit;
  food: string;
}

interface DuckInput {
  animalType: AnimalType.Duck;
  swim_speed: number;
}

type AnimalInput = RabbitInput | DuckInput

type AnimalFunctionMap = {
  [AnimalType.Duck]: (input: DuckInput) => Promise<any>;
  [AnimalType.Rabbit]: (input: RabbitInput) => Promise<any>;
};

const eat = async (input: RabbitInput) => {
    return { 'status': 'satisfied' };
}
const swim = async(input: DuckInput) => {
    return { 'status': 'fast' };
}

const animalFunctions: AnimalFunctionMap = {
  [AnimalType.Duck]: swim,
  [AnimalType.Rabbit]: eat,
};

function isRabbitInput(input: AnimalInput): input is RabbitInput {
  return input.animalType === AnimalType.Rabbit
}
function isDuckInput(input: AnimalInput): input is DuckInput {
  return input.animalType === AnimalType.Duck
}
const applyAnimalBehaviour = async (input: AnimalInput): Promise<any> => {
  const animalFunction = animalFunctions[input.animalType];
  if (animalFunction) {
    if (isRabbitInput(input)) {
      return await animalFunction(input); 
    } else if (isDuckInput(input)) {
      return await animalFunction(input);
    } else {
      throw new Error(`Unsupported animal type.`);
    }
  } else {
    throw new Error(`No animal function found for type.`);
  }
};

但运行时出现了如下类型错误:

Argument of type 'DuckInput' is not assignable to parameter of type 'never'.
  The intersection 'DuckInput & RabbitInput' was reduced to 'never' because property 'animalType' has conflicting types in some constituents.(2345)

错误原因

TypeScript无法自动关联animalFunctions[input.animalType]的函数类型与input的具体类型。当你通过索引访问获取函数时,TS会将其推断为所有对应函数的联合类型,而联合类型的函数调用要求参数是所有函数参数的交集。由于DuckInput和RabbitInput的animalType类型冲突,它们的交集是never,因此出现报错。

解决方案

方案1:使用switch case(最直观类型安全)

直接通过switch匹配动物类型,TS会自动识别每个case中input的具体类型,无需额外类型守卫:

const applyAnimalBehaviour = async (input: AnimalInput): Promise<any> => {
  switch(input.animalType) {
    case AnimalType.Rabbit:
      return await animalFunctions[AnimalType.Rabbit](input);
    case AnimalType.Duck:
      return await animalFunctions[AnimalType.Duck](input);
    default:
      throw new Error(`Unsupported animal type.`);
  }
};

方案2:类型断言简化调用

通过类型断言告诉TS当前函数的参数类型与input匹配:

const applyAnimalBehaviour = async (input: AnimalInput): Promise<any> => {
  const animalFunction = animalFunctions[input.animalType];
  if (animalFunction) {
    return await (animalFunction as (input: typeof input) => Promise<any>)(input);
  } else {
    throw new Error(`No animal function found for type.`);
  }
};

方案3:泛型强关联类型

用泛型约束输入类型,让TS能正确推断函数与参数的匹配关系:

const applyAnimalBehaviour = async <T extends AnimalInput>(input: T): Promise<any> => {
  const animalFunction = animalFunctions[input.animalType] as (input: T) => Promise<any>;
  if (animalFunction) {
    return await animalFunction(input);
  } else {
    throw new Error(`No animal function found for type.`);
  }
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 02:36:00