TypeScript-类类型
类类型
类本身就是一种类型,类的名字可以直接作为类型名:
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";
只读属