如何实现根据动态属性输入生成对应类型的API返回对象?
实现动态推导返回类型的getUserInfo函数
要实现这个根据输入属性数组自动生成对应返回类型的函数,用TypeScript的泛型和映射类型就能搞定,下面是具体实现:
基础实现(固定属性范围)
先定义所有API支持的用户属性,确保传入的参数合法,同时让TypeScript能精准推导类型:
// 定义所有允许查询的用户属性 type UserProperty = 'name' | 'email' | 'height'; async function getUserInfo<T extends UserProperty[]>( properties: [...T] // 用元组类型捕获具体的属性列表 ): Promise<{ [K in T[number]]: string }[]> { // 拼接查询参数 const queryStr = properties.join('&'); // 发起请求并返回数据 const res = await fetch(`http://fake.service.com/users?${queryStr}`); return res.json(); }
调用示例
// 返回类型自动推导为 { name: string; email: string; height: string; }[] const fullInfo = await getUserInfo(['name', 'email', 'height']); // 返回类型自动推导为 { name: string; }[] const onlyName = await getUserInfo(['name']);
进阶实现(支持不同属性类型)
如果API返回的属性值有不同类型(比如age是数字),可以先定义完整的用户类型,再用Pick工具类型来筛选:
// 完整的用户类型定义 interface User { name: string; email: string; height: string; age: number; } async function getUserInfo<T extends keyof User>( properties: T[] ): Promise<Pick<User, T>[]> { const queryStr = properties.join('&'); const res = await fetch(`http://fake.service.com/users?${queryStr}`); return res.json(); } // 返回类型为 { name: string; age: number; }[] const nameAndAge = await getUserInfo(['name', 'age']);
关键原理
- 泛型
T约束为属性数组,[...T]让TypeScript把输入识别为具体元组而非宽泛的数组,从而准确捕获传入的属性列表 - 映射类型
{ [K in T[number]]: string }或Pick<User, T>会根据元组中的属性,动态生成对应的对象类型 - 最终返回类型是该对象类型的数组,被Promise包裹,符合异步函数的返回要求
内容的提问来源于stack exchange,提问作者sifear
相关产品推荐
相关产品推荐

