80
TypeScri pt Это не больно, даже прикольно 1 Александр Майоров Tutu.ru

Фишки и прелести TypeScript

  • Upload
    -

  • View
    269

  • Download
    1

Embed Size (px)

Citation preview

Page 1: Фишки и прелести TypeScript

1

TypeScriptЭто не больно, даже прикольно

Александр МайоровTutu.ru

Page 2: Фишки и прелести TypeScript

2

Александр Майоров

twitter, github: @frontdevops [email protected] [email protected]

Developer advocate & technical evangelist in Tutu.ru

Page 3: Фишки и прелести TypeScript

3

276 сотрудников

500 тыс. посетителей в день

2003 г.год основания

Мы продаем туры, ж/д и авиабилеты, билеты на автобусы, бронируем отели, рассказываем о расписании.

15 млнпосетителей в месяц

Самый посещаемый сервис туристических услуг в России (по результатам исследования comScore).

Page 4: Фишки и прелести TypeScript

4

TypeScript2.0

Page 5: Фишки и прелести TypeScript

5

Опасения при выборе TypeScript

Page 6: Фишки и прелести TypeScript

6

Опасения при выборе TypeScript

Можно писать только ООП код (нет)

Page 7: Фишки и прелести TypeScript

7

Опасения при выборе TypeScript

Можно писать только ООП код (нет) Обязательно использовать типы

Page 8: Фишки и прелести TypeScript

8

Опасения при выборе TypeScript

Можно писать только ООП код (нет) Обязательно использовать типы Другой язык (holy war)

Page 9: Фишки и прелести TypeScript

9

Опасения при выборе TypeScript

Можно писать только ООП код (нет) Обязательно использовать типы Другой язык (holy war) Плохая поддержка в IDE (bullshit)

Page 10: Фишки и прелести TypeScript

10

Опасения при выборе TypeScript

Можно писать только ООП код (нет) Обязательно использовать типы Другой язык (holy war) Плохая поддержка в IDE (bullshit) Нужно все переписывать в TS с JS (no)

Page 11: Фишки и прелести TypeScript

11

Опасения при выборе TypeScript

Можно писать только ООП код (нет) Обязательно использовать типы Другой язык (holy war) Плохая поддержка в IDE (bullshit) Нужно все переписывать в TS с JS (no) Babel умеет больше, развивается быстрее. А для

типов есть Flow (holy war)

Page 12: Фишки и прелести TypeScript

12

Факты про TypeScript

Page 13: Фишки и прелести TypeScript

13

Факты про TypeScript TS – это JavaScript

Page 14: Фишки и прелести TypeScript

14

Факты про TypeScript TS – это JavaScript

class A { static buz = 'Some buz';}class B extends A { constructor(foo, bar) { super(); this.foo = foo; this.bar = bar; } getFooWithBar(){ return [ this.foo , this.bar ] }}

Page 15: Фишки и прелести TypeScript

15

Факты про TypeScript TS – это JavaScript Текущая версия 2.0.10 и уже готов RC 2.1 (!)

( Angular тоже 2 – совпадение? )

Page 16: Фишки и прелести TypeScript

16

Факты про TypeScript TS – это JavaScript Текущая версия 2.0.10 и уже готов RC 2.1 Строгая типизация опциональна

Page 17: Фишки и прелести TypeScript

17

Факты про TypeScript TS – это JavaScript Текущая версия 2.0.10 и уже готов RC 2.1 Строгая типизация опциональна Развитые инструменты для работы в ООП стиле

Page 18: Фишки и прелести TypeScript

18

Факты про TypeScript TS – это JavaScript Текущая версия 2.0.10 и уже готов RC 2.1 Строгая типизация опциональна Развитые инструменты для работы в ООП стиле Режимы (таргеты) транспилирования: ES3, ES5,

ES2015…

Page 19: Фишки и прелести TypeScript

19

Факты про TypeScript TS – это JavaScript Текущая версия 2.0.10 и уже готов RC 2.1 Строгая типизация опциональна Развитые инструменты для работы в ООП стиле Режимы транспилирования: ES3, ES5, … Поддержка разных модульных систем (ES modules,

Commonjs, AMD, …)

