Since the ReadonlyArray
and like are the interfaces, they could not be extended by extend
keyword:
export class ReadonlyRowVector<ElementType> extends ReadonlyArray<ElementType> {
// ...
}
TS2689: Cannot extend an interface
ReadonlyArray
. Did you meanimplements
?
We can write:
export class ReadonlyRowVector<ElementType> extends Array<ElementType> implements ReadonlyArray<ElementType> {
// ...
}
but actually implements ReadonlyArray<ElementType>
gives nothing and all methods of mutable Array
will be available that is unacceptable.
Well, what else possible?
Maybe some manipulations with types declaration or casting?
The below code is invalid but I suppose it will be something like this:
class ReadonlyRowVector<ElementType> extends Array<ElementType> {
// ...
}
// [ INVALID CODE ]
export default ReadonlyRowVector as unknown as ReadonlyArray<ElementType>;
TS2304: Cannot find name ElementType
What’s new ReadonlyRowVector
gives in addition to ReadonlyArray
? Some new properties or methods?
I am planning to add some properties and methods to ReadonlyRowVector, but even it will be same with ReadonlyArray, it has the value because of providing the validation. From the viewpoint of the linear algebra, there are many limitations on the operations with vectors and matrices, so the checks like instance of ReadonlyRowVector
or instance of ReadonlyColumnVector
will required.
But, if you want to see the new properties or methods now, currently I am thinking the adding of fromArray
static method and getElementAt__numerationFrom1
instance method:
import {
isNaturalNumber,
Logger,
InvalidParameterValueError,
isNumber
} from "@yamato-daiwa/es-extensions";
export default class ReadonlyRowVector<ElementType> extends Array<ElementType> implements ReadonlyArray<ElementType> {
public static fromArray<ElementType>(array: ReadonlyArray<ElementType>): ReadonlyRowVector<ElementType> {
return new ReadonlyRowVector(...array);
}
public constructor(...elements: ReadonlyArray<ElementType>) {
super(...elements);
}
public getElementAt__numerationFrom1(targetElementNumber__numerationFrom1: number): ElementType {
if (!isNaturalNumber(targetElementNumber__numerationFrom1)) {
Logger.throwErrorAndLog({
errorInstance: new InvalidParameterValueError({
parameterNumber: 1,
parameterName: "targetElementNumber__numerationFrom1",
messageSpecificPart: [
"Target element number must be the natural number ",
...isNumber(targetElementNumber__numerationFrom1) ?
`while has value ${ targetElementNumber__numerationFrom1 } which is not the natural number.` :
`while has type "${ typeof targetElementNumber__numerationFrom1 }".`
].join(" ")
}),
title: InvalidParameterValueError.localization.defaultTitle,
occurrenceLocation: "RowVector.getElementAt__numerationFrom1(targetElementNumber__numerationFrom1)"
});
}
if (targetElementNumber__numerationFrom1 > this.length) {
Logger.throwErrorAndLog({
errorInstance: new InvalidParameterValueError({
parameterNumber: 1,
parameterName: "targetElementNumber__numerationFrom1",
messageSpecificPart:
`Element number ${ targetElementNumber__numerationFrom1 } (numeration from 1) requested while target ` +
`RowVector has ${ this.length } elements.`
}),
title: InvalidParameterValueError.localization.defaultTitle,
occurrenceLocation: "RowVector.getElementAt__numerationFrom1(targetElementNumber__numerationFrom1)"
});
}
return this[targetElementNumber__numerationFrom1 - 1];
}
}
10
The ReadonlyArray
is an interface, not a class. When you declare an object as a ReadonlyArray
, it is still a standard Array
. However, the ReadonlyArray
interface only exposes the non-mutating functions of the array and conceals its mutating functions.
Therefore, to extend the ReadonlyArray
interface, you must:
- Extend the underlying
Array
class with your functions. - Expose these functions by extending the
ReadonlyArray
interface. - Create an instance of the extended array and type it as your new interface.
So, try something like this:
// 1. extend the Array class
class RowVector<ElementType> extends Array<ElementType> implements ReadonlyRowVector<ElementType> {
rowVectorFunction() : ElementType {
return this[0]
}
}
// 2. expose that in the extended read-only interface
interface ReadonlyRowVector<ElementType> extends ReadonlyArray<ElementType> {
rowVectorFunction(): ElementType
}
// 3. create an instance typed as extended interface
function createReadonlyRowVector<ElementType>(items: ElementType[]): ReadonlyRowVector<ElementType> {
const rv = new RowVector(...items)
return rv
}
const rorv = createReadonlyRowVector([1, 2 ,3])
rorv.rowVectorFunction()
rorv.push(4) // error
Playground link
7