configオブジェクトをクラスにメンバオブジェクトとして追加するという大きな問題はありません。最新のTypescriptバージョンの助けを借りて、現在のすべてのソリューションは素晴らしくなく、ちょうどこれ以上簡単なものが複雑になります。同様のものがCombining destructuring with parameter propertiesより前に提案されています。この提案はほぼ2歳です。しかし、上記を行うには数多くの方法がありますが、クラス内のフィールドにアクセスする必要があるかどうかはわかりません。あなたは次のインターフェイス与えられ、上記を解決するのに役立つかもしれないいくつかの方法で上へ、
...
interface IConfigOpts {
propA: string,
propB: boolean
propC: number
}
...と、このクラス構造。
class Config {
constructor(opts: IConfigOpts) {
// Object.assign(this, opts);
Object.entries(opts).forEach((property: [string, any]) => {
Object.defineProperty(this, property[0], {
writable: true,
value: property[1]
});
});
}
get props() {
return Object.getOwnPropertyNames(this).map(key => ({[key]: this[key]}));
}
}
あなたは、コンストラクタでメンバフィールドを初期化するためにフランクによって提案されObject.assign
(ES5 +)、またはObject.defineProperty
を使用することができます。後者は、プロパティをwritable
にするか、getters
および/またはsetters
を割り当てるオプションを与えます。
あなたのConfigクラスやインタフェースの新しいインスタンスの作成を使用して、クラスの外で自分のタイプのプロパティを取得するためにファクトリメソッドを作成することができます。
const ConfigFactory = (opts: IConfigOpts) => new Config(opts) as Config & IConfigOpts;
const cfg = ConfigFactory({
propA: 'propA',
propB: true,
propC: 5
});
let a: string = cfg.propA; // OK => defined
しかし、これはあなたを許しません型チェックのあるクラスでthis.propA
を使用します。 (まだ)は、型付けされたクラスメンバーを、破壊を使用してクラスに動的にバインドします。代わりにthis[key]
を使用する必要があります。
クラス外のプロパティにアクセスしたくない場合は、名前でプロパティを呼び出すメソッドを定義し、その型を使用して指定されたインターフェイスで定義された型を検証します。this[key]
それらの指定された型を返す:
prop<TKey extends keyof IConfigOpts, TValue extends IConfigOpts[TKey]>(key: TKey): TValue {
return this[key as string];
}
これは、入力されたキーはkeyof
でルックアップを使用してインターフェイスにに存在する保証と同様に正しいタイプを返します。
let a: string = cfg.prop('propA'); // OK => defined
let b: boolean = cfg.prop('propB'); // OK => defined
let c: number = cfg.prop('propC'); // OK => defined
let d: number = cfg.prop('propD'); // Fail => Argument is not assignable to keyof IConfigOpts
let e: boolean = cfg.prop('propC'); // Fail => Type number is not assignle to type boolean
自動的にクラスにプロパティ(の多く)を結合についての唯一の良いところは、あなたがオブジェクトのキーを一致させるために与えられたコンストラクタでオブジェクトのdestructureを編集する必要がないことです。例えばpropA
はpropAB
に変更されます。変更する必要があるのは、インタフェース宣言だけです。
ため
参照JSBinに? – gilamran
@gilamran私の主な動機は、設定オプションをクラス外から変更できないようにすることです。私が設定オブジェクトを参照すると、作成者は設定オブジェクトを参照することによって設定オプションを変更することができます。 'let config = {myProp: '何か'};新しいMyClass(config); config.myProp = 'somethingElse'; '私はこれを望んでいません。 – Samih