Appearance
TypeScript 接口与类
TypeScript 的接口和类提供了面向对象编程的强大功能,使代码更加结构化和可维护。
接口(Interface)
接口是 TypeScript 的核心特性之一,用于定义对象的结构和契约。
基本接口
typescript
interface User {
name: string;
age: number;
email?: string; // 可选属性
readonly id: number; // 只读属性
}
const user: User = {
name: "Alice",
age: 25,
id: 12345
};
// user.id = 123; // 错误:不能修改只读属性
函数类型接口
typescript
interface SearchFunc {
(source: string, subString: string): boolean;
}
let mySearch: SearchFunc = function(source: string, subString: string): boolean {
let result = source.search(subString);
return result > -1;
};
可索引类型
typescript
interface StringArray {
[index: number]: string;
}
let myArray: StringArray = ["Bob", "Fred"];
interface NumberDictionary {
[index: string]: number;
length: number; // 可以,length 是 number 类型
name: string; // 错误,name 的类型与索引类型不匹配
}
继承接口
typescript
interface Shape {
color: string;
}
interface Square extends Shape {
sideLength: number;
}
let square: Square = {
color: "blue",
sideLength: 10
};
// 多重继承
interface PenStroke {
penWidth: number;
}
interface Square2 extends Shape, PenStroke {
sideLength: number;
}
let square2: Square2 = {
color: "blue",
sideLength: 10,
penWidth: 5.0
};
混合类型
typescript
interface Counter {
(start: number): string;
interval: number;
reset(): void;
}
function getCounter(): Counter {
let counter = <Counter>function (start: number) { };
counter.interval = 123;
counter.reset = function () { };
return counter;
}
let c = getCounter();
c(10);
c.reset();
c.interval = 5.0;
类(Class)
TypeScript 完全支持 ES6 的类语法,并添加了额外的功能。
基本类
typescript
class Greeter {
greeting: string;
constructor(message: string) {
this.greeting = message;
}
greet(): string {
return "Hello, " + this.greeting;
}
}
let greeter = new Greeter("world");
继承
typescript
class Animal {
name: string;
constructor(theName: string) { this.name = theName; }
move(distanceInMeters: number = 0) {
console.log(`${this.name} moved ${distanceInMeters}m.`);
}
}
class Snake extends Animal {
constructor(name: string) {
super(name); // 派生类的构造函数必须调用 super()
}
move(distanceInMeters = 5) {
console.log("Slithering...");
super.move(distanceInMeters);
}
}
class Horse extends Animal {
constructor(name: string) { super(name); }
move(distanceInMeters = 45) {
console.log("Galloping...");
super.move(distanceInMeters);
}
}
let sam = new Snake("Sammy the Python");
let tom: Animal = new Horse("Tommy the Palomino");
sam.move();
tom.move(34);
公共和私有修饰符
typescript
class Animal2 {
private name: string;
constructor(theName: string) { this.name = theName; }
}
// new Animal2("Cat").name; // 错误: 'name' 是私有的
// 保护修饰符
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() {
return `Hello, my name is ${this.name} and I work in ${this.department}.`;
}
}
let howard = new Employee("Howard", "Sales");
console.log(howard.getElevatorPitch());
// console.log(howard.name); // 错误
参数属性
typescript
class Octopus {
readonly numberOfLegs: number = 8;
constructor(readonly name: string) { // 参数属性创建并初始化成员
}
}
存取器
typescript
class Employee3 {
private _fullName: string = "";
get fullName(): string {
return this._fullName;
}
set fullName(newName: string) {
if (passcode && passcode == "secret passcode") {
this._fullName = newName;
} else {
console.log("Error: Unauthorized update of employee!");
}
}
}
let employee = new Employee3();
employee.fullName = "Bob Smith";
if (employee.fullName) {
console.log(employee.fullName);
}
静态属性
typescript
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 grid1 = new Grid(1.0); // 1x scale
let grid2 = new Grid(5.0); // 5x scale
console.log(grid1.calculateDistanceFromOrigin({x: 10, y: 10}));
console.log(grid2.calculateDistanceFromOrigin({x: 10, y: 10}));
抽象类
typescript
abstract class Animal3 {
abstract makeSound(): void;
move(): void {
console.log("roaming the earth...");
}
}
class Dog extends Animal3 {
makeSound(): void {
console.log("Woof! Woof!");
}
}
// let a = new Animal3(); // 错误: 不能创建抽象类的实例
let d = new Dog(); // 正确
高级接口概念
函数接口
typescript
interface Counter {
(start: number): string;
interval: number;
reset(): void;
}
function createCounter(): Counter {
let counter = <Counter>function (start: number) { };
counter.interval = 123;
counter.reset = function () { };
return counter;
}
接口继承类
typescript
class Control {
private state: any;
}
interface SelectableControl extends Control {
select(): void;
}
class Button extends Control implements SelectableControl {
select() { }
}
class TextBox extends Control {
select() { }
}
// 错误:Image 类不能实现 SelectableControl
// 因为它没有继承 Control
// class Image implements SelectableControl {
// select() { }
// }
类与接口的实用模式
配置对象模式
typescript
interface Config {
width?: number;
height?: number;
color?: string;
}
function createBox(config: Config): { width: number; height: number; color: string } {
let newBox = { width: 0, height: 0, color: "white" };
if (config.width) {
newBox.width = config.width;
}
if (config.height) {
newBox.height = config.height;
}
if (config.color) {
newBox.color = config.color;
}
return newBox;
}
let myBox = createBox({ width: 100, color: "red" });
索引签名
typescript
interface StringArray {
[index: number]: string;
}
interface NumberDictionary {
[index: string]: number;
length: number; // 可以,length 是 number 类型
name: string; // 错误,类型不匹配
}
// 防止意外添加属性
interface SquareConfig {
color?: string;
width?: number;
[propName: string]: any; // 允许添加其他属性
}
小结
接口和类是 TypeScript 面向对象编程的核心。接口定义契约,类实现具体功能。通过合理使用接口和类,可以创建结构清晰、类型安全的代码,提高代码的可维护性和可扩展性。