Typescript中带可选fallback的字符串转布尔函数返回类型如何设置
报错原因说明
方案1(条件类型)报错原因
TS 无法在函数实现内部对泛型条件类型做实时解析推导,toBooleanReturnType<T> 属于延迟解析的类型,TS 不会根据你的代码逻辑分支判断当前返回值是否匹配该条件类型,所以无论返回 fallback 还是 undefined 都会提示类型不匹配。
方案2(函数重载)报错原因
你写的第二个重载的返回值定义为 boolean | T,当你显式传入非 undefined 类型的 fallback 时,返回值是不允许出现 undefined 的,但你的实现里存在 return undefined 的分支,TS 判定该分支返回值不满足第二个重载的返回类型要求。
正确实现
方式1:函数重载(更推荐,类型提示更直观)
先修正重载的定义,并且让实现签名兼容所有重载分支,代码如下:
/** * 字符串转布尔值 * @param str 待转换的字符串 * @param fallback 入参str不是'true'或'false'时的兜底值,可选 * @returns 转换后的布尔值,或者兜底值,未传兜底则转换失败返回undefined */ // 重载1:未传fallback,返回 boolean | undefined export function toBoolean(str: string): boolean | undefined // 重载2:传入fallback,返回 boolean | T export function toBoolean<T>(str: string, fallback: T): boolean | T // 实现签名,兼容所有重载 export function toBoolean<T>(str: string, fallback?: T): boolean | T | undefined { const trimStr = str.trim() if (trimStr === 'true') return true if (trimStr === 'false') return false return fallback }
这个写法直接把兜底逻辑简化为返回fallback,没传的时候fallback本身就是undefined,完美匹配所有重载的类型要求,不会有报错。
方式2:条件类型 + 类型断言
如果你坚持用条件类型的写法,可以在返回值处加类型断言告诉TS返回值符合要求:
type toBooleanReturnType<T> = T extends undefined ? boolean | undefined : boolean | T /** * 字符串转布尔值 * @param str 待转换的字符串 * @param fallback 入参str不是'true'或'false'时的兜底值,可选 * @returns 转换后的布尔值,或者兜底值,未传兜底则转换失败返回undefined */ export const toBoolean = <T = undefined>( str: string, fallback?: T, ): toBooleanReturnType<T> => { const trimStr = str.trim() if (trimStr === 'true') return true as toBooleanReturnType<T> if (trimStr === 'false') return false as toBooleanReturnType<T> return fallback as toBooleanReturnType<T> }
内容的提问来源于stack exchange,提问作者Omar Omeiri
相关产品推荐
相关产品推荐

