如何根据传入的参数精确 `Promise` 返回的类型?
代码:
const action = {
'/posts': () => Promise.resolve(['a']),
'/test': () => Promise.resolve([1]),
} as const;
type test = ReturnType<ActionType['/test']>;
async function getData<T extends ItemKey>(url: T) {
return await action[url]();
}
type ActionType = typeof action;
type ItemKey = keyof typeof action;
const post = getData('/posts'); // Promise<string[]>
const test = getData('/test'); // Promise<number[]>
结果:
- 传入
'/posts'
拿到Promise<string[]>
- 传入
'/test'
拿到Promise<number[]>
前置条件:
- 尽可能不要强行断言
回复
1个回答

test
2024-06-21
尝试了一下
const action = {
'/posts': () => Promise.resolve(['a']),
'/test': () => Promise.resolve([1]),
} as const;
type test = ReturnType<ActionType['/test']>;
type ActionType = typeof action;
type ItemKey = keyof typeof action;
type DePromise<T> = T extends Promise<infer R> ? R : T;
type InferResult<T extends ItemKey> = DePromise<ReturnType<ActionType[T]>>;
async function getData<T extends ItemKey>(url: T): Promise<InferResult<T>> {
return await action[url]() as InferResult<T>;
}
const post = getData('/posts'); // Promise<string[]>
const test = getData('/test'); // Promise<number[]>
尝试的时候遇到些问题:
- async 函数的返回类型必须是
Promise<?>
,没办法,只好先DePromise
之后再把Promise
加上。 await action[url]()
自动推导出来的类型是number[] | string[]
,所以只好用as InferResult<T>
强制声明类型。
回复

适合作为回答的
- 经过验证的有效解决办法
- 自己的经验指引,对解决问题有帮助
- 遵循 Markdown 语法排版,代码语义正确
不该作为回答的
- 询问内容细节或回复楼层
- 与题目无关的内容
- “赞”“顶”“同问”“看手册”“解决了没”等毫无意义的内容