我需要创建一个类来实现一个具有57个属性的接口(实际上,这是一个goog联动的adminsdk模式)。在创建类时,我希望避免重新键入整个接口定义。正在考虑使用扩展操作符,但是失败了
只有3个属性的简单示例:
interface myInt {
field1:string;
field2:string;
field3?:number;
}
class theClass implements myInt{
private theFields:myInt
constructor(data:myInt)
{
this.theFields = {{}, ...data} <---incorrect
}
}发布于 2019-05-23 00:51:07
嗯,这里发生了一些事情。从您的界面开始:
interface MyInt {
field1: string;
field2: string;
field3?: number;
}您最初的类是一个包含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;
}
}好吧,希望能帮上忙。祝好运!
https://stackoverflow.com/questions/56264238
复制相似问题