TypeScript能否让GetRemoteObj返回类型依赖whatToInclude参数?
TypeScript能否让函数返回类型依赖于传入参数?
我定义了以下类型:
type Obj = { one: number; two: number; three?: number; four?: number; five?: number; } type ObjOptional = { three?: boolean; four?: boolean; five?: boolean; }
用Axios获取远程数据的函数如下:
function GetRemoteObj(id: number, whatToInclude: ObjOptional) { return axios.get<Obj>(`api/obj/${id}`, { params : whatToInclude }); }
想知道TypeScript是否支持改造GetRemoteObj,让它的返回类型根据whatToInclude参数动态变化?比如:
示例1:
const obj = (await GetRemoteObj(1, { three: false, four: true })).data;
此时obj的类型应该是:
{ one: number; two: number; four: number; }
示例2:
const obj = (await GetRemoteObj(1, { })).data;
此时obj的类型应该是:
{ one: number; two: number; }
示例3:
const obj = (await GetRemoteObj(1, { three: true, four: true, five: true })).data;
此时obj的类型应该是:
{ one: number; two: number; three: number; four: number; five: number; }
可以实现,核心是用泛型结合条件类型动态构造返回类型,具体代码如下:
import axios from 'axios'; type Obj = { one: number; two: number; three?: number; four?: number; five?: number; } type ObjOptional = { three?: boolean; four?: boolean; five?: boolean; } // 根据传入的whatToInclude参数,动态构造返回的data类型 type IncludedFields<T extends ObjOptional> = // 保留必填的one和two字段 Pick<Required<Obj>, 'one' | 'two'> & // 只保留whatToInclude中值为true的字段,并且设为必填number类型 { [K in keyof T as T[K] extends true ? K : never]: number }; // 泛型函数,T约束为ObjOptional的子集 function GetRemoteObj<T extends ObjOptional>(id: number, whatToInclude: T) { return axios.get<IncludedFields<T>>(`api/obj/${id}`, { params: whatToInclude }); }
改造后,TypeScript会自动根据传入的whatToInclude参数推断返回data的具体类型:
- 传入
{ three: false, four: true }时,返回的data包含one、two和four字段 - 传入空对象时,仅包含
one和two - 传入全true的参数时,包含所有五个字段
内容的提问来源于stack exchange,提问作者c.bear
相关产品推荐
相关产品推荐

