[英]How to use dynamic object properties in TypeScript
我正在使用 TypeScript,我需要處理動態對象屬性。 我希望我能成為 TypeScript 的大師,但我不是。 我遇到的問題是,在我當前的項目中,我想讓用戶可以將他們自己的自定義界面輸入到通用界面中。
我現在工作的是以下界面
export interface Filter {
columnId: string;
searchTerm: string;
}
export interface GridState {
filters: Filter[];
}
// use it as an array of filters
const state: GridState = {
filters: [{ columnId: 'firtName', searchTerm: 'John' }]
}
然而,從上面顯示的內容來看,我想給用戶使用他自己的界面的可能性。 因此,假設他想使用field
而不是columnId
,而他將使用value
代替searchTerm
。 所以他的自定義界面將是
export interface CustomFilter {
field: string;
value: string;
}
我想提供給用戶的是這樣的東西,一個自定義結構模板
export interface FilterStruct {
propNameColumnId: string;
propNameSearchTerm: string;
}
但是我如何將這兩個連接在一起? 如何將用戶的CustomFilter
與FilterStruct
。 以下不起作用,我知道這是不正確的。
export interface GridState {
filters: FilterStruct<CustomFilter>[];
}
最終目標是用戶將能夠使用他自己的界面和他自己的屬性名稱進行輸入。 然后在我這邊,我將使用提供的動態對象屬性循環遍歷數組。
您可以使GridState
泛型並為泛型參數提供默認值。 FilterStruct
也可以繼承Array
,因此我們可以使用輔助函數向數組添加額外的屬性:
export interface FilterStruct<T> extends Array<T> {
// We make sure the property names are actually properties of T
// We make these optional you should use default values if they are undefined
// We do this to keep initialization simple in the non customized scenario, you can make them mandatory, but then you can't initialize with a simple array
propNameColumnId?: keyof T;
propNameSearchTerm?: keyof T;
}
export interface Filter {
columnId: string;
searchTerm: string;
}
export interface CustomFilter {
field: string;
value: string;
}
// T has a default value of Filter so we don't have to specify it, unless we want to customize
export interface GridState<T = Filter> {
filters: FilterStruct<T>;
}
// Helper function to create an array with the extra properties
function createFilterStruct<T>(cfg: { propNameColumnId: keyof T; propNameSearchTerm: keyof T; }, items: T[]) {
return Object.assign(items, cfg);
}
// Default we can use simple array initailization
const state: GridState = {
filters: [{ columnId: 'firtName', searchTerm: 'John' }]
}
// Custom filter, create with createFilterStruct
const stateCustom: GridState<CustomFilter> = {
filters: createFilterStruct({ propNameColumnId: 'value', propNameSearchTerm: 'field' }, [
{ value: 'firtName', field: 'John' }
])
}
//Usage
function loopThrough<T>(grid: GridState<T>){
// Provide defaults for propNameColumnId and propNameSearchTerm
let propNameColumnId = grid.filters.propNameColumnId || 'columnId' as keyof T
let propNameSearchTerm = grid.filters.propNameSearchTerm || 'searchTerm' as keyof T
// Loop throught the array normally, it is just an array
for(let filter of grid.filters){
// Access the properties
console.log(`${filter[propNameColumnId]} = ${filter[propNameSearchTerm]}`);
}
}
loopThrough(stateCustom);
loopThrough(state);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.