typescript - 具有多个动态键的打字稿界面
问题描述
我有一个查询 MongoDB 数据库的应用程序,但目前只能查询文档中的单个字段:
export interface IKeyValue {
[property : string] : any ;
}
export interface IFilter {
[property : string] : IKeyValue;
}
const filter : IFilter = {
"Name" : { $eq : "Bob" }
}
我想要做的是允许IFilter
允许多个属性:
const filter : IFilter = {
"Name" : { $eq : "Bob" },
"Age" : { $gte : 21 }
}
如何创建一个允许多个动态键的 Typescript 接口,而不恢复为使用object
或any
作为类型IFilter
?
解决方案
我对您的需求的理解是:
- 你有一些实体,比如说用户
- 你想创建一个通用的过滤器类型,它可以用于不同的实体
- 通用过滤器类型应该对每个实体都是类型安全的
首先让我们定义我们需要过滤的可能规则
type Rule<T> = { $eq: T } | { $gte: T } // append any other rules you need
我从您的示例中提取了两条规则 -$eq
但$gte
您|
可以添加您需要的其他规则。
其次让我们定义泛型Filter
类型
type Filter<Obj> = {
[K in keyof Obj]: Rule<Obj[K]>
}
我们的类型说 - 我应该拥有给定对象的所有键,并且对于每个键,我应该定义一个规则,该规则适用于与该属性相同的类型。所以对于财产a: string
,规则需要是 or {$eq: string}
or {$gte: string}
。
让我们看一个例子:
// example filter for the User type
type User = {
id: number;
name: string;
}
// create an instance of the filter for the User entity
const userFilter: Filter<User> = {
id: { $gte: 1 }, // rule needs to have value as number
name: {$eq: '2'} // rule needs to have value as string
}
// what if we want to filter by only part of the interface - use Pick utility type
const userFilter2: Filter<Pick<User, 'name'>> = {
name: {$eq: '2'} // only name is needed to be provided
}
类型Filter
是完全类型安全的,通过创建这种类型的实例,我们需要为这些键定义正确的键和正确的规则。
作为补充,您可以有条件地说明哪些规则适用于哪些类型。可以说$gte
仅适用于数字,但不适用于其他类型。你可以这样做:
type Rule<T> = T extends number ? { $eq: T } | { $gte: T } : { $eq: T }
上面的定义将阻止使用$gte
除数字以外的任何东西。
推荐阅读
- python - 如何在 Pandas 中生成一个新列以按成员身份分组?
- javascript - array_map():参数 #2 应该是一个数组(一对一的关系更新)
- c - c中位域的实现
- asp.net - 农场相关项目的数据模型结构
- r - 创建一个四象限 ggplot2 主题
- module - 在 Excel 上导出分组数据
- javascript - 另一个文件中函数的视觉响应
- jenkins-pipeline - 测试脚本在 Jenkins 中通过 Newman 执行时失败,而在邮递员中工作正常并且没有邮递员控制台错误出现
- c++ - 变量模板的模板特化和类型推导
- sql - 如果不需要,SQL Server 是否足够聪明,不会执行昂贵的查询?(短路)