请原谅天真的问题;我是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
。谁能帮我调试一下吗?我对打字稿不够了解,无法理解问题所在。
更广泛地说,如何调试这样的错误?我发现第三方软件包存在各种类型问题,而且在很多情况下,我不知道如何为我的javascript对象分配正确的类型。感谢您的帮助。
答案 0 :(得分:3)
一旦我安装了@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文件类型的方法。
答案 1 :(得分:2)
有人可以帮我调试吗?
错误基本上表明:
从type
传入的us
对象文字的属性"./counties-albers-10m.json"
的类型为string
,但从@types/topojson
键入的 expect 它应为string literal type "Topology"
,比扩展的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
变成{{1 }} 分别。这种行为是intentional,但是也有一个功能请求,要求more flexbility与number
一起提供给您狭窄,准确的类型。
使用类型断言(as const
)将导入的as
对象转换为us
或自定义类型。
Topology
如何调试这样的错误?
该错误消息非常有用,我想您只是不了解字符串文字类型和/或JSON扩展。通常,您还可以使用VS Code之类的IDE来查看第三种库类型,以了解预期的形状。