Tomasz Ducin
independent consultant, architect, developer, trainer, speaker #architecture #performance #javascript #typescript #react #angular
Tomasz Ducin
22nd April 2017, Warsaw
Tomasz Ducin
14th February 2017, Warsaw
Tomasz Ducin
8th February 2017, Warsaw
Tomasz Ducin
31st January 2017, Warsaw
Tomasz Ducin
30th September 2016, Warsaw
Tomasz Ducin
23rd September 2016, Praha
Tomasz Ducin
8th September 2016, Warsaw
Tomasz Ducin
15th June 2016, Darmstadt
Tomasz Ducin
8th June 2016, Warsaw
Tomasz Ducin
23rd April 2016, Szczecin
Tomasz Ducin
11th April 2016, Warsaw
software developer @ Ivanti
trainer @ Bottega IT Solutions
blah, blah, blah...
function objectRange(obj, times) {
...
}
function objectRange(obj: Object, times: number) {
...
}
function objectRange(obj: Object, times: number): Object[] {
...
}
module myModule {
function objectRange(obj: Object, times: number): Object[] {
...
}
...
}
module myModule {
interface Person {
name: string;
age: number;
}
class MyClass {
private varA: typeA;
constructor(varB: typeB) {...}
public objectRange(obj: Object, times: number): Object[] {
...
}
}
...
}
function objectRange<T>(obj: T, times: number): T[] {
var result: T[] = [];
for (var i = 0; i < times; i++) {
result.push(obj);
}
return result;
}
module cash {
export interface Payment {
amount: number;
account: string;
}
}
var payments = objectRange<cash.Payment>({
"amount":12.34,
"account": "1234 5678 90"
}, 5);
console.log(payments);
function objectRange<T>(obj: T, times: number): T[];
module cash {
export interface Payment {
amount: number;
account: string;
}
}
x
x
x
x
think about the problems you solve,
NOT the tools
~98% aware of TS existence
~72% doesn't know TS / only ~28% does
~53% interested in learning / ~47% not
~85% satisfaction with TS
just what I wanted to say is, please try not introduce new technologies and thereby complexities without having a good reason to do so... For now we have a lot to cope with, So if you guys keep racing then we don't have a chance to get somehow on the same boat.
the purpose of a programming language is to aid programmers in producing error-free programs
test.ts(5,5): error TS2345: Argument of type 'string'
is not assignable to parameter of type 'number'.
var a: boolean;
let f = false;
const t: boolean = true;
var a: number = 5;
let b: number;
const c = 20;
var a: string = 'John';
let name: string = `${a}`;
const c = "training";
var boolList: Array<boolean>
let boolList: boolean[]
const cList: boolean[] = [];
cList.push(true);
same
const
as ES6
function fullName(first, last) {
return first + ' ' + last;
}
function fullName(first, last): string {
return first + ' ' + last;
}
function fullName(first: string, last: string) {
return first + ' ' + last;
}
function fullName(first: string, last: string): string {
return first + ' ' + last;
}
type Oper = (a: number, b: number) => number;
const add: Oper = (a, b) => a + b;
const sub: Oper = (a, b) => a - b;
const mul: Oper = (a, b) => a * b;
const div: Oper = (a, b) => a / b;
get(url: string,
data?: Object|string,
success?: (data: any, textStatus: string, jqXHR: JQueryXHR) => any,
dataType?: string
): JQueryXHR
jQuery.get(...)
type
interface Person {
first: string;
last: string;
}
interface Person {
first: string; // required
last: string; // required
age?: number; // optional
}
interface Address {
city: string;
country: string;
postcode?: string;
}
interface Person {
first: string; // required
last: string; // required
age?: number; // optional
addresses: Address[];
}
type Currency =
"EUR" | "GBP" | "USD" | "AUD" | "CAD";
type Season =
"spring" | "summer" | "autumn" | "winter";
let currentSeason: Season = "autumn"
currentSeason = "cucumber" // ERROR
type Currency =
"EUR" | "GBP" | "USD" | "AUD" | "CAD" | "NZD"
type MoneyTuple = [number, string]
let m: MoneyTuple = [4.99, "EUR"]
type MoneyTuple = [number, Currency]
let m1: MoneyTuple = [4.99, "EUR"]
let m2: MoneyTuple = [4.99, "PLN"] // ERROR
enum Directions {
Up, Down, Left, Right
}
lets moves: Directions[] = [
Directions.Right
Directions.Up,
Directions.Right
Directions.Left,
Directions.Up,
Directions.Up,
Directions.Up,
Directions.Left,
Directions.Down,
Directions.Up,
Directions.Left,
Directions.Down,
];
interface IPerson {
firstName: string,
lastName: string
}
type PersonString = string
type PersonTuple = [string, string]
type UberPerson = IPerson
| PersonString
| PersonTuple
function greet(person: UberPerson) {...}
greet("John Lennon")
greet(["John", "Lennon"])
greet(["John", "Lennon", 40]) // ERROR
greet({ firstName: "John", lastName: "Lennon" })
greet({ firstName: "John", lastName: "Lennon", age: 40 }) // ERROR
interface Person {
first: string;
last: string;
age?: number;
}
interface Citizen {
regNo: string;
bankAccount: string;
}
const john: Person & Citizen = {
first: "John",
last: "Lennon",
regNo: "957204578204",
bankAccount: "94 9834 0956 1238 5499"
}
assert.isString
assert.isNumber
assert.isBoolean
problem exists in all weakly-typed languages
interface AccountingSummary {
id: string;
items: AccoutningItem[];
price: Amount;
signedBy?: Employee;
submittedBy?: Employee;
}
class Department {
public generateSummary(...): AccountingSummary {
... // long method
};
...
}
let foo = 123;
let bar = "Hello";
let foo = 123; // foo is a `number`
let bar = "Hello"; // bar is a `string`
foo = bar;
// Error: cannot assign
// `string` to a `number`
let foo = 123; // foo is a `number`
let bar = "Hello"; // bar is a `string`
// JS
var a = 4;
var b = 5;
var c = a * b;
// c == 20
// JS
var a = "hello";
var b = "world";
var c = a * b;
// c == NaN
// TS
var a: string = "hello";
var b: string = "world";
var c: string = a * b;
// TS
var a = "hello";
var b = "world";
var c = a * b;
test.ts(4,5): error TS2322: Type 'number' is not assignable to
type 'string'.
test.ts(4,17): error TS2362: The left-hand side of an arithmetic
operation must be of type 'any', 'number' or an enum type.
test.ts(4,21): error TS2363: The right-hand side of an arithmetic
operation must be of type 'any', 'number' or an enum type.
var mod = null;
function logic(){
... use `mod` here
}
module.exports = function(){
mod = mod || require('MODULE');
return logic.apply(...);
}
var mod = require('MODULE');
module.exports = function logic(){
... use `mod` here
}
module outer {
var str = "hello world";
module inner {
var num = 6;
}
}
var outer;
(function (outer) {
var str = "hello world";
var inner;
(function (inner) {
var num = 6;
})(inner || (inner = {}));
})(outer || (outer = {}));
class ThatDoesSomething {
public mainPromise: ng.IPromise<IUser[]>;
public users: IUser[];
private fetchUsers(): ng.IPromise<IUser[]> {
return UserModel.getUsers(params)
.then((response: IUser[]) => {
this.users = response;
});
}
public $onInit(): void {
this.mainPromise = this.fetchUsers();
}
}
class UserModel {
public getUsers(params: ...): ng.IPromise<IUser[]> {
return Restangular.get('users');
}
}
var promise = Promise(); // of what ???
promise.then(function(???){
data = ???
})
var price = 7.99;
var price = {
amount: 7.99,
currency: "PLN"
};
declare type Price = number;
interface Price {
amount: number;
}
interface Price {
amount: number;
currency: string;
}
// GET /customers/{id}
interface Customer {
firstName: string;
lastName: string;
age: number;
}
// GET /customers
// GET /customers/{id}
interface Customer {
firstName: string;
lastName: string;
age: number;
}
declare type CustomerList = Customer[];
// GET /customers
// GET /customers/{id}
// GET /customers/{id}/addresses
interface Address {
street: string;
city: string;
country: string;
}
interface Customer {
...
addresses: Address[];
}
getAsyncData({
url: "/customers/<id>"
method: "GET",
...
}, function(customer: Customer): void {
process(customer.firstName); // ok
process(customer.lastName); // ok
process(customer.name); // ERROR!!!
});
var a: any = ... // EXPLICIT any
// a - INFERRED
// b - IMPLICIT any
function doSomething(a, b){
a.push(b);
}
nothing comes for free
JS
vs
ES6
vs
TS
choose TypeScript for development of any new project
JavaScript shall always remain dynamically typed
all decisions have pros and cons
think about the problems you solve, NOT the tools
always be responsible for the tools you introduce
nothing comes for free
all decisions have pros and cons
# Assignment:
number = 42
opposite = true
# Conditions:
number = -42 if opposite
# Functions:
square = (x) -> x * x
# Arrays:
list = [1, 2, 3, 4, 5]
var list, number, opposite, square;
number = 42;
opposite = true;
if (opposite) {
number = -42;
}
square = function(x) {
return x * x;
};
list = [1, 2, 3, 4, 5];
# Splats:
race = (winner, runners...) ->
print winner, runners
var race,
slice = [].slice;
race = function() {
var runners, winner;
winner = arguments[0],
runners = 2 <= arguments.length ?
slice.call(arguments, 1) : [];
return print(winner, runners);
};
class DataWidgetCtrl
fetchData: ->
@$timeout =>
@table.loaded = true
resourceObject = angular.fromJson(@$attrs.resource)
model = @$injector.get(resourceObject.model)
@table.promise = model[resourceObject.method](resourceObject.id).then (res) =>
@setData(res)
@init()
, (res) =>
@getHeader(@def.i18n, @table)
@table.error = res.status
, 0
...
var DataWidgetCtrl;
DataWidgetCtrl = (function() {
DataWidgetCtrl.prototype.fetchData = function() {
return this.$timeout((function(_this) {
return function() {
var model, resourceObject;
_this.table.loaded = true;
resourceObject = angular.fromJson(_this.$attrs.resource);
model = _this.$injector.get(resourceObject.model);
return _this.table.promise = model[resourceObject.method]
(resourceObject.id).then(function(res) {
_this.setData(res);
return _this.init();
}, function(res) {
_this.getHeader(_this.def.i18n, _this.table);
return _this.table.error = res.status;
});
};
})(this), 0);
};
...
return DataWidgetCtrl;
})();
By Tomasz Ducin
independent consultant, architect, developer, trainer, speaker #architecture #performance #javascript #typescript #react #angular