3

I'm wondering what the optimal way to go when you've got an interface method, whose implementations may return sync value in one implementation and async value in another.

Example:

export interface CacheType {
  get<T>(key: string): any
}

then we've got a sync implementation

export class LocalSyncCache implements CacheType {
  public get(key: string): T | undefined {
    return 'some_value_from_a_sync_storage'
  }
}

and async one

export class RemoteAsyncCache implements CacheType {
  public async get(key: string): Promise<T | undefined> {
    return await async_request('https://aws.amazon.com/get')
  }
}

What would be the correct return value for the method interface?

Assume everything async and just always await?

export interface CacheType {
  get(key: string): Promise<T | undefined>
}

export class LocalSyncCache implements CacheType {
  public async get(key: string): Promise<T | undefined> {
    return 'some_value_from_a_sync_storage'
  }
}

const localSyncCache = new LocalSyncCache()
const remoteAsyncCache= new RemoteAsyncCache()

await localSyncCache.get('foo')
await remoteAsyncCache.get('foo')

It works. Doesn't throw any errors. And I've seen it implemented in some popular codebases. OK, but what about the fact that await on sync methods still changes the execution flow? https://stackoverflow.com/a/55263084/255408

Or just use type union and narrow down the types in implementations?

export interface CacheType {
  get(key: string): Promise<T | undefined> | T | undefined
}

export class LocalSyncCache implements CacheType {
  public get(key: string): T | undefined {
    return 'some_value_from_a_sync_storage'
  }
}

export class RemoteAsyncCache implements CacheType {
  public async get(key: string): Promise<T | undefined> {
    return await async_request('https://aws.amazon.com/get')
  }
}

const localSyncCache = new LocalSyncCache()
const remoteAsyncCache= new RemoteAsyncCache()

localSyncCache.get('foo')
await remoteAsyncCache.get('foo')
Vlad
  • 655
  • 6
  • 12

0 Answers0