🧩 一、在 类(class) 中:继承父类
✅ 用法:子类继承父类的属性和方法
class Animal {
move() {
console.log('Moving...');
}
}
class Dog extends Animal {
bark() {
console.log('Woof!');
}
}
const dog = new Dog();
dog.move(); // ✅ 从 Animal 继承
dog.bark(); // ✅ 自己定义
理解:
class Dog extends Animal
意思是「Dog 是 Animal 的子类」,拥有 Animal 的能力。
🧠 补充:super 关键字
当子类重写构造函数或方法时,可以通过 super 调用父类的实现:
class Animal {
constructor(public name: string) {}
}
class Dog extends Animal {
constructor(name: string, public breed: string) {
super(name); // 调用父类构造函数
}
}
🧠 二、在 泛型(Generics) 中:类型约束(extends T)
这部分更重要,也是面试重点。
✅ 用法 1:限制泛型的取值范围
function getLength<T extends { length: number }>(arg: T) {
return arg.length;
}
getLength('hello'); // ✅ string 有 length
getLength([1, 2, 3]); // ✅ 数组有 length
getLength(42); // ❌ number 没有 length
解释:
T extends { length: number }
表示泛型参数T必须“至少拥有一个length属性”。
✅ 用法 2:继承类型或交叉类型
interface Person {
name: string;
}
interface Student extends Person {
grade: number;
}
const s: Student = { name: 'Alice', grade: 90 };
解释:
Student继承了Person的属性,相当于Student = Person & { grade: number }。
✅ 用法 3:泛型条件判断(条件类型)
extends 在条件类型中表示 “是否可赋值” 的判断。
type IsString<T> = T extends string ? true : false;
type A = IsString<'abc'>; // true
type B = IsString<number>; // false
👉 T extends string 表示「T 是否可以赋值给 string」。
这是很多 TS 内置工具类型(如 Exclude、Extract)的核心机制。
✅ 用法 4:联合类型的分发(Distributive)
在条件类型中,extends 对联合类型会自动“分发”:
type T1 = 'a' | 'b' | 'c';
type ExcludeA<T> = T extends 'a' ? never : T;
type R = ExcludeA<T1>; // 'b' | 'c'
解释:
T extends 'a'会对联合类型'a' | 'b' | 'c'分别计算一次,
'a'→ never,'b'→ 'b','c'→ 'c'。
这就是内置类型 Exclude<T, U> 的底层原理。
✅ 用法 5:限制函数参数类型
function merge<T extends object, U extends object>(a: T, b: U) {
return { ...a, ...b };
}
merge({ name: 'Tom' }, { age: 20 }); // ✅
merge(123, 456); // ❌ number 不是 object
✅ 用法 6:提取子类型(infer 搭配 extends)
这是 TS 高级类型中最常用的组合:
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : never;
type Fn = () => number;
type Result = ReturnType<Fn>; // number
解释:
extends (...args: any[]) => infer R
→ 表示 T 必须是函数类型;infer R表示“推断出返回值类型 R”。
✅ 三、总结对比
| 语境 | 写法 | 意义 |
|---|---|---|
| 类继承 | class B extends A | B 继承 A 的属性和方法 |
| 泛型约束 | <T extends U> | 限制 T 必须满足 U 的结构 |
| 条件类型 | T extends U ? X : Y | 判断 T 是否可赋值给 U |
| 接口继承 | interface B extends A | B 拥有 A 的所有属性 |
| infer 结合 | T extends (...) => infer R | 从类型结构中提取部分类型 |
✅ 四、记忆口诀
extends 的本质是“约束 + 继承 + 判断”
- 类中:继承行为
- 泛型中:限制范围
- 条件类型中:类型判断
🎯 一句话总结
extends在 TypeScript 中相当于「类型世界里的 <=」。它表示:左边类型能否赋值给右边类型,
或 左边类型是否是右边的子类型。