Next.js中TypeScript表单校验输入框类型不兼容问题求助
解决Next.js+TypeScript输入组件校验的类型错误问题
问题描述
我用Next.js搭配TypeScript开发带校验功能的输入组件,定义了InputRules接口用来配置校验规则,还有包含对应处理逻辑的handleRules对象。在输入框失焦触发的handleBlur函数中,遍历传入的rules属性并调用handleRules里的对应方法时,出现了类型错误提示:
Argument of type 'number | boolean | undefined' is not assignable to parameter of type 'never'
组件实际运行正常,但这个错误提示一直存在,想解决这个问题。
相关代码
InputRules接口
interface InputRules { required?: boolean min?: number max?: number minLength?: number maxLength?: number }
handleRules处理对象
const handleRules = { required: (val: string, boo: boolean) => { if (boo && !val) return `${label || 'This field'} is required` return '' }, minLength: (val: string, len: number) => { if (val.length < len) return `${label || 'This field'} is must least ${len} character` return '' }, maxLength: (val: string, len: number) => { if (val.length > len) return `${label || 'This field'} cann't have more than ${len} character` return '' }, min: (val: number | string, num: number) => { if (Number(val) < num) return `${label || 'This field'} is must equal or greater than ${num}` return '' }, max: (val: string | number, num: number) => { if (Number(val) > num) return `${label || 'This field'} is must equal or less than ${num}` return '' } }
handleBlur失焦处理函数
const handleBlur = (val: string) => { if (rules) { let result = '' for (const key in rules) { result = handleRules[key as keyof typeof handleRules]( val, rules[key as keyof typeof handleRules] ) if (result) { setErrorMessage(result) break } } } }
InputProps组件属性接口
interface InputProps { type?: 'text' | 'password' | 'number' label?: string prefix?: JSX.Element | string subfix?: JSX.Element | string defaultValue?: string placeHolder?: string passClass?: string error?: string rules?: InputRules disabled?: boolean onChange?: (e: any) => void }
解决办法
这个错误的根源是TypeScript无法自动推断rules[key]和handleRules[key]的参数类型对应关系,导致类型不匹配。以下两种方法可以解决:
方法一:用Switch Case明确类型匹配
通过switch case遍历规则key,明确每个key对应的参数类型,让TypeScript能正确识别:
修改后的handleBlur函数:
const handleBlur = (val: string) => { if (rules) { let result = '' for (const key in rules) { const ruleKey = key as keyof InputRules const ruleValue = rules[ruleKey] if (ruleValue === undefined) continue switch (ruleKey) { case 'required': result = handleRules.required(val, ruleValue) break case 'minLength': case 'maxLength': case 'min': case 'max': result = handleRules[ruleKey](val, ruleValue) break } if (result) { setErrorMessage(result) break } } } }
方法二:定义精确的类型映射
给handleRules创建对应的类型映射,让TypeScript自动关联规则key和参数类型:
- 先定义规则处理函数的类型映射:
type RuleHandlerMap = { [K in keyof InputRules]: (val: string, ruleValue: NonNullable<InputRules[K]>) => string }
- 给
handleRules指定这个类型:
const handleRules: RuleHandlerMap = { required: (val: string, boo: boolean) => { if (boo && !val) return `${label || 'This field'} is required` return '' }, minLength: (val: string, len: number) => { if (val.length < len) return `${label || 'This field'} must be at least ${len} characters` return '' }, maxLength: (val: string, len: number) => { if (val.length > len) return `${label || 'This field'} cannot have more than ${len} characters` return '' }, min: (val: number | string, num: number) => { if (Number(val) < num) return `${label || 'This field'} must be equal or greater than ${num}` return '' }, max: (val: string | number, num: number) => { if (Number(val) > num) return `${label || 'This field'} must be equal or less than ${num}` return '' } }
- 用泛型函数优化
handleBlur:
const handleBlur = (val: string) => { if (rules) { let result = '' const processRule = <K extends keyof InputRules>(key: K) => { const ruleValue = rules[key] if (ruleValue === undefined) return '' return handleRules[key](val, ruleValue) } for (const key in rules) { result = processRule(key as keyof InputRules) if (result) { setErrorMessage(result) break } } } }
额外提示
代码里的提示文本有几处语法错误,比如cann't应该是cannot,is must least改为must be at least,建议修正这些细节,保证提示信息的准确性。
内容的提问来源于stack exchange,提问作者kan
相关产品推荐
相关产品推荐

