如何创建基于自身属性值的条件型IGeometry接口?
实现geometryType与shape类型绑定的IGeometry接口
当然可以实现,你当前的IGeometry接口中shape是所有形状接口的联合类型,无法保证geometryType和shape的类型匹配(比如可能出现geometryType: GeometryType.CIRCLE但shape用IPolygon的情况)。要实现两者的强绑定,最直接的方式是用联合类型定义接口的不同分支,每个分支对应一种geometryType和其匹配的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; }; // 定义条件型联合接口,实现geometryType与shape的强绑定 export type IGeometry = | { geometryType: GeometryType.CIRCLE; shape: ICircle } | { geometryType: GeometryType.POLYGON; shape: IPolygon } | { geometryType: GeometryType.POINT; shape: IPoint } | { geometryType: GeometryType.ELLIPSE; shape: IEllipse };
类型窄化效果
使用这种定义后,TypeScript会自动进行类型推断,当你判断geometryType的具体值时,shape会自动被窄化为对应的接口类型:
function processGeometry(geo: IGeometry) { switch (geo.geometryType) { case GeometryType.CIRCLE: // 此处geo.shape被推断为ICircle,可直接访问center、radius console.log(geo.shape.center); break; case GeometryType.POLYGON: // 此处geo.shape被推断为IPolygon console.log(geo.shape.lat); break; // 其他分支同理,类型完全匹配 } }
可维护性优化(映射类型方式)
如果后续需要新增更多几何类型,手动维护联合分支会比较繁琐,这时可以用映射类型先建立GeometryType到形状接口的映射关系,再自动生成联合类型:
// 建立类型映射关系 type GeometryShapeMap = { [GeometryType.CIRCLE]: ICircle; [GeometryType.POLYGON]: IPolygon; [GeometryType.POINT]: IPoint; [GeometryType.ELLIPSE]: IEllipse; }; // 自动生成联合类型的IGeometry export type IGeometry = { [K in keyof GeometryShapeMap]: { geometryType: K; shape: GeometryShapeMap[K]; }; }[keyof GeometryShapeMap];
这种方式下,新增几何类型时只需修改GeometryShapeMap,无需改动IGeometry的定义,扩展性更强。
内容的提问来源于stack exchange,提问作者karlcess
相关产品推荐
相关产品推荐

