1

Is there a way to declare class as global without code duplication?

This doesn't work

declare global {
  class A {
    hi() { return "hi" }
  }
}

export {}

So I had to use code duplication play

declare global {
  class A {
    hi(): string
  }
}

(window as any).A = class A { // Also why it doesn't work without `any`?
  hi() { return "hi" }
}

export {}

2 Answers 2

1

Yeah, I don't see anything great for this. Without something like microsoft/TypeScript#39504, you'll be forced to do at least some duplication.

One possible solution is the following, which has a fixed amount of overhead, which might be worth it to you if your class definition has more than just one or two methods/properties:

const _A = class A {
  hi() { return "hi" }
}

declare global {
  var A: typeof _A
  interface A extends InstanceType<typeof A> { }
}
window.A = _A; // or globalThis.A = _A;

export { }

First you implement your A class and assign it to a temporary, differently-named variable _A. Then you can use typeof _A to refer to the type of that class constructor, and use it in to augment your global scope. Class declarations introduce both a named value for the constructor and a named type for the instance type), so in order to augment the global scope with a class expression and typeof, you need to do both manually. Hence the var for the constructor and the interface for the instance type.

(With something like a typeof class feature as requested in microsoft/TypeScript#41581 this could be a little less painful, but for now this is the best I can do).

Note that the interface A type uses the InstanceType<T> utility type; this will work reasonably well but has some edge cases; generic classes being a big one. So you'll need to test this on your use cases.

Anyway, once the global scope knows about the global A class, you can just assign the _A constructor to it without error.

Playground link to code

Sign up to request clarification or add additional context in comments.

Comments

0

You can set a new property (say A class) to window like this:

declare global {
  class A {
    hi(): string
  }

  interface Window { AClass: A; }
}

window.AClass = window.AClass || {};

window.AClass.hi();

PlaygroundLink

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.