gpt4 book ai didi

javascript - 如何保证传递的对象键可以使用 Typescript 进行调用?

转载 作者:行者123 更新时间:2023-12-02 22:34:38 24 4
gpt4 key购买 nike

我正在尝试为特定用例创建一个 React 高阶组件,问题归结为以下几点:

function sample<TObj, P extends keyof TObj, F extends keyof TObj>(
obj: TObj,
prop: P,
setProp: TObj[F] extends (value: TObj[P]) => void ? F : never
) {
obj[setProp](obj[prop]);
}

我希望能够传递一个对象、一个应该是该对象的键的字符串以及该对象的另一个键,但它必须是一个函数。

这可以进一步简化:

function sample2<TObj, F extends keyof TObj>(
obj: TObj,
setProp: TObj[F] extends () => void ? F : never
) {
obj[setProp]();
}

在我看来,因为我使用的是条件类型,所以可以保证obj[setProp]将是一个函数,但我收到错误: enter image description here

This expression is not callable.
Type 'unknown' has no call signatures.ts(2349)

如下所示,如果使用不符合要求的键调用该函数,该函数将会出错。但同样的要求似乎并没有应用于函数内部。

我知道这可以被视为 XY 问题,但这让我真正感兴趣的是是否有一种方法可以使这个特定问题正常工作。

最佳答案

里面执行sample2() ,类型TObj[F] extends () => void ? F : never是一个 Unresolved 条件类型。也就是说,它是一个条件类型,依赖于当前未指定的要解析的泛型类型参数。在这种情况下,编译器通常不知道如何处理它,并将其视为本质上不透明的。 (有关此问题的一些讨论,请参阅 microsoft/TypeScript#23132。)特别是它没有意识到 TObj[Tobj[F] extends ()=>void ? F : never]最终必须解析为 ()=>void 的某个子类型.

一般来说,除非有必要,否则我会完全避免使用条件类型。编译器可以更容易地从 mapped types 理解和推断喜欢 Record<K, V> :

function sample2<K extends PropertyKey, T extends Record<K, () => void>>(
obj: T,
prop: K
) {
obj[prop]();
}

当你调用它时,其行为类似:

const obj2 = {
func() { console.log("func") },
prop: 42
};
sample2(obj2, "func"); // okay,
//sample2(obj, "prop"); // error
// ~~~ <-- number is not assignable to ()=>void
<小时/>

编辑:解决原始sample() ,我会使用这个定义:

function sample<
PK extends PropertyKey,
FK extends PropertyKey,
T extends Record<PK, any> & Record<FK, (v: T[PK]) => void>
>(
comp: T,
prop: PK,
setProp: FK
) {
comp[setProp](comp[prop]);
}

const obj = {
func(z: number) { console.log("called with " + z) },
prop: 42
}

我认为,这也符合您的要求:

sample(obj, "prop", "func"); // called with 42
sample(obj, "prop", "prop"); // error!
// ~~~ <-- number not assignable to (v: number)=>void
sample(obj, "func", "func"); // error!
// ~~~ <-- (v: number)=>void not assignable to number
<小时/>

好的,希望有帮助;祝你好运!

Link to code

关于javascript - 如何保证传递的对象键可以使用 Typescript 进行调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58778795/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com