[英]Typescript Interface With Multiple Dynamic Keys
我有一個查詢 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
,規則需要是或{$eq: string}
或{$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
用於數字以外的任何內容。
我想做的是讓 IFilter 允許多個屬性
IFilter
是一種具有string
索引簽名的類型,並且已經允許具有string
名稱類型和IKeyValue
值類型的多個屬性。 只是 IDE/編譯器不能協助自動完成,因為它不知道,由於可以添加屬性的動態方式,里面是什么。
例如,您的代碼甚至對未知的屬性名稱也有效:
const filterValue = filter["helloWorld"] // IKeyValue
const keyValue = filter["hello"]["World"] // any
我不確定,這里最好的解決方案是什么。 如果IFilter
有一組修復(可能是可選的)屬性名稱,例如Name
或Age
,則可以創建具有索引簽名和已知屬性的混合類型:
export interface IFilter {
[property: string]: IKeyValue | undefined;
Name?: IKeyValue;
Age?: IKeyValue;
}
const filter : IFilter = {
"Name": { $eq: "Bob" } // code assist for Name/Age properties
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.