我是打字稿的新手,我正在努力学习如何使用类 .

我的目标是创建一个可以将对象作为参数的构造函数:

{
    first_name: 'Bill',
    foo: 'Bar'
}

并且构造函数会自动填充我的instanciated类的属性,但只会填充声明的属性:

export default class User {
    // Because of "this[key] = data[key]", I need to tell my class 
    // that the class User is a key:string => value:any structure
    [key: string]:any;

    // Here, I define a public property first_name
    public first_name:string;

    constructor (data:{[index:string] : any}) {
        // Here, I get the properties of my Object
        let properties = this.getPublicProperties();

        // I assign the value only if the key is part of my properties
        Object.keys(data).forEach((key:string) => {
            if (typeof properties.find((x:string) => x === key) !== 'undefined') {
                this[key] = data[key];
            }
        })
    }

    getPublicProperties () {
        // I'd like that to be based on defined properties above with "public first_name:string"
        // The ideal would be that I could define "private" properties that would not be able 
        // to be filled with that method.

        return ['first_name'];
    }
}

让我们试试这个主要代码:

import User from './models/User'

let user:User = new User({
    first_name: 'Mathieu',
    foo: 'bar'
});

console.log(user);

Result:

User { first_name: 'Mathieu' }

Question: So how could I change my getPublicProperties() in order to automatically grab my properties?

我遇到的唯一解决方案是将我的公共属性设置为null:

export default class User {
    [key: string]:any;

    public first_name:string = null;

    private foo:string;

    ...

    getPublicProperties () {
        return Object.getOwnPropertyNames(this);
    }
}

现在,让我们说解决方案有效,我想将此行为抽象到另一个类:

export default class Model {
    [key: string]:any;

    construct (data:{[index:string] : any}) {
        let properties = this.getPublicProperties();
        Object.keys(data).forEach((key:string) => {
            if (typeof properties.find((x:string) => x === key) !== 'undefined') {
                this[key] = data[key];
            }
        })
    }

    getPublicProperties () {
        return Object.getOwnPropertyNames(this);
    }
}

import Model from "./Model";

export default class User extends Model{

    public first_name:string = null;

    private foo:string;

    constructor (data:{[index:string] : any}) {
        super();
        super.construct(data);
    }
}

正如你在我的构造函数中看到的那样,我必须在调用构造函数的另一个方法之前调用 super() ,因为如果不这样做, getPublicProperties 抽象方法在我的construct()方法中将不起作用 .

Question: Am I doing it right, or do I miss something in the inheritance functionalities?