无法键入从抽象类泛型方法(TypeScript)扩展而来的类方法

无法键入从抽象类泛型方法(TypeScript)扩展而来的类方法,typescript,generics,interface,abstract-class,Typescript,Generics,Interface,Abstract Class,所以我有一个抽象类,它实现了一个接口: 导出默认接口职责chainHandler{ setNext(处理程序:ResponsibilityChainHandler):ResponsibilityChainHandler 处理(请求:T):承诺 } 从“./responsibility chain.handler.interface”导入responsibility chainHandler 导出默认抽象类AbstractResponsibilityChainHandler 执行职责ChainH

所以我有一个抽象类,它实现了一个接口:

导出默认接口职责chainHandler{
setNext(处理程序:ResponsibilityChainHandler):ResponsibilityChainHandler
处理(请求:T):承诺
}
从“./responsibility chain.handler.interface”导入responsibility chainHandler
导出默认抽象类AbstractResponsibilityChainHandler
执行职责ChainHandler{
私人nextHandler?:负责Chainhandler
公共setNext(处理程序:ResponsibilityChainHandler):ResponsibilityChainHandler{
this.nextHandler=handler
把这个还给我
}
公共异步句柄(请求:T):承诺{
如果(此.nextHandler){
返回此.nextHandler.handle(请求)
}
退货申请
}
}
现在,我想定义一个新类,它只接受类型为
GreetingHandlerRequest
(定义为类)的特定对象

从“../../domain/responsibility chainHandler.handler.abstract”导入AbstractResponsibilityChainHandler
从“../../domain/greeting handler request.domain”导入GreetingHandler请求;
导出默认类WelcomeHandler扩展AbstractResponsibilityChainHandler{
公共异步句柄(
请求:GreetingHandlerRequest
):承诺{
返回超级句柄(请求)
}
}
但是,我在
GreetingHandlerRequest
导入时遇到以下错误:

'GreetingHandlerRequest' is declared but its value is never read.
如果我尝试在方法内部执行类似于
request.existingAttr
的操作,它会抱怨:

Property 'existingAttr' does not exist on type 'GreetingHandlerRequest'.
但是类
GreetingHandlerRequest
有一个可公开访问的属性,名为
existingAttr


我还尝试了导入类型,但没有成功。我被这件事困扰了一段时间。问一些朋友和谷歌搜索对我来说没有效果。有什么想法吗?

类型脚本中有两种截然不同的类型:泛型函数和泛型类型


泛型函数在函数的调用签名上声明其泛型类型参数,如此处的
handle
方法:

interface RCHGenFunc {
  handle<T>(request: T): Promise<T>
}
必须先指定泛型类型(
T
)上的类型参数,然后才能获得该类型的值。如果泛型类型具有引用类型参数的方法(如上面的
handle()
),则在调用该方法之前,只要指定了周围的泛型类型,该类型参数就会被修复。比如说,一旦您谈到一个
RCHGenType
,那么它的
handle()
方法只需要能够处理一个
GreetingHandlerRequest
。因此,要实现该函数,不需要处理
T
的任何可能值


当使用泛型方法的特定类型与使用特定方法的泛型类型相反时,这种区别可能会有点模糊。重要的部分是泛型的范围。如果我在类型系统中使用泛型并与JavaScript中的函数进行类比,区别在于(以下是JS,不一定是TS):

这意味着
AbstractResponsibilityChainHandler
也应该是通用的:

abstract class AbstractResponsibilityChainHandler<T>
  implements ResponsibilityChainHandler<T> {
  private nextHandler?: ResponsibilityChainHandler<T>

  public setNext(handler: ResponsibilityChainHandler<T>): ResponsibilityChainHandler<T> {
    this.nextHandler = handler
    return this.nextHandler
  }

  public async handle(request: T): Promise<T> {
    if (this.nextHandler) {
      return this.nextHandler.handle(request)
    }
    return request
  }
}
然后,
WeclomeHandler
可以如下所示:

interface GreetingHandlerRequest {
  existingAttr: string;
}
class WelcomeHandler extends AbstractResponsibilityChainHandler<GreetingHandlerRequest> {
  public async handle(request: GreetingHandlerRequest): Promise<GreetingHandlerRequest> {
    request.existingAttr.toUpperCase();
    return super.handle(request)
  }
}
类WelcomeHandler扩展AbstractResponsibilityChainHandler{
公共异步句柄(请求:GreetingHandlerRequest):承诺{
request.existingAttr.toUpperCase();
返回超级句柄(请求)
}
}
在这里,
WelcomeHandler
本身不是泛型类。它是通过扩展
AbstractResponsibilityChainHandler
得到的一个特定类,这是通过插入
AbstractResponsibilityChainHandler
中的特定
GreetingHandlerRequest
类型作为类型参数
T
得到的一个特定类型

现在,
WelcomeHandler
handle()
方法只接受
GreetingHandlerRequest
参数。您不必将其设置为泛型(其声明中没有类型参数),并且由于此限制,您可以在实现内部访问
GreetingHandlerRequest
的特定属性


如果您说确实希望
handle()
成为通用方法并处理任何可能的请求类型,那么我们必须要么放弃类层次结构(因为
WelcomeHandler
不能正确地
handle()
所有请求),或者,我们必须让它接受所有请求,但在内部进行某种运行时检查,这样它就不会执行任何操作,除非它得到正确的请求类型。但这不是你想要的(谢天谢地),所以上面的解决方案可能正适合你


类型脚本中有两种截然不同的类型:泛型函数和泛型类型


泛型函数在函数的调用签名上声明其泛型类型参数,如此处的
handle
方法:

interface RCHGenFunc {
  handle<T>(request: T): Promise<T>
}
必须先指定泛型类型(
T
)上的类型参数,然后才能获得该类型的值。如果泛型类型具有引用类型参数的方法(如上面的
handle()
),则在调用该方法之前,只要指定了周围的泛型类型,该类型参数就会被修复。比如说,一旦您谈到一个
RCHGenType
,那么它的
handle()
方法只需要能够处理一个
GreetingHandlerRequest
。因此,要实现该函数,不需要处理
T
的任何可能值


当使用泛型方法的特定类型与使用特定方法的泛型类型相反时,这种区别可能会有点模糊。重要的部分是泛型的范围。如果我在类型系统中使用泛型并与JavaScript中的函数进行类比,那么
interface GreetingHandlerRequest {
  existingAttr: string;
}
class WelcomeHandler extends AbstractResponsibilityChainHandler<GreetingHandlerRequest> {
  public async handle(request: GreetingHandlerRequest): Promise<GreetingHandlerRequest> {
    request.existingAttr.toUpperCase();
    return super.handle(request)
  }
}