Infer type before initializing betterAuth

I'm trying to create a class that to migrate our system to betterAuth, while keeping the current system in place for the time being. I know what plugins are going to be enabled, but things like database password, appName and others will be passed in via configuration options How do I correctly define the type for the authInstance so that I have access to all the plugins? For example:
import { betterAuth, BetterAuthOptions } from "better-auth";
import { jwt } from "better-auth/plugins";


const authInstance = betterAuth({

emailAndPassword: {
enabled: true,
},
advanced: {
cookiePrefix: "pva_",
},
plugins: [jwt()],
});

export class AuthService {
authInstance: ReturnType<typeof betterAuth>;
constructor(o: BetterAuthOptions) {
this.authInstance = betterAuth({
...o,
emailAndPassword: {
enabled: true,
},
advanced: {
cookiePrefix: "pva_",
},
plugins: [jwt()],
});
}

getSession(headers: Headers) {
return this.authInstance.api.getSession({
headers: headers,
});
}
getJwt(headers: Headers) {
// this doesn't work
return this.authInstance.api.getToken({headers});
}
getInstancejwt(headers: Headers) {
// this works
return authInstance.api.getToken({headers})
}
}
import { betterAuth, BetterAuthOptions } from "better-auth";
import { jwt } from "better-auth/plugins";


const authInstance = betterAuth({

emailAndPassword: {
enabled: true,
},
advanced: {
cookiePrefix: "pva_",
},
plugins: [jwt()],
});

export class AuthService {
authInstance: ReturnType<typeof betterAuth>;
constructor(o: BetterAuthOptions) {
this.authInstance = betterAuth({
...o,
emailAndPassword: {
enabled: true,
},
advanced: {
cookiePrefix: "pva_",
},
plugins: [jwt()],
});
}

getSession(headers: Headers) {
return this.authInstance.api.getSession({
headers: headers,
});
}
getJwt(headers: Headers) {
// this doesn't work
return this.authInstance.api.getToken({headers});
}
getInstancejwt(headers: Headers) {
// this works
return authInstance.api.getToken({headers})
}
}
Solution:
I think I got it. Here's the diff of the changes I did ```diff --- oldAuthClass.ts 2025-05-07 18:11:43 +++ authClass.ts 2025-05-07 18:12:53 @@ -1,5 +1,5 @@...
Jump to solution
1 Reply
Solution
momoneko
momoneko•2w ago
I think I got it. Here's the diff of the changes I did
--- oldAuthClass.ts 2025-05-07 18:11:43
+++ authClass.ts 2025-05-07 18:12:53
@@ -1,5 +1,5 @@
-import { betterAuth, BetterAuthOptions } from "better-auth";
-import { jwt } from "better-auth/plugins";
+import { betterAuth, BetterAuthOptions, UnionToIntersection } from "better-auth";
+import { anonymous, jwt } from "better-auth/plugins";


const authInstance = betterAuth({
@@ -12,19 +12,28 @@
},
plugins: [jwt()],
});
+const plugins = [anonymous, jwt];

+type Plugins = typeof plugins;
+type PlugInReturnTypes = ReturnType<Plugins[number]>;
+type PluginEndpoints = UnionToIntersection<PlugInReturnTypes['endpoints']>;
+type PluginApis = {
+ api: PluginEndpoints;
+};
+
export class AuthService {
- authInstance: ReturnType<typeof betterAuth>;
+ authInstance: ReturnType<typeof betterAuth> & PluginApis;
constructor(o: BetterAuthOptions) {
this.authInstance = betterAuth({
...o,
emailAndPassword: {
enabled: true,
},
advanced: {
cookiePrefix: "pva_",
},
- plugins: [jwt()],
+ plugins: plugins.map((plugin) => plugin())
});
}

--- oldAuthClass.ts 2025-05-07 18:11:43
+++ authClass.ts 2025-05-07 18:12:53
@@ -1,5 +1,5 @@
-import { betterAuth, BetterAuthOptions } from "better-auth";
-import { jwt } from "better-auth/plugins";
+import { betterAuth, BetterAuthOptions, UnionToIntersection } from "better-auth";
+import { anonymous, jwt } from "better-auth/plugins";


const authInstance = betterAuth({
@@ -12,19 +12,28 @@
},
plugins: [jwt()],
});
+const plugins = [anonymous, jwt];

+type Plugins = typeof plugins;
+type PlugInReturnTypes = ReturnType<Plugins[number]>;
+type PluginEndpoints = UnionToIntersection<PlugInReturnTypes['endpoints']>;
+type PluginApis = {
+ api: PluginEndpoints;
+};
+
export class AuthService {
- authInstance: ReturnType<typeof betterAuth>;
+ authInstance: ReturnType<typeof betterAuth> & PluginApis;
constructor(o: BetterAuthOptions) {
this.authInstance = betterAuth({
...o,
emailAndPassword: {
enabled: true,
},
advanced: {
cookiePrefix: "pva_",
},
- plugins: [jwt()],
+ plugins: plugins.map((plugin) => plugin())
});
}

The interesting part would be this
const plugins = [anonymous, jwt];

type Plugins = typeof plugins;
type PlugInReturnTypes = ReturnType<Plugins[number]>;
type PluginEndpoints = UnionToIntersection<PlugInReturnTypes['endpoints']>;
type PluginApis = {
api: PluginEndpoints;
};
const plugins = [anonymous, jwt];

type Plugins = typeof plugins;
type PlugInReturnTypes = ReturnType<Plugins[number]>;
type PluginEndpoints = UnionToIntersection<PlugInReturnTypes['endpoints']>;
type PluginApis = {
api: PluginEndpoints;
};
Have fun 😉

Did you find this page helpful?