The future today! and more...
CoffeeScript Dart Haxe Opa
var one = 1;
var two = '2';
var three = one + two;
console.log(three);
"12"
false.toString();
"false"
[1,2,3].toString();
"1,2,3"
"2".toString();
"2"
2.toString();
Unexpected token ILLEGAL
02.toString();
"2"
2 .toString();
"2"
var settings = {
maxTax : 10
}
var product = {
price : 100,
tax : settings.maxTax/2,
discount : 20
};
var totalPrice = product.price + product.maxTax;
var afterDiscount = totalPrice - product.discount;
console.log(afterDiscount);
NaN
var x: string;
var y: number;
var z: boolean;
var foo: any;
var bar; // Same as "any"
var x;
var y;
var z;
var foo;
var bar;
var a: [];
var b: string[];
var p: Product[];
var a;
var b;
var p;
function calcPrice(products: Products[]):number {
.
.
.
}
function calcPrice(products) {
.
.
.
}
var func : (name:string) => number;
function process(x: () => string){
x().toLowerCase();
}
var func;
function process(x){
x().toLowerCase();
}function process(x: {a:string; b:number}){
return x.a.length;
}interface IThing {
a: number;
b: string;
}
function process(x: IThing){
return x.a.length;
}
function process(x){
return x.a.length;
}
function process(x){
return x.a.length;
}
interface IThing {
a: number;
b: string;
}
function process(x: IThing){
return x.b.length;
}
var n = process({a:10, b:'foo', c:'Extra field'});
function process(x){
return x.b.length;
}
var n = process({a:10, b:'foo', c:'Extra field'});interface IPerson {
age: number;
name: string;
address?: string; // <-- optional field
}
function getName(p: IPerson){
return p.name;
}
var name = getName({age:10, name:'Me'});
interface IPerson {
age: number;
name: string;
address: string;
walk(distance:number): number; // <-- a Function
}
interface IPerson {
age: number;
name: string;
address: string;
walk(distance:number): number;
walk(destination:string): number;
walk(location:{x:number, y:number}): number;
}
interface IPerson {
age: number;
name: string;
address: string;
walk(distance:number): number;
(): string; // <-- a Function
}
interface IHumanStatic {
MAX_AGE:number;
new():IHuman;
}
interface StringArray {
[index: number]: string;
}var x = 3; // x is a number
class MyClass {
name = "Foo"; // name is a string
}
function foo(value = false) { // value is a boolean
}
function calc() {
return 55; // calc returns a number
}
var x = calc(); // x is also a number
if (typeof x === "string") {
// x is a string
}
interface IHuman {
age: number;
walk(distance:number):void;
}
var man : IHuman = {
age : 120,
walk: function(distance) {
console.log(distance); // distance inferred to be a number
}
}
window.onmousedown = function(mouseEvent) {
// mouseEvent inferred as MouseEvent
console.log(mouseEvent.button);
};
var x = 3; // x is a number
x = "45"; // compiler error
var foo = {};
foo.description = 'I am FOO'; // compiler error
var person : IPersonModel = {}; // compiler error
var x : any = 3; // x can be anything
x = "45";
var foo : any = {};
foo.description = 'I am FOO'; // compiler is happy
var person : IPersonModel = <IPersonModel>{};
var x = [0, 1, null]; // x is number[]
var y = [0, 1, 'str']; // y is (string | number)[]
var x; // x is any forever
x = '45'; // x is still any
function process(x): { // x is any
return x+x*3; // return type is any
}
process(42); // this does not change the type of x
var x: serverAPI.giveMeXPlease();
if(typeof x === 'string') {
console.log(x.subtr(1)); // Error
}
// x is still any here
x.unknown(); // OK
class Dog { woof() { } }
class Cat { meow() { } }
var pet = serverAPI.getPet();
if(pet instanceof Dog) {
pet.woof(); // OK
} else {
pet.woof(); // Error
}
interface Animal {name: string; }
interface Cat extends Animal { meow(); }
function isCat(a: Animal): a is Cat {
return a.name === 'kitty';
}
var x: Animal;
if(isCat(x)) {
x.meow(); // OK, x is Cat in this block
}
declare var angular : any;17K lines of ambient declarations
eval, parseInt, encodeURI
Math, Date, RegExp
Full DOM declarations
And many more...
1458 contributors
15K commits
Thousands of definition files
node.d.ts
A word about tsd
interface IMemberDetails {
name:string;
email:string;
id:string;
owner:boolean;
}
interface IWixStatic {
addEventListener(eventName:string, cb:Function):void;
closeWindow(message:Object):void;
currentMember(cb:(member:IMemberDetails)=>void):void;
}
declare var Wix : IWixStatic;
declare module jasmine {
interface Matchers {
addMatchers(expected?: any): boolean;
toHaveBeenCalledOnce(): boolean;
toBeOneOf(expected?: any): boolean;
toHaveClass(expected?: any): boolean;
toBeDisabled(): boolean;
toMatchBiUrl(expected: any): boolean;
}
}
interface IOrderItemDTO {
title : string;
SKU : string;
option : string[];
price : number;
quantity : number;
total : number;
image : string;
}
interface IOrderDTO {
id : string;
items : IOrderItemDTO[];
createdDate : number;
quantity : number;
billingAddress : IAddressDTO;
shippingAddress : IAddressDTO;
buyerNote? : string;
currency : string;
}
class Order {
serialize(orderDTO:IOrderDTO) {
}
deserialize():IOrderDTO {
}
}
class Order implements IOrderDTO {
constructor(sourceOrderDTO:IOrderDTO) {
// copy to local variables
}
}
askedTime : number;
askedBy: Attendee;
answers? : boolean;
}
class SettingsData {
private m_padding : string;
get padding():string {
return this.m_padding;
}
set padding(value:string) {
this.m_padding = value;
}
}
var SettingsData = (function () {
function SettingsData() {
}
Object.defineProperty(SettingsData.prototype, "padding", {
get: function () {
return this.m_padding;
},
set: function (value) {
this.m_padding = value;
},
enumerable: true,
configurable: true
});
return SettingsData;
})();
class SettingsData {
private m_padding : string;
private m_WixSDK : IWixSDK;
private sendToSdk(paramName:string, paramValue:any) {
this.m_WixSDK.setSettings(paramName, paramValue);
}
get padding():string {
return this.m_padding;
}
set padding(value:string) {
if (value !== this.m_padding) {
this.m_padding = value;
this.sendToSdk('padding', this.m_padding);
}
}
}
class ReadOnlyData {
private m_id : number;
constructor() {
this.m_id = 0xF23256234;
}
get id():string {
return this.m_id ;
}
}
enum LogType {None, Warning, Error, Fatal}
function log(message:string, logType:LogType) {
}
var LogType;
(function (LogType) {
LogType[LogType["None"] = 0] = "None";
LogType[LogType["Warning"] = 1] = "Warning";
LogType[LogType["Error"] = 2] = "Error";
LogType[LogType["Fatal"] = 3] = "Fatal";
})(LogType || (LogType = {}));
function log(message, logType) {
}
var LogType = {
0: "None",
1: "Warning",
2: "Error",
3: "Fatal",
"None": 0,
"Warning": 1,
"Error": 2,
"Fatal": 3
}
enum LogType {None = 1000, Warning, Error, Fatal}
var logTypeStr = LogType[1000]; // "None"
var logTypeId : LogType = LogType["None"]; // 1000
enum LogType {
None = <any>"LOG_TYPE_NONE",
Warning = <any>"LOG_TYPE_WARNING",
Error = <any>"LOG_TYPE_ERROR",
Fatal = <any>"LOG_TYPE_FATAL"
}
var LogType = {
"LOG_TYPE_NONE": "None",
"LOG_TYPE_WARNING": "Warning",
"LOG_TYPE_ERROR": "Error",
"LOG_TYPE_FATAL": "Fatal",
"None": "LOG_TYPE_NONE",
"Warning": "LOG_TYPE_WARNING",
"Error": "LOG_TYPE_ERROR",
"Fatal": "LOG_TYPE_FATAL"
}
Decorators are called when the class is declared
Multiple decorators can be defined
Decorators are not allowed on constructors
Don't use arrow function inside the decorator
@MyClassDecorator
class Animal {
@MyPropertyDecorator
name : string;
@MyMethodDecorator
func1() {
}
func2(@MyParameterDecorator myParameter: string) {
}
}
function log(target, propertyKey, descriptor) {
// save a reference to the original method
var originalMethod = descriptor.value;
// override with our own implementation
descriptor.value = function(...args: any[]) {
console.log("The method args are: " + JSON.stringify(args));
var result = originalMethod.apply(this, args);
console.log("The return value is: " + result);
return result;
};
return descriptor;
}
class Foo {
@log
func1() {
}
}
function deprecated(target, name, descriptor) {
var original = descriptor.value;
descriptor.value = function() {
console.warn(`Function ${name} is deprecated.`);
return original.apply(target, arguments);
};
return descriptor;
}
class Foo {
@deprecated()
func1() {
}
}
class ProductWidgetStyleModel {
@sdkColor('nameColor', 0xFFFFFF)
nameColor;
@sdkFont('nameFont', 'Arial')
nameFont;
@sdkColor('dividerColor', 0xFF0000)
dividerColor;
@sdkUnit('dividerWidth', 20, 0, 245)
dividerWidth;
.
.
.
}
grunt-ts
tsd
tslint
reference.ts
tsconfig.json*
TBD:
The patterns
How we use it
Avoid $scope
Controller as
Use classes
Component based structure
function MyDirective():angular.IDirective {
function link() {
// link implementation
}
return {
restrict: 'E',
replace: true,
templateUrl: '<h1>I am a directive</h1>',
controller: MyDirectiveController,
link: link
}
}
No inheritance
No this, in the link function
interface IProduct {
name : string;
id : string;
}
var deferred : ng.IDeferred<IProduct> = $q.defer<IProduct>();
var p : ng.IPromise<IProduct> = deferred.promise;
p.then((product:IProduct) => { console.log(product.name)});
interface IProduct {
name : string;
id : string;
}
var deferred = $q.defer();
var p = deferred.promise;
p.then((product:IProduct) => { console.log(product.name)});
interface IProduct {
name : string;
id : string;
}
var deferred = $q.defer<IProduct>();
var p = deferred.promise;
p.then((product) => { console.log(product.name)});
interface IProduct {
name : string;
id : string;
}
function loadProducts():ng.IPromise<IProduct[]> {
}
loadProducts.then((products) => { console.log(products)});