I have the following code
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;
}
the problem is that I get this error
'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'.
I'm pretty sure I don't want typeof JumpableSprite
, because I want it to be typed as JumbableSprite
not JumbableSprite
's class.
Is there a way to use JumpableSprite as a type?
So as @tsecheukfung01 explained in the comments, all you have to do is create a type with the same name as the variable that refers to a class. After you have done this you will see an @typescript-eslint error (if you have @typescript-eslint in your project of course). Acording to the @typescript-eslint docs you should just use an eslint ignore line. The complete working code...
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;
}