Page 20: Фишки и прелести TypeScript

20

Факты про TypeScript TS – это JavaScript Текущая версия 2.0.10 и уже готов RC 2.1 Строгая типизация опциональна Развитые инструменты для работы в ООП стиле Режимы транспилирования: ES3, ES5, … Поддержка разных модульных систем Делается MS, но код открыт и он на Github

Page 21: Фишки и прелести TypeScript

21

Факты про TypeScript TS – это JavaScript Текущая версия 2.0.10 и уже готов RC 2.1 Строгая типизация опциональна Развитые инструменты для работы в ООП стиле Режимы транспилирования: ES3, ES5, … Поддержка разных модульных систем Делается MS, но код открыт, он на Github TS – это диалект JS (лолшто, а как же пункт 1 ?)

Page 22: Фишки и прелести TypeScript

22

Факты про TypeScript TS – это диалект JS

const enum Flag { A = 1, B, C }interface IA { buz :Flag }abstract class A<T extends Object> implements IA { static protected readonly buz :Flag|string = Flag.B;}export default class B<T> extends A<T> { constructor(public foo :T|null, public bar :T|null){ super(); let num :number = parseInt(foo as string); } getFooWithBar(...a :Array<T>) :T[] { return [ this.foo , this.bar, ...a ] }}

Page 23: Фишки и прелести TypeScript

23

Факты про TypeScript TS – это JavaScript Текущая версия 2.0.3 Строгая статическая типизация опциональна Развитые инструменты для работы в ООП стиле Режимы транспилирования: ES3, ES5, ES6, … Поддержка разных модульных систем Делается MS, но код открыт, он на Github TS – это диалект JS На TS можно писать в ФП стиле

Elm не нужен!

Page 24: Фишки и прелести TypeScript

24

Почему стоит писать на TS при работе с Angular2

?НЛО прилетело и удалило слайд, пыщь пыщь

Page 25: Фишки и прелести TypeScript

25

Почему стоит писать на TS при работе с Angular2

• П ТОМУ, что гладиолус…

Page 26: Фишки и прелести TypeScript

26

Почему стоит писать на TS вообще?

Page 27: Фишки и прелести TypeScript

27

Почему стоит писать на TS вообще Отлов некоторых ошибок уже на стадии компиляции

Page 28: Фишки и прелести TypeScript

28

Почему стоит писать на TS вообще Отлов некоторых ошибок уже на стадии компиляции Удобно рефакторить, легче отыскивать breaking changes

Page 29: Фишки и прелести TypeScript

29

Почему стоит писать на TS вообще Отлов некоторых ошибок уже на стадии компиляции Удобно рефакторить, легче отыскивать breaking changes Самодокументируемый код (интерфейсы и не только)

Page 30: Фишки и прелести TypeScript

30

Почему стоит писать на TS вообще Отлов некоторых ошибок уже на стадии компиляции Удобно рефакторить, легче отыскивать breaking changes Самодокументируемый код, контракты через интерфейсы Gradual typings: не требуется указывать типы, но всегда

можно добавить

Page 31: Фишки и прелести TypeScript

31

Почему стоит писать на TS вообще Отлов некоторых ошибок уже на стадии компиляции Удобно рефакторить Самодокументируемый код, контракты через интерфейсы Gradual typings: не требуется указывать типы, но всегда

можно добавить Хорошая навигация по коду и поддержка в IDE

Page 32: Фишки и прелести TypeScript

32

Почему стоит писать на TS вообще Отлов некоторых ошибок уже на стадии компиляции Удобно рефакторить Самодокументируемый код, контракты через интерфейсы Gradual typings: не требуется указывать типы, но всегда

можно добавить Хорошая навигация по коду и поддержка в IDE Если вы поклонник ООП – есть все инструменты для ООП• Бэкендеры PHP, C#, Java, etc … могут понять ваш код и даже

дописать что-то• Он умеет даже React (JSX ⇾ TSX), но это уже другая тема…

Page 33: Фишки и прелести TypeScript

33

Почему стоит писать на TS при работе с Angular2 ?

Page 34: Фишки и прелести TypeScript

34

Почему стоит писать на TS при работе с Angular2

