JSONオブジェクトをtypescriptクラスにキャストする方法


393

リモートRESTサーバーからJSONオブジェクトを読み取ります。このJSONオブジェクトには、(設計上)typescriptクラスのすべてのプロパティがあります。受け取ったJSONオブジェクトを型変数にキャストするにはどうすればよいですか?

typescript varを入力したくない(つまり、このJSONオブジェクトを取得するコンストラクターがある)。これはサイズが大きく、サブオブジェクト間およびプロパティごとのプロパティ間ですべてをコピーするには、かなりの時間がかかります。

更新:ただし、typescriptインターフェースにキャストできます!


JSONがJavaクラスを使用してマッピングされている場合、github.com / vojtechhabarta / typescript-generatorを使用してTypeScriptインターフェースを生成できます
Vojta

小さなキャスティングライブラリをコーディングしました:sulphur-blog.azurewebsites.net/typescript-mini-cast-library
Camille Wintz

1
JSONオブジェクト= JavaScript Object Notationオブジェクト。そこには十分なオブジェクトがありません、私はかなりの数のためにさらにいくつかを投入すると言います。
bug-a-lot


オブジェクトを定義するためのプロトタイプTypeScriptクラスを作成しても、実際の製品コードには影響しません。コンパイルされたJSファイルを見てください。すべての定義はJSの一部ではないため、削除されます。
FisNaN 2018

回答:


167

Ajaxリクエストの単純な古いJavaScript結果をプロトタイプのJavaScript / TypeScriptクラスインスタンスに単純にキャストすることはできません。これを行うにはいくつかの手法があり、一般にデータのコピーが含まれます。クラスのインスタンスを作成しない限り、クラスやメソッドはありません。単純なJavaScriptオブジェクトのままです。

データのみを処理している場合は、インターフェースへのキャストを行うだけで済みます(純粋にコンパイル時の構造であるため)。これには、データインスタンスを使用し、そのデータで操作を実行するTypeScriptクラスを使用する必要があります。

データをコピーするいくつかの例:

  1. AJAX JSONオブジェクトを既存のオブジェクトにコピーする
  2. JavaScriptでJSON文字列を特定のオブジェクトプロトタイプに解析する

本質的に、あなたはただ:

var d = new MyRichObject();
d.copyInto(jsonResult);

私はあなたの答えに同意します。さらに、今は調べてテストする場所にはいませんが、ウェイクアップ関数をにパラメーターとして指定することで、これら2つのステップを組み合わせることができると思いますJSON.parse()。両方を実行する必要がありますが、構文的には組み合わせることができます。
JAAulde 2014

もちろん、それでもうまくいくかもしれません-各プロパティに対して追加の関数呼び出しを呼び出す必要があるので、それがもっと効率的であるかどうかはわかりません。
WiredPrairie 2014

