TypeScript中如何定义条件返回类型且无需使用类型断言?
避免TypeScript泛型函数中的类型断言
方案1:使用函数重载
函数重载能直接对应输入与返回的类型关系,让TypeScript自动完成类型推断,无需手动断言。
// 重载签名:明确不同输入对应的返回类型 function test(value: string): number; function test(value: unknown): string; // 实现签名:处理逻辑 function test(value: unknown): number | string { if (typeof value === 'string') { return 1; } else { return '1'; } } const res1 = test('String'); // 类型自动推断为number const res2 = test(13123); // 类型自动推断为string
方案2:自定义类型守卫细化泛型
通过类型谓词函数,让TypeScript在分支中明确泛型T的具体类型,从而自动匹配返回类型。
type TestReturnType<T> = T extends string ? number : string; // 自定义类型守卫:判断value是否为T与string的交集类型 function isString<T>(value: T): value is T & string { return typeof value === 'string'; } const test = <T>(value: T): TestReturnType<T> => { if (isString(value)) { // 此时T被细化为string,返回值自动匹配TestReturnType<string> return 1; } else { // 此时T被细化为非string类型,返回值自动匹配对应分支的类型 return '1'; } }; const res1 = test('String'); // number const res2 = test(13123); // string
方案3:细化泛型约束(适用于TS 4.7+)
如果使用TypeScript 4.7及以上版本,可以在分支中临时细化泛型约束,让TypeScript自动识别返回类型,相比直接断言返回类型更安全。
type TestReturnType<T> = T extends string ? number : string; const test = <T>(value: T): TestReturnType<T> => { if (typeof value === 'string') { // 临时将T约束为string,返回值自动对应TestReturnType<string> return 1 as TestReturnType<T & string>; } else { // 临时排除string类型,返回值自动对应TestReturnType<Exclude<T, string>> return '1' as TestReturnType<Exclude<T, string>>; } };
原代码需要断言的原因
typeof value === 'string'只能把value的类型细化为string,但泛型T可能是包含string的联合类型(如string | number),TypeScript无法自动将T的范围缩小,因此无法确定返回值是否符合TestReturnType<T>,需要手动断言。上述方案通过明确分支中T的类型,让TypeScript完成自动推断,避免了无意义的类型断言。
内容的提问来源于stack exchange,提问作者DevOverflow
相关产品推荐
相关产品推荐

