TypeScript
Write JavaScript the way you really want to
Rūtenis Turčinas - rutenis.turcinas@gmail.com
Author
 Rūtenis Turčinas
 rutenis.turcinas@gmail.com
 https://github.com/rootis/jug-topic-1.git
http://www.typescriptlang.org/Content/TypeScript Language Specification.pdf
Agenda
Specification Integration
BuildClean Code
Questions Thoughts Suggestions
TypeScript. What is it? Do we need it?
 TypeScript is a typed superset of JavaScript that compiles to plain JavaScript
 Made by Microsoft
 Open Source
 Google had plans to release AtScript language, but desided to use TypeScript
 Google and Microsoft are writing the Angular 2 framework in TypeScript
 If your project uses JavaScript – TypeScript would be better
Difference between other languages
 CoffeeScript
 More differences from JavaScript
 You can not use plain JavaScript in *.coffee files
 Dart
 Has an own virtual machine
 Browser manufacturers has no plans to support Dart in the near future
How TypeScript works?
 TypeScript file: test.ts
 > tsc test.ts
 Compiler makes test.js file
 JavaScript file will be executed by browser
 > tsc test.ts –sourcemap
 Compiler makes the same test.js and one more file: test.js.map
 Map file used to map *.js with *.ts file lines (to debug *.ts file instead of *.js)
Hello World!
Data types
 boolean
 number
 string
 Array
 enum
 any (try to avoid it)
 void
Statements, loops, functions
 Simple variable assignment
 var variableName: dataType = value;
 Variable which data type is a function
 var variableName: (paramName: dataType) => returnType = value;
 Complex data type (do not use such data types)
 var person: {name: string; surname: string; age: number,
isMale: () => boolean} = null;
Classes, interfaces, methods
interface UsersGroup {
getLanguage: () => string;
}
class Jug implements UsersGroup {
public getLanguage(): string {
return "Java " + this.getJavaVersionTitle();
}
protected getJavaVersion(): number {
return 1.7;
}
private getJavaVersionTitle(): string {
return "v" + this.getJavaVersion();
}
}
Inheritance, overriding
class KaunasJug extends Jug {
protected getJavaVersion(): number {
return 1.8;
}
}
function printUsersGroupLanguage(usersGroup: UsersGroup): void {
console.log(usersGroup.getLanguage());
}
printUsersGroupLanguage(new Jug());
printUsersGroupLanguage(new KaunasJug());
Overloading
interface UsersGroup {
getLanguage(isUpperCase: boolean): string;
getLanguage(versionPrefix: string): string;
}
class KaunasJug implements UsersGroup {
getLanguage(property?: any): string {
if (typeof property === 'boolean'){
return property ? "JAVA v1.8" : "Java v1.8";
} else if (typeof property === "string") {
return "Java " + property + "1.8";
}
}
}
Generics
function printProperty<T>(property: T): void {
console.log(property);
}
interface UserGroupArray<T extends Language> {
add(... languages: T[]): void;
printAllGroups(): void;
}
Lambdas (use as little as possible)
class JavaUsersGroup {
private city: string;
constructor(city: string) {
this.city = city;
}
public printTitle1(): void {
console.log(this.city + " JUG");
}
public printTitle2 = (): void => {
console.log(this.city + " JUG");
};
}
Modules
module usersGroup {
export class API {
public static init(data: any) {
new ViewModel(data.someJSON);
}
}
class ViewModel {
constructor(jsonDataToLoad: string) {
console.log('Loading...');
}
}
class SomeInnerClass {
}
}
External libraries
 Large API, difficult to use, hard to remember: actions, events, properties, sub
modules...
 For example: using selector you get jQuery object. You want to get it‘s specific
child. Which method to use? Can you use the selector?
 99% of developers would use google. More convenient to use ctrl+space and get
the suggestion:
 And if you try to do something ridiculous – the code won‘t compile:
DefinetlyTyped - *.d.ts
 Declaration file (*.d.ts) describes the library or module
 > tsc --declaration file.ts
declare module usersGroup {
class API {
static init(data: any): void;
}
}
Definition manager - tsd
 LOTS of the *.d.ts files are here: https://github.com/borisyankov/DefinitelyTyped
 But its hard to search and download... Is there a better way?
 > npm install tsd –g
 E.g. you want to use library lodash
 Does it has lodash.d.ts file? Which version?
 > tsd query lodash
 Yes! It exists. We want to download lodash.d.ts file
 > tsd install lodash –save
 Using -save you wil store the information about installed *.d.ts in tsd.json
