目录
联合类型(Union Types)
联合类型允许一个变量可以是几种类型之一。使用管道符(|
)分隔每个类型,赋值时可以根据设置的类型来赋值。
注意:只能赋值指定的类型,如果赋值其它类型就会报错。
创建联合类型的语言格式如下
Type1|Type2|Type3
let value: string | number;
value = "Hello, World!"; // 正确,类型为 string
value = 123; // 正确,类型为 number
// value = true; // 错误,类型不是 string 或 number
联合类型数组
虽然联合类型主要用于单个变量,但也可以用于数组元素,表示数组中的元素可以是多种类型之一。
示例
let mixedArray: (string | number)[];
mixedArray = ["Hello", 123, "TypeScript"]; // 正确
// mixedArray = [true, false]; // 错误,类型不是 string 或 number
接口
接口是一系列抽象方法的声明,是一些方法特征的集合,这些方法都应该是抽象的,需要由具体的类去实现,然后第三方就可以通过这组抽象方法调用,让具体的类执行具体的方法。
定义接口
interface Person {
name: string;
age: number;
greet(): void;
}
实现接口
一个类可以通过implements
关键字来实现一个接口,从而确保该类具备接口中定义的所有属性和方法。
class Employee implements Person {
name: string;
age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
greet() {
console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);
}
}
let emp = new Employee("John Doe", 30);
emp.greet();
// 输出: Hello, my name is John Doe and I am 30 years old.
接口中的索引签名
索引签名允许你在接口中定义一个对象的属性键和值的类型。索引签名可以是数字或字符串,用于描述对象中可能存在的任意键和值
interface StringIndexedObject {
[key: string]: any;
}
let obj: StringIndexedObject = {a: 1, b: 'hello', c: true};
联合类型和接口
联合类型和接口可以一起使用,以提供更强大的类型检查功能。例如,你可以创建一个接口,其属性可以是联合类型
interface User {
id: number;
name: string;
data: string | number | boolean;
}
let user: User = {
id: 1,
name: 'John Doe',
data: 'Some string data'
};
user.data = 123; // 正确,类型为 number
user.data = true; // 正确,类型为 boolean
接口和数组
接口中我们可以将数组的索引值和元素设置为不同类型,索引值可以是数字或字符串
interface NumberArray {
[index: number]: number;
}
let numArray: NumberArray = [1, 2, 3, 4];
接口继承
接口继承就是说接口可以通过其他接口来扩展自己。
Typescript 允许接口继承多个接口。
继承使用关键字 extends。
单接口继承
interface Animal {
name: string;
eat(): void;
}
interface Dog extends Animal {
bark(): void;
}
class DogImpl implements Dog {
name: string;
constructor(name: string) {
this.name = name;
}
eat() {
console.log(`${this.name} is eating.`);
}
bark() {
console.log(`${this.name} is barking.`);
}
}
多接口继承
(TypeScript不支持传统意义上的多继承,但可以通过组合多个接口来实现类似效果):
虽然TypeScript不支持类直接多继承,但你可以通过让类实现多个接口来达到类似的效果。
interface Flyable {
fly(): void;
}
interface Swimmable {
swim(): void;
}
interface SuperCreature extends Flyable, Swimmable { }
class Dragon implements SuperCreature {
fly() {
console.log('Dragon is flying.');
}
swim() {
console.log('Dragon is swimming.');
}
}
在这个例子中,SuperCreature
接口通过继承Flyable
和Swimmable
接口,定义了一个同时具备飞行和游泳能力的超级生物。然后,Dragon
类实现了这个超级接口。
TypeScript 类
TypeScript 是面向对象的 JavaScript。
类描述了所创建的对象共同的属性和方法。
TypeScript 支持面向对象的所有特性,比如 类、接口等。
TypeScript 类定义方式如下:
class className {
// 类的属性和方法定义在这里
constructor(parameters) {
// 构造函数,用于初始化对象
}
// 类的方法
methodName() {
// 方法实现
}
}
定义类的关键字为 class,后面紧跟类名,类可以包含以下几个模块(类的数据成员):
字段 − 字段是类里面声明的变量。字段表示对象的有关数据。
构造函数 − 类实例化时调用,可以为类的对象分配内存。
方法 − 方法为对象要执行的操作。
创建实例化对象
我们使用 new 关键字来实例化类的对象,语法格式如下:
var object_name = new class_name([ arguments ])
类实例化时会调用构造函数,例如:
var obj = new Car("Engine 1")
类中的字段属性和方法可以使用 . 号来访问:
// 访问属性
obj.field_name
// 访问方法
obj.function_name()
类的继承
TypeScript 支持继承类,即我们可以在创建类的时候继承一个已存在的类,这个已存在的类称为父类,继承它的类称为子类。
关键字extends
类继承使用关键字 extends,子类除了不能继承父类的私有成员(方法和属性)和构造函数,其他的都可以继承。
class ElectricCar extends Car {
battery: number;
constructor(engine: string, battery: number) {
super(engine); // 调用父类的构造函数
this.battery = battery;
}
chargeBattery(): void {
console.log(`Battery ${this.battery} kWh is charging.`);
}
}
TypeScript 一次只能继承一个类,不支持继承多个类,但 TypeScript 支持多重继承(A 继承 B,B 继承 C)。
语法格式如下:
class child_class_name extends parent_class_name
实例化子类对象
var myElectricCar = new ElectricCar("Electric V8", 100);
myElectricCar.startEngine(); // 输出: Engine Electric V8 started.
myElectricCar.chargeBattery(); // 输出: Battery 100 kWh is charging.
继承类的方法重写
类继承后,子类可以对父类的方法重新定义,这个过程称之为方法的重写
其中 super 关键字是对父类的直接引用,该关键字可以引用父类的属性和方法
class SportsCar extends Car {
topSpeed: number;
constructor(engine: string, topSpeed: number) {
super(engine);
this.topSpeed = topSpeed;
}
// 重写父类的方法
startEngine(): void {
console.log(`Revving up engine ${this.engine} to top speed
${this.topSpeed} mph!`);
}
}
实例化并重写方法
var mySportsCar = new SportsCar("Turbo V6", 200);
mySportsCar.startEngine();
// 输出: Revving up engine Turbo V6 to top speed 200 mph!
使用super关键字
super关键字用于调用父类的构造函数和方法
class LuxuryCar extends Car {
interior: string;
constructor(engine: string, interior: string) {
super(engine); // 调用父类的构造函数
this.interior = interior;
}
describeCar(): void {
super.startEngine(); // 调用父类的方法
console.log(`This luxury car has a ${this.interior} interior.`);
}
}
实例化并调用
var myLuxuryCar = new LuxuryCar("V12", "leather");
myLuxuryCar.describeCar();
// 输出:
// Engine V12 started.
// This luxury car has a leather interior.
static 静态成员
static 关键字用于定义类的数据成员(属性和方法)为静态的,静态成员可以直接通过类名调用
class CarFactory {
static buildCar(engine: string): Car {
return new Car(engine);
}
}
调用静态成员
var anotherCar = CarFactory.buildCar("Inline 6");
anotherCar.startEngine();
// 输出: Engine Inline 6 started.
instanceof 运算符
instanceof 运算符用于判断对象是否是指定的类型,如果是返回 true,否则返回 false
console.log(myCar instanceof Car); // true
console.log(myElectricCar instanceof ElectricCar); // true
console.log(myElectricCar instanceof Car);
// true,因为 ElectricCar 继承自 Car
访问控制修饰符
TypeScript 中,可以使用访问控制符来保护对类、变量、方法和构造方法的访问。TypeScript 支持 3 种不同的访问权限。
public(默认) : 公有,可以在任何地方被访问。
protected : 受保护,可以被其自身以及其子类访问。
private : 私有,只能被其定义所在的类访问。
class Person {
public name: string;
private age: number; // 私有成员,不能在类外部访问
protected health: number; // 受保护成员,只能在类及其子类中访问
constructor(name: string, age: number, health: number) {
this.name = name;
this.age = age;
this.health = health;
}
}
var person = new Person("Alice", 30, 100);
console.log(person.name); // Alice
// console.log(person.age); // 错误:age 是私有的
类和接口
类可以实现接口,使用关键字 implements,并将 interest 字段作为类的属性使用
interface Drivable {
drive(): void;
}
class Motorcycle implements Drivable {
drive(): void {
console.log("Driving the motorcycle!");
}
}
实例化并调用接口方法
var myMotorcycle = new Motorcycle();
myMotorcycle.drive(); // 输出: Driving the motorcycle!
完整示例
interface Drivable {
drive(): void;
}
class Car implements Drivable {
engine: string;
constructor(engine: string) {
this.engine = engine;
}
drive(): void {
console.log(`Driving the car with ${this.engine} engine.`);
}
}
class ElectricCar extends Car {
battery: number;
constructor(engine: string, battery: number) {
super(engine);
this.battery = battery;
}
charge(): void {
console.log(`Charging the battery with ${this.battery} kWh.`);
}
}
var myCar = new Car("V8");
myCar.drive(); // 输出: Driving the car with V8 engine.
var myElectricCar = new ElectricCar("Electric V8", 100);
myElectricCar.drive(); // 输出: Driving the car with Electric V8 engine.
myElectricCar.charge(); // 输出: Charging the battery with 100 kWh.
码字不易,各位大佬点点赞呗