Skip to content

Instantly share code, notes, and snippets.

@gavinr
Last active November 22, 2017 21:12
Show Gist options
  • Save gavinr/d5f4b4c11c526895010087980e0a96ed to your computer and use it in GitHub Desktop.
Save gavinr/d5f4b4c11c526895010087980e0a96ed to your computer and use it in GitHub Desktop.
<html><body><p>If you're a JavaScript developer, you may be interested in TypeScript, a typed superset of JavaScript that compiles to plain JavaScript. If you're also creating Web AppBuilder widgets, using TypeScript in a widget is a great way to get started with TypeScript. Here are a few notes and tips that I've discovered while using TypeScript within a Web AppBuilder custom widget development workflow.</p>
<p></p>
<h3>Background</h3>
<p></p>
<p>My usual Web AppBuilder development workflow is to have my widget code in its own code repository, and use a task runner like Grunt or Gulp to automatically compile and copy my code to the correct places (The stemapp directory and optionally the server directory of the app that I'm currently working on). Within this context, TypeScript fills the "transpiler" role where Babel might currently be in your stack.</p>
<p></p>
<h3>tsconfig.json&nbsp;file</h3>
<p></p>
<p>Many aspects of your tsconfig.json file are on a per-project basis, but there are a few things that you do need:</p>
<ol>
<li>"module": "amd" - we choose "amd" because <a href="http://requirejs.org/docs/whyamd.html">AMD</a> is the module style that Web AppBuilder expects to see when loading a widget into an app.</li>
<li>"moduleResolution": "classic" - because we chose "AMD" above</li>
<li>"target": "es5" - the&nbsp;ECMAScript JavaScript type that we want the TypeScript compliler to output. We want to target es5 so the code we write in ES6-style JavaScript will be converted down so older browsers will be able to read it.</li>
<li>"types": [ "arcgis-js-api", "dojo-typings"] - the names of the type definitions we want to include.</li>
</ol>
<p></p>
<p>Full example <a href="https://github.com/gavinr/web-appbuilder-typescript-examples/blob/master/builder/tsconfig.json">here</a>.&nbsp;</p>
<p></p>
<h3>Declare Decorator</h3>
<p></p>
<p>This is&nbsp;the main key to the entire process. It tells the TypeScript compiler how to translate your ES6-style class syntax in your Widget.ts file into the Dojo-style define/declare syntax that Web AppBuilder expects. This bit of code can be obtained <a href="https://github.com/dojo/typings/blob/master/examples/basicApp/src/app/declareDecorator.ts">from the dojo/typings repository</a>, and included in your widget files. You then <a href="https://github.com/gavinr/web-appbuilder-typescript-examples/blob/master/builder/widgets/MyWidget/Widget.ts#L7">import it into your Widget.ts file</a>, and <a href="https://github.com/gavinr/web-appbuilder-typescript-examples/blob/master/builder/widgets/MyWidget/Widget.ts#L25">apply the decorator on your Widget class</a>.</p>
<p></p>
<h3>Promises</h3>
<p></p>
<p>I would like to write code as close as possible to true ES6 JavaScript. So I'd like to use the native JavaScript Promise syntax. But when I tried to do this in my widget, I initially got an error, "error TS2693: 'Promise' only refers to a type, but is being used as a value here." To resolve this problem, all I had to do was add the "es6-promise" declarations file to my project by doing these two things:</p>
<p></p>
<ol>
<li>Add the NPM package with npm add @types/es6-promise</li>
<li>Add an entry to the "types" property in my tsconfig.json file with the contents "es6-promise":<br /><span>"types": [ "arcgis-js-api", "dojo-typings", <span style="text-decoration: underline;"><strong>"es6-promise"</strong></span>]</span></li>
</ol>
<p></p>
<h3>Sourcemaps</h3>
<p></p>
<p><span>This can be tough to get it just right, but if you have this hooked up it makes debugging in the browser much easier. You want to set&nbsp;"sourceMap": true in your tsconfig.json file, and go from there.</span></p>
<p></p>
<h3>Huh?</h3>
<p></p>
<p>That's a lot of information, and it's sometimes hard to get all the settings in your project exactly correct, so I've put an example widget in a GitHub repository that is available for download here:&nbsp;<a href="https://github.com/gavinr/web-appbuilder-typescript-examples" style="color: #2989c5; text-decoration: none;">Web AppBuilder Typescript Examples</a>. Note there are 2 examples in there that represent 2 "styles" of project, so please read the README file for clarification on which to use. We're also considering getting a TypeScript option into the <a href="https://github.com/Esri/generator-esri-appbuilder-js">Web AppBuilder Custom Widget Generator</a>, and if you have any feedback on what you'd like to see there, please let us know via <a href="https://github.com/Esri/generator-esri-appbuilder-js/issues/61">this GitHub issue</a>. Thanks!</p>
<p></p>
<h3>Links</h3>
<p></p>
<ul>
<li><a href="https://github.com/gavinr/web-appbuilder-typescript-examples">Web AppBuilder Typescript Examples</a></li>
<li><a href="/ideas/13147-maintain-a-typescript-definition-file-for-jimujs">ArcGIS Ideas:&nbsp;Maintain a Typescript definition file for jimu.js</a></li>
<li><a href="https://github.com/Esri/generator-esri-appbuilder-js/issues/61">Esri Web AppBuilder Yeoman Generator: TypeScript Support</a></li>
</ul>
</body></html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment