问题
I'm working with Typescript and Vue, but I hope that my framework doesn't matter.
I'm trying to extend Array like that:
class AudioArray extends Array<[number, number]> {
constructor(size: number) {
super(size);
}
static fromArray(array: Array<number>): AudioArray {
return array.map((v, i) => [i, v]) as AudioArray;
}
addNumber(num: number): AudioArray {
return this.map((x: [number, number]) => [x[0], x[1] + num]) as AudioArray;
}
}
export default AudioArray;
and I'm importing it into my component:
<script lang="ts">
import AudioArray from '@/utils/audioarray'
someFunction() {
const normalArray = [0,1,2,3,4];
const audioValues = AudioArray.fromArray(normalArray);
const audioValues2 = audioValues.addNumber(2);
}
My static function fromArray
works very well, but I have such a message:
"TypeError: audioValues.addNumber is not a function"
I've logged AudioArray
and audioValues
to console and here's the result
回答1:
The problem is how you create instances of AudioArray:
static fromArray(array: Array<number>): AudioArray {
return array.map((v, i) => [i, v]) as AudioArray;
}
The fact that you use as
cast to silence the compiler does not make the result of array.map
an instance of AudioArray
(that is, does not set prototype chain). You need to use a proper constructor to do that.
class AudioArray extends Array<[number, number]> {
constructor(size: number) {
super(size);
}
static fromArray(array: Array<number>): AudioArray {
const ret = new AudioArray(0);
ret.push(...array.map((v, i) => AudioArray.toRecord(i, v)));
return ret;
}
static toRecord(a1: number, a2: number): [number, number] {
return [a1, a2];
}
addNumber(num: number): AudioArray {
const ret = new AudioArray(0);
ret.push(...this.map((x: [number, number]) => AudioArray.toRecord(x[0], x[1] + num));
return ret;
}
}
More generally, extending Array to add methods is questionable design, think if you can achieve your goal using composition.
来源:https://stackoverflow.com/questions/60892542/typescript-class-extending-array-cant-assign-method