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.
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:
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:
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
- Why authClient.multiSession is Not Recognized
- Step-by-Step Fix: Intersection Types for Plugin Recognition
- tsconfig.json Tweaks for Better Auth Type Safety
- Official Better Auth Client and Plugin Patterns
- Pitfalls, Runtime vs. Build Quirks, and Alternatives
- Testing Your Vue TypeScript Fix
- Sources
- Conclusion
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.
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:
// 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.
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.
type AuthClientWithPlugins = AuthClient & MultiSessionClient & OrganizationClient;
Step 3: Cast and export.
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.
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:
{
"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.
// 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
AuthClientinterface 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:
- IntelliSense: Type
authClient.multi—seemultiSession? Check. - Lint:
npm run lint—clean? Good. - Build:
npm run build—no TS errors? Ship it. - Runtime: Load sessions—data flows? Perfect.
- 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
- Better Auth Client Documentation — Official guide for Vue client setup and plugin integration: https://www.better-auth.com/docs/concepts/client
- Better Auth TypeScript Concepts — Recommendations for strict mode and type inference like $Infer: https://www.better-auth.com/docs/concepts/typescript
- Better Auth Multi-Session Plugin — Details on client methods like listDeviceSessions and configuration: https://www.better-auth.com/docs/plugins/multi-session
- Better Auth GitHub Repository — Examples of intersection type casting for plugin clients: https://github.com/better-auth/better-auth
- Better Auth GitHub Issue 5159 — Discussion on plugin type inference gaps in strict TypeScript: https://github.com/better-auth/better-auth/issues/5159
- 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.