如何将 类 与 mixin 一起用作打字稿中的类型

How to use classes with mixins as types in typescipt

我有以下代码

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 的 class。

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

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

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;
}