请求实现TypeScript泛型方法中的IsStorable与CastInStorable函数
如何根据对象类型调用不同的泛型方法?
看起来你想要根据toExecute函数返回的对象是否实现了IStorable接口,来动态选择调用GetItemStored还是GetItem。这里的核心问题是TypeScript的泛型类型信息在运行时会被擦除,所以我们需要结合运行时类型检查来实现你的需求。下面是具体的实现方案:
首先,实现运行时类型守卫
我们先写一个基础的类型守卫函数,用来判断一个对象是否符合IStorable的结构:
function isStorable(obj: unknown): obj is IStorable { // 检查对象是否存在,并且包含boolean类型的Enable属性 return typeof obj === 'object' && obj !== null && 'Enable' in obj && typeof (obj as IStorable).Enable === 'boolean'; }
实现IsStorable函数
这个函数需要异步执行toExecute,然后用上面的类型守卫判断结果是否属于IStorable:
async IsStorable<T>(toExecute: () => Promise<T>): Promise<T is IStorable> { const result = await toExecute(); return isStorable(result); }
这里我们用了Promise<T is IStorable>作为返回类型,这样TypeScript编译器能在后续逻辑中自动推断类型,不需要额外的类型转换。
实现CastInStorable函数
如果确实需要单独的类型转换函数(比如你不想提前执行toExecute),可以这样写:
CastInStorable<T>(toExecute: () => Promise<T>): () => Promise<IStorable> { return async () => { const result = await toExecute(); // 这里已经通过IsStorable确认了类型,所以类型断言是安全的 return result as IStorable; }; }
优化Main函数
结合上面的实现,我们可以调整Main函数,避免重复执行toExecute(如果提前执行不影响你的业务逻辑的话):
async Main<T>(toExecute: () => Promise<T>) { const result = await toExecute(); if (isStorable(result)) { // 编译器自动知道result是IStorable类型,直接调用GetItemStored await this.GetItemStored(() => Promise.resolve(result)); } else { await this.GetItem(() => Promise.resolve(result)); } }
如果必须先判断再执行toExecute,可以用之前的IsStorable版本,但注意这样会执行两次toExecute,如果这个函数有副作用的话需要谨慎处理。
关键说明
- TypeScript的泛型是编译时特性,运行时无法直接获取
T的类型信息,所以必须通过检查对象的实际属性来判断类型。 - 类型守卫函数
isStorable既可以在运行时做检查,又能让编译器在编译时推断类型,是这类场景的最佳实践。
内容的提问来源于stack exchange,提问作者rdethurens
相关产品推荐
相关产品推荐

