我有一个这样的类层次结构:
用户:
角色:
每个类都有一个构造函数,可以将参数转换为指定的类,例如 User 将角色转换为 Role 实例。角色将权限转换为权限实例。
示例代码:
const user = new User({
roles: [
{role_name: 'admin', permissions: {'*': '*'}}
]
})
当我使用嵌套的权限对象为用户传递 JSON 时,我收到编译器错误,因为 Permission 上有方法。 Property 'has' is missing in type '{ '*': string; }' but required in type 'Permission'.
如何避免这些问题?
编辑:
如何让 Roles 类将权限作为对象接受,以便它可以正确地将 JSON 强制转换为 Permission 类型?
// users.ts
export interface User extends BaseModel {
createdAt?: string;
updatedAt?: string;
email?: string;
username?: string;
fullname?: string;
microsoftId?: string;
roles?: UserRole[];
}
export class User {
constructor(props?: Partial<User>) {
if(!props){
props = {};
}
props.roles = props.roles?.map(role => new Role(role)) || [];
Object.assign(this, props);
}
hasPermission(service: string, perm: PermissionType){
for(let role of this.roles || []){
const has = (role.permissions as Permission).has(service, perm);
if(has){
return has;
}
}
return false;
}
}
// roles.ts
export interface Permission {
[key: string]: PermissionType[]|any;
}
export class Permission {
constructor(props: Partial<Permission>){
Object.assign(this, props);
}
has(service: keyof Permission, permName: PermissionType|undefined): boolean {
//.....
}
}
export interface Role extends BaseModel {
createdAt?: string;
updatedAt?: string;
role_name?: string;
description?: string;
scopes?: string[];
permissions: Permission;
}
export class Role {
constructor(props?: Partial<Role>) {
if(!props){
props = {};
}
props.permissions = new Permission(props.permissions || {});
if (!Array.isArray(props.scopes)) {
props.scopes = [];
}
Object.assign(this, props);
}
}
答案 0 :(得分:1)
不要将接口命名为与类相同的名称。您正在合并名称并创建一个坦率而相当尴尬的设置。有一个单独的构造函数参数接口。
export interface PlainPermission {
[key: string]: PermissionType[]|any;
}
export class Permission implements PlainPermission {
[key: string]: PermissionType[]|any;
constructor(props: Partial<PlainPermission>){
Object.assign(this, props);
}
has(service: keyof Permission, permName: PermissionType|undefined): boolean {
//.....
}
}
Role
和 User
也是如此。然后你就有了明显的区别:PlainPermission
是你传递给构造函数的“普通”Javascript 对象,而 Permission
是附加了所有漂亮、方便的方法的东西。
当您定义一个接口和一个同名的类时,它们会合并以创建一个更大的类,Permission
被定义为“任何具有接口和 em> has
方法”,这不是您想要的。
您将不得不从类中的接口中复制字段名称,但这是有道理的:接口是实现某些东西的承诺,而类是实际实现。一个是合同,另一个做合同中规定的工作。您可以使用 implements PlainPermission
作为额外检查,以确保您正确实现了接口。