You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 17:33:21