Notes on TypeScript

2023 年 11 月 12 日

类型

对象字面量

对象字面量在将它们分配给其他变量或将它们作为参数传递时会受到特殊处理并进行过多的属性检查。如果对象字面量具有“目标类型”没有的任何属性,您将收到错误

泛型

泛型就是将两个或多个具有相同类型的值关联起来!

never 类型

缩小范围时,您可以将并集的选项减少到消除所有可能性并且没有任何剩余的程度。在这些情况下,TypeScript 将使用 never 类型来表示不应该存在的状态。

never 类型可分配给每种类型;但是,没有任何类型可以分配给 nevernever 本身除外)。这意味着您可以使用缩小范围并依靠 never 出现来在 switch 语句中进行详尽的检查。

可区分的联合类型

当联合中的每个类型都包含具有文字类型的公共属性时,TypeScript 会认为这是一个可区分的联合,并且可以缩小联合的成员范围。

typeof

Note: don’t use typeof x === 'object' to check whether something is a valid object, because it will return true for arrays as well.
注意:不要使用 typeof x === 'object' 来检查某物是否是有效对象,因为它也会为数组返回 true

void, undefined, null

与 void 的区别是,undefined 和 null 是所有类型的子类型。也就是说 undefined 类型的变量,可以赋值给 number 类型的变量:

而  void  类型的变量不能赋值给  number  类型的变量:

类型推论

TypeScript 会在没有明确的指定类型的时候推测出一个类型,这就是类型推论。

如果定义的时候没有赋值,不管之后有没有赋值,都会被推断成  any  类型而完全不被类型检查

let myFavoriteNumber;
myFavoriteNumber = 'seven';
myFavoriteNumber = 7;

类型别名和接口

Type aliases and interfaces are very similar, and in many cases you can choose between them freely. Almost all features of an interface are available in type, the key distinction is that a type cannot be re-opened to add new properties vs an interface which is always extendable.
类型别名和接口非常相似,在许多情况下您可以在它们之间自由选择。 interface  的几乎所有功能都可以在  type  中使用,主要区别在于类型无法重新打开以添加新属性,而接口始终是可扩展的。

类型断言

Sometimes this rule can be too conservative and will disallow more complex coercions that might be valid. If this happens, you can use two assertions, first to any (or unknown, which we’ll introduce later), then to the desired type:
有时,此规则可能过于保守,并且不允许可能有效的更复杂的强制。如果发生这种情况,您可以使用两个断言,首先是  any (或  unknown ,我们将在稍后介绍),然后是所需的类型:

const a = expr as any as T;

Type Gymnastics

属性修饰符

readonly

It’s important to manage expectations of what readonly implies. It’s useful to signal intent during development time for TypeScript on how an object should be used. TypeScript doesn’t factor in whether properties on two types are readonly when checking whether those types are compatible, so readonly properties can also change via aliasing.
管理对 readonly 含义的期望非常重要。在 TypeScript 开发期间发出有关如何使用对象的意图非常有用。在检查两种类型是否兼容时,TypeScript 不会考虑两种类型的属性是否为 readonly ,因此 readonly 属性也可以通过别名进行更改。

interfece

接口合并

interface Shape {
    color: string;
}

interface Shape {
    width: number;
}

// 合并后的结果是一个具有 color 和 width 属性的单一接口
const square: Shape = {
    color: "blue",
    width: 10
};

如果两个接口具有相同名称,并且其中一个接口包含了另一个接口中已经定义的成员,会发生冲突。在这种情况下,TypeScript 将会报错。

对象属性修饰符

在 TypeScript 中,privateprotectedpublic 是用于定义类成员(属性和方法)可访问性的修饰符,它们有以下区别:

  1. private
  • private 修饰符限制了成员的访问权限,只能在定义该成员的类内部访问,外部无法访问。
  • private 成员对继承类也是不可见的,子类无法直接访问父类的 private 成员。
  1. protected
  • protected 修饰符也限制了成员的访问权限,但允许在继承的子类中进行访问。
  • protected 成员可以在定义该成员的类内部访问,也可以在继承的子类中访问,但在类的实例中是不可访问的。
  1. public
  • public 修饰符表示成员是公共的,可以在任何地方被访问。
  • public 成员可以在类内部访问,也可以在类的实例中访问,外部也可以访问。

简而言之,private 限制了只能在类内部访问,protected 允许在继承的子类中访问,而 public 则没有访问限制,可以在任何地方被访问。