When to Type your Return Types in TypeScript

David Barral
Trabe
Published in
2 min readFeb 22, 2023
Photo by Alexander Grey on Unsplash

To be honest, I don’t like TypeScript very much. I’m not riding the hype train. For me, shoving types into a dynamic language like JavaScript, it’s not going to work. To get my point, try to add types to the following JS function. Good luck with that.

  function curry(func) {
return function curried(...args) {
if (args.length >= func.length) {
return func.apply(this, args);
} else {
return function (...args2) {
return curried.apply(this, args.concat(args2));
};
}
};
}

To me, types feel more like a burden than something helpful. This is just my opinion, and the reality is that, like it or not, I’m forced to use TS in several projects. To ease the pain, I type as little as possible, letting TS infer everything else. So, what about function return types?

To type…

If you add return types to your function, the compiler will check that the body returns what’s expected. Basic type safety that may be useful. For example, the following function will rise an error.

function capitalize(s?:string):string {
return s?.toUpperCase();
// Error: Type 'string | undefined' is not assignable to type 'string'.
}

…or not to type

You can let TS infer the types. The same function without a return type won’t rise an error, and TS will infer the return type based on the implementation.

function capitalize(s?:string) {
return s?.toUpperCase();
}
function capitalize(s?: string): string | undefined

But, how do I know if this is ok? Maybe string | undefined is the correct type for this function instead of string. The answer is that your types define your APIs and your APIs are meant to be consumed by client code ( either other parts of your codebase or a test suite that exercises your public APIs). Return types should only matter to client code. So, let your client code check the types for you.

const capitalizedName: string = capitalize(data.name);
// The return type is not ok
// Type 'string | undefined' is not assignable to type 'string'

const maybeCapitalizedName: string | undefined = capitalize(data.name);
// The return type is ok.

So, when to type?

Almost always the answer is never. Just let TS do its thing and use/test your APIs.

I find that most of the time I only need to explicitly type the return type of very dynamic functions that end needing a lot of as usages in their bodies. The kind of code that TS struggles with 🤦🏻‍♀️.

--

--

David Barral
Trabe
Editor for

Co-founder @Trabe. Developer drowning in a sea of pointless code.