I'm designing an authentication backend with TypeScript. I have the following types to describe a user or a guest:
export type LoadingUser = {
loading: true;
};
export type AuthenticatedUser = {
loading: false;
error: string | null;
loggedIn: true;
name: string;
};
export type GuestUser = {
loading: false;
error: string | null;
loggedIn: false;
};
LoadingUser is used to indicate when the user is still being fetched, the frontend could show a spinner here. Notice it's either only loading: true with no other properties, or loading: false with other properties, and then either loading: false; loggedIn: false; error: string | null with no other properties, or loading: false; loggedIn: true; error: string | null with other properties.
I'm then using these types to define my User type:
export type User =
| LoadingUser
| AuthenticatedUser
| GuestUser;
I want to use this to type-check all my API responses, but I have come across the following problem
const user: User = {
loading: true,
loggedIn: true, // Problem: this property is allowed on this object even though `loading: true`
};
When I'm just using AuthenticatedUser and LoadingUser together, or GuestUser with LoadingUser, this problem does not happen. TypeScript then correctly errors and tells me loggedIn does not exist on type LoadingUser like I want.
Why does using type User make TypeScript not report this error?
In advance: Thank you so much for helping me, I've been struggling with this for days!