如何为TypeScript Template Literal Types定义适配的React PropTypes?
适配方案
PropTypes 自带的 PT.string 对应通用字符串类型,和你定义的模板字面量窄类型不兼容,且运行时无法做格式校验,你需要自定义 PropTypes 校验器,同时满足编译时 TypeScript 类型匹配和运行时格式校验。
实现步骤
- 先明确
relativeOrAbsStr对应的运行时校验规则:- 值为数字类型直接合法
- 值为字符串类型时,必须匹配格式:
数字%[可选数字],对应正则为/^\d+%(?:\d+)?$/
- 定义带类型的自定义校验器,完整代码如下:
import PT from 'prop-types'; // 原类型定义 type percentStr = `${number}%`; type relativeOrAbsStr = number | `${number | percentStr}${number | ''}`; // 自定义PropTypes校验器,泛型绑定到自定义类型 const relativeOrAbsStrValidator: PT.Validator<relativeOrAbsStr> = ( props, propName, componentName ) => { const value = props[propName]; // 允许数字类型 if (typeof value === 'number') return null; // 字符串校验格式 if (typeof value === 'string') { if (/^\d+%(?:\d+)?$/.test(value)) return null; return new Error( `组件${componentName}的属性${propName}校验失败:预期符合 \`{数字}%{可选数字}\` 格式的字符串,实际得到 \`${value}\`` ); } // 其他类型不合法 return new Error( `组件${componentName}的属性${propName}校验失败:预期数字或格式合法的字符串,实际得到${typeof value}类型` ); };
- 组件中直接使用该校验器即可,无需
as any断言:
// 组件props类型定义 interface MyComponentProps { myStr: relativeOrAbsStr; } // 组件PropTypes定义 MyComponent.propTypes = { myStr: relativeOrAbsStrValidator };
如果你需要支持带小数的数值(比如合法值
'12.5%3.14'),可将正则替换为/^\d+(?:\.\d+)?%(?:\d+(?:\.\d+)?)?$/。
内容的提问来源于stack exchange,提问作者Eliav Louski
相关产品推荐
相关产品推荐

