在TypeScript中,如果方法可以更改方法链接结果类型,如何指定该类型?

在TypeScript中,如果方法可以更改方法链接结果类型,如何指定该类型?,typescript,generics,method-chaining,Typescript,Generics,Method Chaining,假设我想要实现以下行为: const x = new ChainableClass<any>(); x.get(); // -> any[] (default) x.all().get(); // -> any[] x.single().get(); // -> any x.all().single().all().get(); // -> any 但是,如果我像在single方法中那样更改TResult,则TypeScript会发出错误 src/Chain

假设我想要实现以下行为:

const x = new ChainableClass<any>();
x.get(); // -> any[] (default)
x.all().get(); // -> any[]
x.single().get(); // -> any
x.all().single().all().get(); // -> any
但是,如果我像在
single
方法中那样更改
TResult
,则TypeScript会发出错误

src/ChainableClass.ts:9:5 - error TS2322: Type 'this' is not assignable to type 'ChainableClass<TEntity, TEntity>'.
  Type 'ChainableClass<TEntity, TResult>' is not assignable to type 'ChainableClass<TEntity, TEntity>'.
    Type 'TResult' is not assignable to type 'TEntity'.
      'TEntity' could be instantiated with an arbitrary type which could be unrelated to 'TResult'.

9     return this;
      ~~~~~~~~~~~~
src/ChainableClass.ts:9:5-错误TS2322:类型“this”不可分配给类型“ChainableClass”。
类型“ChainableClass”不可分配给类型“ChainableClass”。
类型“TResult”不可分配给类型“tenty”。
“TEntity”可以用与“TResult”无关的任意类型实例化。
9.归还本文件;
~~~~~~~~~~~~
我可以通过将
this
转换为
any
来抑制它,但我觉得我错过了一些重要的东西。
我的实现根本上是错误的吗?
实现所描述的类类型安全的可能方法是什么


编辑:只有在类中有
get
方法时才会发生错误。

@HarunYilmaz没有帮助。另外:只有当我使用了
get
方法时,才会发生此错误。编译器不理解如何对
this
的类型进行变异,因此您必须使用类型断言(您称之为“casting”)来说服编译器这是可以的,并且您需要小心,您确实返回了正确类型的值,因为编译器帮不了你。如果您真的希望是类型安全的,请不要返回
this
;创建一个正确类型的全新实例,并在不修改原始实例的情况下返回该实例。似乎如果返回值在链期间发生变化,那么我唯一的选择就是构造一个新实例或执行不安全的操作(
this
),至少我找不到更好的方法来解决这个问题。An不需要使用您的实际代码,它只需要演示您的问题,并且只演示您的问题。使用
any
会混淆您所寻找的担保类型;一切都可以分配给任何,包括
any[]
。另外,示例代码多次重用
x
,如果
x.single()
发生变异
x
,则会出现问题。带有突变的流畅/可链接方法通常会阻止重用中间结果。你看到了吗?够了吗?或者甚至可以?
src/ChainableClass.ts:9:5 - error TS2322: Type 'this' is not assignable to type 'ChainableClass<TEntity, TEntity>'.
  Type 'ChainableClass<TEntity, TResult>' is not assignable to type 'ChainableClass<TEntity, TEntity>'.
    Type 'TResult' is not assignable to type 'TEntity'.
      'TEntity' could be instantiated with an arbitrary type which could be unrelated to 'TResult'.

9     return this;
      ~~~~~~~~~~~~