Typescript推断高阶函数中内部函数的类型

时间:2020-07-11 19:52:16

标签: typescript

我有以下代码:

type SuperType<T = any> = {
    entities?: {
        [key: string]: T
    };
}

class Test<T> {
    value: T;

    constructor(v: T) {
      this.value = v;
    }

    update(cb: (v: T) => T) {
      this.value = cb(this.value);
    }
}

interface H extends SuperType<{ prop: number }> {}

const instance = new Test<H>({});

我想创建一个更新值的高阶函数:

function updateSomething<
    T extends SuperType,
    E = T extends SuperType<infer I> ? I : never>(arg: E) {
    return function (value: T) {
       return value;
    }
}

如何推断高阶函数中的泛型?

instance.update(updateSomething(placeholder))

因此,这里placeholder的键入应为{ prop: number }

1 个答案:

答案 0 :(得分:1)

我完全不了解SuperType的参与方式,因为H无法分配给SuperType。我现在暂时不理会SuperType,您可以告诉我是否需要更改您的问题才能使用它。


我倾向于输入updateProp()如下:

function updateProp<K extends PropertyKey>(prop: K) {
    return function <T extends Record<K, any>>(value: T) {
        return value;
    }
}

这里我说的是K可以是任何类似键的东西,然后返回的函数将接受以K作为键的任何值并返回相同类型的东西。与instance.update()一起使用时具有预期的效果:

instance.update(updateProp('name')); // okay
instance.update(updateProp('id')); // okay
instance.update(updateProp('notExists')); // error, as desired

这对您有用吗?希望能有所帮助;祝你好运!

Playground link to code


更新

对于修改后的示例,我更改了类型,但保留了相同的基本思想:您需要使updateProp()的参数类型具有通用性,然后从中计算其他类型:

function updateProp<E>(prop: E) {
    return function <T extends SuperType<E>>(value: T) {
        return value;
    }
}
instance.update(updateProp({ prop: 123 })); // okay
instance.update(updateProp({ prop: "" })); // error
instance.update(updateProp({ prop: 123, unexpectedProp: 456 })); // error

希望再次有所帮助;祝你好运。

Playground link to code