TypeScript とフィールド初期化子 質問する

TypeScript とフィールド初期化子 質問する

TS で新しいクラスをこのように初期化する方法 (私が望むものを示す C# の例):

// ... some code before
return new MyClass { Field1 = "ASD", Field2 = "QWE" };
// ...  some code after

ベストアンサー1

2016年7月12日更新: Typescript 2.1ではマップ型が導入されましたを提供しPartial<T>、これを可能にする....

class Person {
    public name: string = "default"
    public address: string = "default"
    public age: number = 0;

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

let persons = [
    new Person(),
    new Person({}),
    new Person({name:"John"}),
    new Person({address:"Earth"}),    
    new Person({age:20, address:"Earth", name:"John"}),
];

元の回答:

私のアプローチは、fieldsコンストラクターに渡す別の変数を定義することです。秘訣は、この初期化子のすべてのクラス フィールドをオプションとして再定義することです。オブジェクトが (デフォルトで) 作成されると、初期化子オブジェクトをthis;に割り当てるだけです。

export class Person {
    public name: string = "default"
    public address: string = "default"
    public age: number = 0;

    public constructor(
        fields?: {
            name?: string,
            address?: string,
            age?: number
        }) {
        if (fields) Object.assign(this, fields);
    }
}

または手動で実行します(少し安全です)。

if (fields) {
    this.name = fields.name || this.name;       
    this.address = fields.address || this.address;        
    this.age = fields.age || this.age;        
}

使用法:

let persons = [
    new Person(),
    new Person({name:"Joe"}),
    new Person({
        name:"Joe",
        address:"planet Earth"
    }),
    new Person({
        age:5,               
        address:"planet Earth",
        name:"Joe"
    }),
    new Person(new Person({name:"Joe"})) //shallow clone
]; 

コンソール出力:

Person { name: 'default', address: 'default', age: 0 }
Person { name: 'Joe', address: 'default', age: 0 }
Person { name: 'Joe', address: 'planet Earth', age: 0 }
Person { name: 'Joe', address: 'planet Earth', age: 5 }
Person { name: 'Joe', address: 'default', age: 0 }   

これにより、基本的な安全性とプロパティの初期化が実現されますが、すべてオプションであり、順序が異なる場合があります。フィールドを渡さない場合は、クラスのデフォルトがそのまま残ります。

必須のコンストラクター パラメーターと組み合わせることもできます (fields最後に貼り付けます)。

C# スタイルに最も近いものになると思います (実際のフィールド初期化構文は拒否されました)。適切なフィールド初期化子の方がはるかに望ましいのですが、まだ実現しそうにありません。

比較すると、キャスト アプローチを使用する場合、初期化オブジェクトにはキャスト先の型のすべてのフィールドが含まれている必要があり、さらにクラス自体によって作成されたクラス固有の関数 (または派生) は取得されません。

おすすめ記事