Consider this code:
IAppStateProps.ts
:
import {INoteProps} from "./INoteProps";
export interface IAppStateProps {
notesData: INoteProps[];
}
then use it here:
useAppState.ts
:
import {INoteProps} from "./interfaces/INoteProps";
import {IAppStateProps} from "./interfaces/IAppStateProps";
export const useAppState = (): IAppStateProps => {
const [notesData, setNotesData] = useState<INoteProps[]>([]);
...more code
return {
notesData
}
};
My question is, since I defined the return type of useAppState
to be IAppStateProps
, and it knows that notesData
should return INoteProps[]
, is it necessary to define the return type again in const [notesData, setNotesData] = useState<INoteProps[]>([]);
?
2
Answers
If I understand correctly the question. No, you don’t need to specify it.
When you invoke useAppState it should return an object that has property notesData which is an array.
Yes. TypeScript can’t infer it in the direction you’re describing. If you leave the type argument off the call to
useState
and you use an empty array like that as the intial value, TypeScript will infernever[]
as the type, which means you wouldn’t be able to callsetNotesData
with real data:Error on the playground
If you want, you can infer it the other way, though, by leaving off the return type annotation on
useAppState
:Playground example
TypeScript will infer the return type as
{ notesData: INoteProps[]; }
. Since TypeScript’s type system is structural (based on the shape of types) not nominal (based on the names of types), that’s the same asIAppStateProps
.You may not want to do that, though, since an erroneous edit that accidentally changes the return type of the function wouldn’t be caught by TypeScript. In practice, I find inferring the return type is fine for really short, simple functions, but for anything beyond that I need the safety net of specifying what the return should be so edits accidentally changing it get caught early. Your mileage may vary. 🙂