Extending the User Model
Archibald uses TypeScript generics throughout the @archibald/auth package to ensure that your user session data is type-safe across the entire stack, from the server-side providers to the client-side hooks.
Defining Your Custom User
By default, Archibald uses the DefaultUser interface. To add project-specific properties, you should extend this interface. The shop template provides an example using Zod for validation.
// shop/client/interfaces/base/user.ts
import { DefaultUserSchema } from '@archibald/auth';
import * as z from 'zod';
export const UserSchema = DefaultUserSchema.extend({
uid: z.string(),
firstName: z.string(),
lastName: z.string(),
// ... custom properties
});
export interface User extends z.infer<typeof UserSchema> {}
Using the Generic User Model
1. In the SessionClient
When creating the SessionClient, you can pass your custom interface to ensure the client is typed correctly.
import { SessionClient } from '@archibald/auth';
import { type User } from 'shop/client/interfaces/base/user';
export const sessionClient = new SessionClient<User>({
// ... config
});
2. In the AuthModule
On the server, register the AuthModule with your custom user type.
import { AuthModule } from '@archibald/auth';
import { type User } from 'shop/client/interfaces/base/user';
new AuthModule<User>({
// ... config
});
3. In Client Hooks
The hooks like useUser allow you to provide the generic type for full IntelliSense.
import { useUser } from '@archibald/auth';
import { type User } from 'shop/client/interfaces/base/user';
function UserProfile() {
const { user } = useUser<User>();
return <span>Welcome, {user?.firstName}</span>;
}
4. In Server Services
When using getSession(), provide the type to access your custom properties safely.
import { getSession } from '@archibald/auth';
import { type User } from 'shop/client/interfaces/base/user';
export class MyService {
public async doSomething() {
const { user } = getSession<User>();
if (user) {
console.log(`Processing data for ${user.firstName}`);
}
}
}