Ошибка TypeScript [TS2741] с mapKeys (верблюд) из lodash - PullRequest
1 голос
/ 09 февраля 2020

Я пытаюсь напечатать свой объект, но машинопись кажется недовольной по этому поводу:

import { camelCase, mapKeys } from 'lodash/fp';

interface QueryResponse {
  accept_card_payments: boolean;
}

interface FinalResponse {
  acceptCardPayments: boolean;
}

const getResponse = () => {
  const toCamelCase = mapKeys(camelCase);
  const queryResponse: QueryResponse = { accept_card_payments: false };
  const response: FinalResponse = toCamelCase(queryResponse); // error TS2741

  return response;

}; 

Я получил ошибку в const response, сказав:

Property 'acceptCardPayments' is missing in type '
Dictionary<boolean>' but required in type 'FinalResponse'.

Как теперь разрешить TypeScript что мой тип соответствует возвращаемому значению mapKeys(camelCase);?

Я сделал воспроизводимый пример здесь: https://repl.it/repls/MediumblueRudeBinarysearchtree

1 Ответ

2 голосов
/ 09 февраля 2020

Типы Fp не идеальны, а также TS не поддерживает типы строковых шаблонов, так как в отношении преобразования вы преобразуете объект в словарь, и это все.

Метод 1

Быстрым и грязным способом было бы признать, что с использованием unknown:

function getFinalResponse(query: QueryResponse): FinalResponse {
  return <FinalResponse>(<unknown>mapKeys(camelCase)(query));
}

const getResponse = (): FinalResponse => {
  return getFinalResponse({ accept_card_payments: false });
};

Метод 2

Более изощренный способ будет реализовать функцию Type Guard, утверждающую, что типом является FinalResponse, но выполнение этого приведет вас к повторению некоторых преобразований еще раз, чтобы проверить, собирается ли функция case kebab дать вам ключ QueryResponse.

function assertFinalResponse(
  obj: any,
  query: QueryResponse
): asserts obj is FinalResponse {
  const finalResponseKey = Object.keys(obj)[0];
  if (!Reflect.has(query, kebabCase(finalResponseKey))) {
    throw new Error("Not the right object!");
  }
}

const getResponse2 = (): FinalResponse => {
  const query = { accept_card_payments: false };
  const potentiallyFinal = mapKeys(camelCase)(query);
  assertFinalResponse(potentiallyFinal, query);
  return potentiallyFinal;
};
...