gpt4 book ai didi

typescript - TypeScript 是否难以使用泛型进行索引?

转载 作者:行者123 更新时间:2023-12-03 21:40:46 25 4
gpt4 key购买 nike

扩展来自 Effective Typescript 的一个例子,我不知道我是否遇到了类型检查器或我的理解的限制。
这是第 33 页原始形式的示例

interface Point {
x: number
y: number
}

function sortBy<K extends keyof T, T>(vals: T[], key: K): T[] {
// ...
}

const pts: Point[] = [
{ x: 1, y: 1 },
{ x: 2, y: 0 },
]

console.log(sortBy(pts, "x"))
这是我尝试用有用的东西替换//...
interface Point {
x: number
y: number
}

function sortBy<K extends keyof T, T>(vals: T[], key: K): T[] {
// my solution
return vals.sort((a, b) => {
return b[key] - a[key] // Error: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.ts(2362)
})
// end my solution
}

const pts: Point[] = [
{ x: 1, y: 1 },
{ x: 2, y: 0 },
]

console.log(sortBy(pts, "x"))
但如果我替换为
return (b[key] as any) - (a[key] as any)
有用
我想不通的是为什么类型检查器认为 a[key] 或 b[key] 可以是数字以外的任何东西,因为 a 和 b 必须是 Point 类型,而 key 必须是 keyof Point。
如果我在没有泛型的情况下编写它,它可以正常工作,这让我觉得这里发生了一些事情。
function sortBy(vals: Point[], key: "x" | "y"): Point[] {
return vals.sort((a, b) => {
return b[key] - a[key]
})
}

最佳答案

泛型函数或类型必须在内部有效,无论它是如何调用或使用的。换句话说,sortBy不知道 Point存在,或者最终可能会使用该类型调用它。它需要处理您可能想要传入的任何对象形状数组,而不仅仅是 Point[] .
如果你看看这个函数类型:

function sortBy<K extends keyof T, T>(vals: T[], key: K): T[] {
return vals.sort((a, b) => {
return b[key] - a[key]
})
}
型号 number没有出现,但您正在执行需要数字的操作。
这是它提示的情况:
sortBy([{ a: 'a string' }], 'a')
上面的函数签名类型中没有任何内容表明这是无效的。但是当函数运行时它会崩溃,因为 string - string不是有效的操作。
您仅将具有数字属性的对象传递给它的事实并不重要,因为您也可以告诉它查找其他类型。

解决方案是约束 K通用只允许会产生 number 类型的键.
function sortBy<K extends string, T extends Record<K, number>>(vals: T[], key: K): T[] {
return vals.sort((a, b) => {
return b[key] - a[key];
})
}

console.log(sortBy([{a: 'asd', b: 123}], "b")) // works

console.log(sortBy([{a: 'asd', b: 123}], "a")) // type error
// Type 'string' is not assignable to type 'number'.(2322)
现在为了满足调用这个函数 K可以是任何 string ,但该对象必须具有具有 number 的属性在命名属性上。
Playground

关于typescript - TypeScript 是否难以使用泛型进行索引?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67927451/

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