如何填充TypeScript类的属性?

时间:2018-05-29 12:07:05

标签: typescript typescript2.0

让我们假设有一个类似的模型类:

class Filter implements IFilterJournal {
  public category: number;
  public subject: number;
  public teacher: number;
  public mark: number;
}

我可以创建这个类的实例:

let f = new Filter();

它返回内部为空属性的对象Filter

如何更方便地填写类的属性?

我可以确定consturctor:

public constructor(public category: number, public subject: number, public teacher: number, public mark: number){
}

然后在创建实例时传递参数:

let f = new Filter(1, 2, 3, 4)

但是,如果我只需填写public subject: number;财产怎么办?或  其他?如何有选择地填补它们?

另一个是将参数设为可选:

public constructor(public category?: number, public subject?: number, public teacher?: number, public mark?: number){}

然后使用它:

let f = new Filter(subject = 1);

4 个答案:

答案 0 :(得分:5)

如果可以使用任何属性组合初始化对象,则可以使用以Partial<Filter>作为参数的构造函数,并使用Object.assign设置对象上的字段。

class Filter  {
    constructor(data: Partial<Filter>){
        Object.assign(this, data);
    }
    public category: number;
    public subject: number;
    public teacher: number;
    public mark: number;
}
new Filter({ category: 0})
new Filter({ category: 1, subject: 2, teacher: 3, mark: 4})

注意 Partial是一种映射类型,用于保留类型的成员,但将所有成员标记为Partial。见docs。在这种情况下,Partial<Filter>相当于:

interface PartialFilter{
    category?: number;
    subject?: number;
    teacher?: number;
    mark?: number;
}

如果您的类型有方法,Partial将允许构造函数的参数包含这些方法,这可能是一个问题。您可以使用条件类型从参数中过滤出方法,但它有点复杂:

type NotFunctions<T> = { [P in keyof T]: T[P]  extends Function ? never : P }[keyof T];
class Filter  {
    constructor(data: Partial<Pick<Filter, NotFunctions<Filter>>>){
        Object.assign(this, data);
    }
    public category: number;
    public subject: number;
    public teacher: number;
    public mark: number;

    public sayHi(){ return "Hi" }
}
new Filter({ category: 0, sayHi: ()=> {}}) //Error with new constructor argument type 
new Filter({ category: 0})
new Filter({ category: 1, subject: 2, teacher: 3, mark: 4})

答案 1 :(得分:2)

像C#类:

export class Filter {
    category: number = null;
    subject: string = null;
    teacher: number = null;
    mark: boolean = null;

public constructor(init?: Partial<Filter>) {
    Object.assign(this, init);
}}

创建新实例时,所有字段名称都是无效的。

const instance_of_filter: Filter = new Filter();

您现在有了一个定义了所有字段的类:

instance_of_filter {
    "category": null,
    "subject": null,
    "teacher": null,
    "mark": null
}

答案 2 :(得分:1)

这是基本解决方案:

class Filter implements IFilterJournal {

  public subject: number;

  // Define defaults 
  // Not need to complicate with constructor 
  private category: number = 0;
  private teacher: number = 0;
  private mark: number = 0;

  public constructor(subject: number) {

    if (typeof subject === 'number') {
      this.subject = subject;
    } else {
      console.error('Class error: Constructor parameter subject is not a number!');
    }

  }

  // Define setters
  public setCategory(category: number) {
    this.category = category;
  }

  public setTeacher(teacher: number) {
    this.teacher = teacher;
  }

  public setMark(mark: number) {
    this.mark = mark;
  }

  // Define getters
  public getCategory(): number {
    return this.subject;
  }

  public getTeacher(): number {
    return this.teacher;
  }

  public getMark(): number {
    return this.mark;
  }

  public getSubject(): number {
    return this.subject;
  }

}

答案 3 :(得分:0)

您不必直接填充该球棒上的所有对象属性。

public constructor(public _category: number){
    category = _category;
}

工作得很好。请记住,如果您在分配之前稍后调用它们,那么您未填充的属性将是未定义的,因此至少您可能希望将它们初始化为某种可接受的值。也许:

public constructor(public _category: number){
    this.category = _category;
    this.subject = 0;
    this.teacher = 0;
    //etc...
}