多态与this类型
多态与this类型
TypeScript中的多态性允许不同类型的对象通过统一的接口进行操作,而this
类型则提供了对当前实例类型的动态引用。这两者结合能够实现更灵活的代码结构,特别是在继承和链式调用场景下。
多态的基本概念
多态性在TypeScript中主要通过接口和类继承实现。当不同类实现相同接口或继承相同基类时,它们可以被统一处理:
interface Animal {
makeSound(): void;
}
class Dog implements Animal {
makeSound() {
console.log('Woof!');
}
}
class Cat implements Animal {
makeSound() {
console.log('Meow!');
}
}
function animalSound(animal: Animal) {
animal.makeSound(); // 多态调用
}
const dog = new Dog();
const cat = new Cat();
animalSound(dog); // 输出: Woof!
animalSound(cat); // 输出: Meow!
this类型的动态特性
this
类型表示"当前类的实例类型",它在运行时动态确定。这使得方法可以返回当前实例,便于实现链式调用:
class Calculator {
value: number;
constructor(value = 0) {
this.value = value;
}
add(n: number): this {
this.value += n;
return this;
}
multiply(n: number): this {
this.value *= n;
return this;
}
}
const calc = new Calculator();
calc.add(5).multiply(2); // 链式调用
console.log(calc.value); // 输出: 10
多态this与继承
当类被继承时,this
类型会自动调整为子类类型,这在构建可扩展的类层次结构时非常有用:
class BaseClass {
clone(): this {
// 返回当前实例的副本
return Object.create(this);
}
}
class DerivedClass extends BaseClass {
additionalMethod() {
console.log('Additional method');
}
}
const derived = new DerivedClass();
const cloned = derived.clone(); // 类型为DerivedClass,不是BaseClass
cloned.additionalMethod(); // 可以调用子类方法
接口中的this类型
接口也可以使用this
类型来定义更灵活的契约:
interface Builder<T> {
setOption<K extends keyof T>(key: K, value: T[K]): this;
build(): T;
}
class PersonBuilder implements Builder<Person> {
private options: Partial<Person> = {};
setOption<K extends keyof Person>(key: K, value: Person[K]): this {
this.options[key] = value;
return this;
}
build(): Person {
return new Person(this.options);
}
}
const person = new PersonBuilder()
.setOption('name', 'Alice')
.setOption('age', 30)
.build();
多态this的实际应用
在实际开发中,多态this
常用于构建流畅API和扩展类功能:
class QueryBuilder {
where(condition: string): this {
// 添加where条件
return this;
}
limit(count: number): this {
// 设置limit
return this;
}
}
class MySQLQueryBuilder extends QueryBuilder {
useIndex(index: string): this {
// MySQL特定方法
return this;
}
}
const query = new MySQLQueryBuilder()
.where('age > 18')
.useIndex('age_index') // 子类方法
.limit(10); // 父类方法
类型守卫与this
结合类型守卫可以创建更精确的类型判断:
class FileSystemObject {
isFile(): this is File {
return this instanceof File;
}
isDirectory(): this is Directory {
return this instanceof Directory;
}
}
class File extends FileSystemObject {
read(): string {
return 'file content';
}
}
class Directory extends FileSystemObject {
list(): string[] {
return ['file1', 'file2'];
}
}
function process(obj: FileSystemObject) {
if (obj.isFile()) {
obj.read(); // 这里obj被推断为File类型
} else if (obj.isDirectory()) {
obj.list(); // 这里obj被推断为Directory类型
}
}
this参数的特殊用法
方法定义中的this
参数可以约束方法的调用上下文:
function clickHandler(this: HTMLButtonElement) {
this.disabled = true;
}
const btn = document.querySelector('button');
btn?.addEventListener('click', clickHandler); // 正确
// clickHandler(); // 错误:this上下文不符合
多态this的进阶模式
在复杂类型系统中,this
类型可以与其他高级类型特性结合:
class Observable<T> {
private subscribers: ((value: T) => void)[] = [];
subscribe(callback: (value: T) => void): this {
this.subscribers.push(callback);
return this;
}
next(value: T): this {
this.subscribers.forEach(cb => cb(value));
return this;
}
}
class NumberObservable extends Observable<number> {
map(transform: (n: number) => number): this {
// 实现map操作
return this;
}
}
const obs = new NumberObservable()
.map(n => n * 2)
.subscribe(console.log)
.next(10); // 输出: 20
this类型与混入模式
this
类型在混入(mixin)模式中特别有用,可以保持正确的类型推断:
type Constructor<T = {}> = new (...args: any[]) => T;
function Timestamped<TBase extends Constructor>(Base: TBase) {
return class extends Base {
timestamp = Date.now();
};
}
function Activatable<TBase extends Constructor>(Base: TBase) {
return class extends Base {
isActive = false;
activate(): this {
this.isActive = true;
return this;
}
};
}
class User {
name: string;
constructor(name: string) {
this.name = name;
}
}
const TimestampedActivatableUser = Activatable(Timestamped(User));
const user = new TimestampedActivatableUser('Alice');
user.activate();
console.log(user.timestamp, user.isActive);
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn
上一篇:混入(Mixins)模式实现
下一篇:类与接口的关系