打字稿打字的问题 [英] Issue with TypeScript typing

查看:16
本文介绍了打字稿打字的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请看下面的打字稿片段。 为什么不抛出编译错误呢?这难道不是一个明显的打字错误吗?我必须更改什么才能使它再次成为类型安全的?TYVM

type A<P> = {
  p?: never,
  q?: Partial<P>
}

type B<P> = {
  p?: Partial<P> 
  q?: never
}

type C<P> = A<P> | B<P>

const c: C<{ a: number}> = {
  p: {
    a: 1,
    b: 2   // <------ Why is this allowed?!?
  }
}

console.log(c)

单击here观看演示

推荐答案

这是一个known bug,其中excess property checking不以人们期望的方式应用于涉及联合和交集的嵌套类型。额外的属性检查是类型系统的一种附加功能,它只适用于对象文字,所以当它不适用时,就会回到structural subtyping规则,其中类型{a: A, b: B}{a: A}的子类型,因此前一种类型的值应该可以赋给后一种类型的变量。您可能想要转到the issue in Github并给它一个👍,或者解释您的用例(如果您认为它比那里列出的用例更引人注目)。希望有一天会有解决办法。

不过,在那之前,我不确定能做些什么。等同于过度属性检查的类型级是所谓的exact types,它们不作为具体类型存在于类型脚本中。有一些方法可以使用泛型帮助器函数和类型推断来模拟它们。在您的情况下,它将如下所示:

type Exactify<T, K extends keyof any>
  = T & { [P in Exclude<K, keyof T>]?: never };

type A<P, K extends keyof any=never> = {
  p?: never,
  q?: Partial<Exactify<P, K>>
}

type B<P, K extends keyof any=never> = {
  p?: Partial<Exactify<P, K>>
  q?: never
}

type C<P, K extends keyof any = never> = A<P, K> | B<P, K>

type KeyofKeyof<T> =
  keyof T | { [K in keyof T]: T[K] extends object ? keyof T[K] : never }[keyof T];

const asC = <T extends C<{ a: number }, KeyofKeyof<T>>>(c: T) => c;

const c = asC({
  p: {
    a: 1,
    b: 2   // <------ error
  }
})

是的,很难看。不确定这对你来说是否值得。它的工作方式是说C<P, K>与您的C<P>相同,只是增加了P类型以显式排除K中的所有额外属性。然后,我们使用帮助器函数asC()来推断给定传入参数的K的类型。因为有问题的键嵌套在下一层,所以我需要一个KeyofKeyof<T>类型来从下一层提取键(您不可能在不触及循环类型的情况下为所有级别提取键)。

现在将显示所需的错误。是吗?我想是的。

不管怎样,希望这会有帮助。祝你好运!

这篇关于打字稿打字的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