interface I {
test: (a: I) => boolean;
}
class Test implements I {
//constructor (public additional: number) {}
test (a: Test) { return false; }
}
Code works, but if we remove comment from constructor line it is not working. The error it gives is
Type 'I' is missing the following properties from type 'Test': additional
Now is this stupid or am I stupid? If Test
implements I
than it should pass as I
in test
?
How to organize this multiple inheritance type support?
CodePudding user response:
I can think of two ways to solve this. Both with some drawbacks.
The first would be to use polymorphic this
in the interface. This means the type of the parameter will be whatever the implementer is:
interface I {
test: (a: this) => boolean;
}
class Test implements I {
constructor (public additional: number) {}
test (a: Test) { return false; }
}
let o:I = new Test(1); // error
The problem with this approach is you lose assignability to the interface. This might be fine depending on your use case.
The other option is to use a method signature in your interface instead of a function signature. Method signatures are checked bivariantly (I have a video here if you want to know more about variance). This means your code will be less type safe, but you can implement the class without any issues and you don't lose assignability with the I
interface:
interface I {
test(a: I): boolean;
}
class Test implements I {
constructor (public additional: number) {}
test (a: Test) { return this.additional === a.additional; }
}
class Test2 implements I {
constructor (public additional2: number) {}
test (a: Test2) { return this.additional2 === a.additional2; }
}
let o:I = new Test(1);
o.test(new Test2(1)) // this will access additional when Test2 only has additional2