Sorry, I can't seem to find a perfect solution for this issue. Without something similar to microsoft/TypeScript#39504, some level of duplication may be inevitable.
One potential approach is outlined below, with a set amount of extra work involved. This could be beneficial if your class definition contains more than just a couple of methods or 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 { }
Initially, you define your class as A
and assign it to another variable called _A
. By utilizing typeof _A
, you reference the type of the class constructor and incorporate it into your global scope. Class declarations introduce both a named value for the constructor and a named type for the instance, so augmenting the global scope with a class expression and typeof
necessitates manual handling. This explains why the constructor uses var
and the instance type requires an interface
.
(If TypeScript were to include a typeof class
feature as discussed in microsoft/TypeScript#41581, this process might become smoother, but until then, this is the most effective method).
It's important to note that the interface A
type employs the InstanceType<T>
utility type; while generally reliable, there are certain edge cases such as generic classes that may warrant further testing in your specific scenarios.
Once the global scope recognizes the global A
class, assigning the _A
constructor to it becomes seamless.
Playground link to code