【问题标题】:Typescript deduce return type of member function of generic typeTypescript 推导出泛型成员函数的返回类型
【发布时间】: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&lt;Discord.User&gt; 而不是 Promise&lt;Any&gt;

Discord.User.fetch()Discord.PartialUser.fetch()都返回Promise&lt;Discord.User&gt;,这可以在接口或返回类型中推导出来吗?在 C++ 中我们会写类似 decltype(std::declval&lt;T&gt;().fetch()) 的东西,但不确定在 TS 中该做什么。

【问题讨论】:

    标签: typescript discord.js


    【解决方案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 来避免编译器错误。

      • unknownany 更安全,但如果您确实需要 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
      

      【讨论】:

        猜你喜欢
        • 2020-01-23
        • 1970-01-01
        • 1970-01-01
        • 2021-10-06
        • 2019-01-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多