首页 文章

函数类型参数的TypeScript类型推断基于其参数类型

提问于
浏览
1

我正在尝试在TypeScript中声明一个函数 fun ,该函数使用其类型参数 T 作为约束,可以将哪些键用作另一个函数的参数 context.Foo

interface Context<T> {
    Foo(key: keyof T)
}

function fun<T>(provider: (context: Context<T>) => T): number {
    return 1
}

fun<{a: number}>(context => {
    return {a: context.Foo('a')}
})

到目前为止,我只能在底部的 foo 调用中使用'a' literal作为 context.Fookey 参数,因为此调用具有一个声明 T{a: number} 的类型参数 .

困扰我的是我实际上将这种类型的结构内联定义为 provider 函数体 . 我只能返回一个与 {a: number} 定义匹配的对象 .

我想要实现的是摆脱在调用时显式定义 T 类型 fun 的需要,并让类型推断通过我从 fun 返回的对象的结构自己看出这个类型 . 参数(必须是 T ),如下所示:

fun(context => {
    return {a: context.Foo('a')}
})

不幸的是,这以一个错误结束:

TS2345:“a”类型的参数不能分配给“never”类型的参数 .

T 的类型推断失败并且已经回落到 never ,这在这种情况下肯定没用 .

是否可以以不需要 funT 的显式设置的方式定义此函数?

1 回答

  • 1

    我认为没有办法实现这一点,只要你试图将 Context<T> 绑定到结果的键上,编译器就会放弃推理 .

    由于 Foo 总是返回相同的值类型(至少从我在注释中理解的内容),您只能指定类型的键,而不必指定整个类型:

    interface Context<K> {
        Foo(key: K): number;
    }
    
    function fun<K extends string>(provider: (context: Context<K>) => Record<K, number>): Record<K, number> {
        return provider(null as any);
    }
    
    let a = fun<'a'>(context => {
        return { a: context.Foo('a') }
    })
    

相关问题