?確かに私が探していた答え:(好奇心から、なぜこれがない私にはJavaScriptを有効にしてはなんとかなければならないことを動作する方法だ。
デビッド・Thielen

いいえ、JavaScriptでこれを行う簡単な方法がないため、TypeScriptでは機能しません。
WiredPrairie 2014

1
何についてObject.setPrototypeOf
ペタ

102

同じ問題があり、その仕事をするライブラリを見つけました:https : //github.com/pleerock/class-transformer

それはこのように動作します :

let jsonObject = response.json() as Object;
let fooInstance = plainToClass(Models.Foo, jsonObject);
return fooInstance;

ネストされた子をサポートしますが、クラスのメンバーを装飾する必要があります。


14
この見事な小さなライブラリーは、最小限の労力で完全に解決しました(@Typeただし、注釈を忘れないでください)。この回答は、より多くの信用に値します。
ベニーボッテマ2017年

すごいああ!、このライブラリは、それもあなたが@Transformデコレータで変換を制御することができます、あなたが必要とするかもしれないすべてのものを持っているので、小さなではありません:D
ディエゴ・フェルナンド・ムリーリョValenci

3
このライブラリはほとんど保守されていないことに注意してください。Angular5 +では動作しなくなり、プルリクエストをマージすることさえなくなったので、すぐには動作しないと思います。それは素晴らしいライブラリです。
ケンター2018

Angular5 +には回避策があります(実際にはAngularのバグです):github.com/typestack/class-transformer/issues/108
Pak

2
これは、Angular 6でうまく機能します(少なくとも、JSON <=>クラスを文字どおりにマップするための私のユースケースでは)
tftd

54

TypeScriptでは、次のようなインターフェイスとジェネリックスを使用して型アサーションを実行できます。

var json = Utilities.JSONLoader.loadFromFile("../docs/location_map.json");
var locations: Array<ILocationMap> = JSON.parse(json).location;

ILocationMapはデータの形状を表します。このメソッドの利点は、JSONにさらに多くのプロパティを含めることができるが、形状がインターフェースの条件を満たすことです。

お役に立てば幸いです。


49
参考までに:これは型の表明であり、キャストではありません。
WiredPrairie 2015

6
型アサーションキャストの違いについては、こちらをご覧ください。
Stefan Hanke、2015

7
Utilities.JSONLoaderはどこにありますか?
HypeXR 2016

22
しかし、回答で述べたように、メソッドはありません。
マルティン・コル

1
@StefanHankeはURLがわずかに変更されたように見えます:"Type Assertion vs. Casting"
ruffin

37

ES6を使用している場合は、次のことを試してください。

class Client{
  name: string

  displayName(){
    console.log(this.name)
  }
}

service.getClientFromAPI().then(clientData => {

  // Here the client data from API only have the "name" field
  // If we want to use the Client class methods on this data object we need to:
  let clientWithType = Object.assign(new Client(), clientData)

  clientWithType.displayName()
})

しかし、悲しいことに、この方法はnestオブジェクトは機能しません


4
彼らはTypescriptでそれを求めました。
joe.feser 2017年

こんにちは@ joe.feser、私はES6について言及します。これは、この方法で 'Object.assign'メソッドが必要になるためです。
migcoder

1
デフォルトのコンストラクターがない場合はObject.create(MyClass.prototype)、コンストラクターを完全にバイパスして、を介してターゲットインスタンスを作成できます。
マルチェロ

ネストされたオブジェクトの制限についての詳細は、stackoverflow.com
questions / 22885995 /…を

28

TypescriptクラスへのJSONの一般的なキャストに関する非常に興味深い記事を見つけました。

http://cloudmark.github.io/Json-Mapping/

あなたは次のコードで終わります:

let example = {
                "name": "Mark", 
                "surname": "Galea", 
                "age": 30, 
                "address": {
                  "first-line": "Some where", 
                  "second-line": "Over Here",
                  "city": "In This City"
                }
              };

MapUtils.deserialize(Person, example);  // custom class

20

TLDR:1つのライナー

// This assumes your constructor method will assign properties from the arg.
.map((instanceData: MyClass) => new MyClass(instanceData));

詳細な回答

私は考えていない、それはクラス自体内で宣言されていなかった無関係の特性(同様に定義された閉鎖)でごみあなたのクラスのインスタンスを不適切にすることができますよう、Object.assignアプローチをお勧めします。

逆シリアル化しようとしているクラスで、逆シリアル化したいプロパティが定義されていることを確認します(null、空の配列など)。プロパティを初期値で定義することにより、クラスメンバーを反復して値を割り当てるときにそれらの可視性を公開します(以下のデシリアライズメソッドを参照)。

export class Person {
  public name: string = null;
  public favoriteSites: string[] = [];

  private age: number = null;
  private id: number = null;
  private active: boolean;

  constructor(instanceData?: Person) {
    if (instanceData) {
      this.deserialize(instanceData);
    }
  }

  private deserialize(instanceData: Person) {
    // Note this.active will not be listed in keys since it's declared, but not defined
    const keys = Object.keys(this);

    for (const key of keys) {
      if (instanceData.hasOwnProperty(key)) {
        this[key] = instanceData[key];
      }
    }
  }
}

上記の例では、単純に逆シリアル化メソッドを作成しました。実際の例では、再利用可能な基本クラスまたはサービスメソッドに集中化します。

これは、http応答のようなものでこれを利用する方法です...

this.http.get(ENDPOINT_URL)
  .map(res => res.json())
  .map((resp: Person) => new Person(resp) ) );

