我开始在打字稿中对API客户端进行建模,并寻求有关如何正确建模数据的澄清。 API的数据模型都共享一组公共属性(一个抽象),然后每个对象都有更具体的类型。每个对象还将共享一个通用的元数据集($ meta),但每个对象的某些值将有所不同。例如:
type Shapes = "Parallelogram" | "Triangle"
type QuadShapes = "Square" | "Trapezoid" | "Rectangle" | "Rhombus" | "Parallelogram"
type ParallelogramShapes = "Square" | "Rectangle" | "Rhombus" | "Parallelogram"
type TriangleShapes = "Isosceles" | "Scalene" | "Equilateral"
interface Meta {
id: number
number_of_sides: number,
type: Shapes,
is_quadrilateral: Boolean,
is_parallelogram: Boolean,
}
interface IShape {
$meta: Meta
}
interface IQuadrilateral extends IShape {
$meta.number_of_sides: number
}
interface IParallelogram extends IQuadrilateral {
$meta.number_of_parallel_sides: number
$meta.type: ParallelogramShapes
}
interface ITriangle extends IShape {
$meta.is_parallelogram: Boolean
$meta.type: TriangleShapes
}
// ISquare should look like:
// {
// $meta: {
// id: 1,
// type: "Parallelogram",
// parallelogram_type: "Square"
// is_parallelogram: true,
// is_quadrilateral: true,
// number_of_sides: 4,
// number_of_parallel_sides: 2
// },
// name: "Some Square"
// color: "Blue"
// }
interface ISquare extends IParallelogram {
// How do i define the $meta node?
$meta:
name: string,
color: string
}
class Square implements ISquare {
$meta: ?
name: string,
color: string
constructor(meta: any, name: string, color: string) {
this.$meta: meta
this.name: name.
this.color: color
}
}
我不确定是否丢失了某些内容,但是我遇到的最大问题是如何将$meta
参数建模到接口中。如何以一致的,非冗余的方式设置$meta.type
和$meta.is_parallelogram
。
答案 0 :(得分:1)
我倾向于重构,以便您的Meta
类型形成它们自己的接口层次结构,并且将IShape
设为其支持的Meta
类型的generic。 / p>
首先,我将重写您的类型。请注意,为了保持一致性,我认为您希望Shapes
为TriangleShapes | QuadShapes
,因为子类型化要求Square
实现IShape
时,type
属性才能分配给{{ 1}}的{{1}}属性。但是IShape
无法分配给type
,因为它们是string literal类型,并且仅引用特定的字符串:
"Square"
现在我们谈论"Parallelogram" | "Triangle"
阶层。我认为,这涉及最少的冗余,因为您只需指定比其超类型的属性新的或更窄的属性即可:
type Shapes = TriangleShapes | QuadShapes
type QuadShapes = "Trapezoid" | ParallelogramShapes
type ParallelogramShapes = "Square" | "Rectangle" | "Rhombus" | "Parallelogram"
type TriangleShapes = "Isosceles" | "Scalene" | "Equilateral"
现在,我们介绍通用的Meta
:
interface Meta {
id: number
number_of_sides: number,
type: Shapes,
is_quadrilateral: boolean, // Boolean is an object type, use boolean instead
is_parallelogram: boolean, // ditto
}
interface QuadrilateralMeta extends Meta {
number_of_sides: 4;
type: QuadShapes;
is_quadrilateral: true;
}
interface ParallelogramMeta extends QuadrilateralMeta {
type: ParallelogramShapes;
is_parallelogram: true;
}
interface TriangleMeta extends Meta {
type: TriangleShapes;
is_quadrilateral: false;
is_parallelogram: false;
}
interface SquareMeta extends ParallelogramMeta {
type: "Square"
number_of_parallel_sides: 2; // not sure
}
可以通过指定通用的IShape
并添加新属性来简明地描述interface IShape<M extends Meta> {
$meta: M
}
:
ISquare
最后是您的课程:
M
对您有用或给您带来想法的希望。祝你好运!