TypeScriptのプロパティ名、値、値のタイプを知らなくても、クラスのインスタンスにプロパティを割り当てたい。次のexample.ts
スクリプトがあると仮定します。
// This could be a server response and could look totally diffent another time...
const someJson:string = '{ "foo": "bar", "bar": "baz" }'
class MyClass {
someProperty:boolean
constructor( json:string ) {
const parsedJson:any = JSON.parse( json )
Object.keys( parsedJson ).forEach(
( key:string ) => {
this[ key ] = parsedJson[ key ]
}
)
this['someProperty'] = true
}
}
const myInstance = new MyClass( someJson )
// Works fine, logs `true`.
console.log( myInstance.someProperty )
// Error: Property 'foo' does not exist on type 'MyClass'.
console.log( myInstance.foo )
// Error: Property 'bar' does not exist on type 'MyClass'.
console.log( myInstance.bar )
TypeScriptコンパイラが動的に追加されたプロパティについて文句を言わず、代わりにそれらを任意のタイプの"key": value
ペアとして処理することを確認するにはどうすればよいですか。 tsc
でmyInstance.someProperty
のタイプがboolean
である必要があることを確認したいのですが、実行せずに定義されていなくてもmyInstance.whatever
を取得できるようにしたいコンパイラエラーに。
これを明確にするドキュメントは見つかりませんでした。たぶん私は英語を母国語としないからでしょう。ですから、答えは単純にしてください。
編集:
次のようなものがあったことを覚えていますが、それが機能することはありませんでした。
interface IMyClass {
[name:string]: any
}
問題は、実行時に新しいプロパティを追加していて、コンパイラがそれを知る方法がないことです。
プロパティ名を事前に知っている場合は、次のことができます。
type Json = {
foo: string;
bar: string;
}
...
const myInstance = new MyClass(someJson) as MyClass & Json;
console.log(myInstance.foo) // no error
事前にプロパティがわからない場合は、これを行うことはできません。
console.log(myInstance.foo);
foo
が受信したjsonの一部であることがわかっているので、おそらく次のようになります。
let key = getKeySomehow();
console.log(myInstance[key]);
そして、これはコンパイラからのエラーなしで機能するはずです。それに関する唯一の問題は、コンパイラが戻り値の型を知らないことであり、それはany
になります。
だからあなたはこれを行うことができます:
const myInstance = new MyClass(someJson) as MyClass & { [key: string]: string };
let foo = myInstance["foo"]; // type of foo is string
let someProperty = myInstance["someProperty"]; // type of someProperty is boolean
あなたは小道具を知っていますが、クラスでは知らないので、あなたは次のことができます:
type ExtendedProperties<T> = { [P in keyof T]: T[P] };
function MyClassFactory<T>(json: string): MyClass & ExtendedProperties<T> {
return new MyClass(json) as MyClass & ExtendedProperties<T>;
}
次に、次のように使用します。
type Json = {
foo: string;
bar: string;
};
const myInstance = MyClassFactory<Json>(someJson);
これはTypeScript2.1以降でのみ機能することに注意してください。