typescript für fortgeschrittene - bridgingit -...

Post on 11-Jul-2020

6 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

TypeScript für Fortgeschrittene

Tobias Meier, BridgingIT GmbHhttp://blog.bridging-it.de/author/Tobias.Meier

Tobias MeierLead Softwarearchitekt Microsoft

Wir bringen Dinge zusammen

Blog: http://blog.bridging-it.de/author/Tobias.Meier

Twitter: @bitTobiasMeier

Email: Tobias.Meier@bridging-it.de

Standort Nürnberg

Königtorgraben 11

90402 Nürnberg

Standort Zug/Schweiz

Baarerstraße 14

CH-6300 Zug

Standort Mannheim

N7, 5-6

68161 Mannheim

Standort Karlsruhe

Rüppurrer Straße 4

76137 Karlsruhe

Standort Stuttgart

Marienstraße 17

70178 Stuttgart

Standort München

Riesstraße 12

80992 München

Standort Frankfurt

Solmsstraße 4

60486 Frankfurt

Standort Köln

Martinstraße 3

50667 Köln

Copyright © BridgingIT GmbH | Autor: Tobias Meier | Mai 2017 | www.bridging-it.de

Agenda

Status quo, Editor Support

Advanced Variables, Interfaces and Classes

Advanced Types

Async / Await

Decorators und Mixins

Module Resolution

Projektsetup

Erste Hilfe

Agenda

Status quo, Editor Support

Advanced Variables, Interfaces and Classes

Advanced Types

Async / Await

Decorators und Mixins

Module Resolution

Projektsetup

Erste Hilfe

JavaScript

Intellisense

Typsicherheit

Compiler

Refactoring

…….

Warum TypeScript ?

Great tooling enabled by static types

Features from the future today

Wie verwendet ihr TypeScript ?

VSCode

AutoImport

Debugger for Chrome, Edge

TSLint

Codelens, Code Metrics

Angular Language Service

Tooling in VSCode

Quick Fixes

Autoimport

Codelens

Code Metrics

Angular Language Service

Agenda

Status quo, Editor Support

Advanced Variables, Interfaces and Classes

Advanced Types

Async / Await

Decorators und Mixins

Module Resolution

Projektsetup

Erste Hilfe

Aufwärmübung

var conference = 'DevDays Magdeburg';

for (var i=2016; i< 2017; i++) {

var conference = 'Dev Days Magdeburg ' +i;

console.log (conference);

}

console.log (conference);

Aufwärmübung 1

var conference = 'DevDays Magdeburg';

for (var i = 2016; i < 2017; i++) {

var conference = 'Dev Days Magdeburg ' + i;

console.log(conference);}console.log(conference);

Aufwärmübung 2

let conference = 'DevDays Magdeburg';

for (var i = 2016; i < 2017; i++) {

let conference = 'Dev Days Magdeburg ' + i;

console.log(conference);}console.log(conference);

Aufwärmübung 3

const conference = 'DevDays Magdeburg';

for (var i = 2016; i < 2017; i++) {

conference = 'Dev Days Magdeburg ' + i;

console.log(conference);

}

console.log(conference);

Destructuring (1/4)

const sessions = ['IOT', 'TypeScript', 'Automatisieren']

const [session1, session2, session3] = sessions;

console.log(session1);

console.log(session2);

console.log(session3);

Destructuring (2/4)

const sessions = ['IOT', 'TypeScript', 'Automatisieren']

const [session1, ...weitereSessions] = sessions;

console.log(session1);

console.log(weitereSessions.join());

Destructuring (3/4)

const person = {

firstname: 'Tobias', surname: 'Tobias', plz: '70178', city: 'Stuttgart',

street: 'Marienstraße 17'

};

const { firstname, surname, ...address } = person;

console.log(firstname);console.log(surname);console.log(address.plz);console.log(address.city);console.log(address.street);

Destructuring (4/4)

const person = {firstname: 'Tobias', surname: 'Tobias',plz: '70178', city:'Stuttgart', street:'Marienstraße 17'

};

const {firstname :vorname, surname:nachname,

...address: adresse} = person;

