We value your privacy. We use cookies to enhance your experience on our site. By using this site you agree to our Privacy Policy.

Writing Components in Typescript

Package Setup 

Whether you are working on a TypeScript library or directly with a Wonderland Engine project, the setup will be the same.

You will need to install the typescript compiler using your favorite package manager (npm, yarn, etc…):

1npm i typescript --save-dev

Create a new configuration file called tsconfig.json at the root of your project/library:

1{
2  "compilerOptions": {
3    "target": "ES2022",
4    "module": "ES6",
5    "moduleResolution": "nodenext",
6    "experimentalDecorators": true
7  }
8}

Wonderland Engine uses modern JavaScript and TypeScript features, such as:

Some of those features require specific keys to be set in your configuration, such as:

  • “moduleResolution”: Allows to import from the API using the package “exports” field.
  • “experimentalDecorators”: Allows you to use decorators. See the Decorators section for more information.

For more information about the configuration, please have a look at the TypeScript documentation.

Editor Support 

The editor has first class support for Esbuild, a popular JavaScript and TypeScript bundler. Esbuild is able to directly transpile your .ts sources into .js files.

Before writing your first component, open Views > Project Settings. The panel will then appear on the right. Update the Project Settings > Scripting > entryPoint option from js/index.js to js/index.ts.

The setting you are looking for is highlighted here in red:

Writing Components in Typescript

You can now start writing your components using the .ts extensions.

Decorators 

With TypeScript, creating properties using the Property export leads to code repetition:

 1import {Component, Property} from '@wonderlandengine/api';
 2
 3class MyComponent extends MyComponent {
 4    static TypeName = 'my-component';
 5    static Properties = {
 6        myFloat: Property.float(1.0),
 7        myBool: Property.bool(true),
 8    };
 9
10    myFloat!: number;
11    myBool!: boolean;
12}

Each property must appear twice, once for the type declaration, and once for the definition. Decorators are here to help:

 1import {Component} from '@wonderlandengine/api';
 2/* Note the '.js' at the end of the import statement. */
 3import {property} from '@wonderlandengine/api/decorators.js';
 4
 5class MyComponent extends MyComponent {
 6    static TypeName = 'my-component';
 7
 8    @property.float(1.0)
 9    myFloat!: number;
10
11    @property.bool(true)
12    myBool!: boolean;
13}

Instead of using the non-null assertion operator in the class, you can also use dummy values:

1class MyComponent extends MyComponent {
2    static TypeName = 'my-component';
3
4    @property.float(1.0)
5    myFloat: number = 1.0;
6
7    @property.bool(true)
8    myBool: boolean = true;
9}

On the above example, note the missing ! when defining myFloat or myBool.