A have an external array-like interface I want to implement
interface ListOf<T> {
readonly length: number;
readonly [index: number]: T;
item(index: number): T | null;
// note the parent parameter and its type
forEach(callback: (value: T, key: number, parent: ListOf<T>) => void, thisArg?: any): void;
}
The interface looks very similar to normal array, so for implementation I choose to extend the Array
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;
}
}
But it fails
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’
The error can easily be fixed by adding forEach
with compatible signature:
// class SimpleList<T>
forEach(callback: (value: T, key: number, parent: SimpleList<T>) => void, thisArg?: any): void {
super.forEach(callback, thisArg);
}
But for me it looks really awkward – I just call super
here, nothing changed at all, basically original method can do the same thing.
How can I tell typescript that original method with its signature actually matches the new one from the interface? I don’t want an extra method that just re-declares one of superclass.
Beside the question I have a feeling that original Array
should have declared its forEach
as
forEach(callbackfn: (value: T, index: number, array: /*originally T[]*/ this) => void, thisArg?: any): void;
Not sure if its helpful but might lead to some solution.