I'm experimenting with Typescript, and attempting to implement a stack. The 'Stack' objects implements it's own interface, 'IStack' and extends an abstract 'Store' class.
interface IStack<T> {
capacity: number;
push(v: T): void;
pop(): T | undefined;
peek(): T | undefined;
size(): number;
}
abstract class Store<T> {
protected storage: T[] = [];
get size(): number {
return this.storage.length;
}
abstract isFull(): boolean;
}
class Stack<T> extends Store<T> implements IStack<T> {
constructor(public capacity: number = Infinity) {
super();
}
push(v: T): void {
if (this.isFull()) {
throw new Error("Maximum capacity of stack reached.");
}
this.storage.push(v);
}
pop(): T | undefined {
return this.storage.pop();
}
peek(): T | undefined {
return this.storage[this.size - 1];
}
isFull(): boolean {
return this.capacity === this.size;
}
}
let stack = new Stack<number>(4);
stack.push(1);
stack.push(2);
stack.push(3);
stack.push(4);
console.log(stack);
This code generates the following error:
Class 'Stack<T>' incorrectly implements interface 'IStack<T>'.
Types of property 'size' are incompatible.
Type 'number' is not assignable to type '() => number'.ts(2420)
As far as I can tell, there is no assignment to the size property. So I don't really understand what the error is telling me.
The easiest solution is to change the definition of the size
in the interface to be getter:
interface IStack<T> {
capacity: number;
push(v: T): void;
pop(): T | undefined;
peek(): T | undefined;
get size(): number;
}
Alternatively, you could use size
as a method, not a property:
abstract class Store<T> {
protected storage: T[] = [];
size(): number {
return this.storage.length;
}
abstract isFull(): boolean;
}
Stack:
class Stack<T> extends Store<T> implements IStack<T> {
constructor(public capacity: number = Infinity) {
super();
}
push(v: T): void {
if (this.isFull()) {
throw new Error('Maximum capacity of stack reached.');
}
this.storage.push(v);
}
pop(): T | undefined {
return this.storage.pop();
}
peek(): T | undefined {
return this.storage[this.size() - 1];
}
isFull(): boolean {
return this.capacity === this.size();
}
}