如何引导TypeScript编译器为泛型属性T推断正确类型?
TypeScript泛型函数
isUndefined复杂类型类型缩小问题 问题描述
- 自定义泛型函数
isUndefined<T>(...)处理简单类型时,能正确从联合类型中移除undefined;但处理复杂类型时,类型缩小不符合预期。 - 在
CustomStorage类的setItem方法中,调用该函数时TypeScript会推断类型为isUndefined<StorageItemData<SM[K]>>(...),导致assuredData的类型为StorageItemData<SM[K]> | {}(等同于Item | undefined | {}),undefined未被正确排除。 - 预期行为:编译器先将
StorageItemData<SM[K]>解析为Item | undefined,再推断调用isUndefined<Item>(value: Item | undefined),使assuredData类型变为Item | {}。 - 需求:不使用类型断言的临时方案,仅通过修改
isUndefined函数解决问题。
解决方案
修改isUndefined函数的类型定义,添加准确的类型守卫,让TypeScript能正确识别并排除undefined类型:
// 调整后的isUndefined函数,添加类型守卫明确判断结果 function isUndefined<T>(value: T): value is Extract<T, undefined> { return typeof value === 'undefined'; }
在setItem方法中使用时,通过逻辑分支触发类型缩小:
const assuredData = isUndefined(data) ? {} : data;
此时TypeScript会正确推断assuredData的类型为Exclude<StorageItemData<SM[K]>, undefined> | {},也就是Item | {},完全符合预期。
原理说明
Extract<T, undefined>会从联合类型T中提取出undefined类型,作为类型守卫的目标类型。- 当
isUndefined(data)返回true时,TypeScript确定data是undefined,此时赋值为{};当返回false时,TypeScript自动将data的类型缩小为Exclude<StorageItemData<SM[K]>, undefined>(即Item),最终assuredData的类型自然是Item | {}。
内容的提问来源于stack exchange,提问作者Sonny D
相关产品推荐
相关产品推荐

