简体   繁体   English

typescript 中泛型类型的严格输入问题

[英]Strict typing issue with generic types in typescript

I am trying to learn strict typing in Typescript.我正在尝试在 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'."问题是我收到错误“Class 'MyClass' 错误地扩展了基础 class 'MyAbstractClass'。类型具有私有属性 'param' 的单独声明。”

I don't understand why I get this error because AParamType type correctly extends MyParamBaseType我不明白为什么会出现此错误,因为 AParamType 类型正确扩展了 MyParamBaseType

Can somebody helps me?有人可以帮助我吗? Thanks for your help.谢谢你的帮助。

The private keyword is just a compile time checked. private关键字只是编译时检查的。 This means that the field param will be stored at runtime in the instance of the class.这意味着字段param将在运行时存储在 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. MyAbstractClass声明它是私有成员,因此如果允许MyClass重新声明param字段,它将最终在运行时访问实例中名为param的相同字段,从而破坏隐私。

You can use the ES private class fields (with # ).您可以使用 ES 私有 class 字段(带有# )。 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:这些即使在运行时也能确保硬隐私,并且子 class 中的名称冲突不是问题,因为每个声明的字段都是不同的,即使它们共享相同的名称:

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;

}

Playground Link 游乐场链接

Or if you want to access the same field from the base class you might consider protected instead:或者,如果您想从基础 class 访问相同的字段,您可能会考虑改为protected

 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;

}

Playground Link 游乐场链接

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM