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')