TypeScript泛型:任何接口实现程序



我在TypeScript中遇到泛型问题。

我有一个名为Obstacle:的接口

import Shape from "./Shape";
interface Obstacle<S extends Shape> {
readonly type: string;
readonly shape: S;
}
export default Obstacle;

Obstacle是另一个接口Shape:的包装器

interface Shape {
readonly name: string;
}
export default Shape;

我可以使用这两个接口来创建一个实现Shape的类,例如RectancleCircle

然后,我创建另一个类,例如分别实现Obstacle<Rectangle>Obstacle<Circle>RectangleObstacleCircleObstacle

但是,我的问题是,当我在一系列障碍物中使用它们时(它应该容纳任何类型的障碍物(,比如:

import Obstacle from "./Obstacle";
interface Data {
obstacles: Obstacle<any>[]; /* What should I put here? In the generic parameters list? */
}
const DATA: Data = {
obstacles: []
};

我试过放Obstacle<Shape>[]Obstacle<any extends Shape>[],但都不起作用。此外,我应该能够区分不同类型的障碍物,比如:

function somefunc(): void {
for(let i: number = 0; i < DATA.obstacles.length; i++) {
const o: Obstacle = DATA.obstacles[i]; /* what to write here? */
switch(o.type) {
case "rectangle":
/* For example, writting this: */
o.shape.width;
/* results in: property width does not exist on type Shape */
break;
case "circle":
/* ... */
break;
}
}
}

您需要使用有区别的联合

type AppObstacle = RectangleObstacle | CircleObstacle
interface Data {
obstacles: AppObstacle[]; 
}

游乐场链接

此外,为了应用AlekseyL的建议。,如果障碍物只是一个形状的容器,而没有与之相关的附加数据或逻辑,您可以将形状更改为可区分的并集,如下所示:

interface Shape {
readonly type: string;
readonly name: string;
}
interface Rectangle extends Shape {
type: 'rectangle';
width: number;
}
interface Circle extends Shape {
type: 'circle';
radius: number
}
type AppShape = Rectangle | Circle;
interface Data {
obstacles: Obstacle[]; 
}
const DATA: Data = {
obstacles: []
};
function somefunc(): void {
for(let i: number = 0; i < DATA.obstacles.length; i++) {
const o = DATA.obstacles[i]; 
const shape = o.shape;
switch(shape.type) {
case 'rectangle':
shape.width;
break;
case 'circle':
shape.radius;
break;
}
}
}

游乐场链接

最新更新