tslint / ideが引数の型に互換性がないと文句を言う場合は、山括弧を使用して引数を同じ型にキャストしてください<YourClassName>。例:

const person = new Person(<Person> { name: 'John', age: 35, id: 1 });

特定のタイプ(別名:別のクラスのインスタンス)のクラスメンバーがある場合は、getter / setterメソッドを介して型付きインスタンスにキャストできます。

export class Person {
  private _acct: UserAcct = null;
  private _tasks: Task[] = [];

  // ctor & deserialize methods...

  public get acct(): UserAcct {
    return this.acct;
  }
  public set acct(acctData: UserAcct) {
    this._acct = new UserAcct(acctData);
  }

  public get tasks(): Task[] {
    return this._tasks;
  }

  public set tasks(taskData: Task[]) {
    this._tasks = taskData.map(task => new Task(task));
  }
}

上記の例では、acctとタスクのリストの両方をそれぞれのクラスインスタンスに逆シリアル化します。


次のエラーメッセージが表示されます:タイプ '{名前:文字列、年齢:番号、ID:番号}'をタイプ '個人'に変換できません。プロパティ 'id'は、タイプ 'Person'ではプライベートですが、タイプ '{name:string、age:number、id:number}'では
プライベートです

これを列挙型でどのように使用すればよいですか?特定のタイプのアプローチを使用し、それにゲッターとセッターを追加する必要がありますか?
TadijaBagarić17年

@TimothyParezタスクはいつ設定しますか?
Kay

私は同じようなことをやろうとしましたが、console.logの人のとき、私のタスク配列は空です。
Kay

これをコンパイルするには、クラスにインデックス署名を追加する必要がありました:export class Person {[key:string]:any(...)}
Asimov

18

jsonがtypescriptクラスと同じプロパティを持っていると仮定すると、Jsonプロパティをtypescriptオブジェクトにコピーする必要はありません。コンストラクタでjsonデータを渡してTypescriptオブジェクトを作成するだけです。

ajaxコールバックでは、会社を受け取ります。

onReceiveCompany( jsonCompany : any ) 
{
   let newCompany = new Company( jsonCompany );

   // call the methods on your newCompany object ...
}

それを機能させるために:

1)jscriptデータをパラメーターとして取るコンストラクターをTypescriptクラスに追加します。そのコンストラクターで、jsonオブジェクトを次のようにjQueryで拡張します$.extend( this, jsonData)。$ .extendを使用すると、jsonオブジェクトのプロパティを追加しながら、javascriptプロトタイプを保持できます。

2)リンクされたオブジェクトについても同じようにする必要があることに注意してください。この例のEmployeesの場合は、jsonデータの一部の従業員を取得するコンストラクターも作成します。$ .mapを呼び出して、json従業員をtypescript Employeeオブジェクトに変換します。

export class Company
{
    Employees : Employee[];

    constructor( jsonData: any )
    {
        $.extend( this, jsonData);

        if ( jsonData.Employees )
            this.Employees = $.map( jsonData.Employees , (emp) => {
                return new Employee ( emp );  });
    }
}

export class Employee
{
    name: string;
    salary: number;

    constructor( jsonData: any )
    {
        $.extend( this, jsonData);
    }
}

これは、Typescriptクラスとjsonオブジェクトを扱うときに私が見つけた最良のソリューションです。


私のAngular2アプリケーションには、私のアプリケーションが使用するWebサービスのモデルとは異なる可能性がある実際のアプリケーションモデルがあるため、インターフェースの実装と維持よりもこのソリューションを好みます。プライベートデータと計算されたプロパティを持つことができます。
AnthonyBrenelière2017年

