Typescript用57个键实现接口:使用spreadoperator?

Typescript用57个键实现接口:使用spreadoperator?,typescript,class,interface,Typescript,Class,Interface,我需要创建一个类来实现一个具有57个属性的接口(实际上这是一个googleapi adminsdk模式)。 我希望在创建类时避免重新键入整个接口定义。 正在考虑使用spread运算符,但失败了 仅具有3个属性的灯光示例: interface myInt { field1:string; field2:string; field3?:number; } class theClass implements myInt{ private theFields:myInt

我需要创建一个类来实现一个具有57个属性的接口(实际上这是一个googleapi adminsdk模式)。 我希望在创建类时避免重新键入整个接口定义。 正在考虑使用spread运算符,但失败了

仅具有3个属性的灯光示例:

interface myInt {
   field1:string;
   field2:string;
   field3?:number;
}

class theClass implements myInt{
   private theFields:myInt
   constructor(data:myInt)
   {
     this.theFields = {{}, ...data}   <---incorrect
   }
}
接口myInt{
字段1:字符串;
字段2:字符串;
字段3?:编号;
}
类实现myInt{
私人领域:myInt
构造函数(数据:myInt)
{

this.theFields={{},…data}好吧,这里发生了一些事情。从界面开始:

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
接口的实例。如果您想创建一个作为实例的类,“right”不幸的是,这样做的方法涉及到冗余的属性声明,以及使用
--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 spread操作符,因为它允许您修改现有的目标对象(
this
),而不是返回一个新对象

如果您真的想避免冗余的属性声明,可以创建一种“基类工厂”给定对象类型
T
,它将生成一个构造函数,该构造函数将
T
类型的参数中的属性复制到自身中。请注意,这需要编译,因为TypeScript无法将ES5样式的构造函数识别为
新的
函数

function BaseClass<T extends object>() {
  return (function(this: T, data: T) {
    Object.assign(this, data);
  } as any) as new (arg: T) => T; // need assertion
}
如果需要为此类添加更多功能,可以这样做:

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;
  }
}
class ExtendingIsMynt扩展了基类(){
公共其他属性:编号;
构造函数(数据:MyInt,另一个属性:number){
超级(数据);
this.anotherProperty=另一个属性;
}
方法(){
返回this.field2!=this.field1?this.field3 | | this.anotherProperty:0;
}
}


好的,希望有帮助。祝你好运!

谢谢你的回答。我刚开始开发工厂,你的帖子会很有帮助。
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;
  }
}