Reputation: 73
How can I extend the types from a node package without modifying the @types files?
import { Session, useSession } from 'next-auth/client'
// I AM TRYING TO EXTEND THE Session TYPE
export default function Component() {
// useSession() returns type-> useSession(): [Session, boolean]
const [session]: [<ENTER EXTENDED TYPE HERE>, boolean] = useSession()
...
}
Types from @types/next-auth
type Session = SessionBase & GenericObject;
interface SessionBase {
user: User;
accessToken?: string;
expires: string;
}
interface User {
name?: string | null;
email?: string | null;
image?: string | null;
}
The result should be a type like this:
type NewSession = NewSessionBase & Session;
interface NewSessionBase {
user: {
name?: string | null;
email?: string | null;
image?: string | null;
myCustomData?: {
uid: string | null;
}
};
accessToken?: string;
expires: string;
}
This would fix the error: "TS2741", "Property is missing in type but required in type"
Upvotes: 1
Views: 235
Reputation: 33051
You can just overwrite user
property of Session
type.
type GenericObject = {}
type Session = SessionBase & GenericObject;
interface SessionBase {
user: User;
accessToken?: string;
expires: string;
}
interface User {
name?: string | null;
email?: string | null;
image?: string | null;
}
type NewSession = NewSessionBase & Session;
type NewUser = {
name?: string | null;
email?: string | null;
image?: string | null;
myCustomData?: {
uid: string | null;
}
}
interface NewSessionBase {
user: NewUser;
accessToken?: string;
expires: string;
}
// The main part of answer
type ExtendedSession = Session & {user: NewUser};
This is more exotic way to replace one type of property with another. You can use it if you have more complicated replacing logic
type Replace<Obj, Property extends keyof Obj, NewType> = {
[P in keyof Obj]: P extends Property ? NewType : Obj[P]
}
type Foo = Replace<{ expires: string }, 'expires', number> // { expires: number }
Upvotes: 1