#reactjs #typescript
Вопрос:
Имея такую реализацию
// CustomComponent.ts
type SaveProps = {
date: string;
name: string;
}
interface IProps {
onSave: (props: SaveProps) => void;
}
const CustomComponent = ({onSave}: IProps) => {
return (
<button onClick={() => onSave({ date: '', name: '' })}>
Click me
</button>
);
};
// ParentComponent.ts
import CustomComponent from './CustomComponent';
export default function ParentComponent () {
const saveData = props => { // what type is props? how to infer this as SaveProps defined in CustomComponent.ts?
}
return (
<CustomComponent onSave={saveData} />
)
}
Как я могу определить тип реквизита в сохраненных данных как реквизит, не импортируя его тип? Чтобы при чтении реквизитов в обратном вызове SaveData я автоматически знал, какие данные отправляет пользовательский компонент.
Ответ №1:
В большинстве случаев лучше экспортировать Props
тип вместе с компонентом. В вашем конкретном случае вы можете сделать следующее:
import { IProps, CustomComponent } from './CustomComponent';
function ParentComponent () {
const saveData = React.useCallback((props => {
}) as IProps['onSave'], []);
return (
<CustomComponent onSave={saveData} />
)
}
Комментарии:
1. да, импорт действительно заключает сделку, но разве нет другого элегантного решения? 🙂
2. Я буду придерживаться этого
Ответ №2:
Извините за еще один ответ. Комментарии ограничены максимальной длиной.
https://www.typescriptlang.org/docs/handbook/type-inference.html#contextual-typing
TS достаточно умен, чтобы выводить типы в разных направлениях, и им управляет множество эвристических алгоритмов. Вот почему мы не можем реорганизовать ваш пример в соответствии с каким-либо общим набором правил (такого нет).
Еще один трюк без явного экспорта Props
:
(props => {
}) as Parameters<typeof CustomComponent>[0]['onSave']
Комментарии:
1. хм, да, это тоже путь, но гораздо более громоздкий, чем «импортный»…