如何根据multiline属性值为TextField组件条件定义Props类型?
解决TextField组件根据multiline条件渲染的类型报错问题
问题场景与报错
构建TextField组件时,需根据multiline属性值渲染input或textarea元素,但在条件分配Props类型时出现以下报错:
'multiline' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.
原代码如下:
const input = "input"; const textarea = "textarea"; export type TextFieldMultiline<Multiline extends boolean> = { multiline: Multiline, } export type TextFieldProps<Multiline extends boolean> = TextFieldMultiline<Multiline> & (Multiline extends true ? React.ComponentPropsWithRef<typeof textarea> : React.ComponentPropsWithRef<typeof input>) export const TextField = ({multiline, ...props}: TextFieldProps<typeof multiline>) => <> {multiline ? <input {...props}/> : <textarea {...props}/>}</>
错误原因
组件参数中使用typeof multiline作为泛型参数时,multiline尚未完成类型注解,导致TypeScript无法正确推断类型,形成循环引用的类型推断逻辑,最终抛出报错。
可行实现方式
方式一:泛型组件实现类型自动推断
将组件定义为泛型组件,让TypeScript根据传入的multiline值自动匹配对应元素的Props类型:
const input = "input"; const textarea = "textarea"; export type TextFieldProps<Multiline extends boolean> = (Multiline extends true ? React.ComponentPropsWithRef<typeof textarea> : React.ComponentPropsWithRef<typeof input>) & { multiline: Multiline; }; export const TextField = <Multiline extends boolean>({ multiline, ...props }: TextFieldProps<Multiline>) => { return multiline ? <textarea {...props} /> : <input {...props} />; };
使用时,当传入multiline={true},组件会自动校验并提示textarea的合法属性;传入multiline={false}则对应input的属性,完全实现类型安全。
方式二:联合类型明确分支类型
通过联合类型直接定义两种场景的Props,避免泛型循环推断问题:
const input = "input"; const textarea = "textarea"; type TextFieldProps = | (React.ComponentPropsWithRef<typeof input> & { multiline: false }) | (React.ComponentPropsWithRef<typeof textarea> & { multiline: true }); export const TextField = ({ multiline, ...props }: TextFieldProps) => { if (multiline) { return <textarea {...props as React.ComponentPropsWithRef<typeof textarea>} />; } return <input {...props as React.ComponentPropsWithRef<typeof input>} />; };
这种方式通过联合类型拆分两种状态的Props,TypeScript会根据multiline的布尔值约束传入的属性,分支渲染时通过类型断言明确当前Props的类型即可。
内容的提问来源于stack exchange,提问作者GRZa
相关产品推荐
相关产品推荐

