Learning to Love Type Systems Swipe Left, Uncaught TypeError - - PowerPoint PPT Presentation

learning to love type systems
SMART_READER_LITE
LIVE PREVIEW

Learning to Love Type Systems Swipe Left, Uncaught TypeError - - PowerPoint PPT Presentation

Learning to Love Type Systems: Swipe Left, Uncaught TypeError sugarpirate_ poteto Learning to Love Type Systems Swipe Left, Uncaught TypeError PRESENTED BY Lauren Tan (she/her) Cinemagraph by /u/orbojunglist QCon SF 2018


slide-1
SLIDE 1 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

Learning to Love Type Systems Swipe Left, Uncaught TypeError

PRESENTED BY

Lauren Tan (she/her)

sugarpirate_ poteto

Cinemagraph by /u/orbojunglist

💕

slide-2
SLIDE 2 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

Learning to Love Type Systems Swipe Left, Uncaught TypeError

PRESENTED BY

Lauren Tan (she/her)

sugarpirate_ poteto

Cinemagraph by /u/orbojunglist

💕

slide-3
SLIDE 3 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError
slide-4
SLIDE 4 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError
slide-5
SLIDE 5 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError
slide-6
SLIDE 6 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

"If debugging is the process of removing software bugs, then programming must be the process of putting them in."

Djikstra, supposedly 路

slide-7
SLIDE 7 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

💪

slide-8
SLIDE 8 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

Uncaught TypeError, 999

undefined is not a function

slide-9
SLIDE 9 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError
slide-10
SLIDE 10 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

TypeScript, <3

TypeScript is a superset of JavaScript that compiles to plain JavaScript

slide-11
SLIDE 11 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError
slide-12
SLIDE 12 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

Flow, <3

A Static Type Checker for JavaScript

slide-13
SLIDE 13 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError
slide-14
SLIDE 14 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

GraphQL, <3

A (typed) query language for your API

slide-15
SLIDE 15 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError
slide-16
SLIDE 16 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

Lauren Tan

slide-17
SLIDE 17 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

sugarpirate_ poteto

slide-18
SLIDE 18 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

"A type system is a tractable syntactic method for proving the absence of certain program behaviors by classifying phrases according to the kinds of values they compute."

Types and Programming Languages, Benjamin C. Pierce

slide-19
SLIDE 19 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError
slide-20
SLIDE 20 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError
slide-21
SLIDE 21 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

How many ways can this program fail?

slide-22
SLIDE 22 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

const half = x =? x / 2;

slide-23
SLIDE 23 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

const TEST_CASES = [ null, undefined, Symbol(1), 10, '10', 'hello world', { name: 'Lauren' }, [1, 2, 3], x =? x * x ];

slide-24
SLIDE 24 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

TEST_CASES.map(testValue =? { return { result: half(testValue), test: testValue.toString() } });

slide-25
SLIDE 25 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError



not my type!

slide-26
SLIDE 26 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError
slide-27
SLIDE 27 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError
slide-28
SLIDE 28 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError
slide-29
SLIDE 29 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError
slide-30
SLIDE 30 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

const TEST_CASES = [ null, /0 Uncaught TypeError undefined, /0 Uncaught TypeError Symbol(1), /0 Uncaught TypeError 10, /0 5 '10', /0 5 路 'hello world', /0 NaN { name: 'Lauren' }, /0 NaN [1, 2, 3], /0 NaN x =? x * x /0 NaN ];

slide-31
SLIDE 31 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

How many ways can this program fail?

slide-32
SLIDE 32 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

How many ways can this program fail?

(Infinity)

slide-33
SLIDE 33 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

const half = (x: number) =? x / 2;

slide-34
SLIDE 34 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

How many ways can this program fail (at compile time)?

slide-35
SLIDE 35 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

0*

slide-36
SLIDE 36 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

Agenda

A Gentle Introduction to Types Why Less is Better Types Over the Network

slide-37
SLIDE 37 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

A Gentle Introduction to Types

Why You Should Care About Types

slide-38
SLIDE 38 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

A Gentle Introduction to Types

Why You Should Care About Types

slide-39
SLIDE 39 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

