Як я передаю об'єкт JSON класу typecript


393

Я читаю об’єкт JSON з віддаленого сервера REST. Цей об’єкт JSON має всі властивості класу машинописів (за конструкцією). Як передати отриманий об’єкт JSON у тип var?

Я не хочу заповнювати var typecript (тобто мати конструктор, який приймає цей об'єкт JSON). Вона велика, і копіювання всього предмета на суб'єкт та властивість на власність зайняло б багато часу.

Оновлення: однак ви можете передати його на інтерфейс машинопису!


ви можете використовувати github.com/vojtechhabarta/typescript-generator для створення інтерфейсів TypeScript у випадку, якщо ваш JSON відображений за допомогою класів Java
Vojta


1
Об'єкт JSON = Об'єкт позначення JavaScript. Немає в ньому достатньо предметів, я кажу, що ми кидаємо ще пару для гарної міри.
баг-лот

1
Я зробив інструмент для цього beshanoe.github.io/json2ts
beshanoe

Створення прототипу класу TypeScript для визначення вашого об'єкта не зашкодить реальному виробничому коду. Погляньте на складений файл JS, всі визначення буде видалено, оскільки вони не є частиною JS.
FisNaN

Відповіді:


167

Ви не можете просто передати звичайний старий результат JavaScript від запиту Ajax у прототипний екземпляр класу JavaScript / TypeScript. Існує цілий ряд методів для цього і, як правило, передбачає копіювання даних. Якщо ви не створите примірник класу, він не матиме жодних методів чи властивостей. Це залишиться простим об’єктом JavaScript.

Хоча якби ви мали справу лише з даними, ви могли просто зробити передачу інтерфейсу (оскільки це суто структура часу компіляції), для цього потрібно використовувати клас TypeScript, який використовує екземпляр даних і виконує операції з цими даними.

Деякі приклади копіювання даних:

  1. Копіювання об'єкта AJAX JSON в існуючий Об'єкт
  2. Проаналізуйте рядок JSON в прототип конкретного об'єкта в JavaScript

По суті, ви просто:

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

Я згоден з вашою відповіддю. Як додаток, хоча мені зараз не вдається розглянути його і перевірити, я думаю, що ці два кроки можна поєднати, надавши функцію пробудження як парам JSON.parse(). І те й інше все ще потрібно зробити, але синтаксично їх можна поєднувати.
JAAulde

Звичайно, це теж може працювати - я не маю відчуття, чи було б воно більш ефективним, хоча як би потрібно було викликати додатковий виклик функції для кожного ресурсу.
WiredPrairie

Однозначно не відповідь, яку я шукав :( З цікавості, чому це? Мені здається, як працює javascript, що це слід зробити.
Девід Тілен

Ні, це не працює в TypeScript, тому що в JavaScript немає простого способу зробити це.
WiredPrairie

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приміток). Ця відповідь заслуговує на більше кредиту.
Бенні Боттема

О, вау !, ця бібліотека не настільки крихітна, вона має, можливо, все, що вам потрібно, навіть дозволяє контролювати трансформацію за допомогою декоратора @transform: D
Дієго Фернандо Мурілло Валенсі,

3
Зверніть увагу, що ця бібліотека ледве підтримується. Він більше не працює з Angular5 +, і оскільки вони вже навіть не об'єднують запити на виклик, я не думаю, що вони незабаром працюватимуть над цим. Хоча це чудова бібліотека.
Кентор

Існує вирішення для Angular5 + (це насправді Angular Bug): github.com/typestack/class-transformer/isissue/108
Пак

2
Це працює чудово в кутовій 6 (принаймні, для мого використання, який полягає в тому, щоб буквально відобразити JSON <=> Class)
tftd

54

У TypeScript ви можете зробити твердження типу, використовуючи інтерфейс та загальну інформацію:

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

Там, де ILocationMap описує форму ваших даних. Перевага цього методу полягає в тому, що ваш JSON може містити більше властивостей, але форма задовольняє умовам інтерфейсу.

Я сподіваюся, що це допомагає!


49
FYI: Це твердження типу, а не акторський склад.
WiredPrairie

6
Тут дивіться різницю між типовим твердженням та анонсом .
Стефан Ханке

7
Де я можу знайти Utilities.JSONLoader?
HypeXR

22
Але це не матиме жодних методів, про що йдеться у відповіді.
Мартін Колл

1
@StefanHanke виглядає так, що URL трохи змінився: "Введіть твердження проти кастингу"
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()
})

Але цей спосіб не спрацює на гніздовому об’єкті , на жаль.


