You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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和参数类型:

  1. 先定义规则处理函数的类型映射:
type RuleHandlerMap = {
  [K in keyof InputRules]: (val: string, ruleValue: NonNullable<InputRules[K]>) => string
}
  1. 给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 ''
  }
}
  1. 用泛型函数优化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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 17:07:24