Last active
January 3, 2024 11:24
-
-
Save HighLiuk/89bd39cc0b01760bddb8a98d5a395167 to your computer and use it in GitHub Desktop.
WP Hooks with TypeScript
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
type Events = { | |
hook_1: string[]; | |
hook_2: number; | |
}; | |
const { addFilter, applyFilters } = new Filter<Events>(); | |
addFilter('hook_1', callback) | |
// ^ autocomplete on event names | |
// ^ static analysis on callback functions based on the specific event | |
function callback(list: string[]): string[] { | |
if (list.length === 0) { | |
return ['default']; | |
} | |
return list; | |
} | |
// ... | |
const list = applyFilters('hook_1', []); | |
console.log(list) | |
// ^ ['default'] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* A function type that takes a parameter of type T and returns a value of type T. | |
*/ | |
type FilterFunction<T = any> = (data: T) => T; | |
/** | |
* A class that represents a filter system. It maintains a list of filter functions for | |
* each event. E is a record of event names to their data types. | |
*/ | |
export class Filter<E extends Record<string, any>> { | |
/** | |
* A record of filter functions for each event. The keys are event names and the | |
* values are arrays of filter functions. | |
*/ | |
protected filters = {} as Record<keyof E, FilterFunction[]>; | |
public constructor() { | |
// allow destructuring of the methods | |
this.addFilter = this.addFilter.bind(this); | |
this.applyFilters = this.applyFilters.bind(this); | |
} | |
/** | |
* Adds a filter function to a specific event. | |
* | |
* @param event - The name of the event. | |
* @param cb - The filter function to add. | |
*/ | |
public addFilter<T extends keyof E>(event: T, cb: FilterFunction<E[T]>) { | |
if (!this.filters[event]) { | |
this.filters[event] = []; | |
} | |
this.filters[event].push(cb); | |
} | |
/** | |
* Applies the filter functions to the data of a specific event. If no filter | |
* functions are added to the event, the original data is returned. | |
* | |
* @param event - The name of the event. | |
* @param data - The data to apply the filter functions to. | |
* @returns The data after applying the filter functions. | |
*/ | |
public applyFilters<T extends keyof E>(event: T, data: E[T]): E[T] { | |
if (!this.filters[event]) { | |
return data; | |
} | |
return this.filters[event].reduce((value, cb) => cb(value), data); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment