类型接口引用不同类型的结构?



我的目标是创建一个类型界面,该界面具有其名称在其他接口中定义的属性。

我在打字稿中具有以下模型架构对象的定义。

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 */,
  }
};

最新更新