[英]Why am I getting “Type 'String[] | undefined' is not an array type.” for my object variable?
I am trying to create a state variable named hidden
to be a dictionary (ex: [{'cutomkey1':'somevalue', 'customkey2':'somevalue'}]
).我正在尝试创建一个名为
hidden
的 state 变量作为字典(例如: [{'cutomkey1':'somevalue', 'customkey2':'somevalue'}]
)。 hidden can be empty [{}]
. hidden 可以为空
[{}]
。
In one of my methods I want to push an item {'asd':'asd'}
to the hidden state variable and add them up.在我的一种方法中,我想将一个项目
{'asd':'asd'}
推送到隐藏的 state 变量并将它们相加。
I keep getiting this error:我不断收到此错误:
Type 'String[] |
键入'字符串 [] | undefined' is not an array type.
undefined' 不是数组类型。
I'm new to typescript and I am not sure i set all the variables correctly.我是 typescript 的新手,我不确定我是否正确设置了所有变量。 this is my code (only the relevant parts):
这是我的代码(仅相关部分):
import React from 'react';
export type AppState = {
tickets?: Ticket[],
hidden?: Array<String>,
search: string;
}
export class App extends React.PureComponent<{}, AppState> {
state: AppState = {
search: '',
hidden: []
}
hideCard = (e: React.SyntheticEvent<EventTarget>) => {
let targ = e.target as HTMLElement
let parent = targ.parentElement as HTMLElement
let dict: Map<string, string> = new Map();
dict.set(parent.id, parent.id)
this.setState({
hidden: [...this.state.hidden, {dict}]
})
console.log(this.state.hidden)
parent.classList.add('hideTkt')
}
}
export default App;
new code:新代码:
export type AppState = {
tickets?: Ticket[],
hidden?: Array<String> | undefined,
search: string;
}
export class App extends React.PureComponent<{}, AppState> {
state: AppState = {
search: '',
hidden: []
}
hideCard = (e: React.SyntheticEvent<EventTarget>) => {
let targ = e.target as HTMLElement
let parent = targ.parentElement as HTMLElement
let dict: Map<string, string> = new Map();
dict.set(parent.id, parent.id)
if (this.state.hidden) {
this.setState({
hidden: [...this.state.hidden, {dict}]
})
}
console.log(this.state.hidden)
parent.classList.add('hideTkt')
}
this is the error:这是错误:
Type '(String | { dict: Map<string, string>; })[]' is not assignable to type 'String[]'.
类型 '(String | { dict: Map<string, string>; })[]' 不可分配给类型 'String[]'。 Type 'String |
键入'字符串 | { dict: Map<string, string>;
{ 字典:地图<字符串,字符串>; }' is not assignable to type 'String'.
}' 不可分配给类型 'String'。 Type '{ dict: Map<string, string>;
输入 '{ dict: Map<string, string>; }' is not assignable to type 'String'.
}' 不可分配给类型 'String'。 Object literal may only specify known properties, and 'dict' does not exist in type 'String'.
Object 文字只能指定已知属性,并且“字符串”类型中不存在“字典”。
The declaration hidden?: Array<String>,
means that the property could either be a Array<String>
OR undefined
.声明
hidden?: Array<String>,
意味着该属性可以是Array<String>
或undefined
。
Using the property like this will fail:使用这样的属性将失败:
hidden.push(item)
because hidden
could be undefined
(and undefined
has no property push
).因为
hidden
可能是undefined
的(并且undefined
没有属性push
)。
If you check if this.state.hidden
is available, typescript won't complain anymore:如果您检查
this.state.hidden
是否可用,typescript 将不再抱怨:
if(this.state.hidden)
this.setState({
hidden: [...this.state.hidden, {dict}]
})
or you can provide a default value using nullish concealing:或者您可以使用无效隐藏提供默认值:
...(this.state.hidden ?? [])
If you read attentively the code that creates your 'hidden' array,如果您仔细阅读创建“隐藏”数组的代码,
if (this.state.hidden) {
this.setState({
hidden: [...this.state.hidden, {dict}]
})
}
you can see that you spread the state.hidden elements (no pb with those, they already are of the correct type, any type, we don't matter,as they are coming from a previous well typed and built array ),but, then you add a litteral object who has a property called dict, of type Map<string, string>
.你可以看到你传播了 state.hidden 元素(没有 pb ,它们已经是正确的类型,任何类型,我们都没有关系,因为它们来自以前的良好类型和构建的数组),但是,然后你添加一个乱七八糟的 object ,它有一个名为 dict 的属性,类型为
Map<string, string>
。
This means your array will contain objects that have a "dict" property respecting this interface: {dict:Map<string,string>}
.这意味着您的数组将包含具有尊重此接口的“dict”属性的对象:
{dict:Map<string,string>}
。 This is why you have this strange error message about this object litteral with a dict property which does not exist on type string (obviously, the items in your array are not strings)这就是为什么你有这个关于这个 object litteral 的奇怪错误消息的原因,它的 dict 属性在类型 string 上不存在(显然,你的数组中的项目不是字符串)
What you can do is:你可以做的是:
Array<{dict:Map<string,string>}>
.Array<{dict:Map<string,string>}>
。Map<string,string>
inside your array when building it ( hidden: [...this.state.hidden,...dict]
), which will leads you to have an Array<Record<string,string>>
( Record<K,V>
being the type of each key value pair item you have in your Map)Map<string,string>
的内容传播到数组中( hidden: [...this.state.hidden,...dict]
),这将导致您拥有一个Array<Record<string,string>>
( Record<K,V>
是您在 Map 中拥有的每个键值对项的类型) interface MyInterface
{
dict:Map<string,string>;
}
then type your array as Array <MyInterface>
然后将您的数组键入为
Array <MyInterface>
Array.from(dict.entries())
méthod to get an array of tuples ( [key:string,value:string]
), then use the array map operator to transform your entries into something that feets your needs better in this situation (maybe the string you wanted in the first place) by concatening the key and the value of each tuple item (or anything else that gives you a unique string).Array.from(dict.entries())
方法获取元组数组( [key:string,value:string]
),然后使用数组 map 运算符将您的条目转换为更符合您需求的内容通过连接每个元组项的键和值(或任何其他为您提供唯一字符串的任何内容)来解决情况(可能是您首先想要的字符串)。 In another way, if you just keep the array that you get from "Array.from", you will have the kind of structure you want (an array of keyValue Pair tuples) There are lots of other options, but those are the main tracks you can follow.还有很多其他选项,但这些是您可以遵循的主要轨道。 And, at the end, if you really want your "hidden" state variable to be a dictionary,type it as a Map<string,string> from the beginning, and when you reaffect-it, just do
最后,如果您真的希望您的“隐藏” state 变量成为字典,请从头开始将其键入为 Map<string,string> ,当您重新影响它时,只需执行
if (this.state.hidden) {
this.setState({
hidden: new Map([...Array.from(this.state.hidden.entries()), ...Array.from(dict.entries())])
})
}
You don't have to do all this gym if you target ES6, as this will work:如果您以 ES6 为目标,则不必做所有这些练习,因为这将起作用:
if (this.state.hidden) {
this.setState({
hidden: new Map([...this.state.hidden, ...dict])
})
}
And, BTW, I think when you set the objects in your Map, you want to do dict.set(target.id, parent.id) instead of dict.set(parent.id, parent.id).If not, what's the point of using a Map here?而且,顺便说一句,我认为当您在 Map 中设置对象时,您想做 dict.set(target.id, parent.id) 而不是 dict.set(parent.id, parent.id)。如果不是,那是什么在这里使用 Map 的意义何在?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.