为什么我的对象变量得到 "Type 'String[] | undefined' is not an array type."?

Why am I getting "Type 'String[] | undefined' is not an array type." for my object variable?

我正在尝试创建一个名为 hidden 的状态变量作为字典(例如:[{'cutomkey1':'somevalue', 'customkey2':'somevalue'}])。 hidden 可以为空 [{}].

在我的一种方法中,我想将一个项目 {'asd':'asd'} 推送到隐藏状态变量并将它们相加。

我一直收到这个错误:

Type 'String[] | undefined' is not an array type.

我是打字稿的新手,我不确定我是否正确设置了所有变量。这是我的代码(只有相关部分):

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;

新代码:

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')
    }

这是错误:

Type '(String | { dict: Map<string, string>; })[]' is not assignable to type 'String[]'. Type 'String | { dict: Map<string, string>; }' is not assignable to type 'String'. Type '{ dict: Map<string, string>; }' is not assignable to type 'String'. Object literal may only specify known properties, and 'dict' does not exist in type 'String'.

声明 hidden?: Array<String>, 意味着 属性 可以是 Array<String>undefined.

像这样使用属性会失败:

hidden.push(item)

因为 hidden 可能是 undefined(而 undefined 没有 属性 push)。

如果您检查 this.state.hidden 是否可用,typescript 将不再报错:

if(this.state.hidden)
  this.setState({
              hidden: [...this.state.hidden, {dict}]
          })

或者您可以使用无效隐藏提供默认值:

...(this.state.hidden ?? [])

如果您仔细阅读创建 'hidden' 数组的代码,

     if (this.state.hidden) {
            this.setState({
                hidden: [...this.state.hidden, {dict}]
            })
        }

你可以看到你传播了 state.hidden 元素(没有 pb 与那些,它们已经是正确的类型,任何类型,我们不重要,因为它们来自以前的良好类型和构建数组),但是,然后你添加一个垃圾对象,它有一个名为 dict 的 属性 ,类型为 Map<string, string>.

这意味着您的数组将包含具有“字典”的对象 属性 遵守此接口 :{dict:Map<string,string>} 。 这就是为什么你有关于这个对象的奇怪错误消息,其中包含一个字典 属性,它在类型字符串上不存在(显然,你的数组中的项目不是字符串)

您可以做的是:

  1. 类型隐藏为 Array<{dict:Map<string,string>}>
  2. 在构建数组时将 Map<string,string> 的内容分散到数组中 (hidden : [...this.state.hidden,...dict]) ,这将导致您有一个 Array<Record<string,string>>Record<K,V> 是您地图中每个键值对项目的类型)
  3. 创建一个界面,如:
    interface MyInterface
     { 
      dict:Map<string,string>;
    }

然后将数组键入 Array <MyInterface>

  1. 使用 Array.from(dict.entries()) 方法获取元组数组 ([key:string,value:string]),然后使用数组映射运算符将您的条目转换为在这种情况下更好地满足您需求的内容(也许是你首先想要的字符串)通过连接每个元组项的键和值(或任何其他给你一个唯一字符串的东西)。换句话说,如果您只保留从 "Array.from" 获得的数组,您将拥有所需的结构(键值对元组数组)

还有很多其他选项,但这些是您可以遵循的主要路线。 而且,最后,如果你真的希望你的“隐藏”状态变量是一个字典,从一开始就把它键入一个 Map ,当你重新影响它时,只需做

     if (this.state.hidden) {
            this.setState({
                hidden: new Map([...Array.from(this.state.hidden.entries()), ...Array.from(dict.entries())])
            })
        }

如果您以 ES6 为目标,则不必做所有这些运动,因为这会起作用:

     if (this.state.hidden) {
            this.setState({
                hidden: new Map([...this.state.hidden, ...dict])
            })
        }

而且,顺便说一句,我认为当您在 Map 中设置对象时,您想做 dict.set(target.id, parent.id) 而不是 dict.set( parent.id, parent.id) 。如果不是,在这里使用地图有什么意义?