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

时间:2018-03-20 07:41:40

标签: typescript type-inference

我正在尝试在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')}
})

到目前为止,我只能在底部的key调用中使用'a'文字作为context.Foo的{​​{1}}参数,因为此调用的类型参数为声明fooT

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

我想要实现的是摆脱在调用时明确定义{a: number}类型T的需要,并让类型推断通过结构自行计算出这种类型。我正在从fun的参数(需要fun)返回的对象,如下所示:

T

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

  

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

fun(context => { return {a: context.Foo('a')} }) 的类型推断失败,并且已经回落到T,在这种情况下肯定没用。

是否可以定义此功能,以便不需要明确设置never的{​​{1}}?

1 个答案:

答案 0 :(得分: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') }
})