Should you use return types?

  Рет қаралды 39,673

Matt Pocock

Matt Pocock

Күн бұрын

Your default attitude towards return types should be 'don't use them', unless one of three things are true:
- You're writing a function with multiple branches
- You're building a library
- You have a specific TS perf concern and you're banging your head against the wall
Become a TypeScript Wizard with Matt's free TypeScript Course:
www.totaltypescript.com/tutor...
Follow Matt on Twitter
/ mattpocockuk
00:00 What is a return type?
00:49 Should you use them?
01:08 Multiple branches in functions
02:32 Library code
03:10 Performance

Пікірлер: 207
@erlendryan
@erlendryan Жыл бұрын
In my opinion, by explicitly declaring the return type, developers can create more readable and maintainable code, as it provides an explicit contract for what the function should return. Additionally, explicitly declaring return types can also help to avoid ambiguity and prevent implicit type coercion, which can lead to unexpected behaviour.
@beeman-dev
@beeman-dev Жыл бұрын
Definitely. Explicit beats implicit in a lot of cases.
@vukkulvar9769
@vukkulvar9769 Жыл бұрын
Exactly. It's not about telling TypeScript what we think it return, it's about telling TypeScript what it SHOULD return. Contract is king, be it for function, or a class public methods.
@SubZero101010
@SubZero101010 Жыл бұрын
Readability is king.
@wtho
@wtho Жыл бұрын
I agree. On the other hand, if "code reading tools" could display the inferred type (either "on-demand", like on hover, or always), we could reduce manual maintenance. Maybe a few more years until we're there.
@RatonBroyeur
@RatonBroyeur Жыл бұрын
That By enforcing type, you create a contract. getId will always return a string, otherwise, you're gonna break things. Changing a type SHOULD create errors to ensure the change has been correctly implemented where needed. By not enforcing, you simply defer to other the task of ensuring your key id a string.
@TheNoim
@TheNoim Жыл бұрын
The general rule, in my opinion, should be to always specify a return type, unless the function is not meant to be exposed outside of its own scope. This helps prevent unintended changes and ensures proper type safety. Even in non library code. Sometimes, this also makes the code easier to read. I can stop reading the function definition in line 1, if a return type is specified.
@mattpocockuk
@mattpocockuk Жыл бұрын
You can hover over the function to figure out what type it returns. I.e. a return type isn't needed to see the result. Though if you're building something that's even library-like within an application (i.e. in a utils folder consumed by lots of modules) then probably specifying return types will be useful.
@TheNoim
@TheNoim Жыл бұрын
​@@mattpocockuk But this won't work in a PR or in a non IDE scenario.
@mattpocockuk
@mattpocockuk Жыл бұрын
​@@TheNoim Interesting, I always check PR's locally so haven't found that trade-off.
@S7hadow
@S7hadow Жыл бұрын
​@@mattpocockuk Mke North, who has some TS-Courses on FrontendMasters has a strong argument for always including the return type: It brings the error closer to where it is actually produced. As an example, let's say you are working on a function that returns an object and you accidentally rename a key. In another file, this function is called and the returned value is saved in a variable, of which the type is inferred as per usual. At some point the key is used and throws a type error. First of all, you have to find that error, which might only happen in CI, if you are not working on that file. Then you have to backtrace that error to the function call and back to the function. For that reason alone, I feel that 'maintaining' a return type is usually worth it and should be the rule and not the exception. One such exception could be that the function is small and is not leaving its own scope, as Noim put it
@taragnor
@taragnor Жыл бұрын
​@@S7hadow Yeah personally I find that putting in an explicit return type catches more stupid errors that I make. It's really useful especially when dealing with a bunch of nested map/filter/etc operations, because if I forget to flatten an array for instance, it will let me know. The type checker is just much better at dealing with complex types than I am, and can easily spot an error when I'm leaving something out. I mainly only ignore it in very small functions with very simple primitive type returns, like a getter function. The other good reason is if you're converting a JS library to TS. Often times there's no need to put in the work of defining a return type to a function that you know already works in functioning code.
@SubZero101010
@SubZero101010 Жыл бұрын
There are so many "if's" that I simplify the rule and just say: return it always and it works everywhere and always.
@moodynoob
@moodynoob Жыл бұрын
As long as you don't make it an eslint rule I can get behind this
@nielskersic328
@nielskersic328 Жыл бұрын
My primary reason for writing return types is not so I can see the type on hover, but to make sure the function is actually returning what my team and I have decided it should return. If you're returning the wrong type, it will also error on the function itself and not in some other function that's getting an unexpected type. I'm sure your advice is good in certain cases, but I'm actually quite happy with the Eslint rule that enforces return types.
@szymonszadkowski5693
@szymonszadkowski5693 Жыл бұрын
Shouldn't we use return types to make sure that the code we write, does exactly what it's supposed to do? It's like a unit test to check if the return value if valid. With return types we can make sure that we don't make a type mistake when we write the logic of a function. Even with one branch in function, it can be a pretty complicated one. IMO it all depends on the complexity of the code. What do you think?
@mattpocockuk
@mattpocockuk Жыл бұрын
Because for non-branching functions, it's actually slightly less useful to infer the return type: const returnAbc = (): string | number => { return 'str' } const value = returnAbc(); value is typed as string | number. Without a return type, it's just string. So, the idea of it being as good as a unit test isn't quite right.
@aram5642
@aram5642 Жыл бұрын
Agreed, in this specific example, where the name doesn't really tell us what the function returns, I would prefer to be explicit too. If only to make new team members more comfortable. And I would probably never have to maintain it. Plus, I like consistency.
@szymonszadkowski5693
@szymonszadkowski5693 Жыл бұрын
​@@mattpocockuk I'm not proposing using return types instead of unit tests, but alongside them. In the example you provided, the problem is not return type itself, but poor usage of it. My argument is that when writing a function we have specific goal in mind (or rather we should), so we know what should be returned.
@ajfalo-fi3721
@ajfalo-fi3721 Жыл бұрын
I agree. I made some mistakes in the past specially with functions that are supposed to return booleans. It's very easy to mess up here and return something like boolean | number | string| undefined.
@Trequetrum8
@Trequetrum8 Жыл бұрын
@@mattpocockuk This is a great example of why you *should* include a return type. You may know that your current implementation has an invariant that shouldn't/may not hold for the function. In general, inferred return types leak implementation details of a function. Any function that serves as an abstraction boundary (pretty much any named function) should endeavor to define the abstraction explicitly. Anonymous functions tend to specialize behavior for named functions/methods where that boundary is hopefully maintained.
@AlexanderSkoropad
@AlexanderSkoropad Жыл бұрын
in my opinion, there are too many "ifs", especially if you work in a team, it's much easier to say "use it always" because your junior/middle developers won't make mistakes and waste time thinking whether they should use return types or not
@mattpocockuk
@mattpocockuk Жыл бұрын
I think empowering your junior/mid devs to understand the trade-offs with each approach is exactly how you let them grow. That's how I wanted to be treated when I was a junior - taught, not railroaded.
@IvanKleshnin
@IvanKleshnin Жыл бұрын
100% 1) Start a function, omit return type 2) Forget to implement the body or return some junk value 3) The function is ready to use as properly typed 😱
@mattpocockuk
@mattpocockuk Жыл бұрын
@@IvanKleshnin How is the function properly typed? If the body isn't implemented, it'll return void. If you try to use the function, it won't work because it returns void. Even with return types, you can forget basic stuff and leave junk values in the code.
@rand0mtv660
@rand0mtv660 Жыл бұрын
Although I would agree with this approach as the path of least resistance while working in a team, I think it's not good for junior/mid devs because they won't really understand how things work. They will just do this "because someone said to do so" without actually understanding code that they write. But on the other hand, if they want to understand how things work, they can always just take their time and try to learn those things. It's a balance. I personally prefer not to type code if I don't have to, that's why I like the fact that TS can infer so many things and I don't have to worry about them. I rarely specify function return types and that has served me well. I would rather TS infer from primitives or types I already have defined, rather than me copy-pasting type definitions for no reason. In extremely large projects I could see the benefit of doing every type 100% explicitly, but I never worked on such a project so I don't know if there is a true benefit or not.
@AlexanderSkoropad
@AlexanderSkoropad Жыл бұрын
My comment was not that you don't need to know this, I meant that the fewer complex rules for writing code you have the better, especially since it's pretty easy to get it typed using eslint. Is it possible to check the conditions described in the video using eslint? I do not think so. And if you create a bunch of conditions for fairly simple things like typing the returned result that you can't check automatically, this will only complicate the development process, and inevitably lead to the fact that someone somewhere forgot to describe something, another person missed this thing at the PR review stage, and now you have a function somewhere with a type that was incorrectly inferred by a typescript.
@byronhogan8405
@byronhogan8405 Жыл бұрын
I think this is fine if you are the only one working on a project and don't like return types. But if you are working in a large project, it makes reading code, especially other people's code or code you wrote forever ago, much easier. It doesn't take much to add the return type but it saves on mental thought by knowing what a function returns without having to decipher it yourself.
@imfastboi
@imfastboi Жыл бұрын
Rust has made me like return types, it allows you to actually make code that depends on other functions not scream at you whenever you change the implementation. Calls to the annotated function will only care about what the function is supposed to be doing, not what it is doing. Of course, in the long run on stable features of a project it shouldn't really matter since you probably wouldn't be changing the return type everyday but I still think it's a neat way to think about it
@zheil9152
@zheil9152 Жыл бұрын
It’s a whole lot easier to specify a return type and know when that contract is validated than to not specify, make a small change that changes the return type, and watch all the cascading calls of that function break in different files. Of course, this doesn’t sound bad for small projects, but in larger monoliths at work it takes ts server in vscode a good 2 minutes to catch up to type changes throughout the codebase sometimes (depending on how bogged down the computer or VSCode is). Why wait for all those changes to get recognized throughout the codebase when I can just put a simple return type on the function and see it break a lot quicker in that one file?
@wlockuz4467
@wlockuz4467 Жыл бұрын
My rule of thumb is to specify the return type if its a complex type like an object, or an union regardless of the function logic. This is just so that its easier to know at a glance whats coming up from a function. For a single primitive type like number or string its better to just let TS infer it.
@mado_z
@mado_z Жыл бұрын
I think declaring a return type is useful when you're building the function itslef, helps you be sure you're returning what you want
@BritainRitten
@BritainRitten Жыл бұрын
I think this is a rare miss by you, Matt. The minimal documentation aspect of return types makes it so much better for code hygene. And for me, the most compelling reason to almost always add return types is to make sure that the function you are writing does what you say it's doing. The return type becomes an assertion of truth, and the implementation fails (ie TS yells at you) until it agrees with that assertion. That makes it so much easier for making sure your code does (at least part of) what it says. I think there are rare times you can go without return types: really just where the return type is extremely obvious - like React components are always gonna be returning JSX.Element (or similar). But keeping that rule in place at almost all times is just gonna be easier.
@tjsr
@tjsr Жыл бұрын
Yeah, this one's a big 'no' from me. The whole topic is basically "do this thing because it clearly provides value any time you do these things but let's have this set of niche edge-cases where we don't" as opposed to "do this thing as a rule because it clearly provides value". Always returning a type protects against future changes without a signature changing. You shouldn't be relying on tools and the compiler to be able to deal with inferred types to check things - it should be easily apparent to the human reader at a glance, without digging. I've seen plenty of times in React components where people have accidentally returned say string values - which is why even for 'simple' component functions I insist they return JSX.Element.
@rcnhsuailsnyfiue2
@rcnhsuailsnyfiue2 Жыл бұрын
Exactly. If you don’t want to specify types, why even bother using TypeScript in the first place! When functions are callable, their return types are equivalent to the typing of any other variable.
@franssu2229
@franssu2229 10 ай бұрын
@@rcnhsuailsnyfiue2 "their return types are equivalent to the typing of any other variable." no it's not ; you don't write const toto: string = 'toto' do you ?
@rcnhsuailsnyfiue2
@rcnhsuailsnyfiue2 10 ай бұрын
@@franssu2229 I mean, you can? If you’re happy to define the return type loosely like that. But it’s not was I referring to. I’m saying that because functions can be used like variables, specifying the return type of a function is equivalent to specifying the value type of any other variable you explicitly define.
@franssu2229
@franssu2229 10 ай бұрын
@@rcnhsuailsnyfiue2 which is then equivalent to something that most of the time you wouldn't do, and rely on type inference instead. "Why even bother use typescript in the first place ?" Because typescript guarantees that the inferred types match and it's is very different from having no type at all, wtf ?!
@Fuzbo_
@Fuzbo_ Жыл бұрын
Love your videos, and love how concise they are at explaining things that very few people in the community touch upon.
@kappascopezz5122
@kappascopezz5122 Жыл бұрын
The "lowercase latestupdate" bug seems like it could happen just as well with only one main branch. I think I'll keep using return types unless the returned value is a primitive.
@TheStone190
@TheStone190 Жыл бұрын
Per habbit from how I learned at uni, I always write the functions declaration before filling in their logic, so I always specify the return type of what I expect It does help me catch missunderstandings about how libraries are used as I use them
@mattpocockuk
@mattpocockuk Жыл бұрын
This is definitely true for me too in branching functions!
@VivekYadav-ds8oz
@VivekYadav-ds8oz Жыл бұрын
The fact that types are still marked in Python where they add no compiler checks but are just for readability, should alone make it pretty obvious why having type hints is superior.
@AlexanderTrefz
@AlexanderTrefz Жыл бұрын
The majority of your application code should behave and be considered as library code, even if it is internal to this single application. This has all sorts of benefits in how code is structured. From that follows the simple rule of always using return types. This is mentally easier, it doesn't change as your functions change, and is generally a good safety net. Inference at the boundary layers of functions is generally very likely of creating subtle, hard to track down bugs or error messages.
@i.j.5513
@i.j.5513 Жыл бұрын
I also agree with some other posters about preferring to declare the return type explicitly. Why? Because when you inevitably have to change your code sooner or later, the return type serves as a guard to remind you when you are changing the nature of the function and can save you some trouble down the road. By changing the return type you are changing the nature of a function, yet with TS's smart inference that is not obvious / stays implicit. Now if the consumers of your functions accept a wide type, this might not trigger errors, but lead to unexpected behavior down the road. With explicit returns, you have to change the return type yourself and think about what that means in the wider context of your application.
@daniellynch3724
@daniellynch3724 Жыл бұрын
What a hot take. I can see the utility in it, by making code a little simpler, but I think always requiring them has the benefit of not having to think about whether or not you need one.
@adambickford8720
@adambickford8720 Жыл бұрын
I tend to skip it for private methods as the actual return doesn't matter since it only has 1-2 call sites. My helper function names are usually also give you some idea anyway.
@Mikenight120
@Mikenight120 Жыл бұрын
Just earned a new sub! Love ypur typescript videos. Every video I see from you I learn that I write horrible typescript code
@Sammi84
@Sammi84 Жыл бұрын
Leaving out the return type forces the compiler to do more work in order to infer the type. This has performance impacts especially in large code bases where you do this often, as the compiler will have to infer recursively very deeply. A return type will stop this recursive inference and save cpu cycles.
@mattpocockuk
@mattpocockuk Жыл бұрын
This isn't correct - the compiler is doing that work anyway in order to compare your return type to your function's implementation. It caches the result of it so it doesn't do it twice. The reason TS doesn't do well in large codebases is that it doesn't parallelise work, so it scales badly. Return types can assist in some use cases, but not enough to force me to always use them.
@Sammi84
@Sammi84 Жыл бұрын
@@mattpocockuk An inferred return type depends on the input parameters. So it has to be checked for each use of the function in the codebase. This causes it to happen recursively for each function with a inferred return type. An explicit return type will short circuit this recursion. I hope you will prove me wrong :)
@mattpocockuk
@mattpocockuk Жыл бұрын
@@Sammi84 An inferred return type depends on the input parameters. This is only true for generic signatures, which TypeScript can cache because it turns the function itself into a cacheable type function.
@abstractalgo
@abstractalgo Жыл бұрын
I think the argument is not expressed in a fair way: instead of saying "don't write them by default unless a,b,c,d...", you're actually saying "write them by default unless it's a simple function". Thinking overhead is much smaller. Also, code reviews get much easier with explicit return types, as you properly understand the intent and the flow of reasoning (i.e. "here's a signature of the function, and now here's the actual impl"). Also, code review tools don't necessarily offer hover to show you inferred types. The final reasoning for me is simply about "honouring the contract". The author had a specific intent in mind, so they wrote a full signature and then complied to that signature while writing out the impl. This is also a premise of TDD - "I comply to interface and behavior expectations, instead of hope that I get it right". I, however, don't ever enforce eslint rule for return types (too much friction and then zero flexibility for people accidentally doing things other way).
@FunctionGermany
@FunctionGermany Жыл бұрын
it's a hot take but i agree. writing less code is generally better, but my rule of thumb was always to specify return types when the function is simply a bit complex and changing it could easily change the inferred return type if it's not enforced. so a very psychological decision.
@SeanCassiere
@SeanCassiere Жыл бұрын
Could we get a video on conditional types? Asking since its something I tend to see inside library code.
@mattvicent
@mattvicent Жыл бұрын
When the return is an object I always like to specify the return type, because that way I avoid missing properties in the returned object because I'm explicitly telling the function should return an specific set of properties. This is specially useful when dealing with functions related to form. Let's say I have a getInitialValues function that takes in the values from the server and parses it into values for the Form. If I add a new field to the form I will need to grab that value from the server and return it along the rest. If type the return, I'll receive a typescript error because of that missing value and go fix it. So it actually HELPS type safety and insuring that I return the correct values.
@robhannah2794
@robhannah2794 Жыл бұрын
I need return types for methods I decorate with logging. By accessing the metadata, I can determine what the decorator can use for getting the result to log, as well as handle error conditions (nothing vs await vs pipe(), throw vs throw vs throwError())
@Blafasel3
@Blafasel3 Жыл бұрын
Considering there are so many exceptions to "Do Not use return types on functions", it just becomes easier to do it all the time instead. I want clear and easy rules and "Always specify the return type" is way easier than "if there is more than one branch or a complex Object returned, specify the return type". Especially if the function returns anything else then a primitive you basically have to specify the type because you very easily might break the Code with a refactoring.
@CapitaineToinon
@CapitaineToinon Жыл бұрын
This channel is a banger
@DevvOscar
@DevvOscar Жыл бұрын
What is that plugin he is using that shows the type with ^?
@MiuBrothersOfficial
@MiuBrothersOfficial Жыл бұрын
The issue with the rule "Don't use return types, unless..." is that it is open to interpretation. How can we enforce the instances where return types are necessary in ESLint, and ignore those where they are not needed? It's not possible, right? When reading code, our eyes quickly scan the function signature, and we don't want to have to keep moving our gaze up and down to understand what the function does. This makes reviewing pull requests more challenging. Code is read far more often than it is written, so it's important to be explicit to make it easier to read. Additionally, being explicit can be enforced with ESLint, making our job easier.
@marloeleven
@marloeleven Жыл бұрын
another great video
@jimmyj.6792
@jimmyj.6792 Жыл бұрын
Thanks a lot for your really nice summary 🙏 wizard of ts ❤
@Gabriel-iq6ug
@Gabriel-iq6ug Жыл бұрын
I get your point but I also think it is necessary to be a regular TS dev to fully understand when to specify a return type and when not
@djcamp5610
@djcamp5610 Жыл бұрын
Thanks for video =) Could you recommend top lint rules for TS ?
@nikfp
@nikfp Жыл бұрын
From my view, return types are very useful as they give you a contract to adhere to at the function level, and an error at the place that needs fixing if you don't follow it. By inferring the return type you open up the possibility of having to debug the error from calling code and working backwards which increases mental overhead. You also have the possibility of calling code being built against multiple options of an ambiguous return type, leading to higher bug rates and higher difficulty if you ever have to refactor. Also, if for some reason your function ends up with a gnarly union for a return type, it's a code smell and you can deal with it as you write the code, which makes consuming it easier as well.
@iamchu
@iamchu Жыл бұрын
Cheers for video! Couple of points: - I think there's a case to be made for typing the return of your makeId fn, as the type is only inferred correctly up until someone changes implementation details which could silently break its usage (ie now returns a number but result is used in places treating it still as a string). You could make the argument that return type should only be added at point of this implementation change though. - Another strong case I think to avoid return types would be functions that return functions. For example if I have a hook that returns multiple methods, I might want to type each methods return type, but I don't want to type the hook return type itself as it adds no value, and that ESLint rule here would be very annoying.
@Drobnydrobny
@Drobnydrobny Жыл бұрын
I like your balanced approach 👍
@BradenSimpson
@BradenSimpson Жыл бұрын
What's the vscode extension that provides the // ^? functionality to view what type the above line is?
@joeledwardson8537
@joeledwardson8537 Жыл бұрын
how did you get the printout in white of the inferred type at 0:58, is that auto-generated? I've not seen in it vscode before
@moodynoob
@moodynoob Жыл бұрын
This is a pretty balanced take on explicit return types, especially after seeing the slugfest between Theo and Prime over this topic. That being said, I find explicit return types quite useful and only omit them based on experience. If I was to make a rule of when I do and don't use them it'd be a bit complicated!
@nivaldolemos5280
@nivaldolemos5280 Жыл бұрын
You can also transiently declare the return type before implementing the function, just in case, to guarantee you are implementing correctly. Once done, you erase the return type declaration.
@rupakkarki
@rupakkarki Жыл бұрын
was just looking at this on twitter and the notification appeared. of course i clicked on it instantly.
@faizanahmed9304
@faizanahmed9304 Жыл бұрын
Thank you!
@javierolazaran7227
@javierolazaran7227 Жыл бұрын
So, in my opinion, I feel that explicit return type makes it way easier to read the code. For example, in the makeId() function you can see just by reading the declaration with the explicit return type what to expect from the function whereas if you have it implicit you are forced into read the logic to inferit your self or wait for the IDE to tell you if you are wrong.
@erikslorenz
@erikslorenz Жыл бұрын
I do for certain things. Usually if its some sort of complex object that im exporting a type for already and the function is manipulating some input to build that object. Let the ide help me out when im typing the logic
@Luxcium
@Luxcium Жыл бұрын
When I have complexe types and I want to be sure I want to conform to what I am doing I prefer to have return types annotated especially when I’m implementing complicated stuff or doing something like a library or package that is to be reused accordingly to a specific API that I am creating… I guess that trivial code is too trivial for me to even consider adding such annotations especially if it involves a primitive JavaScript or TypeScript type… I am also someone who in TypeScript uses the async keyword to mark the functions returning a promise even if it doesn’t use the await keyword and I think that the same arguments for or against it would be like the return type annotation (which is also making it redundant I understand that)…
@sludgepuppy
@sludgepuppy Жыл бұрын
Can you explain why NOT to use them a bit more? You just mention that there's more to maintain. What issue does this actually cause? And why is it bad? My thinking of explicit return types is that it makes the function more readable - you know what the function returns from its declaration. Can you explain why to not to use them compared to this point? Keep up the great content, Matt.
@michaelkurzewski2937
@michaelkurzewski2937 Жыл бұрын
I would do return type, because the file might expand in someone else's hands. If they don't know TS as well let's say junior person would introduce some branching. If there is no return type weird things might happen and things can get overlooked. It's not massive headache to be explicit. Also makes code slightly bit more readable imo.
@micalevisk
@micalevisk Жыл бұрын
I like that eslint rule because it helps on code reviews But you got your point.
@ThiagoVieira91
@ThiagoVieira91 Жыл бұрын
ThePrimeage just released a video about this same subject, following a discussion with Theo. Guess we could have your opinion there, Matt!
@peterparkour2137
@peterparkour2137 Жыл бұрын
Instead of remembering caveats, I'm gonna stick to declaring every return type
@brokula1312
@brokula1312 Жыл бұрын
For me, every time I want to make sure that contract is fulfilled by the function implementation I use return types. It can be as simple as primitive or complex type.
@aurorazuoris6654
@aurorazuoris6654 Жыл бұрын
In my opinion, function signatures are the one place you should always declare all the types. And the return type is part of the function signature. Although I do think that it's okay to skip them in ad hoc anonymous functions, for example when using map or filter.
@steamer2k319
@steamer2k319 10 ай бұрын
This is basically just Ya Ain't Gonna Need It (YAGNI) applied to return types. Don't write that extra code until you actually need it.
@DanielDogeanu
@DanielDogeanu Жыл бұрын
I think this is another unnecessary rule that we have to remember. I would add return types everywhere regardless and forget about it. There are other things more important than to deal with this nuance!
@foolmoron
@foolmoron Жыл бұрын
Libraries don't need to export simple types that they use in exposed functions. Consumers can use ReturnType or Parameters to access those if really necessary.
@mattpocockuk
@mattpocockuk Жыл бұрын
They do, because not doing so ends up in emitting long declarations which are usually worse for TS perf. Some TSConfig settings even explicitly force you to name the types that you export.
@foolmoron
@foolmoron Жыл бұрын
@@mattpocockuk What I'm saying is for the lib to declare the return types internally, but don't necessarily export them. Does that still have the long declaration problem?
@mattpocockuk
@mattpocockuk Жыл бұрын
@@foolmoron No it doesn't! Though I really do hate libraries that do this, like react-aria.
@mluevanos
@mluevanos Жыл бұрын
When I write my own functions I make sure to add a return type to make sure other Developers know the intent in case they change the internals. I'd rather have verbosity that is clear over writing shorter code that may have unintended results.
@thepetesmith
@thepetesmith Жыл бұрын
I call this “over typing” , I suggested an eslint rule but it is very hard to enforce. I find inferred types to be superior and is less code.
@aram5642
@aram5642 Жыл бұрын
I prefer to be explicit. If only to be clear about that the function is expected to return a value. When you look at a function signature that is missing a return type, you might understand that it is expected to return void and it basically performs some side effects. An example like the one in your newsletter (return 'abc') is too simplistic. a one-liner like this obviously might get away without a return type, but in real life a function like this is a rarity. The only case where I let go of return types are Angular lifecycle hooks which return void. I agree with eslint being a nightmare, but it also depends on the average skill level in the team.
@AlainBoudard
@AlainBoudard Жыл бұрын
Yeah, these are good explainations, although it's sometimes easier to stick to the same policy, right ? And also, how can we apply coherent lint rules if we don't adopt the same way ? Anyway, great content Matt !
@spiraI64
@spiraI64 Жыл бұрын
It’s better to always have a return type than to debate correct return type usage on every PR
@jeromealtariba7339
@jeromealtariba7339 Жыл бұрын
Hi, agree with you but... You have forgotten, in my opinion, the readibility requirement. Even for small functions that return primitive types, adding the return type in the signature is adding readibility to the code, especially in a team. That prevent us from reading the function to get the return type. There is also the option to define a naming convention for small (inline) functions that contains the expected returnng type. CU !
@lordpablo1985
@lordpablo1985 Жыл бұрын
What was the // ^? Extension called again?
@ChillAutos
@ChillAutos Жыл бұрын
I would say more than one branch OR the the function is somewhat complex even without branches.
@coder_one
@coder_one 9 ай бұрын
2:26 - what's the name of this es-lint rule?
@cotneit
@cotneit Жыл бұрын
IMO by default return type should be specified, but I wish we could use infer keyword or something to shut eslint up if we explicitly don't want to do that. Comments work just fine though, so that's not a big deal
@PeidosFTW
@PeidosFTW Жыл бұрын
why would you use TS and not take advantage of returning a certain type?? Specially when you add so many exceptions as to when you shouldn't use a return type
@zenpool
@zenpool Жыл бұрын
Me using `ReturnType` a lot because Im too lazy typing my return types.
@eliberkowitz7454
@eliberkowitz7454 Жыл бұрын
All the comments agree; just use return types. It's more explicit it brings errors closer to the source it's easier to read without having to check out a PR the caveats you have in your video and another one for me, it works for being specific about object types. For example say you're writing a function that returns an ast node, you could `return {kind: "DOCUMENT", statements: [{kind: "FUNCTION", name: ...}, ...]}` and it'll get inferred as some big object type, but really what it is is `ASTNode` imported from some ast library; better to be specific about what you want. I don't think you need return types on anonymous functions for stuff like mapping/filtering unless you want them, but for any concrete, testable, especially exported piece of code, they seem very useful.
@Trequetrum8
@Trequetrum8 Жыл бұрын
A good rule of thumb is that named functions should be typed and anonymous functions can be inferred. Just a rule of thumb since question like "Is an anonymous function that's assigned to a variable now named?" muddy the waters a bit. Though generally that tends to happen with parameters & properties which should be typed.
@evowizz
@evowizz Жыл бұрын
Definitely not a good advice imo. The whole idea behind this video is that return types are inferred anyway. But return types are only inferred if you're actually in your IDE. If you have a complex function and you're reviewing code on GitHub (for example), chances are you'd rather see the return type at first glance rather than looking for it. But that's also the case in VSCode. Sure you can hover things to see inferred types, but seeing it at first glance just makes your code easier to read, and doesn't have any negative impact on your code.
@t3dotgg
@t3dotgg Жыл бұрын
Another Matt W (don’t let Prime win)
@royz_1
@royz_1 Жыл бұрын
This is exactly what I do!
@lightninginmyhands4878
@lightninginmyhands4878 Жыл бұрын
Is that ^? actually displaying that const!?
@neek01
@neek01 Жыл бұрын
But at this point why not use Javascript? you can still get types in javascript through JSdoc (vscode recognises it and enables intellisense for jsdoc typed code)
@mattpocockuk
@mattpocockuk Жыл бұрын
Because JSDoc is much less ergonomic than a language _designed_ for the purpose.
@rafaeltab
@rafaeltab Жыл бұрын
I don't fully agree with this one. I would instead say that any exported members need a return type, but non-exported members do not. This should become especially obvious when doing red-green-refactor, you write the function definition first, with parameters, and a return type. This then allows your unit test to not test the returned type since this was already done by typescript, and instead, it can focus on testing the actual logic. Now that you've got your unit tests, you can create the implementation, and you're sure you won't mess up because you're stopped when you return the wrong thing and when your logic is wrong. This same idea doesn't work for non-exported members, since they are not directly tested. Here I think typescript inference is more important.
@RaphaelAlejandro
@RaphaelAlejandro Жыл бұрын
"Don't require my devs to do that". Okay, I'll not require myself to do that. I find useful when using NestJs, and Swagger, so it creates the specification based on the DTO.
@Ultrajuiced
@Ultrajuiced 11 ай бұрын
Then somebody comes, adds a branch where there were no branches before and doesn't add the return type ...
@joshuagalit6936
@joshuagalit6936 Жыл бұрын
ESLINT: Don't mess up with me. Please put proper return type and don't turn it off :P
@ColinRichardson
@ColinRichardson Жыл бұрын
Sorry, we value consistency.. If you "should" add it for 1 type of function, we add them for all functions. We even have it as a lint rule that you should..
@nathanfranck5822
@nathanfranck5822 Жыл бұрын
I'm just glad you triggered Primeagen, I've never seen him so mad
@TheBswan
@TheBswan Жыл бұрын
Finally Matt gives controversial TS advice
@NoName-1337
@NoName-1337 Жыл бұрын
You don't need to tell typescript, but I would always use returntypes. It gives me and everyone else a guarantee to be something the developer want to get.
@victorlongon
@victorlongon Жыл бұрын
Amen!
@SoldierXfreedom
@SoldierXfreedom Жыл бұрын
I thought this video was about the ReturnType generic, just me?
@odra873
@odra873 Жыл бұрын
EsLint won’t allow this in our project:D
@silverhairs
@silverhairs Жыл бұрын
just use copilot if you are worried about writing too much code
@Trequetrum8
@Trequetrum8 Жыл бұрын
That's a **hard** no from me. I'm gonna stomp the breaks on that one. This is all subjective, of course, but functions aren't just about code re-use, they're powerful abstraction boundaries in their own right. Any argument for the correctness of some code that relies on me (or my IDE) inspecting the implementation of a function being called is non-local. Explicitly typing every variable is noisy, but functions seem like a great place to draw the line. Since those types don't need to appear at the call cites where they're used, there's less (almost no) risk of function type signatures becoming needlessly noisy.
@hubrismaxim
@hubrismaxim Жыл бұрын
Work with the compiler. Excluding the return type means you’re not giving enough info to the compiler. Leaving it out you are fighting the compiler.
@mattpocockuk
@mattpocockuk Жыл бұрын
The compiler will infer the return type whether or not you explicitly type it!
@hubrismaxim
@hubrismaxim Жыл бұрын
@@mattpocockuk that’s not the point. The whole point of adding the type is to use the compiler to check your work. This is pretty much the #1 mistakes I see juniors making. They don’t specify a return type and then get errors because the function isn’t returning what they thought. If they had just specified the return type for their functions the compiler would have caught it and saved hours debugging. Based on my experience with junior devs, specifying the return type’s consistently is probably is one of the most important habits of a successful typescript developer. Typescript isn’t like Rust or Haskell. Because it is transpired to JS, you have to be even more judicious in communicating with the compiler. You can’t rely on inference like those languages.
@osabros
@osabros Жыл бұрын
Matt, this is the first video I've seen of yours with a pretty controversial opinion. In this one I respectfully disagree, writing the return type in declaration makes writing and maintaining so much easier. When writing - you know exactly what you need to return. When maintaining - you can immediately tell if you've screwed up something. Keep up the great videos! Would love to get more of your opinions and ideas
@armantavakoli5314
@armantavakoli5314 Жыл бұрын
i see you have declared war on half of all js programmers
@Nicolasmelo12
@Nicolasmelo12 Жыл бұрын
This falls in the category of: "Just because you can, doesn't mean you should". Types are rules, rules that define the path other programmers should follow. I would JUST approve this in the case of a really, REALLY basic and dumb function like: 'generateUuid()', or `sleep()` or functions that returns void. Besides that use cases, you should always specify the return type.
@kurishutofu
@kurishutofu Жыл бұрын
Oh, I thought it was going to be about `ReturnType`
@MatanGubkin
@MatanGubkin Жыл бұрын
In contracts to the comments here.. Over Typing in application code is almost always a bad practice
@marcusrehn6915
@marcusrehn6915 Жыл бұрын
Have you never been annoyed by { /*long implicit return type*/ } is not compatible with {/* other long implicit type*/}. I think naming and being super explicit is almost always better.
@mattpocockuk
@mattpocockuk Жыл бұрын
Giving it an explicit type often doesn't help here!
@marcusrehn6915
@marcusrehn6915 Жыл бұрын
@@mattpocockuk Not fully but I do find the following much easier to read: Property 'lastName' is missing in type 'HalfAPerson' but required in type 'Person'.
@butbutmybutt
@butbutmybutt Жыл бұрын
U should be using return types. It prevents errors.
@codetour
@codetour Жыл бұрын
TypeScript smart. Me Dumb. Thx Matt
@mikhailmikheev8043
@mikhailmikheev8043 Жыл бұрын
0:07 "specify what you think a function should return" IMO this is not the right mental model, the more correct one is "specify what you want a function to return" and le
@beeman-dev
@beeman-dev Жыл бұрын
Sorry, but at this point the recommendation might be: use explicit return types, unless you return a `string`... 😅
@Tantewillieja
@Tantewillieja Жыл бұрын
Normal speed editing, thanks :-)
TypeScript 5.0 BETA IS HERE
6:41
Matt Pocock
Рет қаралды 68 М.
Infer is easier than you think
13:38
Matt Pocock
Рет қаралды 86 М.
MEGA BOXES ARE BACK!!!
08:53
Brawl Stars
Рет қаралды 35 МЛН
OMG😳 #tiktok #shorts #potapova_blog
00:58
Potapova_blog
Рет қаралды 4,4 МЛН
THEY made a RAINBOW M&M 🤩😳 LeoNata family #shorts
00:49
LeoNata Family
Рет қаралды 28 МЛН
Wait for the last one! 👀
00:28
Josh Horton
Рет қаралды 140 МЛН
TypeScript Speedrun: Crash Course for Beginners
23:39
Matt Pocock
Рет қаралды 39 М.
Type your functions in TypeScript and SAVE TIME
8:31
ThePrimeTime
Рет қаралды 49 М.
Learn TypeScript Generics In 13 Minutes
12:52
Web Dev Simplified
Рет қаралды 233 М.
Deep studying tsconfig.json. Part 1. Type Checking (Compiler options)
32:53
Elena Litvinova — The Art of Web Development 🛸
Рет қаралды 848
7 Awesome TypeScript Types You Should Know
8:57
Josh tried coding
Рет қаралды 78 М.
any vs unknown vs never: TypeScript demystified
8:01
Andrew Burgess
Рет қаралды 20 М.
TypeScript: Should you use Types or Interfaces?
4:06
Matt Pocock
Рет қаралды 149 М.
Zod Goes Where TypeScript Can't
8:11
Theo - t3․gg
Рет қаралды 55 М.
I Cannot Believe TypeScript Recommends You Do This!
7:45
Web Dev Simplified
Рет қаралды 163 М.
Поставила пароль на телефон
0:45
Штукенция
Рет қаралды 2 МЛН