TypeScript版本:typescript@3.7.0-dev.20190831
搜索词: tagged disjoint union generic
这个问题源于我在StackOverflow上提出的问题,@jcalz 慷慨地为我进行了研究。我将他的例子改编成一个更接近#17110的示例。
代码
interface A { a: string; }
interface W {
x: A
}
function foo<W1 extends W>(w: W1, k: keyof W1['x']) {
w.x[k]; // Type 'keyof W1["x"]' cannot be used to index type 'A'.
const x: W1['x'] = w.x; // Okay
x[k] // Okay
}
预期行为:
与#17110相同。然而,与#17110不同,W['x']
只有A
,而不是A | B | undefined
。给出的关于为什么#17110不是一个bug的解释是:keyof W1["x"]
的约束是keyof (A | B)
,简化后为keyof A & keyof B
,即never
(因为没有共同属性)。
然而,在这里keyof W1['x']
是keyof A
,这并不是never
。
实际行为:
与#17110相同。
** playground链接:**http://www.typescriptlang.org/play/#code/JYOwLgpgTgZghgYwgAgILIN7LgLmQZzClAHMBuZAXwChrRJZEUB1Ta5D5ADz1WpuowAriARhgAexDIYEiQB5mARmQQukEABN8yZgD4AFAHc8ygDTIA1nksQAnhJi6lAbQDkXNwF0AlGw5GAHRcLpZeFAD0EcgAKnYADihutg5Oyi4ARFwZXm7ICHAgIBJgyABGKEL4EJrIYBLIoJpqdQlJqG6BtBwIUoTcpq4e3sgAvMhBXJHRAPKWcHbs3KFeyFHIcwv8QA
相关问题:#17110
2条答案
按热度按时间k2fxgqgv1#
属性访问和元素访问返回约束的相应属性类型,因此
w.x
和w['x']
具有类型A
,这就是为什么使用k
访问失败的原因。一旦你回退到具体的东西,你就不能再用通用的东西进行索引。访问
x[k]
之所以有效,是因为它使用了声明的类型,这是一个已经足够延迟的泛型索引访问类型,因此保留了其“泛型性”。我认为唯一可能解决这个问题的方法是为属性访问表达式合成更多的索引访问类型,也许在某些条件下,例如作为更大的属性访问链的一部分,其中外部键是泛型的。
感觉像是设计限制,但我不确定。
jw5wzhpr2#
在当前设计下,是这样的。我认为我们可能有将
w.x: A
切换到w.x: W1['x']
的机器,但这听起来像是一个破坏性的改变。要实现这一点,我们需要