Amir-Mousavi
Amir-Mousavi

Reputation: 4563

destruct attribute from object in typescript

In my react application with typescript I am using semantic-ui-react for UI. this snabdobx shows the usage of Menu.Item in javascript but I wan to use it in typescript and got confused.

<Menu.Item  name="home"  active={activeItem === 'home'}
      onClick={this.handleItemClick}>

public handleItemClick = (
    e: React.MouseEvent<HTMLAnchorElement>,
    {name} // Here I ahve problem with typings to destruct the name
  ) => {
    this.setState({ activeItem: name });
  };

the types in the MenuItem.d.ts are

export interface MenuItemProps extends StrictMenuItemProps {[key: string]: any}

export interface StrictMenuItemProps {
  /*many other values */
  /** Internal name of the MenuItem. */
  name?: string

  onClick?: (event: React.MouseEvent<HTMLAnchorElement>, data: MenuItemProps) => void
}

here {name}:{name:string} does not work. and geting whole data the I can not setState with data.name

Upvotes: 0

Views: 761

Answers (2)

Przemyslaw Jan Beigert
Przemyslaw Jan Beigert

Reputation: 2486

typing like this means ({ name }) that argument name is any type, so it will not throw error.

to pass string e.g. "messages" to handleItemClick you should do something like this:

 handleItemClick = (name: string) => () => this.setState({ activeItem: name })
...
<Menu.Item
    name='messages'
    active={activeItem === 'messages'}
    onClick={this.handleItemClick('message')}
/>

As you can see in TS error message, second argument of Menu.click callback is MouseEvent not a {name: string}

btw: to be more type safe you can turn on strictFunctionTypes flag in compilerOptions in tsconfig.json file

---- Edited -----

I think i got your point. Please forgot previous part:

Menu.Item.onClick is already typed by @types lib in StrictMenuItemProps interface. To get onClick type you can use this syntax StrictMenuItemProps['onClick'] thats is equal to onClick?: (event: React.MouseEvent<HTMLAnchorElement>, data: MenuItemProps) => void but you can use it without copy code form lib.

So instead typing public handleItemClick by (arg1: Type1, arg2: Type2): Result { ... you can type it by public handleItemClick: StrictMenuItemProps['onClick'] = (e, {name}) => setState.

TS will match function's argument types to argument so e and name will not be any type

Example

Upvotes: 2

Amir-Mousavi
Amir-Mousavi

Reputation: 4563

so it seems it does not matter that the name it self is of type string the whole object is of type MenuItemProps

therefore the following solved the issue

  public handleItemClick = (
    e: React.MouseEvent<HTMLAnchorElement>,
    { name }: MenuItemProps
  ) => {
    this.setState({ activeItem: name! });
  };

Upvotes: 0

Related Questions