TypeScript 是 JS 的超集,本质上他是拥有了静态类型(可选),和基于类的面向对象编程的一门语言,他将会被编译成 JS,并且整个类型检查过程是在编译的,也就不会导致性能问题。他某种程度上可以提前去帮助你免除一些较为低级的 BUG。最重要的是,因为微软一家亲的缘故,VSCODE 这个编辑器对于 TypeScript 具有天生的强大支持。因为上述原因,我开始学习 TypeScript。

我个人觉得 TypeScript 某种意义上可能会比较适合一些中大型的公司来使用,具有更强大的限制,能够让不同人写出来的代码尽可能的一致,限制在很多情况下都是一件至少不坏的事。

为了更好的帮助自己记录与快速回想 TypeScript 的大致功能,简单写一下 TypeScript 的主要功能。

基础类型

let a: String = 'name'

除此之外还有 Number 等基础类型

变量声明

type C = { a: string, b?: number }
function f({ a, b }: C): void {
  // 解构 + 类型检查 + 默认值
}

其余与 es6 基本相同。

接口

在很多 OOP 语言里都拥有接口,接口本质上是鸭子类型的一种思想体现,它可以去描述一种结构,并且建立一种验证关系。

interface LabelledValue {
  label: string
  width?: number // 可选属性
  readonly x: number // 只读属性
  [propName: string]: any // 索引签名
}
// 声明一个接口,内部拥有key为label,值为string的属性

function printLabel(labelledObj: LabelledValue) {
  console.log(labelledObj.label)
}

interface SearchFunc {
  (source: string, subString: string): boolean
} // 函数类型接口 定义参数列表,类型,返回值类型

tips: 如果传入参数为一个对象字面量,可能会收到额外类型检查,即不允许一个对象字面量拥有目标类型没有的属性。

简单来说就是在 ES6 类的基础上增加了修饰符,类的结构描述,静态类型

class Person {
  protected name: string // 修饰符 + 类的结构描述
  constructor(name: string) {
    this.name = name
  }
}

class Employee extends Person {
  private department: string

  constructor(name: string, department: string) {
    super(name) // this传递
    this.department = department
  }

  public getElevatorPitch() {
    return `Hello, my name is ${this.name} and I work in ${this.department}.`
  }
}

class Grid {
  static origin = { x: 0, y: 0 } // 静态方法
  calculateDistanceFromOrigin(point: { x: number; y: number }) {
    let xDist = point.x - Grid.origin.x
    let yDist = point.y - Grid.origin.y
    return Math.sqrt(xDist * xDist + yDist * yDist) / this.scale
  }
  constructor(public scale: number) {}
}

函数

let myAdd = function(x: number, y: number): number {
  return x + y
}

与 ES6 的区别并不大

泛型

泛型其实是被预留的空间,因为可能无法确定将来这个函数会被传入什么类型的数据

interface GenericIdentityFn {
    <T>(arg: T): T;
}

function identity<T>(arg: T): T {
    return arg;
}

let myIdentity: GenericIdentityFn = identity;

枚举

const enum Directions {
    Up,
    Down,
    Left,
    Right
}

let directions = [Directions.Up, Directions.Down, Directions.Left, Directions.Right]

模块与命名空间

总的来说,推荐用模块来引入,命名空间做单文件内部的分层。