TypeScript中extends关键字的使用场景及说明
作者:阿珊和她的猫
在 TypeScript 中,extends 关键字是实现类继承和泛型约束的核心语法。它允许开发者通过继承扩展类的功能,或者通过约束泛型参数来增强代码的灵活性和安全性。
本文将详细介绍 extends 关键字在不同场景下的使用方法和实际案例。

一、类继承中的extends

(一)定义与作用
在 TypeScript 中,extends 关键字用于表示一个类继承自另一个类。子类可以继承父类的属性和方法,并可以添加新的属性和方法或覆盖父类的方法。
基础语法
class Parent {
constructor(public name: string) {}
greet() {
console.log(`Hello, my name is ${this.name}`);
}
}
class Child extends Parent {
constructor(name: string, public age: number) {
super(name); // 调用父类的构造函数
}
greet() {
console.log(`Hello, my name is ${this.name} and I am ${this.age} years old`);
}
}
在这个例子中,Child 类继承了 Parent 类。Child 类通过 super 调用了父类的构造函数,并添加了一个新的属性 age 和一个覆盖的 greet 方法。
(二)使用场景
扩展功能
通过继承,子类可以扩展父类的功能,同时保持代码的复用性。
class Animal {
constructor(public name: string) {}
makeSound() {
console.log(`${this.name} makes a sound`);
}
}
class Dog extends Animal {
constructor(name: string) {
super(name);
}
makeSound() {
console.log(`${this.name} barks`);
}
}
在这个例子中,Dog 类继承了 Animal 类,并覆盖了 makeSound 方法,以实现特定的行为。
实现多态
继承是实现多态的基础。通过继承,子类可以覆盖父类的方法,从而实现不同的行为。
class Shape {
draw() {
console.log("Drawing a shape");
}
}
class Circle extends Shape {
draw() {
console.log("Drawing a circle");
}
}
class Square extends Shape {
draw() {
console.log("Drawing a square");
}
}
function drawShape(shape: Shape) {
shape.draw();
}
const circle = new Circle();
const square = new Square();
drawShape(circle); // 输出: Drawing a circle
drawShape(square); // 输出: Drawing a square
在这个例子中,Circle 和 Square 类继承了 Shape 类,并覆盖了 draw 方法。drawShape 函数可以接受任何 Shape 类型的对象,并调用其 draw 方法,从而实现多态。
二、泛型约束中的extends
(一)定义与作用
在泛型中,extends 关键字用于约束泛型参数的类型。通过 extends,可以指定泛型参数必须是某个类型或其子类型的实例。
基础语法
function getProperty<T, K extends keyof T>(obj: T, key: K) {
return obj[key];
}
const obj = { a: 1, b: 'hello' };
const value = getProperty(obj, 'b'); // value 的类型是 'hello'
在这个例子中,泛型参数 K 被约束为 T 的键类型(keyof T)。这确保了 key 参数必须是 obj 的有效键。
(二)使用场景
约束泛型参数
通过 extends,可以确保泛型参数满足特定的条件,从而提高代码的安全性和可读性。
class Component<T extends HTMLElement> {
constructor(public element: T) {}
getInnerText(): string {
return this.element.innerText;
}
}
const divComponent = new Component(document.createElement('div'));
console.log(divComponent.getInnerText()); // 输出: 空字符串
在这个例子中,Component 类的泛型参数 T 被约束为 HTMLElement 或其子类型。这确保了 element 属性是一个有效的 DOM 元素。
实现高级类型模式
extends 可以用于实现更复杂的类型模式,如条件类型和映射类型。
type MyType<T extends string | number> = T extends string ? { value: T } : { value: number };
const strType: MyType<string> = { value: 'hello' };
const numType: MyType<number> = { value: 42 };
在这个例子中,MyType 是一个条件类型,根据泛型参数 T 的类型返回不同的结构。
三、接口继承中的extends
(一)定义与作用
在接口中,extends 关键字用于表示一个接口继承自另一个接口。子接口可以扩展父接口的属性和方法。
基础语法
interface Animal {
name: string;
makeSound(): void;
}
interface Dog extends Animal {
bark(): void;
}
function getAnimalSound(animal: Animal) {
animal.makeSound();
}
const myDog: Dog = {
name: 'Buddy',
makeSound() {
console.log(`${this.name} makes a sound`);
},
bark() {
console.log(`${this.name} barks`);
}
};
getAnimalSound(myDog); // 输出: Buddy makes a sound
在这个例子中,Dog 接口继承了 Animal 接口,并添加了一个新的方法 bark。
(二)使用场景
扩展接口功能
通过继承,接口可以扩展其他接口的功能,同时保持代码的复用性。
interface Shape {
draw(): void;
}
interface Circle extends Shape {
radius: number;
}
interface Square extends Shape {
sideLength: number;
}
function drawShape(shape: Shape) {
shape.draw();
}
const myCircle: Circle = {
radius: 5,
draw() {
console.log(`Drawing a circle with radius ${this.radius}`);
}
};
const mySquare: Square = {
sideLength: 4,
draw() {
console.log(`Drawing a square with side length ${this.sideLength}`);
}
};
drawShape(myCircle); // 输出: Drawing a circle with radius 5
drawShape(mySquare); // 输出: Drawing a square with side length 4
在这个例子中,Circle 和 Square 接口继承了 Shape 接口,并添加了特定的属性。
四、总结
extends 关键字在 TypeScript 中用于实现类继承、泛型约束和接口继承。通过 extends,可以扩展类和接口的功能,约束泛型参数的类型,从而提高代码的复用性、安全性和灵活性。
希望本文能够帮助你更好地理解和使用 extends 关键字,提升你的 TypeScript 开发能力。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。
