Как преобразовать ответ от запроса API в экземпляр класса с помощью `class-transformer` в TypeScript? - PullRequest
0 голосов
/ 24 февраля 2020

У меня есть нормальный метод Request(method: HttpMethod, url: string, ...) для вызова API. Я использую TypeScript.

Мне нужно преобразовать ответ от этого запроса API в экземпляр класса с class-transformer (или без него: D).

Пример:

class UserResponse {
  id: number;l
  foo: string;
  bar: string;
}
const user = await Request(HttpMEthod.GET, '/user/1');
// `user` should be class instance `UserResponse`

Я знаю, что не могу использовать дженерики примерно так:

const Request = <T>(method: HttpMethod, url: string, ...) => {
  // axios or something else...
  return plainToClass(T, res);
}

const user = await Request<UserResponse>(HttpMEthod.GET, '/user/1');

Обобщения не работают таким образом, но я могу сделать что-то вроде:

const Request = <T>(method: HttpMethod, url: string, ...,  transformTo?: { new (): T }) => {
  // axios or something else...
  return plainToClass(transformTo, res);
}

const user = await Request(HttpMEthod.GET, '/user/1', ... , new UserResponse());

Но это также не работает. Я все еще получаю user тип:

const user: unknown

Что я делаю не так?

1 Ответ

1 голос
/ 24 февраля 2020

Прежде всего, что такое Request? Я предполагаю, что это возвращает Promise.

У вас есть пара проблем:

  1. На самом деле вы никогда не отображаете свой ответ в new UserResponse
  2. Generics в TypeScript не будет новый до ответ. Он действует больше как interface, где это скорее контракт на данные, чем полностью инициализированный класс.

Вот как вам нужно это сделать:

class UserResponse {
  public id: number;
  public foo: string;
  public bar: string;
  constructor(user: UserResponse) {
    Object.assign(this, user); // or set each prop individually
  }
}
const response = await Request(HttpMEthod.GET, '/user/1');
const user = new UserResponse(response);

По сути, вам нужно добавить constructor к вашему классу (в противном случае, просто используйте interface). Получив constructor, вы можете новый новый UserResponse класс из ответа.

Кроме того, если Request выглядит следующим образом:

const Request = <T>(method: HttpMethod, url: string, ...,  transformTo?: { new (): T }) => {
  // axios or something else...
  return plainToClass(transformTo, res);
}

Я думаю, что вы хотите сделать это вместо: const user = await Request(HttpMEthod.GET, '/user/1', ... , UserResponse);

...