typescript - 强制 TypeScript 在悬停时显示变量的最终状态

标签 typescript typescript-typings

在我的项目中,TypeScript 多次向我显示未解释的类型。

示例:
在以下代码中,将鼠标悬停在 Foo 上会给我以下结果:
playground

interface FooParent {
    fish: {
        catfish: string;
    }[];
}

type Foo = {
    test: FooParent['fish'][0];
};

enter image description here

如果我想知道 FooParent['fish'][0] 的类型,我得自己解读。
我看到可以使用 infer 键来欺骗 TypeScript:
playground
interface FooParent {
    fish: {
        catfish: string;
    }[];
}

type Foo = {
    test: FooParent['fish'][0] extends infer U ? { [P in keyof U]: U[P] } : never;
};

enter image description here

但它是不可预测的( Playground )。

你知道有什么方法可以让 TypeScript 以简单可靠的方式向你显示你悬停的变量的最终类型吗?

最佳答案

根据您的 Typescript 知识,解决方案本身可能有点紧张;我提供了一些评论来引导您完成。
但是用法相当简单和可靠 - 非常类似于您最初的工作示例:YourType extends ForceType<infer U> ? U : _whatever_ .

interface FooParent {
    fish: {
        catfish: string;
        foo: {
            bar: () => void
        },
        loop: FooParent
    }[];
}

type Foo = {
    test: 
        // FooParent,
        // FooParent extends ForceType<infer U> ? U : never,
        // FooParent['fish'],
        // FooParent['fish'] extends ForceType<infer U> ? U : never,
        // FooParent['fish'][0],
        FooParent['fish'][0] extends ForceType<infer U> ? U : never,
        // FooParent['fish'][0]['catfish'],
        // FooParent['fish'][0]['catfish'] extends ForceType<infer U> ? U : never
    
};

type Index = number | string | symbol
type ForceType<T, Path extends Index[] = Index[]> = Path extends [infer _] ?
 T extends Record<Index, any> ? ForceObject<T, Path>
    : T extends ReadonlyArray<any> ? ForceArray<T, Path>
        : never // neither object nor array; never could only happen if Path was specified explicitly
            : T // closes the first condition - Path is empty we reached a leaf

type ForceObject<T, Path extends Index[]> = Path extends [infer H, ...infer Rest] ?
        Rest extends Index[] ?
            H extends keyof T ? ForceType<T[H], Rest> // traverse and recurse
                : never : never : never // never could only happen if Path was specified explicitly

type ForceArray<T extends ReadonlyArray<any>, Path extends Index[]> = Path extends [number, ...infer Rest] ?
   Rest extends Index[] ? ForceType<T[number], Rest> // traverse and recurse
    : never : never // never could only happen if Path was specified explicitly
PLAYGROUND
下图是在按下 CMD 的情况下拍摄的。显示原始代码和计算类型。
working example from TS playground
我认为最终应该在 IDE 级别解决该问题,因为它主要是 DX 挑战。看起来 Monaco Editor/VSCode 非常接近实际解决它,但在大多数情况下,在按下 CMD 的情况下将鼠标悬停在类型定义上只会显示重复的信息。
幸运的是,在这种情况下,可以使用更多类型来解决类型问题。
顺便提一句。一个非常好的问题——经过充分研究、记录和具有挑战性。谢谢你。

关于typescript - 强制 TypeScript 在悬停时显示变量的最终状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65994768/

相关文章:

javascript - Angular 2 ngFor 行和列创建了一个大 Col

typescript - 如何在 Typescript 的函数内声明静态变量?

loops - ngFor 内的 angular2 切换图标

reactjs - 自定义 Typescript NPM 包不会生成类型

typescript - 如何在 try-catch block 中输入 Firebase JS SDK 错误?

angular - 从 Angular 2 中的 FileReader 获取值

typescript - 使用数字枚举创建 Typescript `Record<>` 类型

typescript - 从多个 typescript 文件 + 入口点导出单个 .d.ts

class - 在 TypeScript 中声明动态添加的类属性

javascript - 如何配置 JSON 字段到 TypeScript 对象属性的映射?