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

如何根据Animal的type属性推断move方法的参数类型?

问题描述

现有以下TypeScript代码:

type AnimalType = "dog" | "fish";

interface DogMoveProps {
  legs: number;
}

interface FishMoveProps {
  fins: number;
}

interface Animal {
  type: AnimalType;
  move: (props) => void; // 该如何为此类型标注?
}

需求是:当Animal的type属性为"dog"时,move方法的props参数自动推断为DogMoveProps类型;当type为"fish"时,props自动推断为FishMoveProps类型。比如下面的场景中,move的props应该被正确推断:

const dog: Animal = {
  type: "dog",
  move(props) { // <-- 应自动推断为DogMoveProps类型
    // props.legs
  }
}
解决方案

要实现这种根据type字段约束props类型的需求,不能用单一的Animal接口,而是需要定义带关联关系的联合类型,让TypeScript能通过type的字面量类型自动推断出对应的props类型。

方法一:直接定义关联联合类型

先创建映射关系绑定动物类型与对应move参数类型,再基于映射生成联合类型:

type AnimalType = "dog" | "fish";

interface DogMoveProps {
  legs: number;
}

interface FishMoveProps {
  fins: number;
}

// 定义动物类型与move参数的映射关系
type AnimalMovePropsMap = {
  dog: DogMoveProps;
  fish: FishMoveProps;
};

// 生成带关联关系的Animal联合类型
type Animal = {
  [K in AnimalType]: {
    type: K;
    move: (props: AnimalMovePropsMap[K]) => void;
  };
}[AnimalType];

现在使用时,TypeScript会自动根据type的值推断move的参数类型:

const dog: Animal = {
  type: "dog",
  move(props) {
    // props 自动推断为 DogMoveProps,可直接访问 props.legs
    console.log(props.legs);
  }
};

const fish: Animal = {
  type: "fish",
  move(props) {
    // props 自动推断为 FishMoveProps,可直接访问 props.fins
    console.log(props.fins);
  }
};

方法二:类型守卫处理函数场景

如果需要在函数中处理不同类型的Animal,可以用类型守卫缩小类型范围,确保参数推断正确:

function handleAnimal(animal: Animal) {
  if (animal.type === "dog") {
    // 此时 animal.move 的参数自动推断为 DogMoveProps
    animal.move({ legs: 4 });
  } else {
    // 此时 animal.move 的参数自动推断为 FishMoveProps
    animal.move({ fins: 2 });
  }
}

这种方式的核心是让type字段作为判别式,让TypeScript识别联合类型中不同成员的关联关系,从而自动完成参数类型的推断。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 12:25:16