这个 DeepPartial 类型如何在 Typescript 中工作?

Mis*_*r M 5 typescript

我在这里查看这个问题:

TypeScript:深度部分?

最上面的答案的 DeepPartial 类型定义如下:

type DeepPartial<T> = {
    [P in keyof T]?: DeepPartial<T[P]>;
};
Run Code Online (Sandbox Code Playgroud)

我测试过,这种类型按预期工作,但我无法完全理解它的内部工作原理。

让我们以同一问题的界面为例:

interface Foobar {
  foo: number;
  bar: {
    baz: boolean;
    qux: string;
  };
}
Run Code Online (Sandbox Code Playgroud)

当P=bar时,很容易理解,递归地会进入

DeepPartial<{
    baz: boolean;
    qux: string;
  }>
Run Code Online (Sandbox Code Playgroud)

并使“baz”和“qux”键可选。

但我不明白的是,递归如何适用于原始类型?就像fookey 一样,如何与DeepPartial<number>相同number?当T=数字时,

[P in keyof number]?: DeepPartial<number[P]>;
Run Code Online (Sandbox Code Playgroud)

对我来说没有意义。

在我看来,DeepPartial 的实现应该是这样的:

type DeepPartial<T> = {
    [P in keyof T]?: isPrimitive(T[P]) ? T[P] : DeepPartial<T[P]>;
};
Run Code Online (Sandbox Code Playgroud)

但最初的实现也有效,但我不明白如何。

我希望我能很好地解释我的问题。这是游乐场示例:

https://www.typescriptlang.org/play?#code/JYOwLgpgTgZghgYwgAgGIHt0CM5WQbwChlkZMAuZEAVwFstoBuY5HKSokknAL0q0wAbCHBDMuyAI7UAHpQDOYKKADm45AF9mGwoTABPAA4oAIhAiGACrjDA4ggDwAVAHzIAvARYka2peSgyADWEProMMhOALoA -JRmFtZQtvbOflEu2syECOggiqSYbPHmVjZ2jhjYuG6enIXolACMADQsxQSscHzIStQoOlq6uflgvRCKAJLgJYnlqTT00LXIAKzMQA

编辑: 我进一步调查发现

type DeepPartial<T> = {
    [P in keyof T]?: any;
};

type DeepPartialTest<T> = {
        [P in keyof number]?: any;
    };
Run Code Online (Sandbox Code Playgroud)

nowDeepPartial<number>将返回数字类型,但DeepPartialTest<number>不会。这让我觉得更奇怪了。

编辑2添加截图:

这按预期工作:

在此输入图像描述

这不会:

在此输入图像描述

实际上两者应该相同吗?

小智 2

这实际上是 TypeScript 中类型参数的内部机制,其中指出:

当一个基本类型替换同构映射类型中的 T 时,我们只需生成该基本类型。

您可以在此拉取请求中阅读更多相关信息。