Consider the following code:
interface classAOptions {
optionA?: string
}
abstract class Base<TOptions extends classAOptions = classAOptions> {
protected options: TOptions;
constructor(options: TOptions) {
this.options = options;
}
updateOptions(options: Partial<TOptions>) {}
}
interface classBOptions extends classAOptions {
optionB?: string
}
class Extending<TOptions extends classBOptions = classBOptions> extends Base<TOptions> {
constructor(options: TOptions) {
super(options);
}
}
const bInstance = new Extending({
optionB: 'test'
});
/** Why can't I see "optionA" here? */
bInstance.updateOptions({
optionA: 'something else'
});
The problem is, that if I create a class
with a generic option method, to have the possibility, to expand it further, typescript somehow infers the generic on instantiation, and forgets about the rules I set.
In the above situation, typescript, somehow, infers that my bInstance
, is a type of Extending
with the generic set to an object which only defines the optionB
property. Because of this, later on, when I try to use the updateOptions
method, inherited from the abstract Base
class, the input parameter only accepts the optionB
parameter.
How could I achieve, the following things:
- when I use the
updateOptions
method from thebInstance
, I would like to allow the usage of both theclassAOptions
andclassBOptions
interface - in other words, I would like to be able to set theoptionA
property, even though it was not set at instantiaton - I would like to achieve this, without having to extend the
updateOptions
function inExtending
class
Is this possible somehow?
Here's a playground link.
CodePudding user response:
You just have to specify the generic parameter when instantiating:
const bInstance = new Extending<classBOptions>({
optionB: 'test'
});
/** Why can't I see "optionA" here? */
bInstance.updateOptions({
optionA: 'something else'
});
CodePudding user response:
You could also change the definition of updateOptions
:
updateOptions(options: Partial<TOptions & classAOptions>) {}