TypeScript如何为转任意值为安全数组的toArray函数定义正确类型?
解决方案
TypeScript 暂时无法在函数实现内部自动关联泛型条件类型与分支判断的返回值类型,你直接用条件类型作为返回值时,TS 无法识别分支返回值和类型定义的匹配关系,因此会抛出错误。
最优方案是用函数重载实现,分别定义不同入参对应的返回类型,实现层面写宽松的类型即可:
// 重载1:入参为 null/undefined 时返回空数组类型 function toArray(value: null | undefined): [] // 重载2:入参为数组时,返回对应元素类型的数组 function toArray<U>(value: U[]): U[] // 重载3:入参为非空非数组值时,返回包含该值的数组类型 function toArray<T>(value: T): T[] // 实现签名,类型写得足够宽松即可 function toArray(value: unknown): unknown[] { if (value == null) { return [] } if (Array.isArray(value)) { return value } return [value] }
验证效果完全符合你的预期:
toArray(null) // 类型:[] toArray(undefined) // 类型:[] toArray([]) // 类型:[] toArray({}) // 类型:{}[] toArray(0) // 类型:number[] toArray('') // 类型:string[] toArray(['']) // 类型:string[] toArray([1]) // 类型:number[]
如果你不想用重载,也可以在原有实现的基础上给返回值加断言,写法如下:
type ToArrayResult<T> = T extends null | undefined ? [] : T extends Array<infer U> ? U[] : T[] function toArray<T>(value: T): ToArrayResult<T> { if (value == null) { return [] as ToArrayResult<T> } if (Array.isArray(value)) { return value as ToArrayResult<T> } return [value] as ToArrayResult<T> }
内容的提问来源于stack exchange,提问作者BernaMariano
相关产品推荐
相关产品推荐

