【问题标题】:How to type a function which returns a function's result from a collection of functions in typescript如何键入从打字稿中的函数集合返回函数结果的函数
【发布时间】:2021-10-02 20:09:09
【问题描述】:

我有这个函数,它接收一个函数对象,根据某些条件选择一个,然后调用并返回其中一个函数:

type ProductName = 'product1' | 'product2' | 'product3' | 'product4';
function detectProduct(): ProductName  {
    return 'product1'; // for demo purpose
}

export function onAnyProduct<T extends Partial<Record<ProductName, () => any>>> (
    productCallbacks: T
): ReturnType<T[keyof T]> | undefined {
    const name = detectProduct();
    const callback = productCallbacks[name];
    return callback?.();
}

const a = onAnyProduct({
    product1: () => '1',
    product2: () => ({}),
});

您可以在 TypeScript 操场上查看它:
https://www.typescriptlang.org/play?ssl=17&ssc=4&pln=1&pc=1#code/C4TwDgpgBACgTgewCYFcDGwByBDAttAXigHIxFUMBGYqAHxLOXWACYb7TzmBmdhrjABZiAbgBQAMxQA7DAEsE0qEgjAIGeEwwAKAJQAuWAKx5oUAN5io1qHFUo4SzluDURUAPQeoEhHGUQuAhQYA5gCADOEGIAvmJiEAAe4XDAPjLyilCKAILSIJoUwAA8ACpQSWrSSBGw2Kly2AA2xQBK6n5IxYXMOPgANFB6UAQAfFDY+aPTQ1Y2jEUAws1NAEbYaADWEYalYgZQ7cAO0qXgEGUA2psQIAgSUKUAuuP0MioSctIQSBZz1mhFBE0tJTCMAmoNMY9OIbFBAdJgfCVustuCFsxlk01httpdQfgnrCbHZjo5kdjUZsAPwAOhhsXiCKR2HBuXyPR0ljhGKohmGYxI1H6-xCxhY-N0I3G2nMMV0IvlIiAA

如您所见,T[keyof T] 存在问题,但 a 的类型正确为 const a: string | {} | undefined

为什么它不知道T[keyof T] 是一个函数?

【问题讨论】:

    标签: typescript


    【解决方案1】:

    因为在你扩展你的记录类型之后,扩展对象的键/值可以是任何东西,而不仅仅是ProductName() =&gt; {}

    Type 'T[keyof T]' does not satisfy the constraint '(...args: any) => any'
    => keyof T = string | number | symbol
    Type 'T[string] | T[number] | T[symbol]' is not assignable to type '(...args: any) => any'
    
    type ProductName = 'product1' | 'product2' | 'product3' | 'product4';
    function detectProduct(): ProductName  {
        return 'product1'; // for demo purpose
    }
    
    // because you mark T as extended of Partial type
    // then T["product1"] = () => any | undefined
    // then you should use NonNullable
    export function onAnyProduct<T extends Partial<Record<ProductName, () => any>>> (
        productCallbacks: T
    ): ReturnType<NonNullable<T["product1"]>> | undefined {
        const name = detectProduct();
        const callback = productCallbacks[name];
        return callback?.();
    }
    
    const a = onAnyProduct({
        product1: () => '1',
        product2: () => ({}),
    });
    

    【讨论】:

    • T["product1"] 应该是T[keyof T],对吧?
    • 不,keyof T 可以是“product1”、“extendname”。
    猜你喜欢
    • 2012-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-05
    • 1970-01-01
    • 2021-12-08
    • 1970-01-01
    相关资源
    最近更新 更多