2019-02-10

Being explicit with your own React Hook + TypeScript return type

blogentry, programming, react, typescript

banner

_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 🙂

🤔 Question to readers

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.

🏔 Resources