• Потому, что разработчики Angular2 советуют

Page 35: Фишки и прелести TypeScript

35

Почему стоит писать на TS при работе с Angular2

• Потому, что разработчики Angular2 советуют• Все примеры в документации на TS

Page 36: Фишки и прелести TypeScript

36

Почему стоит писать на TS при работе с Angular2

• Потому, что разработчики Angular2 советуют• Все примеры в документации на TS• Синтаксис декораторов расширен!

Page 37: Фишки и прелести TypeScript

37

Почему стоит писать на TS при работе с Angular2

• Потому, что разработчики Angular2 советуют• Все примеры в документации на TS• Синтаксис декораторов расширен• Сам Angular2 написан на TS!

Page 38: Фишки и прелести TypeScript

38

Сложности при работе с TS?

Page 39: Фишки и прелести TypeScript

39

Сложности при работе с TS?

Есть…

Page 40: Фишки и прелести TypeScript

40

Сложности при работе с TS?

Они все решаемы!

Page 41: Фишки и прелести TypeScript

41

Сложности при работе с TS?• Многословен

Page 42: Фишки и прелести TypeScript

42

Сложности при работе с TS?• Многословен• Бывают сложности с составными типами и

генериками

Page 43: Фишки и прелести TypeScript

43

Сложности при работе с TS?• Многословен• Бывают сложности с составными типами и

генериками• Интерфейсы становятся бесполезными, если их

не поддерживать

Page 44: Фишки и прелести TypeScript

44

Сложности при работе с TS?• Многословен• Бывают сложности с составными типами и

генериками• Интерфейсы становятся бесполезными, если их

не поддерживать• Бывают сложности со сторонними JS пакетами

Page 45: Фишки и прелести TypeScript

45

Сложности при работе с TS?• Многословен• Бывают сложности с составными типами и

генериками• Интерфейсы становятся бесполезными, если их

не поддерживать• Бывают сложности со сторонними JS пакетами• Не все фичи ES.Next транспилируются в ES5 (в

версии 2.0 …)

Page 46: Фишки и прелести TypeScript

46

tsc -t ES2015 ⇾ Babel = Double compile

TS 2.1 уже RC!

Page 47: Фишки и прелести TypeScript

47

Сложности при работе с TS?• Многословен• Бывают сложности с составными типами и

генериками• Интерфейсы становятся бесполезными, если их

не поддерживать• Бывают сложности со сторонними JS пакетами• Не все фичи ES.Next транспилируются в ES5 (в

версии 2.0 …)• Были сложности с импортом интерфейсов

(дублирование)

Page 48: Фишки и прелести TypeScript

48

Сложности при работе с TS?• Многословен• Бывают сложности с составными типами и

генериками• Интерфейсы становятся бесполезными, если их

не поддерживать• Бывают сложности со сторонними JS пакетами• Не все фичи ES.Next транспилируются в ES5 (в

версии 2.0 …)• Были сложности с импортом интерфейсов

(дублирование)• Могут появиться новые… Но они все решаются!

Page 49: Фишки и прелести TypeScript

49

@декораторыАннотации и вот это вот всё…

Page 50: Фишки и прелести TypeScript

50

Hello world Angular2

import { Component } from '@angular/core';

