Классы с данными гидратации / дегидратации в машинописи - PullRequest
4 голосов
/ 25 июня 2019

Я хотел бы поделиться классами TS или интерфейсами между внешним интерфейсом React + TS и внутренним узлом + TS.Проблема в том, что типы TS удаляются во время компиляции, поэтому я не могу использовать их, когда хочу преобразовать экземпляр класса в JSON.

Мне было интересно, есть ли какие-нибудь решения, с помощью которых я мог бы описать свойОбъект в статическом файле, генерировать классы TS и использовать этот файл для гидратации и дегидратации данных.Некоторые свойства являются moment.js объектами и Decimal.js объектами.Я ищу решение, в котором преобразование может быть выполнено на основе статического дескриптора, мне не нужно писать его для каждого свойства вручную.

Обезвоженный формат используется в HTTP-запросе плюс он хранится вDB (Firebase Firestore) и доступ к нему напрямую через интерфейс для чтения.

1 Ответ

2 голосов
/ 26 июня 2019

Я бы подошел к этому, используя потрясающую библиотеку io-ts.

Обезвоженный формат используется в HTTP-запросе, плюс он хранится в БД (Firebase Firestore) и доступен для чтения напрямую из внешнего интерфейса.

В общем, я бы предположил разные форматы сериализации для разных слоев. Если в вашем конкретном случае это упрощение можно сделать, то 101

Мне было интересно, есть ли какие-нибудь решения, с помощью которых я мог бы описать свой объект в статическом файле

С io-ts вы бы определили набор codec s как значения TypeScript, представляющие ваш домен. Кодек является как валидатором, так и (де) сериализатором, поэтому вы можете очень хорошо сериализовать экземпляр класса в строку JSON и наоборот (при условии, что JSON успешно проверен, а затем создан экземпляр класса с соответствующими десериализованными значениями) .

Ниже приведен упрощенный и очень нестандартный кодек, выполняющий такую ​​работу:

// class definition:

class MyModel {
  constructor(readonly value: number) {}

  getValue() {
    return this.value;
  }
}

// codec definition:

import * as t from 'io-ts';
import { JSONFromString } from 'io-ts-types/lib/JSON/JSONFromString';

const MyModelFromString = new t.Type<MyModel, string, unknown>(
  'MyModel',
  (value): value is MyModel => value instanceof MyModel,
  str =>
    t.string
      .decode(str)
      .chain(JSONFromString.decode)
      .chain(json => t.type({ value: t.number }).decode(json))
      .map(({ value }) => new MyModel(value)),
  instance => JSON.stringify({ value: instance.value })
);

// usage:

MyModelFromString.decode('{ "value": 1 }').fold(
  errors => {
    console.error(errors);
  },
  inst => {
    // inst has type `MyModel` here
    console.log(inst.getValue());
  }
);

MyModelFromString.encode(new MyModel(2)); // '{ "value": 2 }'

Кроме того, вы, как правило, позаботитесь о сериализации также какого-либо тега, позволяющего вам решить, какой класс вы собираетесь попытаться создать, просто глядя на обычную сериализованную строку JSON.

Вы также, вероятно, захотите взглянуть на io-ts-types, который уже включает в себя множество готовых к использованию кодеков, которые вы, вероятно, можете использовать повторно, например DateFromISOString.

...