如何在TypeScript中定义既支持单实例又支持同类型数组的类型?
问题原因
你的validator字段类型定义本身是正确的,报错是因为你使用的isArray方法没有被TypeScript识别为类型守卫,无法对Validator | Validator[]的联合类型完成分支类型收窄。
解决方法
方案1:使用原生Array.isArray做判断
原生Array.isArray内置了类型守卫能力,TypeScript可以自动识别并把对应分支的类型收窄为数组/非数组类型:
export type Validator = { message: string, test: (text: string) => boolean } export type ValidatedInputProps = InputProps & { validator: Validator | Validator[], skipBlurIfInvalid?: boolean, } // 调用时使用原生Array.isArray判断 if (Array.isArray(validator)) { // 此处validator自动被识别为Validator[]类型 for (let v of validator) { const {message, test} = v if (!test(value)) { this.showError(message) return false } } } else { // 此处validator自动被识别为单个Validator类型 const {message, test} = validator if (!test(value)) { this.showError(message) return false } }
方案2:给自定义isArray添加类型守卫
如果你使用的是封装的自定义isArray工具方法,给方法添加类型守卫声明即可:
// 给自定义isArray添加类型守卫返回值 function isArray<T>(value: T | T[]): value is T[] { return Array.isArray(value) }
添加后你原有逻辑中的类型判断就可以被TypeScript正确识别。
方案3:统一转为数组处理(更简洁)
不需要写分支判断,不管传入的是单个校验器还是数组,先统一转为数组再遍历:
const validators = Array.isArray(validator) ? validator : [validator] for (let v of validators) { const {message, test} = v if (!test(value)) { this.showError(message) return false } }
内容的提问来源于stack exchange,提问作者1mike12
相关产品推荐
相关产品推荐

