为什么我收到“类型 'String[] | undefined' 不是数组类型。” 对于我的对象变量?

IT技术 javascript reactjs typescript react-state react-typescript
2021-05-17 00:25:22

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

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

我不断收到此错误:

输入'字符串[] | undefined' 不是数组类型。

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

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

这是错误:

类型 '(String | { dict: Map<string, string>; })[]' 不能分配给类型 'String[]'。输入'字符串| { 字典:地图<字符串,字符串>;}' 不可分配给类型 'String'。输入 '{ dict: Map<string, string>; }' 不可分配给类型 'String'。对象字面量只能指定已知属性,而“字符串”类型中不存在“dict”。

2个回答

声明hidden?: Array<String>,意味着该属性可以是Array<String>OR 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 ?? [])

如果您仔细阅读创建“隐藏”数组的代码,

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

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

这意味着您的数组将包含具有与此接口相关的“dict”属性的对象:{dict:Map<string,string>}这就是为什么您会收到关于此对象的奇怪错误消息,该对象的 dict 属性在类型字符串中不存在(显然,数组中的项目不是字符串)

你可以做的是:

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

然后将您的数组键入为 Array <MyInterface>

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

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

     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) 。如果不是,那是什么在这里使用地图的重点是什么?