4
Вони просили це в Typescript.
joe.feser

HI @ joe.feser, я згадую ES6, тому що таким чином потрібен метод 'Object.assign'.
migcoder

1
Якщо конструктор за замовчуванням відсутній, цільовий екземпляр може бути створений шляхом Object.create(MyClass.prototype), повністю обходячи конструктор.
Marcello

Більш пояснення про вкладені об'єктах обмеження см в stackoverflow.com/questions/22885995 / ...
Майкл Freidgeim

28

Я знайшов дуже цікаву статтю про загальний кастинг JSON до класу Typescript:

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: Один вкладиш

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

Детальний відповідь

Я б не рекомендував підхід Object.assign, оскільки він може неналежним чином засмітити ваш екземпляр класу невідповідними властивостями (а також визначеними закриттями), які не були оголошені в межах самого класу.

У класі, в який ви намагаєтеся десеріалізувати, я б гарантував, що визначені будь-які властивості, які ви хочете десеріалізувати (нульовий, порожній масив тощо). Визначаючи свої властивості з початковими значеннями, ви виявляєте їх видимість при спробі ітерації членів класу для присвоєння значень (див. Метод десеріалізації нижче).

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 resp ...

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));
  }
}

Наведений вище приклад дезаріалізує як дію, так і список завдань у відповідних екземплярах класу.


Я отримую це повідомлення про помилку: Введіть '{ім'я: рядок, вік: номер, ідентифікатор: номер}' не можна перетворити у тип 'Особа'. Властивість 'id' приватна типу "Person", але не за типом "{ім'я: рядок, вік: номер, id: номер} '
utiq

Як я маю це використовувати із перерахунками? Чи потрібно використовувати підхід конкретного типу та додавати для нього геттер і сетер?
Tadija Bagarić

@TimothyParez Коли ви ставите завдання?
Кей

Я намагався зробити щось подібне, але масив моїх завдань порожній, коли я console.log person.
Кей

Для цього для компіляції мені довелося додати індекс підпису до класу: експортний клас Особа {[key: string]: any (...)}
Азимов

18

Якщо припустити, що json має ті ж властивості, що і для вашого класу typecript, вам не доведеться копіювати свої властивості Json у ваш об'єкт typecript. Вам просто доведеться побудувати об’єкт Typescript, передаючи дані json у конструктор.

Під час зворотного дзвінка ajax ви отримуєте компанію:

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

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

Для того, щоб зробити цю роботу:

1) Додайте конструктор у свій клас Typescript, який приймає дані json як параметр. У цьому конструкторі ви розширюєте свій об’єкт json за допомогою jQuery, наприклад:$.extend( this, jsonData) . $ .extend дозволяє зберігати прототипи javascript, додаючи властивості об’єкта json.

2) Зауважте, що вам доведеться робити те ж саме для пов'язаних об'єктів. Що стосується працівників у прикладі, ви також створюєте конструктор, який приймає частину даних json для працівників. Ви закликаєте $ .map для перекладу співробітників json на машинописні об'єкти 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 є реальна модель програми, яка може відрізнятися від моделі веб-сервісів, якими користується моя програма. Він може мати приватні дані та обчислені властивості.
Ентоні Бренельєр

7
Використання JQuery в кутових проектах - жахлива ідея. І якщо ваші моделі містять у собі купу функцій, вони вже не є моделями.
Давор

