
本文介绍如何在 TypeScript 中定义泛型条件接口,使 shape 属性的类型严格依赖于同一接口中 geometryType 枚举值,实现编译时精准类型约束与智能提示。
本文介绍如何在 typescript 中定义泛型条件接口,使 `shape` 属性的类型严格依赖于同一接口中 `geometrytype` 枚举值,实现编译时精准类型约束与智能提示。
在地理信息系统(GIS)或图形建模等场景中,常需根据几何类型(如圆形、多边形、点、椭圆)动态切换数据结构。若将所有子类型简单联合(ICircle | IPolygon | ...),会丧失类型安全性——例如为 geometryType: GeometryType.CIRCLE 赋予 IPolygon 形状时,TypeScript 无法报错。真正的解法是使用泛型 + 分布式条件类型,构建“类型即契约”的条件接口。
以下是完整实现:
完整的Galileo AI平台 TypeScript/JS SDK 参考,用于评估、观察和保护 GenAI 应用。适用于构建 Node.js 或 TypeScript 项目。
export enum GeometryType {
CIRCLE = 4,
POLYGON = 5,
POINT = 6,
ELLIPSE = 7
}
export interface ICircle {
center: number;
radius: number;
}
export interface IPolygon {
lat: number;
lon: number;
}
export interface IPoint {
lat: number;
lon: number;
}
export interface IEllipse {
yAxis: number;
xAxis: number;
angle: number;
}
// ✅ 条件接口:shape 类型随 geometryType 枚举值精确推导
export interface IGeometry<t extends geometrytype> {
geometryType: T;
shape: T extends GeometryType.CIRCLE
? ICircle
: T extends GeometryType.POLYGON
? IPolygon
: T extends GeometryType.POINT
? IPoint
: T extends GeometryType.ELLIPSE
? IEllipse
: never; // 确保枚举全覆盖,避免意外类型
}</t>
✅ 正确用法示例(类型安全)
// 编译通过:geometryType 与 shape 完全匹配
const circle: IGeometry<geometrytype.circle> = {
geometryType: GeometryType.CIRCLE,
shape: { center: 0, radius: 5 }
};
const polygon: IGeometry<geometrytype.polygon> = {
geometryType: GeometryType.POLYGON,
shape: { lat: 10.0000, lon: -10.0000 }
};
// ❌ 编译报错:类型不匹配(TypeScript 精准提示)
const invalid: IGeometry<geometrytype.circle> = {
geometryType: GeometryType.CIRCLE,
shape: { lat: 1, lon: 2 } // ❌ Property 'lat' does not exist on type 'ICircle'
};</geometrytype.circle></geometrytype.polygon></geometrytype.circle>
⚠️ 注意事项
-
必须显式指定泛型参数:IGeometry
,不可省略;TypeScript 不支持从对象字面量自动推导泛型约束(除非配合函数重载或 as const 辅助)。 - never 是防御性设计:末尾的 : never 确保新增枚举值后未更新条件分支时,编译器立即报错,提升可维护性。
-
类型收窄生效:在运行时可通过 switch (geo.geometryType) 进行类型守卫,配合 as 或类型断言进一步细化 shape 的具体类型(推荐结合 function isCircle(geo: IGeometry
): geo is IGeometry 自定义类型谓词)。
该模式本质是 TypeScript 高级类型系统的核心能力之一——利用泛型约束与条件类型(T extends U ? X : Y)实现“值驱动类型”,既保持代码简洁性,又杜绝运行时类型错误,是构建强类型领域模型的关键实践。










