close

Filter

loading table of contents...

Studio Developer Manual / Version 2110

Table Of Contents
5.2.5.2.3 Creating Ext Config Objects in TypeScript

Now, we have strictly typed Config objects, but they lack xclass/alias/xtype properties, which Ext uses to determine the target class when instantiating a Config object later (see Section 5.2.5.1.2, “Advanced Ext JS Config System”). Since we do not want to specify the Config type twice, once as a TypeScript type and once as a utility function that add the target class indicator, we combine both into one.

To this end, the generic Config function supports an overloaded signature which takes as first argument the target class which must define a Config type and as second (optional) argument a Config object of the corresponding Config type, and returns that Config object complemented by xclass/alias/xtype properties taken from the class.

With this new usage of the Config function, you can now create Ext Config objects like so:

import Config from "@jangaroo/runtime/Config";
import MyClass from "./MyClass";

...
    // use Config function with target class + config object:
    const myClassConfig: Config<MyClass> = Config(MyClass, {
      // inherited from Config<Component>:
      id: "4711",
      // MyClass Config property:
      configOption1: "bar",
      // an undeclared property now *does* lead to a type error:
      untyped: new Date(),
      // type error: '"42" is not assignable to type number[]':
      configOption2: "42",
    });
...

Example 5.13.  Create Ext Config objects with Config function


As you can see, the syntax is very similar to using Config for a strict type-check. The crucial difference is that MyClass is not a type parameter (which is just a compiler hint and only relevant for type checking), but an argument of the function call. The class reference is needed at runtime to determine the xclass etc. and add it to the config object. Although this Config signature still has a type parameter, is should never be necessary to specify it explicitly, just leave it to TypeScript's type inference.

If you use a class as first argument, but leave out the second one, the Config function returns an empty Config object with just the target class marker (xclass, xtype, ...). This comes in handy for simple components like Config(Separator). TypeScript automatically distinguishes the two one-argument usages of Config by overloaded signatures, one with a Config object, the other with a class that declares a Config type.

In the rare case that you need to instantiate the "real" object from a given Config object, you have different options:

import { cast } from "@jangaroo/runtime";
import Ext from "@jangaroo/ext-ts";

    // Alternatives
    // ============

    // using constructor directly
    // xclass of Config object is ignored:
    const myClassInstance: MyClass = new MyClass(myClassConfig);

    // using Ext.create() with class and Config object
    // xclass of Config object is ignored:
    const myClassInstance: MyClass = Ext.create(MyClass, myClassConfig);

    // using Ext.create() with Config object only, type on left-hand side
    // must repeat target class, but incompatible class and Config type would be reported:
    const myClassInstance: MyClass = Ext.create(myClassConfig);

    // using Ext.create() with type parameter and Config object
    // must repeat target class, but incompatible class and Config type would be reported:
    const myClassInstance = Ext.create<MyClass>(myClassConfig));

Example 5.14.  Instantiate object from Config object


The first two usages are when you know which target class to create, anyway, so you would construct myClassConfig without any xclass, but just use the strict Config type function.

The latter two usages are when the Config object might have its own xclass of some MyClass subclass. Ext.create() uses the xclass to instantiate the corresponding class, and the resulting object is type-compatible with MyClass. This is the kind of mechanism used by Ext.Container to instantiate its items.

But the best thing is, that if you want to create an instance directly, you can do so in a strongly typed fashion with full IDE support using an inline, ad-hoc Config object, which does not need any Config usage:

 const myClassInstance: MyClass = new MyClass({
  id: "4711",
  configOption1: "bar",
  configOption2: [42, 24]
});

Example 5.15.  Inline ad-hoc Config object


In other words, the difference between creating a Config object and creating an instance is just using Config(MyClass, ...) versus using new MyClass(...).

Note that when creating the component tree, you usually use Config objects, while certain elements like Actions require instantiation. Any Ext Container takes care that its items are instantiated if they are Config objects, but for example a Component's baseAction property does not support Config objects. This is reflected in the Ext TS API by declaring

Container.items: (Component | Config<Component>)[],

but

Component.baseAction: Action (not Config<Action>).

In other words, inadvertently using a Config object for a baseAction results in a type error.

Search Results

Table Of Contents
warning

Your Internet Explorer is no longer supported.

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