I have created a class which has 2 properties storing arrays of tuples with numbers. I also have created a method "getIndex" that accesses those properties dynamically and then checks whether there is a tuple containing identical numbers. The function looks like this:
getIndex(posX: number, posY: number, pathArr: string) {
for (let routeCoordinates of this[pathArr]) {
if (routeCoordinates[0] === posX && routeCoordinates[1] === posY) {
return this[pathArr].indexOf(routeCoordinates);
}
}
}
The problem is that whenever I try to pass pathArr as a key I get the following error message:
"Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'PathfinderSecondStage'. No index signature with a parameter of type 'string' was found on type 'PathfinderSecondStage'."
I know about generics but solutions I found on the internet do not work as I am dealing with a class instance. Is there a solution that keeps typechecking?
CodePudding user response:
Without the full code it is impossible to know what this[]
refers to, but you can allow a Typescript array to be indexed with strings by declaring it as let ARRAY: { [key: string]: DTYPE; } = {};
where ARRAY is your array name and DTYPE is the data type you are storing.
CodePudding user response:
The immediate solution is pretty simple. All you need to do is change pathArr: string
parameter to pathArr: keyof PathfinderSecondStage
which will cause TypeScript to create a union type of all the public fields/methods within the class and then extract the this[pathArr]
statement and assign it into a variable with the assistance of type assertion to tell it the exact type that is going to be used:
getIndex(posX: number, posY: number, pathArr: string) {
const myArray = this[pathArr] as number[][];
for (let routeCoordinates of myArray) {
if (routeCoordinates[0] === posX && routeCoordinates[1] === posY) {
return myArray.indexOf(routeCoordinates);
}
}
}
You can additionally narrow down the allowed variables for the pathArr
parameter by specifically defining the names of the fields that contain the arrays which can be traversed within the function as below:
getIndex(posX: number, posY: number, pathArr: 'fieldName1'|'fieldName2') {
This will narrow down the number of types TypeScript needs to create a union type with, and if they are all arrays of numbers (number[][]
), you will not need to do the type assertion as displayed in the first example.