TypScript通常被称为structural typing language,其类型判断系统仅考虑值的成员(属性)与目标类型的(错误)匹配.

在这方面,TypScript实际上和 struct 上如何定义基元类型(例如stringnumber)?是否有声明的接口包含所有所需的属性?(字符串为charaAtconcat等.数字为toExponentialvalueOf等)

尽管如此,我还是不太容易判断 struct 错误是什么阻碍了此类情况下的作业(job):

type AB = 'A' | 'B';
const c: AB = 'C'; // Type '"C"' is not assignable to type 'AB'.

哪些房产没有'C',而'A''B'上有'C'

推荐答案

Structural typing仅真正适用于比较对象或类对象类型. 或者至少是比较两种类型的 struct 或形状的部分.这种比较需要在某个地方"触底",这几乎是不言而喻的,否则您可能能够得出几乎每对类型都共享一个 struct (例如,如果"a""b"由于都是string而具有相同的 struct ,那么{a: Date}{b: Date}将具有相同的 struct ,因为键"a""b"是相同的,并且很快您最终得出结论,类型景观的大片实际上是一种类型).

比较两种类型的形状本质上是一个迭代过程,要终止该过程,您需要一些基本情况.基本词充当此类基本 case .这些基本情况比 struct 类型更接近nominal typing. 如果两种名义类型在不同的地方声明,则被认为是不同的.


TypScript中的非空primitives被视为与其自动装箱包装器对象相对应的interfaces的子类型. 这些接口具有与基元关联的方法和属性,例如toUpperCase()代表StringtoFixed()代表Number. 这些基元是其包装器类型的proper个子类型,这意味着,例如,string(基元类型)被认为可分配给String(包装器对象类型)but not vice versa:

declare let s: string;
declare let S: String;
S = s; // okay
s = S; // error

此外,literal types是其相关原始类型的适当子类型.例如,"a"被认为可分配给string,但反之亦然:

declare let a: "a";
declare let s: string;
s = a; // okay
a = s; // error

这为类型层次 struct 增加了一点深度,因此"a"将可分配给{length: number},因为"a"可分配给string,而string可分配给String,而String在 struct 上可分配给{length: number}:

let lengthable: { length: number } = a; // okay

因此,您确实可以将基元的 struct 与其他类型进行比较,但单独 struct 并不能解释类型的差异.


如果纯粹从 struct 上思考有帮助,那么您可以通过想象类型具有区分它们的"幻影"属性来做到这一点.您可能会认为string看起来像String & {[str]: true},而str是某种独特的符号.事实上,这样的技术实际上在实践中使用到了emulate nominal typing;参见Intersection of primitive and object types with Typescript.

Playground link to code

Typescript相关问答推荐

如何根据参数的值缩小函数内的签名范围?

有没有可能使用redux工具包的中间件同时监听状态的变化和操作

在泛型类型中对子代执行递归时出错

有没有办法解决这个问题,类型和IntrinsicAttributes类型没有相同的属性?

如何推断计算逻辑的类型

如果字符串文字类型是泛型类型,则用反引号将该类型括起来会中断

如何使默认导出与CommonJS兼容

类型脚本映射类型:从对象和字符串列表到键值对象

获取一个TypeScrip对象,并将每个属性转换为独立对象的联合

以Angular 自定义快捷菜单

在列表的指令中使用intersectionObservable隐藏按钮

创建Angular 为17的动态形状时出错

从route.参数获取值.订阅提供";无法读取未定义";的属性

作为参数的KeyOf变量的类型

有没有一种更好的方法来存储内存中的数据,而不是在类型脚本中使用数组和基于索引的函数?

递归类型别名的Typescript 使用

窄SomeType与SomeType[]

如何知道使用TypeScript时是否在临时工作流内运行

为什么 Typescript 无法正确推断数组元素的类型?

如何使用布尔值构建对象 TYPE,但至少有一个必须为 true