Typescript
TypeScript is a typed superset of JavaScript that compiles to plain JavaScript.
Any browser. Any host. Any OS. Open Source.
Plan
- All the history about TS in details
- Biography of the creator
- A small code example to finish off.
Real PLAN
- I will tell you about TS in general
- A little about ES2015
- I will try to answer the question "Why TS?"
- Pros and Cons
- Type system
- Some runtime TS features
- Transpiled output
- How to start using TS in your project
- typescript@next
Overview
in general
HISTORY
- Developed And Maintained By Microsoft (I know, I know..)
- Introduced in October 2012 by Ander’s Hejlsberg
- First public appearance: October 1, 2012
Anders Hejlsberg, lead architect of C# and creator of Delphi and
Turbo Pascal, has been working on the development of
TypeScript
BACKSTORY
- Free & Open source language
- It is a “superset of JavaScript”
- Influenced By Javascript, Java, And C#
- Conforms to ECMA standards & proposals
- Rapidly becoming an Industry Standard (Angular 2)
- Build Plugins for maven, gradle, grunt, gulp, webpack
Any browser
I'm on the edge!
COMPATIBILITY
Any OS
TypeScript is a typed superset of JavaScript that compiles to plain JavaScript
COMPATIBILITY
ES5
ES2015
ES2016
TS
ES+
What is superset
COMPILE-TO-JS LANGUAGES
Good old standards...
What do we have?
- Dart
- elm
- CoffeeScript
- PureScript
- TypeScript
- ...
Note: there are hundreds of other solutions...
https://github.com/jashkenas/coffeescript/wiki/list-of-languages-that-compile-to-js
WHO is USING TYPESCRIPT
ES2015
AKA ES6
May '95
Dec '95
Sep '95
1997
Aug '96
1999
1998
2009
2003
2015
2011
2016
Mocha (Brendan Eich, Netscape)
LiveScript
JavaScript
Edition 1
JScript (Microsoft)
Edition 2
Edition 3
Edition 4
Edition 5
Edition 5.1
Edition 6
Edition 7
ECMA-262 specification
- Latest finalised version ECMAScript 2015
- Change to yearly naming convention (ES7 = ES2016)
History
WHAT IS Es2015?
- ECMAScript 2015, also known as ECMAScript 6 is the upcoming version of the ECMAScript standard.
- This standard is ratificationed in June 2015.
- ES6 is a significant update to the language, and the first update to the language since ES5 was standardized in 2009.
CLASS
ES6 classes are 'syntactic sugar' on top of prototypal inheritance
class Client {
constructor(firstname, lastname) {
this.id = undefined
this.firstname = firstname
this.lastname = lastname
}
getFullName() {
return this.firstname + this.lastname
}
generateId() {
this.id = generateGuid()
}
}
STATIC METHODS
class Client {
constructor(firstname, lastname) {
this.id = undefined
this.firstname = firstname
this.lastname = lastname
}
getFullName() {
return this.firstname + this.lastname
}
generateId() {
this.id = generateGuid()
}
static generateGuid() {
function s4() {
return Math.floor((1 + Math.random()) * 0x10000)
.toString(16)
.substring(1)
}
return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
s4() + '-' + s4() + s4() + s4()
}
}
- Can't be called on an instantiated class
- No access to 'this' properties/methods
- Most useful when associated with class, but don't need unique variables of instanced class
ES6 introduces the 'extend' keyword
class TCSClient extends Client {
this.evalSystem = "TCS"
}
ES6
class TCSClient extends Client {
getFullName() {
return this.firstname + " " +
this.lastname
}
}
ES6
Can override functions by re-implementing them in child class
INHERITANCE
MODULES
class ClientService {
clients = [];
addClient(client) {
this.clients.add(client);
}
}
export ClientService;
import {ClientService} from './ClientService';
class ClientComponent {
submitClient(client) {
ClientService.addClient(client);
}
}
In ES6 each module is defined in its own file. The functions or variables defined in a module are not visible outside unless you explicitly export them.
main.js
ClientService.js
LET
- Alternatives to declaring a variable with 'var'
- 'let' block-scopes variables rather than var's function- scoping
var x = 1;
if (x) {
let x = 2;
}
console.log(x);
> 1
ES6
Console
- Using 'let' allows for block-scoping ( {} )
- Maintains encapsulation principles
- Allows same variable names where appropriate
const stuff = { things: ['chair', 'desk', 'computer'] };
const stuff = { things: ['chair', 'desk', 'computer'] };
stuff = {}; // fails
console.log(stuff.things); // ...
const stuff = { things: ['chair', 'desk', 'computer'] };
stuff.things.push('pot plant');
console.log(stuff.things);
// chair,desk,computer,pot plant
- Also block-scoped
- Must be decalred using an initializer
- Can only be assigned to once
- Will fail silently if assigned again
- Does not make the assigned value itself immutable
CONST
ARROW FUNCTIONS
- Also known as lambda expressions
- Makes code more 'terse'
var arrow = function() {}
var arrow = () => {}
becomes
function() {}
() => {}
becomes
- 'return' keyword implied for single expressions in function body
- No parentheses required for 1 argument
function(a) { return a * a }
a => a * a
becomes
- Parentheses for 0, or >1 arguments
function(a, b) { return a + b }
(a, b) => a + b
becomes
- A 'fat arrow' takes the place of the 'function' keyword
ARROW FUNCTIONS
function Counter() {
this.seconds = 0;
setInterval(function() {
this.seconds++
}.bind(this), 1000);
}
function Counter() {
this.seconds = 0;
setInterval(() => this.seconds++, 1000);
}
- Arrow functions are bound to their lexical scope
- 'this' in an arrow function is the same as the outer scope
- Best used for functions with low amount of arguments/statements
ES5
ES6
ARROW FUNCTIONS
var text = `
This is a template literal
'It can span multiple lines'
"And can contain quotation marks"
`
var text = (
'This is the old method\n' +
'for strings spanning\n' +
'several lines'
)
var text = [
'Or',
'perhaps',
'this'
].join('\n')
- A string wrapped in backticks ( ` )
- Can be multiline
- Strings can contain ' and " characters without escaping
ES5
ES6
TEMPLATE LITERALS
var text = `the time and date is ${new Date().toLocaleString()}`
var a = 6;
console.log(`The number is ${a}`)
Can interpolate expressions with ${expression}
TEMPLATE LITERALS
let myObject = { foo:'bar', baz: 'qux' };
//....
let { foo, baz } = myObject
console.log(foo) // 'bar'
console.log(baz) // 'qux'
An object literal lets us create multiple properties at the same time
An object pattern lets us extract multiple properties at the same time
Properties mapped to aliases
ASSIGNMENT DESTRUCTURING
function swapIf () {
var left = 10;
var right = 20;
var aux;
if(right > left) {
aux = right;
right = left;
left = aux;
}
}
function swapIf () {
var left = 10
var right = 20
if(right > left) {
[left, right] = [right, left]
}
}
Can swap variables without need for a temporary variable
ES5
ES6
ASSIGNMENT DESTRUCTURING
function displayNameAge ( {name, age} ) {
console.log(`${name} is ${age} years old`)
}
displayNameAge( { age: 27, name: 'John'} ) // 'John is 27 years old'
Can destructure a function's parameter list
ASSIGNMENT DESTRUCTURING
function getCoordinates() {
return {
x: 5,
y: 22
}
}
var {x, y} = getCoords()
console.log(x) // 5
console.log(y) // 22
function getCoordinates() {
return {
x: 5,
y: 22
}
}
var object = getCoordinates();
var x = object.x;
var y = object.y;
console.log(x) // 5
console.log(y) // 22
Possible use cases
More terse interaction with returned objects
ES5
ES6
ASSIGNMENT DESTRUCTURING
WHY TYPESCRIPT?
WHY USE TYPESCRIPT?
- Better overall code readability in large codebases
- Ease of refactoring
- Use new ES6 features in older browsers
- IntelliSense auto suggest in code editors
Dynamic
TYPING....
Static
JavaScript, Python,
Ruby, PHP
C, C++, C#, Java, Fortran, Haskell
var number = 5;
number = "Hello!";
//👍np, bro!
int a = 10;
a = "Hello!";
//🔥Compiler Error
JAVASCRIPT
function numberCruncher (numA, numB){
return numA + numB;
}
var result = numberCruncher(5, 5);
console.log(result);
>> 10
result = numberCruncher(5, true);
console.log(result);
>> 6 😒
result = numberCruncher(5, 'js4lyfe');
console.log(result);
>> "5js4lyfe" 😁
result = numberCruncher(5, {param: true});
console.log(result);
>> "5[object Object]" 👀🔫
TYPING WITH TYPESCRIPT
function myTypedFunction(paramName : dataType) : returnType {
// Regular junk here
}
var varName : string = 'Yeah baby!';
Type a variable:
Type a function:
function trimLength(inputVal : string) : number {
return inputVal.trim().length;
}
Available Types:
Standard JS Types: Boolean, Number, String, Array
Also includes Enum, Any, Void
A function that returns nothing
VOID
function initSomething() : void {
doSomeStuff();
}
var pointless = initSomething(); // 🍋Compiler Error
ANY
Restores basic JavaScript dynamic typing behavior
var foo : any;
declare var jQuery : any;
jQuery.get('/awesome.html');
foo = 'Hello!';
foo = true;
foo = 42;
Proof
export interface UserPositionInfo {
jobFunctionId?: number;
title?: string;
level: number;
}
export interface SidebarItem {
name?: string;
iconUrl?: string;
applicationUrl?: string;
}
export interface AppContextVM {
userId: number;
userName?: string;
isDev: boolean;
currentPosition?: UserPositionInfo;
sidebarItems?: SidebarItem[];
}
JAVA TYPES
CRAZY OOP DIAGRAMS
People thoughts
AREN'T WE ALREADY USING TYPES?
WHY TYPESCRIPT?
- Provide an optional type system for JavaScript
- Provide planned features from future JavaScript editions to current JavaScript engines
- Types increase the agility when doing refactoring
- Types are one of the best forms of documentation you can have.
TYPESCRIPT is JAVASCRIPT
- TypeScript is a superset of JavaScript
- TypeScript provides compile time type safety for JavaScript code
- Types in TypeScript are completely optional
- .js file can be renamed to .ts file and TypeScript will still compile to .js equivalent to the original*
WHY USE TYPESCRIPT?
- It's JavaScript, but better...with intellisense and API help
- Smaller Transpiled output than ES2015's
- Help's Identify Bugs during design... instead of after deployment
- Easy to configure
- Better overall code readability in large codebases
- Ease of refactoring
- IntelliSense auto suggest in code editors
DESIGN TIME ANALYSIS
- Finding bugs earlier in your development process
- Fix a bug in your logic at design time rather than fixing the bug at run time.
- Runtime bugs can slip under a crack in your logic and lurk there (sometimes for months) until discovered.
TypeScript IS JAVASCRIPT AT SCALE
- Checks code on the fly at design time
- Compatible with most editors, via plugins to:
- Provides custom code completion
- Error identification via tooltips (with plugin support)
- Allows you to catch bugs prior to JS build
- Compatible with most editors, via plugins to:
- Transpiles to ES5
- tsc watcher for compiling on save
- ES5 output is ~HALF the size of Babel’s
Pros and Cons
of using typescript
Benefits
- Static analysis
- You'll always know how the object works
- The IDE will also help (autocomplete)
- Nobody will add arbitrary variables
- ES Compatibility
- Matured technology
- Well supported
- 'JavaScript safe'
pros and cons
Static typing
Cons
Pros
- Documentation
- IDE support
- Detection of mistakes
- More verbose
- d.ts
- Delay in developing high-end features (like JSX)
IT'S ES2015!
- Arrow Functions
- Spread
- Block scoping (let & const)
- Classes with constructors, get/set
- Enhanced Object Literals
- Template Strings
- Destructuring
- Iterables and Iterators
Plus
- Types
- Decorators (from ES7)
- Generics
- Enums!
- Class Extensions
- Access Modifiers
- Interfaces
- Namespaces
TYPE ANNOTATIONS
FUNCTION PARAMETERS
/**
* @param {string} msg Message to display.
*/
function Display(msg) {
console.log(msg);
}
/**
* @param {boolean} [loud=false] Greet "loudly".
*/
function Greet(loud) {
if (typeof loud === 'undefined') {
loud = false;
}
var msg = "Hello World";
console.log(loud ? msg.toUpperCase() : msg);
}
/**
* @param msg Message to display.
*/
function Display(msg: string) {
console.log(msg);
}
/**
* @param loud Greet "loudly".
*/
function Greet(loud: boolean = false) {
var msg = "Hello World";
console.log(loud ? msg.toUpperCase() : msg);
}
function Display(msg) {
console.log(msg);
}
function Greet(loud) {
if (typeof loud === 'undefined') {
loud = false;
}
var msg = "Hello World";
console.log(loud ? msg.toUpperCase() : msg);
}
CLASS PROPERTIES
class Person {
name: string;
age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
}
/**
* @class Person
* @param {string} name
* @param {number} age
*/
function Person(name, age) {
/**
* @name Person#name
* @type string
*/
this.name = name;
/**
* @name Person#age
* @type number
*/
this.age = age;
}
function Person(name, age) {
this.name = name;
this.age = age;
}
INCORRECT USAGE
var person = new Person("Dima", 23);
person.talks()
RUNTIME ERROR
Uncaught TypeError: undefined is not a function
COMPILER ERROR
Property 'talks' does not exist on type 'Person'.
We're Not Writing C
It's not about telling the computer how to store data, it's about validating your assumptions.
Types
Class, inheritance, interface, generic, type inering
TYPESCRIPT TYPES
var num: number = 123;
function identity(num: number): number {
return num;
}
identity('string'); // error!
var myNumbers : number[] = [170, 2.6, 2245, 3032, 400];
Void type represents the absence of a value and is used similar to null and undefined
Void TYPE
var n: number = null; // Primitives can be null
var x = null; // Same as x: any = null
var x: void = null; // Correct
x = 2; // Error
var e: Null; // Error, can't reference Null type
VOID & ANY
function initSomething() : void {
doSomeStuff();
}
var pointless = initSomething(); // Compiler Error
// if you absolutely have to (don't do it young Jedi!)
var foo : any;
foo = 'Hello!';
foo = true;
foo = 42;
Functions
-
In TypeScript every parameter to a function is assumed to be required by the function.
-
The number of parameters to the function has to match with the number of parameters the function expects.
REQUIRED PARAMETERS
function fullName(firstName: string, lastName: string) {
return firstName + " " + lastName;
}
var result1 = fullName("Bob"); //error, too few parameters
var result2 = fullName("Bob", "Adams", "Sr."); //error, too many parameters
var result3 = fullName("Bob", "Adams"); //ah, just right
-
In JavaScript, every parameter is considered option and assumed to be undefined.
-
Using the '?' to denote option parameters in TypeScript
OPTIONAL PARAMETERS
function fullName(firstName: string, lastName?: string) {
if (lastName)
return firstName + " " + lastName;
else
return firstName;
}
var result1 = fullName("Bob"); //works correctly now
var result2 = fullName("Bob", "Adams", "Sr."); //error, too many parameters
var result3 = fullName("Bob", "Adams"); //ah, just right
OPTIONAL PARAMETERS
buildName(firstName: string, lastName?: string {
if (lastName) {
return firstName + ' ' + lastName;
} else {
return firstName;
}
}
let result1 = buildName('Steve'); // 'Steve'
let result2 = buildName('Steve', 'Hartzog'); // 'Steve Hartzog'
// Compiler error, too many parameters
let result3 = buildName('Steve', 'Hartzog', 'Jr.');
We can also set up a value that an optional parameter will have if the user does not provide one.
DEFAULT PARAMETERS
function fullName(firstName: string, lastName = "Smith") {
return firstName + " " + lastName;
}
var result1 = fullName("Bob"); //works correctly now, also
var result2 = fullName("Bob", "Adams", "Sr."); //error, too many parameters
var result3 = fullName("Bob", "Adams"); //ah, just right
-
Use to group multiple parameters into one.
-
Similar to argument in JavaScript
REST PARAMETERS
function buildName(firstName: string, ...restOfName: string[]) {
return firstName + " " + restOfName.join(" ");
}
var employeeName = buildName("Joseph", "Samuel", "Lucas", "MacKinzie");
CLASSES
Very similar to classes in C# or Java
CLASS MODEL
class Point {
x: number;
y: number;
constructor(x: number, y: number) {
this.x = x;
this.y = y;
}
add(point: Point) {
return new Point(this.x + point.x, this.y + point.y);
}
}
class Person {
constructor(name) {
this.name = name;
}
greet() {
return 'My name is ' + this.name;
}
}
var annabelle = new Person('Annabelle');
console.log(annabelle.greet());
// > My name is Annabelle
class Person {
constructor(public name: string) { }
greet(): string {
return 'My name is ' + this.name;
}
}
var annabelle = new Person('Annabelle');
console.log(annabelle.greet());
// > My name is Annabelle
ES6
TypeScript
Class
Classes in TypeScript support single inheritance using the extends keyword
INHERITANCE
class Point3D extends Point {
z: number;
constructor(x: number, y: number, z: number) {
super(x, y);
this.z = z;
}
add(point: Point3D) {
var point2D = super.add(point);
return new Point3D(point2D.x, point2D.y, this.z + point.z);
}
}
ACCESS MODIFIERS
class FooBase {
public x: number;
private y: number;
protected z: number;
}
// EFFECT ON INSTANCES
var foo = new FooBase();
foo.x; // okay
foo.y; // ERROR : private
foo.z; // ERROR : protected
- public: available everywhere on instances
- private: not available for access outside the class
- protected: available on child classes but no on instances directly
class FooChild extends FooBase {
constructor(){
super();
this.x; // okay
this.y; // ERROR: private
this.z; // okay
}
}
INTERFACE
can be substituted for another interface type or object type literal with an identical set of members.
INTERFACE AS TYPE
interface IPlant{
name: string;
genus: string;
category: string;
}
var plant: IPlant;
plant = new Plant();
class Plant{
name: string;
genus: string;
category: string;
}
Interface can be used to constrain a set of classes to implement the same set of properties or functions.
INTERFACE AS TYPE
class tree implements IPlant {
name: string;
genus: string;
category: string;
}
// TypeScript would produce an error
// because the "flowers" class does not
// implement a "genus" category
class flowers implements IPlant {
name: string;
category: string;
}
interface IPlant{
name: string;
genus: string;
category: string;
}
GENERICS
that will accept any and all types for the type of 'arg'. However, we lose the information about what type was when the function returns
'ANY' KEYWORD
function identity(arg: any) {
return arg;
}
var output1 = identity('hello') // output is string
var output2 = identity(123) // output is number
This 'T' allows us to capture the type the user provides, so we know the return type of the function.
'T' GENERIC TYPE
function identity<T>(arg: T): T {
return arg;
}
var output1 = identity<string>('hello') // type of output is string
var output2 = identity(123) // type of output is number
var output3 = identity<boolean>(true) // type of output is boolean
Generic Constraints
Here, we’ll create an interface that has a single .length property and then we’ll use this interface and the extends keyword to denote our constraint:
interface Lengthwise {
length: number;
}
function loggingIdentity<T extends Lengthwise>(arg: T): T {
console.log(arg.length);
return arg;
}
Union Types
Occasionally, you’ll run into a library that expects a parameter to be either a number or a string. For instance, take the following function:
function padLeft(value: string, padding: string | number) {
// ...
}
// errors during compilation
let indentedString = padLeft("Hello world", true);
Intersection Types
type LinkedList<T> = T & { next: LinkedList<T> };
interface Person {
name: string;
}
var people: LinkedList<Person>;
var s = people.name;
var s = people.next.name;
var s = people.next.next.name;
var s = people.next.next.next.name;
Intersection types are closely related to union types, but they are used very differently.
String Literal Types
type Easing = "ease-in" | "ease-out" | "ease-in-out";
class UIElement {
animate(dx: number, dy: number, easing: Easing) {
if (easing === "ease-in") {
// ...
}
else if (easing === "ease-out") {
}
else if (easing === "ease-in-out") {
}
else {
// error! should not pass null or undefined.
}
}
}
let button = new UIElement();
button.animate(0, 0, "ease-in");
button.animate(0, 0, "uneasy"); // error: "uneasy" is not allowed here
String literal types allow you to specify the exact value a string must have.
declaration file
When using an external JavaScript library, or new host API, you'll need to use a declaration file (.d.ts) to describe the shape of that library.
declare class Tether {
constructor(options: Tether.ITetherOptions);
public setOptions(options: Tether.ITetherOptions): void;
public enable(): void;
public static position(): void;
}
declare namespace Tether {
interface ITetherOptions {
classes?: {[className: string]: boolean};
classPrefix?: string;
constraints?: ITetherConstraint[];
element?: HTMLElement | string | any /* JQuery */;
}
interface ITetherConstraint {
attachment?: string;
pin?: boolean | string[];
to?: string | HTMLElement | number[];
}
}
declare module "tether" {
export = Tether;
}
type inference
In TypeScript, there are several places where type inference is used to provide type information when there is no explicit type annotation. For example, in this code
let x = 3; // The type of the x variable is inferred to be number.
function createZoo(): Animal[] {
return [new Rhino(), new Elephant(), new Snake()];
}
let zoo = createZoo(); // It is Animal[]
function echo<T>(value: T) {
return value;
}
let numb = echo<number>(2); // numb is number
let text = echo('Some'); // text is string
SHOULD WE LOVE
Why should we love TypeScript?
- Code Completion
- Find Occurrences
- Refactoring
- List Parameters
- Go To Definition
- Inline Errors
MOST PRE-EXISTING JAVASCRIPT
IS ALREADY VALID TYPESCRIPT
var items = getItems();
var goSportsTeam = true;
var letter = 'z';
some-javascript.js
some-typescript.ts
Static Types
ECMAScript 6
...and more!
What does it give us?
Runtime features
Enum, namespace
ENUMS
enum CardSuit {
Clubs,
Diamonds,
Hearts,
Spades
}
// Sample usage
var card = CardSuit.Clubs;
switch (myCard.suit) {
case CardSuit.Clubs:
console.log(CardSuit.Clubs);
break;
otherwise:
console.log('Not a club.');
}
NAMESPACES
- aka Internal Modules
- Reduce global footprint
- Open to be extended
- No Helper libraries required
namespace my.example {
export function doSmth(){
// Actions
}
}
// Somewhere else
console.log(my.example.doSmth())
Output
TYPESCRIPT TRANSPILATION
TRANSPILATION
- No type checking required in our code
- No type checking added into the output
// ES2015
doSomething (smidge) {
if (smidge instanceOf repo
&& smidge.myProp) {
let a = smidge.myProp;
}
//...
}
// Transpiled ES5
function doSomething (smidge) {
if (smidge instanceOf repo
&& smidge.myProp) {
var a = smidge.myProp;
}
//...
}
// TypeScript
doSomething (smidge:repo) {
let a = smidge.myProp;
...
}
// Transpiled ES5
function doSomething (smidge) {
var a = smidge.myProp;
...
}
GETTERS/SETTERS
JAVASCRIPT
function Troll() {}
Object.defineProperty(Troll.prototype, "message", {
get: function () {
return "You mad bro?";
},
set: function (msg) {
console.log("Cool message bro ...");
}
});
TYPESCRIPT
class Troll {
get message() {
return "You mad bro?";
}
set message(msg) {
console.log("Cool message bro ...");
}
}
TRANSPILED
var Troll = (function () {
function Troll() {
}
Object.defineProperty(Troll.prototype, "message", {
get: function () {
return "You mad bro?";
},
set: function (msg) {
console.log("Cool message bro ...");
},
enumerable: true,
configurable: true
});
return Troll;
})();
FUNCTIONS
JAVASCRIPT
function DoSomethingCool() {
// no ...
}
TYPESCRIPT
function DoSomethingCool() {
// no ...
}
TRANSPILED
function DoSomethingCool() {
// no ...
}
ARROW FUNCTIONS
JAVASCRIPT
function Fetcher () {};
Fetcher.prototype.massageIt = function (data) {
return data;
};
Fetcher.prototype.fetchStuff = function () {
var _this = this;
return getJSON("/stuff").then(function (data) {
return _this.massageIt(data.data);
});
};
TYPESCRIPT
function Fetcher () {}
Fetcher.prototype.massageIt = function (data) {
return data;
};
Fetcher.prototype.fetchStuff = function () {
return getJSON("/stuff").then((data) => {
return this.massageIt(data.data);
});
};
TRANSPILED
function Fetcher() {
}
Fetcher.prototype.massageIt = function (data) {
return data;
};
Fetcher.prototype.fetchStuff = function () {
var _this = this;
return getJSON("/stuff").then(function (data) {
return _this.massageIt(data.data);
});
};
DEFAULT PARAMETERS
JAVASCRIPT
function Say(words) {
if (typeof words === 'undefined') {
words = "Hello World";
}
console.log(words);
}
TYPESCRIPT
function Say(words = "Hello World") {
console.log(words);
}
TRANSPILED
function Say(words) {
if (words === void 0) { words = "Hello World"; }
console.log(words);
}
REST PARAMETERS
JAVASCRIPT
function Add(/* ...values */) {
var slice = Array.prototype.slice,
values = slice.call(arguments);
return values.reduce(function (sum, value) {
return sum + value;
});
}
TYPESCRIPT
function Add(...values) {
return values.reduce((sum, value) => sum + value);
}
TRANSPILED
function Add() {
var values = [];
for (var _i = 0; _i < arguments.length; _i++) {
values[_i - 0] = arguments[_i];
}
return values.reduce(function (sum, value) {
return sum + value;
});
}
TEMPLATE STRINGS
JAVASCRIPT
var name = "Dima",
age = 23;
console.log("My name is " + name + ". I'm " +
age + " years old")
TYPESCRIPT
var name = "Dima";
var age = 23;
var isFree = true;
console.log(`My name is ${name}. I'm ${age} years old
and I'm ${isFree ? '' : 'not'} free`);
TRANSPILED
var name = "Dima";
var age = 23;
var isFree = true;
console.log("My name is " + name + ". I'm " + age
+ " years old \n and I'm "
+ (isFree ? '' : 'not') + " free");
MODULES
JAVASCRIPT
var MyModule = MyModule || {};
MyModule.Foo = "Bar";
MyModule.LogFoo = function () {
console.log(MyModule.Foo);
};
TYPESCRIPT
namespace my.example {
export function doSmth(){
// Actions
}
}
TRANSPILED
var my;
(function (my) {
var example;
(function (example) {
function doSmth() {
// Actions
}
example.doSmth = doSmth;
})(example = my.example || (my.example = {}));
})(my || (my = {}));
// Somewhere else
console.log(my.example.doSmth());
How to start using TS in your project?
without sms and registration
TODO
- Start using ES2015 modules
- Install TypeScript
- Configure TypeScript
- Add TypeScript support to your IDE
- Add typings to the libs in your project
- Set up building system like webpack
- Configure webpack
Install TypeScript
The command-line TypeScript compiler can be installed as a Node.js package.
# INSTALL
npm install -g typescript
#COMPILE
tsc helloworld.ts
EASY TO CONFIGURE
tsconfig.json
{
"compilerOptions": {
"jsx": "react",
"module": "commonjs",
"noEmitOnError": true,
"outDir": "./dist/",
"removeComments": true,
"allowJs": true
},
"files": [
"./index.ts" // Entry point
]
}
TypeScript Editor Support
alm.tools
Atom
Eclipse
Emacs
NetBeans
Sublime Text
Vim
Visual Studio
Visual Studio Code
WebStorm
Typings
The TypeScript Definition Manager
# Install Typings CLI utility.
npm install typings --global
# Install i.e. React.js
typings install --save --ambient react
# If you use the package as a module:
# Install non-ambient typings
typings install chai --save
# If you use the package through script tag, or
# it is part of the environment, or
# the non-ambient typings is not yet available:
# Install ambient typings
typings install mocha --ambient --save
Webpack
- ts-loader - Choose it if you have small project.
-
awesome-typescript-loader - For big projects
- Incremental building
- Cache
- Fork Checking
- Babel
...
module: {
loaders: [{
test: /\.tsx?$/,
loader: 'awesome-typescript',
include: [path.resolve(path.join(__dirname, "src"))],
query: {
doTypeCheck: true,
useCache: true,
forkChecker: true,
usePrecompiledFiles: true,
tsconfig: './src/tsconfig.json',
cacheDirectory: __dirname + '/.awcache'
}
}]
}
...
DOC GENERATOR
typescrpt@next
What future versions wil include
V 2.0
- Non-nullable types
- Control flow based type analysis
- Readonly properties
- Use path mappings in module resolution
- Support private and protected constructors
- Support abstract properties
- Support for UMD module definitions
- async/await and generators support for ES5/ES3
- Type guards on property access
- Glob support in tsconfig.json
- Decorators for function expressions/arrow functions
- ...
V 2.1
- Support ES8 object property spread and rest
- Variadic types
- Deprecated decorator
- Support for project references
- ...
SUMMARY
- As open as JavaScript.
- It IS ES2015, plus some features.
- Smaller, simpler output than babel.
- Advantages at scale.
- Helps catch bugs at design time.
- Custom Code Completion.
- Easy to integrate into existing build.
- Plugins for all dev environments.
- Simple to convert.
CONCLUSION
Matured technology
Well supported
'JavaScript safe'
Must have in every project
One more thing!
A little story
about react.js, modules and migrations
aT THE BEGINING...
- No direct imports, just use as is
- No webpack, gulp, npm and other stuff
- .NET build everything: JS, TS, CSS...
Preparation
We decided to move to main-stream front-end Technologies
- First we needed to start use modules
- Common.js - only relative require
- AMD - not so popular
- Builder
- Gulp - just plain task runner
- webpack - Module shim
- LESS and Typescript compiler
- less-loader for LESS
- awesome-typescript-loader for TypeScript
- Start using NPM as most as possible
Problems
- Architecture - how to organise folders
- Module injections
- Case sensivity
- Build speed
- Integration to Visual Studio
- Circule dependencies
File organising
Module injections
Case sensivity
Build speed
Circule dependencies
Useful links
http://www.typescriptlang.org - TypeScript
http://www.typescriptlang.org/play/index.html - Sandbox
https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md - TypeScript Language Specification
https://www.gitbook.com/book/basarat/typescript - TypeScript Deep Dive
https://www.youtube.com/watch?v=r_yBvQxEbFg - Введение в TypeScript
https://www.youtube.com/watch?v=_3n4JdZdXWo - Разработка на TypeScript
https://github.com/s-panferov/awesome-typescript-loader - Loader for webpack
THANKS FOR YOUR ATTENTION
Typescript
TypeScript
By Dima Pikulin
TypeScript
JavaScript that scales
- 1,550