TypeScript泛型条件返回类型return报类型错但调用时推断正常问题
问题原因
TypeScript 当前存在设计层面的限制:无法通过函数内部的类型收窄逻辑,自动匹配泛型条件类型的返回值。你定义的T extends string[] ? string[] : string | undefined是未解析的条件类型,TS 不会因为你用Array.isArray(data)收窄了T的实际类型,就自动判定当前分支的返回值匹配最终的条件类型结果,所以会触发内部类型错误。
而函数调用时你传入的是具体的string/string[]类型,TS 可以直接计算出条件类型的最终结果,因此调用侧的类型推断是完全正常的。
解决方案
方案1:使用函数重载(更推荐,可读性更高,无强制类型断言)
直接定义两个重载签名匹配两种入参场景,实现签名用更宽松的类型即可,不会触发内部报错:
// 重载签名1:入参为字符串数组时返回字符串数组 function arrayTest(data: string[]): string[] // 重载签名2:入参为字符串时返回字符串或undefined function arrayTest(data: string): string | undefined // 实现签名 function arrayTest(data: string | string[]) { if(Array.isArray(data)){ return data } else{ return Math.random() > 0.5 ? data : undefined } } const arr = arrayTest(['a']) // 类型推导为 string[] const str = arrayTest('a') // 类型推导为 string | undefined
方案2:添加类型断言跳过内部检查
如果希望保留原有的泛型条件类型写法,可以在 return 处添加类型断言,主动告诉 TS 返回值符合定义的返回类型:
function arrayTest<T extends string | string[]>( data: T ): T extends string[] ? string[] : string | undefined { if(Array.isArray(data)){ return data as T extends string[] ? string[] : string | undefined } else{ return (Math.random() > 0.5 ? data : undefined) as T extends string[] ? string[] : string | undefined } }
内容的提问来源于stack exchange,提问作者Ivan V.
相关产品推荐
相关产品推荐

