Typescript 映射类型如何与基类型一起工作?

Typescript 映射类型如何与基类型一起工作?,typescript,Typescript,我不明白为什么在下面的情况下,类型T0是一个字符串,而不是带有键“toString”、“slice”和“split”的对象。。。为什么type T1是键类型为string的对象,而我们现在知道keyof any是一个string | symbol | number type MappedType<T> = { [K in keyof T]: T; } type T0 = MappedType<string>; type T1 = MappedType<any>

我不明白为什么在下面的
情况下,类型T0
是一个字符串,而不是带有键“toString”、“slice”和“split”的对象。。。为什么
type T1
是键类型为
string
的对象,而我们现在知道keyof any是一个
string | symbol | number

type MappedType<T> = {
[K in keyof T]: T;
}

type T0 = MappedType<string>;
type T1 = MappedType<any>;
类型MappedType={
[K in keyof T]:T;
}
T0型=MappedType;
T1型=MappedType;

可以在实现了“同态”或映射类型的中找到
{[K in keyof T]:…}
形式的
T0
的权威答案,其中
T
是泛型类型参数。(请注意,它最初被称为“同构”而不是“同态”,但它是同一件事。)

这种映射类型的正常用例是当
T
是某个objdct类型时;在这种情况下,映射保留
T
中的键名以及它们的“只读性”和“可选性”修饰符。(可以通过在映射类型中显式设置这些修改器来覆盖它们。)

那么当
T
是像
string
这样的基本类型时会发生什么呢?pull请求说“我们只是生成那个基本类型”。这非常有用,尤其是在递归使用映射类型的情况下。一类

type DeepPartial<T> = { [K in keyof T]?: DeepPartial<T[K]> }
这就不那么方便了(直到TS2.8引入了条件类型才可能实现)

在某种意义上,人们通常希望为映射同态的事物保留“相同的一般形状”,但“相同的一般形状”的含义并不总是显而易见的。对象类型保持为对象类型。原语保持原语。最初,数组被视为常规对象类型,产生了一种几乎无用的类型,它将数组方法转换为无法识别的东西。这对任何人来说都不愉快,这就是为什么映射数组类型仍然是数组类型,而映射元组类型仍然是元组类型


这就给我们留下了
T1
,其中
any
属性上的同态映射产生了一个可索引类型

之前链接的pull请求没有进入其中,但是实现者在一个报告此行为为bug的示例中解释了他的推理:

any
的键是
string | number | symbol
,因此应用于
any
的映射类型将产生与
{[x:string]:XXX}
等价的值

请注意,他说的是“相当于”<代码>符号
自动从映射类型中删除,因此
{[K in“a”| symbol]:string}
产生
{a:string}
。您可以分别拥有
string
number
索引,因此
{[K in string | number]:string}
{[K:string]:string;[K:number]:string}
。但由于数字键在和中被视为字符串值,因此这与
{[k:string]:string}
相同。(如果您想了解更多有关映射时
字符串
数字
符号
键的情况,您可以看到。)

就个人而言,我并不是100%同意将
keyofany
映射到一个
string
索引而不是
string
number
,因为
{[K in keyof T]:K}
会显示出不同。。。但这是一个小问题

重要的一点来自评论的其余部分:

您可能会争辩说,当同态映射类型应用于
any
时,我们应该只生成
any
,但这将不太精确。例如,
{[K in keyof T]:number}
T
实例化为
any
确实应该产生
{[x:string]:number}
,而不仅仅是
any

你就这样走了<代码>任何
都被视为具有字符串可索引键的对象类型,因此在其上的映射会产生合理的结果。这是我见过的最接近于这个问题的规范答案的评论


好吧,希望这会有帮助;祝你好运


可以在中找到
T0
的权威答案,该答案实现了“同态”,或映射了
{[K in keyof T]:…}
形式的类型,其中
T
是泛型类型参数。(请注意,它最初被称为“同构”而不是“同态”,但它是同一件事。)

这种映射类型的正常用例是当
T
是某个objdct类型时;在这种情况下,映射保留
T
中的键名以及它们的“只读性”和“可选性”修饰符。(可以通过在映射类型中显式设置这些修改器来覆盖它们。)

那么当
T
是像
string
这样的基本类型时会发生什么呢?pull请求说“我们只是生成那个基本类型”。这非常有用,尤其是在递归使用映射类型的情况下。一类

type DeepPartial<T> = { [K in keyof T]?: DeepPartial<T[K]> }
这就不那么方便了(直到TS2.8引入了条件类型才可能实现)

在某种意义上,人们通常希望为映射同态的事物保留“相同的一般形状”,但“相同的一般形状”的含义并不总是显而易见的。对象类型保持为对象类型。原语保持原语。最初,数组被视为常规对象类型,产生了一种几乎无用的类型,它将数组方法转换为无法识别的东西。这对任何人来说都不愉快,这就是为什么映射数组类型仍然是数组类型,而映射元组类型仍然是元组类型


这就给我们留下了
T1
,其中
any
属性上的同态映射产生了一个可索引类型

之前链接的pull请求没有进入其中,但是实现者在一个报告此行为为bug的示例中解释了他的推理:

任何的
键都是
字符串|数字|符号<
type DeepPartial2<T> = 
  { [K in keyof T]?: T[K] extends object ? DeepPartial2<T[K]> : T[K] }