【发布时间】:2021-11-11 21:21:29
【问题描述】:
我在一些 TypeScript PR 中看到了术语“同态映射类型”。这是一个例子:https://github.com/microsoft/TypeScript/pull/21919
在 --strictNullChecks 模式下,当同态映射类型删除 ?基础类型中的属性的修饰符,它还会从该属性的类型中删除 undefined
什么是同态映射类型?同态究竟是什么?有没有一个非-同态映射类型的好例子
我感到困惑的原因是homomorphism 是保留特定操作的两个结构之间的映射。这里有问题的操作是什么?也就是说,其中f是映射,下面等式中op是什么:
f(x op y) = f(x) op f(y)
我尝试了什么
我尝试假设op 是&,这是两种类型相交的操作。
一个同态映射将是这样的:
F<T & U> = F<T> & F<U>
同态映射的一个例子(来自the TS handbook)是:
type Partial<T> = { [P in keyof T]?: T[P] }
因为Partial<T & U> 始终与Partial<T> & Partial<U> 相同。
问题是我想不出任何方法来使映射类型非同态!
即使是像这样愚蠢的看起来也是同态的:
type Silly<T> = { [P in "foo"]: number}
让我感到困惑的是Silly 似乎是同态(Silly <T & U> = Silly<T> & Silly<U>)。
这似乎与handbook所说的同态映射类型相矛盾:
...同态,这意味着该映射仅适用于 T 的属性,而不适用于其他属性。编译器知道它可以在添加任何新的属性修饰符之前复制所有现有的属性修饰符
Silly 保留了&,但不是手册中定义的同态映射类型。
【问题讨论】:
-
{ [P in keyof T]: something possibly involving T[P] but not T }形式的映射通过&和|对类型的操作都是同态的。您的Silly类型是微不足道的同态;就像一个同态,它将一个组的所有元素映射到另一组的单位元素。我认为您从文档中引用的句子不是“同态”的良好定义。 -
@kaya3 你能想出一个映射类型的例子,它不是
&或|中的同态(根据“同态”的真正定义,而不是TS 中的那个)文档)? -
例如,
Example<T> = { [k in keyof T]: T }不是同态的,因为如果type Foo = {a: number}和type Bar = {b: string}那么Example<Foo & Bar>是{a: Foo & Bar, b: Foo & Bar}但Example<Foo> & Example<Bar>是{a: Foo} & {b: Bar}。同样适用于|。 -
不,同态映射类型与
F<T|U>或F<T&U>以及它们与F<T>和F<U>的关系无关。type Example<T> = {[K in keyof T]: T}确实是一个同态映射类型,因为如果你这样做Example<{readonly a: string}>,则结果类型的a属性将为readonly。我会写一个答案。 -
好的,所以如果我们认为固定
K的ReadonlyProperty<T, K extends keyof T>是对T类型的一元运算,这使得属性K只读,那么Mapped是同态的,因为ReadonlyProperty<Mapped<T>, K>与Mapped<ReadonlyProperty<T, K>>相同。我想这确实符合数学定义,尽管说映射Mapped<...>与映射ReadonlyProperty<..., K>通勤会更自然。
标签: typescript