7
AngularプロジェクトでJQueryを使用するのはひどい考えです。また、モデルに多数の関数が含まれている場合、それらはモデルではなくなります。
Davor

1
@Davor POJO、またはモデルのことですか?POJO(基本的にプレーンオブジェクト)には機能がありませんが、モデルはより広い用語であり、リポジトリを含みます。POJOとは対照的に、リポジトリパターンは関数に関するものですが、それでもモデルです。
フォースバーグ2017年

@Davor:DOMを操作するために使用しない限り、AngularプロジェクトでJQueryを使用することは悪い考えではありません。これは本当にひどい考えです。私のAngularプロジェクトに必要なライブラリはすべて使用します。jQueryの場合、プロジェクトに依存するSignalRを使用するため、これはオプションではありません。現在、JavaScript ES6で使用されているクラスの場合、データは、データがメモリに格納される方法をカプセル化する関数であるプロパティでアクセスされます。コンストラクターには、ファクトリーを使用する適切な方法があります。
AnthonyBrenelière2017年

OPは明らかにRESTのプレーンデータモデルについてです。あなたはそれを不必要に複雑にしています、皆さん。そして、そうです、追加のものにJqueryを使用できますが、その1%を使用するために大規模なライブラリーをインポートしています。私がこれまでに見たことがなければ、それはコードのにおいです。
Davor

18

サーバーから受け取ったJSONオブジェクトが、typescriptのインターフェイスプロパティに期待される(読み取りが準拠している)かどうかを自動的にチェックするものはまだありません。ただし、ユーザー定義のタイプガードを使用できます。

次のインターフェースとばかげたjsonオブジェクトを考えます(任意のタイプである可能性があります):

interface MyInterface {
    key: string;
 }

const json: object = { "key": "value" }

3つの可能な方法:

A.変数の後に配置される型アサーションまたは単純な静的キャスト

const myObject: MyInterface = json as MyInterface;

B.変数の前とダイヤモンドの間の単純な静的キャスト

const myObject: MyInterface = <MyInterface>json;

C.高度な動的キャスト。オブジェクトの構造を自分で確認します

function isMyInterface(json: any): json is MyInterface {
    // silly condition to consider json as conform for MyInterface
    return typeof json.key === "string";
}

if (isMyInterface(json)) {
    console.log(json.key)
}
else {
        throw new Error(`Expected MyInterface, got '${json}'.`);
}

ここでこの例を試すことができます

ここでの難しさはisMyInterface関数を書くことです。TSがデコレータを追加して、複雑な型付けをランタイムにエクスポートし、必要に応じてランタイムがオブジェクトの構造をチェックできるようにしてほしいと思います。現時点では、目的がほぼ同じであるjsonスキーマバリデーターを使用するか、このランタイムタイプチェック関数ジェネレーターを使用できます


1
あなたの答えは私が思う一番上にあるはずです
afzalex

絶対に。これは、ts Webサイトに直接依存する最良の回答です。
BurakKarakuş

15

私の場合、それは動作します。関数 Object.assign(target、sources ...)を使用しました。まず、正しいオブジェクトを作成してから、jsonオブジェクトからターゲットにデータをコピーします。例:

let u:User = new User();
Object.assign(u , jsonUsers);

そして、より高度な使用例。配列を使用した例。

this.someService.getUsers().then((users: User[]) => {
  this.users = [];
  for (let i in users) {
    let u:User = new User();
    Object.assign(u , users[i]);
    this.users[i] = u;
    console.log("user:" + this.users[i].id);
    console.log("user id from function(test it work) :" + this.users[i].getId());
  }

});

export class User {
  id:number;
  name:string;
  fullname:string;
  email:string;

  public getId(){
    return this.id;
  }
}

私有財産があるとどうなりますか?
prasanthv 2017

jsonUserオブジェクトはUserクラスではないためです。操作Object.assign(u、jsonUsers);なし。getId()関数は使用できません。割り当て後のみ、getId()関数を使用できる有効なUserオブジェクトを取得します。getId()関数は、操作が成功した例のみを示しています。
Adam111p 2017

