Skip to content

Instantly share code, notes, and snippets.

@andantonyan
Created August 30, 2022 22:12
Show Gist options
  • Save andantonyan/79f95cb6f9308eb732dd5fde867417ab to your computer and use it in GitHub Desktop.
Save andantonyan/79f95cb6f9308eb732dd5fde867417ab to your computer and use it in GitHub Desktop.
PermissionService with auto generated methods based on Permission type using Proxy
class PermissionService extends (class {} as new () => Proxy) {
constructor() {
super();
return this.createProxy();
}
private static camelCaseToUpperCase(key: string): string {
return key
.replace(/([A-Z])/g, ' $1')
.split(' ')
.join('_')
.toUpperCase();
}
flush(): void {
console.log('Flushing permissions');
}
private addPermission(permission: Permission | Set<Permission>): void {
if (typeof permission === 'string') {
console.log('Adding single permission', permission);
} else {
console.log('Adding multiple permissions', permission);
}
}
private hasPermission(permission: Permission): boolean {
console.log('Checking permission', permission);
return true;
}
private createProxy(): typeof this {
return new Proxy(this, {
get: (target, prop: string) => {
if (prop in target) {
return target[prop as keyof this];
}
return () => {
let permission = PermissionService.camelCaseToUpperCase(prop);
permission = permission.slice(4); // remove [CAN_] prefix;
return this.hasPermission(permission as Permission);
};
},
});
}
}
type UpperCaseToCamelCase<S extends string> = S extends `${infer T}_${infer U}`
? `${Lowercase<T>}${Capitalize<UpperCaseToCamelCase<U>>}`
: Capitalize<Lowercase<S>>;
type UserModificationPermission =
| 'CREATE_USER'
| 'DELETE_USER';
type Permission = 'USE_ADMIN' | UserModificationPermission;
type ProxyMethod<S extends string> = `can${Capitalize<UpperCaseToCamelCase<S>>}`;
type Proxy = {
[key in ProxyMethod<Permission>]: () => boolean;
};
function main(): void {
const permissionService = new PermissionService();
if (permissionService.canCreateUser()) {
console.log('Creating a user');
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment