Prefer Returning Objects to Literal Types

2 min read

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.

Hey, you! 🫵

Did you know I created a YouTube channel? I'll be putting out a lot of new content on web development and software engineering so make sure to subscribe.

(clap if you liked the article)

You might also like