代码网 logo
AI

TypeScript-类类型

小开开2020-12-11 17:16:04283

类类型

类本身就是一种类型,类的名字可以直接作为类型名:

typescript 复制代码
// 定义类
class TypeA {
  // ...
}

// 声明TypeA类型
let a: TypeA;
// 赋值TypeA类型
a = new TypeA();

语法扩展

属性扩展

在ES6中,实例属性和静态属性不能直接定义在类内部:

javascript 复制代码
// 下面是ES6代码

// 不合法的定义
class Greeter {
  // 错误,实例属性不能定义在类里
  greeting = 'world';
  // 错误,静态属性不能定义在类里
  static greeting = 'world';
}

// 合法的定义
class Greeter {
  constructor(){
    // 正确,ES6中实例属性只能定义在构造器内部
    this.greeting = 'world';
  }
}
// 正确,ES6中静态属性只能定义在类外部
Greeter.greeting = 'world';

而在TypeScript中,下面的定义是合法的:

typescript 复制代码
// 下面是TypeScript代码

class Greeter {
  // 定义实例属性并初始化
  greeting: string = 'world';

  // 定义静态属性并初始化
  static greeting: string = 'world';
}

访问控制 public/private/protected 修饰符

在TypeScript中,修饰符不是必须的,他们主要用来控制类成员的可访问性,类成员包括:

  • 实例属性
  • 静态属性
  • 实例方法
  • 静态方法
  • 构造函数
  • getter/setter

如果你没有显式为成员添加访问控制修饰符,那么将默认为 public

typescript 复制代码
class Animal {
  // name属性未显式添加修饰符,默认为public
  age: number; 

  // 显式添加 private
  private name: string;

  // show方法未显式添加修饰符,默认为public
  show(){ 
    // ...
  }
}

// 与上述定义等价
class Animal {
  public age: number;
  private name: string;
  public show() {
    // ...
  }
}

当成员被标记成 private 时,它不能在声明它的类外部访问。比如:

typescript 复制代码
class Animal {
    private name: string;
    constructor(theName: string) { this.name = theName; }
}

// 错误: 不能在类外访问私有成员
// error TS2341: Property 'name' is private and only accessible within class 'Animal'
new Animal("Cat").name;

protected 修饰符与 private 修饰符的行为相似,都不能在类的外部访问。但有一点不同, protected 成员可以在派生类中访问。例如:

typescript 复制代码
// 定义基类
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.department = department;
  }

  public getElevatorPitch() {
    // 正确,来自父类的name成员在派生类里可以访问。虽然它位于Persion类的外部
    return `Hello, my name is ${this.name} and I work in ${this.department}.`;
  }
}

let howard = new Employee("Howard", "Sales");
console.log(howard.getElevatorPitch());

// 错误,受保护的成员 name 不能在外部访问
// error TS2445: Property 'name' is protected and only accessible within class 'Person' and its subclasses
console.log(howard.name); 

访问控制修饰符可直接用于构造函数的参数声明,这是一个语法糖,可以非常方便的实现属性的定义并初始化:

typescript 复制代码
class Animal {
  // private修饰符用于构造器的name参数前
  constructor(private name: string) {}
}

// 以上定义相当于
class Animal {
  private name: string;
  constructor(name: string) {
    this.name = name;
  }
}

只读修饰符 readonly

你可以使用 readonly 关键字将属性设置为只读的。 只读属性必须声明时构造函数里被初始化

typescript 复制代码
class Octopus {
  readonly name: string;
  // 在属性声明时初始化
  readonly numberOfLegs: number = 8;
  constructor (theName: string) {
    // 在构造函数里初始化
    this.name = theName;
  }
}
let dad = new Octopus("Man with the 8 strong legs");

// 错误! name 是只读的
// error TS2540: Cannot assign to 'name' because it is a constant or a read-only property
dad.name = "Man with the 3-piece suit";

只读属

广告