【问题标题】:How to fill properties of class TypeScript?如何填充 TypeScript 类的属性?
【发布时间】:2018-05-29 12:07:04
【问题描述】:

假设有一个模型类,如:

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

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

let f = new Filter();

它返回对象Filter,其中包含空属性。

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

我可以像这样确定构造函数:

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);

【问题讨论】:

    标签: typescript typescript2.0


    【解决方案1】:

    如果您可以使用任何属性组合初始化对象,则可以使用以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&lt;Filter&gt; 相当于:

    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})
    

    【讨论】:

    • 这是什么:Partial?就我而言,它是interface IFilter {} 类型
    • @OPV 稍微解释了一下。
    【解决方案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);
    }}
    

    当您创建一个新实例时,所有字段名称都是 disponible 和空的。

    const instance_of_filter: Filter = new Filter();
    

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

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

    【讨论】:

      【解决方案3】:

      您不必立即填写所有对象属性。

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

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

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

      【讨论】:

      • 我不想为每个属性写set/get
      • 这样的? new Filter({catagory: 5, subject: 4})
      【解决方案4】:

      这是基本解决方案:

      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;
        }
      
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-06-21
        • 2015-09-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多