console.log (vorname);console.log (nachname);console.log(adresse.plz);console.log(adresse.city);console.log(adresse.street);

Parameter: Optional, Default, Sonstige

function buildAddress(firstname: string,

surname?: string, ...address: string[]) {

let result = surname;

if (surname) result = result + ' ' + surname;

return result + address.join(' ');

}

console.log(buildAddress('Tobias', 'Meier','70178','Stuttgart', 'Marienstr. 17'));

Klasse als Interface verwenden

class Person{

name: string;

}

interface OnlinePerson extends Person {

email: string;

}

const person: OnlinePerson = {name: 'Meier', email: 'tobias.meier@bridging-it.de'};

console.log (person.email);

Spread

let original = { name: 'Tobias' };let address = { city: 'Stuttgart' };let copy = { ...original };let merged = { ...original, ...address };

let obj = { x: 1, y: "string" };var newObj = { ...obj, z: 3, y: 4 };

Rest

let obj = { x: 1, y: 1, z: 1

};

let { z, ...obj1 } = obj;

console.log (obj1.x);

console.log (obj1.y);

Agenda

Status quo, Editor Support

Advanced Variables, Interfaces and Classes

Advanced Types

Async / Await

Decorators und Mixins

Module Resolution

Projektsetup

Erste Hilfe

Null und undefined

function add (zahl1: number, zahl2: number | null):number{

return zahl1 + (zahl2 != null ? zahl2 : 0);}

var result = add (1,1); // => 2var result = add (1,null); // => 1

//Kompilierfehlervar result = add (null,1);

tsconfig.json

"compilerOptions": {"strictNullChecks": true

}

Nun auch in Angular verwendbar: Angular 4.1.2

Intersection Types

interface Company { name: string}

interface Address { street: string, plz: string, city:string }

type CompanyWithAddress = Company & Address

const person : CompanyWithAddress = {

name: "BridgingIT GmbH",

plz: "70178",

city: "Stuttgart",

street: "Marienstraße 17"

} ;

Datentypen: Union Types

