2019-02-10
Being explicit with your own React Hook + TypeScript return type
blogentry, programming, react, typescript
blogentry, programming, react, typescript
_Photo by Rafaela Biazi on _Unsplash
TheAifam5 graciously reported an issue for react-use-localstorage that even though it was written using TypeScript, it wasn't distributing TypeScript type declaration file.
react-use-localstorage is a React Hook that returns an array of Local Storage item and a way to set it
Initially written in JavaScript but recently converted to TypeScript to learn TypeScript.
I followed TheAifam5's instruction to generate a type file and distributed it.
But when I tried to use the new distrubution within a React + TypeScript project, I was getting the following error.
https://gist.github.com/dance2die/2cb920c9166637535e0b44e867152042
Error Message
Error Message in VS Code
Below is the full source code for useLocalStorage.
https://gist.github.com/dance2die/004c227bd94d574c313cde52868e9cf5
useLocalStorage - react-use-localstorage on NPM
As you can see, useLocalStorage returns an array of [item, setItem].
When auto-generating a type file using tsc, TypeScript generates following definition code.
https://gist.github.com/dance2die/9597d9483267c0a1df837f2119bdbd60
Bad return type
TypeScript inferred the return type as (string | ((item: string) => void))[] which is not right.
So to fix it you need to explicitly declare the return type of useLocalStorage to generate a correct type definition.
https://gist.github.com/dance2die/eb06fd7002fe75ce7f948fdcc754df44
Return type specified explicitly
You can now see that TypeScript has generated the definition correctly.
https://gist.github.com/dance2die/92efeaee3c5be12a6bea18033fd09e2d
Good return type
And TypeScript is happy (in VS Code).
TypeScript is now 🙂
Does anyone know why TypeScript wasn't able to infer the return type correctly?
UPDATE: 2019-02-12
pgrizzay & AngularBeginner have generously answered the question above in Reddit.
The gist is that, TypeScript does not infer tuple type variable because there isn't enough information.