一般的な初期化方法
TypeScriptにおいてclassの初期化を行う際、多くの場合はconstructor
を利用するかと思います。以下のPerson
classを例にしてconstructorを使用した初期化処理を見てみましょう。
class Person {
name: string;
age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
}
const takashi = new Person('Takashi', 70);
ここでは、Person
classはname
とage
という2つのプロパティを持っており、constructorにそれぞれの値を渡すことで、各プロパティの初期化を行っています。
これはごく基本的な初期化方法ですが、あらかじめ初期化に使用することのできるオブエジェクトをAPIサーバーなどから受け取っている場合、初期化を行うためのコードが冗長になりがちです。下のコードを見てみましょう。
// 何らかのAPIコールで人の情報を取得
server.getPerson().then(person => {
// person === {name: 'Takashi', age: 70}
const takashi = new Person(person.name, person.age);
});
上の例では、各プロパティを別々のパラメータとしてconstructorに渡しているため、コードの記述量が多くなってしまっています。person
をパラメータとして直接渡せたらどんなに楽でしょう。それを実現するための手段がPartial
です。
Partial
Partial
はTypeScript 2.1から導入されたtypeで、Partial<T>
と指定した時に、T
が持つ全てのプロパティをオプションとした型として振る舞う性質を持っています。これはどういうことでしょうか。以下の例を見てみましょう。
例えば、次のようなPerson
classを定義していると仮定します。
class Person {
name: string;
age: number;
}
この際、Partial<Person>
を使用すると、Person
が持つname
とage
というプロパティがオプションとなった型として扱われます。つまり、下記コードのa
とb
は、同じ型の変数として振る舞います。
const a: Partial<Person>;
const b: { name?: string, age?: number };
// aとbは同様の型として振る舞う
この効果を利用することで、上述したconstructorをより簡潔に記述することができます。
Partialを使ったconstructor
それでは、Partial
を利用したconstructorの記述例を見てみましょう。Partial
を利用することで、冒頭で記述したPerson
classのconstructorは以下のように定義することができます。
class Person {
name?: string;
age?: number;
constructor(init?: Partial<Person>) {
Object.assign(this, init);
}
}
見て分かるように、Person
のconstructorにはPartial<Person>
のパラメータを渡すように定義しています。こうして渡されたパラメータをObject.assign
を使用して自身へと割り当てることで、各プロパティへと値がセットされます。これにより、以下のようにPerson
のconstructorに直接オブジェクトをパラメータとして渡すことができます。
const obj = {
name: 'Takashi',
age: 70,
};
const takashi = new Person(obj);
console.log(takashi.name); // => 'Takashi'
console.log(takashi.age); // => 70
継承したclassの場合
先ほどの Person
classを継承したclass Programmer
を定義することを考えてみましょう。この場合でも、constructor内で値をセットすることで、同様にオブジェクトからclassを初期化することが可能です。
class Programmer extends Person {
salary: number;
skills: Array<{ lang: string, rate: number }>;
constructor(init?: Partial<Programmer>) {
super();
Object.assign(this, init);
}
}
Programmer
を初期化する例は以下の通りです。
const obj = {
name: 'Takashi',
age: 70,
salary: 200,
skills: [
{ lang: 'JavaScript', rate: 5 },
{ lang: 'Ruby', rate: 2 },
],
};
const takashi = new Programmer(obj);
console.log(takashi.name); // => 'Takashi'
console.log(takashi.age); // => 70
console.log(takashi.salary); // => 200
console.log(takashi.skills); // => [{lang: 'JavaScript', rate: 5}, {lang: 'Ruby', rate: 2}]
このように、Partial
を利用することで、オブジェクトから簡単にclassを初期化することができます。やったね!