Skip to content

Type-Safe Roles

@weconjs/lib supports TypeScript generics for type-safe role autocomplete in your IDE.

The easiest way to enable type-safe roles across your entire project is to override the global Wecon.Roles type.

Step 1: Create a Declaration File

Create a wecon.d.ts file in your project's src directory:

typescript
// src/wecon.d.ts
declare global {
  namespace Wecon {
    type Roles = 'admin' | 'user' | 'moderator' | 'guest';
  }
}

export {};

IMPORTANT

The export {} at the end is required to make this a module file.

Step 2: Use Routes Without Generics

Now all Route and Routes automatically use your custom roles:

typescript
import { Route, Routes, Wecon } from '@weconjs/lib';

// Autocomplete works automatically - no generics needed!
const userRoutes = new Routes({
  prefix: '/users',
  routes: [
    new Route({
      method: 'GET',
      path: '/',
      rai: 'users:list',
      roles: ['admin', 'user'],  // ✓ Suggests 'admin' | 'user' | 'moderator' | 'guest'
      middlewares: [getUsersHandler],
    }),
    new Route({
      method: 'DELETE',
      path: '/:id',
      rai: 'users:delete',
      roles: ['admin'],  // ✓ TypeScript enforces valid roles
      middlewares: [deleteUserHandler],
    }),
  ],
});

const wecon = new Wecon()
  .roles(['admin', 'user', 'moderator', 'guest'])
  .routes(userRoutes)
  .build();

Explicit Generics (Alternative)

If you prefer explicit typing or need different roles in different parts of your app:

typescript
type AppRoles = 'admin' | 'user' | 'guest';

const route = new Route<AppRoles>({
  method: 'GET',
  path: '/users',
  rai: 'users:list',
  roles: ['admin'],  // ✓ Autocomplete works
  middlewares: [handler],
});

const routes = new Routes<AppRoles>({
  prefix: '/api',
  routes: [route],
});

Backward Compatibility

Without global override or explicit generics, roles accepts any string[]:

typescript
// No type safety, but still works
const route = new Route({
  roles: ['anything'],  // Any string allowed
  // ...
});

Best Practices

  1. Use global override for consistent type safety across your project
  2. Keep roles in sync between your wecon.d.ts and Wecon.roles() call
  3. Add the declaration file early in your project setup

Released under the MIT License.