TypeScript能否基于对象形状做类型推断?复用函数返回不同子类型
TypeScript 动态返回类型与类型推断解决方案
一、让函数返回对应类型,无需重复实现
你可以通过类型映射+泛型实现函数根据输入的animalType返回对应的Dog或Cat类型,无需重复编写多个函数。
步骤1:建立类型与字符串标识的映射
先定义一个类型映射,将字符串标识和对应的接口绑定:
interface Animal { height: number name: string } interface Dog extends Animal { numberOfTeeth: number hasTail: boolean } interface Cat extends Animal { sizeOfPaw: number } // 类型映射:字符串标识 → 对应接口 type AnimalTypeMap = { dog: Dog cat: Cat }
步骤2:重写泛型函数
用泛型约束输入的animalType是映射的key,同时让函数返回对应类型。注意原函数漏加了async关键字(因使用了await),需要补上:
import axios from "axios"; async function getAnimal<T extends keyof AnimalTypeMap>( id: string, animalType: T ): Promise<AnimalTypeMap[T]> { const res = await axios.get(`http://animalapi.com/${animalType}/${id}`); // 断言返回数据符合对应类型(需保证API返回结构与接口匹配) return res.data as AnimalTypeMap[T]; }
步骤3:调用函数(自动推断类型)
调用时TypeScript会根据传入的animalType自动推断返回类型,无需手动指定:
// 返回Dog类型 const dog = await getAnimal("1", "dog"); console.log(dog.numberOfTeeth); // 无类型错误 // 返回Cat类型 const cat = await getAnimal("2", "cat"); console.log(cat.sizeOfPaw); // 无类型错误
二、避免手写字符串,用常量关联类型
如果不想手写"dog"这类字符串,可以定义常量集合,同时用as const让TypeScript保留字面量类型:
const AnimalTypes = { dog: "dog" as const, cat: "cat" as const }; // 调用时直接用常量,避免拼写错误 const dog = await getAnimal("1", AnimalTypes.dog);
三、关于基于对象形状的类型推断
TypeScript支持基于对象形状的类型推断,但分两种场景:
- 对于本地定义的对象,TypeScript会自动根据结构推断类型:
const myDog = { height: 50, name: "旺财", numberOfTeeth: 42, hasTail: true }; // myDog自动推断为Dog类型(结构完全匹配时) - 对于API返回的运行时数据,编译阶段无法预知其形状,所以需要通过类型映射、泛型等方式提前关联输入标识与返回类型,让TypeScript能正确推断。
内容的提问来源于stack exchange,提问作者Sheen
相关产品推荐
相关产品推荐