一時this.users[i] = new User(); Object.assign(this.users[i], users[i])
変数

戻り値のまたはより良いメイクの使用:this.users[i] = Object.assign(new User(), users[i]);
cyptus

この長いバージョンは説明のみを目的としています。コードは好きなだけ短くできます:)
Adam111p

6

それ自体はキャストではありませんが、https://github.com/JohnWhiteTB/TypedJSONが便利な代替手段であることがわかりました。

@JsonObject
class Person {
    @JsonMember
    firstName: string;

    @JsonMember
    lastName: string;

    public getFullname() {
        return this.firstName + " " + this.lastName;
    }
}
var person = TypedJSON.parse('{ "firstName": "John", "lastName": "Doe" }', Person);

person instanceof Person; // true
person.getFullname(); // "John Doe"

1
キャストしない、それは実際に何をするのですか?
DanielM 2017

1
このソリューションには、非常に多くの注釈が必要です。本当に簡単な方法はありませんか?
JPNotADragon


3

jsonオブジェクトをtypescriptクラスにキャストし、そのインスタンスメソッドを結果のオブジェクトで使用できるObject.setPrototypeOfようにする必要がある場合は、次のコードスニペットで行ったように、使用する必要があります。

Object.setPrototypeOf(jsonObject, YourTypescriptClass.prototype)

2

ほぼ正しいが非常に効率的な回答ではない古い質問。これは私が提案するものです:

