我的目标是创建一个类型界面,该界面具有其名称在其他接口中定义的属性。
我在打字稿中具有以下模型架构对象的定义。
export interface ModelSchema {
idAttribute: string;
name: string;
attributes: {
[attrName: string]:
{ type: 'number', default?: number, readOnly?: boolean} |
{ type: 'string', default?: string, readOnly?: boolean} |
{ type: 'boolean', default?: boolean, readOnly?: boolean} |
{ type: 'date', default?: Date, readOnly?: boolean} |
{ type: 'array', default?: string[] | number[], readOnly?: boolean } |
{ type: 'object', default?: object, readOnly?: boolean}
};
relationships: {
[relName: string]: {
type: RelationshipSchema,
readOnly?: boolean,
},
};
};
我们在这里讨论的关键是关系属性。它可以具有多数属性,每个属性都带有一个字符串名称("孩子","答复"等(,并且每个名称都代表DataModel中的Has-andy关系。
我想为批准者定义一个单独的容器 - 服务器可以要求"该用户允许使用C/r/u/d,该项目/关系?"结构是平行的,由于每个关系都有不同的规则,因此每个关系都有其自己的批准方法。
所以,理想情况下,我会说
export interface ApproverDefinition<S extends ModelSchema> {
typeName: string,
attributes: AttributesAuthorize,
relationships: {
[name: string]: RelationshipAuthorize,
}
}
,但基本上有一个单独的警卫,基本上说:" crandverdefinition的字符串索引属性。相关验证需要与s的关系属性的名称相同,该名称是与S的关系属性,该属性属性相同,该模型chema通常与。<<<<<<<<<</p>
类似(伪代码在这里(:
export interface ApproverDefinition<S extends ModelSchema> {
typeName: string,
attributes: AttributesAuthorize,
relationships: {
[name in keyof S.relationships]: RelationshipAuthorize,
}
}
上述几乎有效(除了它不需要完整的覆盖范围,但我会忍受它( - 我觉得它解释了我想做什么,但是我从TS中遇到了两个错误。首先,我要导出界面上的私人名称,其次是我将S作为名称空间对待。
我需要/想要保持批准器代码与架构代码不同的原因有很多,因此仅扩展ModelsChema并不可行。
我可以进行运行时类型检查,如果我基本上检查以确保object.keys.keys(anderver.Realationships(和object.keys.keys(model.Realationships(具有相同的条目,但我有点想在打字稿语言。
完全可以做这样的事情吗?
编辑:这是一个示例模型架构:
const ProfileSchema = {
idAttribute: 'id',
name: 'profiles',
attributes: {
id: { type: 'number', readOnly: true },
short_text: { type: 'string', readOnly: false },
long_text: { type: 'string', readOnly: true },
// SNIP ...
},
relationships: {
memberships: { type: Memberships, readOnly: false },
conversations: { type: ProfilePermissions, readOnly: false },
followingProfiles: { type: FollowingProfiles, readOnly: false},
followingDocuments: { type: FollowingDocuments, readOnly: false},
followingCommunities: { type: FollowingCommunities, readOnly: false},
followers: { type: FollowingProfiles, readOnly: false},
},
};
我想定义
const ProfileApprover: ApproverDefinition<ProfileSchema> = {
typeName: 'profiles'
attributes: /* attribute approver */
relationships: {
memberships: /* approver function */,
conversations: /* approver function */,
followingProfiles: /* approver function */,
followingDocuments: /* approver function */,
followingCommunities: /* approver function */,
followers: /* approver function */,
}
}
请注意,profileapprover.ysyationships具有与proileschema.syphiphips相同的属性,但是这些属性具有不同的值。这是我想在类型规则中指定的内容 - 所有批准者实例与其相应的架构匹配。
如果他们不存在,我总是可以在注册批准者时丢下运行时错误,但这感觉就像我应该能够静态定义为Typescript。
如果我正确理解您,您想要的就是这样
首先,我们将Modelshema的关系属性的类型提取到接口中,以便我们可以独立参考
export interface Relationships {
[relName: string]: {
type: RelationshipSchema,
readOnly?: boolean,
},
}
我们在ModelsChema中使用此接口代替上一个对象字体类型
export interface ModelSchema {
idAttribute: string;
name: string;
attributes: {
[attrName: string]:
{type: 'number', default?: number, readOnly?: boolean} |
{type: 'string', default?: string, readOnly?: boolean} |
{type: 'boolean', default?: boolean, readOnly?: boolean} |
{type: 'date', default?: Date, readOnly?: boolean} |
{type: 'array', default?: string[] | number[], readOnly?: boolean} |
{type: 'object', default?: object, readOnly?: boolean}
};
retationships: Relationships;
}
由于ARENVERDEFINITION仅引用模型Chema的关系属性,因此我们可以将其现有类型用作我们的约束。这使我们可以访问与KEYOF
一起使用的键export interface ApproverDefinition<R extends Relationships> {
typeName: string;
attributes: AttributesAuthorize;
relationships: {
[name in keyof R]: RelationshipAuthorize
}
}
const ProfileSchema = {
idAttribute: 'id',
name: 'profiles',
attributes: {
id: {type: 'number', readOnly: true},
short_text: {type: 'string', readOnly: false},
long_text: {type: 'string', readOnly: true},
// SNIP ...
},
relationships: {
memberships: {type: Memberships, readOnly: false},
conversations: {type: ProfilePermissions, readOnly: false},
followingProfiles: {type: FollowingProfiles, readOnly: false},
followingDocuments: {type: FollowingDocuments, readOnly: false},
followingCommunities: {type: FollowingCommunities, readOnly: false},
followers: {type: FollowingProfiles, readOnly: false},
},
};
最后,由于proileschema是一种值,而不是类型,因此我们需要在其关系属性上使用类型,并将结果用作类型参数来批准
const ProfileApprover: ApproverDefinition<typeof ProfileSchema.relationships> = {
typeName: 'profiles',
attributes: {}, /* attribute approver */
relationships: {
// all of these are now required by the type
memberships: /* approver function */,
conversations: /* approver function */,
followingProfiles: /* approver function */,
followingDocuments: /* approver function */,
followingCommunities: /* approver function */,
followers: /* approver function */,
}
};