The Basics

slide-40
SLIDE 40 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

const text1 = 'hello react rally'; const text2: string = 'hello react rally';

slide-41
SLIDE 41 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

const list1 = [1, 2, 3]; const list2: number[] = [4, 5, 6];

slide-42
SLIDE 42 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

type ServerStacks = 'canary' | 'beta' | 'production' interface User { id: number; name: string; isAdmin: boolean; }

slide-43
SLIDE 43 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

function makeAdmin(user: User) { user.isAdmin = true; return user; }

slide-44
SLIDE 44 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

function makeAdmin(user: User) { user.isAdmin = 1; return user; }

[ts] Type '1' is not assignable to type 'boolean'. (property) User.isAdmin: boolean

slide-45
SLIDE 45 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

Generics

(Parametric Polymorphism)

slide-46
SLIDE 46 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

function makeArray(x: number): number[] { return [x]; } function makeArray(x: string): string[] { return [x]; } function makeArray(x: boolean): boolean[] { return [x]; }

slide-47
SLIDE 47 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

function makeArray<T>(x: T): T[] { return [x]; }

slide-48
SLIDE 48 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

function makeArray<T>(x: T): T[] { return [x]; }

slide-49
SLIDE 49 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

function makeArray<T>(x: T): T[] { return [x]; }

slide-50
SLIDE 50 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

function makeArray<T>(x: T): T[] { return [x]; }

slide-51
SLIDE 51 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

makeArray(1);

function makeArray<number>(x: number): number[]

slide-52
SLIDE 52 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

makeArray('hello');

function makeArray<string>(x: string): string[]

slide-53
SLIDE 53 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

function map<A, B>(fn: (item: A) =? B, items: A[]): B[] { /0 ../ }

slide-54
SLIDE 54 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

function map<A, B>(fn: (item: A) =? B, items: A[]): B[] { /0 ../ }

slide-55
SLIDE 55 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

function map<A, B>(fn: (item: A) =? B, items: A[]): B[] { /0 ../ }

slide-56
SLIDE 56 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

function map<A, B>(fn: (item: A) =? B, items: A[]): B[] { /0 ../ }

slide-57
SLIDE 57 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

function map<A, B>(fn: (item: A) =? B, items: A[]): B[] { /0 ../ }

slide-58
SLIDE 58 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

function map<A, B>(fn: (item: A) =? B, items: A[]): B[] { /0 ../ }

slide-59
SLIDE 59 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

map(x =? x * x, [1, 2, 3]); /0 number[] map(x =? x.toUpperCase(), ['hello', 'react', 'rally']); /0 string[]

slide-60
SLIDE 60 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

Why Less Is Better

Precise Types Means Less Bugs

slide-61
SLIDE 61 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

Why Less Is Better

Precise Types Means Less Bugs

slide-62
SLIDE 62 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

Learning from Functional Programming

https://www.youtube.com/watch?v=ev7AYsLljxk&index=5&list=PL8Ky8lYL8-Oh7awp0sqa82o7Ggt4AGhyf

slide-63
SLIDE 63 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError
slide-64
SLIDE 64 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

Proof theory

Logic

Type theory

Programs

Category theory

Algebra

slide-65
SLIDE 65 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

Curry–Howard–Lambek correspondence

slide-66
SLIDE 66 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

Stop with the jargon, Lauren

slide-67
SLIDE 67 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

Stop with the jargon, Lauren

slide-68
SLIDE 68 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

declare function Addition(x: number, y: number): number; /0 proposition function add(x: number, y: number): number { return x + y; } /0 proof

slide-69
SLIDE 69 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

declare function Addition(x: number, y: number): number; /0 proposition function add(x: number, y: number): number { return x + y; } /0 proof

Proposition: If x and y are numbers, a number exists

slide-70
SLIDE 70 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

declare function Addition(x: number, y: number): number; /0 proposition function add(x: number, y: number): number { return x + y; } /0 proof

Proposition: If x and y are numbers, a number exists Proof: x + y proves that a number exists

slide-71
SLIDE 71 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

What is a function?

slide-72
SLIDE 72 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

f : A → B

a : A b : B

f

slide-73
SLIDE 73 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

