请原谅天真的问题;我是Typescript的新手。在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 party软件包存在各种类型问题,而且在许多情况下,我不知道如何为我的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
);
更广泛地说,如何调试这样的错误?
为了调试这种事情,我使用我的IDE(VS代码)来检查方法,例如.mesh
方法,并查看其期望的类型。我还使用了[[转到定义功能(⌘+在Mac上单击)来查看类型定义:
尽管有一部分我无法弄清楚。当您在TypeScript中导入JSON时,它会自动推断类型,但是出于多种原因(例如@types/topojson
),这些自动类型似乎与number[] !== [number, number]
类型冲突。这就是为什么我需要在强制转换为正确类型之前先强制转换为unknown
。这可能不是最佳解决方案,但是我不知道一种描述JSON文件类型的方法。
有人可以帮我调试吗?
错误基本上说:
C0]中传入的type
对象文字的[属性us
具有类型"./counties-albers-10m.json"
,但从string
中键入
期望则为@types/topojson
string literal type,即比加宽"Topology"
更具体。例如,您不能执行以下操作:
string
[检查类型为const wideString: string = "something" const stringLiteral: "Topology" = wideString // error, string not assignable to type "Topology"
的mesh
及其第一个函数参数mesh
的类型时,的确与上述类型完全相同。那为什么呢?让我们看一个简单的JSON文件:
topology
[使用Topology
导入此文件时,实际上Topology
类型是:
{ "a": "foo", "b": 42 }
从JSON文件推断出的属性文字类型:TypeScript widens
import us from "./counties-albers-10m.json"
分别变为us
和type US = typeof us; // type US = { a: string; b: number; }
变为"foo"
。此行为是string
,但是也有一个功能请求,要求42
与number
一起提供给您精确的窄类型。解决方案as const
或自定义类型。as
如何调试这样的错误?错误消息非常有用,我想您只是不了解字符串文字类型和/或JSON扩展。通常,您还可以使用VS Code这样的IDE来查看第三种库类型,以了解预期的形状。