TypeScript:能否用泛型返回不同值,避免重复定义函数?
用TypeScript优化获取位置函数的类型推断
方案一:函数重载(推荐)
函数重载是TypeScript处理这类多返回类型场景最直观的方式,既不用重复编写核心逻辑,也能让编译器自动推断正确的返回类型,完全避免外部类型断言。
实现代码:
// 内部核心逻辑,仅在模块内部使用 function _getPosition(withError: boolean): GeoLocation | GeoError | undefined { // 这里编写你的位置获取逻辑(比如调用navigator.geolocation相关API) let position: GeoLocation | undefined = ...; let positionError: GeoError = ...; if (!position) { return withError ? positionError : undefined; } return position; } // 对外暴露的重载签名,定义不同参数对应的返回类型 export function getPosition(): GeoLocation | undefined; export function getPosition(withError: true): GeoLocation | GeoError; // 实际实现签名(外部调用时不会感知到这个宽泛的类型) export function getPosition(withError: boolean = false): GeoLocation | GeoError | undefined { return _getPosition(withError); }
使用方式:
// 自动推断返回 GeoLocation | undefined const pos = getPosition(); if (!pos) { alert("无法获取位置"); return; } // pos此时自动识别为GeoLocation类型,无需类型断言 // 自动推断返回 GeoLocation | GeoError const posOrErr = getPosition(true); if ('coords' in posOrErr) { // 处理位置数据 } else { // 处理错误信息 }
方案二:泛型+条件类型
如果希望用单一函数实现,可利用TypeScript的泛型布尔字面量和条件类型,让编译器根据参数值自动推断返回类型。
实现代码:
export function getPosition<T extends boolean = false>( withError?: T ): T extends true ? GeoLocation | GeoError : GeoLocation | undefined { let position: GeoLocation | undefined = ...; let positionError: GeoError = ...; if (!position) { // 内部仅需一次as any妥协,外部调用完全类型安全 return (withError ? positionError : undefined) as any; } return position as any; }
使用方式和重载方案完全一致,调用方无需任何类型断言,编译器会自动匹配对应的返回类型。
方案对比
- 函数重载:代码可读性更高,逻辑分层清晰,内部无需任何类型断言,是这类场景的首选方案。
- 泛型方案:API更紧凑,但内部需要少量类型妥协(
as any),适合追求极简函数数量的场景。
内容的提问来源于stack exchange,提问作者Avishay Matayev
相关产品推荐
相关产品推荐