an object* of type B an object* of type A

f

f :; function from type A to type B

* not a JS object

slide-74
SLIDE 74 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

Types are propositions Programs are proofs

Curry-Howard Correspondence

slide-75
SLIDE 75 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

Let the type system suggest the implementation

slide-76
SLIDE 76 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

function head<T>(list: T[]): T { /0 ../ }

slide-77
SLIDE 77 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

function head<T>(list: T[]): T { return list; }

[ts] Type 'T[]' is not assignable to type 'T'. (parameter) list: T[]

slide-78
SLIDE 78 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

function head<T>(list: T[]): T { return list[0]; }

slide-79
SLIDE 79 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

function map<A, B>(fn: (item: A) =? B, items: A[]): B[] { /0 ../ }

slide-80
SLIDE 80 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

function map<A, B>(fn: (item: A) =? B, items: A[]): B[] { return items; } [ts] Type 'A[]' is not assignable to type 'B[]'. Type 'A' is not assignable to type 'B'. (parameter) items: A[]

slide-81
SLIDE 81 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

function map<A, B>(fn: (item: A) =? B, items: A[]): B[] { return fn(items[0]); } [ts] Type 'B' is not assignable to type 'B[]'. (parameter) fn: (item: A) =? B

slide-82
SLIDE 82 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

function map<A, B>(fn: (item: A) =? B, items: A[]): B[] { return items.reduce((acc, curr) =? { acc.push(fn(curr)); return acc; }, [] as B[]); }

slide-83
SLIDE 83 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

myStatelessComponent :; Props -? React.ReactNode

slide-84
SLIDE 84 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

const MyStatelessComponent: React.SFC<MyProps> = 1;

[ts] Type '1' is not assignable to type 'StatelessComponent<MyProps>'. const MyStatelessComponent: React.StatelessComponent<MyProps>

slide-85
SLIDE 85 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

const MyStatelessComponent: React.SFC<MyProps> = () =? 1;

[ts] Type '() =? number' is not assignable to type 'StatelessComponent<MyProps>'. Type 'number' is not assignable to type 'ReactElement<any>'. const MyStatelessComponent: React.StatelessComponent<MyProps>

slide-86
SLIDE 86 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

const MyStatelessComponent: React.SFC<MyProps> = props =? <div>../<0div>;

slide-87
SLIDE 87 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

Writing better functions

slide-88
SLIDE 88 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

f(x) = x2

slide-89
SLIDE 89 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

1 2 3 4 5 6 ../ 1 4 9 16 25 36 ../ Domain Codomain

f(x) = x2

slide-90
SLIDE 90 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

Total vs Partial functions

slide-91
SLIDE 91 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

Impure & Total Impure & Partial Pure & Total Pure & Partial

Partial Total Impure Pure

slide-92
SLIDE 92 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

A partial function is a function that is not defined for all possible input values.

Partial

slide-93
SLIDE 93 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

const half = x =? x / 2;

slide-94
SLIDE 94 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

number string void

  • bject

array symbol number NaN Uncaught TypeError Possible Domains Possible Codomains

const half = x =? x / 2;

slide-95
SLIDE 95 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

number string void

  • bject

array symbol number NaN Uncaught TypeError Possible Domains Possible Codomains

const half = x =? x / 2;

slide-96
SLIDE 96 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

number string void

  • bject

array symbol number NaN Uncaught TypeError Possible Domains Possible Codomains

const half = x =? x / 2;

slide-97
SLIDE 97 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

number string void

  • bject

array symbol number NaN Uncaught TypeError Possible Domains Possible Codomains

const half = x =? x / 2;

half('10') /0 5 half('hello world') /0 NaN

slide-98
SLIDE 98 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError
slide-99
SLIDE 99 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

number string void

  • bject

array symbol number NaN Uncaught TypeError Possible Domains Possible Codomains

const half = x =? x / 2;

slide-100
SLIDE 100 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

number string void

  • bject

array symbol number NaN Uncaught TypeError Possible Domains Possible Codomains

const half = x =? x / 2;

slide-101
SLIDE 101 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

Possible Domains Possible Codomains

const half = (x: number) =? x / 2;

number string void

  • bject

