From 1e7742f2d5ee127e4bccd916aae024ad107d594c Mon Sep 17 00:00:00 2001 From: monsterkrampe Date: Sat, 5 Oct 2019 16:22:10 +0200 Subject: [PATCH] add more advanced examples --- index.html | 242 +++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 226 insertions(+), 16 deletions(-) diff --git a/index.html b/index.html index 7fe3b3b..29f91a3 100755 --- a/index.html +++ b/index.html @@ -7,7 +7,7 @@ reveal.js - + @@ -110,7 +110,7 @@ - More work gets done - Maintainability - Enables fast fixes - - Dev. must not be context aware + - Dev. does not have to be context aware - Autocompletition, "Smart" IDEs, etc. @@ -523,6 +523,216 @@ } +
+

Return Type depends on argument

+

+						function choose<T, P>(a: T, b: P, takeFirst?: false): P;
+						function choose<T, P>(a: T, b: P, takeFirst: true): T;
+						function choose<T, P>(a: T, b: P, takeFirst?: boolean): T | P {
+							if (takeFirst)
+								return a
+							else
+								return b
+						}
+
+						choose('a', 1).includes('a'); // error
+						choose('a', 1) * 2;
+						choose('a', 1, true) * 2; // error
+						choose('a', 1, true).includes('a');
+					
+
+
+

Argument type depends on another argument

+

+						function checkLock<
+							B extends { alwaysUnlocked?: boolean }, 
+							O extends (B extends { alwaysUnlocked: true } ? {} : { locked: boolean })
+						>(obj: O, options?: B) {
+							return options && options.alwaysUnlocked || !obj.locked
+						}
+
+						checkLock({}); // error
+						checkLock({ locked: false });
+						checkLock({ locked: true, foo: 'bar' });
+
+						checkLock({}, { alwaysUnlocked: false }); // error
+						checkLock({}, { alwaysUnlocked: true });
+						checkLock({ foo: 'bar' }, { alwaysUnlocked: true });
+					
+
+
+

Options exclude each other

+

+						type ColumnProps = {
+							width: number;
+							autoCalculateWidth?: false;
+						} | {
+							width?: undefined;
+							autoCalculateWidth: true;
+						}
+						
+						// error
+						const props: ColumnProps = {
+							width: 4,
+							autoCalculateWidth: true,
+						};
+					
+
+
+

Merging Objects together

+

+						function merge<O, T>(data1: O, data2: T): O | T {
+							return {
+								...data1,
+								...data2,
+							};
+						}
+					
+

+						type Merge<O, T> = Omit<O, keyof T> & T;
+
+						function merge<O, T>(data1: O, data2: T): Merge<O, T> {
+							return {
+								...data1,
+								...data2,
+							};
+						}
+					
+
+
+

Distinguish union types

+

+						interface TypeA {
+							type: 'A';
+							foo: string;
+							bar: string;
+						}
+						
+						interface TypeB {
+							type: 'B';
+							foo: number;
+							blubb: string;
+						}
+						
+						function distinguishType(type: TypeA | TypeB) {
+							if (type.type === 'A') {
+								type.foo.includes('whatever');
+								type.bar;
+							} else {
+								type.blubb.includes('something');
+								type.foo.toFixed(2);
+							}
+						}
+					
+
+ +
+
+

The agony of Object.keys

+

+						const someObj = {
+							a: 'a',
+							b: 'b',
+							2: 'c',
+						};
+						
+						function filterByKeys(keys: (keyof typeof someObj)[]) {
+							keys.map(key => someObj[key]);
+						}
+						
+						filterByKeys(Object.keys(someObj)); // error
+					
+

+						function getKeysFromObject<
+							T extends {}, K extends string = (keyof T & string)
+						>(object: T): K[] {
+							const keyPredicate = (key: string): key is K =>
+								object.hasOwnProperty(key) && typeof object[key] !== 'undefined' && object[key] !== null;
+						
+							return Object
+								.keys(object)
+								.filter<K>(keyPredicate);
+						};
+					
+
+
+

about predicates

+

+						interface SomeInterface {
+							what: string,
+							you: string,
+						}
+						
+						const someArray: (SomeInterface | null)[] = [
+							{ what: 'ever', you: 'like' },
+							null,
+							{ what: 'the fuck', you: 'want' },
+							null,
+						];
+						
+						// error: Signature ... must be a type predicate ?!
+						const filteredArray: SomeInterface[] = someArray.filter<SomeInterface>(value => !!value);
+					
+

+						const predicate = (value: SomeInterface | null): value is SomeInterface => !!value;
+
+						const workingArray: SomeInterface[] = someArray.filter(predicate);
+					
+
+
+

Back to Object.keys

+

+						const someObj = {
+							a: 'a',
+							b: 'b',
+							2: 'c',
+						};
+						
+						function filterByKeys(keys: (keyof typeof someObj)[]) {
+							keys.map(key => someObj[key]);
+						}
+						
+						function getKeysFromObject<
+							T extends {}, K extends string = (keyof T & string)
+						>(object: T): K[] {
+							const keyPredicate = (key: string): key is K =>
+								object.hasOwnProperty(key) && typeof object[key] !== 'undefined' && object[key] !== null;
+						
+							return Object
+								.keys(object)
+								.filter<K>(keyPredicate);
+						};
+					
+

+						filterByKeys(getKeysFromObject<typeof someObj>(someObj));
+					
+
+
+

Tradeoffs

+

+						function getKeysFromObject<
+							T extends {}, K extends string = (keyof T & string)
+						>(object: T): K[] {
+							const keyPredicate = (key: string): key is K =>
+								object.hasOwnProperty(key) && typeof object[key] !== 'undefined' && object[key] !== null;
+						
+							return Object
+								.keys(object)
+								.filter<K>(keyPredicate);
+						};
+					
+

+						const testObject = {
+							2: 'teststring',
+							'testkey': 2131,
+							'otherkey': null,
+							3: null,
+						};
+						
+						getKeysFromObject(testObject); // ('testkey' | 'otherkey')[]  --- :(
+						getKeysFromObject<typeof testObject, '2' | 'testkey'>(testObject); // meh...
+					
+
@@ -577,22 +787,22 @@ 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 - } + 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 + } ] }); - \ No newline at end of file +