gpt4 book ai didi

索引类型的TypeScript键太宽

转载 作者:行者123 更新时间:2023-12-03 16:20:02 25 4
gpt4 key购买 nike

抱歉,我敢肯定这已经在某处得到了回答,但是我不确定要用谷歌搜索什么。如果标题中的术语有误,请编辑我的问题。
我有这样的事情:

type RowData = Record<string, unknown> & {id: string}; 


type Column<T extends RowData, K extends keyof T> = {
key: K;
action: (value: T[K], rowData: T) => void;
}

type RowsAndColumns<T extends RowData> = {
rows: Array<T>;
columns: Array<Column<T, keyof T>>;
}
而且TypeScript应该能够通过检查行的形状以及为该列提供的 action值来推断 key函数的类型:
IE:
function myFn<T extends RowData>(config: RowsAndColumns<T>) {

}

myFn({
rows: [
{id: "foo",
bar: "bar",
bing: "bing",
bong: {
a: 99,
b: "aaa"
}
}
],
columns: [
{
key: "bar",
action: (value, rowData) => {
console.log(value);
}
},
{
key: "bong",
action: (value, rowData) => {
console.log(value.a); //Property 'a' does not exist on type 'string | { a: number; b: string; }'.

}
}
]
});

Playground Link
问题是,TypeScript似乎将值的类型( value: T[K])派生为“T的所有键都可以访问的所有类型”,而不是仅使用column对象中提供的键。
为什么TypeScript会这样做,我该如何解决呢?
定义一些特定的术语和概念将是一个很好的答案。
我想我想将 K extends keyof T更改为类似“K是T的键,但只有一个键,并且它永远不会改变”。

最佳答案

如果您希望T的键像"bong" | "bing" | ...(而不只是string)一样是unionliterals,那么您可以表达一种类型,该类型本身就是Column<T, K>中每个键Kkeyof T的并集。
我通常通过立即将indexing (lookup)转换为mapped type来执行此操作:

type SomeColumn<T extends RowData> = {
[K in keyof T]-?: Column<T, K>
}[keyof T]
但是您也可以通过 distributive conditional types来做到这一点:
type SomeColumn<T extends RowData> = keyof T extends infer K ?
K extends keyof T ? Column<T, K> : never : never;
无论哪种方式,您的 RowsAndColumns类型都将使用 SomeColumn而不是 Column:
type RowsAndColumns<T extends RowData> = {
rows: Array<T>;
columns: Array<SomeColumn<T>>;
}
这可以使您期望的用例按预期工作,而不会出现编译错误:
myFn({
rows: [
{
id: "foo",
bar: "bar",
bing: "bing",
bong: {
a: 99,
b: "aaa"
}
}
],
columns: [
{
key: "bar",
action: (value, rowData) => {
console.log(value);
}
},
{
key: "bong",
action: (value, rowData) => {
console.log(value.a);
}
},
]
});
Playground link to code

关于索引类型的TypeScript键太宽,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64744734/

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