Я нашел решение для реализации своего рода множественного наследия (на самом деле это каскадно), но стоит взглянуть.
Предположим, у вас есть класс Base с несколькими свойствами и методами:
class Base {
tableName = 'My table name';
hello(name) {
return `hello ${name}`;
}
}
И вы хотите, чтобы класс расширял Base, но вы также определили некоторые свойства, которые хотите использовать повторно.Для этого мы будем выполнять следующую функцию:
type Constructor<T = {}> = new (...args: any[]) => T;
function UserFields<TBase extends Constructor>(Base: TBase) {
return class extends Base {
name: string;
email: string;
};
}
Теперь мы можем создать класс, который расширяет Base и расширяет UserFields, а служба языка машинописи найдет свойства из обоих классов.Он эмулирует множественное наследие, но на самом деле это каскад.
class User extends UserFields(Base) { }
const u = new User();
u.tableName = 'users'; // ok
u.name = 'John'; // ok
Таким образом, вы можете повторно использовать функцию UserFields с любыми другими классами.Ярким примером этого является то, что если вы хотите представить объект User на стороне клиента как «чистый» объект и иметь доступные поля, а затем у вас есть объект UserDb с подключениями к базе данных, и любые другие методы на стороне сервера могут иметь те же полятоже.Мы определяем поля базы данных только один раз!
Еще одна хорошая вещь - вы можете связать mixins mixin1 (mixin2 .... (Base)), чтобы иметь столько атрибутов, сколько вы хотите иметь в одном классе.
Все ожидают, что атрибуты декоратора будут видны при машинописи, но между тем это хорошее решение.