TypeScript and field initializers

前端 未结 14 2299
暖寄归人
暖寄归人 2020-11-30 16:49

How to init a new class in TS in such a way (example in C# to show what I want):

// ... some code before
return new MyClass { Field         


        
14条回答
  •  北荒
    北荒 (楼主)
    2020-11-30 17:22

    I wanted a solution that would have the following:

    • All the data objects are required and must be filled by the constructor.
    • No need to provide defaults.
    • Can use functions inside the class.

    Here is the way that I do it:

    export class Person {
      id!: number;
      firstName!: string;
      lastName!: string;
    
      getFullName() {
        return `${this.firstName} ${this.lastName}`;
      }
    
      constructor(data: OnlyData) {
        Object.assign(this, data);
      }
    }
    
    const person = new Person({ id: 5, firstName: "John", lastName: "Doe" });
    person.getFullName();
    

    All the properties in the constructor are mandatory and may not be omitted without a compiler error.

    It is dependant on the OnlyData that filters out getFullName() out of the required properties and it is defined like so:

    // based on : https://medium.com/dailyjs/typescript-create-a-condition-based-subset-types-9d902cea5b8c
    type FilterFlags = { [Key in keyof Base]: Base[Key] extends Condition ? never : Key };
    type AllowedNames = FilterFlags[keyof Base];
    type SubType = Pick>;
    type OnlyData = SubType any>;
    

    Current limitations of this way:

    • Requires TypeScript 2.8
    • Classes with getters/setters

提交回复
热议问题