chore: Enabled eslint rules requiring return types on functions#1503
chore: Enabled eslint rules requiring return types on functions#1503bmingles merged 5 commits intodeephaven:mainfrom
Conversation
| layout.xaxis.title = 'Datestamp'; | ||
| layout.yaxis.title = 'Price'; | ||
|
|
||
| if (layout.xaxis) { |
There was a problem hiding this comment.
These 2 if statements should be the only 2 runtime code changes in this PR
Codecov ReportPatch coverage:
Additional details and impacted files@@ Coverage Diff @@
## main #1503 +/- ##
==========================================
- Coverage 46.42% 46.42% -0.01%
==========================================
Files 558 558
Lines 35691 35706 +15
Branches 8915 8917 +2
==========================================
+ Hits 16571 16576 +5
- Misses 19069 19080 +11
+ Partials 51 50 -1
Flags with carried forward coverage won't be shown. Click here to find out more.
☔ View full report in Codecov by Sentry. |
|
I'm not sure if we want the explicit return on all functions. We previously only had the module boundary rule enabled. All functions feels too noisy to me and removes some of the good parts of TS inference. Module boundaries being explicit makes it easier to catch/document public API breakages. Any non-module boundaries will only be used within our code and inferred types will all get checked. |
@mattrunyon I didn't quite enable it for all functions. The Do you have any specific examples of where the type inference would be better without the new rules? |
|
I don't think most of the added types were heavy, but it feels like writing I think the rule was removed from the default rulesets we consumed because it goes against the power of TS inference, but module boundaries for a library help us catch breaking the API on accident. If we set up api-extractor we could even remove this linter rule and still have confidence we didn't break our external API. There's already a bunch of inferred return types we have to make explicit because they are module boundaries, but the module is not exposed as part of the public API. |
|
To clarify, this shouldn't require adding types to things like That said, I'm not hard sold on having to enable this rule, but I do want to highlight the benefits I see in doing so. |
|
I know you don't have to type variables, it just feels akin to typing simple variables (although slightly different). I think the class of error where you meant to return something is already handled by the TS compiler. Unless you start using casts and other things to lie to the compiler, in which case the explicit types still won't save you. I mostly just use hover tooltips if I need to know what a function returns when reading things. I see a bit of benefit for readability, but find the TS inference to be nice for all the simpler functions. |
677787b to
4afa235
Compare
mofojed
left a comment
There was a problem hiding this comment.
Overall supportive of the change. Being explicit seems safer, in cases where you might accidentally return the wrong thing/change the return type inadvertently. You can still use type inference to hover over the method to figure out what TS thinks it is if you haven't filled it in yet, but they we should be explicit and lock it in.
Some things to clean up.
| * Component that broadcasts a message when mounted. Should be mounted after the user has logged in. | ||
| */ | ||
| export function LoginNotifier() { | ||
| export function LoginNotifier(): null { |
There was a problem hiding this comment.
Kind of weird just having a null return type here - I was going to suggest ReactNode as that includes null, but then that freaks out in AuthBootstrap. Looks like that issue is fixed in TS 5.1: https://devblogs.microsoft.com/typescript/announcing-typescript-5-1-beta/#decoupled-type-checking-between-jsx-elements-and-jsx-tag-types
If we were >=5.1, might consider using ReactNode instead.
There was a problem hiding this comment.
It looks like JSX.Element | null is currently the return type declared by React.FC. Maybe that new 5.1 type will address this, but seems like <SomeComponent/> does not work for things like string which is included in ReactNode. For now I think JSX.Element | null will be the most appropriate for component return types.
| const mapStateToProps = ( | ||
| state: RootState | ||
| ): Omit< | ||
| AppMainContainerProps, | ||
| 'match' | 'setActiveTool' | 'updateDashboardData' | 'updateWorkspaceData' | ||
| > => ({ |
There was a problem hiding this comment.
Another way to separate the props is in Linker.tsx. I kind of like the way Linker is done, what do you think? Doesn't need to be changed in this PR.
There was a problem hiding this comment.
I'm a fan of this approach. Wish I'd noticed it before. I won't address on this PR, as there were a bunch of them.
|
@mofojed Echoing my previous comments, but I don't see explicitly typing all returns as that beneficial compared to just the module return types. Any of those mistakes where you accidentally return the wrong type or change the type should automatically be caught by the compiler unless the consuming code (in the same file) is not typed properly. This is not the case for the public API where we want to prevent accidental changes, so typing the module boundaries makes sense. Just my 2 cents |
|
@mofojed @mattrunyon I ran these rules on Enterprise just to see how big the breaking change is going to be. Looks like 278 errors vs 0 errors for the |
OnlyOnePropNote, the only runtime changes that should be in this PR are 2 if statements in MockChartModel
https://github.com/deephaven/web-client-ui/pull/1503/files#r1322021147
resolves #1413