init()メソッドと静的キャストメソッド(単一のオブジェクトと配列用を含む基本クラスを作成します。静的メソッドはどこにあってもかまいません。基本クラスとinit()を備えたバージョンでは、後で簡単に拡張できます。

export class ContentItem {
    // parameters: doc - plain JS object, proto - class we want to cast to (subclass of ContentItem)
    static castAs<T extends ContentItem>(doc: T, proto: typeof ContentItem): T {
        // if we already have the correct class skip the cast
        if (doc instanceof proto) { return doc; }
        // create a new object (create), and copy over all properties (assign)
        const d: T = Object.create(proto.prototype);
        Object.assign(d, doc);
        // reason to extend the base class - we want to be able to call init() after cast
        d.init(); 
        return d;
    }
    // another method casts an array
    static castAllAs<T extends ContentItem>(docs: T[], proto: typeof ContentItem): T[] {
        return docs.map(d => ContentItem.castAs(d, proto));
    }
    init() { }
}

同様のメカニズム(assign()を使用)は、@ Adam111p投稿で言及されています。それを行うもう1つの(より完全な)方法です。@Timothy Perezはassign()に批判的ですが、ここでは完全に適切です。

派生した(実際の)クラスを実装します。

import { ContentItem } from './content-item';

export class SubjectArea extends ContentItem {
    id: number;
    title: string;
    areas: SubjectArea[]; // contains embedded objects
    depth: number;

    // method will be unavailable unless we use cast
    lead(): string {
        return '. '.repeat(this.depth);
    }

    // in case we have embedded objects, call cast on them here
    init() {
        if (this.areas) {
            this.areas = ContentItem.castAllAs(this.areas, SubjectArea);
        }
    }
}

これで、サービスから取得したオブジェクトをキャストできます。

const area = ContentItem.castAs<SubjectArea>(docFromREST, SubjectArea);

SubjectAreaオブジェクトのすべての階層に正しいクラスがあります。

ユースケース/例。Angularサービスを作成します(もう一度基本クラスを抽象化します):

export abstract class BaseService<T extends ContentItem> {
  BASE_URL = 'http://host:port/';
  protected abstract http: Http;
  abstract path: string;
  abstract subClass: typeof ContentItem;

  cast(source: T): T {
    return ContentItem.castAs(source, this.subClass);
  }
  castAll(source: T[]): T[] {
    return ContentItem.castAllAs(source, this.subClass);
  }

  constructor() { }

  get(): Promise<T[]> {
    const value = this.http.get(`${this.BASE_URL}${this.path}`)
      .toPromise()
      .then(response => {
        const items: T[] = this.castAll(response.json());
        return items;
      });
    return value;
  }
}

使い方はとても簡単になります。エリアサービスを作成します。

@Injectable()
export class SubjectAreaService extends BaseService<SubjectArea> {
  path = 'area';
  subClass = SubjectArea;

  constructor(protected http: Http) { super(); }
}

サービスのget()メソッドは、SubjectAreaオブジェクト(階層全体)として既にキャストされた配列のPromiseを返します

ここで、別のクラスがあるとします。

export class OtherItem extends ContentItem {...}

データを取得して正しいクラスにキャストするサービスの作成は、次のように簡単です。

@Injectable()
export class OtherItemService extends BaseService<OtherItem> {
  path = 'other';
  subClass = OtherItem;

  constructor(protected http: Http) { super(); }
}

2

インターフェイスから拡張されたクラスを使用します。

次に:

Object.assign(
                new ToWhat(),
                what
              )

そして最高:

Object.assign(
                    new ToWhat(),
                    <IDataInterface>what
                  )

ToWhatはDataInterfaceのコントローラーになります。



0

TSの後半では、次のようにすることができます。

const isMyInterface = (val: any): val is MyInterface => {
  if (!val) { return false; }
  if (!val.myProp) { return false; }
  return true;
};

そして、このようなユーザーより:

if (isMyInterface(data)) {
 // now data will be type of MyInterface
}

0

私も同じようなニーズに遭遇しました。特定のクラス定義とのREST API呼び出しからのJSONへの簡単な変換ができるものを望んでいました。私が見つけた解決策は、クラスのコードを書き直して注釈または類似のものを追加するのに不十分または意味がありませんでした。

JavaでGSONを使用してクラスをJSONオブジェクトとの間でシリアル化/逆シリアル化したかったのですが。

コンバーターがJSでも機能するという後の必要性と合わせて、私は自分のパッケージの作成を終了しました。

ただし、少しオーバーヘッドがあります。しかし、起動すると、追加や編集に非常に便利です。

あなたはモジュールを初期化します:

  1. 変換スキーマ-フィールド間のマッピングと変換の実行方法の決定を可能にします
  2. クラスマップ配列
  3. 変換関数マップ-特別な変換用。

次に、コードで、次のように初期化されたモジュールを使用します。

const convertedNewClassesArray : MyClass[] = this.converter.convert<MyClass>(jsonObjArray, 'MyClass');

const convertedNewClass : MyClass = this.converter.convertOneObject<MyClass>(jsonObj, 'MyClass');

または、JSONに:

const jsonObject = this.converter.convertToJson(myClassInstance);

npmパッケージへのこのリンクと、モジュールの操作方法の詳細な説明を使用してください:json-class-converter

また、
Angularでの使用のためにそれをラップしました: angular-json-class-converter


0

オブジェクトをそのままクラスコンストラクターに渡します。規約やチェックはありません

interface iPerson {
   name: string;
   age: number;
}

class Person {
   constructor(private person: iPerson) { }

   toString(): string {
      return this.person.name + ' is ' + this.person.age;
   }  
}


// runs this as // 
const object1 = { name: 'Watson1', age: 64 };
const object2 = { name: 'Watson2' };            // age is missing

const person1 = new Person(object1);
const person2 = new Person(object2 as iPerson); // now matches constructor

console.log(person1.toString())  // Watson1 is 64
console.log(person2.toString())  // Watson2 is undefined

0

このnpmパッケージを使用できます。https://www.npmjs.com/package/class-converter

使い方は簡単です。例えば:

class UserModel {
  @property('i')
  id: number;

  @property('n')
  name: string;
}

const userRaw = {
  i: 1234,
  n: 'name',
};

// use toClass to convert plain object to class
const userModel = toClass(userRaw, UserModel);
// you will get a class, just like below one
// const userModel = {
//   id: 1234,
//   name: 'name',
// }

0

個人的には、typescriptではエンドポイントの定義で受信するオブジェクトのタイプを指定できないのが恐ろしいと思います。これが実際にそうであるように、私は他の言語で行ったことと同じことを行います。つまり、JSONオブジェクトをクラス定義から分離し、クラス定義でJSONオブジェクトを唯一のデータメンバーとして使用します。 。

私は定型コードを軽視しているので、私にとっては通常、型を保持しながら最小限のコードで目的の結果を得ることが問題です。

次のJSONオブジェクト構造定義を検討してください。これらはエンドポイントで受け取るものであり、構造定義のみであり、メソッドではありません。

interface IAddress {
    street: string;
    city: string;
    state: string;
    zip: string;
}

interface IPerson {
    name: string;
    address: IAddress;
}

上記をオブジェクト指向の用語で考えると、上記のインターフェイスはデータ構造を定義するだけなので、クラスではありません。オブジェクト指向のクラスは、データとそれを操作するコードを定義します。

そこで、データとそれを操作するコードを指定するクラスを定義します...

class Person {
    person: IPerson;

    constructor(person: IPerson) {
        this.person = person;
    }

    // accessors
    getName(): string {
        return person.name;
    }

    getAddress(): IAddress {
        return person.address;
    }

    // You could write a generic getter for any value in person, 
    // no matter how deep, by accepting a variable number of string params

    // methods
    distanceFrom(address: IAddress): float {
        // Calculate distance from the passed address to this persons IAddress
        return 0.0;
    }
}

これで、IPerson構造に準拠するオブジェクトを渡すだけで、処理を続行できます...

   Person person = new Person({
            name: "persons name",
            address: {
                street: "A street address",
                city: "a city",
                state: "a state",
                zip: "A zipcode"
            }
        });

同じ方法で、エンドポイントで受信したオブジェクトを次のように処理できます...

Person person = new Person(req.body);    // As in an object received via a POST call

person.distanceFrom({ street: "Some street address", etc.});

これはパフォーマンスがはるかに高く、メモリの半分を使用してデータをコピーする一方で、エンティティタイプごとに記述する必要があるボイラープレートコードの量を大幅に削減します。TypeScriptが提供する型の安全性に依存しています。



-1

これはシンプルで本当に良いオプションです

let person = "{"name":"Sam","Age":"30"}";

const jsonParse: ((key: string, value: any) => any) | undefined = undefined;
let objectConverted = JSON.parse(textValue, jsonParse);

そして、あなたは持っているでしょう

objectConverted.name

-1

ここでこのライブラリを使用しました:https : //github.com/pleerock/class-transformer

<script lang="ts">
    import { plainToClass } from 'class-transformer';
</script>

実装:

private async getClassTypeValue() {
  const value = await plainToClass(ProductNewsItem, JSON.parse(response.data));
}

場合によっては、plainToClassのJSON値を解析して、それがJSON形式のデータであることを理解する必要があります


「クラス・トランス」ライブラリーは、すでに上記の他の回答で提案されてstackoverflow.com/a/40042282/52277
マイケルFreidgeim

-1

Javaオブジェクトを返すフロントエンドでAngular 6を、バックエンドでSpring Bootアプリケーションを使用しています。私がする必要があるのは、一致するプロパティを持つ角度アプリケーションで同様のクラスを定義することだけです。それから、オブジェクトを角度クラスオブジェクトとして「受け入れる」ことができます(Comp as Company)。以下の例では)。

例として、以下のフロントエンドコードを参照してください。より明確にする必要があるものがあればコメントで教えてください。

  createCompany() {
    let company = new Company();
    company.name = this.companyName;

    this.companyService.createCompany(company).subscribe(comp => {
       if (comp !== null) {
        this.employerAdminCompany = comp as Company;
      }
    });
  }

ここで、companyはSpring Bootアプリのエンティティオブジェクトであり、Angularのクラスでもあります。

export class Company {
    public id: number;
    public name: string;
    public owner: User;
    public locations: Array<Location>;
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.