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



我正在尝试在 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"文字作为context.Fookey参数,因为此调用有一个类型参数,该参数声明T{a: number}

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

我想实现的是摆脱在调用时显式定义T类型的fun的需要,并让类型推断通过我从fun的参数返回的对象的结构自行计算出此类型(需要T), 喜欢这个:

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

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

TS2345:类型"a"的参数不可分配给类型为"从不"的参数。

T的类型推断失败并回退到never在这种情况下绝对没有用。

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

我认为没有任何方法可以实现这一点,一旦您尝试将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') }
})

最新更新