TypeScript悬停类型信息未完全计算的原因及解决办法
TypeScript中嵌套泛型场景下Omit类型未展开的问题
问题描述
在简单类型场景中,TypeScript会自动将工具类型的计算结果展开显示:
type AB = { a: 1, b: 2, } type A = Omit<AB, 'a'> // hover A会显示展开后的类型:{ b: 2 }
但在返回函数的高阶函数场景中,类型计算结果不会自动展开,仍保留工具类型的原始形式:
const omitKey = <K extends string>(key: K) => <V extends Record<string, any>>(val: V): Omit<V, K> => { const result = {} as V for (const k of Object.keys(val) as (keyof V)[]) { if (k !== key) { // 修正原代码逻辑bug:排除指定key result[k] = val[k] } } return result } type AB = { a: 1, b: 2, } const ab: AB = { a: 1, b: 2 } const result = omitKey('a')(ab) // hover result显示:Omit<AB, "a">,而非展开后的{ b: 2 }
原因分析
这并非TypeScript的功能局限,而是它的类型显示策略导致的:
- 为避免类型信息过载,TS会根据场景选择保留工具类型(如
Omit)的原始形式,还是展开为具体类型。 - 简单场景(非嵌套泛型)下,TS会自动展开计算后的类型;但在嵌套泛型(高阶函数的泛型嵌套)场景中,TS会优先保留工具类型的可读性,不自动展开。
解决方法
如果需要让类型显示为展开后的具体形式,可以通过以下几种方式实现:
1. 显式定义展开后的类型
提前用type关键字定义展开后的具体类型,再赋值给变量:
type ResultType = Omit<AB, 'a'>; const result: ResultType = omitKey('a')(ab); // hover result会显示展开后的{ b: 2 }
2. 使用自定义Prettify工具类型强制展开
定义一个工具类型Prettify,用来强制展开嵌套的工具类型:
type Prettify<T> = T extends infer U ? { [K in keyof U]: U[K] } : never;
修改高阶函数的返回类型为Prettify<Omit<V, K>>:
const omitKey = <K extends string>(key: K) => <V extends Record<string, any>>(val: V): Prettify<Omit<V, K>> => { const result = {} as V for (const k of Object.keys(val) as (keyof V)[]) { if (k !== key) { result[k] = val[k] } } return result } const result = omitKey('a')(ab); // hover result直接显示{ b: 2 }
3. 类型断言(临时方案,不推荐)
通过类型断言强制TS展开显示类型:
const result = omitKey('a')(ab) as Omit<AB, 'a'>; // hover result会显示展开后的{ b: 2 }
内容的提问来源于stack exchange,提问作者aaaaaa
相关产品推荐
相关产品推荐

