如何根据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
相关产品推荐
相关产品推荐

