Я новичок в машинописном тексте, и я пытаюсь создать компонент ввода, который, если он получает type = "text", отображает input, а если он получает type = "textarea", он отображает, вы его получили, textarea. Проблема в том, что машинописный текст жалуется, когда я использую компонент в своем коде вместе с onChange, кажется, это не позволяет мне использовать два типа в одном и том же событии?
Он показывает мне:
Type '(e: ChangeEvent<HTMLInputElement>) => void' is not assignable to type '(e?: ChangeEvent<HTMLInputElement> | ChangeEvent<HTMLTextAreaElement> | undefined) => void'.
Types of parameters 'e' and 'e' are incompatible.
Type 'ChangeEvent<HTMLInputElement> | ChangeEvent<HTMLTextAreaElement> | undefined' is not assignable to type 'ChangeEvent<HTMLInputElement>'.
Type 'undefined' is not assignable to type 'ChangeEvent<HTMLInputElement>'.
input.js
interface InputProps {
className?: string;
type?: string;
placeholder?: string;
onChange?: (e?: React.ChangeEvent<HTMLInputElement> | React.ChangeEvent<HTMLTextAreaElement>) => void;
}
const Input: FunctionComponent<InputProps> = ({ type = 'text', ...props }) => {
if (type === 'textarea') {
return <textarea {...props} />;
}
return <input type = {type} {...props} />;
};
использование:
class Usage extends React.Component<State> {
state: State;
onInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
this.setState({ input: e.target.value });
};
render() {
return (
<Input placeholder = "Write an something..." onChange = {this.onInputChange} />
);
}
}
Как я могу это исправить?
ОБНОВИТЬ
На данный момент я решил это, сказав, что событие может иметь тип any, но это своего рода взлом
type CommonProps = {
className?: string;
placeholder?: string;
type?: string;
onChange?: (e: any) => void;
};
@barnski typescript - v3.2.1 / @ types / react - v16.7.6





Вам нужно создать класс, если вы используете машинописный текст.
Обычная функция не позволяет использовать | в типах опор машинописного текста.
Это должен быть ваш файл Input.js:
export interface IInputProps {
className?: string;
type?: string;
placeholder?: string;
onChange?: (e?: React.ChangeEvent<HTMLInputElement> | React.ChangeEvent<HTMLTextAreaElement>) => void;
}
export class Input extends React.Component<IInputProps, {}> {
constructor(props: IInputProps) {
super(props);
}
render() {
const { props, props: { type } } = this;
if (type === 'textarea') {
return <textarea {...props} />;
}
return <input type = {type} {...props} />;
}
}
и вот как это можно использовать:
class Usage extends React.Component<State> {
state: State;
onInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
this.setState({ input: e.target.value });
};
render() {
return (
<Input placeholder = "Write an something..." onChange = {this.onInputChange} />
);
}
}
Вот как он будет оценивать, является ли это Input или TextArea:
Хм .. каково ваше определение IInputProps? В коде, который вы предоставляете, такая же ошибка в Usage.
TypeScript V3.2.2
ваш код работает с strict:false, но код OP также работал бы со строгим выключением ... Я предполагаю, что strictFunctionTypes вызывает ошибку при назначении onChange
Вы можете использовать размеченное объединение для передачи двух типов аргументов: одного для text, а другого для textarea. Это дает дополнительный бонус в виде обеспечения синхронизации обработчика и типа.
type InputProps = { // The common Part
className?: string;
placeholder?: string;
} & ({ // The discriminated union
type?: "text";
onChange?: (e: React.ChangeEvent<HTMLInputElement>) => void;
} | {
type: "textarea";
onChange?: (e: React.ChangeEvent<HTMLTextAreaElement>) => void;
})
const Input: FunctionComponent<InputProps> = (props: InputProps) => {
if (props.type === 'textarea') {
return <textarea {...props} />;
}
return <input {...props} />;
};
class Usage extends React.Component<State> {
state: State;
onInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
this.setState({ input: e.target.value });
};
render() {
return (
<Input placeholder = "Write an something..." onChange = {this.onInputChange} />
);
}
}
Слишком долго, пришлось добавить в качестве ответа
У меня работает: github.com/dragomirtitian/so-answers/tree/so-53943737
Это сработало с некоторыми корректировками. Он терпит неудачу всякий раз, когда я пытаюсь разрушить реквизит. Спасибо!
@JCQuintas, да, нарушение структуры не будет работать должным образом из-за союза ... поэтому я удалил его. (Удалите ответ с ошибкой, иначе он получит отрицательное голосование по уважительной причине)
Не могли бы вы вставить свою версию машинописного текста и версию @ types / react? Кажется, это работает для меня, но, вероятно, я делаю что-то по-другому. Кстати, он на самом деле жалуется на эту деталь
undefined, так что e не является обязательным.