【问题标题】:Typescript infer the type of inner function in higher order function打字稿在高阶函数中推断内部函数的类型
【发布时间】:2020-07-11 19:52:16
【问题描述】:

我有以下代码:

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 }

【问题讨论】:

  • 你能解释更多你想用E 完成的事情吗?也许还有更多关于updateProp 的返回值的例子?它会根据道具的名称仅更新名称还是仅更新 ID?也许增加 id 并将“先生”添加到 name

标签: typescript


【解决方案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 可以是任何keylike 的东西,然后返回的函数将接受任何以K 为key 的值并返回相同类型的东西。当与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

【讨论】:

  • 很抱歉给您带来了困惑。这是我能写的最简单的用例。我已经更新了问题。
  • 更新了我的答案以适合您的新示例代码;请查看。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-22
  • 2020-01-24
  • 1970-01-01
相关资源
最近更新 更多