1
@Davor Ви маєте на увазі POJO чи модель? POJO (в основному звичайні об'єкти) не мають функцій, тоді як модель - це більш широкий термін, і він включає сховище. Шаблон сховища, на відміну від POJO, стосується функцій, але все ще є моделлю.
форсберг

@Davor: використання JQuery в кутових проектах не є поганою ідеєю, якщо ви не використовуєте його для маніпулювання DOM, що справді є жахливою ідеєю. Я використовую будь-яку потрібну мені бібліотеку для своїх кутових проектів, а для jQuery це не варіант, оскільки мій проект використовує SignalR, який залежить від нього. У випадку класів, які зараз використовуються javascript ES6, доступ до даних здійснюється з властивостями, які є функцією, яка інкапсулює спосіб збереження даних у пам'яті. Для конструкторів існує правильний спосіб використання заводів.
Ентоні Бренелье

ОП чітко стосується простих моделей даних для REST. Ви робите це непотрібно складніше, хлопці. І так, ви можете використовувати Jquery для додаткових матеріалів, але ви імпортуєте масивну бібліотеку, щоб використовувати 1% її. Це кодовий запах, якщо я його коли-небудь бачив.
Давор

18

Ще немає нічого, щоб автоматично перевірити, чи отриманий від сервера об'єкт JSON має очікувані властивості інтерфейсу typecript (читання відповідає). Але ви можете використовувати захищені типом охоронці

Враховуючи наступний інтерфейс і нерозумний json-об’єкт (це міг бути будь-який тип):

interface MyInterface {
    key: string;
 }

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

Три можливі способи:

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.
Бурак Каракуш

15

У моєму випадку це працює. Я використовував функції Object.assign (ціль, джерела ...) . Спочатку створюється правильний об'єкт, потім копіюються дані з 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

Тому що об’єкт jsonUser не є класом користувача. Без операції Object.assign (u, jsonUsers); Не можна використовувати функцію getId (). Лише після призначення ви отримуєте дійсний об'єкт User, в якому ви можете використовувати функцію getId (). Функція getId () є лише прикладом успішної операції.
Adam111p

ви можете пропустити темп-вар - просто робітьthis.users[i] = new User(); Object.assign(this.users[i], users[i])
cyptus

а ще краще скористайтеся зворотним значенням: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

1
Для цього рішення потрібно надзвичайно багато приміток. Невже немає простішого шляху?
JPNotADragon

3

Ви можете створити interfaceтип свого типу ( SomeType) і закинути об'єкт у ньому.

const typedObject: SomeType = <SomeType> responseObject;

3

Якщо вам потрібно віднести ваш об’єкт json до класу typecript і наявні його методи екземпляра в отриманому об'єкті, який потрібно використовувати 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() { }
}

Подібні механіки (з присвоєнням () ) були згадані в публікації @ Adam111p. Просто ще один (більш повний) спосіб зробити це. @Timothy Perez критично ставиться до присвоєння () , але імхо це цілком доречно.

Реалізуйте похідний (реальний) клас:

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;
  }
}

Використання стає дуже простим; створити службу Area:

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

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

Метод get () послуги поверне Обіцяння масиву, який вже передано як SubjectArea об'єкти (вся ієрархія)

А тепер скажіть, у нас є ще один клас:

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
                  )

Для того, що стає контролером DataInterface.



0

У пізньому ТС ви можете зробити так:

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

Я зіткнувся з подібною потребою. Я хотів чогось, що дасть мені просту трансформацію з / в JSON, що походить від виклику REST api до / з конкретного визначення класу. Знайдені нами рішення були недостатніми або мали на меті переписати код моїх класів та додавати анотації чи подібні засоби.

Я хотів, щоб щось на зразок GSON використовується в Java для серіалізації / деріаріалізації класів до / з 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-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

Особисто мені здається жахливим, що typecript не дозволяє визначенню кінцевої точки визначати тип отриманого об'єкта. Оскільки виявляється, що це дійсно так, я б робив те, що робив з іншими мовами, і це полягає в тому, що я би відокремлював об'єкт JSON від визначення класу, і, якщо визначення класу використовувало об'єкт JSON як єдиний член даних .

Я зневажаю код котла, тому для мене зазвичай питання досягнення бажаного результату з найменшою кількістю коду при збереженні типу.

Розглянемо наступні визначення об'єктної структури JSON - це було б те, що ви отримаєте в кінцевій точці, вони є лише визначеннями структури, ніяких методів.

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

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

Якщо ми думаємо про вищезазначене в об'єктно-орієнтованому вираженні, вищевказані інтерфейси не є класами, оскільки вони визначають лише структуру даних. Клас в умовах OO визначає дані та код, який діє на них.

Отже, ми зараз визначимо клас, який визначає дані та код, який працює на ньому ...

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));
}

Іноді вам доведеться проаналізувати значення JSON для plainToClass, щоб зрозуміти, що це дані, відформатовані JSON


Бібліотека «клас-трансформер» вже пропонуються в іншому відповіді вище stackoverflow.com/a/40042282/52277
Майкл Freidgeim

-1

Я використовую програму Angular 6 на передній панелі та програмі Spring Boot на бекенді, який повертає об'єкти Java. Все, що мені потрібно зробити, - це визначити подібний клас у кутовій програмі, яка має відповідні властивості, і тоді я можу прийняти об’єкт 'як' об’єкт кутового класу ( comp як Company у наведеному нижче прикладі).

Наприклад, зверніться до коду переднього кінця нижче. Повідомте мене в коментарях, якщо щось потребує більшої ясності.

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

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

де компанія є об’єктом сутності у весняному завантажувальному додатку, а також є класом у Angular.

export class Company {
    public id: number;
    public name: string;
    public owner: User;
    public locations: Array<Location>;
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.