TypeScript:为评估通用对象上的函数属性的函数推断正确的类型

时间:2019-12-23 11:51:07

标签: typescript generics types type-inference typescript-generics

我想定义一个功能如下:

const result = evaluate({x: () => 2 * 3, y: () => "hello"})

result的值是:

{x: 6, y: "hello"}

据我所知,该定义必须类似于:

function evaluate<T>(obj: Record<keyof T, () => T[keyof T]>): T {
    // Copy the key-value pairs, invoking each value.
    // There are a few different ways to do this.
    return Object.assign({}, ...Object.entries<() => T[keyof T]>(obj).map(([k, v]) => ({[k]: v()})))
}

但是,这不太起作用。在前面提供的示例中,result的类型推断为:

{x: unknown, y: unknown}

如果明确提供了type参数,则功能调用正常工作:

const result = evaluate<{x: number, y: string}>({x: () => 2 * 3, y: () => "hello"})

是否可以通过某种方式使类型推断正常工作?

1 个答案:

答案 0 :(得分:2)

我认为TS不够聪明,无法以这种方式解析T

解决方案很简单,您可以在T中捕获参数的类型,然后使用自定义映射类型将参数转换为所需的类型:

const result = evaluate({x: () => 2 * 3, y: () => "hello"})

function evaluate<T extends Record<keyof T, () => any>>(obj: T): {
    [P in keyof T]: ReturnType<T[P]>
} {
    // Copy the key-value pairs, invoking each value.
    // There are a few different ways to do this.
    return Object.assign({}, ...Object.entries<() => T[keyof T]>(obj).map(([k, v]) => ({[k]: v()})))
}

Playground Link