简体   繁体   English

带有Typescript的ReactJS不接受带有属性的对象

[英]ReactJS with Typescript not accepting Object with properties

I am trying to apply TypeScript in my ReactJS project.我正在尝试在我的 ReactJS 项目中应用 TypeScript。 I am starting apply it to one of my components but somehow I am having hard time applying typescript when a components accepts object with properties as its props.我开始将它应用于我的一个组件,但不知何故,当组件接受具有属性的对象作为其道具时,我很难应用打字稿。

Here is my code这是我的代码

interface iValue {
 results: string[] | number[];
}

interface DropDownInputInt {
 name: string;
 value: iValue | string;
 multiple: boolean;
}

const DropDownInput = ({
 name,
 value,
 multiple
}: DropDownInputInt) => {

 return (
  <> 
   <Dropdown
     name={name}
     value={multiple && value
           ? value.hasOwnProperty('results')
              ? value.results
              : value
           : value
          }

    />
  </>
 )
})

For my props named "value" I am accepting 2 possible inputs, string or an object(with 'results' key and can have both an array string or number)对于名为“value”的道具,我接受 2 个可能的输入,字符串或对象(带有 'results' 键并且可以同时具有数组字符串或数字)

在此处输入图片说明

See image below for a sample of props.value that has a string value.有关具有字符串值的 props.value 示例,请参见下图。

在此处输入图片说明

Not sure why but currently my VSCode is showing errors when I tried to use value.results.不知道为什么,但目前我的 VSCode 在我尝试使用 value.results 时显示错误。 See image below for the error.有关错误,请参见下图。

在此处输入图片说明

UPDATE更新

I tried to incopmperate some answers from我试图从

interface iValue {
 results: (string | number | boolean)[];
}

interface DropDownInputInt {
 name: string;
 value: iValue | boolean | number | string;
 multiple: boolean;
}

const DropDownInput = ({
 name,
 value,
 multiple
}: DropDownInputInt) => {

return (
 <> 
   <Dropdown
     name={name}
      value={
      multiple && value
        ? typeof value === 'string' ||
          typeof value === 'number' ||
          typeof value === 'boolean'
          ? value
          : value.results
        : typeof value === 'object' && value
    }
    />
   </>
   )
 })

But I am still getting errors, now its pointing to value property in my Dropdown但是我仍然遇到错误,现在它指向我的下拉列表中的 value 属性

在此处输入图片说明

But when I check the property that being accepted by the "Dropdown" component但是当我检查“下拉”组件接受的属性时

在此处输入图片说明

Thanks in advance提前致谢

value can be string or object, when it is a string it still has hasOwnProperty because of boxing. value可以是字符串或对象,当它是一个字符串时,由于装箱,它仍然具有hasOwnProperty Potentially it might have results field and fit iValue type, in practice you cannot assign a property to primitive string but TS does not take it into account.可能它可能有results字段并适合iValue类型,实际上您不能将属性分配给原始字符串,但 TS 不会考虑它。

More predictable check is needed, for example需要更多可预测的检查,例如

value={multiple && value
  ? typeof value === "object" && value.hasOwnProperty('results')
    ? value.results
    : value
  : value

or it could be reversed或者它可以逆转

value={multiple && value
  ? typeof value === "string"
    ? value
    : value.results
  : value

I think I solve it using.我想我解决它使用。 Thank you @Shlang for point out the problem谢谢@Shlang 指出问题

interface iValue {
 results: (string | number | boolean)[];
}

interface DropDownInputInt {
 name: string;
 value: iValue | boolean | number | string;
 multiple: boolean;
}

const DropDownInput = ({
 name,
 value,
 multiple
}: DropDownInputInt) => {

return (
 <> 
   <Dropdown
     name={name}
      value={
      multiple && value
        ? typeof value === 'string' ||
          typeof value === 'number' ||
          typeof value === 'boolean'
          ? value
          : value.results
        : typeof value === 'object' && value
    }
    />
   </>
   )
 })

TS is not smart enough to figure this out on its own (ie to figure out that it's not a string, but an iValue) so you need to help it out using a type guard , eg TS 不够聪明,无法自行解决(即找出它不是字符串,而是 iValue),因此您需要使用类型保护来帮助它,例如

    function isIValue(value: string | iValue): value is iValue {
      return typeof value !== "string"
    }

The value is iValue annotation essentially tells the Typescript type system that if the function returns true, the argument is of type iValue . value is iValue注释本质上告诉 Typescript 类型系统,如果函数返回 true,则参数的类型为iValue

Hence you can then do:因此,您可以执行以下操作:

   <Dropdown
     name={name}
     value={(multiple && isIValue(value) && value.results) || value}
    />

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM