# Propaganda ## Transparenz von Schnittstellen Es fehlt als Konsument die Transparenz, wie Schnittstellen benutzt werden. ```js // @iserv/graph.js export function drawGraph(data, options = {}) { [... Implementierungsdetails] } // your-module.js /* Wie sieht die API aus? */ drawGraph([{ x: 2, y: 5, }, { x: 3, y: 7, }]); /* Könnte mehrere Formate annehmen */ drawGraph([ 5, 7 ], { start: 0, stepSize: 1, }); ``` Muss man wirklich immer direkt Dokumentationen oder Implementierungsdetails lesen? ## JSDoc für Schnittstellentransparenz ```js // @iserv/graph.js /** * @typedef {Object} GraphOptions * @property {HTMLCanvasElement} mount * @property {number} start * @property {number} stepSize */ /** * @param {GraphOptions} options */ export function drawGraph(data, options = {}) { [...Implementierungsdetail] } // your-module.js drawGraph( data, { mount: document.getElementById('my-canvas'), start: 2, stepSize: 1, }, ) ``` ## Wobei JSDoc lügen kann: ```js // @iserv/graph.js /** * @typedef {Object} GraphOptions * @property {HTMLCanvasElement} mount * @property {number} start * @property {number} stepSize */ /** * @param {GraphOptions} options */ export function drawGraph(data, options = {}) { // Erwartet ein Container-Element, kein Canvas! const canvas = document.createElement('canvas'); options.mount.appendChild(canvas); // Die Optionen `start` und `stepSize` heißen anders for (let x = options.begin; x < data.length; x += options.step) { [...Implementierungsdetail] } } ``` Wann bekommt man von diesen Fehlern mit? * Bei JSDoc wird nicht automatisch überprüft, ob Schnittstellen eingehalten werden * Wenn JSDoc mal valide war, kann es bei Änderungen aber inkonsistent werden # Flüchtigkeitsfehler ## Array access ```js // Rendering required select of users in a group const users = fetchUsersInGroup(GROUP_STUDENT_UUID); const list = renderList(users); const someUser = users[0]; // Just get the first user // Preselect some user, because the field is required list.select(someUser); ``` Breaks, on empty groups! ```ts const users: Users[] = fetchUsersInGroup(GROUP_STUDENT_UUID); const list: List = renderList(users); // Invalid types, User|undefined vs. User const someUser: User = users[0]; [...] ``` # Aufsetzen von Typescript-Projekten ## Installation ``` npm install -g typescript # global npm install --save-dev typescript # lokal ``` ## Neues Projekt ``` tsc --init ``` (Lokal ist der Befehl dann `npx tsc [...]`) ### Konfiguration tsconfig.json ```json { "compilerOptions": { "target": "es2016", "module": "commonjs", "esModuleInterop": true, "forceConsistentCasingInFileNames": true, "strict": true } } ``` ### Kompilieren ``` tsc [] ``` ## Integration in Webpack-Applikationen ``` npm install --save-dev typescript ts-loader ``` webpack.config.js ``` module.exports = { [...] module: { rules: [ { test: /\.tsx?$/, use: 'ts-loader', exclude: /node_modules/, }, ], }, resolve: { extensions: ['.tsx', '.ts', '.js'], }, }; ``` ## Nutzung in Vue3 Applikationen ``` npm install --save-dev typescript ``` tsconfig.json ```json { "extends": "@vue/tsconfig/tsconfig.json", [...] } ``` ```vue ``` # Migration zu Typescript Ich habe ein existierendes und großes Javascript Projekt. Ist der Zug schon abgefahren oder kann ich noch mit Typescript anfangen? * Javascript darf Typescript importieren, nicht anders herum * Wenn man doch Javascript importieren muss, gibt es Umwege ## Umwege Type-Declaration Files ```js // maximum-number.js export function maximumNumber(numbers) { return Math.max(...numbers); } ``` ```ts // maximum-number.d.ts export function maximumNumber(numbers: number[]): number; ``` * Keine Implementierung * Kein Type-Checking der Implementierung * Schnittstellen werden wenigstens typisiert `¯\_(ツ)_/¯` * Das geht auch mit JS-Libraries Unsortiert: * Types, die man kennen sollte * Record * Partial * Readonly * union * intersection * typeof * keyof * `as` ![img.png](img/trustmebro.png) * Migration nach Typescript * Typescript und Vue3 * Wichtige Typescript Konfigurationen * strict * noImplicitAny * strictNullChecks * strictPropertyInitialization * useUnknownInCatchVariables * noUncheckedIndexAccess * Typescript-ESLint für noch weniger Fehler * https://typescript-eslint.io/rules/no-floating-promises/ * Type-Narrowing * Duck-Typing * Monty python? * If it quacks like a duck... * ts-auto-guard # Reminder: Vortrag in der Entwicklung - Donnerstag (den 06.07.) um 12-13 Uhr mit dem Thema **Typescript**. > Warum hilft uns Typescript unser Frontend robuster zu gestalten und Fehler vorzubeugen? Wie integriere ich Typescript in bestehende Projekte? Und wie sehen die nützlichsten Features aus?