问题描述
我很难理解为什么某种类型转换在这里有帮助.
I'm struggling to understand why a certain typecast helps here.
功能如下:
function getAttributeFromVerification<V extends Verification>(
verification: V | null,
attribute: keyof V['attributes']
) {
// the verification may not exist at all
if (verification == null) {
return null
}
// the verification existing but missing the given attribute is a distinct error case
return verification.attributes[attribute] || 'some value signifying attribute is missing'
}
关于类型的一些细节:
Verification
是一个不相交的联合,看起来像{ type: DisjointUnionTag, attributes: { ...properties unique to a given verify type } }
.所以EmailVerification
可能看起来像{ type: 'email', attributes: { email: '[email protected]', someOtherEmailSpecificProperty: 'foo' }}
,而AddressVerification
可能看起来像{ type: 'address', attributes: { street1: 'Foo', street2: 'Bar', city: '...', ... }}
, 和type Verification = EmailVerification |地址验证 |...其他验证
- 我希望我的函数能够对传递的
attribute
进行类型检查,这样我就可以执行getAttributeFromVerification(myEmailVerification, 'street2')
并获取类型错误,因为street2
在EmailVerification
的属性中不存在. - 最后一行的上述函数错误
Type 'keyof V["attributes"]' 不能用于索引类型 EmailVerification |地址验证 |...等
Verification
is a disjoint union that looks like{ type: DisjointUnionTag, attributes: { ...properties unique to a given verification type } }
. SoEmailVerification
may look like{ type: 'email', attributes: { email: '[email protected]', someOtherEmailSpecificProperty: 'foo' }}
, whereasAddressVerification
may look like{ type: 'address', attributes: { street1: 'Foo', street2: 'Bar', city: '...', ... }}
, andtype Verification = EmailVerification | AddressVerification | ...other verifications
- I want my function to be able to typecheck
attribute
s passed, such that I can dogetAttributeFromVerification<EmailVerification>(myEmailVerification, 'street2')
and get a type error sincestreet2
does not exist onEmailVerification
's attributes. - The above function errors on the final line with
Type 'keyof V["attributes"]' cannot be used to index type EmailVerification | AddressVerification | ...etc.
当将 verification.attributes
转换为 (verification.attributes as V['attributes'])
时,所有类型检查都正确.但是,我不知道为什么会这样.如果 verification
是 V
,为什么 verification.attributes
不被识别为 V['attributes']
?为什么显式输入它有效?
When casting verification.attributes
to (verification.attributes as V['attributes'])
everything typechecks properly. However, I have no idea why this works. If verification
is a V
, why isn't verification.attributes
being recognized as V['attributes']
? And why does explicitly typing it work?
谢谢大家!
推荐答案
Answer来自 Typescript 合作者@jack-williams:
属性访问和元素访问返回约束对应的属性类型,所以wx
和w['x']
的类型为A
,这就是使用 k
访问失败的原因.一旦你回到具体的东西,你以后就不能用通用的东西来索引了.
访问 x[k]
之所以有效,是因为它使用声明的类型,该类型是已充分延迟的泛型索引访问类型,因此保留了其通用性".
The access x[k]
works because it uses the declared type which is a generic indexed access type which has been sufficiently deferred, therefore retaining its 'generic-ness'.
链接的 Github 线程还包括关于如何在未来改进此的评论,以便按预期正确推断属性访问.
The linked Github thread also includes a comment regarding how this may be improved in the future such that the property access is correctly inferred as expected.
这篇关于在标记的不相交联合上运行的泛型函数 - 为什么这里需要类型规范?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!