typescript-talk/index.html
2019-10-03 19:02:58 +02:00

598 lines
17 KiB
HTML
Executable File

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>reveal.js</title>
<link rel="stylesheet" href="https:https://unpkg.com/reveal.js/css/reset.css">
<link rel="stylesheet" href="https://unpkg.com/reveal.js/css/reveal.css">
<link rel="stylesheet" href="https://unpkg.com/reveal.js/css/theme/black.css">
<!-- Theme used for syntax highlighting of code -->
<link rel="stylesheet" href="https://unpkg.com/reveal.js/lib/css/monokai.css">
<style>
.reveal pre code {
max-height: unset;
padding: .5rem;
border-radius: .25rem;
}
</style>
<!-- Printing and PDF exports -->
<script>
var link = document.createElement('link');
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = window.location.search.match(/print-pdf/gi) ? 'https://unpkg.com/reveal.js/css/print/pdf.css' :
'https://unpkg.com/reveal.js/css/print/paper.css';
document.getElementsByTagName('head')[0].appendChild(link);
</script>
</head>
<body>
<div class="reveal">
<div class="slides">
<section data-background-color="#357EDD">
<h1>Typescript</h1>
<ul class="fragment">
<li>What is typescript?</li>
<li>History & Today</li>
<li>Why?</li>
<li>Basics</li>
<li>Typescript Utilities</li>
<li>Examples</li>
<li>Future</li>
</ul>
</section>
<section>
<section data-markdown data-background-color="#CDECFF">
<script type="text/template">
## What is Typescript?
- Superset of Javascript <!-- .element: class="fragment" -->
- Enables typschecking <!-- .element: class="fragment" -->
</script>
</section>
<section data-transition="fade-out slide-in">
<h3>Javascript</h3>
<pre><code data-trim class="hljs">
let a = 'a string'
a = 5
a = [1, 'two', {three: true}]
</code></pre>
</section>
<section data-transition="fade-in slide-out">
<h3>Typescript</h3>
<pre><code data-trim class="hljs">
let a = 'a string' // a is a string now
a = 5 // ❌
a = [1, 'two', {three: true}] // ❌
</code></pre>
</section>
</section>
<section data-background-color="#FBF1A9">
<section data-markdown>
<script type="text/template">
## Brief History Lesson
- <!-- .element: class="fragment" --> Development started in 2009 (codename Strada)
- <!-- .element: class="fragment" --> Problems scaling the office 365 suite (released June 2011)
- <!-- .element: class="fragment" --> Lead by Anders Hejlsberg (Author of C#, Delphi & Tubro Pascal) and Luke Hoban (Part of tc39)
- <!-- .element: class="fragment" --> 2012: <span><!-- .element: class="fragment fade-in" --><span><!-- .element: class="fragment highlight-red" -->World End</span></span><span> <!-- .element: class="fragment fade-in" -->; Released to public `v0.8`</span>
- <!-- .element: class="fragment" --> 2014: Moved to Github
</script>
</section>
<section data-markdown>
<script type="text/template">
## Today
<small>2 Oct. 2019</small>
- <!-- .element: class="fragment" --> ~54k Stargazers
- <!-- .element: class="fragment" --> ~10k closed PRs (167 open)
- <!-- .element: class="fragment" --> ~20k closed issues (~3.5k open)
- <!-- .element: class="fragment" --> 419 Contributors
- <!-- .element: class="fragment" --> Made & <b>Maintained</b> by Microsoft
</script>
</section>
</section>
<section data-background-color="#FFDFDF">
<section data-markdown>
<script type="text/template">
## So Why?
- <!-- .element: class="fragment" --> Less Errors
- <!-- .element: class="fragment" --> Less Bug-Hunting
- <!-- .element: class="fragment" --> More work gets done
- <!-- .element: class="fragment" --> Maintainability
- <!-- .element: class="fragment" --> Enables fast fixes
- <!-- .element: class="fragment" --> Dev. must not be context aware
- <!-- .element: class="fragment" --> Autocompletition, "Smart" IDEs, etc.
</script>
</section>
<section data-background-image="https://media.giphy.com/media/YXpp9YxWhyWBy/giphy.gif"></section>
</section>
<section data-background-color="#E8FDF5">
<section>
<h2>TS Config</h2>
<pre class="fragment"><code data-trim class="hljs">
npm i typescript
tsc --init
</code></pre>
</section>
<section>
<h3>General</h3>
<ul>
<li class="fragment">target <small>(ES2014, ..., ES2019, ESNEXT, ...)</small></li>
<li class="fragment">module <small>(commonjs, es2016, esnext, ...)</small></li>
<li class="fragment">jsx</li>
<li class="fragment">esModuleInterop</li>
<li class="fragment">allowSyntheticDefaultImports</li>
<li class="fragment">experimentalDecorators</li>
<li class="fragment">emitDecoratorMetadata</li>
</ul>
</section>
<section>
<h3>Type Cheking</h3>
<ul>
<li class="fragment">noImplicitAny</li>
<li class="fragment">strictNullChecks</li>
<li class="fragment">strictFunctionTypes</li>
<li class="fragment">strictBindCallApply</li>
<li class="fragment">strictPropertyInitialization</li>
<li class="fragment">noImplicitThis</li>
<li class="fragment">alwaysStrict</li>
<li class="fragment">noImplicitReturns</li>
<li class="fragment">noFallthroughCasesInSwitch</li>
</ul>
</section>
<section>
<h3>Production</h3>
<ul>
<li class="fragment">noUnusedLocals</li>
<li class="fragment">noUnusedParameters</li>
<li class="fragment">removeComments</li>
</ul>
</section>
</section>
<section>
<section>
<h2>Basics</h2>
</section>
<section data-transition="slide-id fade-out">
<h3>Simple types</h3>
<pre class="fragment"><code data-trim class="hljs">
const a: string = 'a string'
const b: number = 5
const c: boolean = true
const d: string[] = ['a', 'b', 'c']
const e: number[] = [1, 2, 3]
</code></pre>
</section>
<section data-transition="fate-in slide-out">
<h3>Simple types</h3>
<pre><code data-trim class="hljs">
const a = 'a string'
const b = 5
const c = true
const d = ['a', 'b', 'c']
const e = [1, 2, 3]
</code></pre>
</section>
<section>
<h3>Types</h3>
<pre class="fragment"><code data-trim class="hljs">
type StrinOrNumber = string | number
</code></pre>
<pre class="fragment"><code data-trim class="hljs">
type StringOrNumberOrBoolean = StringOrNumber | boolean
</code></pre>
</section>
<section>
<h3>Modifiers</h3>
<pre class="fragment"><code data-trim class="hljs">
const a?: string // string | undefined
const obj = {
a: string,
b?: number,
}
funntion log(msg?: string) {}
</code></pre>
<pre class="fragment"><code data-trim class="hljs">
class {
b!: string
}
obj!.one!.two!.three
</code></pre>
</section>
<section data-transition="slide-id fade-out">
<h3>Interfaces</h3>
<pre class="fragment"><code data-trim class="hljs">
interface Pizza {
slices: number
round: boolean
name: string
}
const pizza: Pizza = {
slices: 4,
round: true,
name: 'Hawaii'
}
</code></pre>
</section>
<section data-transition="slide-out fade-in">
<h3>Interfaces</h3>
<pre><code data-trim class="hljs">
interface Pizza {
slices: 4 | 8
round: boolean
name: 'Margherita' | 'Parmigiana'
}
const pizza: Pizza = {
slices: -1, // ❌
round: true,
name: 'Margherita'
}
</code></pre>
</section>
<section>
<h3>Interfaces</h3>
<pre><code data-trim class="hljs">
interface A {
one: string
}
interface B extends A {
two: number
three?: string
}
</code></pre>
</section>
<section>
<h3>Interfaces</h3>
<pre><code data-trim class="hljs">
interface Project {
name: string,
paymentBasis: 'fix' | 'hour'
}
</code></pre>
<pre class="fragment"><code data-trim class="hljs">
interface GoodProject extends Project {
paymentBasis: 'hour'
}
</code></pre>
</section>
<section>
<h3>Functions</h3>
<pre class="fragment fade-in-then-semi-out"><code data-trim class="hljs">
function add(x: number, y: number): number {
return x + y
}
const add = (x: number, y: number): number => {
return x + y
}
</code></pre>
<pre class="fragment fade-in-then-semi-out"><code data-trim class="hljs">
function choose&lt;T, P&gt;(a: T, b: P): T | P {
if (something)
return a
else
return b
}
</code></pre>
<pre class="fragment fade-in-then-semi-out"><code data-trim class="hljs">
const waitForMe = async (text:string): Promise&lt;string&gt; =&gt; text
</code></pre>
</section>
<section>
<h3>Overloading</h3>
<pre class="fragment fade-in-then-semi-out"><code data-trim class="hljs">
function add(x: number): number
function add(x: number, y: number = 1): number {
return x + y
}
</code></pre>
<pre class="fragment fade-in-then-semi-out"><code data-trim class="hljs">
function add(a: string, b: string): string
function add(a: number, b: number): number
function add(a: string | number, b: string | number): string | number {
if (a.constructor.name === 'String') return a + b
else return a + b
}
</code></pre>
</section>
<section>
<h3>Classes</h3>
<pre class="fragment fade-in-then-semi-out"><code data-trim class="hljs">
class User {
private id: string
public readonly username: string
friends: User[] = []
constructor() {
this.id = 'abc'
this.username = 'John Doe'
}
private doSomeStuff() {}
}
</code></pre>
</section>
<section>
<h3>Generics</h3>
<pre class="fragment fade-in-then-semi-out"><code data-trim class="hljs">
function choose&lt;T, P&gt;(a: T, b: P): T | P {
if (something)
return a
else
return b
}
</code></pre>
<pre class="fragment fade-in-then-semi-out"><code data-trim class="hljs">
type Something&lt;T&gt; = {
a: string,
b: T
}
</code></pre>
</section>
</section>
<section>
<section>
<h2>Typescript Utilities Types</h2>
<ul class="fragment">
<li>Partial & Required</li>
<li>Readonly</li>
<li>Pick & Omit</li>
</ul>
</section>
<section>
<h3>Partial / Required</h3>
<pre class="fragment fade-in-then-semi-out"><code data-trim class="hljs">
interface Props {
a: number;
b: string;
};
const x: Props = { a: 5 }; // Error: property 'b' missing
const y: Partial&lt;Props&gt; = { a: 5 }; // OK
</code></pre>
<pre class="fragment fade-in-then-semi-out"><code data-trim class="hljs">
interface Props {
a?: number;
b?: string;
};
const x: Props = { a: 5 }; // OK
const y: Required&lt;Props&gt; = { a: 5 }; // Error: property 'b' missing
</code></pre>
</section>
<section>
<h3>Readonly</h3>
<pre class="fragment fade-in-then-semi-out"><code data-trim class="hljs">
interface Todo {
title: string;
}
const todo: Readonly&lt;Todo&gt; = {
title: 'Delete inactive users',
};
todo.title = 'Hello'; // Error: cannot reassign a readonly property
</code></pre>
</section>
<section>
<h3>Pick / Omit</h3>
<pre class="fragment fade-in-then-semi-out"><code data-trim class="hljs">
interface Todo {
title: string;
description: string;
completed: boolean;
}
const todo: Pick&lt;Todo, 'title' | 'completed'&gt; = {
title: 'Clean room',
completed: false,
};
</code></pre>
<pre class="fragment fade-in-then-semi-out"><code data-trim class="hljs">
interface Todo {
title: string;
description: string;
completed: boolean;
}
const todo: Omit&lt;Todo, 'description'&gt; = {
title: 'Clean room',
completed: false,
};
</code></pre>
</section>
<section>
<h2>Also there are...</h2>
<ul>
<li>Exclude & Extract</li>
<li>Record</li>
<li>NonNullable</li>
<li>ReturnType</li>
<li>InstanceType</li>
<li>ThisType</li>
</ul>
</section>
</section>
<section>
<section>
<h2>Examples</h2>
</section>
<section>
<h3>Constructor</h3>
<pre class="fragment fade-in-then-semi-out"><code data-trim class="hljs">
class Auto {
wheels: number
constructor(wheel: number) {
this.wheels = wheel
}
}
</code></pre>
<pre class="fragment fade-in-then-semi-out"><code data-trim class="hljs">
class Auto {
constructor(private wheel: number) { }
}
</code></pre>
<pre class="fragment fade-in-then-semi-out"><code data-trim class="hljs">
class Auto {
wheels!: number
constructor(init: typeof Auto) {
Object.assign(this, init)
}
}
</code></pre>
</section>
<section>
<h3>Advanced Stuff</h3>
<pre><code data-trim class="hljs">
class Auto {
wheels?: number
doors?: number
// ...
constructor(init: Partial&lt;Auto&gt;) {
Object.assign(this, init)
}
}
const a = new Auto({
doors: 5,
})
</code></pre>
</section>
<section>
<h3>Advanced Stuff</h3>
<pre><code data-trim class="hljs">
type RequireSome&lt;T, K extends keyof T&gt; = {
[X in Exclude&lt;keyof T, K&gt;]?: T[X]
} &amp; {
[P in K]-?: T[P]
}
class Auto {
wheels!: number
doors?: number
// ...
constructor(init: RequireSome&lt;Auto, 'wheels'&gt;) {
Object.assign(this, init)
}
}
const a = new Auto({
wheels: 4,
doors: 5,
})
</code></pre>
</section>
<section>
<h3>React Higher Order Components</h3>
<pre><code data-trim class="hljs" data-line-numbers="1,2,5">
function withLayout&lt;P extends object&gt;(WrappedComponent: React.ComponentType&lt;P&gt;) {
return (props: P) =&gt; (
&lt;div id='app'&gt;
&lt;Header/&gt;
&lt;WrappedComponent {...props}/&gt;
&lt;Footer/&gt;
&lt;/div&gt;
);
}
</code></pre>
</section>
</section>
<section>
<section>
<h2>Future</h2>
</section>
<section>
<h3>Optional Chaining</h3>
<i>TS 3.7</i>
<pre class="fragment"><code data-trim class="hljs">
a && a.b && a.b.c // 🤬
</code></pre>
<pre class="fragment"><code data-trim class="hljs">
a?.b?.c // 🚀
</code></pre>
</section>
<section>
<h3>Null Coalescing</h3>
<i>TS 3.7</i>
<pre class="fragment fade-in-then-semi-out"><code data-trim class="hljs">
something || 'default'
</code></pre>
<pre class="fragment fade-in-then-semi-out"><code data-trim class="hljs">
false || 'default' // => 'default'
0 || 'default' // => 'default'
</code></pre>
<pre class="fragment"><code data-trim class="hljs">
something ?? 'default' // 🚀
</code></pre>
<pre class="fragment"><code data-trim class="hljs">
0 ?? 'default' // => 0
false ?? 'default' // => false
</code></pre>
<pre class="fragment"><code data-trim class="hljs">
(something === null || something === undefined) ? something : 'default'
</code></pre>
</section>
</section>
</div>
</div>
<script src="https://unpkg.com/reveal.js/js/reveal.js"></script>
<script>
Reveal.initialize({
width: "100%",
height: "100%",
margin: .1,
minScale: 1,
maxScale: 1,
transition: 'slide',
hash: true,
fragmentInURL: true,
slideNumber: 'c/t',
dependencies: [{
src: 'https://unpkg.com/reveal.js/plugin/markdown/marked.js'
},
{
src: 'https://unpkg.com/reveal.js/plugin/markdown/markdown.js'
},
{
src: 'https://unpkg.com/reveal.js/plugin/notes/notes.js',
async: true
},
{
src: 'https://unpkg.com/reveal.js/plugin/highlight/highlight.js',
async: true
}
]
});
</script>
</body>
</html>