Ответ
Нет, TypeScript, как и JavaScript, не поддерживает множественное наследование классов в классическом понимании (когда класс наследует реализацию от нескольких родительских классов). Попытка написать class C extends A, B {} вызовет ошибку.
Однако, для повторного использования кода из нескольких источников в TypeScript используются альтернативные подходы:
-
Миксины (Mixins): Это функции, которые принимают класс и возвращают новый класс с расширенной функциональностью.
class CanLog { log(msg: string) { console.log(msg); } } class CanSerialize { serialize() { return JSON.stringify(this); } } type Constructor = new (...args: any[]) => {}; function Loggable<TBase extends Constructor>(Base: TBase) { return class extends Base { log = CanLog.prototype.log; }; } function Serializable<TBase extends Constructor>(Base: TBase) { return class extends Base { serialize = CanSerialize.prototype.serialize; }; } class MyService {} const EnhancedService = Serializable(Loggable(MyService)); const instance = new EnhancedService(); instance.log('Hello'); // OK instance.serialize(); // OK -
Композиция: Часто является более предпочтительным и гибким подходом. Вместо наследования класс содержит экземпляры других классов (делегирует им работу).
class Logger { log(msg: string) { /* ... */ } } class Serializer { serialize(data: any) { /* ... */ } } class MyService { private logger = new Logger(); private serializer = new Serializer(); process(data: any) { this.logger.log('Processing'); const result = this.serializer.serialize(data); // ... } } -
Реализация нескольких интерфейсов: Класс может реализовывать несколько интерфейсов, что гарантирует наличие определенных методов, но не предоставляет их реализацию.
interface Loggable { log(): void; } interface Serializable { serialize(): string; } class MyComponent implements Loggable, Serializable { log() { /* реализация */ } serialize() { /* реализация */ } }
В своей практике я чаще всего использую композицию и интерфейсы, так как это приводит к более слабо связанному и тестируемому коду.