@Component({ // магия детектед selector: 'my-app', template: '<h1>My First {{title}}</h1>'})export class AppComponent { title :string = 'Angular App'; // где логика? Почему класс пустой?}

Page 51: Фишки и прелести TypeScript

51

ES DECOR@TOR

Принимает target key descriptor | index

Может возвращать function Decorator (target, name, [descriptor|index] ) descriptor void

Page 52: Фишки и прелести TypeScript

52

@ ИСПОЛЬЗУЕТСЯ ДЛЯ

Декорирования

Аннотирования

Page 53: Фишки и прелести TypeScript

53

МОЖНО @

Классы @decorate class A {} Методы class A { @decorate foo(){} } Свойства class A { @decorate foo = 1; } Accessors class A { @dcrt get foo(){ … }} Аргументы* class A { foo(@annotate a){} }

Page 54: Фишки и прелести TypeScript

54

ДЕКОРАТОР КЛАССА

target - конструктор класса return - новый конструктор или ничего

declare type ClassDecorator = <T extends Function>(target :T) => T| void;

Page 55: Фишки и прелести TypeScript

55

ДЕКОРАТОР КЛАССА// пример@Componentclass MyComponent { public template :string = '<h1>Hello, people!</h1>';}

function Component(target) { let metadata = { style: "...", selector: "main-app" }; Reflect.defineMetadata('annotations', [ metadata ], target);}

Page 56: Фишки и прелести TypeScript

56

ДЕКОРАТОР МЕТОДА

declare type MethodDecorator = <T>( target :Object, propertyKey :string | symbol, descriptor :TypedPropertyDescriptor<T> ) => TypedPropertyDescriptor<T> | void;

C#? Java? WTF?

Page 57: Фишки и прелести TypeScript

57

ДЕКОРАТОР МЕТОДА

function methodDecorator(target, propertyKey, descriptor) { return descriptor;}

Простым ES языком

target - ссылка на prototype класса key - имя метода descriptor = Object.getOwnPropertyDescriptor return - ничего или дескриптор

Page 58: Фишки и прелести TypeScript

58

ДЕКОРАТОР МЕТОДА

// пример@Component({…})class MyComponent {

@HostBinding('window:scroll') onScroll(event){ ... }

}

Page 59: Фишки и прелести TypeScript

59

ДЕКОРАТОР МЕТОДА ДОСТУПА (ACCESSORS)

Аналогично методу. Следует применять к первому методу доступа (get или set), в порядке объявления.

class Line { private _start :Point;

@strictType set start(v :Point) { this._start = v }

get start() { return this._start }}

Page 60: Фишки и прелести TypeScript

60

ДЕКОРАТОР СВОЙСТВАdeclare type PropertyDecorator = (target :Object, property :string|symbol) => void;

// ES реализация вышеописанного заклинанияfunction PropertyDecorator (target, property) { ... } target - ссылка на prototype класса key - имя свойства return – null или дескриптор свойства

Page 61: Фишки и прелести TypeScript

61

ДЕКОРАТОР СВОЙСТВА

// пример

class TodoComponent { @readonly readonly public foo :string; @Input() bar; @Output() getBar = new EventEmitter(); // …}

Page 62: Фишки и прелести TypeScript

62

ДЕКОРАТОР AННОТАТОР ПАРАМЕТРА

declare type ParameterDecorator = (target :Object, key :string|symbol, index :number) => void;• target - ссылка на prototype класса• key - имя метода или undefined• index - номер аргумента• return - ничего

Page 63: Фишки и прелести TypeScript

63

ДЕКОРАТОР AННОТАТОР ПАРАМЕТРА

// примерimport { Optional } from '@angular/core';@Component({…})export class InjectorComponent {

constructor( @Optional() private logger: Logger ) {

if (this.logger) this.logger.log(some_message); }}

Page 64: Фишки и прелести TypeScript

64

DECORATOR FACTORYfunction Factory(...params){ // do anything with params return function Decorator(target :Object, key :string|symbol, descriptor?) { // decorate or annotate target // or return descriptor // or return void }}

Page 65: Фишки и прелести TypeScript

65

ФАБРИЧНЫЙ ДЕКОРАТОР

import { Component } from '@angular/core';

@Component({ // магии нет selector: 'my-app', template: '<h1>My First {{title}}</h1>'})export class AppComponent { protected title :string = 'Angular App';}

Page 66: Фишки и прелести TypeScript

66

ДЕКОРАТОРЫ В ANGULAR2

@NgModule @Component @Directive @Pipe @Injectable @Input @Output …

@HostBinding @HostListener @ContentChild @ContentChildren @ViewChild @ViewChildren @Optional …

Page 67: Фишки и прелести TypeScript

67

А ЕЩЕ ДОБАВИТЬ CORE-DECORATORS.JS

@readonly @nonconfigurable @nonenumerable @lazyInitialize @autobind @deprecate @suppressWarnings

@enumerable @override @debounce @throttle @time @decorate @mixin

Библиотека готовых декораторов

Page 68: Фишки и прелести TypeScript

68

БУДУЩЕЕ JAVASCRIPT @Component({ selector: 'myapp' })@View({ template: 'mytemplate' })@log @lorem @ipsum @dolor @sit @amet @consecteturclass SomeClass { @readonly @deprecated @memoize @enumerable @_if(User.login) @log @merge( function mergedFunc(){...} ) action(@log @Inject() config, name) { ... }}

Page 69: Фишки и прелести TypeScript

69

REFLECT METADATA API

Page 70: Фишки и прелести TypeScript

70

Refelect Reflect.apply() Reflect.construct() Reflect.defineProperty() Reflect.deleteProperty() Reflect.enumerate() Reflect.get() Reflect.getOwnPropertyDescriptor()

Reflect.getPrototypeOf() Reflect.has() Reflect.isExtensible() Reflect.ownKeys() Reflect.preventExtensions() Reflect.set() Reflect.setPrototypeOf()

Page 71: Фишки и прелести TypeScript

71

reflect-metadataPolyfill for Metadata Reflection API. Proposal to add Decorators to ES.Next, along with a prototype for an ES.Next Reflection API for Decorator Metadata

Reflect.defineMetadata() Reflect.hasMetadata() Reflect.hasOwnMetadata() Reflect.getMetadata()

npm install --save reflect-metadata

Reflect.getOwnMetadata() Reflect.getMetadataKeys() Reflect.getOwnMetadataKeys() Reflect.deleteMetadata()

Page 72: Фишки и прелести TypeScript

72

Reflect Metadata API in TypeScript

tsconfig.json:{ "compilerOptions": { "target": "ES5", "experimentalDecorators": true, "emitDecoratorMetadata": true }}

Page 73: Фишки и прелести TypeScript

73

Reflect Metadata API примерclass Point {constructor( public x :number, public y :number){}}

class Line { private _start :Point; private _stop :Point;

set start(v :Point) { this._start = v } get start() { return this._start }

set stop(v :Point) { this._stop = v } get stop() { return this._stop }}

let foo = new Line;foo.start = new Point(1,1);foo.stop = new Point(9,9);

// или

let bar = new Line;bar.start = { x: 1, y: 1 };bar.stop = { x: 1, y: 1 };

Page 74: Фишки и прелести TypeScript

74

Reflect Metadata API пример

function strictType<T>(t :any, k :string, d :TypedPropertyDescriptor<T>) :never|void {

d.set = (value :T) :never|void => {

let type = Reflect.getMetadata("design:type", t, k);

if (!(value instanceof type))throw new TypeError("Invalid type!");

}

}

Декоратор

Page 75: Фишки и прелести TypeScript

75

Reflect Metadata API примерclass Point {constructor( public x :number, public y :number){}}

class Line { private _start :Point; private _stop :Point;

@strictType set start(v :Point) { this._start = v } get start() { return this._start }

@strictType set stop(v :Point) { this._stop = v } get stop() { return this._stop }}

let foo = new Line;foo.start = new Point(1,1);foo.stop = new Point(9,9);

// или

let bar = new Line;bar.start = { x: 1, y: 1 }; // Throw error (!)bar.stop = { x: 1, y: 1 }; // Throw error (!)

Page 76: Фишки и прелести TypeScript

76

Ссылки по темеhttps://goo.gl/dYFfrl

Page 77: Фишки и прелести TypeScript

77

Александр Майоров

twitter, github: @frontdevops medium: @frontman [email protected] [email protected]

Developer advocate & technical evangelist in Tutu.ru

Спасибо! Вопросы?

https://goo.gl/dYFfrl

Page 78: Фишки и прелести TypeScript

78

HOLY WARКак лучше писать аннотации типов?

Page 79: Фишки и прелести TypeScript

79

Как лучше писать аннотации типов?let Trump :{ foo :string; bar :any; } = { foo: "abc"; bar: 123; };

let Hillary: { foo: string; bar: any; } = { foo: "abc"; bar: 123; };

¯\_(ツ )_/¯

let Truhilla : { foo : string; bar : any; } = { foo : "abc"; bar : 123; };

Page 80: Фишки и прелести TypeScript

80

ГолосованиеТрамп или Хилари?