I'd probably argue there should be a useMutableRef and useRef rather than complicated types to communicate intent. I often have these small functions that map to normal functions to more clearly communicate intent:
constmutableRef=useMutableRef(false)// mutable, default assignedconstimmutableRef=useRef<HTMLInputElement>(null)// React handles this, no default assigned/**
* Alias to `useEffect` that intentionally is only run on mount/unmount
*/constuseMount=(callback?:()=>void)=>{React.useEffect(callback,[])}
It is even possible to create nice utility functions that make element refs easier to work with:
Notice the theme where the Typescript types start to disappear for normal usage? This means you can still get the benefits of Typescript without explicitly using Typescript. Even JavaScript users of your code can benefit. This technique works better for libraries, especially if you have JavaScript users of your library. You can use JSDoc to explicitly type JS code, but that is a pain for non-primitive types.
I say there doesn't need to be a tradeoff between Typescript gifts and expressing intent. If your team only uses Typescript and understands all the types in use, maybe you don't need to spend any extra time communicating intent through functions. But it is very useful for JavaScript users in addition to Typescript users who don't spend time finding out all the nuances of Typescript type differences like useRef. You have to learn something extra either way (type differences or which function to use), but why not communicate intent explicitly through names vs types?
I actually never type anything in TypeScript unless I have to, and I consider explicit types to be an antipattern.
In my opinion, it's easy to check VSCode's Intellisense to make sure that the right type was inferred.
In React, for example, I've never had to actually use the FC type or explicitly return JSX.Element; if I write a function component, then TypeScript catches it 100% of the time.
There are definitely certain cases where I type function returns, such as if I'm using a "pseudo enum" (union type of strings) and want to coerce the function return down from string to either "thingOne" | "thingTwo" -- so I do see your point.
Overall, I don't think it's useful for productivity or type safety to explicitly type things when the implicit type was correct, so I try to avoid it.
For further actions, you may consider blocking this person and/or reporting abuse
We're a place where coders share, stay up-to-date and grow their careers.
I'd probably argue there should be a
useMutableRef
anduseRef
rather than complicated types to communicate intent. I often have these small functions that map to normal functions to more clearly communicate intent:It is even possible to create nice utility functions that make element refs easier to work with:
Notice the theme where the Typescript types start to disappear for normal usage? This means you can still get the benefits of Typescript without explicitly using Typescript. Even JavaScript users of your code can benefit. This technique works better for libraries, especially if you have JavaScript users of your library. You can use JSDoc to explicitly type JS code, but that is a pain for non-primitive types.
I say there doesn't need to be a tradeoff between Typescript gifts and expressing intent. If your team only uses Typescript and understands all the types in use, maybe you don't need to spend any extra time communicating intent through functions. But it is very useful for JavaScript users in addition to Typescript users who don't spend time finding out all the nuances of Typescript type differences like
useRef
. You have to learn something extra either way (type differences or which function to use), but why not communicate intent explicitly through names vs types?Because in this example case Typescript may :
I actually never type anything in TypeScript unless I have to, and I consider explicit types to be an antipattern.
In my opinion, it's easy to check VSCode's Intellisense to make sure that the right type was inferred.
In React, for example, I've never had to actually use the FC type or explicitly return JSX.Element; if I write a function component, then TypeScript catches it 100% of the time.
There are definitely certain cases where I type function returns, such as if I'm using a "pseudo enum" (union type of strings) and want to coerce the function return down from string to either "thingOne" | "thingTwo" -- so I do see your point.
Overall, I don't think it's useful for productivity or type safety to explicitly type things when the implicit type was correct, so I try to avoid it.