Предположим, у меня есть иерархия классов, реализованная в c# с Protobuf.net
. (Также был бы класс Rectangle
, который реализует Shape
, но для краткости я его опустил.)
[ProtoContract]
[ProtoInclude(1, typeof(Circle))]
public class Shape {
}
[ProtoContract]
public class Circle : Shape {
[ProtoMember(1)]
public int Radius {get;set;}
}
Я хочу представить эту же иерархию классов в TypeScript, используя protobuf.js
. Однако я не могу понять, как сопоставить поле oneof с подклассом.
Это лучшее, что я смог придумать:
// It's not possible to make this inherit from 'Shape'
class Circle extends Message<Circle> {
@Field.d(1, "int32")
radius: number;
}
class Shape extends Message<Shape> implements IShape {
@Field.d(1, Circle)
circle: Circle;
@OneOf.d("circle") // ,"rectangle"
which: string;
// Implements the property on ICircle
get radius(): number {
return this.circle.radius;
}
}
interface IShape {
}
interface ICircle extends IShape {
radius: number;
}
function isCircle(shape: IShape): shape is ICircle {
return (shape as any).which === "circle";
}
const shape = new Shape({
circle: new Circle({ radius: 5 }),
which: "circle"
});
const buffer = Shape.encode(shape).finish();
const decoded = Shape.decode(buffer);
if (isCircle(decoded)) {
const itsACircle: ICircle = decoded;
// Do something
}
Мне это кажется счастливым, потому что:
- Мы должны выставить все возможные поля подкласса как свойства базового
Shape
класса (в данном случае radius
свойство Circle
). - Ни один из классов на самом деле не реализует
ICircle
, поэтому, если мы не сможем должным образом раскрыть некоторые свойства, компилятор не предупредит нас. - Защита типов использует приведение к
any
.
Кто-нибудь может предложить лучший способ достижения этого?