_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.
| [ts] Cannot invoke an expression whose type lacks a call signature. | |
| Type 'string | ((item: string) => void)' has no compatible call signatures. [2349] |
Error Message

Error Message in VS Code
Below is the full source code for useLocalStorage.
| import React from "react"; | |
| export default function useLocalStorage(key: string, initialValue: string = "") { | |
| const [item, setValue] = React.useState(() => { | |
| const value = localStorage.getItem(key) || initialValue; | |
| localStorage.setItem(key, value); | |
| return value; | |
| }); | |
| const setItem = (item: string) => { | |
| setValue(item); | |
| window.localStorage.setItem(key, item); | |
| }; | |
| return [item, setItem]; | |
| } |
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.
| export default function useLocalStorage(key: string, initialValue?: string): (string | ((item: string) => void))[]; | |
| //# sourceMappingURL=index.d.ts.map |
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.
| export default function useLocalStorage(key: string, initialValue: string = "") | |
| : [string, (item: string) => void] { | |
| // rest omitted for brevity ... | |
| } |
Return type specified explicitly
You can now see that TypeScript has generated the definition correctly.
| export default function useLocalStorage(key: string, initialValue?: string): [string, (item: string) => void]; | |
| //# sourceMappingURL=index.d.ts.map |
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
- GitHub Issue - Package does not contains typings for Typescript development
- Demo Codes
- react-use-localstorage