はじめに
下記のようなクラスがあった場合にどうやって初期化しようかと悩んだため色々試してみました
class User { name: string; age: number; nickname?: string; public hello(): string { return `[${this.nickname ?? this.name}] Hello!!`; } }
やったこと
先に結論ですが、最終的には下記の形に落ち着きました
// Tのpropertyの名前の列挙 type NonFunctionPropertyNames<T> = { [K in keyof T]: T[K] extends Function ? never : K }[keyof T]; // Tのproperty type NonFunctionProperties<T> = Pick<T, NonFunctionPropertyNames<T>>; class User { name?: string = 'anonymous'; age!: number; nickname?: string; public constructor(params: NonFunctionProperties<User>) { Object.assign(this, params); } public hello(): string { return `[${this.nickname ?? this.name}] Hello!!`; } } const user = new User({ age: 18, }); console.log(user.hello()); // > [anonymous] Hello!!
Partial
を試してみたんですが、絶対に欲しい値もオプショナルになってしまうので要望に合いませんでした
また、単純なpropertyの列挙だとメソッドまで含まれてしまうのでメソッドを除外しています
デフォルト値も定義できるので今のところ特に困ってません
NonFunctionPropertyNames
などはここを参考にしました
www.typescriptlang.org