Как устранить ошибку машинописи для пакета topo json? - PullRequest
1 голос
/ 24 февраля 2020

Прошу простить наивный вопрос; Я новичок в Typescript. В javascript я могу использовать topo json .me sh для создания объекта me sh следующим образом:

import us from "./counties-albers-10m.json"
topojson.mesh(us, us.objects.states, (a, b) => a !== b))

Когда я пытаюсь сделать это в Машинопись, я получаю это предупреждение:

Types of property 'type' are incompatible. Type 'string' is not assignable to type "Topology" TS2345

У меня также установлено @types/topojson. Может кто-нибудь помочь мне отладить это? Я недостаточно разбираюсь в машинописи, чтобы понять, в чем проблема.

В более широком смысле, как можно отлаживать подобные ошибки? Я нахожу всевозможные проблемы с типами сторонних пакетов и во многих случаях не знаю, как назначить моим javascript объектам правильный тип. Спасибо за помощь.

Ответы [ 2 ]

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

Может кто-нибудь помочь мне отладить это?

Ошибка в основном говорит:

Свойство type вашего переданного в us объекта литерал от "./counties-albers-10m.json" имеет тип string, но от @types/topojson ожидается, что будет строковым литералом типа "Topology", который более специфичен c, чем расширенный string , Например, вы не можете сделать это:

const wideString: string = "something"
const stringLiteral: "Topology" = wideString // error, string not assignable to type "Topology"

При проверке набора для mesh и его первого аргумента функции topology с типом Topology, вы действительно могу видеть, что типы в точности соответствуют определенным выше.

Так почему же это так? Давайте возьмем простой JSON файл:

{ "a": "foo", "b": 42 }

При импорте этого файла с import us from "./counties-albers-10m.json" тип us на самом деле:

type US = typeof us; // type US = { a: string; b: number; }

TypeScript расширяет типы литералов свойств, выведенные из файла JSON : "foo" становится string и 42 становится number соответственно. Это поведение преднамеренное , но есть также запрос функции, запрашивающий большую гибкость с as const, чтобы дать вам узкий, точный тип.

Решение

Используйте утверждение типа (as), чтобы преобразовать импортированный объект us в Topology или в пользовательский тип.

import { Topology } from "topojson-specification" // needed type for mesh API
// alternatively use a custom compatible json type

import us_ from "./counties-albers-10m.json"

const us: Topology = us_ as Topology; 

topojson.mesh(us, ...) // this should work now

как отлаживать ошибки, подобные этой ?

Сообщение об ошибке было довольно информативным, я думаю, вы просто не знали о строковых литеральных типах и / или расширении JSON. В общем, вы также можете заглянуть в третьи типы библиотек с помощью IDE, такой как VS Code, чтобы увидеть, какая форма ожидается.

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

Как только я установил @types/topojson, я мог импортировать требуемые типы из topojson-specification, например:

import * as topojson from 'topojson-client';
import { GeometryObject, Topology } from 'topojson-specification';
import us from '../counties-albers-10m.json';

topojson.mesh(
  (us as unknown) as Topology,
  us.objects.states as GeometryObject,
  (a: GeometryObject, b: GeometryObject) => a !== b
);

В более широком смысле, как можно отлаживать подобные ошибки?

Для отладки такого рода вещей я использую свою среду IDE (VS Code) для проверки методов, таких как метод .mesh, и вижу ожидаемые типы. Я также использовал функциональность Go To Definition (⌘ + нажмите на Ma c) для просмотра определений типов: enter image description here

Переход к Файл определения типа также показал мне, откуда они импортировали типы.

Была часть об этом, которую я не мог понять, хотя. Когда вы импортируете JSON в TypeScript, он автоматически определяет типы, но эти автоматические c типы, по-видимому, конфликтуют с @types/topojson по ряду причин (например, number[] !== [number, number]). Вот почему мне нужно было привести к unknown, прежде чем привести к правильному типу. Возможно, это не оптимальное решение, но я не знаю, как описать типировку для файла JSON.

...