Compiling TypeScript with filter () thisArg
I am working on an application in Node written in TypeScript and I would like to use filter()
to filter an array of objects based on an attribute. I have a public method ( getValidObjects()
) that takes an object ( preferred
) that has properties that I would like to map.
In my current setup I am using thisArg
to set the context in my callback to the preferred object.
class Sample {
_objects:Object[];
_preferred:Object;
constructor() {
this._objects = [
{
valid: true,
label: 'This is valid'
},
{
valid: false,
label: 'This is invalid'
}
];
}
public getValidObjects(preferred:Object) {
return this._objects.filter(this.filterObjects, preferred);
}
private filterObjects(sample:Object, index:number, array:Object[]) {
// "this" should be the preferred object
return this.valid == sample.valid;
}
}
export = Sample;
Ultimately the class compiles, but at the end it throws an error:
error TS2339: Property 'valid' does not exist on type 'Sample'.
It looks like the compiler is choking because it is trying to do type checking on the class with this
. I'm not sure if this is a bug tsc
, and she just doesn't know how to handle it thisArg
, or if there is another way to accomplish this.
Additional Information
- I am using typescript-require for
require
my modules; - This is not my exact implementation, but it is close enough to illustrate the problem.
TL; DR
How can I get tsc
to compile my class without throwing an error when using the parameter filter()
thisArg
?
source to share
This error occurs because you have created a class level method filterObjects()
and are using it in a different context.
TypeScript compiler does not know the intended use of this method, he decides that you are going to use it in the context of Sample
: sample.filterObjects()
.
You have at least 2 different options for fixing this error:
-
Insert
this
into the type you have in your array:private filterObjects(sample:Object, index:number, array:Object[]) { // here, Object is your type, but it can be anything else // you have to cast to <any> first, because compiler may warn you // that Sample can not be cast directly to your type return (<Object><any>this).valid == sample.valid; }
-
Move the
filterObjects()
declaration insidegetValidObjects()
:public getValidObjects(preferred:Object) { function filterObjects(sample:Object, index:number, array:Object[]) { return this.valid == sample.valid; } return this._objects.filter(filterObjects, preferred); }
I suggest the second one, it is semantically better (if filterObjects
not a Sample
method, it shouldn't be on it).
source to share