【问题标题】:Extract call signature from a type从类型中提取调用签名
【发布时间】:2020-01-29 22:22:20
【问题描述】:

给定一个包含调用签名和附加属性的类型,例如:

export interface Foo<T> {
    (arg: T): T;
    doFoo(): void;
}

我们如何键入一个实现这种类型的调用签名的函数?

// Property 'doFoo' is missing in type '(arg: string) => string'
// but required in type 'Foo<string>'.
const foo: Foo<string> = (arg: string) => arg;

排除调用签名的一种方法是使用映射类型,因为调用签名不会在keyof Foo&lt;T&gt;中:

type FooProperties<T> = { [K in keyof Foo<T>]: Foo<T>[K] };

const foo: FooProperties<string> = {
    doFoo() {}
};

但是我们怎样才能得到相反的结果,即只有调用签名所以我们可以写如下?

type FooSignature<T> = /* …? */

const foo: FooSignature<string> = (arg: string) => arg;

【问题讨论】:

    标签: typescript


    【解决方案1】:

    您可以使用ReturnTypeParameters 内置类型来提取参数和返回类型并重建签名:

    export interface Foo<T> {
        (arg: T): T;
        doFoo(): void;
    }
    
    type JustSignature<T extends (...a: any[]) => unknown> = (...a: Parameters<T>) => ReturnType<T>
    
    type FooSignature<T> = JustSignature<Foo<T>>
    
    const foo: FooSignature<string> = (arg: string) => arg; 
    

    注意:有关适用于多个重载的解决方案,请参阅here

    【讨论】:

    • 感谢提香!我完全没有想到,我一直在思考映射类型。感谢您在 SO 上为 Typescript 所做的所有工作。
    • @IngoBürk 谢谢,请继续提问 :) 对于 TS 来说,SO 已经过了几个星期了,至少就语言问题而言 :)
    • 看起来当有多个调用签名(函数重载)时它不起作用。 JustSignature 在重载列表中选择最新的调用签名。
    • @htulipe 确实可以提取多个签名但很麻烦(类似于这里的stackoverflow.com/questions/52760509/…),这也不适用于泛型。这是原始问题中提出的问题的有限解决方案。
    • 好的,我刚刚在这里发布了问题stackoverflow.com/questions/59968958/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多