如何解决 topojson 包的打字稿错误?

How to resolve typescript error for topojson package?

问题幼稚请见谅;我是打字稿的新手。在 javascript 中,我可以使用 topojson.mesh 来创建这样的网格对象:

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

当我尝试在 Typescript 中执行此操作时,我收到此警告:

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

我也安装了 @types/topojson。谁能帮我调试这个?我对打字稿的了解不够,无法理解问题所在。

更广泛地说,如何调试这样的错误?我发现 3rd 方包存在各种类型问题,并且在很多情况下不知道如何为我的 javascript 对象分配正确的类型。感谢您的帮助。

安装 @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
);

More broadly, how does one debug errors like this?

为了调试这种东西,我使用我的 IDE (VS Code) 检查方法,比如 .mesh 方法并查看它期望的类型。我还使用了 Go To Definition 功能(⌘ + 单击 Mac)来查看类型定义:

转到类型定义文件还向我展示了他们从何处导入类型。

虽然有一部分我想不通。当您在 TypeScript 中导入 JSON 时,它会自动推断类型,但由于多种原因(例如 number[] !== [number, number]),这些自动类型似乎与 @types/topojson 冲突。这就是为什么我需要先转换为 unknown,然后再转换为正确的类型。这可能不是最佳解决方案,但我不知道如何描述 JSON 文件的类型。

Can anyone help me debug this?

错误基本上是这样说的:

属性 type 您从 "./counties-albers-10m.json" 传入的 us 对象字面量具有类型 string,但从 @types/topojson 键入 预计它是string literal type"Topology",它比加宽的string更具体。例如你不能这样做:

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

检查 mesh and its first function argument topology with type 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"分别变为 string42 变为 number。此行为是 intentional, but there is also a feature request asking for more flexbilityas 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

how does one debug errors like this?

错误消息提供了很多信息,我认为您只是没有意识到字符串文字类型 and/or JSON 扩大。通常,您还可以使用像 VS Code 这样的 IDE 查看第三种库类型,以查看预期的形状。