Search code examples
typescriptfunctiontypesreturntype-inference

TypeScript: Is it bad practice to explicitly set type when type inference detects the type correctly?


when TypeScript infers the variable type correctly, should I set the type explicitly? for exa:

const add = (a: number, b: number) => a + b;

const  result = add(2, 3);

// or should I explicitly set return value type?
const add = (a: number, b: number): number => a + b;

const result = add(2, 3);

I know type inference has many cases. If this one is not a bad practice, I would like to know if there's any case in which explicit types are better.


Solution

  • I agree the answer to your question of when to add explicit types if the type can already be inferred is to some degree a manner of opinion, since the explicit types are not required in these cases. However, there are some advantages and disadvantages to adding explicit types (when not required):

    Disadvantages:

    • adding explicit types means more work, more code - so there is some additional cost to add and maintain them

    Advantages:

    • explicit types serve as self-documenting code: you are declaring to the reader what type you intend the function to return. Also, they are an easy reference for what type the function maintains - no need to used an advanced IDE with TSC running and hover over the function to get type intellisense - the return type declaration is explicit in code as part of the function signature.
    • explicit types guard against bugs in function implementation: instead of relying on yourself to write correct code and return the intended type, you declare what type you want the function to return and then you are leveraging TSC to make sure all paths through your function return that type. This is especially helpful in future-proofing the function - if anyone makes a code change inside the function that changes the return type, they must also acknowledge and change the explicit return type on the function signature.

    IMO explicit types are superfluous for simple functions (e.g. trivial lambda functions with a single return value) but are well worth the extra effort for complex functions (e.g. functions with multiple return statements). Since functions tend to become more complex over type, I err on the side of adding explicit return types to functions.