I'm looking to implement an external array-like interface called ListOf<T>. It has properties like length, indexed access, and a forEach method that takes a callback function. Here's how it looks:
interface ListOf<T> {
readonly length: number;
readonly [index: number]: T;
item(index: number): T | null;
forEach(callback: (value: T, key: number, parent: ListOf<T>) => void, thisArg?: any): void;
}
To implement this interface, I decided to extend the Array class with my SimpleList<T> class:
export class SimpleList<T> extends Array<T> implements ListOf<T> {
constructor(arrayLength: number) {
super(arrayLength);
}
item(index: number): T | null {
return this[index] || null;
}
}
However, I encountered an error:
Error TS2420: Class 'SimpleList' incorrectly implements interface 'ListOf'.
Types of property 'forEach' are incompatible.
...
Property 'item' is missing in type 'T[]' but required in type 'ListOf'
To fix this, I had to add a custom implementation for the forEach method:
// class SimpleList<T>
forEach(callback: (value: T, key: number, parent: SimpleList<T>) => void, thisArg?: any): void {
super.forEach(callback, thisArg);
}
While this solution works, it feels redundant as I am basically just calling the superclass method. Is there a way to make TypeScript recognize that the original Array method already matches the interface signature without having to override it?
On another note, I believe the Array class should have declared its forEach method with a more specific parameter type:
forEach(callbackfn: (value: T, index: number, array: /*originally T[]*/ this) => void, thisArg?: any): void;
This change could potentially lead to a cleaner solution. Any insights on this matter would be greatly appreciated.