array symbol number NaN Uncaught TypeError

slide-102
SLIDE 102 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

A total function is a function that is defined for all possible values

  • f its input. That is, it terminates

and returns a value.

Total

slide-103
SLIDE 103 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

string number void

  • bject

array symbol Promise<User> Uncaught Error Possible Domains Possible Codomains

function fetchUser(username: string): Promise<User>

slide-104
SLIDE 104 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

string number void

  • bject

array symbol Promise<Either<FetchError, User>? Uncaught Error Possible Domains Possible Codomains

function fetchUser(username: string): Promise<Either<FetchError, User>?

slide-105
SLIDE 105 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

type Either<L, A> = Left<L, A> | Right<L, A>

It looks like you're trying to use a monad. Would you like help?

slide-106
SLIDE 106 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

type Either<L, A> = Left<L, A> | Right<L, A>

It looks like you're trying to use a monad. Would you like help?

slide-107
SLIDE 107 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

import { Either, left, right } from 'fp-ts/lib/Either'; import fetch from 'node-fetch'; async function fetchUser(username: string): Promise<Either<FetchError, User>? { const res = await fetch(`https:/0api.sugarpirate.com/users/${username}`); if (!res.ok) { return left(new FetchError(`[${res.status}] ${res.statusText}`)) } return right(await res.json()); }

https://github.com/gcanti/fp-ts

slide-108
SLIDE 108 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

import { Either, left, right } from 'fp-ts/lib/Either'; import fetch from 'node-fetch'; async function fetchUser(username: string): Promise<Either<FetchError, User>? { const res = await fetch(`https:/0api.sugarpirate.com/users/${username}`); if (!res.ok) { return left(new FetchError(`[${res.status}] ${res.statusText}`)) } return right(await res.json()); }

https://github.com/gcanti/fp-ts

slide-109
SLIDE 109 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

import { Either, left, right } from 'fp-ts/lib/Either'; import fetch from 'node-fetch'; async function fetchUser(username: string): Promise<Either<FetchError, User>? { const res = await fetch(`https:/0api.sugarpirate.com/users/${username}`); if (!res.ok) { return left(new FetchError(`[${res.status}] ${res.statusText}`)) } return right(await res.json()); }

https://github.com/gcanti/fp-ts

slide-110
SLIDE 110 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

import { Either, left, right } from 'fp-ts/lib/Either'; import fetch from 'node-fetch'; async function fetchUser(username: string): Promise<Either<FetchError, User>? { const res = await fetch(`https:/0api.sugarpirate.com/users/${username}`); if (!res.ok) { return left(new FetchError(`[${res.status}] ${res.statusText}`)) } return right(await res.json()); }

https://github.com/gcanti/fp-ts

slide-111
SLIDE 111 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

async function doIt() { const maybeLauren = await fetchUser('lauren'); const maybeNoOne = await fetchUser('asdjasjdashjdkahjksd'); maybeLauren .map(lauren =? lauren.projects) .map(projects =? console.log(projects.map(p =? p.name))); maybeNoOne .map(noOne =? noOne.projects) .map(projects =? console.log(projects.map(p =? p.name))); }

slide-112
SLIDE 112 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

async function doIt() { const maybeNoOne = await fetchUser('asdjasjdashjdkahjksd'); maybeNoOne .mapLeft(e =? console.log(e.message)); /0 e: FetchError }

slide-113
SLIDE 113 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

[string, string] number void

  • bject

array symbol Element undefined Possible Domains Possible Codomains

export function firstVisibleElement( selector: string, scrollableAreaSelector: string ): Element | undefined

slide-114
SLIDE 114 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

[string, string] number void

  • bject

array symbol Option<Element> undefined Possible Domains Possible Codomains

export function firstVisibleElement( selector: string, scrollableAreaSelector: string ): Option<Element>

slide-115
SLIDE 115 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

type Option<A> = None<A> | Some<A>

https://github.com/gcanti/fp-ts

slide-116
SLIDE 116 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

