typescript - TypeScript 输入问题

标签 typescript types typescript-typings

请查看以下 TypeScript 片段。 为什么这不会引发编译错误?这不是明显的类型错误吗?我必须更改什么才能使其再次成为类型安全的? 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并给它一个 👍 或解释你的用例,如果你认为它比已经列出的那些更有吸引力。希望有一天会有修复。

不过,在那之前,我不确定能做什么。相当于超额属性(property)检查的类型级别是所谓的exact types ,它们在 TypeScript 中不作为具体类型存在。有一些方法可以使用通用辅助函数和类型推断来模拟它们......在你的情况下它看起来像这样:

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 type 被扩充以明确排除 K 中的所有额外属性.然后我们使用辅助函数 asC()推断 K 的类型给定传入的参数。由于有问题的键嵌套了一层,我需要一个 KeyofKeyof<T> type 从一个级别向下提取键(如果不点击循环类型,你不能对所有级别执行此操作)。

所需的错误现在出现了。好极了?我猜。

无论如何希望对您有所帮助。祝你好运!

关于typescript - TypeScript 输入问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55334784/

相关文章:

typescript - 如何在 typescript 中创建对象时通过传递JSON来初始化构造函数参数

typescript - 如何为 TypeScript 配置自定义全局接口(interface)(.d.ts 文件)?

typescript - 将 string[] 字面量转换为 string 类型字面量

typescript - 使用 TypeScript 在节点应用程序中导入 JSON 文件

C++11 在成员函数上应用 result_of,失败,为什么?

c# - 为什么我应该在 C# 中使用 int 而不是 byte 或 short

typescript - knockout es5 类型

typescript - 如何将分离的 Koa-Router 与 Typescript 结合起来

Angular 8 : How to use formControlName with FormArray

c++ - 如何将 float 转换为非标准编码