assemblyscript
assemblyscript copied to clipboard
Enhancement: Emit "plain object" classes as a named (non-generic) interface or type
Problem
Currently, plain objects (objects without constructors or functions) are emit to the deceleration file as generically named interface types, in the form of __Record{classId}
.
// ./assembly/index.ts
class Bar {
value: u8;
}
export function foo(): Bar {
return {
value: 0
}
}
// ./build/release.d.ts
/** assembly/index/Bar */
declare interface __Record10<TOmittable> {
/** @type `u8` */
value: number | TOmittable;
}
/**
* assembly/index/foo
* @returns `assembly/index/Bar`
*/
export declare function foo(): __Record10<never>;
This is not expected behavior; I would expect AssemblyScript classes which merely define the shape of a plain object to be emit as interface
or type
with the same name as the class.
// ./build/release.d.ts
// type version
declare type __Record10<TOmittable> = {
/** @type `u8` */
value: number | TOmittable;
}
// interface version
declare interface __Record10<TOmittable> {
/** @type `u8` */
value: number | TOmittable;
}
Proposal
Plain object classes are emit as type/ interface if an annotation is present.
The name of this annotation, and what the new "default" behavior is, is an implementation detail.
Considerations
Plain objects returns/ arguments are "not really an instance"
In TypeScript, an interface
or type
with no functions merely defines the shape of plain object. On the AssemblyScript side, a class with no constructor or functions also merely defines the shape of a plain object. In both cases, that plain object really is that type in both TypeScript and AssmeblyScript.
Naming Conflicts
As naming collisions are unavoidable, it is the responsibility of the application developer to resolve naming conflicts within their application through alias imports. eg, import { Foo as MyFoo } from 'my-wasm-module';
Maybe it would be better if AS supported interface
instead, and did with it similar to constructor-less classes, rather than investing time down this path.
Maybe it would be better if AS supported
interface
instead, and did with it similar to constructor-less classes, rather than investing time down this path.
This makes a lot more sense, as TypeScript interfaces are similar to constructorless classes in AssemblyScript (merely defines the shape of a plain object), and instances can easily be emit as those interfaces without changing their behavior.