interface Stack<T> {
push(...items: T[]): void
pop(): T | undefined
clear(): T[]
}
interface CloneableStack {
new <V>(...args: any[]): Stack<V>
// this static method should remove all function objects from the stack
clone<T>(original_stack: Stack<T>): Stack<Exclude<T, Function>>
}
const stack_class_alias = class MyStack<T> implements StaticImplements<CloneableStack, typeof MyStack> {
arr: T[]
constructor(first_item?: T) {
this.arr = first_item === undefined ? [] : [first_item]
}
push(...items: T[]): void { this.arr.push(...items) }
pop(): T | undefined { return this.arr.pop() }
clear(): T[] { return this.arr.splice(0) }
static clone<V>(some_stack: Stack<V>) {
const arr_no_func = (some_stack as MyStack<V>).arr.filter((v) => typeof v !== "function") as Array<Exclude<V, Function>>
const new_stack = new this<Exclude<V, Function>>()
new_stack.push(...arr_no_func)
return new_stack
}
}
allows one to declare static interface
CONSTRUCTOR
that must be implemented by a classCLASS
it is important that your
CONSTRUCTOR
static interface must contain a constructor method in it. although, that constructor could be super generalized too, despite the other static methods being narrowly defined, like:to use this utility type, you must provide the static interface as the first parameter, and then
typeof CLASS_NAME
(which is the name of the class itself) as the second parameter.