如何定义省略指定属性的组件类型作为React组件属性?
问题描述
我需要在React中定义一个组件属性,要求该属性是已省略指定属性的组件实例。现有以下代码:
Validation组件
interface ValidationProps { value: string, check: Array<(value: string) => boolean> } const Validation: FC<ValidationProps> = () => {} export default Validation;
Input组件
interface InputProps { value: string, onChange: (e: React.SyntheticEvent) => void, validations: ??? // 这里需要定义为已省略value属性的Validation组件 } const Input: FC<InputProps> = (props) => { return <span> <input value={props.value} onChange={props.onChange} /> {React.cloneElement(props.validations, { value: props.value })} </span> } export default Input;
预期使用方式如下,传入的validations是不包含value属性的Validation组件实例:
<Input value="value" onChange={(e) => {}} validations={<Validation check={[(value) => value != null, (value) => value.length <= 5]} />} />
解决方案
可以通过TypeScript的工具类型精准定义这个属性类型:
- 使用
Omit<ValidationProps, 'value'>剔除ValidationProps中的value属性,得到仅包含check的属性类型 - 结合
React.ReactElement,限定validations是基于该剔除后属性的Validation组件实例
修改后的InputProps定义如下:
import React, { FC, ReactElement } from 'react'; import Validation, { ValidationProps } from './Validation'; interface InputProps { value: string, onChange: (e: React.SyntheticEvent) => void, // 仅接受省略了value属性的Validation组件实例 validations: ReactElement<Omit<ValidationProps, 'value'>, typeof Validation> }
完整Input组件代码
import React, { FC, ReactElement, cloneElement } from 'react'; import Validation, { ValidationProps } from './Validation'; interface InputProps { value: string, onChange: (e: React.SyntheticEvent) => void, validations: ReactElement<Omit<ValidationProps, 'value'>, typeof Validation> } const Input: FC<InputProps> = (props) => { return <span> <input value={props.value} onChange={props.onChange} /> {cloneElement(props.validations, { value: props.value })} </span> } export default Input;
说明
- 这样定义后,TypeScript会自动校验传入的
validations:必须是<Validation />组件,且不能显式传入value属性(如果传入会报错) - Input组件内部通过
cloneElement给validations注入value属性,符合预期逻辑
内容的提问来源于stack exchange,提问作者Nico Richter
相关产品推荐
相关产品推荐

