Ну, здесь кое-что происходит. Начиная с вашего интерфейса:
interface MyInt {
field1: string;
field2: string;
field3?: number;
}
ваш первоначальный класс был чем-то содержащим a MyInt
, на самом деле он не реализовывал этого. «Правильный» способ хранить MyInt
в классе:
class HasMyInt {
private theFields: MyInt;
constructor(data: MyInt) {
this.theFields = { ...data }; // spread data into this.theFields
}
}
Возможно, вам этого достаточно, но тогда HasMyInt
сам по себе не является экземпляром интерфейса MyInt
. Если вы хотите создать класс, который является экземпляром, то «правильный» способ сделать это, к сожалению, включает избыточные объявления свойств, а также определенные утверждения присваивания для подавления любых предупреждений с помощью --strictPropertyInitialization
:
class IsMyIntManual implements MyInt {
// need these, unfortunately:
field1!: string;
field2!: string;
field3?: number;
constructor(data: MyInt) {
Object.assign(this, data); // spread data into this
}
}
Использует Object.assign()
вместо оператора распространения объекта, поскольку позволяет изменять существующий целевой объект (this
) вместо возврата нового.
Если вы действительно хотите избежать избыточных объявлений свойств, вы можете создать своего рода «фабрику базовых классов», которая с учетом типа объекта T
создает функцию-конструктор, которая копирует свойства из аргумента типа T
в сам. Обратите внимание, что для компиляции здесь требуется утверждение типа , поскольку TypeScript не распознает функцию конструктора в стиле ES5 как new
способную.
function BaseClass<T extends object>() {
return (function(this: T, data: T) {
Object.assign(this, data);
} as any) as new (arg: T) => T; // need assertion
}
Это позволяет легко создавать IsMyInt
, расширяя BaseClass<MyInt>()
:
// this implements IsMyInt
class IsMyIntAutomatic extends BaseClass<MyInt>() {}
И если вам нужно добавить больше функций в этот класс, вы можете сделать это:
class ExtendingIsMyInt extends BaseClass<MyInt>() {
public anotherProperty: number;
constructor(data: MyInt, anotherProperty: number) {
super(data);
this.anotherProperty = anotherProperty;
}
method() {
return this.field2 != this.field1 ? this.field3 || this.anotherProperty : 0;
}
}
Ссылка на этот код
Хорошо, надеюсь, это поможет. Удачи!