我在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
的类,例如Rectancle
或Circle
。
然后,我创建另一个类,例如分别实现Obstacle<Rectangle>
或Obstacle<Circle>
的RectangleObstacle
或CircleObstacle
。
但是,我的问题是,当我在一系列障碍物中使用它们时(它应该容纳任何类型的障碍物(,比如:
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;
}
}
}
游乐场链接