I have recreated the error I'm getting in a brandnew Create-React-App repo, source code can be found here.
As you can see in MyContext.tsx, I'm simply adding the result of useState to my context. The type of the context is also defined as a tuple by
const UDContext = createContext<
| undefined
| [
UserData | undefined,
React.Dispatch<React.SetStateAction<UserData | undefined>>
]
>(undefined);
However, when I try to access the data in MyComponent.tsx by doing
const [userData] = useUserData();
I'm getting the error
Property 'username' does not exist on type 'UserData | Dispatch<SetStateAction<UserData | undefined>>'.
This to me looks like it is somehow combining the tuple's types to one?
The funny thing: the below code does actually work (it does give a warning that context may be undefined, which indeed makes sense).
const context = useUserData();
const userData = context[0];
Exactly the same is happening in MySetter.tsx, where the exact error is
Not all constituents of type 'UserData | Dispatch<SetStateAction<UserData | undefined>>' are callable.
The above "solution" without direct destructuring works here as well.
The only way I can get this to work, is by explicitly declaring the type of the return value of useUserData.
A few sidenotes:
- This is the
@nextversion of Create-React-App - I had to enable
--downlevelIteration, or else the destructuring ofuseUserData()was givingType '[UserData | undefined, Dispatch<SetStateAction<UserData | undefined>>] | undefined' is not an array type or a string type. Use compiler option '--downlevelIteration' to allow iterating of iterators. - I have a working example in CodeSandbox that gives no issues at all.