在Reactjs函数组件中使用typescript泛型



我的react应用程序中的下一个组件:

import "./styles.css";
type InpuType = "input" | "textarea";
interface IContainer {
name: string;
placeholder: string;
as: InpuType;
}
const Container = ({
name,
placeholder,
as,
...rest
}: IContainer &
(
| React.TextareaHTMLAttributes<HTMLTextAreaElement>
| React.InputHTMLAttributes<HTMLInputElement>
)) => {
const Comp = as || "input";
return <Comp name={name} placeholder={placeholder} {...rest} />;
};
export default function App() {
return (
<div className="App">
<Container name="hi" as="textarea" placeholder="start" />
</div>
);
}

...rest是所有可以添加textareainput的默认道具。
我在这里有一个打字问题<Comp name={name} ...,悬停在组件上,我得到这个消息:

Type '{ autoComplete?: string | undefined; autoFocus?: boolean | undefined; cols?: number | undefined; dirName?: string | undefined; disabled?: boolean | undefined; form?: string | undefined; ... 261 more ...; placeholder: string; } | { ...; }' is not assignable to type 'IntrinsicAttributes & ClassAttributes<HTMLInputElement> & InputHTMLAttributes<HTMLInputElement> & ClassAttributes<...> & TextareaHTMLAttributes<...>'.

,我不知道如何摆脱它。问题:为什么会出现这个问题?如何解决?
演示:https://codesandbox.io/s/react-typescript-forked-z6dk4i?file=/src/App.tsx: 379 - 396

与其使用rest ({...rest})抛出所有本地道具,不如区分textareainput之间的道具。

interface IContainer {
name: string;
placeholder: string;
textareaProps?: React.TextareaHTMLAttributes<HTMLTextAreaElement>;
inputProps?: React.InputHTMLAttributes<HTMLInputElement>;
}
const Container = ({
name,
placeholder,
textareaProps,
inputProps,
}: IContainer) => {
if (inputProps) {
return <input {...inputProps} name={name} placeholder={placeholder} />;
}
return <textarea {...textareaProps} name={name} placeholder={placeholder} />;
};

https://codesandbox.io/s/react-typescript-forked-j9kgh2?file=/src/App.tsx: 51 - 523

您应该创建一个函数,并根据您传递给它的内容创建输入

import "./styles.css";
type InpuType = "input" | "textarea";
interface IComp {
name: string;
placeholder: string;
as: InpuType;
rest?: any;
}
const Comp = ({ as, name, placeholder, ...rest }: IComp) => {
switch (as) {
case "input":
return <input name={name} placeholder={placeholder} {...rest} />;
case "textarea":
return <textarea name={name} placeholder={placeholder} {...rest} />;
}
};
interface IContainer {
name: string;
placeholder: string;
as: InpuType;
}
const Container = ({
name,
placeholder,
as,
...rest
}: IContainer &
(
| React.TextareaHTMLAttributes<HTMLTextAreaElement>
| React.InputHTMLAttributes<HTMLInputElement>
)) => {
return <Comp as={as} name={name} placeholder={placeholder} {...rest} />;
};
export default function App() {
return (
<div className="App">
<Container name="hi" as="textarea" placeholder="start" />
</div>
);
}

最新更新