【发布时间】:2019-09-12 17:06:14
【问题描述】:
我想创建一个继承类的类,并为父类中不存在的所有新类属性指定索引签名。
考虑一种情况,您希望为搜索查询指定某种格式,该格式可以在字段上采用搜索词数组,并且继承自通用查询类。
class Query {
limit = 25;
offset?: number;
constructor() { /* do stuff */ }
}
class FieldSearchQuery extends Query {
[key: Exclude<string, keyof Query>]: string[]; // not valid, but captures the gist
constructor() { super(); /* do stuff */ }
}
对替代品有什么想法吗?请注意,有一个现有的基类,我的目标是缩小子类的类型,以便它可以使用不与父键相交的任何 new 键值 并且 我们应该能够对与那些未知键关联的值进行类型检查,确保它们是已定义的类型(在上面的示例中,字符串数组)。
我一直在查看 Advanced Types 文档,感觉好像我一定遗漏了什么,因为似乎存在完成此任务的所有工具。
编辑: 我只是想出了一个可能的改进,您至少可以排除父级中不存在的所有值类型:
class Query {
limit = 25;
offset?: number;
constructor() { /* do stuff */ }
}
class FieldSearchQuery extends Query {
[key: string]: Query[keyof Query]|string[]; // valid, but overly broad
constructor() { super(); /* do stuff */ }
}
【问题讨论】:
-
是否有超过 2 个类或用例是什么?这不会总是排除所有
Query键,因为它正在扩展它吗? -
这确实会排除索引签名中的所有查询键,但在类本身上需要它们。这种情况涉及从父类继承的多个类。
-
为了进一步澄清,您希望能够通过使用该类的任何内容来提供 FieldSearchQuery 所需的任何字段名称作为键,并检查那些 new 值(即不在查询中的值)始终是索引签名指定的值。使用签名
{ name: "Joe" }(获得默认值{ name: "Joe", limit: 25, constructor: fn() ...etc })的搜索应该键入错误,因为name键未解析为字符串数组) -
再澄清一点:问题是子类的索引签名与父类的签名相交。
limit = 25不是子类上索引签名[key: string]: string[]的有效键/值。
标签: typescript typescript-generics