You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:如何实现Feature内部Geometry类型的通用Typeguard

通用GeoJSON Feature类型守卫实现

现有类型定义

工作中使用的GeoJSON相关TypeScript类型如下:

export type GeoJSON = Geometry | Feature;

export type GeoJsonTypes = GeoJSON['type'];

export interface GeoJsonObject { type: GeoJsonTypes; }

export interface Point extends GeoJsonObject {
   type: 'Point';
   coordinates: number[];
 }

export interface MultiPoint extends GeoJsonObject {
   type: "MultiPoint",
   coordinates: number[][];
 }

export type Geometry =
 | Point
 | MultiPoint

export interface Feature<G extends Geometry = Geometry>
  extends GeoJsonObject {
  type: 'Feature';
  geometry: G;
}

问题场景

当前收窄Feature<Geometry>类型时,必须为每种Geometry对应的Feature编写单独的类型守卫,例如:

export function isPolygon(f: Feature): f is Feature<Polygon> {
  return f && f.geometry && f.geometry.type === 'Polygon';
}

尝试编写通用类型守卫时遇到类型错误:将泛型T约束为Feature会触发A type Predicate's type must be assignable to it's parameter type;约束为Geometry则会出现T could be instantiated with an arbitrary type which could be unrelated错误。

解决方案

调整泛型约束逻辑,直接针对Geometry的类型值做限定,即可实现合法的通用类型守卫:

export function isFeature<U extends Geometry['type']>(
  feature: Feature<Geometry>,
  type: U
): feature is Feature<Extract<Geometry, { type: U }>> {
  return !!feature && !!feature.geometry && feature.geometry.type === type;
}

关键说明

  • 泛型U直接绑定到Geometry['type'],确保传入的type参数只能是合法的Geometry类型标识(如'Point'、'MultiPoint')
  • 参数feature直接使用最宽泛的Feature<Geometry>类型,规避泛型参数T带来的类型兼容性冲突
  • 通过Extract工具类型从Geometry联合类型中筛选出对应type的具体类型,再包装为对应的Feature类型,保证类型断言的合法性

使用示例

const feature: Feature<Geometry> = {/* 任意Feature数据 */};

if (isFeature(feature, 'Point')) {
  // 此处feature类型自动收窄为Feature<Point>
  console.log(feature.geometry.coordinates); // 类型为number[]
}

if (isFeature(feature, 'MultiPoint')) {
  // 此处feature类型自动收窄为Feature<MultiPoint>
  console.log(feature.geometry.coordinates); // 类型为number[][]
}

内容的提问来源于stack exchange,提问作者Martin Hansson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 07:13:32