function sum (x: number | number[]) { if (typeof x === "number") {

return x + 10; } else {

// return sum of numbers}

}

Type Guard typeof

function format(obj: string | number): string {

if (typeof obj === 'number') {

return obj.toLocaleString();

}

return obj;

}

console.log( format("abc") );

console.log( format(10.124));

Type Guard instanceof

class Person {constructor(public firstname: string, public lastname: string){}

}class Company { constructor(public companyname: string) { } }

function getName(obj: Person | Company): string {

if (obj instanceof Person) {

return obj.firstname + ' ' + obj.lastname;

}

return obj.companyname;

}

Eigene Type Guards

function isPerson(obj: Person | Company): obj is Person {if (obj instanceof Person) {return true;

}return false;

}

var obj: Person | Company = new Company("BridingIT GmbH");if (isPerson(obj)) { console.info(obj.lastname); }else { console.info(obj.companyname); }

Discriminated Union

interface Square {kind: "square";size: number;

}

interface Rectangle {kind: "rectangle";width: number;height: number;

}

interface Circle {kind: "circle";radius: number;

}

type Shape = Square | Rectangle | Circle;

function area(s: Shape) {

switch (s.kind) {

case "square": return s.size * s.size;

case "rectangle":

return s.width * s.height;

case "circle":

return Math.PI *s.radius * s.radius;

}

}

Fluent API: Polymorphic this

class StringBuilder {

add (str: string) : this {

//…return this;

}}

class AdvancedStringBuilder extends StringBuilder {

appendLine () : this { return this;

}}

new AdvancedStringBuilder().add('Hello').appendLine();

Mapped Types

class User {

firstname: string;

surname: string;

}

interface ReadonlyUser {

readonly firstname: string;

readonly surname: string;

}

const user = new User();

user.firstname = 'Tobias';

user.surname = 'Meier';

const ruser = <ReadonlyUser> user;

ruser.firstname = "tobias";

Mapped Types: Readonly

class User {

firstname: string;

surname: string;

}

const user = new User();

user.firstname = 'Tobias'; user.surname = 'Meier';

const ruser = <Readonly<User>> user;

ruser.firstname = "tobias";

Mapped Types: Partial

class User {

firstname: string;

surname: string;

}

const user : User = {firstname: 'Tobias'; }

const puser : <Partial<User>> = {firstname: 'Tobias'; }

Und wie lautet der Zaubertrick ?

Keyof-Operator

type Readonly<T> = {

readonly [P in keyof T]: T[P];

}

type Partial<T> = {

[P in keyof T]?: T[P];

}

Mapped Types: Record

type Person =

Record<'firstname' | 'surname' | 'email', string>;

const person1 = <Person> {

firstname:"Tobias",

surname:"Meier",

email:"tobias.meier@bridging-it.de"

};

Mapped Types: Pick

type Person=Record<'firstname'|'surname'|'email',string>;

const P1 = <Person> {

firstname:"Tobias", surname:"Meier",

email:"tobias.meier@bridging-it.de"

};

type OnlinePerson = Pick<Person, 'email'>;

const P2 = <OnlinePerson> P1;

console.log(P2.email);

Keyof-Operator Record und Pick

type Record<K extends string | number, T> = {[P in K]: T;

}

type Pick<T, K extends keyof T> = {[P in K]: T[P];

}

String Literal Types

type Direction= "north" | "south" | "west" | "east";function drive (dir: Direction) {//….}

drive ('north'); //okdrive ('east'); //ok

drive ('n'); //error

Type Assertions

interface SquareConfig { color?: string; width?: number;

}

function createSquare(config: SquareConfig): { color: string; area: number } { return null;

}

let mySquare = createSquare({ colour: "red", width: 100 } );

Type Assertions

interface SquareConfig { color?: string; width?: number;

}

function createSquare(config: SquareConfig): { color: string; area: number } { return null;

}

let mySquare = createSquare({ colour: "red", width: 100 } as SquareConfig

);

Type Assertions

interface SquareConfig {

color?: string; width?: number;

[propName: string]: any;

}

function createSquare(config: SquareConfig): {

color: string; area: number } {

//..}

let mySquare = createSquare( { colour: "red", width: 100 });

Agenda

Status quo, Editor Support

Advanced Variables, Interfaces and Classes

Advanced Types

Async / Await

Decorators und Mixins

Module Resolution

Projektsetup

Erste Hilfe

async / await

async function main() {

await ping();

}

async function ping() {

for (var i = 0; i < 10; i++) {

await delay(300); console.log("ping");

}

}

function delay(ms: number) {

return new Promise(resolve => setTimeout(resolve, ms));

}

main();

Agenda

Status quo, Editor Support

Advanced Variables, Interfaces and Classes

Advanced Types

Async / Await

Decorators und Mixins

Module Resolution

Projektsetup

Erste Hilfe

Decorator

Entspricht Attributen in C#

Feature muss explizit aktiviert werden:

In Angular stark verwendet:

Eigener Decorator (1/2)

function sealed(constructor: Function) {

Object.seal(constructor);

Object.seal(constructor.prototype);

}

Eigener Decorator (2/2):function logger(): any {return function (target: any, propertyKey: string, descriptor:

PropertyDescriptor) {const originalMethod = descriptor.value; descriptor.value = function (...args: any[]) {

console.log("Called method " + propertyKey +" (" + JSON.stringify(args) +")");const result = originalMethod.apply(this, args);console.log("Method " + propertyKey +" returns:" + result);return result;

};return descriptor;

}};

var sb = new StringBuilder();sb.add('Hallo').add(' Magdeburg');

Mixins

class Person{

///...

}

export type Constructable = new (...args: any[]) => object;

export function Timestamped<BC extends Constructable>(Base: BC) {

return class extends Base {

timestamp = new Date();

};

}

const TimestampedPerson= Timestamped(Person);

const person1 = new TimestampedPerson();

console.info (person1.timestamp);

Agenda

Status quo, Editor Support

Advanced Variables, Interfaces and Classes

Advanced Types

Async / Await

Decorators und Mixins

Module Resolution

Projektsetup

Erste Hilfe

Modulauflösung

Angelehnt an NodeJS

Tracing :

tsconfig.json

{"compilerOptions": {

"moduleResolution": "node","traceResolution": true}

}

Modulauflösung (relativ)

File Main.ts:

File 'C:/Projekte/ET/ts/customer.ts' does not exist.File 'C:/Projekte/ET/ts/customer.tsx' does not exist.File 'C:/Projekte/ET/ts/customer.d.ts' does not exist.Directory 'C:/Projekte/ET/ts/customer' does not exist, skipping all lookups in it.Loading module as file / folder, candidate module location 'C:/Projekte/ET/ts/customer', target file type 'JavaScript'.File 'C:/Projekte/ET/ts/customer.js' does not exist.File 'C:/Projekte/ET/ts/customer.jsx' does not exist.Directory 'C:/Projekte/ET/ts/customer' does not exist, skipping all lookups in it.======== Module name './customer' was not resolved. ========

import {Cust} from './customer';

Modulauflösung (absolut)

File Main.ts:

File 'C:/Projekte/ET/ts/node_modules/customer.ts' does not exist.File 'C:/Projekte/ET/ts/node_modules/customer.tsx' does not exist.File 'C:/Projekte/ET/ts/node_modules/customer.d.ts' does not exist.Directory 'C:/Projekte/ET/ts/node_modules/@types' does not exist, skipping all lookups in it.Directory 'C:/Projekte/ET/node_modules' does not exist, skipping all lookups in it.Directory 'C:/Projekte/node_modules' does not exist, skipping all lookups in it.Directory 'C:/node_modules' does not exist, skipping all lookups in it.Loading module 'customer' from 'node_modules' folder, target file type 'JavaScript'.File 'C:/Projekte/ET/ts/node_modules/customer.js' does not exist.File 'C:/Projekte/ET/ts/node_modules/customer.jsx' does not exist.Directory 'C:/Projekte/ET/node_modules' does not exist, skipping all lookups in it.Directory 'C:/Projekte/node_modules' does not exist, skipping all lookups in it.Directory 'C:/node_modules' does not exist, skipping all lookups in it.======== Module name 'customer' was not resolved. ========

import {Cust} from 'customer';

SystemJS: Textdateien importieren 1/2

System.config({

map: {

text:

'path/to/text.js'

}

});

import myText from './mytext.html!text';

SystemJS: Textdateien importieren 1/2

tsconfig.json

{

"compilerOptions": {

"sourceMap": true,

"module": "system",

"target": "es5",

"strictNullChecks": true,

"alwaysStrict": true

},

"exclude": [

"node_modules",

"jspm_packages",

"**/*.spec.ts"

]

}

package.json (Ausschnitt)

{

"jspm": {

"dependencies": {

"systemjs":

"npm:systemjs@^0.19.25",

"text":

"github:systemjs/plugin-text@^0.0.9"

},

"devDependencies": {

"jspm": "0.16.34"

}

}

Agenda

Status quo, Editor Support

Advanced Variables, Interfaces and Classes

Advanced Types

Async / Await

Decorators und Mixins

Module Resolution

Projektsetup

Erste Hilfe

TSConfig – Meine Empfehlung

{

"compilerOptions": {

"target": "es5",

"module": "commonjs",

"noImplicitThis": false,

"strict": true

}

}

Erzeugbar über: tsc -init Seit TypeScript 2.3

Agenda

Status quo, Editor Support

Advanced Variables, Interfaces and Classes

Advanced Types

Async / Await

Decorators und Mixins

Module Resolution

Projektsetup

Erste Hilfe

VS-Code TypeScript-Version:

TypeScript-Version:tsc –v

Suchpfad überprüfenwhere tsc

TypeScript wächst

TypeScript für Fortgeschrittene

JavaScript that scales

Great tooling enabled by static types

Features from the future today

Vielen Dank

Blog: http://blog.bridging-it.de/author/Tobias.Meier

Email: Tobias.Meier@bridging-it.de

Twitter: @bITTobiasMeier

Bilder: www.dreamstime.com

top related