如何在typecipt中使用带有mixin的类作为类型

问题描述

我有以下代码

type GConstructor<T = {}> = new (...args: any[]) => T;
class Sprite {
  name = "";
  x = 0;
  y = 0;

  constructor(name: string) {
    this.name = name;
  }

  setPos(x:number,y:number) {
    this.x = x;
    this.y = y
  }
}
type Positionable = GConstructor<{ setPos: (x: number,y: number) => void }>;

function Jumpable<TBase extends Positionable>(Base: TBase) {
  return class Jumpable extends Base {
    jump() {
      this.setPos(0,20);
    }
  };
}

const JumpableSprite = Jumpable(Sprite);

function hi(x: JumpableSprite) {
  return 4;
}

问题是我收到这个错误

'JumpableSprite' refers to a value,but is being used as a type here. Did you mean 'typeof JumpableSprite'?
Parameter 'x' of exported function has or is using private name 'JumpableSprite'.

我很确定我不想要 typeof JumpableSprite,因为我希望它被输入为 JumbableSprite 而不是 JumbableSprite 的类。

有没有办法将 JumpableSprite 用作类型?

解决方法

正如@tsecheukfung01 在评论中所解释的那样,您所要做的就是创建一个与引用类的变量同名的类型。完成此操作后,您将看到 @typescript-eslint 错误(当然,如果您的项目中有 @typescript-eslint)。根据 @typescript-eslint docs 您应该只使用 eslint ignore 行。完整的工作代码...

type GConstructor<T = {}> = new (...args: any[]) => T;
class Sprite {
  name = "";
  x = 0;
  y = 0;

  constructor(name: string) {
    this.name = name;
  }

  setPos(x:number,y:number) {
    this.x = x;
    this.y = y
  }
}
type Positionable = GConstructor<{ setPos: (x: number,y: number) => void }>;

function Jumpable<TBase extends Positionable>(Base: TBase) {
  return class Jumpable extends Base {
    jump() {
      this.setPos(0,20);
    }
  };
}

const JumpableSprite = Jumpable(Sprite);
// eslint-disable-next-line @typescript-eslint/no-redeclare -- intentionally naming the variable the same as the type
type JumpableSprite = Sprite & {jump(): undefined};

function hi(x: JumpableSprite) {
  return 4;
}