我有以下React组件,该组件根据对象数组生成HTML表。通过import webbrowser
a_website = "https://www.google.com"
# Open url in a new window of the default browser, if possible
webbrowser.open_new(a_website)
# Open url in a new page (“tab”) of the default browser, if possible
webbrowser.open_new_tab(a_website)
webbrowser.open(a_website, 1) # Equivalent to: webbrowser.open_new(a_website)
webbrowser.open(a_website, 2) # Equivalent to: webbrowser.open_new_tab(a_website)
属性定义应显示的列。
在遍历tableColumns
并显示正确的列时,我必须使用items
对象(key
)的tableColumn
属性,但打字稿会产生以下错误:
元素隐式地具有“ any”类型,因为类型“ string”的表达式不能用于索引类型“ {}”。 在类型“ {}”上找不到参数类型为“字符串”的索引签名。
该如何解决?我迷路了
我如何称呼该组件:
{item[column.key]}
我的组件:
<TableGridView
items={[
{
id: 1,
name: 'John Doe',
email: 'john@doe.de'
},
{
id: 2,
name: 'Lorem ipsum',
email: 'lorem@ipsum.com',
}
]}
tableColumns={[
{
key: 'id',
label: 'ID',
},
{
key: 'name',
label: 'Name',
}
]}
/>
答案 0 :(得分:7)
items: object[],
那只是一个不好的类型。相反,请准确输入,例如:
items: {
[key: string]: number | string,
}[]
答案 1 :(得分:5)
使用泛型
// bad
const _getKeyValue = (key: string) => (obj: object) => obj[key];
// better
const _getKeyValue_ = (key: string) => (obj: Record<string, any>) => obj[key];
// best
const getKeyValue = <T extends object, U extends keyof T>(key: U) => (obj: T) =>
obj[key];
错误-错误的原因是object
类型默认情况下只是一个空对象。因此,不可能使用string
类型来索引{}
。
更好-错误消失的原因是因为现在我们告诉编译器obj
参数将是字符串/值(string/any
)对的集合。但是,我们使用的是any
类型,所以我们可以做得更好。
最佳-T
扩展空对象。 U
扩展了T
的键。因此U
将始终存在于T
上,因此可以用作查找值。
以下是完整示例:
我已更改了泛型的顺序(U extends keyof T
现在位于T extends object
之前),以强调泛型的顺序并不重要,您应该选择对您的功能最有意义的顺序。
const getKeyValue = <U extends keyof T, T extends object>(key: U) => (obj: T) =>
obj[key];
interface User {
name: string;
age: number;
}
const user: User = {
name: "John Smith",
age: 20
};
const getUserName = getKeyValue<keyof User, User>("name")(user);
// => 'John Smith'
答案 2 :(得分:5)
如果这是一个脚的javascript对象,没有必要为每个字段创建类型定义,并且也没有类定义的含义,则可以使用any
键入对象,而typescript会让您随便索引。
例如。
//obviously no one with two brain cells is going to type each field individually
let complicatedObject: any = {
attr1: 0,
attr2: 0,
...
attr999: 0
}
Object.keys(complicatedObject).forEach(key => {
complicatedObject[key] += 1;
}
答案 3 :(得分:4)
首先,将 items
的类型定义为 objects
的数组是一个坏主意,因为它违背了 Typescript 的目的。而是定义数组将包含什么类型的对象。我会这样做:
type Item = {
id: number,
name: string,
email: string,
}
export type TableGridViewProps = {
items: Item[],
tableColumns: TableColumn[]
};
之后,如果您绝对确定 key
将存在于 item
中,您可以执行以下操作来告诉 Typescript 您正在访问一个有效的索引。
<td
key={column.key}
className="lorem ipsum"
>
{item[column.key as keyof typeof Item]}
</td>
答案 4 :(得分:0)
尝试更改:
items={[
{}
]}
收件人:
items=[
{}
]
这是假定的输出吗?
1
John Doe
2
Lorem ipsum
我明白了。
答案 5 :(得分:-2)
尝试添加类型any []
items:any[]