我正在努力理解为什么某种类型转换在这里会有所帮助。
功能如下:
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 verification type } }
。因此EmailVerification
看起来像{ type: 'email', attributes: { email: 'test@123.com', someOtherEmailSpecificProperty: 'foo' }}
,而AddressVerification
看起来像{ type: 'address', attributes: { street1: 'Foo', street2: 'Bar', city: '...', ... }}
和type Verification = EmailVerification | AddressVerification | ...other verifications
attribute
进行类型检查,这样我才能执行getAttributeFromVerification<EmailVerification>(myEmailVerification, 'street2')
并收到类型错误,因为street2
在EmailVerification
上不存在的属性。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']
?为什么显式键入它有效?
谢谢!
答案 0 :(得分:0)
Answer from Typescript collaborator @jack-williams:
属性访问和元素访问返回约束的相应属性类型,因此
w.x
和w['x']
的类型为A
,这就是使用k
的访问失败的原因。 一旦您退回到具体的东西,您以后就无法使用通用的东西编制索引。访问
x[k]
之所以有效,是因为它使用了声明的类型,该类型是已被充分延迟的通用索引访问类型,因此保留了它的“通用性”。
链接的Github线程还包含有关将来如何改进此 的注释,以便按预期正确推断出属性访问。