本文介绍如何在 TypeScript 中定义泛型条件接口,使 shape 属性的类型严格依赖于同一接口中 geometryType 枚举值,实现编译时精准类型约束与智能提示。
本文介绍如何在 typescript 中定义泛型条件接口,使 `shape` 属性的类型严格依赖于同一接口中 `geometrytype` 枚举值,实现编译时精准类型约束与智能提示。
在地理信息系统(GIS)或图形建模等场景中,常需根据几何类型(如圆形、多边形、点、椭圆)动态切换数据结构。若将所有子类型简单联合(ICircle | IPolygon | ...),会丧失类型安全性——例如为 geometryType: GeometryType.CIRCLE 赋予 IPolygon 形状时,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; // 确保枚举全覆盖,避免意外类型}
// 编译通过: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'};
该模式本质是 TypeScript 高级类型系统的核心能力之一——利用泛型约束与条件类型(T extends U ? X : Y)实现“值驱动类型”,既保持代码简洁性,又杜绝运行时类型错误,是构建强类型领域模型的关键实践。