# TypeScript met clasp en Apps Script ## Waarom clasp en TypeScript clasp (Command Line Apps Script Projects) is de officiele CLI van Google waarmee je Apps Script lokaal ontwikkelt. Je schrijft code in je eigen editor, krijgt typeveiligheid en autocompletion via TypeScript en beheert versies met Git. Het resultaat push je met een enkel commando naar Google. :::warn title="Belangrijk sinds clasp 3" Vanaf clasp 3 (de huidige major in 2026) zet clasp TypeScript niet meer zelf om naar JavaScript. Je hebt nu zelf een bundelstap nodig, bijvoorbeeld met **esbuild** of **Rollup**, die je `.ts`-bestanden compileert naar `.js`. Het resultaat push je daarna met clasp. Oudere handleidingen die `.ts` direct naar Apps Script pushen kloppen niet meer. ::: ## clasp installeren clasp 3 vereist Node.js 22 of nieuwer. Controleer je versie met `node -v` en installeer clasp daarna globaal. ```bash npm install -g @google/clasp clasp login ``` `clasp login` opent een browservenster voor de Google-autorisatie. Na akkoord worden je inloggegevens lokaal opgeslagen. ## Nieuw project aanmaken In clasp 3 zijn enkele commando's hernoemd. `clasp create-script` is de nieuwe naam; het oude `clasp create` blijft als alias bestaan. Hetzelfde geldt voor `clasp clone-script` (was `clasp clone`) en `clasp open-script` (was `clasp open`). ```bash mkdir mijn-script && cd mijn-script clasp create-script --title "Mijn Script" --type standalone npm init -y npm install --save-dev @types/google-apps-script typescript esbuild ``` Maak een `tsconfig.json` aan. De Apps Script V8-runtime ondersteunt grofweg ES2019, dus dat is een veilig doel: ```json { "compilerOptions": { "target": "ES2019", "module": "ESNext", "lib": ["ES2019"], "strict": true, "noEmit": true, "rootDir": "src" }, "include": ["src/**/*"] } ``` `noEmit` staat hier aan omdat TypeScript zelf alleen typecheckt; het echte bouwen doet de bundler. Wijs in `.clasp.json` de `rootDir` naar de map met de gebundelde uitvoer: ```json { "scriptId": "JOUW_SCRIPT_ID", "rootDir": "dist" } ``` ## Bundelen met esbuild esbuild bundelt je TypeScript snel naar een enkel JavaScript-bestand dat Apps Script begrijpt. Maak een `build.mjs`: ```javascript import { build } from 'esbuild'; await build({ entryPoints: ['src/Code.ts'], outfile: 'dist/Code.js', bundle: true, format: 'iife', target: 'es2019', }); ``` Apps Script verwacht globale functies, dus gebruik `format: 'iife'` of plaats je entrypoint-functies op het globale bereik. Zorg dat functies die je vanuit triggers of het menu aanroept benaderbaar blijven na het bundelen. ## TypeScript-code schrijven ```typescript interface Klant { id: number; naam: string; email: string; actief: boolean; } interface SpreadsheetConfig { spreadsheetId: string; bladNaam: string; } function haalKlantenOp(config: SpreadsheetConfig): Klant[] { const ss = SpreadsheetApp.openById(config.spreadsheetId); const blad = ss.getSheetByName(config.bladNaam); if (!blad) { throw new Error(`Blad ${config.bladNaam} niet gevonden`); } const data = blad.getDataRange().getValues(); return data.slice(1).map((rij): Klant => ({ id: Number(rij[0]), naam: String(rij[1]), email: String(rij[2]), actief: Boolean(rij[3]), })); } function stuurEmail(ontvanger: string, onderwerp: string, body: string): boolean { try { GmailApp.sendEmail(ontvanger, onderwerp, body); return true; } catch (e) { console.error(`E-mail fout: ${e}`); return false; } } ``` :::info title="Volledige type-definities" Het pakket `@types/google-apps-script` geeft TypeScript-definities voor alle Apps Script-services, zoals `SpreadsheetApp` en `GmailApp`. Daardoor krijg je autocompletion en typecontrole in je editor, ook al draait de code uiteindelijk op Google. ::: ## De dagelijkse workflow Voeg handige scripts toe aan je `package.json` zodat bouwen en pushen in een stap gaan: ```json { "scripts": { "typecheck": "tsc", "build": "node build.mjs", "push": "npm run build && clasp push", "watch": "clasp push --watch" } } ``` De kerncommando's van clasp gebruik je zo: ```bash npm run build clasp push clasp pull clasp open-script clasp logs ``` `clasp push` uploadt de inhoud van je `rootDir` naar Google. `clasp pull` haalt de huidige versie uit Apps Script terug, handig als iemand in de online-editor iets heeft aangepast. ## Bestaand project klonen Heb je al een script in Apps Script (bijvoorbeeld een spreadsheet-gebonden script)? Kloon het lokaal en bouw daaromheen je TypeScript-project op. ```bash clasp clone-script JOUW_SCRIPT_ID clasp pull ``` ## Geheimen en configuratie Bewaar API-sleutels en andere geheimen niet in je code. In Apps Script gebruik je daarvoor Script Properties; lokaal houd je gevoelige waarden buiten Git via een `.env`-bestand dat in `.gitignore` staat. ```typescript interface Configuratie { apiKey: string; apiUrl: string; debugMode: boolean; } function getConfig(): Configuratie { const props = PropertiesService.getScriptProperties().getProperties(); return { apiKey: props['API_KEY'] || '', apiUrl: props['API_URL'] || 'https://api.voorbeeld.nl', debugMode: props['DEBUG'] === 'true', }; } ``` :::tip title="Zet geheimen veilig in Script Properties" Schrijf een eenmalige functie die je waarden uit een lokale bron leest en met `PropertiesService.getScriptProperties().setProperties(...)` wegschrijft. Voer die functie eenmaal uit en verwijder de waarden daarna uit je lokale bestanden. Commit nooit echte sleutels naar Git. ::: ## Enum-typen voor leesbaarheid Enums maken statuswaarden en logniveaus expliciet en voorkomen typfouten in strings. ```typescript enum Status { Actief = 'actief', Inactief = 'inactief', InAfwachting = 'in_afwachting', } enum LogNiveau { INFO = 'INFO', WAARSCHUWING = 'WAARSCHUWING', FOUT = 'FOUT', } function log(niveau: LogNiveau, bericht: string): void { const tijdstip = Utilities.formatDate(new Date(), 'Europe/Amsterdam', 'yyyy-MM-dd HH:mm:ss'); console.log(`[${tijdstip}] [${niveau}] ${bericht}`); } ``` :::howto title="Lokale TypeScript-omgeving opzetten" 1. Controleer dat je Node.js 22 of nieuwer hebt: `node -v`. 2. Installeer clasp globaal: `npm install -g @google/clasp`. 3. Log in: `clasp login`. 4. Maak een projectmap aan en initialiseer met `clasp create-script`. 5. Installeer de types en bouwtools: `npm install --save-dev @types/google-apps-script typescript esbuild`. 6. Maak `tsconfig.json` aan met `target: ES2019` en `noEmit: true`. 7. Schrijf een bundelscript (`build.mjs`) dat `src/` naar `dist/` compileert. 8. Zet `rootDir` in `.clasp.json` op `dist`. 9. Bouw en push: `npm run build && clasp push`. ::: :::faq ### Zet clasp mijn TypeScript nog automatisch om? Nee, niet meer. Vanaf clasp 3 is de ingebouwde TypeScript-transpilatie verwijderd. Je gebruikt nu zelf een bundler zoals esbuild of Rollup om je `.ts`-bestanden naar `.js` te compileren, en pusht daarna het JavaScript-resultaat met clasp. ### Welke JavaScript-versie ondersteunt Apps Script? Apps Script draait op de V8-runtime, die grofweg overeenkomt met ES2019. Stel daarom je compile-doel in op `es2019`, zowel in `tsconfig.json` als in je bundler. ### Welke Node.js-versie heb ik nodig voor clasp 3? clasp 3 vereist Node.js 22 of nieuwer. Controleer dit met `node -v` voordat je installeert; op een oudere versie weigert clasp te starten. ### Kan ik npm-pakketten gebruiken in Apps Script? Soms. Een bundler zoals esbuild of Rollup kan zuivere JavaScript-bibliotheken meebundelen in je uitvoer. Pakketten die afhangen van Node.js-API's of de browser werken niet, omdat de Apps Script-runtime die omgeving niet biedt. ### Werkt clasp ook met spreadsheet-gebonden scripts? Ja. Gebruik `clasp clone-script JOUW_SCRIPT_ID` om een bestaand gebonden script lokaal te halen, of zet de bijbehorende scriptId handmatig in `.clasp.json`. ### Hoe bewaar ik geheimen veilig? Houd lokale waarden in een `.env`-bestand dat in `.gitignore` staat, en zet de echte waarden via een eenmalige functie in Script Properties met `PropertiesService.getScriptProperties()`. Commit nooit echte sleutels naar je repository. ::: ## Conclusie clasp met TypeScript blijft de professionele manier om Apps Script te bouwen: typeveiligheid, betere tooling en Git-versiecontrole. Het grote verschil sinds clasp 3 is dat je zelf een bundelstap toevoegt. Wie dat eenmaal heeft ingericht, ontwikkelt sneller en betrouwbaarder dan in de online-editor.