Angular 财产';特点';不存在于类型';功能<;点,{[name:string]:any;}>';

Angular 财产';特点';不存在于类型';功能<;点,{[name:string]:any;}>';,angular,d3.js,geojson,topojson,Angular,D3.js,Geojson,Topojson,我是Angular的新手,我正在尝试用Angular/d3绘制一幅德国地图。地图数据存储在Topojson文件plz_map_ger.json中: { "type": "Topology", "arcs": [...], "transform": {...}, "objects": { "plz5stellig": {...} } } 这是我绘制地图的代码: import * as d3 from "d3"; import * as t from 'topojson'

我是Angular的新手,我正在尝试用Angular/d3绘制一幅德国地图。地图数据存储在Topojson文件plz_map_ger.json中:

{
"type": "Topology",
"arcs": [...],
"transform": {...},
"objects": {
      "plz5stellig": {...}
      }
 }
这是我绘制地图的代码:

import * as d3 from "d3";
import * as t from 'topojson';

但是,我得到以下编译错误:

error TS2339: Property 'features' does not exist on type 'Feature<Point, { [name: string]: any; }>'.
错误TS2339:类型“Feature”上不存在属性“features”。
我需要做什么来解决这个问题

编辑: 当我将鼠标悬停在VS代码中的错误上时,会收到以下消息:

Property 'features' does not exist on type 'Feature<Point, { [name: string]: any; }>'.ts(2339)
属性“features”在类型“Feature”上不存在。ts(2339)
我使用使用mapshaper.org创建的以下Topojson文件(该文件稍微简化,但结构保持不变):

根据函数
feature()
返回
feature
FeatureCollection
。只有
FeatureCollection
将具有您要查找的
.features
属性

检查(第4-8行)我们可以看到,如果
拓扑
GeometryCollection
作为其
类型

export default function(topology, o) {
  return o.type === "GeometryCollection"
  ? {type: "FeatureCollection", features: o.geometries.map(function(o) { return feature(topology, o); })}
      : feature(topology, o);
}
您正在异步加载
拓扑
,因此编译器不可能知道其
.type
是否为
GeometryCollection

为了解决这个问题,您需要安装GeoJSON类型(
npm i@types/GeoJSON

然后,您可以设置临时变量的类型

    ...
    d3.json("../../assets/plz_map_ger.json")
      .then(function(top:any) {

          // This row sets the temporary variable
          let mapFeatures: FeatureCollection = t.feature(top, top.objects.plz5stellig)

           g.selectAll('path')

          // We use the temporary variable here
          .data(mapFeatures.features)
          .enter()
          .append('path')
          .attr('d', path)
          .attr("class","kreisgrenzen")
          .on("click", function() {
            d3.select(this).attr("class","selected-kreis");
          });
      });
或者您可以显式地将集合强制转换为功能集合(感谢@altocumulus)


feature(a,b)
函数可以返回
GeoJSON.feature
GeoJSON.FeatureCollection
这两个函数中的哪一个不是在编译时决定的,而是在运行时决定的,因为它取决于异步加载拓扑的
type
属性。所以将
mapFeatures
的类型设置为
GeoJSON.FeatureCollection
;对的我可能需要更新解决方案。感谢您的讨论和帮助!我已经上传并链接了我在问题中使用的Topojson文件。
    ...
    d3.json("../../assets/plz_map_ger.json")
      .then(function(top:any) {

          // This row sets the temporary variable
          let mapFeatures: FeatureCollection = t.feature(top, top.objects.plz5stellig)

           g.selectAll('path')

          // We use the temporary variable here
          .data(mapFeatures.features)
          .enter()
          .append('path')
          .attr('d', path)
          .attr("class","kreisgrenzen")
          .on("click", function() {
            d3.select(this).attr("class","selected-kreis");
          });
      });
  ...
    d3.json("../../assets/plz_map_ger.json")
      .then(function(top:any) {
           g.selectAll('path')
          // explicit cast
          .data((t.feature(top, top.objects.plz5stellig) as GeometryCollection).features)
          .enter()
          .append('path')
          .attr('d', path)
          .attr("class","kreisgrenzen")
          .on("click", function() {
            d3.select(this).attr("class","selected-kreis");
          });
      });