2

I have a burger menu, which will receive two props: 1) isOpen, and 2) a file object { name, type, size, modifiedAt, downloadUrl }

I'm trying to do something like this, but Typescript is complaining

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

This is the error:

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; }; }'.

I'm wondering if I define a File type and cast the file attribute of the burger state as that that it would work?

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

However I'm not sure how to do that

1 Answer 1

3

You could go with something like this:

Define a type for a "file" property in your component state.

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

All properties are marked as optional.

In your component function specify a type for the "file" property

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

We can set file property to be empty object as all properties are optional and ts will not complain. But this means name, size and other properties will be undefined (not "null" as you wrote). If you need them to be "null" you will need to modify the TFile type

You could go with a alternate syntax and write

 file:<TFile>{}

but unfortunately inside a tsx file you can only use "as TFile" syntax.

after this typescript should not complain when you set the state in your click handler:

setBurger({isOpen:false, file: {
                    name: "HR STUFF",
                    modifiedAt: "01/03/2019",
                    size: 40,
                    type: "folder",
                    downloadUrl: "www.google.com"
                  }}) -->>should be ok 
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.