export function firstVisibleElement( selector: string, scrollableAreaSelector: string ): Option<Element> { const scrollableElement = document.querySelector(scrollableAreaSelector); if (!scrollableElement) return none; const scrollableBounds = scrollableElement.getBoundingClientRect(); const firstVisibleItem = Array.from(document.querySelectorAll(selector)).find( el =? { const elBounds = el.getBoundingClientRect(); const isInViewport = detectInViewport(elBounds, scrollableBounds); return isInViewport &' elBounds.top - scrollableBounds.top <> 0; } ); return firstVisibleItem ? some<Element>(firstVisibleItem) : none; }

slide-117
SLIDE 117 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

export function firstVisibleElement( selector: string, scrollableAreaSelector: string ): Option<Element> { const scrollableElement = document.querySelector(scrollableAreaSelector); if (!scrollableElement) return none; const scrollableBounds = scrollableElement.getBoundingClientRect(); const firstVisibleItem = Array.from(document.querySelectorAll(selector)).find( el =? { const elBounds = el.getBoundingClientRect(); const isInViewport = detectInViewport(elBounds, scrollableBounds); return isInViewport &' elBounds.top - scrollableBounds.top <> 0; } ); return firstVisibleItem ? some<Element>(firstVisibleItem) : none; }

slide-118
SLIDE 118 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

export function firstVisibleElement( selector: string, scrollableAreaSelector: string ): Option<Element> { const scrollableElement = document.querySelector(scrollableAreaSelector); if (!scrollableElement) return none; const scrollableBounds = scrollableElement.getBoundingClientRect(); const firstVisibleItem = Array.from(document.querySelectorAll(selector)).find( el =? { const elBounds = el.getBoundingClientRect(); const isInViewport = detectInViewport(elBounds, scrollableBounds); return isInViewport &' elBounds.top - scrollableBounds.top <> 0; } ); return firstVisibleItem ? some<Element>(firstVisibleItem) : none; }

slide-119
SLIDE 119 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

firstVisibleElement('.item', '.item-container').map(el =? el.getAttribute('data-whatever') /0 string );

slide-120
SLIDE 120 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

firstVisibleElement('.item', '.item-container').map(el =? el.getAttribute('data-whatever') /0 string );

(method) map<string>(f: (a: Element) =? string): Option<string> Takes a function f and an Option of A. Maps f either on None or Some, Option's data constructors. If it maps on Some then it will apply the f on Some's value, if it maps on None it will return None. @example assert.deepEqual(some(1).map(n =? n * 2), some(2))

slide-121
SLIDE 121 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

import { NoData, Pending, Failure } from './MyPlaceholders'; import { TCustomer } from './MyModel'; type TCustomersList = { entities: RemoteData<TCustomer[]>; }; const CustomersList: React.SFC<TCustomersList> = ({ entities }) =? entities.foldL( () =? <NoData /?, () =? <Pending /?, err =? <Failure error={err} /?, data =? <ul>{data.map(item =? <li>{item.name}<0li>)}<0ul> );

https://github.com/devex-web-frontend/remote-data-ts

slide-122
SLIDE 122 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

Cardinality

cardinality · number of elements of the set

slide-123
SLIDE 123 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

Lower cardinality = Less bugs*

slide-124
SLIDE 124 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

Pragmatic Set Theory

set · collection of objects

slide-125
SLIDE 125 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

type Conferences = 'QConSF' | 'dotJS' | 'React Rally';

slide-126
SLIDE 126 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

|Conferences| = 3

(not real syntax)

slide-127
SLIDE 127 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

type Conferences = string;

slide-128
SLIDE 128 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

|Conferences| = Infinity

(not real syntax)

slide-129
SLIDE 129 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

Primitive types are not precise

slide-130
SLIDE 130 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

|string| = Infinity |number| = Infinity |symbol| = Infinity |boolean| = 2 |null| = 1 |undefined| = 1

(not real syntax)

slide-131
SLIDE 131 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

|object| = Infinity

(not real syntax)

slide-132
SLIDE 132 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

Be precise

slide-133
SLIDE 133 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

function toString<T>(x: T): string { return x.toString(); } toString(undefined); toString(null);

slide-134
SLIDE 134 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

function toString<T>(x: T): string { return x.toString(); } toString(undefined); toString(null);

function toString<undefined>(x: undefined): string function toString<null>(x: null): string

slide-135
SLIDE 135 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

string number

  • bject

array symbol void string Uncaught TypeError Possible Domains Possible Codomains

function toString<T>(x: T): string

slide-136
SLIDE 136 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

function toString<T>(x: NonNullable<T>): string { return x.toString(); } toString(undefined); toString(null);

slide-137
SLIDE 137 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

function toString<T>(x: NonNullable<T>): string { return x.toString(); } toString(undefined); toString(null);

slide-138
SLIDE 138 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

function toString<T>(x: NonNullable<T>): string { return x.toString(); } toString(undefined); toString(null);

[ts] Argument of type 'undefined' is not assignable to parameter of type '{}'. [ts] Argument of type 'null' is not assignable to parameter of type '{}'.

slide-139
SLIDE 139 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

string number

  • bject

array symbol void string Uncaught TypeError Possible Domains Possible Codomains

function toString<T>(x: NonNullable<T>): string

slide-140
SLIDE 140 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

undefined null A: Set of nullable types B \ A: Set of non-nullable types B: Set of all types string number

  • bject

symbol array

slide-141
SLIDE 141 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

type NonNullable<T> = T extends null | undefined ? never : T type T34 = NonNullable<string | number | undefined>; /0 string | number type T35 = NonNullable<string | string[] | null | undefined>; /0 string | string[]

slide-142
SLIDE 142 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

type Partial<T> = { [P in keyof T]?; T[P]; }; type Required<T> = { [P in keyof T]-?; T[P]; }; type Readonly<T> = { readonly [P in keyof T]: T[P]; }; type Pick<T, K extends keyof T> = { [P in K]: T[P]; }; type Record<K extends keyof any, T> = { [P in K]: T; }; type Exclude<T, U> = T extends U ? never : T; type Extract<T, U> = T extends U ? T : never; type NonNullable<T> = T extends null | undefined ? never : T; type ReturnType<T extends (../args: any[]) =? any> = T extends (../args: any[]) =? infer R ? R : any;

https://github.com/Microsoft/TypeScript/blob/v3.0.1/src/lib/es5.d.ts

slide-143
SLIDE 143 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

Be pragmatic

slide-144
SLIDE 144 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

"No matter what language you work in, programming in a functional style provides benefits. You should do it whenever it is convenient, and you should think hard about the decision when it isn't convenient."

John Carmack

slide-145
SLIDE 145 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

Types Over the Network

GraphQL, Your New BFF

slide-146
SLIDE 146 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

Types Over the Network

GraphQL, Your New BFF

slide-147
SLIDE 147 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

type Project { name: String tagline: String contributors: [User] }

slide-148
SLIDE 148 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

{ project(name: "GraphQL") { tagline } }

slide-149
SLIDE 149 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

{ "project": { "tagline": "A query language for APIs" } }

slide-150
SLIDE 150 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError
slide-151
SLIDE 151 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError
slide-152
SLIDE 152 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError
slide-153
SLIDE 153 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError
slide-154
SLIDE 154 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError
slide-155
SLIDE 155 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError
slide-156
SLIDE 156 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError
slide-157
SLIDE 157 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError
slide-158
SLIDE 158 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

TypeScript interface GraphQL schema protobuf

slide-159
SLIDE 159 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

gRPC Microservice GraphQL Gateway Strongly Typed UI

slide-160
SLIDE 160 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError
slide-161
SLIDE 161 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError
slide-162
SLIDE 162 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError
slide-163
SLIDE 163 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

Agenda

A Gentle Introduction to Types Why Less is Better Types Over the Network

slide-164
SLIDE 164 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

Agenda

A Gentle Introduction to Types Why Less is Better Types Over the Network

slide-165
SLIDE 165 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

Agenda

A Gentle Introduction to Types Why Less is Better Types Over the Network

slide-166
SLIDE 166 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError

sugarpirate_ poteto

slide-167
SLIDE 167 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError Cinemagraph by /u/fezzo

Thank you

slide-168
SLIDE 168 QCon SF 2018 Learning to Love Type Systems: Swipe Left, Uncaught TypeError Cinemagraph by /u/fezzo

Thank you