SOAP Webサービスからの応答を逆シリアル化する必要がありました。最初に、既存のSOAPクライアントを使用して返されたXMLからオブジェクトを取得し、次にJSONデシリアライザ(http://cloudmark.github.io/Json-Mapping/)を使用して、このオブジェクトを必要な実際のタイプにデシリアライズしました。
返されたプロパティの1つが基本型として宣言され、実際には多数の異なるサブタイプのインスタンスが含まれる可能性があるという問題がありました。
派生型に適用するクラスデコレータを作成して解決しました。このクラス・デコレータは、基本クラスを取得し、それにメタデータを適用して派生クラスを説明します。
次のコードを理解するには、WebサービスのXMLに多形性が有効であることを示すtype
属性が含まれている場合、XML - > JSONパーサーが$type
プロパティを追加することが重要です。
基本型に適用される実際のメタデータは、XMLの型名と派生型のコンストラクタです。
メタデータ登録とクラスのデコレータ:
export interface IJsonPolymorphism {
name: string;
clazz: {new(): any};
}
export function RegisterForPolymorphism(name: string) {
return (target) => {
let metadata = getJsonPolymorphism(target.__proto__);
if (!metadata) {
metadata = [];
}
metadata.push({name: name, clazz: target});
target.__proto__ = Reflect.metadata(jsonPolymorphismMetadataKey, metadata)(target.__proto__);
return target;
};
}
export function getJsonPolymorphism(target: any): IJsonPolymorphism[] {
return Reflect.getMetadata(jsonPolymorphismMetadataKey, target);
}
は使用方法:
// The base class
export class PropertyBase { /*...*/ }
// The derived classes
//
@RegisterForPolymorphism("b:PicklistProperty")
export class PicklistProperty extends PropertyBase { /*...*/ }
@RegisterForPolymorphism("b:TextProperty")
export class TextProperty extends PropertyBase { /*...*/ }
クラスのデコレータに渡された文字列は、WebからのXML応答でtype
属性の値であり、サービス。
デシリアライザのコードはこのようにそれを使用しています:
if (jsonObject["$type"]) {
const polymorphism = getJsonPolymorphism(clazz);
if (polymorphism && polymorphism.filter) {
const subclassDefinition = polymorphism.filter(x => x.name === jsonObject["$type"])[0];
if (subclassDefinition && subclassDefinition.clazz) {
clazz = subclassDefinition.clazz;
}
}
}
基本的には、clazz
はにJSONオブジェクトをデシリアライズし、我々は派生型のコンストラクタでそれを交換するタイプのコンストラクタです。
このコードでは、メタデータを直接ベースクラス、階層全体に追加するという制限があります。しかし、これはRegisterForPolymorphism
のコードを調整してツリーを歩くことで簡単に解決できます。
これは現在、TypeScriptの[非目標](https://github.com/Microsoft/TypeScript/wiki/TypeScript-Design-Goals)です。あなたが解決しようとしている実際の問題は何ですか? –
TypeScriptでクラスを作成するためにhttps://frhagn.github.io/Typewriter/を使用する方法はありますか? –
@PaulBullivant私はそのツールが大好きですが、彼は何か違うものを探していると思います –