close

Filter

loading table of contents...

Studio Developer Manual / Version 2406.0

Table Of Contents

5.2.2 Interfaces

TypeScript has a notion of interfaces, but uses different semantics than other statically typed languages like Java or ActionScript.

In TypeScript, a class "automatically" implements an interface when it defines the same member signatures (duck typing). You can, however, use the keyword implements to explicitly state that your class intends to implement some interface. A TypeScript interface defines a so-called ambient type, that is a type that is only relevant for the compiler/type checker, but not at runtime. Consequently, there is no built-in way to do an instance-of check with an interface. To simulate this, you have to provide a custom function that tests whether a given object is of the interface type (type guard).

Studio used to be implemented in ActionScript, where it can be checked at run-time whether an object is an instance of a given interface, using the ActionScript built-in operator is. This means that in ActionScript, interfaces do have some run-time representation.

When converting code from ActionScript to TypeScript, we wanted to keep the ActionScript interface semantics, so we had to find some way to represent interfaces and the is operator in TypeScript.

Since Jangaroo ActionScript was compiled to JavaScript using the Ext class system, too, there already was a solution at run-time. Interfaces are represented as "empty" Ext classes, that is, classes that have no members, but an identity. When a class A implements an interface I, in Ext, the class corresponding to I is mixed into A. The is check is implemented by looking up the mixins hierarchy of the object's class.

We use a similar approach in TypeScript. A "runtime interface" is represented as a completely abstract class, that is, an abstract class that only has abstract members. At runtime, again, only an empty class with an identity remains. When implementing an interface, this abstract class is implemented and mixed in. TypeScript allows to "implement a class", because a class actually defines two entities: a value (the "class object" that exists at runtime) and a type (only relevant for the type checker / compiler). If you use a class in an implements clause, only its type is used. The mixin aspect is represented in TypeScript by calling the Jangaroo runtime function mixin(Clazz, Interface1, ..., InterfaceN) after the class declaration.

The following example illustrates how "runtime interfaces" are specified in TypeScript and how they translate to Ext JS.

TypeScript Ext JS
abstract class IFoo extends Base {
  abstract foo: string;

  abstract get bar(): number;
  abstract set bar(value: number);

  abstract isAFoo(obj: any): boolean;
}

class Foo extends Base implements IFoo {
  foo: string;
  #bar: number;

  get bar(): number {
    return this.#bar;
  }

  set bar(value: number) {
    this.#bar = value;
  }

  isAFoo(obj: any): boolean {
    return is(obj, IFoo);
  }
}

mixin(Foo, IFoo);
Ext.define("IFoo", {
  extend: "Ext.Base"
});

Ext.define("Foo", {
  extend: "Ext.Base",
  mixins: ["IFoo"],
  requires: ["IFoo"],
  foo: undefined,
  bar$fPTk: undefined,
  __accessors__: {
    bar: {
      get: function () {
        return this.bar$fPTk;
      },
      set: function (value) {
        this.bar$fPTk = value;
      }
    }
  },
  isAFoo: function (obj) {
    return is(obj, IFoo);
  }
});

Table 5.2.  Runtime Interfaces in TypeScript and Ext JS


The utility functions is and mixin are imported from @jangaroo/runtime. Section 5.2.3, “Imports and Exports” explains how importing and exporting works in Ext TS.

The main takeaways here are that runtime interfaces are represented by abstract classes in TypeScript and by empty classes in Ext JS, implementing a runtime interface means mixing-in that class, and Ext JS's mixins class definition property is represented in TypeScript by calling the utility function mixin with the class that implements the runtime interface as the first argument, and the runtime interface itself as the second argument.

Search Results

Table Of Contents
warning

Your Internet Explorer is no longer supported.

Please use Mozilla Firefox, Google Chrome, or Microsoft Edge.