类型“数字[]”缺少类型“ [数字,数字,数字,数字]”的以下属性:0、1、2、3

时间:2019-02-23 05:41:07

标签: javascript reactjs typescript

type padding = [number, number, number, number]

interface IPaddingProps {
  defaultValue?: padding
  className?: string
  disabled?: boolean
  min?: number
  max?: number
  onChange?: (value: number | string) => void
}
interface IFieldSate {
  value: padding
}
export default class FieldPadding extends React.Component<IPaddingProps, IFieldSate> {

  readonly state = {
    value: [0, 0, 0, 0]
  }
  constructor(props: IPaddingProps) {
    super(props)
    if (props.defaultValue) {
      this.state.value = [...props.defaultValue]
    }
  }

}

我在state收到一条错误消息:

  

类型'数字[]'缺少类型[数字,数字,数字,数字]中的以下属性:0、1、2、3?

2 个答案:

答案 0 :(得分:1)

您可以编写type padding = number[]type padding = Array<number>

,而不是将value的类型写为具有4个number类型的元素的数组。
type padding = number[]

interface IPaddingProps {
  defaultValue?: padding
  className?: string
  disabled?: boolean
  min?: number
  max?: number
  onChange?: (value: number | string) => void
}
interface IFieldSate {
  value: padding
}
export default class FieldPadding extends React.Component<IPaddingProps, IFieldSate> {

  readonly state = {
    value: [0, 0, 0, 0]
  }
}

答案 1 :(得分:1)

您的问题是,state被推断为数组而不是tuple。有多种解决方法,如this answer中所述。我这里只介绍其中之一。

假设您使用的是TypeScript 3.0或更高版本,则可以定义以下tuple()帮助函数,该函数接受任意数量的参数并返回这些参数的元组:

type Narrowable = string | number | boolean | undefined | null | void | {};
const tuple = <T extends Narrowable[]>(...t: T)=> t;

然后,您可以在FieldPadding类定义中使用它:

export default class FieldPadding extends React.Component<IPaddingProps, IFieldSate> {
  readonly state = {
    value: tuple(0, 0, 0, 0) 
  }
}

赋予value类型[0, 0, 0, 0],这是一个具有四个元素的元组类型,numeric literal类型为0


更新:

因此您想将state设为readonly,但又想将state.value的值从0更改为其他数字? ‍

在这种情况下,您希望value键入[number, number, number, number],它比[0, 0, 0, 0]宽但比number[]窄。您可以自己注释,如果您希望对类型进行严格控制,建议您这样做:

export default class FieldPadding extends React.Component<IPaddingProps, IFieldSate> {
  readonly state = {
    value: [number, number, number, number] = [0, 0, 0, 0]
  }
}

您也可以这样做

export default class FieldPadding extends React.Component<IPaddingProps, IFieldSate> {
  readonly state = {
    value: tuple(0 as number, 0 as number, 0 as number, 0 as number) 
  }
}

const z: number = 0;
export default class FieldPadding extends React.Component<IPaddingProps, IFieldSate> {
  readonly state = {
    value: tuple(z, z, z, z)
  }
}

甚至缩小收窄范围tuple()

const wideTuple = <T extends any[]>(...t: T) => t;
export default class FieldPadding extends React.Component<IPaddingProps, IFieldSate> {
  readonly state = {
    value: wideTuple(0, 0, 0, 0) 
  }
}

其中任何一个都应该为您工作。不过,对于所提问题的简短回答是,您需要一个元组类型,而不是数组。究竟如何获得取决于您自己。


希望有所帮助;祝你好运!