Skip to content

Commit

Permalink
Update basicApp example to use declare decorator and i18n (#117)
Browse files Browse the repository at this point in the history
* Update basicApp example to use declare decorator

Add to the basicApp example a `declare` decorator that generates a
`dojo/_base/declare` constructor from a class, update the `Dialog`
widget to a class that uses that decorator, and add i18n messages.

* Fix typos; add experimentalDecorators to tsconfig

* Fix typo in basicApp Dialog.ts
  • Loading branch information
Matt Wistrand authored and dylans committed Mar 23, 2017
1 parent 47aa2bf commit 826ed4e
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 40 deletions.
52 changes: 27 additions & 25 deletions examples/basicApp/src/app/Dialog.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,31 @@
import * as declare from 'dojo/_base/declare';
import * as Dialog from 'dijit/Dialog';
import * as DijitDialog from 'dijit/Dialog';
import * as messages from 'dojo/i18n!./nls/main';
import declare from './declareDecorator';

/* We are using the ES6 module format here, as it is more forward compatible */
/**
* `dojo/_base/declare` can infer typings, but since we are generating our declare
* constructor with a decorator (see below), we need to define our widget interface
* explicitly.
*/
interface Dialog extends DijitDialog {}

/* While type inference works with declare, if you want to refer to the type at
* some other point, you cannot easily extract the type. Therefore we will do
* essentially what the dojo.declare typings will do and create type reference.
* This does not emit anything, but it allows others using this module in
* TypeScript to have a clear reference to the type we are creating here */
export type DialogType = dijit.Dialog & {
title: string;
content: string;
};
/**
* By using a decorator to create constructors with `dojo/_base/declare`, we can
* write our widgets using TypeScript classes. The one caveat is that we are then
* required to use merged declarations to define our interface, so the widget
* class has to be declared as the default export in a separate statement.
*/
@declare(DijitDialog)
class Dialog {
title: string = messages.dialogTitle;
content: string = messages.dialogContent;
}

/* dojo.declare can infer the typings here, but as explained above, we want to
* specfically assert the type, so we are providing it as a generic argument
* for decalare
*
* In addition, we are using `export default` here, which is part of the ES6
* module format. If other consumers of the module are compatible with default
* exports, like other modules written in TypeScript, then this is fine, but if
* someone consumes this module, that insead of this being the return value of
* the module, it will be located under Dialog.default.
/*
* We are using `export default` here, which is part of the ES6 module format.
* If other consumers of the module are compatible with default exports, like
* other modules written in TypeScript, then this is fine, but if someone
* consumes this module, that instead of this being the return value of the module,
* it will be located under Dialog.default.
*/
export default declare<DialogType>(Dialog, {
title: 'Hello World',
content: 'Loaded successfully!'
});
export default Dialog;
12 changes: 12 additions & 0 deletions examples/basicApp/src/app/declareDecorator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import * as declare from 'dojo/_base/declare';

/**
* A decorator that converts a TypeScript class into a declare constructor.
* This allows declare constructors to be defined as classes, which nicely
* hides away the `declare([], {})` boilerplate.
*/
export default function (... mixins: Object[]): ClassDecorator {
return function (target: Function) {
return declare(mixins, target.prototype);
};
}
14 changes: 3 additions & 11 deletions examples/basicApp/src/app/main.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,11 @@
import Dialog, { DialogType } from './Dialog';
import Dialog from './Dialog';
import 'dojo/domReady!';

/* Using just "import 'mid'"" above loads the modules for and causes the
* appropriate side affects, but doesn't create any reference in the module
*
* Also we are using the destrcuring syntax to also import a reference to the
* DialogType type above. This will not actually emit anything because there
* is no runtime emit for the type
*/

/* So others can consume our application module better under TypeScript, lets
/* So others can consume our application module better under TypeScript, let's
* specify an interface for our application and export it
*/
export interface App {
dialog: DialogType;
dialog: Dialog;
}

/* Now we are creating our application object */
Expand Down
4 changes: 4 additions & 0 deletions examples/basicApp/src/app/nls/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export const root = {
dialogTitle: 'Hello World',
dialogContent: 'Loaded successfully!'
};
10 changes: 6 additions & 4 deletions examples/basicApp/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@
"outDir": "_build",
"removeComments": false,
"sourceMap": true,
"target": "ES5"
"target": "ES5",
"experimentalDecorators": true
},
"include": [
"./src/**/*.ts"
],
"files": [
"./src/app/main.ts",
"./src/app/Dialog.ts",
"../../dojo/1.11/modules.d.ts",
"../../dijit/1.11/modules.d.ts"
]
}
}

0 comments on commit 826ed4e

Please sign in to comment.