Prefer Returning Objects to Literal Types
Let's say you're designing an API to return awards your user has won.
Instead of returning a list of awards as literal types:
function getUserAwards(user: User): string[] { ... }
console.log(getUserAwards(joe)); // ["rockstar", "10x-engineer", ...]
Consider returning a list of objects instead:
interface Award {
name: string;
}
function getUserAwards(user: User): Award[] { ... }
console.log(getUserAwards(joe)); // [{name: "rockstar"}, {name: "10x-engineer"}, ...]
You might think returning an object is overkill, especially since this object only has one property, but there are benefits to doing this.
Your API can be extended
Let's say you want to start returning the timestamp the award was given to the user.
If you're returning string[]
, you're going to have a problem.
You'll either make another API to get the timestamps,
or you're going to have to make a breaking change to the existing API to add the timestamp.
You should try not to introduce breaking changes as much as possible, as doing so can cause a lot of frustration.
However, if the API returns Award[]
, then you can extend the model to add the timestamp.
interface Award {
...
awardedAt: Date;
}
But extensibility is not the only reason you should prefer objects to literal types.
Named objects favors domain-driven design
The names given in the codebase should reflect the common language used
inside the business.
So if you're returning a collection of awards using domain-driven design,
you'll return Award[]
over the more vague string[]
.
An Award
means something. A string
could be anything.
For these reasons, I prefer designing APIs to return objects to literal types.