Библиотека react-svg-worlmap, ошибка в типах данных

от автора

Введение

В одном переданном проекте на NextJs и typescript, попалась “интересная” ошибка при использовании библиотеки react-svg-worldmap. Для решения ошибки, пришлось обращаться к разработчику библиотеки.

О библиотеке react-svg-worldmap

Данная библиотека — github, используется для отображения карты мира, и как я понял в основном используется для вывода статистики. У нее 1049 скачиваний в неделю NPM

При наведении на страну, выводится подсказка с названием страны и суммой ВВП.
При наведении на страну, выводится подсказка с названием страны и суммой ВВП.

В основном пропсе data данной библиотеки ожидается массив — страна и число, для подсветки страны и вывода данных при наведении

// Тип данных принимаемых в пропс data type DataItem = {   country: ISOCode;   value: number; }; // Передаваемые данные в пропс data const data = [     {country: 'cn', value: 1389618778}, // china     {country: 'in', value: 1311559204}, // india     {country: 'us', value: 331883986}, // united states     {country: 'id', value: 264935824}, // indonesia     {country: 'pk', value: 210797836}, // pakistan     {country: 'br', value: 210301591}, // brazil     {country: 'ng', value: 208679114}, // nigeria     {country: 'bd', value: 161062905}, // bangladesh     {country: 'ru', value: 141944641}, // russia     {country: 'mx', value: 127318112}, // mexico   ]; 

Проект не билдится локально, но работает на сервере

В моем случае, в проекте требовалось выводить: Название страны, и текст. Предыдущий разработчик решил данное требование довольно оригинально просто, напрямую передав в пропс data — в массиве: название страны и текст. И на сервере, при наведении — успешно выводил Название страны и текст.

const data = [     {country: 'cn', value: 'Густонаселенная страна'}, // china     {country: 'in', value: 'Слоны' }, // india     {country: 'us', value: 'Кремниевая долина'}, // united states   ]; 

Но у меня после скачивания из репозитория, и развертывания проект не билдился, выдавая ошибку, что в пропс data — переданы некорректные данные. Что логично — так как в массиве должно быть — страна (тип string) и число (тип number)

npm run build Failed to compile. ./src/components/templates/map/component.tsx:51:29 Type error: Type '{ country: string; value: string; }[]' is not assignable to type 'IData[]'. Type '{ country: string; value: string; }' is not assignable to type 'IData'. Types of property 'value' are incompatible. Type 'string' is not assignable to type 'number'.                            title=""                            size="xl"                            data={translation.data}                            ^                            valuePrefix=":"                            tooltipBgColor="white"                            tooltipTextColor="blue"  

В React/NextJs новичок. И хотя понимаю ошибку — что переданный параметр использует неверный тип, не понимал, как ранее проект билдился и работал на сервере.

Прочитал документацию библиотеки, ясно вижу, что ожидаются данные в формате — страна, число. В проекте передаются некорректные данные, но тогда почему проект успешно билдился?

После поисков, я был удивлен понял — предыдущий разработчик, после установки, менял в коде библиотеки, в папке node_modules/react-svg-worldmap/dist — принимаемый тип для второго параметра — с number на string. После чего билд проходил без ошибок.

// node_modules\\react-svg-worldmap\\dist\\WorldMap.d.ts interface IData {     country: string;     value: string; // number; } 

Полагаю, что разработчик до меня, сперва пытался сделать правильно. Но пошел по легкому пути, библиотека проста и в примерах использовалась для вывода статистики. Поэтому применил подобный угадайкак способ.

Теперь понимая почему проект не билдился, получил ситуацию:

  • что менять код в скомпилированной библиотеки в папке dist — не вариант (wrong way).

  • Использовать другую библиотеку — нежелательно.

  • Решать задачу по выводу названию страны и текста при наведении — надо.

Подумал, что точно кто-то еще сталкивался с подобной проблемой при использовании данной библиотеки, и наверняка другие разработчики справились. И тогда обратился к Вселенскому разуму написал issue запрос к разработчику библиотеки, с предложением добавить дополнительное поле, для возможности добавлять текст или просьбой подсказать способ вывода текста в подсказке при наведении.

К своему удивлению, довольно быстро (через пару часов) получил ответ, что уже существует параметр tooltipTextFunction, указали прямую ссылку на документацию с примером  https://yanivam.github.io/react-svg-worldmap/examples/localization . За что им очень благодарен. Сам я на эту документацию не наткнулся, т.к читал только код в репозитарии (к стыду, я затем нашел что и там все же был указан этот пропс, но я проглядел).

Решение, которое я использовал

В моем случае данные с нужным текстом подтягивались из json файла, на разных языках, поэтому их требовалось предварительно заносить в массив в нужном формате.

// файл с переводом src\\locales\\ru.ts const data = [     {country: 'cn', value: 1389618778}, // china     {country: 'in', value: 1311559204}, // india     {country: 'us', value: 331883986}, // united states ]; const dataTranslation= [ {country: 'cn', value: 'Густонаселенная страна'}, // china {country: 'in', value: 'Слоны' }, // india {country: 'us', value: 'Кремниевая долина'}, // united states ]; // файл ./src/components/templates/map/component.tsx // заносим текст с переводом в массив let localizedArray = [] for (var val of translation.dataTranslation) { localizedArray.push([val.country, val.value]) } const localizedCountryDictionary: Map<string, Array<string>> = new Map(localizedArray); // возвращаем результат локализации // localization callback const getLocalizedText = (countryCode, countryValue, prefix, suffix) => { const localizedCountryName = localizedCountryDictionary.has(     countryValue.toLowerCase(), ) ? localizedCountryDictionary.get(countryValue.toLowerCase()) : 'Unknown';    const russianTranlation = countryCode + ': ' + localizedCountryName  return russianTranlation;  }; // код компонента с параметром <Component title="" size="xl" data={translation.data} valuePrefix=":" tooltipBgColor="white" tooltipTextColor="blue" tooltipTextFunction={getLocalizedText} /> 

Суть решения, в том что в передаваемом props data — передаются корректные данные в формате — Страна, число. Затем в зависимости от страны, по коду страны выводится подсказка.

А подсказка выводится, через пропс tooltipTextFunction и getLocalizedText которая предварительно берет данные из файла требуемой локали и выводит в формате string.

Само решение было на виду — причем указано в документации, но я не видел, так как рассматривал в контексте — передаю в props data — страну и текст, хочу получить подсказку с текстом. Вместо, задача выводить в подсказке при наведении на страну требуемый текст.

Выводы:

  • Если используется костыль — указывать в комментарии, чтобы не тратить время на поиск ошибки. Навряд ли легко догадаться, что то кто-то меняет код в папке dist библиотеки после установки.

  • Рассматривать в контексте — какая задача стоит, и как решить задачу. А не “как вылечить эту ошибку”.

  • На том конце гитхаба — разработчики библиотек, участники проекта это живые люди. Они существуют, и могут подсказать. В этом сила комьюнити.

  • Рассматривать ошибку — в контексте, как решить задачу, а не избавиться от ошибки.

Спасибо за то, что дочитали. Надеюсь пригодится и натолкнет на мысли.


ссылка на оригинал статьи https://habr.com/ru/post/649733/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *