用typescript反应useState来设置嵌套的类型化对象

时间:2019-04-16 19:51:15

标签: typescript

我有一个汉堡菜单,它将收到两个道具:1)isOpen和2)文件对象{ name, type, size, modifiedAt, downloadUrl }

我正在尝试做这样的事情,但是Typescript在抱怨

const FileManagerSlide = () => {
  const [burger, setBurger] = useState({
    isOpen: false,
    file: {
      name: null,
      modifiedAt: null,
      size: null,
      type: null,
      downloadUrl: null
    }
  });


  ...

                  <Tr
                  onClick={() =>
                    setBurger({
                      isOpen: true,
                      file: {
                        name: "HR STUFF",
                        modifiedAt: "01/03/2019",
                        size: 40,
                        type: "folder",
                        downloadUrl: "www.google.com"
                      }
                    })
                  }
                >

这是错误:

ERROR in [at-loader] ./src/components/file-manager/file-manager-slide.tsx:287:31
    TS2345: Argument of type '{ isOpen: true; file: { name: string; modifiedAt: string; size: number; type: string; downloadUrl...' is not assignable to parameter of type 'SetStateAction<{ isOpen: boolean; file: { name: null; modifiedAt: null; size: null; type: null; d...'.
  Type '{ isOpen: true; file: { name: string; modifiedAt: string; size: number; type: string; downloadUrl...' is not assignable to type '(prevState: { isOpen: boolean; file: { name: null; modifiedAt: null; size: null; type: null; down...'.
    Type '{ isOpen: true; file: { name: string; modifiedAt: string; size: number; type: string; downloadUrl...' provides no match for the signature '(prevState: { isOpen: boolean; file: { name: null; modifiedAt: null; size: null; type: null; downloadUrl: null; }; }): { isOpen: boolean; file: { name: null; modifiedAt: null; size: null; type: null; downloadUrl: null; }; }'.

我想知道是否定义一种File类型并强制转换burger状态的file属性,使其可以正常工作?

interface File {
  name: string;
  modifiedAt: string;
  size: number;
  type: string;
  downloadUrl: string;
}

但是我不确定该怎么做

1 个答案:

答案 0 :(得分:1)

您可以使用类似这样的内容:

在组件状态下为“文件”属性定义类型。

type TFile={
   name?:string,
   modifiedAt?:string,
   size?:number,
   type?:string,
   downloadUrl?:string
 }

所有属性都标记为可选。

在您的组件函数中,为“文件”属性指定一种类型

const [burger,setBurger]=React.useState({
    isOpen:false,
    file:{} as TFile
  })

我们可以将文件属性设置为空对象,因为所有属性都是可选的,ts不会抱怨。但这意味着名称,大小和其他属性将是未定义的(如您所写,不是“ null”)。如果您需要将它们设为“ null”,则需要修改TFile类型

您可以使用其他语法编写

 file:<TFile>{}

但不幸的是,在tsx文件中,您只能使用“作为TFile”语法。

在您在点击处理程序中设置状态后,此打字稿后不应抱怨:

setBurger({isOpen:false, file: {
                    name: "HR STUFF",
                    modifiedAt: "01/03/2019",
                    size: 40,
                    type: "folder",
                    downloadUrl: "www.google.com"
                  }}) -->>should be ok