I already worked with JSRender, JSViews, and JSObservables in the past. This time, I started a new project but using TypeScript and I am not sure how to use it. I find very confusing where to put the references to .js, .d.ts, .ts, etc.
I will describe what I have and where it fails.
My "scripts" folder contains these files:
~\Typings\jQuery\jQuery.d.ts
installed from this NuGet package: jquery.TypeScript.DefinitelyTyped v0.0.1
~\Typings\jsrender\jsrender.d.ts
installed from this NuGet package: jsrender.TypeScript.DefinitelyTyped v0.1.8
File: ~/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<script src="scripts/jquery-3.1.1.js"></script>
<script src="scripts/jsviews.js"></script>
<script src="scripts/game/game.js"></script>
<script src="scripts/game/app.js"></script>
</head>
<body>
<div id="view">
<div id="myMap"></div>
<div id="optionsTmpl"></div>
</div>
</body>
</html>
File: ~/tmpl/options.tmpl.html
<div class="optionsFrame">
<select data-link="mapType">
{^{for mapTypes}}
<option value="{{:id}}">{{:name}}</option>
{{/for}}
</select>
<input type="button" value="test">
</div>
File: app.ts
/// <reference path="../typings/jquery/jquery.d.ts" />
/// <reference path="../typings/jsrender/jsrender.d.ts" />
class UnchartedApp {
game: UnchartedGame;
init() {
this.game = new UnchartedGame();
this.game.loadMap();
}
}
window.onload = () => {
var app = new UnchartedApp();
app.init();
};
File: game.ts
/// <reference path="../typings/jquery/jquery.d.ts" />
/// <reference path="../typings/jsrender/jsrender.d.ts" />
class UnchartedGame {
constructor() {
}
/***** Error on the $.observe() line !! *****/
loadMap() {
this.linkTemplate("options", "#optionsTmpl", this).done(function (currentGame) {
$.observe(currentGame, "*", currentGame.modelChangeHandler);
});
}
modelChangeHandler(ev, eventArgs) {
if (ev.type == "propertyChange") {
var _game: UnchartedGame = ev.currentTarget;
if (eventArgs.path == "mapType") {
try {
_game.myMap.setMapType(mapTypeNames[newValue]);
}
catch (ex) {
}
}
}
}
loadTemplate(tmplName: string) {
var deferredLoad = $.Deferred();
try {
var filePath: string = "../tmpl/" + tmplName + ".tmpl.html";
$.get(filePath).then(function (templateText) {
$.templates(tmplName, templateText);
deferredLoad.resolve();
})
}
catch (e) {
deferredLoad.reject();
}
return deferredLoad.promise();
}
linkTemplate(tmplName: string, targetId: string, model: UnchartedGame) {
var deferredLink = $.Deferred();
try {
this.loadTemplate(tmplName).done(
function () {
$.templates[tmplName].link(targetId, model);
deferredLink.resolve(model);
});
}
catch (e) {
deferredLink.reject();
}
return deferredLink.promise();
}
}
What can I try next?
TypeScript wants you to use ES6 import statements ie: import * as jQuery from 'jquery';
The other way to do it is to reference the script (jquery, for example) in your module loader and then use declare const jQuery: any
to be used throughout your application. Another way to do is to reference the typings in your tsconfig:
First way using import statements:
import * as jQuery from 'jquery'; // jquery installed via npm install jquery
import * as jsrender from 'jsrender'; // jsrender installed via npm install jsrender
// === OR ===
declare const jQuery: any; // Reference the script in your module loader/html
declare const jsrender: any; // Reference the script in your module loader/html
class UnchartedGame {
constructor() {
}
/***** Error on the $.observe() line !! *****/
loadMap() {
this.linkTemplate("options", "#optionsTmpl", this).done(function (currentGame) {
$.observe(currentGame, "*", currentGame.modelChangeHandler);
});
}
modelChangeHandler(ev, eventArgs) {
if (ev.type == "propertyChange") {
var _game: UnchartedGame = ev.currentTarget;
if (eventArgs.path == "mapType") {
try {
_game.myMap.setMapType(mapTypeNames[newValue]);
}
catch (ex) {
}
}
}
}
loadTemplate(tmplName: string) {
var deferredLoad = $.Deferred();
try {
var filePath: string = "../tmpl/" + tmplName + ".tmpl.html";
$.get(filePath).then(function (templateText) {
$.templates(tmplName, templateText);
deferredLoad.resolve();
})
}
catch (e) {
deferredLoad.reject();
}
return deferredLoad.promise();
}
linkTemplate(tmplName: string, targetId: string, model: UnchartedGame) {
var deferredLink = $.Deferred();
try {
this.loadTemplate(tmplName).done(
function () {
$.templates[tmplName].link(targetId, model);
deferredLink.resolve(model);
});
}
catch (e) {
deferredLink.reject();
}
return deferredLink.promise();
}
}
Using TSConfig:
{
"compilerOptions": {
"types": ["jquery", "jsrender"]
}
}
One other possible way is to go to your main module and use the following line:
import 'jquery'; // jquery installed via npm install jquery
I noticed that's how I'm using it in one of my projects (required @types file).
I would also recommend getting away from using reference paths as TypeScript is all about types. Most modules (from what I've seen thus far) come with a typings file. However, jQuery for example does not. So, after you do npm install jquery
, you'll want to additionally install it's typings by running npm install @types/jquery --save-dev