我不明白为什么TypeScript对相等类型(ObjType1和ObjType2)有不同的建议?

在第一种情况下,它的并集类型为"a" | "b"

在第二种情况下,对于相同的类型,它没有提供联合类型.为什么?

const obj = {
  a: 1,
  b: 1,
};

type ObjType1 = {
  a: number;
  b: number;
}

type ObjType2 = typeof obj;

type R1 = ObjType1 extends ObjType2 ? true : false; // true
type R2 = ObjType2 extends ObjType1 ? true : false; // true


type Result1 = keyof ObjType2; // type Result1 = "a" | "b"

type Result2 = keyof ObjType1; // type Result2 = keyof ObjType1

Sandbox

推荐答案

"a" | "b"keyof ObjType1在该代码中是完全相同的类型.

在第二种情况下,对于相同的类型,它没有提供联合类型.

keyof ObjType1 is为联合型.这只是"a" | "b"的另一个名字.它们的含义是相同的,并且可以互换(直到或除非您更改了ObjType1obj的定义).

这里唯一的区别是TypeScript用于显示目的的类型的名称(例如,它通过语言服务器进程向IDE报告的内容).但是TypeScript的类型系统几乎从不关心名称/标签/别名(接口的例外是declaration merging).类型系统是structural;它关心的是shape个类型,而不是它们被称为什么.

至于在第二种情况下,为什么TypeScrip Select 名字/标签/任何东西keyof ObjType1而不是"a" | "b",我怀疑这是因为它提供了更有用的信息--它告诉你类型的含义来自哪里.(当然,第一个示例中的keyof typeof obj也将提供比"a" | "b"更多的信息,但是您必须知道obj是运行时标识符,而不是类型.)


?或许我应该称它为label?我认为alias不太适用于这里……

Typescript相关问答推荐

如何使用Generics保留构造函数的类型信息?

动态判断TypScript对象是否具有不带自定义类型保护的键

如何在排版中正确键入中间件链和控制器链

扩展函数签名中的参数类型,而不使用泛型

rxjs forkJoin在错误后不会停止后续请求

如何通过TypeScript中的工厂函数将区分的联合映射到具体的类型(如类)?

泛型类型,引用其具有不同类型的属性之一

使用Dockerfile运行Vite React应用程序时访问env变量

MatTool提示在角垫工作台中不起作用

如何通过TypeScrip中的函数防止映射类型中未能通过复杂推理的any值

返回嵌套props 的可变元组

ANGLE订阅要么不更新价值,要么不识别价值变化

在打字脚本中对可迭代对象进行可变压缩

带投掷的收窄类型

使用Type脚本更新对象属性

如何创建一个将嵌套类属性的点表示法生成为字符串文字的类型?

映射类型不是数组类型

Typescript循环函数引用

如何在 TypeScript 类型定义中简化定义长联合类型

const nav: typechecking = useNavigation() 和 const nav = useNavigation() 之间有什么区别?