Typescript 推导出泛型成员函数的返回类型
Posted
技术标签:
【中文标题】Typescript 推导出泛型成员函数的返回类型【英文标题】:Typescript deduce return type of member function of generic type 【发布时间】:2021-12-25 18:05:37 【问题描述】:我有一些我正在尝试做的事情,但我不太确定如何在 typescript 中实现它。
我正在使用 discord.js,我正在尝试制作一个包装器来将 Discord.User | Discord.PartialUser
(或类似的 T | PartialT
类型)转换为它们的非部分版本。
类似这样的:
interface Partial
partial: boolean;
fetch(): Promise<any>;
async function departialize<T extends Partial>(thing: T)
if(thing.partial)
return await thing.fetch();
else
return thing;
编译时,我想包含更多类型信息。 IE。在这个例子中,我希望它返回 Promise<Discord.User>
而不是 Promise<Any>
。
Discord.User.fetch()
和Discord.PartialUser.fetch()
都返回Promise<Discord.User>
,这可以在接口或返回类型中推导出来吗?在 C++ 中我们会写类似 decltype(std::declval<T>().fetch())
的东西,但不确定在 TS 中该做什么。
【问题讨论】:
【参考方案1】:想通了,这就是我要做的,以防它帮助其他人:
type PotentiallyPartial = Discord.AllowedPartial | Discord.Partialize<Discord.AllowedPartial>;
async function departialize<T extends PotentiallyPartial, R extends ReturnType<T["fetch"]>>(thing: T): Promise<R>
if(thing.partial)
return thing.fetch();
else
return thing as R;
;
【讨论】:
【参考方案2】:这是一个重载函数,它将为您的输入提供正确的返回类型,并根据partial
属性的推断值缩小范围。
注意事项:
因为
Partial
utility 已经在 TypeScript 中声明,所以我使用类型名称Incomplete
来避免编译器错误。
unknown
比any
更安全,但如果您确实需要any
,请随时更换。
TS Playground link
interface Incomplete<T = unknown>
partial: boolean;
fetch (): Promise<T>;
function departialize <T extends Incomplete & partial: true >(thing: T): ReturnType<T['fetch']>;
function departialize <T extends Incomplete & partial: false >(thing: T): T;
function departialize <T extends Incomplete>(thing: T): T | ReturnType<T['fetch']>;
function departialize <T extends Incomplete>(thing: T): T | ReturnType<T['fetch']>
return thing.partial ? thing.fetch() as ReturnType<T['fetch']> : thing;
// Usage:
declare const input1:
partial: boolean;
fetch (): Promise<string>;
someOtherProp: number;
;
const output1 = departialize(input1); // typeof input1 | Promise<string>
declare const input2:
partial: true;
fetch (): Promise<string>;
someOtherProp: number;
;
const output2 = departialize(input2); // Promise<string>
declare const input3:
partial: false;
fetch (): Promise<string>;
someOtherProp: number;
;
const output3 = departialize(input3); // typeof input3
【讨论】:
以上是关于Typescript 推导出泛型成员函数的返回类型的主要内容,如果未能解决你的问题,请参考以下文章