My API follows the HATEOAS architecture, providing me with structures based on my request. Whether it's a single entity or an array of entities, at the core of these responses lies valuable data.
// single entity
{
links: [{ ... }],
data: {
links: [{ ... }],
data: {
id: 1,
title: "example entity"
}
}
}
// array of entities
{
links: [{ ... }],
data: [{
links: [{ ... }],
data: {
id: 1,
title: "example entity"
}
}, {
links: [{ ... }],
data: {
id: 2,
title: "another entity"
}
}]
}
All responses are generically typed in the following way:
type Link = {
href: string;
ref: string;
type: string;
}
type EntityResponse<T> = { links: Link[], data: T };
type Response<T, Type extends [] | undefined> = {
links: Link[];
data: Type extends []
? EntityResponse<T>[]
: EntityResponse<T>;
}
Ideally, I would like to specify the data using the entities type:
Response<Product>
// or
Response<Product[]>
However, due to each entity being concatenated with a links
object, it becomes more complex. The solution above was my workaround for this issue.
If I need to define an array type response, I would use:
Response<Product, []>
For a single entity, the typing would be as follows:
Response<Product>
I suspect that there might be a way to simplify the conditional type used, but I'm unsure how to do so without adding the links
key/value pair to the entity type itself. Any guidance on this matter would be greatly appreciated!