gpt4 book ai didi

typescript :将函数的参数约束为与特定类型的值关联的对象的键

转载 作者:搜寻专家 更新时间:2023-10-30 21:21:51 25 4
gpt4 key购买 nike

有没有办法进行以下类型检查?

function getNumberFromObject<T>(obj: T, key: keyof T): number {
return obj[key] // ERROR: obj[key] might not be a number
}

我想指定 key 不仅应该是 T 的键,而且是具有 number 值的键。

最佳答案

最直接的方法是让调用者和执行者都执行此操作 getNumberFromObject<T>类型检查正确是这样的:

function getNumberFromObject<T extends Record<K, number>, K extends keyof any>(
obj: T,
key: K
): number {
return obj[key] // okay
}

当你调用它时:

getNumberFromObject({dog: 2, cat: "hey", moose: 24}, "dog"); // okay
getNumberFromObject({dog: 2, cat: "hey", moose: 24}, "cat"); // error
getNumberFromObject({dog: 2, cat: "hey", moose: 24}, "moose"); // okay
getNumberFromObject({dog: 2, cat: "hey", moose: 24}, "squirrel"); // error

一切正常,除了你得到的错误有点模糊,因为它提示 Object literal may only specify known properties, and 'dog' does not exist in type 'Record<"somebadkey", number>' .此投诉是 excess property check这不是真正的问题。

如果你想让调用者得到更好的错误,你可以使用更复杂的 conditional type像这样:

function getNumberFromObject<T, K extends keyof any & {
[K in keyof T]: T[K] extends number ? K : never
}[keyof T]>(
obj: T,
key: K
): T[K] {
return obj[key] // okay
}

getNumberFromObject({ dog: 2, cat: "hey", moose: 24 }, "dog"); // okay
getNumberFromObject({ dog: 2, cat: "hey", moose: 24 }, "cat"); // error
getNumberFromObject({ dog: 2, cat: "hey", moose: 24 }, "moose"); // okay
getNumberFromObject({ dog: 2, cat: "hey", moose: 24 }, "squirrel"); // error

在这种情况下,T不受约束,但是 K被迫只是来自 T 的那些键其中 T[K]number .

现在错误显示 Argument of type '"somebadkey"' is not assignable to parameter of type '"dog" | "moose"'. ,这对开发人员更友好。不过,不确定签名的额外复杂性对您来说是否值得。

希望对您有所帮助。祝你好运!


更新:后一个函数返回 T[K] , 不是 number .这可能是一件好事,因为 T[K]可能比 number 更具体.例如:

interface Car {
make: string,
model: string,
horsepower: number,
wheels: 4
}
declare const car: Car;
const four = getNumberFromObject(car, 'wheels'); // 4, not number

four类型为 4 ,比 number 更具体.如果你真的想把函数的返回类型扩大到number ,你可以...尽管实现会对此犹豫不决,因为编译器不够聪明,无法意识到 T[K]可分配给 number在一般情况下。有多种方法可以解决这个问题,但最简单的方法是在实现中使用类型断言 (return obj[key] as any as number)。

Playground link to code

关于 typescript :将函数的参数约束为与特定类型的值关联的对象的键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52188399/

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