如何在TypeScript中根据标志返回Promise或值并实现正确类型推断?
如何让TypeScript根据驱动类型自动区分同步/异步方法的返回值?
要实现让TypeScript根据驱动类型强制区分set方法的返回值(同步驱动返回boolean,异步驱动返回Promise<boolean>),核心是利用泛型+条件类型,让类的方法返回值与驱动类型绑定,从而让TS在实例化时自动推断正确的类型。
解决方案步骤
明确驱动的类型区分
基于你现有的checkDriverIsAsync函数,构建类型层面的同步/异步判断逻辑,让TS能识别驱动的特性。用泛型绑定驱动类型
将GoodDB改为泛型类,泛型参数绑定具体驱动类型,使类的方法和属性类型能动态依赖这个参数。用条件类型定义返回值
通过条件类型判断泛型参数对应的驱动是同步还是异步,以此指定set方法的返回值类型。
完整代码示例
1. 基础类型定义(复用你现有逻辑)
// 同步驱动与异步驱动的基础类型 type SyncDriver = { // 同步驱动的核心方法 setSync(key: string, value: any): boolean; }; type AsyncDriver = { // 异步驱动的核心方法 setAsync(key: string, value: any): Promise<boolean>; }; type Drivers = SyncDriver | AsyncDriver; // 你原有的驱动异步判断函数 function checkDriverIsAsync(driver: Drivers): boolean { return 'setAsync' in driver; } // 基于函数返回值构建类型层面的异步判断 type IsAsync<D extends Drivers> = ReturnType<typeof checkDriverIsAsync> extends true ? true : false;
2. 改造后的GoodDB类
class GoodDB<D extends Drivers> { private driver: D; public readonly isAsync: IsAsync<D>; constructor( driver: D, private options?: any ) { this.driver = driver; this.isAsync = checkDriverIsAsync(driver) as IsAsync<D>; } set(key: string, value: any, options?: any): IsAsync<D> extends true ? Promise<boolean> : boolean { if (this.isAsync) { // 异步逻辑执行 return (async () => { // 这里替换为你的异步驱动处理逻辑 return await this.driver.setAsync(key, value); })() as IsAsync<D> extends true ? Promise<boolean> : boolean; } else { // 同步逻辑执行 return this.driver.setSync(key, value) as IsAsync<D> extends true ? Promise<boolean> : boolean; } } }
3. 实例化验证
// 同步驱动实例 const syncDriver: SyncDriver = { setSync(key: string, value: any): boolean { // 同步存储逻辑 return true; } }; const syncDb = new GoodDB(syncDriver); const syncResult = syncDb.set('key', 'value'); // TS自动推断为boolean,无await提示 // 异步驱动实例 const asyncDriver: AsyncDriver = { async setAsync(key: string, value: any): Promise<boolean> { // 异步存储逻辑 return true; } }; const asyncDb = new GoodDB(asyncDriver); const asyncResult = await asyncDb.set('key', 'value'); // TS自动推断为Promise<boolean>,必须使用await,否则会报错
为什么之前的方法无效?
你之前使用的方法重载是静态的,TypeScript无法根据实例的isAsync属性动态调整返回值类型——重载是针对整个类的所有实例,而泛型是在实例化时确定具体类型,因此能让TS精准推断每个实例的方法返回值。
内容的提问来源于stack exchange,提问作者usif
相关产品推荐
相关产品推荐

