I am trying to learn strict typing in Typescript.
I defined these classes:
export abstract class MyAbstractClass<TParam extends MyParamBaseType> {
private param: TParam;
setInitParams(init: TParam): void {
...
}
getInitParams(): TParam {
....
}
}
export class MyClass extends MyAbstractClass<AParamType> {
private param: AParamType;
...
}
The problem is that I get the error " Class 'MyClass' incorrectly extends base class 'MyAbstractClass'. Types have separate declarations of a private property 'param'."
I don't understand why I get this error because AParamType type correctly extends MyParamBaseType
Can somebody helps me ? Thanks for your help.
CodePudding user response:
The private
keyword is just a compile time checked. This means that the field param
will be stored at runtime in the instance of the class. MyAbstractClass
declares it's member private, so if MyClass
were allowed to redeclare the param
field it would end up accessing the same field named param
in the instance at runtime breaking privacy.
You can use the ES private class fields (with #
). These ensure hard privacy even at runtime and name collisions in the sub class are not an issue since each declared field is distinct even if they share the same name:
type MyParamBaseType = {}
export abstract class MyAbstractClass<TParam extends MyParamBaseType> {
#param!: TParam;
setInitParams(init: TParam): void {
}
getInitParams(): TParam {
return this.#param;
}
}
type AParamType = {}
export class MyClass extends MyAbstractClass<AParamType> {
#param!: AParamType;
}
Or if you want to access the same field from the base class you might consider protected
instead:
type MyParamBaseType = {}
export abstract class MyAbstractClass<TParam extends MyParamBaseType> {
protected param!: TParam;
setInitParams(init: TParam): void {
}
getInitParams(): TParam {
return this.param
}
}
type AParamType = {}
export class MyClass extends MyAbstractClass<AParamType> {
protected param!: AParamType;
}