Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Of the three code-related sections, I think only Using Type Annotations makes sense. While the compiler _can_ infer the return type and the user can mouse-over the function to see what the language server has determined the type to be, I feel that explicitly noting what the return type is preferred. Yes, the compiler can act more quickly, but also it makes it more clear quickly to others working on the same project what the function does. Even in languages like Swift which are happy to use type inference, you still must annotate your functions.

The other two code-related sections seem odd, to write code that improves compile-time performance. It would be beneficial to see compile duration differences between projects that heavily use union types and projects that don't. Otherwise, changing your coding style and not using explicit features of a language that are hard to find in other languages seems counter-productive.

That said, the actual compiler configuration changes that follow seem very useful, from someone who doesn't write much TS.




> Otherwise, changing your coding style and not using explicit features of a language that are hard to find in other languages seems counter-productive

As with most optimization suggestions, I take these to be intended as a remedy when you're actually running into problems, not something to be done eagerly. I've never run into significant cross-project TypeScript performance issues personally, but I have heard of that happening to some people.


It does explicitly say this at the top:

> The earlier on these practices are adopted, the better.


Technically, yes, but we don't expect most users to stumble onto this page unless they're already hitting perf issues.


Haha, good thing it's on HN now then :P


Hum. I missed that. That does seem unideal.


My only issue with this is that it introduces the possibility for human error. It’s rare, but if the returned object fits more than one type (say, a superclass vs concrete class instance) the incorrect one could be selected and the code still compile. Is this even a valid concern?

The only time I see manual type annotation cause problems consistently is with React.FC<Props>: (props: T). People don’t always remember to provide their props interface as the generic, and instead directly annotate the props argument of the function. This is a subtle issue that breaks the “magic” props added by React (like children), leading to people adding their own children definitions to their props interfaces d’oh


I personally find that manual return type annotations actually prevent some errors. A common case: I forget the return statement in one branch, and TypeScript is happy to infer something like number|undefined as the return type.


>leading to people adding their own children definitions to their props interfaces

IMO this is a feature not a bug. Type definitions aren't just for the compiler, they're also for the developer. Being able to see at a glance which components expect children and which don't is really valuable. Not to mention that there are situations where I want to restrict what kinds of children can be passed in (think render-props, or named slot projection patterns).

In other words, just because React supports an implicit definition of what a "child" can be doesn't mean that my specific component supports all of those same possibilities.


I see your point, and agree under the condition that I trust everyone contributing to the codebase knows it. But, in reality, they don’t. I’d rather have the children type available but unused most of the time than one-off type definitions of children.

Maybe for you my own projects I’ll employ your approach, because I agree from the fundamentals side of it


Would be really helpful if there was an autofix suggestion available so that LSP can add the return type for you.


I'd love it if typescript could one day grow a mechanism to allow it to rewrite closure definitions to contain the inferred type declarations -- some kind of keyword to indicate "this return type will be re-inferred by compiler based on the call sites within local scope" and have it integrate with ide "rewrite on file save" infrastructure.

So you get minimal keyboard typing when passing around inline closures -- don't have to write the types yourself or maintain them as the code changes -- and any changes to the inferred return types would be visible in source control with diffs that provide quite rich information about changes that might have done something unexpected or propagated further than realized


The default eslint/prettier settings require return types for this very reason. Readability and not having to tab between files to figure out a return value is surprisingly helpful for your overall dev velocity.




Consider applying for YC's Fall 2025 batch! Applications are open till Aug 4

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: