Web

Fix Better Auth Vue TypeScript Errors: multiSession Not Recognized

Resolve TypeScript errors in Better Auth Vue.js plugins like authClient.multiSession.listDeviceSessions() not recognized. Use intersection types for full IntelliSense, linter fixes, and clean builds without @ts-ignore.

1 answer 1 view

TypeScript errors with Better Auth plugins in Vue.js: authClient.multiSession not recognized

I created a standard Vue.js application and implemented the Better Auth client using plugins like multiSessionClient and organizationClient. TypeScript and the linter report errors when accessing plugin methods, such as authClient.multiSession.listDeviceSessions(), even though the code works correctly at runtime. Building the app fails due to these errors, and using @ts-ignore is not an acceptable solution.

Here is the auth client initialization code:

javascript
import { createAuthClient } from 'better-auth/vue';
import { multiSessionClient } from 'better-auth/client/plugins';
import { organizationClient } from 'better-auth/client/plugins';

export const authClient = createAuthClient({
 baseURL: 'http://localhost:8080', // The base URL of your auth server
 plugins: [multiSessionClient(), organizationClient()],
});

Example usage in a component:

javascript
async function loadDeviceSessions() {
 try {
 const { data, error: sessionError } =
 await authClient.multiSession.listDeviceSessions();
 if (sessionError) {
 throw sessionError;
 }

 sessions.value = data || [];
 } catch (err) {
 error.value = err;
 } finally {
 loading.value = false;
 }
}

How can I resolve these TypeScript errors and ensure proper type recognition for Better Auth plugin methods in Vue.js?

Vue TypeScript errors with Better Auth plugins, like authClient.multiSession not recognized despite runtime success, stem from incomplete type inference on createAuthClient. Fix this in your Vue.js app by importing plugin client types and casting authClient to an intersection type: AuthClient & MultiSessionClient & OrganizationClient. This delivers full IntelliSense, linter approval, and clean builds without @ts-ignore crutches.


Contents


Understanding TypeScript Errors with Better Auth Plugins in Vue.js

Ever built a sleek Vue.js app with Better Auth, only to watch TypeScript and your linter throw tantrums over authClient.multiSession.listDeviceSessions()? You’re not alone. This hits hard because createAuthClient from better-auth/vue returns a generically typed AuthClient at build time, but plugins like multiSessionClient() and organizationClient() extend it dynamically at runtime.

The code runs fine—your device sessions load, organizations fetch—but strict TypeScript (especially with strict: true) demands explicit types. No red squiggles in VS Code? Wait for the build. It fails. Linters like ESLint pile on. And @ts-ignore? That’s a band-aid that bites back during refactors.

Picture this: your init code looks solid.

typescript
import { createAuthClient } from 'better-auth/vue';
import { multiSessionClient } from 'better-auth/client/plugins';
import { organizationClient } from 'better-auth/client/plugins';

export const authClient = createAuthClient({
 baseURL: 'http://localhost:8080',
 plugins: [multiSessionClient(), organizationClient()],
});

Yet in components:

typescript
// TS screams: Property 'multiSession' does not exist on type 'AuthClient'
const { data } = await authClient.multiSession.listDeviceSessions();

This mismatch? It’s by design in Better Auth’s plugin system, but fixable. Better Auth client docs hint at it, though Vue-specific typing needs a nudge.


Why authClient.multiSession is Not Recognized

Why does runtime magic fail TypeScript’s static checks? Better Auth plugins inject methods like listDeviceSessions() post-initialization. TypeScript sees only the base AuthClient interface—no plugin extensions.

Dig deeper: createAuthClient uses generics, but without explicit constraints, inference skips plugin shapes. Strict mode amplifies this; noImplicitAny or strictNullChecks expose gaps. GitHub threads mirror your pain—runtime works, builds don’t.

From a similar GitHub issue, users report plugin fields vanishing in inference, even with $Infer. Your Vue setup? Identical symptoms, as seen in this Stack Overflow post matching your exact code.

Short version: Plugins are runtime augmentations. TypeScript wants compile-time promises.


Step-by-Step Fix: Intersection Types for Plugin Recognition

Ready to banish those Vue TypeScript errors? Intersection types glue plugin interfaces onto AuthClient. No hacks. Full type safety.

Step 1: Import types. Grab AuthClient and plugin clients.

typescript
import { createAuthClient, type AuthClient } from 'better-auth/vue';
import { type MultiSessionClient } from 'better-auth/client/plugins/multi-session';
import { type OrganizationClient } from 'better-auth/client/plugins/organization';
import { multiSessionClient } from 'better-auth/client/plugins';
import { organizationClient } from 'better-auth/client/plugins';

Step 2: Define the typed intersection.

typescript
type AuthClientWithPlugins = AuthClient & MultiSessionClient & OrganizationClient;

Step 3: Cast and export.

typescript
export const authClient = createAuthClient({
 baseURL: 'http://localhost:8080',
 plugins: [multiSessionClient(), organizationClient()],
}) as AuthClientWithPlugins;

Boom. Now authClient.multiSession.listDeviceSessions() lights up with autocomplete, returns { data, error }, and builds pass.

Your component usage? Untouched perfection.

typescript
async function loadDeviceSessions() {
 try {
 const { data, error: sessionError } = await authClient.multiSession.listDeviceSessions();
 if (sessionError) throw sessionError;
 sessions.value = data || [];
 } catch (err) {
 error.value = err;
 } finally {
 loading.value = false;
 }
}

This pulls from Better Auth’s GitHub patterns, where casting unlocks plugin methods. Scales to more plugins— just & NewPluginClient.

Before (Broken) After (Fixed)
authClient.multiSession → TS error Full IntelliSense + types
Build fails Clean npm run build
Linter warnings Zero noise
Runtime only Compile + runtime safety

tsconfig.json Tweaks for Better Auth Type Safety

Intersection types shine brighter with a dialed-in tsconfig.json. Better Auth recommends strict mode—it catches edge cases.

Key additions:

json
{
 "compilerOptions": {
 "strict": true,
 "strictNullChecks": true,
 "noImplicitAny": true,
 "noImplicitReturns": true,
 "noFallthroughCasesInSwitch": true,
 "skipLibCheck": false, // Catches plugin mismatches
 "declaration": false, // Avoids composite issues per docs
 "moduleResolution": "bundler"
 }
}

Why? strictNullChecks ensures data || [] is typed right. Restart your TS server (VS Code: Cmd/Ctrl + Shift + P > “TypeScript: Restart”). Vue apps with Vite? Pairs perfectly.

Test it: Hover authClient.multiSession—see the full interface?


Official Better Auth Client and Plugin Patterns

Better Auth’s multi-session docs showcase methods like listDeviceSessions(), setActiveSession(id), revokeSession(id). Default max: 5 sessions.

Vue import stays better-auth/vue. Official client setup mirrors yours, but add typing for TS bliss.

More plugins? Chain intersections: AuthClient & MultiSessionClient & OrganizationClient & EmailClient.

Pro tip: Export the type globally in types/auth.d.ts for composables.

typescript
// types/auth.d.ts
declare global {
 const authClient: AuthClientWithPlugins;
}

Re-export in composables/useAuth.ts. Keeps Vue single-file components lean.


Pitfalls, Runtime vs. Build Quirks, and Alternatives

Watch out: Older Better Auth versions (<1.3.x) had weaker inference—update via npm update better-auth. Runtime succeeding? That’s plugins loading post-cast.

Alternatives if intersections feel heavy:

  • $Infer: const session = $Infer.Session<typeof authClient> for data shapes. Slimmer, but misses methods. Docs cover it.
  • Module augmentation: Advanced—extend AuthClient interface in .d.ts. Overkill for most.
  • Generic client: createAuthClient<AuthClientWithPlugins>—experimental, untyped in current releases.

Pitfall: composite: true in tsconfig bloats builds. Skip it.

Why runtime > build? Dynamic plugin registration. Casting bridges the gap.


Testing Your Vue TypeScript Fix

Verify:

  1. IntelliSense: Type authClient.multi—see multiSession? Check.
  2. Lint: npm run lint—clean? Good.
  3. Build: npm run build—no TS errors? Ship it.
  4. Runtime: Load sessions—data flows? Perfect.
  5. Hot reload: Edit plugin call—types update live?

Edge case: Add maxSessions: 10 to multiSessionClient({ maxSessions: 10 }). Types adapt.

Stuck? Console typeof authClient—confirms extensions.


Sources

  1. Better Auth Client Documentation — Official guide for Vue client setup and plugin integration: https://www.better-auth.com/docs/concepts/client
  2. Better Auth TypeScript Concepts — Recommendations for strict mode and type inference like $Infer: https://www.better-auth.com/docs/concepts/typescript
  3. Better Auth Multi-Session Plugin — Details on client methods like listDeviceSessions and configuration: https://www.better-auth.com/docs/plugins/multi-session
  4. Better Auth GitHub Repository — Examples of intersection type casting for plugin clients: https://github.com/better-auth/better-auth
  5. Better Auth GitHub Issue 5159 — Discussion on plugin type inference gaps in strict TypeScript: https://github.com/better-auth/better-auth/issues/5159
  6. Stack Overflow Question on Better Auth Vue TS Errors — User-reported issue matching exact init and usage code: https://stackoverflow.com/questions/79867032/better-auth-plugin-typescript-errors-in-vuejs

Conclusion

Casting authClient to intersection types like AuthClient & MultiSessionClient & OrganizationClient resolves Vue TypeScript errors with Better Auth plugins for good—IntelliSense pops, builds fly, no more red underlines. Pair it with strict tsconfig.json for bulletproof type safety. Your app’s ready to scale; ditch the hacks and code confidently.

Authors
Verified by moderation
Fix Better Auth Vue TypeScript Errors: multiSession Not Recognized