我正在看Anders Hejlsberg在这个github线程中提供的Diff
方法:https://github.com/microsoft/TypeScript/issues/12215#issuecomment-307871458
在类型的上下文中,我不太了解此索引签名{ [x: string]: never }
的含义
type Diff<T extends string, U extends string> = ({[P in T]: P } & {[P in U]: never } & { [x: string]: never })[T];
他解释
它依赖于以下事实:带有字符串索引签名的对象可以用任何字符串索引。
但它仍然没有为我点击
这里的任何帮助将不胜感激!
答案 0 :(得分:4)
注意:今天不要在打字稿中使用Diff
。从2.8版打字稿开始,我们有了更好的替代方法,将diff内置到称为Exclude
的默认类型中。 Exclude
使用条件类型来过滤类型更简洁。
Diff
曾经是过滤字符串文字类型的技巧。这个技巧使用never
T & never
是never
T | never
是T
第一个映射类型{[P in T]: P }
产生一个类型,该类型的每个键的值都与键名相同。因此,如果T
是'a' | 'b'
,则此映射类型将产生{a : "a", b: "b"}
第二个映射类型会为我们要删除的那些键生成一个never
的类型。因此,如果U
是'b'
,则此映射类型将产生{ b: never }
将这两个相交会产生{a : "a", b: "b"} & { b: never }
,而{a : "a", b: "b" & never }
会减少为{a : "a", b: never }
。
如果我们要获得上述类型(即(... & ...)[T]
)的值的并集,则将得到Diff
的结果,因为({a : "a", b: never })["a" | "b"]
将是"a" | never
所以"a"
但这是我们遇到的问题。回到打字稿2.4,如果我们用T
进行索引,则会得到一个错误(这个type Diff<T extends string, U extends string> = ({[P in T]: P } & {[P in U]: never })[T];
这是一个错误see playground),因为打字稿不满足于先前定义的交集是可被T
索引。在当前的打字稿(see)中,这实际上不再是问题。但是当这个技巧有用时,我们需要一些额外的东西来说服编译器允许通过T
进行索引。
这是{ [x: string]: never }
。它将允许按任何字符串进行索引(因此[T]
将起作用)。而且它不会影响索引操作的结果,因为其他任何键值都将与索引中的never
并入联合,而联合中的never
会消失。