本文介绍了在标记的不相交联合上运行的泛型函数 - 为什么这里需要类型规范?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我很难理解为什么某种类型转换在这里有帮助.

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: 'test@123.com', someOtherEmailSpecificProperty: 'foo' }},而 AddressVerification 可能看起来像 { type: 'address', attributes: { street1: 'Foo', street2: 'Bar', city: '...', ... }}, 和 type Verification = EmailVerification |地址验证 |...其他验证
  • 我希望我的函数能够对传递的 attribute 进行类型检查,这样我就可以执行 getAttributeFromVerification(myEmailVerification, 'street2') 并获取类型错误,因为 street2EmailVerification 的属性中不存在.
  • 最后一行的上述函数错误 Type 'keyof V["attributes"]' 不能用于索引类型 EmailVerification |地址验证 |...等
  • Verification is a disjoint union that looks like { type: DisjointUnionTag, attributes: { ...properties unique to a given verification type } }. So EmailVerification may look like { type: 'email', attributes: { email: 'test@123.com', someOtherEmailSpecificProperty: 'foo' }}, whereas AddressVerification may look like { type: 'address', attributes: { street1: 'Foo', street2: 'Bar', city: '...', ... }}, and type Verification = EmailVerification | AddressVerification | ...other verifications
  • I want my function to be able to typecheck attributes passed, such that I can do getAttributeFromVerification<EmailVerification>(myEmailVerification, 'street2') and get a type error since street2 does not exist on EmailVerification'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']) 时,所有类型检查都正确.但是,我不知道为什么会这样.如果 verificationV,为什么 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:

属性访问和元素访问返回约束对应的属性类型,所以wxw['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.

这篇关于在标记的不相交联合上运行的泛型函数 - 为什么这里需要类型规范?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-21 09:17