
本文介绍如何在 TypeScript 中定义一个泛型条件接口 IGeometry,使其 shape 属性的类型严格依赖于同接口中 geometryType 的具体枚举值,实现类型安全的几何对象建模。
本文介绍如何在 typescript 中定义一个泛型条件接口 `igeometry
在构建地理信息系统(GIS)、图形渲染或空间数据处理类库时,我们常需对多种几何类型(如圆形、多边形、点、椭圆)进行统一建模,同时保证每个实例的结构与类型声明完全匹配——即:当 geometryType 为 CIRCLE 时,shape 必须是 ICircle,且不能被误赋为 IPolygon 等其他类型。TypeScript 原生不支持“运行时值驱动编译时类型”,但可通过泛型约束 + 分布式条件类型优雅实现该需求。
核心思路是将 geometryType 的具体值作为泛型参数 T 传入接口,再利用条件类型(T extends X ? Y : Z)逐级推导 shape 的精确类型:
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 值导致 shape 为 never,强制编译报错
}</t>
使用时,显式指定泛型参数即可获得强类型保障:
完整的Galileo AI平台 TypeScript/JS SDK 参考,用于评估、观察和保护 GenAI 应用。适用于构建 Node.js 或 TypeScript 项目。
// ✅ 正确: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 }
};
// ❌ 编译错误:类型不兼容(若取消注释将触发 TS2322)
// const invalid: IGeometry<geometrytype.circle> = {
// geometryType: GeometryType.CIRCLE,
// shape: { lat: 0, lon: 0 } // Error: Type 'IPoint' is not assignable to type 'ICircle'
// };</geometrytype.circle></geometrytype.polygon></geometrytype.circle>
⚠️ 注意事项:
- 泛型必须显式标注(如 IGeometry
),TypeScript 通常无法从对象字面量自动推导出 T(尤其在初始化阶段),否则 shape 将退化为联合类型 ICircle | IPolygon | ...,失去条件约束; - 若需运行时类型校验(如反序列化 JSON),应额外编写类型守卫函数(如 isCircleGeometry(geo: IGeometry
): geo is IGeometry ); - 枚举值建议使用字符串字面量(如 CIRCLE = "circle")提升可读性与调试体验,但当前数字枚举同样完全适用;
- never 作为最终分支是关键防御机制:当传入未覆盖的 GeometryType 值(如未来新增但未更新条件逻辑)时,shape: never 会使整个赋值失败,避免静默类型漏洞。
通过该模式,你不仅实现了“一值定型”的接口契约,更将类型系统转化为领域建模的主动约束工具——让错误在编码阶段暴露,而非运行时崩溃。










