在标记的不相交联合上运行的泛型函数-为什么在此需要类型说明?

时间:2019-06-22 19:45:15

标签: typescript typescript-generics

我正在努力理解为什么某种类型转换在这里会有所帮助。

功能如下:

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')并收到类型错误,因为street2EmailVerification上不存在的属性。
  • 上述功能在最后一行Type 'keyof V["attributes"]' cannot be used to index type EmailVerification | AddressVerification | ...etc.上出现错误

verification.attributes强制转换为(verification.attributes as V['attributes'])时,所有类型检查均正确。但是,我不知道为什么会这样。如果verificationV,为什么不将verification.attributes识别为V['attributes']?为什么显式键入它有效?

谢谢!

1 个答案:

答案 0 :(得分:0)

Answer from Typescript collaborator @jack-williams

  

属性访问和元素访问返回约束的相应属性类型,因此w.xw['x']的类型为A,这就是使用k的访问失败的原因。 一旦您退回到具体的东西,您以后就无法使用通用的东西编制索引。

     

访问x[k]之所以有效,是因为它使用了声明的类型,该类型是已被充分延迟的通用索引访问类型,因此保留了它的“通用性”。

链接的Github线程还包含有关将来如何改进此 的注释,以便按预期正确推断出属性访问。