TypeScript:如何为Map设置动态值类型?缓存服务类型报错求助
TypeScript缓存服务移除any类型后的类型兼容问题
我在TypeScript中实现了一个以Map为核心容器的缓存服务,初始代码如下:
import { Observable } from 'rxjs'; import { shareReplay } from 'rxjs/operators'; interface CacheItem { value: Observable<any>; // validUntil: Date; // 为简化已移除 } private readonly cacheMap = new Map<string, CacheItem>(); public cachify<T>(cacheKey: string, cacheableFunction: () => Observable<T>): Observable<T> { const itemExists = this.cacheMap.has(cacheKey); if (!itemExists) { this.cacheMap.set(cacheKey, { value: cacheableFunction().pipe(shareReplay()) }); } return this.cacheMap.get(cacheKey).value; }
使用方式:
return this.cacheService .cachify('great-cache-key', () => fetchSomethingNice);
这段代码能正常运行,但我想移除any类型的使用,于是修改了服务代码:
interface CacheItem<T> { value: Observable<T>; } private readonly cacheMap = new Map<string, CacheItem<unknown>>();
由于服务内部无法预知具体类型,初始化时用unknown指定类型,但修改后cachify方法的最后一行出现类型错误:
Type 'Observable<unknown>' is not assignable to type 'Observable<T>'. Type 'unknown' is not assignable to type 'T'. 'T' could be instantiated with an arbitrary type which could be unrelated to 'unknown'.
解决方案
问题核心是TypeScript无法自动推断cacheMap中对应cacheKey的CacheItem类型与当前泛型T匹配,但业务逻辑上我们可以保证:要么该cacheKey是刚通过传入的cacheableFunction(返回Observable<T>)存入的,要么是之前存入的同类型值。因此可以通过类型断言解决:
修改cachify方法的返回语句:
return (this.cacheMap.get(cacheKey)!.value) as Observable<T>;
!断言是因为我们已经通过this.cacheMap.has(cacheKey)确认键存在,不会返回undefined;as Observable<T>是明确告知TypeScript,我们确认该值的类型就是当前泛型T对应的Observable。
也可以通过封装类型安全的获取逻辑,或在业务层面约定同一个cacheKey始终对应相同类型返回值,进一步规避类型问题。
内容的提问来源于stack exchange,提问作者sandrooco
相关产品推荐
相关产品推荐

