close

Filter

loading table of contents...

CoreMedia Content Cloud v11 Upgrade Guide / Version 2110

Table Of Contents

7.3.1.2 Interfaces

While ActionScript and TypeScript have a notion of interfaces and even use the same keyword, the semantics are different.

In ActionScript, an interface must be implemented by a class explicitly. 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 an interface must have some run-time representation.

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. To simulate this, you have to provide custom functions that test a given object (type assertions).

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 is compiled to JavaScript using the Ext class system, there already is 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. An 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 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 utility function mixin, which is usually imported as a named import, so you'll see it simply as mixin(Clazz, Interface1, ..., InterfaceN) after the class declaration.

Furthermore, in ActionScript interfaces, only methods may be declared. TypeScript allows to declare fields in interfaces, too. Note that a field and an accessor pair is considered two different things in both languages.

The following example illustrates the differences. Assume that accessor pair foo was meant as a field (which ActionScript cannot express in an interface), while bar was intended to be implemented as an accessor pair. The underscore prefix of _bar is left out in TypeScript, as # private names do not clash with public names, anyway.

ActionScript TypeScript
interface IFoo {
  function get foo(): String;
  function set foo(value: String): void;

  function get bar(): Number;
  function set bar(value: Number): void;

  function isAFoo(obj: *): Boolean;
}

public class Foo implements IFoo {
  private var _foo: String;
  private var _bar: Number;

  public function get foo(): String {
    return _foo;
  }

  public function set foo(value: String): void {
    _foo = value;
  }

  public function get bar(): Number {
    return _bar;
  }

  public function set bar(value: Number): void {
    _bar = value;
  }

  public function isAFoo(obj: *): Boolean {
    return obj is IFoo;
  }
}
abstract class IFoo {
  abstract foo: string;


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

  abstract isAFoo(obj: any): boolean;
}

class Foo 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);

Table 7.2.  Interfaces ActionScript-TypeScript example comparison


Note that is and mixin must be imported from Jangaroo Runtime as a named import, so they can be used simply as is and mixin. See below for details about importing and exporting in TypeScript.

Search Results

Table Of Contents
warning

Your Internet Explorer is no longer supported.

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