我有以下代码:
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 }
答案 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
这对您有用吗?希望能有所帮助;祝你好运!
对于修改后的示例,我更改了类型,但保留了相同的基本思想:您需要使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
希望再次有所帮助;祝你好运。