#reactjs #typescript #typescript-typings #react-tsx
#reactjs #typescript #typescript-типизации #реагировать-tsx
Вопрос:
В моем приложении react с typescript я использую semantic-ui-react
для пользовательского интерфейса. этот snabdobx показывает использование Menu.Item
в javascript, но я хотел использовать его в typescript и запутался.
<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 });
};
типы в MenuItem.d.ts
являются
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
}
здесь {name}:{name:string}
не работает. и получить целые данные, с помощью которых я не могу установить состояние data.name
Комментарии:
1.
{name}:{name:string}
Выдает ли какие-либо ошибки компиляции?2. Да, это приводит к
Type '(e: MouseEvent<HTMLAnchorElement, MouseEvent>, { name }: { name: string; }) => void' is not assignable to type '(event: MouseEvent<HTMLAnchorElement, MouseEvent>, data: MenuItemProps) => void'.
@PrzemyslawPietrzak3. что-то не так с моим ответом?
Ответ №1:
такой ввод означает, что ({ name })
этот аргумент name
является any
типом, поэтому он не выдаст ошибку.
чтобы передать строку, например, «messages» в handleItemClick
, вы должны сделать что-то вроде этого:
handleItemClick = (name: string) => () => this.setState({ activeItem: name })
...
<Menu.Item
name='messages'
active={activeItem === 'messages'}
onClick={this.handleItemClick('message')}
/>
Как вы можете видеть в сообщении об ошибке TS, второй аргумент обратного вызова Menu.click MouseEvent
не является {name: string}
кстати: для большей безопасности при вводе текста вы можете включить strictFunctionTypes
флаг в compilerOptions
в tsconfig.json
файле
—- Отредактировано ——
Думаю, я понял вашу точку зрения. Пожалуйста, забыли предыдущую часть:
Menu.Item.onClick
уже набран с помощью @types lib в StrictMenuItemProps
интерфейсе. Чтобы получить onClick
тип, вы можете использовать этот синтаксис, StrictMenuItemProps['onClick']
который равен onClick?: (event: React.MouseEvent<HTMLAnchorElement>, data: MenuItemProps) => void
, но вы можете использовать его без копирования кода из библиотеки.
Таким образом, вместо ввода public handleItemClick
by (arg1: Type1, arg2: Type2): Result { ...
вы можете ввести его с помощью public handleItemClick: StrictMenuItemProps['onClick'] = (e, {name}) => setState
.
TS будет сопоставлять типы аргументов функции с аргументом so e
и name
не будет any
типом
class X {
attr: T[‘cb’] = arg => arg + 1;
attr = arg => arg + 1;
}
» rel=»nofollow noreferrer»>Пример
Комментарии:
1. извините, это не то, что я ищу, это больше похоже на взлом. 1. почему я должен передавать строку, где она уже передана вложенной в data. 2. Я искал тип имени для получения destruct 3.it это не тот подход, о котором говорится в официальных документах
2. Также я думаю, что вы неправильно прочитали мой комментарий, исправляющий ошибку компилятора, о которой вы упомянули »
second argument of Menu.click callback is MouseEvent not a {name: string}
3. Думаю, теперь я вас понял, пожалуйста, проверьте отредактированную часть
4. @Amir-Mousavi это то решение, которое вы ищете?
5. На самом деле, прежде чем вы отправите отредактированную версию ответа, я разобрался с этим и опубликовал в качестве ответа, но ваш подход выглядит неплохо, пока не было времени протестировать его и проверить, является ли это более выгодным или нет, но спасибо за это, через несколько дней вернувшись к этому проекту, протестирую и приму ваш ответ, если он покажется более удобным
Ответ №2:
таким образом, кажется, что не имеет значения, что само имя имеет тип string
весь объект имеет тип MenuItemProps
поэтому проблема была решена следующим образом
public handleItemClick = (
e: React.MouseEvent<HTMLAnchorElement>,
{ name }: MenuItemProps
) => {
this.setState({ activeItem: name! });
};