AssemblyScript/assemblyscript

A way to make AS globals also visible to TS (for VS Code intellisense for example).

trusktr opened this issue · 9 comments

There doesn't seem to be a way to make @global AS variables visible to TypeScript. For example, this doesn't work:

// AS uses `@global`
@global
const foo: i32 = 123

// Try to make it visible in VS Code intellisense
declare global {
  const foo: i32
}

playground

You could try a triple slash reference with a custom d.ts, but in general I'd recommend to avoid @global.

I'm thinking for asdom, things like document and window, to make the usage align well with existing JS/TS code. In JS/TS projects, they don't import document from '...' in every file.

In general I do like to avoid globals as much as I can, and I prefer importing everything to be explicit, but document and window are a special case in this case.

You could try a triple slash reference with a custom d.ts, but in general I'd recommend to avoid @global.

Do you mean I'd use @global like I am already doing, but also repeat all the types in a separate declaration file just for TS that only TS picks up? I was hoping to keep it DRY.

I would say you should not use @global if you can avoid it. Just import { document } from "asdom", as one would do with a package, and leave the @global stuff to stdlib eventually. The latter is what the @global decorator is for.

I know, but like I mentioned, document and window are global in JS, so I was trying to emulate that.

In AssemblyScript making globals is done in a way that TypeScript doesn't understand.

Is there some way to make making globals portable?

Globals are provided by stdlib with some magic currently, and that's pretty much it. I would discourage attempting to introduce globals otherwise, and recommend using imports.

Portable variant:

// asdom.ts
export const document = ASC_TARGET ? getWasmDocument() : window.document;
import { document } from "./asdom";

Yeah, import is the way it currently works:

https://github.com/lume/asdom/blob/ee252d42f64bb33f12e52a5a1b03f3ca110a5a2c/example/assembly/index.ts#L3

It works! Just thinking about when people will want to start using it, telling users how to port code: just setup up tsconfig.json like this, then your DOM code should have the global APIs ready (like with regular DOM).

But if that won't be the case, then oh well. Not the end of the world. I think it would be nice though.

But I also think having only imports is a nicer concept in general.

This issue has been automatically marked as stale because it has not had recent activity. It will be closed in one week if no further activity occurs. Thank you for your contributions!

What if we make a special globalThis "object" that isn't really an object in AS, but things like globalThis.foo = 123 as i32 would essentially create a global var just like @global let foo = 123 would in AS (identical behavior in AS)?

Then for TypeScript, asc can output a .d.ts file for portability that would define all the variables that were defined on globalThis (the casting would be required, in order for the types to be recognized by AS statically).

A TS user could use this .d.ts file to have the same global types in TS, and at runtime the expressions globalThis.foo = 123 would create the same globals, thus code would work the same on both sides.