Modern

& applicative

(Part 2)

''Type safety at runtime with JSON decoders''

WROCLAW TYPEsCRIPT #6

SEPTEMBER 25TH, 18:30

plac jana pawla II 14

Modern

& applicative

(Part 2)

Modern

& applicative

What is TypeScript?

Superset of JavaScript

function add(nr1: number, nr2: number): number {
  return nr1 + nr2;
}

Strong typing

Compilation (transpilation) step

Developed by creators of C#

Developed and maintained

by Microsoft

FUN FACTS

How does it work?

Transpiles to JavaScript

class User {
  firstName: string;
  lastName: string;

  constructor(fn: string, ln: string) {
    this.firstName = fn;
    this.lastName = ln;
  }

  greet(): void {
    console.log(`I'm ${this.getFullName()}`);
  }

  private getFullName(): string {
    return `${this.firstName} ${this.lastName}`;
  }
}
var User = /** @class */ (function () {
  function User(fn, ln) {
    this.firstName = fn;
    this.lastName = ln;
  }
  User.prototype.greet = function () {
    console.log("I'm " + this.getFullName());
  };
  User.prototype.getFullName = function () {
    return this.firstName + " " + this.lastName;
  };
  return User;
}());

target:

ES5

Uses source maps

Traces transpiled files back to the original content

Great for debugging

(from RisingStack blog)

Types, alright... What else?

interfaces & types

interface HttpResponse {
  body: string;
  status: number;
}

const res: HttpResponse = {
  body: 'Hello World',
  status: 200 
};
type HttpResponse = {
  body: string;
  status: number;
}

const res: HttpResponse = {
  body: 'Hello World',
  status: 200 
};

Enums

enum Direction {
    Up = 'Up',
    Down = 'Down',
    Left = 'Left',
    Right = 'Right',
}
console.log(Direction.Up);  // Up
var Direction;
(function (Direction) {
    Direction["Up"] = "Up";
    Direction["Down"] = "Down";
    Direction["Left"] = "Left";
    Direction["Right"] = "Right";
})(Direction || (Direction = {}));
console.log(Direction.Up); // Up

target:

ES5

STRING LITERAL TYPE

type HttpMethod = 'GET';

const hm1: HttpMethod = 'GET'; 
// OK
const hm2: HttpMethod = 'test';
// ERROR: Type '"test"' is not 
// assignable to type 'HttpMethod'.
const hm3: HttpMethod = null;
// ERROR: Type 'null' is not 
// assignable to type 'HttpMethod'.

Union Types

type HttpGET = {
  params: string[];
};

type HttpPOST = {
  body: any;
};

type HTTPRequest = HttpGET | HttpPOST;

generics

class Collection<T> {
  private collection: T[];
  constructor(...items: T[]) {
    this.collection = items;
  }
  get(index: number): T {
    return this.collection[index];
  }
}

const users = new Collection(
  { name: 'Kevin' },
  { name: 'John' }
);

users.get(0).name; 
// OK
users.get(0).age;
// Property 'age' does not 
// exist on type...

benefits

strong typing

no unwanted assignments and operations on types

COMPILATION STEP

NO INVALID SYNTAX ERRORS

NO INVALID OPERATIONS

EASY SYNTAX

JUST ADD TYPE SIGNATURE TO YOUR VARIABLE

java or c# like

ide integration

auto-check type errors

set up your standards (tslint)

flaws

every tech requires some learning, doesn't it?

new concepts (?)

does not solve all problems

does not guarantee no runtime errors

looks like c# but isn't c#

lots of misconceptions

steep learning curve

lots of options

compiler configuration

what's the alternative?

@Controller('user')
export class UserController {
  constructor(private userService: UserService) {}
  
  @Post()
  save(@Body() user: User): User {
    return this.userService.save(user);
  }

  @Get()
  findAll(): User[] {
    return this.userService.findAll();
  }
}

Basics of TypeScript

By Kajetan Świątek

Basics of TypeScript

  • 300