Libraries without *.d.ts or legacy code
 We are using super secret library...
 In our project exists lots of legacy code...
 But we still want to use TypeScript!
 What to do?
 Need to create declaration file for that library or legacy code (*.d.ts)
interface A_Static {
new(m: any): A_Instance;
st: string;
}
interface A_Instance {
inst: number;
}
declare var A: A_Static;
Dependency management tools
 Internal modules
 External modules: import $ = require('jquery');
 commonJS
 --module commonjs
 AMD - requireJS
 --module amd
How to write TypeScript correctly?
 TypeScript also can be terrible... if its plain JavaScript
 How to prevent it?
 Use simple rules:
 Every variable, property, or function result – must have defined data type
 Never use any data type
 Use same clean code conventions like in server side
Decouple modules
 Most of the times JavaScript logic lives in one place
 Large files tightly coupled in different ways
 Impossible to do refactoring without bugs
 How to solve it?
 Decouple logic to different modules
 Don‘t copy paste, just depend on some module
 Define strict public API for integration with other modules
Single responsibility for every item
 One module/class/method should be responsible just for one thing
 Currently we are trying one approach:
 If length of file is more than 200 lines – we should rethink: is it only
responsible for one thing?
 If length of method is more than 5 lines – we should rethink: is it only
responsible for one thing?
 In our project:
 97% of files have <= 200 lines
 72% of methods have <= 5 lines (in 4 files: ~200, ~180, ~150, ~120)
Hide as much as possible
 Encapsulate code
 Export only public API
 One file - one module
 Except – model entities
 Much easier to refactor hidden code
Try to keep code in first level
 JAVA developers can feel much more convenient by having source code in first
level
 Less complexity
 Easyer to understand and support
OK. But my friend uses SunOS and VIM
for editing source code. Can he..?
 Sure thing!
One more thing… Production needs one
file rather than 3
 For development we want all files: *.ts, *.js, *.js.map
 But for production we want only one: compressed *.js
 You can configure build scripts
 E.g. maven resource filtering
Large project. Lots of code.
How to test it?
 Karma, Jasmine, Mocha, tsJunit, Qjunit, ...
 Karma tests can be binded or decoupled from back end unit tests
 Binded tests can be skipped together with java tests using –DskipTests
 Decoupled tests can be skipped separate from java tests using custom
properties
Minuses in TypeScript
 Eclipse IDE
 After compiler version update your code may be broken...
Questions Thoughts Suggestions

TypeScript - Silver Bullet for the Full-stack Developers

  • 1.
    TypeScript Write JavaScript theway you really want to Rūtenis Turčinas - rutenis.turcinas@gmail.com
  • 2.
    Author  Rūtenis Turčinas rutenis.turcinas@gmail.com  https://github.com/rootis/jug-topic-1.git
  • 3.
  • 4.
  • 5.
  • 6.
    TypeScript. What isit? Do we need it?  TypeScript is a typed superset of JavaScript that compiles to plain JavaScript  Made by Microsoft  Open Source  Google had plans to release AtScript language, but desided to use TypeScript  Google and Microsoft are writing the Angular 2 framework in TypeScript  If your project uses JavaScript – TypeScript would be better
  • 7.
    Difference between otherlanguages  CoffeeScript  More differences from JavaScript  You can not use plain JavaScript in *.coffee files  Dart  Has an own virtual machine  Browser manufacturers has no plans to support Dart in the near future
  • 8.
    How TypeScript works? TypeScript file: test.ts  > tsc test.ts  Compiler makes test.js file  JavaScript file will be executed by browser  > tsc test.ts –sourcemap  Compiler makes the same test.js and one more file: test.js.map  Map file used to map *.js with *.ts file lines (to debug *.ts file instead of *.js)
  • 9.
  • 10.
    Data types  boolean number  string  Array  enum  any (try to avoid it)  void
  • 11.
    Statements, loops, functions Simple variable assignment  var variableName: dataType = value;  Variable which data type is a function  var variableName: (paramName: dataType) => returnType = value;  Complex data type (do not use such data types)  var person: {name: string; surname: string; age: number, isMale: () => boolean} = null;
  • 12.
    Classes, interfaces, methods interfaceUsersGroup { getLanguage: () => string; } class Jug implements UsersGroup { public getLanguage(): string { return "Java " + this.getJavaVersionTitle(); } protected getJavaVersion(): number { return 1.7; } private getJavaVersionTitle(): string { return "v" + this.getJavaVersion(); } }
  • 13.
    Inheritance, overriding class KaunasJugextends Jug { protected getJavaVersion(): number { return 1.8; } } function printUsersGroupLanguage(usersGroup: UsersGroup): void { console.log(usersGroup.getLanguage()); } printUsersGroupLanguage(new Jug()); printUsersGroupLanguage(new KaunasJug());
  • 14.
    Overloading interface UsersGroup { getLanguage(isUpperCase:boolean): string; getLanguage(versionPrefix: string): string; } class KaunasJug implements UsersGroup { getLanguage(property?: any): string { if (typeof property === 'boolean'){ return property ? "JAVA v1.8" : "Java v1.8"; } else if (typeof property === "string") { return "Java " + property + "1.8"; } } }
  • 15.
    Generics function printProperty<T>(property: T):void { console.log(property); } interface UserGroupArray<T extends Language> { add(... languages: T[]): void; printAllGroups(): void; }
  • 16.
    Lambdas (use aslittle as possible) class JavaUsersGroup { private city: string; constructor(city: string) { this.city = city; } public printTitle1(): void { console.log(this.city + " JUG"); } public printTitle2 = (): void => { console.log(this.city + " JUG"); }; }
  • 17.
    Modules module usersGroup { exportclass API { public static init(data: any) { new ViewModel(data.someJSON); } } class ViewModel { constructor(jsonDataToLoad: string) { console.log('Loading...'); } } class SomeInnerClass { } }
  • 18.
    External libraries  LargeAPI, difficult to use, hard to remember: actions, events, properties, sub modules...  For example: using selector you get jQuery object. You want to get it‘s specific child. Which method to use? Can you use the selector?  99% of developers would use google. More convenient to use ctrl+space and get the suggestion:  And if you try to do something ridiculous – the code won‘t compile:
  • 19.
    DefinetlyTyped - *.d.ts Declaration file (*.d.ts) describes the library or module  > tsc --declaration file.ts declare module usersGroup { class API { static init(data: any): void; } }
  • 20.
    Definition manager -tsd  LOTS of the *.d.ts files are here: https://github.com/borisyankov/DefinitelyTyped  But its hard to search and download... Is there a better way?  > npm install tsd –g  E.g. you want to use library lodash  Does it has lodash.d.ts file? Which version?  > tsd query lodash  Yes! It exists. We want to download lodash.d.ts file  > tsd install lodash –save  Using -save you wil store the information about installed *.d.ts in tsd.json
  • 21.
    Libraries without *.d.tsor legacy code  We are using super secret library...  In our project exists lots of legacy code...  But we still want to use TypeScript!  What to do?  Need to create declaration file for that library or legacy code (*.d.ts) interface A_Static { new(m: any): A_Instance; st: string; } interface A_Instance { inst: number; } declare var A: A_Static;
  • 22.
    Dependency management tools Internal modules  External modules: import $ = require('jquery');  commonJS  --module commonjs  AMD - requireJS  --module amd
  • 23.
    How to writeTypeScript correctly?  TypeScript also can be terrible... if its plain JavaScript  How to prevent it?  Use simple rules:  Every variable, property, or function result – must have defined data type  Never use any data type  Use same clean code conventions like in server side
  • 24.
    Decouple modules  Mostof the times JavaScript logic lives in one place  Large files tightly coupled in different ways  Impossible to do refactoring without bugs  How to solve it?  Decouple logic to different modules  Don‘t copy paste, just depend on some module  Define strict public API for integration with other modules
  • 25.
    Single responsibility forevery item  One module/class/method should be responsible just for one thing  Currently we are trying one approach:  If length of file is more than 200 lines – we should rethink: is it only responsible for one thing?  If length of method is more than 5 lines – we should rethink: is it only responsible for one thing?  In our project:  97% of files have <= 200 lines  72% of methods have <= 5 lines (in 4 files: ~200, ~180, ~150, ~120)
  • 26.
    Hide as muchas possible  Encapsulate code  Export only public API  One file - one module  Except – model entities  Much easier to refactor hidden code
  • 27.
    Try to keepcode in first level  JAVA developers can feel much more convenient by having source code in first level  Less complexity  Easyer to understand and support
  • 28.
    OK. But myfriend uses SunOS and VIM for editing source code. Can he..?  Sure thing!
  • 29.
    One more thing…Production needs one file rather than 3  For development we want all files: *.ts, *.js, *.js.map  But for production we want only one: compressed *.js  You can configure build scripts  E.g. maven resource filtering
  • 30.
    Large project. Lotsof code. How to test it?  Karma, Jasmine, Mocha, tsJunit, Qjunit, ...  Karma tests can be binded or decoupled from back end unit tests  Binded tests can be skipped together with java tests using –DskipTests  Decoupled tests can be skipped separate from java tests using custom properties
  • 31.
    Minuses in TypeScript Eclipse IDE  After compiler version update your code may be broken...
  • 32.