IExportable Summary Defines conversion rules to the external type. Description IExportable is an interface to define a custom conversion to the external type. All types implementing IExportable can be converted to the external type by calling the toExternal() method. Custom Conversion Rules Complex types, such as user-defined types (e.g. classes), will usually require custom conversion rules. For example, to define a class that can be used by JavaScript: 123456789101112131415161718192021222324import System; class Point : IExportable{ int x; int y; Point(int x, int y) { this.x = x; this.y = y; } override function toExternal() { return { x: x, y: y }; }} Point p = new Point(2, 3);var p2 = p.toExternal(); // conversion to 'external'Console.log(p2.x); // 2Console.log(p2.y); // 3 However, the above code only converts an instance of the class to external. In order to expose the entire class to JavaScript users, an "external constructor" is needed: 123456789101112131415161718192021222324252627import System;import Externals.JS; // exposes 'global' JS object class Point : IExportable{ int x; int y; Point(int x, int y) { this.x = x; this.y = y; } override function toExternal() { return { x: x, y: y }; } // Constructor for JavaScript users, the "external constructor" static function ExternalConstructor(x, y) { return new Point(x, y).toExternal(); }} global.Point = Point.ExternalConstructor; The above code essentially defines a constructor with only external return and parameter types as a static method. The method itself only calls the constructor and converts the object to external via the toExternal() method. This allows plain JavaScript users to consume a full JS++ class by importing the compiled JS++ library and instantiating with the new operator: 1new Point(0, 0); // from plain JavaScript Examples Basic Usage 123456789101112131415161718192021222324import System; class Point : IExportable{ int x; int y; Point(int x, int y) { this.x = x; this.y = y; } override function toExternal() { return { x: x, y: y }; }} Point p = new Point(2, 3);var p2 = p.toExternal(); // conversion to 'external'Console.log(p2.x); // 2Console.log(p2.y); // 3 'IExportable' Generic Constraint for working with external APIs 1234567891011121314151617181920import System; external mysql = { query: function(q, a) { Console.log(q, a); } }; // Constrain type arguments to only classes that can convert to 'external'interface ICommand<T: IExportable>{ void execute(...T args);} class CreateUser : ICommand<String>{ final void execute(...String args) { string username = args[0] ?? ""; mysql.query("INSERT INTO `users`(`username`) VALUES(?);", username.toExternal()); }} auto createUserCommand = new CreateUser();createUserCommand.execute("foo"); // "INSERT INTO `users`(`username`) VALUES(?); foo" Methods toExternalDefines a conversion to external. Share HTML | BBCode | Direct Link