[
  {
    "path": ".github/workflows/compile.sh",
    "content": "#!/bin/bash\nset -e\necho \"Compiling all code snippets ...\"\ncd tools\nnpm ci\nnpm run compile"
  },
  {
    "path": ".github/workflows/lint.sh",
    "content": "#!/bin/bash\nset -e\necho \"Linting Markdown and Code files ...\"\ncd tools\nnpm ci\nnpm run lint\nnpm run lint:md"
  },
  {
    "path": ".github/workflows/validate-content.yml",
    "content": "name: validate-content \nrun-name: ${{ github.actor }} validate content\non: [pull_request]\njobs:\n  lint-content:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v3\n      - name: Run lint script\n        run: bash ${GITHUB_WORKSPACE}/.github/workflows/lint.sh\n  compile-snippets:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v3\n      - name: Run compile script\n        run: bash ${GITHUB_WORKSPACE}/.github/workflows/compile.sh\n\n      "
  },
  {
    "path": ".gitignore",
    "content": "node_modules\ntemp\n!.vscode\n__pycache__/\n"
  },
  {
    "path": ".vscode/settings.json",
    "content": "{\n    \"editor.formatOnSave\": false,\n}"
  },
  {
    "path": "FUNDING.yml",
    "content": "github: gibbok\nbuy_me_a_coffee: simonepoggiali\ncustom: [\"https://www.paypal.com/donate/?business=QW82ZS956XLFY&no_recurring=0&currency_code=EUR\"]\n"
  },
  {
    "path": "LICENSE.MD",
    "content": "# Licence\n\nThe Concise TypeScript Book © by Simone Poggiali is licensed under Attribution 4.0 International.\n\nFor more information visit:\n<https://creativecommons.org/licenses/by/4.0/>\n"
  },
  {
    "path": "README-it_IT.md",
    "content": "# The Concise TypeScript Book\n\nThe Concise TypeScript Book offre una panoramica completa e concisa delle funzionalità di TypeScript. Questo libro offre spiegazioni chiare che coprono tutti gli aspetti dell'ultima versione del linguaggio, dal suo potente sistema di tipi alle funzionalità avanzate. Che siate principianti o sviluppatori esperti, questo libro è una risorsa preziosa per migliorare la vostra comprensione e competenza in TypeScript.\n\nQuesto libro è completamente gratuito e open source.\n\nCredo che un'istruzione tecnica di alta qualità debba essere accessibile a tutti, ed è per questo che mantengo questo libro gratuito e aperto.\n\nSe il libro ti ha aiutato a risolvere un bug, a comprendere un concetto ostico o a progredire nella tua carriera, ti prego di considerare di sostenere il mio lavoro pagando quanto vuoi (prezzo suggerito: 15 euro) o sponsorizzando un caffè. Il tuo supporto mi aiuta a mantenere i contenuti aggiornati e ad ampliarli con nuovi esempi e spiegazioni più approfondite.\n\n[![Buy Me a Coffee](https://img.shields.io/badge/buy_me_a_coffee-FFDD00?style=for-the-badge&logo=buy-me-a-coffee&logoColor=black)](https://www.buymeacoffee.com/simonepoggiali)\n\n[![Dona](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.com/donate/?business=QW82ZS956XLFY&no_recurring=0&currency_code=EUR)\n\n## Traduzioni\n\nQuesto libro è stato tradotto in diverse lingue, tra cui:\n\n[Cinese](https://github.com/gibbok/typescript-book/blob/main/README-zh_CN.md)\n\n[Italiano](https://github.com/gibbok/typescript-book/blob/main/README-it_IT.md)\n\n[Portoghese (Brasile)](https://github.com/gibbok/typescript-book/blob/main/README-pt_BR.md)\n\n[Svedese](https://github.com/gibbok/typescript-book/blob/main/README-sv_SE.md)\n\n## Download e sito web\n\nPuoi anche scaricare la versione Epub:\n\n[https://github.com/gibbok/typescript-book/tree/main/downloads](https://github.com/gibbok/typescript-book/tree/main/downloads)\n\nÈ disponibile una versione online su:\n\n[https://gibbok.github.io/typescript-book](https://gibbok.github.io/typescript-book)\n\n## Indice\n\n<!-- markdownlint-disable MD004 -->\n\n- [The Concise TypeScript Book](#the-concise-typescript-book)\n- [Traduzioni](#traduzioni)\n- [Download e sito web](#download-e-sito-web)\n- [Indice](#indice)\n- [Introduzione](#introduzione)\n- [Informazioni sull'autore](#informazioni-sullautore)\n- [Introduzione a TypeScript](#introduzione-a-typescript)\n  - [Cos'è TypeScript?](#cosè-typescript)\n  - [Perché TypeScript?](#perché-typescript)\n  - [TypeScript e JavaScript](#typescript-e-javascript)\n  - [Generazione di codice TypeScript](#generazione-di-codice-typescript)\n  - [JavaScript moderno ora (Downleveling)](#javascript-moderno-ora-downleveling)\n- [Per iniziare con TypeScript](#per-iniziare-con-typescript)\n  - [Installazione](#installazione)\n  - [Configurazione](#configurazione)\n  - [File di configurazione TypeScript](#file-di-configurazione-typescript)\n    - [target](#target)\n    - [lib](#lib)\n    - [strict](#strict)\n    - [module](#module)\n    - [moduleResolution](#moduleresolution)\n    - [esModuleInterop](#esmoduleinterop)\n    - [jsx](#jsx)\n    - [skipLibCheck](#skiplibcheck)\n    - [files](#files)\n    - [include](#include)\n    - [exclude](#exclude)\n  - [importHelpers](#importhelpers)\n  - [Consigli per la migrazione a TypeScript](#consigli-per-la-migrazione-a-typescript)\n- [Esplorazione del sistema di tipi](#esplorazione-del-sistema-di-tipi)\n  - [Il servizio di linguaggio TypeScript](#il-servizio-di-linguaggio-typescript)\n  - [Tipizzazione Strutturale](#tipizzazione-strutturale)\n  - [Regole fondamentali di confronto di TypeScript](#regole-fondamentali-di-confronto-di-typescript)\n  - [Tipi come insiemi](#tipi-come-insiemi)\n  - [Allargamento di tipo](#allargamento-di-tipo)\n  - [Const](#const)\n    - [Modificatore Const sui parametri di tipo](#modificatore-const-sui-parametri-di-tipo)\n    - [Asserzione Const](#asserzione-const)\n  - [Annotazione di tipo esplicita](#annotazione-di-tipo-esplicita)\n  - [Restringimento dei tipi](#restringimento-dei-tipi)\n    - [Condizioni](#condizioni)\n    - [Generazione o restituzione](#generazione-o-restituzione)\n    - [Unione Discriminata](#unione-discriminata)\n    - [Protezioni di tipo definite dall'utente](#protezioni-di-tipo-definite-dallutente)\n- [Tipi primitivi](#tipi-primitivi)\n  - [string](#string)\n- [Inferenza letterale](#inferenza-letterale)\n- [strictNullChecks](#strictnullchecks)\n- [Enumerazioni](#enumerazioni)\n  - [Enumerazioni numeriche](#enumerazioni-numeriche)\n  - [Enum String](#enum-string)\n  - [Enum Constant](#enum-constant)\n  - [Mapping inverso](#mapping-inverso)\n  - [Enum ambientali](#enum-ambientali)\n  - [Membri calcolati e costanti](#membri-calcolati-e-costanti)\n- [Restringimento](#restringimento)\n  - [protezioni di tipo typeof](#protezioni-di-tipo-typeof)\n  - [Restringimento di veridicità](#restringimento-di-veridicità)\n  - [Restringimento di uguaglianza](#restringimento-di-uguaglianza)\n  - [Restringimento dell'operatore \"in\"](#restringimento-delloperatore-in)\n  - [Restringimento instanceof](#restringimento-instanceof)\n- [Assegnazioni](#assegnazioni)\n- [Analisi del flusso di controllo](#analisi-del-flusso-di-controllo)\n- [Tipo da Valore](#tipo-da-valore)\n- [Tipo da Ritorno Funzione](#tipo-da-ritorno-funzione)\n- [Tipo da modulo](#tipo-da-modulo)\n- [Tipi mappati](#tipi-mappati)\n- [Modificatori di tipo mappati](#modificatori-di-tipo-mappati)\n- [Tipi condizionali](#tipi-condizionali)\n- [Tipi condizionali distributivi](#tipi-condizionali-distributivi)\n- [infer Inferenza di tipo nei tipi condizionali](#infer-inferenza-di-tipo-nei-tipi-condizionali)\n- [Tipi Condizionali Predefiniti](#tipi-condizionali-predefiniti)\n- [Tipi di unione di template](#tipi-di-unione-di-template)\n- [Tipo Any](#tipo-any)\n- [Tipo Unknown](#tipo-unknown)\n- [Tipo Void](#tipo-void)\n- [Tipo Never](#tipo-never)\n- [Interfaccia e tipo](#interfaccia-e-tipo)\n  - [Sintassi comune](#sintassi-comune)\n  - [Tipi di base](#tipi-di-base)\n  - [Oggetti e interfacce](#oggetti-e-interfacce)\n  - [Modificatori di accesso](#modificatori-di-accesso)\n  - [Get e Set](#get-e-set)\n  - [Accessori automatici nelle classi](#accessori-automatici-nelle-classi)\n  - [this](#this)\n  - [Proprietà dei parametri](#proprietà-dei-parametri)\n  - [Classi astratte](#classi-astratte)\n  - [Con i generici](#con-i-generici)\n  - [Decoratori](#decoratori)\n    - [Decoratori di classe](#decoratori-di-classe)\n    - [Decoratore di proprietà](#decoratore-di-proprietà)\n  - [Ereditarietà](#ereditarietà)\n  - [Statiche](#statiche)\n  - [Inizializzazione delle proprietà](#inizializzazione-delle-proprietà)\n  - [Sovraccarico dei metodi](#sovraccarico-dei-metodi)\n- [Generici](#generici)\n  - [Tipo generico](#tipo-generico)\n  - [Classi generiche](#classi-generiche)\n  - [Vincoli generici](#vincoli-generici)\n  - [Restringimento contestuale generico](#restringimento-contestuale-generico)\n- [Tipi strutturali cancellati](#tipi-strutturali-cancellati)\n- [Namespace](#namespace)\n- [Simboli](#simboli)\n- [Direttive con tripla barra](#direttive-con-tripla-barra)\n- [Manipolazione dei tipi](#manipolazione-dei-tipi)\n  - [Creazione di tipi da tipi](#creazione-di-tipi-da-tipi)\n  - [Tipi di accesso indicizzati](#tipi-di-accesso-indicizzati)\n  - [Tipi di utilità](#tipi-di-utilità)\n    - [Awaited\\<T\\>](#awaitedt)\n    - [Partial\\<T\\>](#partialt)\n    - [Required\\<T\\>](#requiredt)\n    - [Readonly\\<T\\>](#readonlyt)\n    - [Record\\<K, T\\>](#recordk-t)\n    - [Pick\\<T, K\\>](#pickt-k)\n    - [Omit\\<T, K\\>](#omitt-k)\n    - [Exclude\\<T, U\\>](#excludet-u)\n    - [Extract\\<T, U\\>](#extractt-u)\n    - [NonNullable\\<T\\>](#nonnullablet)\n    - [Parameters\\<T\\>](#parameterst)\n    - [ConstructorParameters\\<T\\>](#constructorparameterst)\n    - [ReturnType\\<T\\>](#returntypet)\n    - [InstanceType\\<T\\>](#instancetypet)\n    - [ThisParameterType\\<T\\>](#thisparametertypet)\n    - [OmitThisParameter\\<T\\>](#omitthisparametert)\n    - [ThisType\\<T\\>](#thistypet)\n    - [Uppercase\\<T\\>](#uppercaset)\n    - [Lowercase\\<T\\>](#lowercaset)\n    - [Capitalize\\<T\\>](#capitalizet)\n    - [Uncapitalize\\<T\\>](#uncapitalizet)\n    - [NoInfer\\<T\\>](#noinfert)\n- [Altri](#altri)\n  - [Gestione degli errori e delle eccezioni](#gestione-degli-errori-e-delle-eccezioni)\n  - [Classi Mixin](#classi-mixin)\n  - [Funzionalità del linguaggio asincrono](#funzionalità-del-linguaggio-asincrono)\n  - [Iteratori e Generatori](#iteratori-e-generatori)\n  - [Riferimento JSDoc di TsDocs](#riferimento-jsdoc-di-tsdocs)\n  - [@types](#types)\n  - [JSX](#jsx-1)\n  - [Moduli ES6](#moduli-es6)\n  - [Operatore di elevamento a potenza ES7](#operatore-di-elevamento-a-potenza-es7)\n  - [L'istruzione for-await-of](#listruzione-for-await-of)\n  - [Nuova meta-proprietà target](#nuova-meta-proprietà-target)\n  - [Espressioni di importazione dinamica](#espressioni-di-importazione-dinamica)\n  - [\"tsc –watch\"](#tsc-watch)\n  - [Operatore di asserzione non nullo](#operatore-di-asserzione-non-nullo)\n  - [Dichiarazioni predefinite](#dichiarazioni-predefinite)\n  - [Concatenamento opzionale](#concatenamento-opzionale)\n  - [Operatore di coalescenza nullo](#operatore-di-coalescenza-nullo)\n  - [Tipi letterali di template](#tipi-letterali-di-template)\n  - [Sovraccarico di funzioni](#sovraccarico-di-funzioni)\n  - [Tipi ricorsivi](#tipi-ricorsivi)\n  - [Tipi condizionali ricorsivi](#tipi-condizionali-ricorsivi)\n  - [Supporto per i moduli ECMAScript in Node](#supporto-per-i-moduli-ecmascript-in-node)\n  - [Funzioni di asserzione](#funzioni-di-asserzione)\n  - [Tipi di tupla variadici](#tipi-di-tupla-variadici)\n  - [Tipi boxed](#tipi-boxed)\n  - [Covarianza e Controvarianza in TypeScript](#covarianza-e-controvarianza-in-typescript)\n    - [Annotazioni di varianza opzionali per i parametri di tipo](#annotazioni-di-varianza-opzionali-per-i-parametri-di-tipo)\n  - [Firme di indice con pattern di stringhe modello](#firme-di-indice-con-pattern-di-stringhe-modello)\n  - [Operatore `satisfies`](#operatore-satisfies)\n  - [Importazioni ed esportazioni solo per tipo](#importazioni-ed-esportazioni-solo-per-tipo)\n  - [Dichiarazione using e Gestione Risorse Esplicita](#dichiarazione-using-e-gestione-risorse-esplicita)\n    - [dichiarazione await using](#dichiarazione-await-using)\n  - [Attributi di importazione](#attributi-di-importazione)\n<!-- markdownlint-enable MD004 -->\n\n## Introduzione\n\nBenvenuti a The Concise TypeScript Book! Questa guida vi fornirà le conoscenze essenziali e le competenze pratiche per uno sviluppo TypeScript efficace. Scoprite i concetti e le tecniche chiave per scrivere codice pulito e robusto. Che siate principianti o sviluppatori esperti, questo libro rappresenta sia una guida completa che un pratico riferimento per sfruttare la potenza di TypeScript nei vostri progetti.\n\nQuesto libro tratta TypeScript 5.2.\n\n## Informazioni sull'autore\n\nSimone Poggiali è uno Staff Engineer esperto, con una passione per la scrittura di codice di livello professionale fin dagli anni '90. Nel corso della sua carriera internazionale, ha contribuito a numerosi progetti per un'ampia gamma di clienti, dalle startup alle grandi organizzazioni. Aziende di spicco come HelloFresh, Siemens, O2, Leroy Merlin e Snowplow hanno beneficiato della sua competenza e dedizione.\n\nÈ possibile contattare Simone Poggiali sulle seguenti piattaforme:\n\n* LinkedIn: [https://www.linkedin.com/in/simone-poggiali](https://www.linkedin.com/in/simone-poggiali)\n* GitHub: [https://github.com/gibbok](https://github.com/gibbok)\n* X.com: [https://x.com/gibbok_coding](https://x.com/gibbok_coding)\n* Email: gibbok.coding📧gmail.com\n\nElenco completo dei collaboratori: [https://github.com/gibbok/typescript-book/graphs/contributors](https://github.com/gibbok/typescript-book/graphs/contributors)\n\n## Introduzione a TypeScript\n\n### Cos'è TypeScript?\n\nTypeScript è un linguaggio di programmazione fortemente tipizzato basato su JavaScript. È stato originariamente progettato da Anders Hejlsberg nel 2012 ed è attualmente sviluppato e gestito da Microsoft come progetto open source.\n\nTypeScript si compila in JavaScript e può essere eseguito in qualsiasi runtime JavaScript (ad esempio, un browser o Node.js su un server).\n\nSupporta diversi paradigmi di programmazione, come la programmazione funzionale, generica, imperativa e orientata agli oggetti, ed è un linguaggio compilato (transpilato) che viene convertito in JavaScript prima dell'esecuzione.\n\n### Perché TypeScript?\n\nTypeScript è un linguaggio fortemente tipizzato che aiuta a prevenire errori di programmazione comuni ed evitare determinati tipi di errori di runtime prima dell'esecuzione del programma.\n\nUn linguaggio fortemente tipizzato consente allo sviluppatore di specificare vari vincoli e comportamenti del programma nelle definizioni dei tipi di dati, facilitando la verifica della correttezza del software e la prevenzione dei difetti. Questo è particolarmente utile nelle applicazioni su larga scala.\n\nAlcuni dei vantaggi di TypeScript:\n\n* Tipizzazione statica, facoltativamente fortemente tipizzata\n* Inferenza di tipo\n* Accesso alle funzionalità di ES6 ed ES7\n* Compatibilità multipiattaforma e multibrowser\n* Supporto degli strumenti con IntelliSense\n\n### TypeScript e JavaScript\n\nTypeScript è scritto in file `.ts` o `.tsx`, mentre i file JavaScript sono scritti in file `.js` o `.jsx`.\n\nI file con estensione `.tsx` o `.jsx` possono contenere l'estensione di sintassi JavaScript JSX, utilizzata in React per lo sviluppo dell'interfaccia utente.\n\nTypeScript è un superset tipizzato di JavaScript (ECMAScript 2015) in termini di sintassi. Tutto il codice JavaScript è codice TypeScript valido, ma il contrario non è sempre vero.\n\nAd esempio, si consideri una funzione in un file JavaScript con estensione `.js`, come la seguente:\n\n<!-- skip -->\n```typescript\nconst sum = (a, b) => a + b;\n```\n\nLa funzione può essere convertita e utilizzata in TypeScript modificando l'estensione del file in `.ts`. Tuttavia, se la stessa funzione è annotata con tipi TypeScript, non può essere eseguita in alcun runtime JavaScript senza compilazione. Il seguente codice TypeScript genererà un errore di sintassi se non compilato:\n\n<!-- skip -->\n```typescript\nconst sum = (a: number, b: number): number => a + b;\n```\n\nTypeScript è stato progettato per rilevare possibili eccezioni che possono verificarsi in fase di runtime durante la compilazione, consentendo allo sviluppatore di definire l'intento con annotazioni di tipo. Inoltre, TypeScript può anche rilevare problemi se non viene fornita alcuna annotazione di tipo. Ad esempio, il seguente frammento di codice non specifica alcun tipo TypeScript:\n\n<!-- skip -->\n```typescript\nconst items = [{ x: 1 }, { x: 2 }];\nconst result = items.filter(item => item.y);\n```\n\nIn questo caso, TypeScript rileva un errore e segnala:\n\n```text\nLa proprietà 'y' non esiste sul tipo '{ x: number; }'.\n```\n\nIl sistema di tipi di TypeScript è ampiamente influenzato dal comportamento runtime di JavaScript. Ad esempio, l'operatore di addizione (+), che in JavaScript può eseguire sia la concatenazione di stringhe che l'addizione numerica, è modellato allo stesso modo in TypeScript:\n\n```typescript\nconst result = '1' + 1; // Il risultato è di tipo stringa\n```\n\nIl team di TypeScript ha deliberatamente deciso di segnalare come errori l'utilizzo insolito di JavaScript. Ad esempio, si consideri il seguente codice JavaScript valido:\n\n<!-- skip -->\n```typescript\nconst result = 1 + true; // In JavaScript, il risultato è uguale a 2\n```\n\nTuttavia, TypeScript genera un errore:\n\n```text\nL'operatore '+' non può essere applicato ai tipi 'number' e 'boolean'.\n```\n\nQuesto errore si verifica perché TypeScript applica rigorosamente la compatibilità di tipo e, in questo caso, identifica un'operazione non valida tra un numero e un valore booleano.\n\n### Generazione di codice TypeScript\n\nIl compilatore TypeScript ha due responsabilità principali: il controllo degli errori di tipo e la compilazione in JavaScript. Questi due processi sono indipendenti l'uno dall'altro. I tipi non influenzano l'esecuzione del codice in un runtime JavaScript, poiché vengono completamente cancellati durante la compilazione. TypeScript può comunque generare codice JavaScript anche in presenza di errori di tipo.\nEcco un esempio di codice TypeScript con un errore di tipo:\n\n<!-- skip -->\n```typescript\nconst add = (a: number, b: number): number => a + b;\nconst result = add('x', 'y'); // L'argomento di tipo 'string' non è assegnabile al parametro di tipo 'number'.\n```\n\nTuttavia, può comunque produrre un output JavaScript eseguibile:\n\n<!-- skip -->\n```typescript\n'use strict';\nconst add = (a, b) => a + b;\nconst result = add('x', 'y'); // xy\n```\n\nNon è possibile controllare i tipi TypeScript in fase di esecuzione. Ad esempio:\n\n<!-- skip -->\n```typescript\ninterface Animal {\n    name: string;\n}\ninterface Dog extends Animal {\n    bark: () => void;\n}\ninterface Cat extends Animal {\n    meow: () => void;\n}\nconst makeNoise = (animal: Animal) => {\n    if (animal instanceof Dog) {\n        // 'Dog' si riferisce solo a un tipo, ma qui viene utilizzato come valore.\n        // ...\n    }\n};\n```\n\nPoiché i tipi vengono cancellati dopo la compilazione, non è possibile eseguire questo codice in JavaScript. Per riconoscere i tipi a runtime, dobbiamo usare un altro meccanismo. TypeScript offre diverse opzioni, una delle quali è la \"tagged union\". Ad esempio:\n\n```typescript\ninterface Dog {\n    kind: 'dog'; // Tagged union\n    bark: () => void;\n}\ninterface Cat {\n    kind: 'cat'; // Tagged union\n    meow: () => void;\n}\ntype Animal = Dog | Cat;\n\nconst makeNoise = (animal: Animal) => {\n    if (animal.kind === 'dog') {\n        animal.bark();\n    } else {\n        animal.meow();\n    }\n};\n\nconst dog: Dog = {\n    kind: 'dog',\n    bark: () => console.log('bark'),\n};\nmakeNoise(dog);\n```\n\nLa proprietà \"kind\" è un valore che può essere utilizzato in fase di esecuzione per distinguere gli oggetti in JavaScript.\n\nÈ anche possibile che un valore in fase di esecuzione abbia un tipo diverso da quello dichiarato nella dichiarazione di tipo. Ad esempio, se lo sviluppatore ha interpretato erroneamente un tipo API e lo ha annotato in modo errato.\n\nTypeScript è un superset di JavaScript, quindi la parola chiave \"class\" può essere utilizzata come tipo e valore in fase di esecuzione.\n\n```typescript\nclass Animal {\n    constructor(public name: string) {}\n}\nclass Dog extends Animal {\n    constructor(\n        public name: string,\n        public bark: () => void\n    ) {\n        super(name);\n    }\n}\nclass Cat extends Animal {\n    constructor(\n        public name: string,\n        public meow: () => void\n    ) {\n        super(name);\n    }\n}\ntype Mammal = Dog | Cat;\n\nconst makeNoise = (mammal: Mammal) => {\n    if (mammal instanceof Dog) {\n        mammal.bark();\n    } else {\n        mammal.meow();\n    }\n};\n\nconst dog = new Dog('Fido', () => console.log('bark'));\nmakeNoise(dog);\n```\n\nIn JavaScript, una \"classe\" ha una proprietà \"prototype\" e l'operatore \"instanceof\" può essere utilizzato per verificare se la proprietà prototype di un costruttore appare in qualsiasi punto della catena di prototipi di un oggetto.\n\nTypeScript non ha alcun effetto sulle prestazioni di runtime, poiché tutti i tipi verranno cancellati. Tuttavia, TypeScript introduce un certo overhead in fase di compilazione.\n\n### JavaScript moderno ora (Downleveling)\n\nTypeScript può compilare codice per qualsiasi versione rilasciata di JavaScript a partire da ECMAScript 3 (1999). Ciò significa che TypeScript può transpilare codice dalle funzionalità JavaScript più recenti a versioni precedenti, un processo noto come Downleveling. Questo consente l'utilizzo di JavaScript moderno mantenendo la massima compatibilità con gli ambienti di runtime più vecchi.\n\nÈ importante notare che durante la transpilazione a una versione precedente di JavaScript, TypeScript potrebbe generare codice che potrebbe comportare un sovraccarico di prestazioni rispetto alle implementazioni native.\n\nEcco alcune delle funzionalità di JavaScript moderno che possono essere utilizzate in TypeScript:\n\n* Moduli ECMAScript al posto delle callback \"define\" in stile AMD o delle istruzioni \"require\" di CommonJS.\n* Classi al posto dei prototipi.\n* Dichiarazione di variabili utilizzando \"let\" o \"const\" al posto di \"var\".\n* Ciclo \"for-of\" o \".forEach\" al posto del tradizionale ciclo \"for\".\n* Funzioni freccia al posto delle espressioni di funzione.\n* Assegnazione destrutturata. \\* Nomi abbreviati di proprietà/metodi e nomi di proprietà calcolate.\n* Parametri di funzione predefiniti.\n\nSfruttando queste moderne funzionalità di JavaScript, gli sviluppatori possono scrivere codice più espressivo e conciso in TypeScript.\n\n## Per iniziare con TypeScript\n\n### Installazione\n\nVisual Studio Code offre un eccellente supporto per il linguaggio TypeScript, ma non include il compilatore TypeScript. Per installare il compilatore TypeScript, è possibile utilizzare un gestore di pacchetti come npm o yarn:\n\n```shell\nnpm install typescript --save-dev\n```\n\noppure\n\n```shell\nyarn add typescript --dev\n```\n\nAssicurarsi di eseguire il commit del file di lock generato per garantire che ogni membro del team utilizzi la stessa versione di TypeScript.\n\nPer eseguire il compilatore TypeScript, è possibile utilizzare i seguenti comandi:\n\n```shell\nnpx tsc\n```\n\noppure\n\n```shell\nyarn tsc\n```\n\nSi consiglia di installare TypeScript a livello di progetto anziché globale, poiché garantisce un processo di build più prevedibile. Tuttavia, per occasioni particolari, è possibile utilizzare il seguente comando:\n\n```shell\nnpx tsc\n```\n\noppure installarlo globalmente:\n\n```shell\nnpm install -g typescript\n```\n\nSe si utilizza Microsoft Visual Studio, è possibile ottenere TypeScript come pacchetto in NuGet per i progetti MSBuild. Nella console di Gestione Pacchetti di NuGet, eseguire il seguente comando:\n\n```shell\nInstall-Package Microsoft.TypeScript.MSBuild\n```\n\nDurante l'installazione di TypeScript, vengono installati due eseguibili: \"tsc\" come compilatore TypeScript e \"tsserver\" come server autonomo TypeScript. Il server autonomo contiene il compilatore e i servizi linguistici che possono essere utilizzati da editor e IDE per fornire il completamento intelligente del codice.\n\nInoltre, sono disponibili diversi transpiler compatibili con TypeScript, come Babel (tramite un plugin) o swc. Questi transpiler possono essere utilizzati per convertire il codice TypeScript in altri linguaggi o versioni di destinazione.\n\n### Configurazione\n\nTypeScript può essere configurato utilizzando le opzioni della CLI di tsc o un file di configurazione dedicato chiamato tsconfig.json, posizionato nella radice del progetto.\n\nPer generare un file tsconfig.json precompilato con le impostazioni consigliate, è possibile utilizzare il seguente comando:\n\n```shell\ntsc --init\n```\n\nQuando si esegue il comando `tsc` localmente, TypeScript compilerà il codice utilizzando la configurazione specificata nel file tsconfig.json più vicino.\n\nEcco alcuni esempi di comandi CLI che vengono eseguiti con le impostazioni predefinite:\n\n```shell\ntsc main.ts // Compila un file specifico (main.ts) in JavaScript\ntsc src/*.ts // Compila tutti i file .ts nella cartella 'src' in JavaScript\ntsc app.ts util.ts --outfile index.js // Compila due file TypeScript (app.ts e util.ts) in un singolo file JavaScript (index.js)\n```\n\n### File di configurazione TypeScript\n\nUn file tsconfig.json viene utilizzato per configurare il compilatore TypeScript (tsc). Solitamente, viene aggiunto alla radice del progetto, insieme al file `package.json`.\n\nNote:\n\n* tsconfig.json accetta commenti anche se è in formato json.\n* Si consiglia di utilizzare questo file di configurazione al posto delle opzioni della riga di comando.\n\nAl seguente link potete trovare la documentazione completa e il relativo schema:\n\n[https://www.typescriptlang.org/tsconfig](https://www.typescriptlang.org/tsconfig)\n\n[https://www.typescriptlang.org/tsconfig/](https://www.typescriptlang.org/tsconfig/)\n\nDi seguito è riportato un elenco delle configurazioni più comuni e utili:\n\n#### target\n\nLa proprietà \"target\" viene utilizzata per specificare in quale versione di JavaScript ECMAScript TypeScript deve emettere/compilare. Per i browser moderni, ES6 è una buona opzione, mentre per i browser più vecchi si consiglia ES5.\n\n#### lib\n\nLa proprietà \"lib\" viene utilizzata per specificare quali file di libreria includere in fase di compilazione. TypeScript include automaticamente le API per le funzionalità specificate nella proprietà \"target\", ma è possibile omettere o selezionare librerie specifiche per esigenze particolari. Ad esempio, se si lavora su un progetto server, è possibile escludere la libreria \"DOM\", utile solo in un ambiente browser.\n\n#### strict\n\nLa proprietà \"strict\" offre garanzie più solide e migliora la sicurezza dei tipi. Si consiglia di includere sempre questa proprietà nel file tsconfig.json del progetto. Abilitando la proprietà \"strict\", TypeScript può:\n\n* Emettere codice utilizzando \"use strict\" per ogni file sorgente.\n* Considerare \"null\" e \"undefined\" nel processo di controllo dei tipi.\n* Disabilitare l'utilizzo del tipo \"any\" quando non sono presenti annotazioni di tipo.\n* Generare un errore sull'utilizzo dell'espressione \"this\", che altrimenti implicherebbe il tipo \"any\".\n\n#### module\n\nLa proprietà \"module\" imposta il sistema di moduli supportato dal programma compilato. Durante l'esecuzione, un caricatore di moduli viene utilizzato per individuare ed eseguire le dipendenze in base al sistema di moduli specificato.\n\nI caricatori di moduli più comuni utilizzati in JavaScript sono Node.js CommonJS per le applicazioni lato server e RequireJS per i moduli AMD nelle applicazioni web basate su browser. TypeScript può generare codice per vari sistemi di moduli, tra cui UMD, System, ESNext, ES2015/ES6 ed ES2020.\n\nNota: il sistema di moduli deve essere scelto in base all'ambiente di destinazione e al meccanismo di caricamento dei moduli disponibile in tale ambiente.\n\n#### moduleResolution\n\nLa proprietà \"moduleResolution\" specifica la strategia di risoluzione dei moduli. Utilizzare \"node\" per il codice TypeScript moderno, la strategia \"classic\" viene utilizzata solo per le vecchie versioni di TypeScript (precedenti alla 1.6).\n\n#### esModuleInterop\n\nLa proprietà \"esModuleInterop\" consente l'importazione predefinita dai moduli CommonJS che non sono stati esportati utilizzando la proprietà \"default\". Questa proprietà fornisce uno shim per garantire la compatibilità nel codice JavaScript emesso. Dopo aver abilitato questa opzione, possiamo usare `import MyLibrary from \"my-library\"` invece di `import * as MyLibrary from \"my-library\"`.\n\n#### jsx\n\nLa proprietà \"jsx\" si applica solo ai file .tsx utilizzati in ReactJS e controlla il modo in cui i costrutti JSX vengono compilati in JavaScript. Un'opzione comune è \"preserve\", che compilerà in un file .jsx mantenendo invariato il codice JSX, in modo che possa essere passato a diversi strumenti come Babel per ulteriori trasformazioni.\n\n#### skipLibCheck\n\nLa proprietà \"skipLibCheck\" impedisce a TypeScript di controllare il tipo di tutti i pacchetti di terze parti importati. Questa proprietà riduce il tempo di compilazione di un progetto. TypeScript controllerà comunque il codice rispetto alle definizioni di tipo fornite da questi pacchetti.\n\n#### files\n\nLa proprietà \"files\" indica al compilatore un elenco di file che devono essere sempre inclusi nel programma.\n\n#### include\n\n<!-- markdownlint-disable MD049 -->\n\nLa proprietà \"include\" indica al compilatore un elenco di file che si desidera includere. Questa proprietà consente schemi di tipo glob, come \"\\*_\" per qualsiasi sottodirectory, \"_\" per qualsiasi nome di file e \"?\" per caratteri opzionali.\n\n<!-- markdownlint-enable MD049 -->\n\n#### exclude\n\nLa proprietà \"exclude\" indica al compilatore un elenco di file che non devono essere inclusi nella compilazione. Questo può includere file come \"node_modules\" o file di test.\nNota: tsconfig.json consente commenti.\n\n### importHelpers\n\nTypeScript utilizza codice helper durante la generazione di codice per determinate funzionalità JavaScript avanzate o di livello inferiore. Per impostazione predefinita, questi helper vengono duplicati nei file che li utilizzano. L'opzione `importHelpers` importa invece questi helper dal modulo `tslib`, rendendo l'output JavaScript più efficiente.\n\n### Consigli per la migrazione a TypeScript\n\nPer progetti di grandi dimensioni, si consiglia di adottare una transizione graduale in cui TypeScript e codice JavaScript coesisteranno inizialmente. Solo i progetti di piccole dimensioni possono essere migrati a TypeScript in un'unica soluzione.\n\nIl primo passo di questa transizione è introdurre TypeScript nel processo di build chain. Questo può essere fatto utilizzando l'opzione del compilatore \"allowJs\", che consente ai file .ts e .tsx di coesistere con i file JavaScript esistenti. Poiché TypeScript tornerà al tipo \"any\" per una variabile quando non riesce a dedurre il tipo dai file JavaScript, si consiglia di disabilitare \"noImplicitAny\" nelle opzioni del compilatore all'inizio della migrazione.\n\nIl secondo passaggio consiste nell'assicurarsi che i test JavaScript funzionino insieme ai file TypeScript, in modo da poterli eseguire durante la conversione di ciascun modulo. Se si utilizza Jest, si può valutare l'utilizzo di `ts-jest`, che consente di testare i progetti TypeScript con Jest.\n\nIl terzo passaggio consiste nell'includere le dichiarazioni di tipo per le librerie di terze parti nel progetto. Queste dichiarazioni sono disponibili in bundle o su DefinitelyTyped. È possibile cercarle utilizzando [https://www.typescriptlang.org/dt/search](https://www.typescriptlang.org/dt/search) e installarle tramite:\n\n```shell\nnpm install --save-dev @types/package-name\n```\n\nor\n\n```shell\nyarn add --dev @types/package-name\n```\n\nIl quarto passaggio consiste nel migrare modulo per modulo con un approccio bottom-up, seguendo il grafo delle dipendenze partendo dalle foglie. L'idea è di iniziare a convertire i moduli che non dipendono da altri moduli. Per visualizzare i grafici delle dipendenze, è possibile utilizzare lo strumento \"madge\".\n\nI moduli candidati ideali per queste conversioni iniziali sono funzioni di utilità e codice relativo ad API o specifiche esterne. È possibile generare automaticamente definizioni di tipo TypeScript da contratti Swagger, schemi GraphQL o JSON da includere nel progetto.\n\nQuando non sono disponibili specifiche o schemi ufficiali, è possibile generare tipi da dati grezzi, come JSON restituiti da un server. Tuttavia, si consiglia di generare tipi da specifiche anziché da dati per evitare di perdere casi limite.\n\nDurante la migrazione, evitare il refactoring del codice e concentrarsi solo sull'aggiunta di tipi ai moduli.\n\nIl quinto passaggio consiste nell'abilitare \"noImplicitAny\", che garantirà che tutti i tipi siano noti e definiti, offrendo una migliore esperienza TypeScript per il progetto.\n\nDurante la migrazione, è possibile utilizzare la direttiva `@ts-check`, che abilita il controllo dei tipi TypeScript in un file JavaScript. Questa direttiva fornisce una versione semplificata del controllo dei tipi e può essere utilizzata inizialmente per identificare problemi nei file JavaScript. Quando `@ts-check` è incluso in un file, TypeScript tenterà di dedurre le definizioni utilizzando commenti in stile JSDoc. Tuttavia, si consiglia di utilizzare le annotazioni JSDoc solo in una fase molto precoce della migrazione.\n\nSi consiglia di mantenere il valore predefinito di `noEmitOnError` nel file tsconfig.json su false. Questo consentirà di generare codice sorgente JavaScript anche se vengono segnalati errori.\n\n## Esplorazione del sistema di tipi\n\n### Il servizio di linguaggio TypeScript\n\nIl servizio di linguaggio TypeScript, noto anche come tsserver, offre diverse funzionalità come la segnalazione degli errori, la diagnostica, la compilazione al salvataggio, la ridenominazione, il passaggio alla definizione, gli elenchi di completamento, la guida alle firme e altro ancora. Viene utilizzato principalmente dagli ambienti di sviluppo integrati (IDE) per fornire supporto IntelliSense. Si integra perfettamente con Visual Studio Code ed è utilizzato da strumenti come Conquer of Completion (Coc).\n\nGli sviluppatori possono sfruttare un'API dedicata e creare plugin di servizi linguistici personalizzati per migliorare l'esperienza di modifica di TypeScript. Questo può essere particolarmente utile per implementare funzionalità di linting speciali o abilitare il completamento automatico per un linguaggio di template personalizzato.\n\n<!-- markdownlint-disable MD044 -->\n\nUn esempio di plugin personalizzato reale è \"TypeScript-styled-plugin\", che fornisce la segnalazione degli errori di sintassi e il supporto IntelliSense per le proprietà CSS nei componenti con stile. <!-- markdownlint-enable MD044 -->\n\nPer ulteriori informazioni e guide rapide, è possibile consultare il Wiki ufficiale di TypeScript su GitHub: [https://github.com/microsoft/TypeScript/wiki/](https://github.com/microsoft/TypeScript/wiki/)\n\n### Tipizzazione Strutturale\n\nTypeScript si basa su un sistema di tipi strutturale. Ciò significa che la compatibilità e l'equivalenza dei tipi sono determinate dalla struttura o definizione effettiva del tipo, piuttosto che dal suo nome o dal punto di dichiarazione, come nei sistemi di tipi nominativi come C# o C.\n\nIl sistema di tipi strutturale di TypeScript è stato progettato sulla base del funzionamento del sistema di tipizzazione dinamica di JavaScript durante l'esecuzione.\n\nL'esempio seguente è codice TypeScript valido. Come si può osservare, \"X\" e \"Y\" hanno lo stesso membro \"a\", anche se hanno nomi di dichiarazione diversi. I tipi sono determinati dalle loro strutture e, in questo caso, poiché le strutture sono le stesse, sono compatibili e validi.\n\n```typescript\ntype X = {\n    a: string;\n};\ntype Y = {\n    a: string;\n};\nconst x: X = { a: 'a' };\nconst y: Y = x; // Valido\n```\n\n### Regole fondamentali di confronto di TypeScript\n\nIl processo di confronto di TypeScript è ricorsivo ed è eseguito su tipi annidati a qualsiasi livello.\n\nUn tipo \"X\" è compatibile con \"Y\" se \"Y\" ha almeno gli stessi membri di \"X\".\n\n```typescript\ntype X = {\n    a: string;\n};\nconst y = { a: 'A', b: 'B' }; // Valido, poiché ha almeno gli stessi membri di X\nconst r: X = y;\n```\n\nI parametri delle funzioni vengono confrontati in base al tipo, non al nome:\n\n```typescript\ntype X = (a: number) => void;\ntype Y = (a: number) => void;\nlet x: X = (j: number) => undefined;\nlet y: Y = (k: number) => undefined;\ny = x; // Valido\nx = y; // Valido\n```\n\nI tipi restituiti dalla funzione devono essere gli stessi:\n\n<!-- skip -->\n```typescript\ntype X = (a: number) => undefined;\ntype Y = (a: number) => number;\nlet x: X = (a: number) => undefined;\nlet y: Y = (a: number) => 1;\ny = x; // Non valido\nx = y; // Non valido\n```\n\nIl tipo di ritorno di una funzione sorgente deve essere un sottotipo del tipo di ritorno di una funzione target:\n\n<!-- skip -->\n```typescript\nlet x = () => ({ a: 'A' });\nlet y = () => ({ a: 'A', b: 'B' });\nx = y; // Valido\ny = x; // Il membro non valido b è mancante\n```\n\nÈ consentito ignorare i parametri della funzione, come è prassi comune in JavaScript, ad esempio utilizzando \"Array.prototype.map()\":\n\n```typescript\n[1, 2, 3].map((element, _index, _array) => element + 'x');\n```\n\nPertanto, le seguenti dichiarazioni di tipo sono completamente valide:\n\n```typescript\ntype X = (a: number) => undefined;\ntype Y = (a: number, b: number) => undefined;\nlet x: X = (a: number) => undefined;\n\nlet y: Y = (a: number) => undefined; // Parametro b mancante\ny = x; // Valido\n```\n\nTutti i parametri opzionali aggiuntivi del tipo sorgente sono validi:\n\n```typescript\ntype X = (a: number, b?: number, c?: number) => undefined;\ntype Y = (a: number) => undefined;\nlet x: X = a => undefined;\nlet y: Y = a => undefined;\ny = x; // Valido\nx = y; //Valido\n```\n\nTutti i parametri opzionali del tipo destinazione senza parametri corrispondenti nel tipo sorgente sono validi e non costituiscono un errore:\n\n```typescript\ntype X = (a: number) => undefined;\ntype Y = (a: number, b?: number) => undefined;\nlet x: X = a => undefined;\nlet y: Y = a => undefined;\ny = x; // Valido\nx = y; // Valido\n```\n\nIl parametro rest viene trattato come una serie infinita di parametri opzionali:\n\n```typescript\ntype X = (a: number, ...rest: number[]) => undefined;\nlet x: X = a => undefined; //valido\n```\n\nLe funzioni con overload sono valide se la firma di overload è compatibile con la firma della sua implementazione:\n\n<!-- skip -->\n```typescript\nfunction x(a: string): void;\nfunction x(a: string, b: number): void;\nfunction x(a: string, b?: number): void {\n    console.log(a, b);\n}\nx('a'); // Valido\nx('a', 1); // Valido\n\nfunction y(a: string): void; // Non valido, non compatibile con la firma dell'implementazione\nfunction y(a: string, b: number): void;\nfunction y(a: string, b: number): void {\n    console.log(a, b);\n}\ny('a');\ny('a', 1);\n```\n\nIl confronto dei parametri della funzione ha esito positivo se i parametri sorgente e destinazione sono assegnabili a supertipi o sottotipi (bivarianza).\n\n```typescript\n// Supertipo\nclass X {\n    a: string;\n    constructor(value: string) {\n        this.a = value;\n    }\n}\n// Sottotipo\nclass Y extends X {}\n// Sottotipo\nclass Z extends X {}\n\ntype GetA = (x: X) => string;\nconst getA: GetA = x => x.a;\n\n// La bivarianza accetta supertipi\nconsole.log(getA(new X('x'))); // Valido\nconsole.log(getA(new Y('Y'))); // Valido\nconsole.log(getA(new Z('z'))); // Valido\n```\n\nGli enum sono confrontabili e validi con i numeri e viceversa, ma il confronto di valori Enum di tipi Enum diversi non è valido.\n\n<!-- skip -->\n```typescript\nenum X {\n    A,\n    B,\n}\nenum Y {\n    A,\n    B,\n    C,\n}\nconst xa: number = X.A; // Valido\nconst ya: Y = 0; // Valido\nX.A === Y.A; // Non valido\n```\n\nLe istanze di una classe sono soggette a un controllo di compatibilità per i loro membri privati ​​e protetti:\n\n<!-- skip -->\n```typescript\nclass X {\n    public a: string;\n    constructor(value: string) {\n        this.a = value;\n    }\n}\n\nclass Y {\n    private a: string;\n    constructor(value: string) {\n        this.a = value;\n    }\n}\n\nlet x: X = new Y('y'); // Non valido\n```\n\nIl controllo di confronto non tiene conto della diversa gerarchia di ereditarietà, ad esempio:\n\n```typescript\nclass X {\n    public a: string;\n    constructor(value: string) {\n        this.a = value;\n    }\n}\nclass Y extends X {\n    public a: string;\n    constructor(value: string) {\n        super(value);\n        this.a = value;\n    }\n}\nclass Z {\n    public a: string;\n    constructor(value: string) {\n        this.a = value;\n    }\n}\nlet x: X = new X('x');\nlet y: Y = new Y('y');\nlet z: Z = new Z('z');\nx === y; // Valido\nx === z; // Valido anche se z proviene da una gerarchia di ereditarietà diversa\n```\n\nI generici vengono confrontati utilizzando le loro strutture in base al tipo risultante dopo l'applicazione del parametro generico; solo il risultato finale viene confrontato come tipo non generico.\n\n<!-- skip -->\n```typescript\ninterface X<T> {\n    a: T;\n}\nlet x: X<number> = { a: 1 };\nlet y: X<string> = { a: 'a' };\nx === y; // Non valido poiché l'argomento tipo è utilizzato nella struttura finale\n```\n\n```typescript\ninterface X<T> {}\nconst x: X<number> = 1;\nconst y: X<string> = 'a';\nx === y; // Valido poiché l'argomento tipo non è utilizzato nella struttura finale\n```\n\nQuando i generici non hanno il loro argomento tipo specificato, tutti gli argomenti non specificati vengono trattati come tipi con \"any\":\n\n```typescript\ntype X = <T>(x: T) => T;\ntype Y = <K>(y: K) => K;\nlet x: X = x => x;\nlet y: Y = y => y;\nx = y; // Valido\n```\n\nRicorda:\n\n<!-- skip -->\n```typescript\nlet a: number = 1;\nlet b: number = 2;\na = b; // Valido, tutto è assegnabile a se stesso\n\nlet c: any;\nc = 1; // Valido, tutti i tipi sono assegnabili a qualsiasi\n\nlet d: unknown;\nd = 1; // Valido, tutti i tipi sono assegnabili a sconosciuto\n\nlet e: unknown;\nlet e1: unknown = e; // Valido, sconosciuto è assegnabile solo a se stesso e a qualsiasi\nlet e2: any = e; // Valido\nlet e3: number = e; // Non valido\n\nlet f: never;\nf = 1; // Non valido, nulla è assegnabile a never\n\nlet g: void;\nlet g1: any;\ng = 1; // Non valido, void non è assegnabile a o da nulla, tranne qualsiasi\ng = g1; // Valido\n```\n\nSi noti che quando \"strictNullChecks\" è abilitato, \"null\" e \"undefined\" vengono trattati in modo simile a \"void\"; in caso contrario, sono simili a \"never\".\n\n### Tipi come insiemi\n\nIn TypeScript, un tipo è un insieme di possibili valori. Questo insieme è anche definito dominio del tipo. Ogni valore di un tipo può essere visto come un elemento di un insieme. Un tipo stabilisce i vincoli che ogni elemento dell'insieme deve soddisfare per essere considerato membro di quell'insieme.\nIl compito principale di TypeScript è controllare e verificare se un insieme è un sottoinsieme di un altro.\n\nTypeScript supporta vari tipi di insiemi:\n\n| Termine di insieme             | TypeScript                        | Note                                                                                                                                          |\n| ------------------------------ | --------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |\n| Insieme vuoto                  | never                             | \"never\" non contiene nulla                                                                                                   |\n| Insieme di un singolo elemento | undefined / null / tipo letterale |                                                                                                                                               |\n| Insieme finito                 | boolean / union                   |                                                                                                                                               |\n| Insieme infinito               | string / number / object          |                                                                                                                                               |\n| Insieme universale             | any / unknown           | Ogni elemento è un membro di \"any\" e ogni insieme è un suo sottoinsieme / \"unknown\" è una controparte di tipo sicuro di \"any\" |\n\nEcco alcuni esempi:\n\n| TypeScript     | Termine di insieme          | Esempio                                                                           |\n| -------------- | --------------------------- | --------------------------------------------------------------------------------- |\n| never          | ∅ (insieme vuoto)           | const x: never = 'x'; // Errore: il tipo 'string' non è assegnabile al tipo 'never' |\n|                |                             |\n| Tipo letterale | Insieme di elementi singoli | type X = 'X';                                                                     |\n\n| | | type Y = 7; |\n| | |\n| Valore assegnabile a T | Valore ∈ T (membro di) | type XY = 'X' \\| 'Y'; |\n| | | const x: XY = 'X'; |\n| | |\n| T1 assegnabile a T2 | T1 ⊆ T2 (sottoinsieme di) | type XY = 'X' \\| 'Y'; |\n| | | const x: XY = 'X'; |\n| | | const j: XY = 'J'; // Il tipo '\"J\"' non è assegnabile al tipo 'XY'. |\n| | | |\n| T1 extends T2 | T1 ⊆ T2 (sottoinsieme di) | type X = 'X' extends string ? true : false; |\n| | |\n| T1 \\| T2 | T1 ∪ T2 (unione) | type XY = 'X' \\| 'Y'; |\n| | | type JK = 1 \\| 2; |\n| | |\n| T1 & T2 | T1 ∩ T2 (intersezione) | type X = \\{ a: string \\} |\n| | | type Y = \\{ b: string \\} |\n| | | type XY = X & Y |\n| | | const x: XY = \\{ a: 'a', b: 'b' \\} |\n| | |\n| unknown | Insieme universale | const x: unknown = 1 |\n\nUn'unione (T1 | T2) crea un insieme più ampio (entrambi):\n\n```typescript\ntype X = {\n    a: string;\n};\ntype Y = {\n    b: string;\n};\ntype XY = X | Y;\nconst r: XY = { a: 'a', b: 'x' }; // Valido\n```\n\nUn'intersezione (T1 e T2) crea un insieme più ristretto (solo condiviso):\n\n<!-- skip -->\n```typescript\ntype X = {\n    a: string;\n};\ntype Y = {\n    a: string;\n    b: string;\n};\ntype XY = X & Y;\nconst r: XY = { a: 'a' }; // Non valido\nconst j: XY = { a: 'a', b: 'b' }; // Valido\n```\n\nLa parola chiave `extends` potrebbe essere considerata un \"sottoinsieme di\" in questo contesto. Imposta un vincolo per un tipo. L'extends utilizzato con un generico, considera il generico come un insieme infinito e lo vincola a un tipo più specifico. Si noti che ``extends` non ha nulla a che fare con la gerarchia in senso OOP (questo concetto non esiste in TypeScript).\nTypeScript funziona con insiemi e non ha una gerarchia rigida; infatti, come nell'esempio seguente, due tipi potrebbero sovrapporsi senza che uno dei due sia un sottotipo dell'altro (TypeScript considera la struttura e la forma degli oggetti).\n\n```typescript\ninterface X {\n    a: string;\n}\ninterface Y extends X {\n    b: string;\n}\ninterface Z extends Y {\n    c: string;\n}\nconst z: Z = { a: 'a', b: 'b', c: 'c' };\ninterface X1 {\n    a: string;\n}\n\ninterface Y1 {\n    a: string;\n    b: string;\n}\ninterface Z1 {\n    a: string;\n    b: string;\n    c: string;\n}\nconst z1: Z1 = { a: 'a', b: 'b', c: 'c' };\n\nconst r: Z1 = z; // Valido\n```\n\n### Assegnare un tipo: Dichiarazioni di tipo e asserzioni di tipo\n\nUn tipo può essere assegnato in diversi modi in TypeScript:\n\n#### Dichiarazione di tipo\n\nNell'esempio seguente, utilizziamo x: X (\": Type\") per dichiarare un tipo per la variabile x.\n\n```typescript\ntype X = {\n    a: string;\n};\n\n// Dichiarazione di tipo\nconst x: X = {\n    a: 'a',\n};\n```\n\nSe la variabile non è nel formato specificato, TypeScript segnalerà un errore. Ad esempio:\n\n<!-- skip -->\n```typescript\ntype X = {\n    a: string;\n};\n\nconst x: X = {\n    a: 'a',\n    b: 'b', // Errore: il letterale dell'oggetto può specificare solo proprietà note\n};\n```\n\n#### Asserzione di tipo\n\nÈ possibile aggiungere un'asserzione utilizzando la parola chiave `as`. Questo indica al compilatore che lo sviluppatore ha maggiori informazioni su un tipo e silenzia eventuali errori.\n\nAd esempio:\n\n```typescript\ntype X = {\n    a: string;\n};\nconst x = {\n    a: 'a',\n    b: 'b',\n} as X;\n```\n\nNell'esempio precedente, si asserisce che l'oggetto x abbia il tipo X utilizzando la parola chiave as. Questo informa il compilatore TypeScript che l'oggetto è conforme al tipo specificato, anche se ha una proprietà aggiuntiva b non presente nella definizione del tipo.\n\nLe asserzioni di tipo sono utili in situazioni in cui è necessario specificare un tipo più specifico, soprattutto quando si lavora con il DOM. Ad esempio:\n\n```typescript\nconst myInput = document.getElementById('my_input') as HTMLInputElement;\n```\n\nQui, l'asserzione di tipo come HTMLInputElement viene utilizzata per indicare a TypeScript che il risultato di getElementById deve essere trattato come un HTMLInputElement.\nLe asserzioni di tipo possono anche essere utilizzate per rimappare le chiavi, come mostrato nell'esempio seguente con letterali di template:\n\n```typescript\ntype J<Type> = {\n    [Property in keyof Type as `prefix_${string &\n        Property}`]: () => Type[Property];\n};\ntype X = {\n    a: string;\n    b: number;\n};\ntype Y = J<X>;\n```\n\nIn questo esempio, il tipo `J<Tipo>` utilizza un tipo mappato con un letterale template per rimappare le chiavi di Tipo. Crea nuove proprietà con un \"prefisso\\_\" aggiunto a ciascuna chiave e i valori corrispondenti sono funzioni che restituiscono i valori delle proprietà originali.\n\nÈ importante notare che quando si utilizza un'asserzione di tipo, TypeScript non eseguirà controlli di proprietà eccessivi. Pertanto, è generalmente preferibile utilizzare una Dichiarazione di Tipo quando la struttura dell'oggetto è nota in anticipo.\n\n#### Dichiarazioni Ambientali\n\nLe dichiarazioni Ambientali sono file che descrivono i tipi per il codice JavaScript e hanno un formato di nome file come `.d.ts.`. Di solito vengono importate e utilizzate per annotare librerie JavaScript esistenti o per aggiungere tipi a file JS esistenti nel progetto.\n\nMolti tipi di librerie comuni sono disponibili all'indirizzo:\n[https://github.com/DefinitelyTyped/DefinitelyTyped/](https://github.com/DefinitelyTyped/DefinitelyTyped/)\n\ne possono essere installate tramite:\n\n```shell\nnpm install --save-dev @types/library-name\n```\n\nPer le dichiarazioni di ambiente definite, è possibile importarle utilizzando il riferimento \"tripla barra\":\n\n<!-- skip -->\n```typescript\n/// <reference path=\"./library-types.d.ts\" />\n```\n\nÈ possibile utilizzare le dichiarazioni di ambiente anche all'interno di file JavaScript utilizzando `// @ts-check`.\n\nLa parola chiave `declare` abilita le definizioni di tipo per il codice JavaScript esistente senza importarlo, fungendo da segnaposto per i tipi da un altro file o a livello globale.\n\n### Controllo delle proprietà e controllo delle proprietà in eccesso\n\nTypeScript si basa su un sistema di tipi strutturale, ma il controllo delle proprietà in eccesso è una proprietà di TypeScript che gli consente di verificare se un oggetto possiede esattamente le proprietà specificate nel tipo.\n\nIl controllo delle proprietà in eccesso viene eseguito, ad esempio, quando si assegnano letterali di oggetto a variabili o quando li si passa come argomenti alla proprietà in eccesso di una funzione.\n\n<!-- skip -->\n```typescript\ntype X = {\n    a: string;\n};\nconst y = { a: 'a', b: 'b' };\nconst x: X = y; // Valido perché tipizzazione strutturale\nconst w: X = { a: 'a', b: 'b' }; // Non valido perché controllo delle proprietà in eccesso\n```\n\n### Tipi deboli\n\nUn tipo è considerato debole quando contiene solo un insieme di proprietà completamente opzionali:\n\n```typescript\ntype X = {\n    a?: string;\n    b?: string;\n};\n```\n\nTypeScript considera un errore assegnare qualsiasi cosa a un tipo debole quando non c'è sovrapposizione, ad esempio, il seguente codice genera un errore:\n\n<!-- skip -->\n```typescript\ntype Options = {\n    a?: string;\n    b?: string;\n};\n\nconst fn = (options: Options) => undefined;\n\nfn({ c: 'c' }); // Non valido\n```\n\nSebbene non sia consigliato, se necessario, è possibile bypassare questo controllo utilizzando l'asserzione di tipo:\n\n```typescript\ntype Options = {\n    a?: string;\n    b?: string;\n};\nconst fn = (options: Options) => undefined;\nfn({ c: 'c' } as Options); // Valido\n```\n\nOppure aggiungendo `unknown` alla firma dell'indice del tipo debole:\n\n```typescript\ntype Options = {\n    [prop: string]: unknown;\n    a?: string;\n    b?: string;\n};\n\nconst fn = (options: Options) => undefined;\nfn({ c: 'c' }); // Valido\n```\n\n### Controllo rigoroso dei letterali di oggetto (freschezza)\n\nIl controllo rigoroso dei letterali di oggetto, a volte chiamato \"freschezza\", è una funzionalità di TypeScript che aiuta a individuare proprietà in eccesso o con errori di ortografia che altrimenti passerebbero inosservate nei normali controlli di tipo strutturale.\n\nQuando si crea un letterale di oggetto, il compilatore TypeScript lo considera \"fresco\". Se il letterale di oggetto viene assegnato a una variabile o passato come parametro, TypeScript genererà un errore se il letterale di oggetto specifica proprietà che non esistono nel tipo di destinazione.\n\nTuttavia, la \"freschezza\" scompare quando un letterale di oggetto viene ampliato o viene utilizzata un'asserzione di tipo.\n\nEcco alcuni esempi per illustrare:\n\n<!-- skip -->\n```typescript\ntype X = { a: string };\ntype Y = { a: string; b: string };\n\nlet x: X;\nx = { a: 'a', b: 'b' }; // Controllo di freschezza: Assegnazione non valida\nvar y: Y;\ny = { a: 'a', bx: 'bx' }; // Controllo di freschezza: Assegnazione non valida\n\nconst fn = (x: X) => console.log(x.a);\n\nfn(x);\nfn(y); // Allargamento: Nessun errore, strutturalmente compatibile con il tipo\n\nfn({ a: 'a', bx: 'b' }); // Controllo di aggiornamento: argomento non valido\n\nlet c: X = { a: 'a' };\nlet d: Y = { a: 'a', b: '' };\nc = d; // Allargamento: nessun controllo di aggiornamento\n```\n\n### Inferenza di tipo\n\nTypeScript può inferire i tipi quando non viene fornita alcuna annotazione durante:\n\n* Inizializzazione delle variabili.\n* Inizializzazione dei membri.\n* Impostazione dei valori predefiniti per i parametri.\n* Tipo di ritorno della funzione.\n\nAd esempio:\n\n```typescript\nlet x = 'x'; // Il tipo inferito è una stringa\n```\n\nIl compilatore TypeScript analizza il valore o l'espressione e ne determina il tipo in base alle informazioni disponibili.\n\n### Inferenze più avanzate\n\nQuando si utilizzano più espressioni nell'inferenza di tipo, TypeScript cerca i \"tipi più comuni\". Ad esempio:\n\n```typescript\nlet x = [1, 'x', 1, null]; // Il tipo dedotto è: (string | number | null)[]\n```\n\nSe il compilatore non riesce a trovare i tipi comuni migliori, restituisce un tipo unione. Ad esempio:\n\n```typescript\nlet x = [new RegExp('x'), new Date()]; // Il tipo inferito è: (RegExp | Date)[]\n```\n\nTypeScript utilizza la \"tipizzazione contestuale\" basata sulla posizione della variabile per inferire i tipi. Nell'esempio seguente, il compilatore sa che `e` è di tipo `MouseEvent` grazie al tipo di evento `click` definito nel file lib.d.ts, che contiene dichiarazioni ambientali per vari costrutti JavaScript comuni e il DOM:\n\n```typescript\nwindow.addEventListener('click', function (e) {}); // Il tipo inferito di e è MouseEvent\n```\n\n### Allargamento di tipo\n\nL'allargamento di tipo è il processo in cui TypeScript assegna un tipo a una variabile inizializzata quando non è stata fornita alcuna annotazione di tipo. Consente il passaggio da tipi stretti a più ampi, ma non viceversa. Nell'esempio seguente:\n\n<!-- skip -->\n```typescript\nlet x = 'x'; // TypeScript inferisce come stringa, un tipo ampio\nlet y: 'y' | 'x' = 'y'; // Il tipo y è un'unione di tipi letterali\ny = x; // Il tipo non valido 'string' non è assegnabile al tipo '\"x\" | \"y\"'.\n```\n\nTypeScript assegna `string` a `x` in base al singolo valore fornito durante l'inizializzazione (`x`); questo è un esempio di ampliamento.\n\nTypeScript fornisce modi per controllare il processo di ampliamento, ad esempio utilizzando \"const\".\n\n### Const\n\nL'utilizzo della parola chiave `const` durante la dichiarazione di una variabile produce un'inferenza di tipo più ristretta in TypeScript.\n\nAd esempio:\n\n```typescript\nconst x = 'x'; // TypeScript deduce il tipo di x come 'x', un tipo più ristretto\nlet y: 'y' | 'x' = 'y';\ny = x; // Valido: il tipo di x viene dedotto come 'x'\n```\n\nUtilizzando `const` per dichiarare la variabile x, il suo tipo viene ristretto allo specifico valore letterale 'x'. Poiché il tipo di x viene ristretto, può essere assegnato alla variabile y senza errori.\nIl motivo per cui il tipo può essere dedotto è che le variabili `const` non possono essere riassegnate, quindi il loro tipo può essere ristretto a un tipo letterale specifico, in questo caso, il tipo letterale 'x'.\n\n#### Modificatore Const sui parametri di tipo\n\nDalla versione 5.0 di TypeScript, è possibile specificare l'attributo `const` su un parametro di tipo generico. Questo consente di dedurre il tipo più preciso possibile. Vediamo un esempio senza usare `const`:\n\n```typescript\nfunction identity<T>(value: T) {\n    // Nessuna costante qui\n    return value;\n}\nconst values = identity({ a: 'a', b: 'b' }); // Il tipo inferito è: { a: string; b: string; }\n```\n\nCome puoi vedere, le proprietà `a` e `b` vengono inferite con un tipo `string`.\n\nOra, vediamo la differenza con la versione `const`:\n\n```typescript\nfunction identity<const T>(value: T) {\n    // Utilizzo del modificatore const sui parametri di tipo\n    return value;\n}\nconst values = identity({ a: 'a', b: 'b' }); // Il tipo inferito è: { a: \"a\"; b: \"b\"; }\n```\n\nOra possiamo vedere che le proprietà `a` e `b` vengono dedotte come `const`, quindi `a` e `b` vengono trattate come stringhe letterali anziché come semplici tipi `string`.\n\n#### Asserzione Const\n\nQuesta funzionalità consente di dichiarare una variabile con un tipo letterale più preciso in base al suo valore di inizializzazione, indicando al compilatore che il valore deve essere trattato come un letterale immutabile. Ecco alcuni esempi:\n\nSu una singola proprietà:\n\n```typescript\nconst v = {\n    x: 3 as const,\n};\nv.x = 3;\n```\n\nSu un intero oggetto:\n\n```typescript\nconst v = {\n    x: 1,\n    y: 2,\n} as const;\n```\n\nQuesto può essere particolarmente utile quando si definisce il tipo per una tupla:\n\n```typescript\nconst x = [1, 2, 3]; // number[]\nconst y = [1, 2, 3] as const; // Tupla di readonly [1, 2, 3]\n```\n\n### Annotazione di tipo esplicita\n\nPossiamo essere specifici e passare un tipo, nell'esempio seguente la proprietà `x` è di tipo `number`:\n\n```typescript\nconst v = {\n    x: 1, // Inferred type: number (widening)\n};\nv.x = 3; // Valido\n```\n\nPossiamo rendere l'annotazione di tipo più specifica utilizzando un'unione di tipi letterali:\n\n<!-- skip -->\n```typescript\nconst v: { x: 1 | 2 | 3 } = {\n    x: 1, // x è ora un'unione di tipi letterali: 1 | 2 | 3\n};\nv.x = 3; // Valido\nv.x = 100; // Non valido\n```\n\n### Restringimento dei tipi\n\nIl restringimento dei tipi è il processo in TypeScript in cui un tipo generico viene ridotto a un tipo più specifico. Ciò si verifica quando TypeScript analizza il codice e determina che determinate condizioni o operazioni possono perfezionare le informazioni sul tipo.\n\nIl restringimento dei tipi può avvenire in diversi modi, tra cui:\n\n#### Condizioni\n\nUtilizzando istruzioni condizionali, come `if` o `switch`, TypeScript può restringere il tipo in base al risultato della condizione. Ad esempio:\n\n```typescript\nlet x: number | undefined = 10;\n\nif (x !== undefined) {\n    x += 100; // Il tipo è number, che è stato ristretto dalla condizione\n}\n```\n\n#### Generazione o restituzione\n\nGenerare un errore o restituire un'istruzione in anticipo da un branch può essere utilizzato per aiutare TypeScript a restringere un tipo. Ad esempio:\n\n```typescript\nlet x: number | undefined = 10;\n\nif (x === undefined) {\n    throw 'error';\n}\nx += 100;\n```\n\nAltri modi per restringere i tipi in TypeScript includono:\n\n* Operatore `instanceof`: utilizzato per verificare se un oggetto è un'istanza di una classe specifica.\n* Operatore `in`: utilizzato per verificare se una proprietà esiste in un oggetto.\n* Operatore `typeof`: utilizzato per verificare il tipo di un valore in fase di esecuzione.\n* Funzioni integrate come `Array.isArray()`: utilizzate per verificare se un valore è un array.\n\n#### Unione Discriminata\n\nL'utilizzo di una \"Unione Discriminata\" è un pattern in TypeScript in cui un \"tag\" esplicito viene aggiunto agli oggetti per distinguere i diversi tipi all'interno di un'unione. Questo pattern è anche definito \"unione con tag\". Nell'esempio seguente, il \"tag\" è rappresentato dalla proprietà \"type\":\n\n```typescript\ntype A = { type: 'type_a'; value: number };\ntype B = { type: 'type_b'; value: string };\n\nconst x = (input: A | B): string | number => {\n    switch (input.type) {\n        case 'type_a':\n            return input.value + 100; // il tipo è A\n        case 'type_b':\n            return input.value + 'extra'; // il tipo è B\n    }\n};\n```\n\n#### Protezioni di tipo definite dall'utente\n\nNei casi in cui TypeScript non sia in grado di determinare un tipo, è possibile scrivere una funzione di supporto nota come \"protezione di tipo definita dall'utente\". Nell'esempio seguente, utilizzeremo un predicato di tipo per restringere il tipo dopo aver applicato un determinato filtro:\n\n```typescript\nconst data = ['a', null, 'c', 'd', null, 'f'];\n\nconst r1 = data.filter(x => x != null); // Il tipo è (string | null)[], TypeScript non è riuscito a dedurre correttamente il tipo\n\nconst isValid = (item: string | null): item is string => item !== null; // Protezione personalizzata del tipo\n\nconst r2 = data.filter(isValid); // Il tipo ora è corretto string[], utilizzando la protezione del tipo predicato siamo riusciti a restringere il tipo\n```\n\n## Tipi primitivi\n\nTypeScript supporta 7 tipi primitivi. Un tipo di dati primitivo si riferisce a un tipo che non è un oggetto e non ha metodi associati. In TypeScript, tutti i tipi primitivi sono immutabili, il che significa che i loro valori non possono essere modificati una volta assegnati.\n\n### string\n\nIl tipo primitivo `string` memorizza dati testuali e il valore è sempre racchiuso tra virgolette doppie o singole.\n\n```typescript\nconst x: string = 'x';\nconst y: string = 'y';\n```\n\nLe stringhe possono estendersi su più righe se racchiuse dal carattere di apice inverso (`):\n\n```typescript\nlet sentence: string = `xxx,\nyyy`;\n```\n\n### boolean\n\nIl tipo di dati `boolean` in TypeScript memorizza un valore binario, `true` o `false`.\n\n```typescript\nconst isReady: boolean = true;\n```\n\n### number\n\nUn tipo di dati `number` in TypeScript è rappresentato da un valore in virgola mobile a 64 bit. Un tipo di dati `number` può rappresentare numeri interi e frazioni.\nTypeScript supporta anche i sistemi di numerazione esadecimale, binario e ottale, ad esempio:\n\n```typescript\nconst decimal: number = 10;\nconst hexadecimal: number = 0xa00d; // L'esadecimale inizia con 0x\nconst binary: number = 0b1010; // Il binario inizia con 0b\nconst octal: number = 0o633; // L'ottale inizia con 0o\n```\n\n### bigInt\n\nUn `bigInt` rappresenta valori numerici molto grandi (253 – 1) e non possono essere rappresentati con un `number`.\n\nUn `bigInt` può essere creato chiamando la funzione integrata `BigInt()` o aggiungendo `n` alla fine di qualsiasi letterale numerico intero:\n\n```typescript\nconst x: bigint = BigInt(9007199254740991);\nconst y: bigint = 9007199254740991n;\n```\n\nNote:\n\n* I valori `bigInt` non possono essere combinati con `number` e non possono essere utilizzati con `Math` integrato, devono essere forzati allo stesso tipo.\n* I valori `bigInt` sono disponibili solo se la configurazione di destinazione è ES2020 o superiore.\n\n### Simbolo\n\nI simboli sono identificatori univoci che possono essere utilizzati come chiavi di proprietà negli oggetti per evitare conflitti di denominazione.\n\n```typescript\ntype Obj = {\n    [sym: symbol]: number;\n};\n\nconst a = Symbol('a');\nconst b = Symbol('b');\nlet obj: Obj = {};\nobj[a] = 123;\nobj[b] = 456;\n\nconsole.log(obj[a]); // 123\nconsole.log(obj[b]); // 456\n```\n\n### null e undefined\n\nI tipi `null` e `undefined` rappresentano entrambi nessun valore o l'assenza di qualsiasi valore.\n\nIl tipo `undefined` indica che il valore non è assegnato o inizializzato o indica un'assenza involontaria di valore.\n\nIl tipo `null` indica che sappiamo che il campo non ha un valore, quindi il valore non è disponibile, e indica un'assenza intenzionale di valore.\n\n### Array\n\nUn `array` è un tipo di dati che può memorizzare più valori dello stesso tipo o meno. Può essere definito utilizzando la seguente sintassi:\n\n```typescript\nconst x: string[] = ['a', 'b'];\nconst y: Array<string> = ['a', 'b'];\nconst j: Array<string | number> = ['a', 1, 'b', 2]; // Unione\n```\n\nTypeScript supporta array di sola lettura utilizzando la seguente sintassi:\n\n<!-- skip -->\n```typescript\nconst x: readonly string[] = ['a', 'b']; // Modificatore di sola lettura\nconst y: ReadonlyArray<string> = ['a', 'b'];\nconst j: ReadonlyArray<string | number> = ['a', 1, 'b', 2];\nj.push('x'); // Non valido\n```\n\nTypeScript supporta tuple e tuple di sola lettura:\n\n```typescript\nconst x: [string, number] = ['a', 1];\nconst y: readonly [string, number] = ['a', 1];\n```\n\n### any\n\nIl tipo di dati ``any` rappresenta letteralmente un valore \"qualsiasi\", ed è il valore predefinito quando TypeScript non può dedurre il tipo o non è specificato.\n\nQuando si utilizza `any`, il compilatore TypeScript salta il controllo del tipo, quindi non c'è sicurezza di tipo quando si utilizza `any`. In genere, non utilizzare `any` per silenziare il compilatore quando si verifica un errore, ma concentrarsi sulla correzione dell'errore, poiché utilizzando `any` è possibile interrompere i contratti e perdere i vantaggi del completamento automatico di TypeScript.\n\nIl tipo `any` potrebbe essere utile durante una migrazione graduale da JavaScript a TypeScript, in quanto può silenziare il compilatore.\n\nPer i nuovi progetti, utilizzare la configurazione TypeScript `noImplicitAny`, che consente a TypeScript di generare errori quando viene utilizzato o dedotto `any`.\n\nIl tipo `any` è solitamente fonte di errori che possono mascherare problemi reali con i tipi. Evitatelo il più possibile.\n\n## Annotazioni di tipo\n\nSulle variabili dichiarate usando `var`, `let` e `const`, è possibile aggiungere facoltativamente un tipo:\n\n```typescript\nconst x: number = 1;\n```\n\nTypeScript esegue un buon lavoro nell'inferenza dei tipi, soprattutto quando si tratta di tipi semplici, quindi queste dichiarazioni nella maggior parte dei casi non sono necessarie.\n\nSulle funzioni è possibile aggiungere annotazioni di tipo ai parametri:\n\n```typescript\nfunction sum(a: number, b: number) {\n    return a + b;\n}\n```\n\nIl seguente è un esempio che utilizza una funzione anonima (la cosiddetta funzione lambda):\n\n```typescript\nconst sum = (a: number, b: number) => a + b;\n```\n\nQueste annotazioni possono essere evitate quando è presente un valore predefinito per un parametro:\n\n```typescript\nconst sum = (a = 10, b: number) => a + b;\n```\n\nLe annotazioni del tipo di ritorno possono essere aggiunte alle funzioni:\n\n```typescript\nconst sum = (a = 10, b: number): number => a + b;\n```\n\nQuesto è utile soprattutto per le funzioni più complesse, poiché scrivere esplicitamente il tipo di ritorno prima di un'implementazione può aiutare a pensare meglio alla funzione.\n\nIn genere, si consiglia di annotare le firme dei tipi, ma non le variabili locali del corpo, e di aggiungere i tipi sempre ai letterali degli oggetti.\n\n## Proprietà facoltative\n\nUn oggetto può specificare Proprietà facoltative aggiungendo un punto interrogativo `?` alla fine del nome della proprietà:\n\n```typescript\ntype X = {\n    a: number;\n    b?: number; // Facoltativo\n};\n```\n\nÈ possibile specificare un valore predefinito quando una proprietà è facoltativa\"\n\n```typescript\ntype X = {\n    a: number;\n    b?: number;\n};\nconst x = ({ a, b = 100 }: X) => a + b;\n```\n\n## Proprietà di sola lettura\n\nÈ possibile impedire la scrittura su una proprietà utilizzando il modificatore `readonly`, che assicura che la proprietà non possa essere riscritta ma non fornisce alcuna garanzia di immutabilità totale:\n\n```typescript\ninterface Y {\n    readonly a: number;\n}\n\ntype X = {\n    readonly a: number;\n};\n\ntype J = Readonly<{\n    a: number;\n}>;\n\ntype K = {\n    readonly [index: number]: string;\n};\n```\n\n## Firme di indice\n\nIn TypeScript possiamo usare come firma di indice `string`, `number` e `symbol`:\n\n```typescript\ntype K = {\n    [name: string | number]: string;\n};\nconst k: K = { x: 'x', 1: 'b' };\nconsole.log(k['x']);\nconsole.log(k[1]);\nconsole.log(k['1']); // Stesso risultato di k[1]\n```\n\nSi noti che JavaScript converte automaticamente un indice con `number` in un indice con `string`, quindi `k[1]` o `k[\"1\"]` restituiscono lo stesso valore.\n\n## Estensione dei tipi\n\nÈ possibile estendere un'`interfaccia` (copiare membri da un altro tipo):\n\n```typescript\ninterface X {\n    a: string;\n}\ninterface Y extends X {\n    b: string;\n}\n```\n\nÈ anche possibile estendere da più tipi:\n\n```typescript\ninterface A {\n    a: string;\n}\ninterface B {\n    b: string;\n}\ninterface Y extends A, B {\n    y: string;\n}\n```\n\nLa parola chiave `extends` funziona solo su interfacce e classi; per i tipi utilizzare un'intersezione:\n\n```typescript\ntype A = {\n    a: number;\n};\ntype B = {\n    b: number;\n};\ntype C = A & B;\n```\n\nÈ possibile estendere un tipo utilizzando un'inferenza, ma non viceversa:\n\n```typescript\ntype A = {\n    a: string;\n};\ninterface B extends A {\n    b: string;\n}\n```\n\n## Tipi letterali\n\nUn tipo letterale è un singolo insieme di elementi di un tipo collettivo; definisce un valore molto preciso che è una primitiva JavaScript.\n\nI tipi letterali in TypeScript sono numeri, stringhe e booleani.\n\nEsempio di letterali:\n\n```typescript\nconst a = 'a'; // Stringa tipo letterale\n\nconst b = 1; // Numeric literal type\nconst c = true; // Boolean literal type\n```\n\nI tipi letterali stringa, numerico e booleano vengono utilizzati nell'unione, nella protezione dei tipi e negli alias di tipo.\nNell'esempio seguente, è possibile vedere un alias di tipo unione. `O` è costituito solo dai valori specificati, nessun'altra stringa è valida:\n\n```typescript\ntype O = 'a' | 'b' | 'c';\n```\n\n## Inferenza letterale\n\nL'inferenza letterale è una funzionalità di TypeScript che consente di dedurre il tipo di una variabile o di un parametro in base al suo valore.\n\nNell'esempio seguente possiamo vedere che TypeScript considera `x` un tipo letterale in quanto il valore non può essere modificato in seguito, mentre `y` viene dedotto come stringa in quanto può essere modificato in seguito.\n\n```typescript\nconst x = 'x'; // Literal type of 'x', because this value cannot be changed\nlet y = 'y'; // Type string, because we can change this value\n```\n\nNell'esempio seguente possiamo vedere che `o.x` è stato dedotto come `string` (e non come un letterale di `a`), poiché TypeScript considera che il valore possa essere modificato in qualsiasi momento successivo.\n\n<!-- skip -->\n```typescript\ntype X = 'a' | 'b';\n\nlet o = {\n    x: 'a', // Questa è una stringa più ampia\n};\n\nconst fn = (x: X) => `${x}-foo`;\n\nconsole.log(fn(o.x)); // L'argomento di tipo 'string' non è assegnabile al parametro di tipo 'X'\n```\n\nCome puoi vedere, il codice genera un errore quando si passa `o.x` a `fn`, poiché X è un tipo più ristretto.\n\nPossiamo risolvere questo problema utilizzando l'asserzione di tipo `const` o il tipo `X`:\n\n<!-- skip -->\n```typescript\nlet o = {\n    x: 'a' as const,\n};\n```\n\noppure:\n\n<!-- skip -->\n```typescript\nlet o = {\n    x: 'a' as X,\n};\n```\n\n## strictNullChecks\n\n`strictNullChecks` è un'opzione del compilatore TypeScript che impone un controllo null rigoroso. Quando questa opzione è abilitata, variabili e parametri possono essere assegnati a `null` o `undefined` solo se sono stati dichiarati esplicitamente di quel tipo utilizzando l'unione `null` | `undefined`. Se una variabile o un parametro non viene dichiarato esplicitamente come nullable, TypeScript genererà un errore per prevenire potenziali errori di runtime.\n\n## Enumerazioni\n\nIn TypeScript, un `enum` è un insieme di valori costanti denominati.\n\n```typescript\nenum Colore {\n    Rosso = '#ff0000',\n    Verde = '#00ff00',\n    Blu = '#0000ff',\n}\n```\n\nGli enum possono essere definiti in diversi modi:\n\n### Enumerazioni numeriche\n\nIn TypeScript, un enum numerico è un enum in cui a ogni costante viene assegnato un valore numerico, a partire da 0 per impostazione predefinita.\n\n```typescript\nenum Size {\n    Small, // il valore inizia da 0\n    Medium,\n    Large,\n}\n```\n\nÈ possibile specificare valori personalizzati assegnandoli esplicitamente:\n\n```typescript\nenum Size {\n    Small = 10,\n    Medium,\n    Large,\n}\nconsole.log(Size.Medium); // 11\n```\n\n### Enum String\n\nIn TypeScript, un enum String è un enum in cui a ogni costante viene assegnato un valore stringa.\n\n```typescript\nenum Language {\n    English = 'EN',\n    Spanish = 'ES',\n}\n```\n\nNota: TypeScript consente l'utilizzo di enum eterogenei in cui stringhe e membri numerici possono coesistere.\n\n### Enum Constant\n\nUn enum Constant in TypeScript è un tipo speciale di enum in cui tutti i valori sono noti in fase di compilazione e vengono inlineati ovunque venga utilizzato l'enum, con conseguente maggiore efficienza del codice.\n\n```typescript\nconst enum Language {\n    English = 'EN',\n    Spanish = 'ES',\n}\nconsole.log(Language.English);\n```\n\nVerrà compilato in:\n\n```typescript\nconsole.log('EN' /* Language.English */);\n```\n\nNote:\n\nGli enum costanti hanno valori hardcoded, che cancellano l'enum, il che può essere più efficiente nelle librerie autonome, ma generalmente non è auspicabile. Inoltre, gli enum costanti non possono avere membri calcolati.\n\n### Mapping inverso\n\nIn TypeScript, i mapping inversi negli enum si riferiscono alla possibilità di recuperare il nome del membro dell'enum dal suo valore. Per impostazione predefinita, i membri dell'enum hanno mapping in avanti dal nome al valore, ma i mapping inversi possono essere creati impostando esplicitamente i valori per ciascun membro. I mapping inversi sono utili quando è necessario cercare un membro dell'enum in base al suo valore o quando è necessario iterare su tutti i membri dell'enum. Si noti che solo i membri dell'enum numerico genereranno mapping inversi, mentre i membri dell'enum stringa non generano alcun mapping inverso.\n\nIl seguente enum:\n\n```typescript\nenum Grade {\n    A = 90,\n    B = 80,\n    C = 70,\n    F = 'fail',\n}\n```\n\nCompila in:\n\n<!-- skip -->\n```javascript\n\"use strict\";\nvar Grade;\n(function (Grade) {\n  Grade[(Grade[\"A\"] = 90)] = \"A\";\n  Grade[(Grade[\"B\"] = 80)] = \"B\";\n  Grade[(Grade[\"C\"] = 70)] = \"C\";\n  Grade[\"F\"] = \"fail\";\n})(Grade || (Grade = {}));\n```\n\nPertanto, la mappatura dei valori alle chiavi funziona per i membri enum numerici, ma non per i membri enum stringa:\n\n<!-- skip -->\n```typescript\nenum Grade {\n    A = 90,\n    B = 80,\n    C = 70,\n    F = 'fail',\n}\nconst myGrade = Grade.A;\nconsole.log(Grade[myGrade]); // A\nconsole.log(Grade[90]); // A\n\nconst failGrade = Grade.F;\nconsole.log(failGrade); // fail\nconsole.log(Grade[failGrade]); // Element ha implicitamente un tipo 'any' perché l'espressione indice non è di tipo 'number'.\n```\n\n### Enum ambientali\n\nUn enum ambientale in TypeScript è un tipo di Enum definito in un file di dichiarazione (\\*.d.ts) senza un'implementazione associata. Permette di definire un set di costanti denominate che possono essere utilizzate in modo sicuro tra file diversi senza dover importare i dettagli di implementazione in ogni file.\n\n### Membri calcolati e costanti\n\nIn TypeScript, un membro calcolato è un membro di un Enum il cui valore è calcolato in fase di esecuzione, mentre un membro costante è un membro il cui valore è impostato in fase di compilazione e non può essere modificato in fase di esecuzione. I membri calcolati sono consentiti negli Enum normali, mentre i membri costanti sono consentiti sia negli enum normali che in quelli costanti.\n\n```typescript\n// Membri costanti\nenum Color {\n    Red = 1,\n    Green = 5,\n    Blue = Red + Green,\n}\nconsole.log(Color.Blue); // 6 generazioni in fase di compilazione\n```\n\n```typescript\n// Membri calcolati\nenum Color {\n    Red = 1,\n    Green = Math.pow(2, 2),\n    Blue = Math.floor(Math.random() * 3) + 1,\n}\nconsole.log(Color.Blue); // numero casuale generato in fase di esecuzione\n```\n\nGli enum sono indicati da unioni che comprendono i loro tipi di membri. I valori di ciascun membro possono essere determinati tramite espressioni costanti o non costanti, con i membri che possiedono valori costanti a cui vengono assegnati tipi letterali. Per illustrare, si consideri la dichiarazione del tipo E e dei suoi sottotipi E.A, E.B ed E.C. In questo caso, E rappresenta l'unione E.A | E.B | E.C.\n\n```typescript\nconst identity = (value: number) => value;\n\nenum E {\n    A = 2 * 5, // Letterale numerico\n    B = 'bar', // Letterale stringa\n    C = identity(42), // Calcolato opaco\n}\n\nconsole.log(E.C); //42\n```\n\n## Restringimento\n\nIl restringimento di TypeScript è il processo di perfezionamento del tipo di una variabile all'interno di un blocco condizionale. Questo è utile quando si lavora con tipi union, in cui una variabile può avere più di un tipo.\n\nTypeScript riconosce diversi modi per restringere il tipo:\n\n### protezioni di tipo typeof\n\nIl type guard typeof è uno specifico type guard in TypeScript che controlla il tipo di una variabile in base al suo tipo JavaScript predefinito.\n\n```typescript\nconst fn = (x: number | string) => {\n    if (typeof x === 'number') {\n        return x + 1; // x è un numero\n    }\n    return -1;\n};\n```\n\n### Restringimento di veridicità\n\nIl restringimento di veridicità in TypeScript funziona verificando se una variabile è vera o falsa, per restringerne di conseguenza il tipo.\n\n```typescript\nconst toUpperCase = (name: string | null) => {\n    if (name) {\n        return name.toUpperCase();\n    } else {\n        return null;\n    }\n};\n```\n\n### Restringimento di uguaglianza\n\nIl restringimento di uguaglianza in TypeScript funziona verificando se una variabile è uguale o meno a un valore specifico, per restringerne di conseguenza il tipo.\n\nViene utilizzato insieme alle istruzioni `switch` e agli operatori di uguaglianza come `===`, `!==`, `==` e `!=` per restringere i tipi.\n\n```typescript\nconst checkStatus = (status: 'success' | 'error') => {\n    switch (status) {\n        case 'success':\n            return true;\n        case 'error':\n            return null;\n    }\n};\n```\n\n### Restringimento dell'operatore `in`\n\nIl restringimento dell'operatore `in` in TypeScript è un modo per restringere il tipo di una variabile in base all'esistenza di una proprietà all'interno del tipo della variabile.\n\n```typescript\ntype Dog = {\n    name: string;\n    breed: string;\n};\n\ntype Cat = {\n    name: string;\n    likesCream: boolean;\n};\n\nconst getAnimalType = (pet: Dog | Cat) => {\n    if ('breed' in pet) {\n        return 'dog';\n    } else {\n        return 'cat';\n    }\n};\n```\n\n### Restringimento instanceof\n\nL'operatore di restringimento `instanceof` in TypeScript è un modo per restringere il tipo di una variabile in base alla sua funzione costruttore, verificando se un oggetto è un'istanza di una determinata classe o interfaccia.\n\n```typescript\nclass Square {\n    constructor(public width: number) {}\n}\nclass Rectangle {\n    constructor(\n        public width: number,\n        public height: number\n    ) {}\n}\nfunction area(shape: Square | Rectangle) {\n    if (shape instanceof Square) {\n        return shape.width * shape.width;\n    } else {\n        return shape.width * shape.height;\n    }\n}\nconst square = new Square(5);\nconst rectangle = new Rectangle(5, 10);\nconsole.log(area(square)); // 25\nconsole.log(area(rectangle)); // 50\n```\n\n## Assegnazioni\n\nIl restringimento TypeScript tramite assegnazioni è un modo per restringere il tipo di una variabile in base al valore assegnato. Quando a una variabile viene assegnato un valore, TypeScript ne deduce il tipo in base al valore assegnato e restringe il tipo della variabile in modo che corrisponda al tipo dedotto.\n\n```typescript\nlet value: string | number;\nvalue = 'hello';\nif (typeof value === 'string') {\n    console.log(value.toUpperCase());\n}\nvalue = 42;\nif (typeof value === 'number') {\n    console.log(value.toFixed(2));\n}\n```\n\n## Analisi del flusso di controllo\n\nL'analisi del flusso di controllo in TypeScript è un modo per analizzare staticamente il flusso di codice per dedurre i tipi di variabili, consentendo al compilatore di restringere i tipi di tali variabili secondo necessità, in base ai risultati dell'analisi.\n\nPrima di TypeScript 4.4, l'analisi del flusso di codice veniva applicata solo al codice all'interno di un'istruzione if, ma da TypeScript 4.4 può essere applicata anche alle espressioni condizionali e agli accessi alle proprietà discriminanti referenziati indirettamente tramite variabili const.\n\nAd esempio:\n\n```typescript\nconst f1 = (x: unknown) => {\n    const isString = typeof x === 'string';\n    if (isString) {\n        x.length;\n    }\n};\n\nconst f2 = (\n    obj: { kind: 'foo'; foo: string } | { kind: 'bar'; bar: number }\n) => {\n    const isFoo = obj.kind === 'foo';\n    if (isFoo) {\n        obj.foo;\n    } else {\n        obj.bar;\n    }\n};\n```\n\nAlcuni esempi in cui il restringimento non avviene:\n\n<!-- skip -->\n```typescript\nconst f1 = (x: unknown) => {\n    let isString = typeof x === 'string';\n    if (isString) {\n        x.length; // Errore, nessun restringimento perché isString non è costante\n    }\n};\n\nconst f6 = (\n    obj: { kind: 'foo'; foo: string } | { kind: 'bar'; bar: number }\n) => {\n    const isFoo = obj.kind === 'foo';\n    obj = obj;\n    if (isFoo) {\n        obj.foo; // Errore, nessun restringimento perché obj è assegnato nel corpo della funzione\n    }\n};\n```\n\nNote: Nelle espressioni condizionali vengono analizzati fino a cinque livelli di indirezione.\n\n## Predicati di tipo\n\nI predicati di tipo in TypeScript sono funzioni che restituiscono un valore booleano e vengono utilizzate per restringere il tipo di una variabile a un tipo più specifico.\n\n```typescript\nconst isString = (value: unknown): value is string => typeof value === 'string';\n\nconst foo = (bar: unknown) => {\n    if (isString(bar)) {\n        console.log(bar.toUpperCase());\n    } else {\n        console.log('not a string');\n    }\n};\n```\n\n## Unioni Discriminate\n\nLe unioni Discriminate in TypeScript sono un tipo di unione che utilizza una proprietà comune, nota come discriminante, per restringere l'insieme dei tipi possibili per l'unione.\n\n```typescript\ntype Square = {\n    kind: 'square'; // Discriminante\n    size: number;\n};\n\ntype Circle = {\n    kind: 'circle'; // Discriminante\n    radius: number;\n};\n\ntype Shape = Square | Circle;\n\nconst area = (shape: Shape) => {\n    switch (shape.kind) {\n        case 'square':\n            return Math.pow(shape.size, 2);\n        case 'circle':\n            return Math.PI * Math.pow(shape.radius, 2);\n    }\n};\n\nconst square: Square = { kind: 'square', size: 5 };\nconst circle: Circle = { kind: 'circle', radius: 2 };\n\nconsole.log(area(square)); // 25\nconsole.log(area(circle)); // 12.566370614359172\n```\n\n## Il tipo never\n\nQuando una variabile viene ristretta a un tipo che non può contenere alcun valore, il compilatore TypeScript dedurrà che la variabile deve essere del tipo `never`. Questo perché il tipo `never` rappresenta un valore che non può mai essere prodotto.\n\n```typescript\nconst printValue = (val: string | number) => {\n    if (typeof val === 'string') {\n        console.log(val.toUpperCase());\n    } else if (typeof val === 'number') {\n        console.log(val.toFixed(2));\n    } else {\n        // val ha il tipo never qui perché non può essere altro che una stringa o un numero\n        const neverVal: never = val;\n        console.log(`Valore imprevisto: ${neverVal}`);\n    }\n};\n```\n\n## Controllo di esaustività\n\nIl controllo di esaustività è una funzionalità di TypeScript che garantisce che tutti i possibili casi di unione discriminata vengano gestiti in un'istruzione `switch` o in un'istruzione `if`.\n\n```typescript\ntype Direction = 'up' | 'down';\n\nconst move = (direction: Direction) => {\n    switch (direction) {\n        case 'up':\n            console.log(\"Spostamento verso l'alto\");\n            break;\n        case 'down':\n            console.log('Spostamento verso il basso');\n            break;\n        default:\n            const exhaustiveCheck: never = direction;\n            console.log(exhaustiveCheck); // Questa riga non verrà mai eseguita\n    }\n};\n```\n\nIl tipo `never` viene utilizzato per garantire che il caso predefinito sia esaustivo e che TypeScript generi un errore se un nuovo valore viene aggiunto al tipo Direction senza essere gestito nell'istruzione switch.\n\n## Tipi di oggetto\n\nIn TypeScript, i tipi di oggetto descrivono la forma di un oggetto. Specificano i nomi e i tipi delle proprietà dell'oggetto, nonché se tali proprietà sono obbligatorie o facoltative.\n\nIn TypeScript, è possibile definire i tipi di oggetto in due modi principali:\n\ninterface, che definisce la forma di un oggetto specificando i nomi, i tipi e l'opzionalità delle sue proprietà.\n\n```typescript\ninterface User {\n    name: string;\n    age: number;\n    email?: string;\n}\n```\n\nUn alias di tipo, simile a un'interfaccia, definisce la forma di un oggetto. Tuttavia, può anche creare un nuovo tipo personalizzato basato su un tipo esistente o su una combinazione di tipi esistenti. Ciò include la definizione di tipi unione, tipi intersezione e altri tipi complessi.\n\n```typescript\ntype Point = {\n    x: number;\n    y: number;\n};\n```\n\nÈ anche possibile definire un tipo in modo anonimo:\n\n```typescript\nconst sum = (x: { a: number; b: number }) => x.a + x.b;\nconsole.log(sum({ a: 5, b: 1 }));\n```\n\n## Tipo di tupla (anonimo)\n\nUn tipo di tupla è un tipo che rappresenta un array con un numero fisso di elementi e i relativi tipi. Un tipo di tupla impone un numero specifico di elementi e i rispettivi tipi in un ordine fisso. I tipi di tupla sono utili quando si desidera rappresentare una raccolta di valori con tipi specifici, dove la posizione di ciascun elemento nell'array ha un significato specifico.\n\n```typescript\ntype Point = [number, number];\n```\n\n## Tipo di tupla denominato (etichettato)\n\nI tipi di tupla possono includere etichette o nomi opzionali per ciascun elemento. Queste etichette servono per migliorare la leggibilità e facilitare l'utilizzo degli strumenti e non influiscono sulle operazioni che è possibile eseguire con esse.\n\n```typescript\ntype T = string;\ntype Tuple1 = [T, T];\ntype Tuple2 = [a: T, b: T];\ntype Tuple3 = [a: T, T]; // Tupla con nome più Tupla anonima\n```\n\n## Tupla a lunghezza fissa\n\nUna tupla a lunghezza fissa è un tipo specifico di tupla che impone un numero fisso di elementi di tipi specifici e non consente alcuna modifica alla lunghezza della tupla una volta definita.\n\nLe tuple a lunghezza fissa sono utili quando è necessario rappresentare una raccolta di valori con un numero specifico di elementi e tipi specifici e si desidera garantire che la lunghezza e i tipi della tupla non possano essere modificati inavvertitamente.\n\n<!-- skip -->\n```typescript\nconst x = [10, 'hello'] as const;\nx.push(2); // Errore\n```\n\n## Tipo Unione\n\nUn Tipo Unione è un tipo che rappresenta un valore che può essere di diversi tipi. I Tipi Unione sono indicati con il simbolo `|` tra ogni tipo possibile.\n\n```typescript\nlet x: string | number;\nx = 'hello'; // Valido\nx = 123; // Valido\n```\n\n## Tipi Intersezione\n\nUn Tipo Intersezione è un tipo che rappresenta un valore che ha tutte le proprietà di due o più tipi. I Tipi Intersezione sono indicati con il simbolo `&` tra ogni tipo.\n\n```typescript\ntype X = {\n    a: string;\n};\n\ntype Y = {\n    b: string;\n};\n\ntype J = X & Y; // Intersezione\n\nconst j: J = {\n    a: 'a',\n    b: 'b',\n};\n```\n\n## Indicizzazione dei tipi\n\nL'indicizzazione dei tipi si riferisce alla capacità di definire tipi che possono essere indicizzati da una chiave non nota in anticipo, utilizzando una firma di indice per specificare il tipo per le proprietà che non sono dichiarate esplicitamente.\n\n```typescript\ntype Dictionary<T> = {\n    [key: string]: T;\n};\nconst myDict: Dictionary<string> = { a: 'a', b: 'b' };\n\nconsole.log(myDict['a']); // Restituisce un\n```\n\n## Tipo da Valore\n\nIn TypeScript, il tipo da valore si riferisce all'inferenza automatica di un tipo da un valore o da un'espressione tramite inferenza di tipo.\n\n```typescript\nconst x = 'x'; // TypeScript inferisce 'x' come una stringa letterale con 'const' (immutabile), ma lo amplia a 'string' con 'let' (riassegnabile).\n```\n\n## Tipo da Ritorno Funzione\n\nIl tipo da Ritorno Funzione si riferisce alla possibilità di inferire automaticamente il tipo di ritorno di una funzione in base alla sua implementazione. Ciò consente a TypeScript di determinare il tipo del valore restituito dalla funzione senza annotazioni di tipo esplicite.\n\n```typescript\nconst add = (x: number, y: number) => x + y; // TypeScript può dedurre che il tipo restituito dalla funzione sia un numero\n```\n\n## Tipo da modulo\n\nIl tipo da modulo si riferisce alla possibilità di utilizzare i valori esportati di un modulo per dedurne automaticamente il tipo. Quando un modulo esporta un valore con un tipo specifico, TypeScript può utilizzare tali informazioni per dedurre automaticamente il tipo di quel valore quando viene importato in un altro modulo.\n\n<!-- skip -->\n```typescript\n// calc.ts\nexport const add = (x: number, y: number) => x + y;\n// index.ts\nimport { add } from 'calc';\nconst r = add(1, 2); // r è un numero\n```\n\n## Tipi mappati\n\nI tipi mappati in TypeScript consentono di creare nuovi tipi basati su un tipo esistente trasformando ciascuna proprietà tramite una funzione di mappatura. Mappando i tipi esistenti, è possibile creare nuovi tipi che rappresentano le stesse informazioni in un formato diverso. Per creare un tipo mappato, si accede alle proprietà di un tipo esistente utilizzando l'operatore `keyof` e quindi le si modifica per produrre un nuovo tipo.\nNell'esempio seguente:\n\n```typescript\ntype MyMappedType<T> = {\n    [P in keyof T]: T[P][];\n};\ntype MyType = {\n    foo: string;\n    bar: number;\n};\ntype MyNewType = MyMappedType<MyType>;\nconst x: MyNewType = {\n    foo: ['hello', 'world'],\n    bar: [1, 2, 3],\n};\n```\n\nDefiniamo MyMappedType per mappare le proprietà di T, creando un nuovo tipo con ogni proprietà come array del suo tipo originale. In questo modo, creiamo MyNewType per rappresentare le stesse informazioni di MyType, ma con ogni proprietà come array.\n\n## Modificatori di tipo mappati\n\nI modificatori di tipo mappati in TypeScript consentono la trasformazione delle proprietà all'interno di un tipo esistente:\n\n* `readonly` o `+readonly`: questo rende una proprietà nel tipo mappato di sola lettura.\n* `-readonly`: questo consente a una proprietà nel tipo mappato di essere modificabile.\n* `?`: questo designa una proprietà nel tipo mappato come facoltativa.\n\nEsempi:\n\n```typescript\ntype ReadOnly<T> = { readonly [P in keyof T]: T[P] }; // Tutte le proprietà contrassegnate come di sola lettura\n\ntype Mutable<T> = { -readonly [P in keyof T]: T[P] }; // Tutte le proprietà contrassegnate come modificabili\n\ntype MyPartial<T> = { [P in keyof T]?: T[P] }; // Tutte le proprietà contrassegnate come facoltative\n```\n\n## Tipi condizionali\n\nI tipi condizionali sono un modo per creare un tipo che dipende da una condizione, in cui il tipo da creare viene determinato in base al risultato della condizione. Sono definiti utilizzando la parola chiave `extends` e un operatore ternario per scegliere condizionatamente tra due tipi.\n\n```typescript\ntype IsArray<T> = T extends any[] ? true : false;\n\nconst myArray = [1, 2, 3];\nconst myNumber = 42;\n\ntype IsMyArrayAnArray = IsArray<typeof myArray>; // Type true\ntype IsMyNumberAnArray = IsArray<typeof myNumber>; // Type false\n```\n\n## Tipi condizionali distributivi\n\nI tipi condizionali distributivi sono una funzionalità che consente di distribuire un tipo su un'unione di tipi, applicando una trasformazione a ciascun membro dell'unione individualmente.\nQuesto può essere particolarmente utile quando si lavora con tipi mappati o tipi di ordine superiore.\n\n```typescript\ntype Nullable<T> = T extends any ? T | null : never;\ntype NumberOrBool = number | boolean;\ntype NullableNumberOrBool = Nullable<NumberOrBool>; // number | boolean | null\n```\n\n## infer Inferenza di tipo nei tipi condizionali\n\nLa parola chiave `infer` viene utilizzata nei tipi condizionali per inferire (estrarre) il tipo di un parametro generico da un tipo che dipende da esso. Questo consente di scrivere definizioni di tipo più flessibili e riutilizzabili.\n\n```typescript\ntype ElementType<T> = T extends (infer U)[] ? U : never;\ntype Numbers = ElementType<number[]>; // number\ntype Strings = ElementType<string[]>; // string\n```\n\n## Tipi Condizionali Predefiniti\n\nIn TypeScript, i Tipi Condizionali Predefiniti sono tipi condizionali integrati forniti dal linguaggio. Sono progettati per eseguire trasformazioni di tipo comuni in base alle caratteristiche di un dato tipo.\n\n`Exclude<UnionType, ExcludedType>`: questo tipo rimuove da Type tutti i tipi assegnabili a ExcludedType.\n\n`Extract<Type, Union>`: questo tipo estrae da Union tutti i tipi assegnabili a Type.\n\n`NonNullable<Type>`: questo tipo rimuove null e undefined da Type.\n\n`ReturnType<Type>`: questo tipo estrae il tipo di ritorno di un Type di funzione.\n\n`Parameters<Type>`: questo tipo estrae i tipi di parametro di un Type di funzione.\n\n`Required<Type>`: Questo tipo rende obbligatorie tutte le proprietà in Type.\n\n`Partial<Type>`: Questo tipo rende facoltative tutte le proprietà in Type.\n\n`Readonly<Type>`: Questo tipo rende di sola lettura tutte le proprietà in Type.\n\n## Tipi di unione di template\n\nI tipi di unione di template possono essere utilizzati per unire e manipolare il testo all'interno del sistema di tipi, ad esempio:\n\n```typescript\ntype Status = 'active' | 'inactive';\ntype Products = 'p1' | 'p2';\ntype ProductId = `id-${Products}-${Status}`; // \"id-p1-active\" | \"id-p1-inactive\" | \"id-p2-active\" | \"id-p2-inactive\"\n```\n\n## Tipo Any\n\nIl tipo `any` è un tipo speciale (supertipo universale) che può essere utilizzato per rappresentare qualsiasi tipo di valore (primitive, oggetti, array, funzioni, errori, simboli). Viene spesso utilizzato in situazioni in cui il tipo di un valore non è noto in fase di compilazione, o quando si lavora con valori provenienti da API o librerie esterne che non dispongono di tipi TypeScript.\n\nUtilizzando il tipo `any`, si indica al compilatore TypeScript che i valori devono essere rappresentati senza alcuna limitazione. Per massimizzare la sicurezza dei tipi nel codice, tieni presente quanto segue:\n\n* Limitare l'utilizzo di `any` a casi specifici in cui il tipo è realmente sconosciuto.\n* Non restituire `any` da una funzione, poiché ciò indebolisce la sicurezza del tipo nel codice che lo utilizza.\n* Invece di `any`, utilizzare `@ts-ignore` se è necessario silenziare il compilatore.\n\n```typescript\nlet value: any;\nvalue = true; // Valido\nvalue = 7; // Valido\n```\n\n## Tipo Unknown\n\nIn TypeScript, il tipo `unknown` rappresenta un valore di tipo sconosciuto. A differenza del tipo `any`, che consente qualsiasi tipo di valore, `unknown` richiede un controllo o un'asserzione di tipo prima di poter essere utilizzato in un modo specifico, quindi non sono consentite operazioni su un `unknown` senza prima aver effettuato un'asserzione o aver limitato il campo a un tipo più specifico.\n\nIl tipo `unknown` è assegnabile solo a qualsiasi tipo e il tipo `unknown` stesso è un'alternativa type-safe ad `any`.\n\n<!-- skip -->\n```typescript\nlet value: unknown;\n\nlet value1: unknown = value; // Valido\nlet value2: any = value; // Valido\nlet value3: boolean = value; // Non valido\nlet value4: number = value; // Non valido\n```\n\n```typescript\nconst add = (a: unknown, b: unknown): number | undefined =>\n    typeof a === 'number' && typeof b === 'number' ? a + b : undefined;\nconsole.log(add(1, 2)); // 3\nconsole.log(add('x', 2)); // non definito\n```\n\n## Tipo Void\n\nIl tipo `void` viene utilizzato per indicare che una funzione non restituisce un valore.\n\n```typescript\nconst sayHello = (): void => {\n    console.log('Hello!');\n};\n```\n\n## Tipo Never\n\nIl tipo `never` rappresenta valori che non si verificano mai. Viene utilizzato per indicare funzioni o espressioni che non restituiscono mai né generano errori.\n\nAd esempio, un ciclo infinito:\n\n```typescript\nconst infiniteLoop = (): never => {\n    while (true) {\n        // fai qualcosa\n    }\n};\n```\n\nGenerazione di un errore:\n\n```typescript\nconst throwError = (message: string): never => {\n    throw new Error(message);\n};\n```\n\nIl tipo `never` è utile per garantire la sicurezza dei tipi e rilevare potenziali errori nel codice. Aiuta TypeScript ad analizzare e dedurre tipi più precisi se utilizzato in combinazione con altri tipi e istruzioni di controllo del flusso, ad esempio:\n\n```typescript\ntype Direction = 'up' | 'down';\nconst move = (direction: Direction): void => {\n    switch (direction) {\n        case 'up':\n            // sposta verso l'alto\n            break;\n        case 'down':\n            // sposta verso il basso\n            break;\n        default:\n            const exhaustiveCheck: never = direction;\n            throw new Error(`Unhandled direction: ${exhaustiveCheck}`);\n    }\n};\n```\n\n## Interfaccia e tipo\n\n### Sintassi comune\n\nIn TypeScript, le interfacce definiscono la struttura degli oggetti, specificando i nomi e i tipi di proprietà o metodi che un oggetto deve avere. La sintassi comune per definire un'interfaccia in TypeScript è la seguente:\n\n<!-- skip -->\n```typescript\ninterface InterfaceName {\n    property1: Type1;\n    // ...\n    method1(arg1: ArgType1, arg2: ArgType2): ReturnType;\n    // ...\n}\n```\n\nAnalogamente per la definizione del tipo:\n\n<!-- skip -->\n```typescript\ntype TypeName = {\n    property1: Type1;\n    // ...\n    method1(arg1: ArgType1, arg2: ArgType2): ReturnType;\n    // ...\n};\n```\n\n`interface InterfaceName` o `type TypeName`: Definisce il nome dell'interfaccia.\n`property1`: `Type1`: Specifica le proprietà dell'interfaccia insieme ai tipi corrispondenti. È possibile definire più proprietà, ciascuna separata da un punto e virgola.\n`method1(arg1: ArgType1, arg2: ArgType2): ReturnType;`: Specifica i metodi dell'interfaccia. I metodi sono definiti con i loro nomi, seguiti da un elenco di parametri tra parentesi e dal tipo di ritorno. È possibile definire più metodi, ciascuno separato da un punto e virgola.\n\nEsempio di interfaccia:\n\n```typescript\ninterface Person {\n    name: string;\n    age: number;\n    greet(): void;\n}\n```\n\nEsempio di tipo:\n\n```typescript\ntype TypeName = {\n    property1: string;\n    method1(arg1: string, arg2: string): string;\n};\n```\n\nIn TypeScript, i tipi vengono utilizzati per definire la forma dei dati e applicare il controllo dei tipi. Esistono diverse sintassi comuni per la definizione dei tipi in TypeScript, a seconda del caso d'uso specifico. Ecco alcuni esempi:\n\n### Tipi di base\n\n```typescript\nlet myNumber: number = 123; // number type\nlet myBoolean: boolean = true; // boolean type\nlet myArray: string[] = ['a', 'b']; // array di stringhe\nlet myTuple: [string, number] = ['a', 123]; // tupla\n```\n\n### Oggetti e interfacce\n\n```typescript\nconst x: { name: string; age: number } = { name: 'Simon', age: 7 };\n```\n\n### Tipi di unione e intersezione\n\n```typescript\ntype MyType = string | number; // Union type\nlet myUnion: MyType = 'hello'; // Can be a string\nmyUnion = 123; // Or a number\n\ntype TypeA = { name: string };\ntype TypeB = { age: number };\ntype CombinedType = TypeA & TypeB; // Intersection type\nlet myCombined: CombinedType = { name: 'John', age: 25 }; // Object with name and age properties\n```\n\n## Primitive di tipo predefinite\n\nTypeScript dispone di diverse primitive di tipo predefinite che possono essere utilizzate per definire variabili, parametri di funzione e tipi restituiti:\n\n* `number`: rappresenta valori numerici, inclusi numeri interi e numeri in virgola mobile.\n* `string`: rappresenta dati testuali.\n* `boolean`: rappresenta valori logici, che possono essere true o false.\n* `null`: rappresenta l'assenza di un valore.\n* `undefined`: rappresenta un valore che non è stato assegnato o non è stato definito.\n* `symbol`: rappresenta un identificatore univoco. I simboli vengono in genere utilizzati come chiavi per le proprietà degli oggetti.\n* `bigint`: rappresenta numeri interi con precisione arbitraria.\n* `any`: rappresenta un tipo dinamico o sconosciuto. Le variabili di tipo any possono contenere valori di qualsiasi tipo e ignorano il controllo del tipo. \\* `void`: rappresenta l'assenza di qualsiasi tipo. È comunemente usato come tipo di ritorno di funzioni che non restituiscono alcun valore.\n* `never`: rappresenta un tipo per valori che non si verificano mai. È tipicamente usato come tipo di ritorno di funzioni che generano un errore o entrano in un ciclo infinito.\n\n## Oggetti JavaScript predefiniti comuni\n\nTypeScript è un superset di JavaScript e include tutti gli oggetti JavaScript predefiniti comunemente usati. Un elenco completo di questi oggetti è disponibile sul sito web di documentazione di Mozilla Developer Network (MDN):\n[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects)\n\nEcco un elenco di alcuni oggetti JavaScript predefiniti comunemente utilizzati:\n\n* Function\n* Object\n* Boolean\n* Error\n* Number\n* BigInt\n* Math\n* Date\n* String\n* RegExp\n* Array\n* Map\n* Set\n* Promise\n* Intl\n\n## Sovraccarichi\n\nGli overload di funzione in TypeScript consentono di definire più firme di funzione per un singolo nome di funzione, consentendo di definire funzioni che possono essere chiamate in più modi. Ecco un esempio:\n\n```typescript\n// Sovraccarichi\nfunction sayHi(name: string): string;\nfunction sayHi(names: string[]): string[];\n\n// Implementazione\nfunction sayHi(name: unknown): unknown {\n    if (typeof name === 'string') {\n        return `Ciao, ${name}!`;\n    } else if (Array.isArray(name)) {\n        return name.map(name => `Ciao, ${name}!`);\n    }\n    throw new Error('Valore non valido');\n}\n\nsayHi('xx'); // Valido\nsayHi(['aa', 'bb']); // Valido\n```\n\nEcco un altro esempio di utilizzo di overload di funzione all'interno di una `class`:\n\n```typescript\nclass Greeter {\n    message: string;\n\n    constructor(message: string) {\n        this.message = message;\n    }\n\n    // Sovraccarichi\n    sayHi(name: string): string;\n    sayHi(name: string[]): ReadonlyArray<string>;\n\n    // Implementazione\n    sayHi(name: unknown): unknown {\n        if (typeof name === 'string') {\n            return `${this.message}, ${name}!`;\n        } else if (Array.isArray(name)) {\n            return name.map(name => `${this.message}, ${name}!`);\n        }\n        throw new Error('value is invalid');\n    }\n}\nconsole.log(new Greeter('Hello').sayHi('Simon'));\n```\n\n## Unione ed estensione\n\nMerging ed estensione si riferiscono a due concetti diversi relativi all'utilizzo di tipi e interfacce.\n\nMerging consente di combinare più dichiarazioni con lo stesso nome in un'unica definizione, ad esempio quando si definisce un'interfaccia con lo stesso nome più volte:\n\n```typescript\ninterface X {\n    a: string;\n}\n\ninterface X {\n    b: number;\n}\n\nconst person: X = {\n    a: 'a',\n    b: 7,\n};\n```\n\nL'estensione si riferisce alla possibilità di estendere o ereditare da tipi o interfacce esistenti per crearne di nuovi. È un meccanismo per aggiungere proprietà o metodi aggiuntivi a un tipo esistente senza modificarne la definizione originale. Esempio:\n\n```typescript\ninterface Animal {\n    name: string;\n    eat(): void;\n}\n\ninterface Bird extends Animal {\n    sing(): void;\n}\n\nconst dog: Bird = {\n    name: 'Bird 1',\n    eat() {\n        console.log('Eating');\n    },\n    sing() {\n        console.log('Singing');\n    },\n};\n```\n\n## Differenze tra tipo e interfaccia\n\nUnione delle dichiarazioni (aumento):\n\nLe interfacce supportano l'unione delle dichiarazioni, il che significa che è possibile definire più interfacce con lo stesso nome e TypeScript le unirà in un'unica interfaccia con le proprietà e i metodi combinati. D'altra parte, i tipi non supportano l'unione delle dichiarazioni. Questo può essere utile quando si desidera aggiungere funzionalità extra o personalizzare i tipi esistenti senza modificare le definizioni originali o correggere tipi mancanti o errati.\n\n```typescript\ninterface A {\n    x: string;\n}\ninterface A {\n    y: string;\n}\nconst j: A = {\n    x: 'xx',\n    y: 'yy',\n};\n```\n\nEstensione di altri tipi/interfacce:\n\nSia i tipi che le interfacce possono estendere altri tipi/interfacce, ma la sintassi è diversa. Con le interfacce, si utilizza la parola chiave `extends` per ereditare proprietà e metodi da altre interfacce. Tuttavia, un'interfaccia non può estendere un tipo complesso come un tipo unione.\n\n```typescript\ninterface A {\n    x: string;\n    y: number;\n}\ninterface B extends A {\n    z: string;\n}\nconst car: B = {\n    x: 'x',\n    y: 123,\n    z: 'z',\n};\n```\n\nPer i tipi, si utilizza l'operatore & per combinare più tipi in un unico tipo (intersezione).\n\n```typescript\ninterface A {\n    x: string;\n    y: number;\n}\n\ntype B = A & {\n    j: string;\n};\n\nconst c: B = {\n    x: 'x',\n    y: 123,\n    j: 'j',\n};\n```\n\nTipi di unione e intersezione:\n\nI tipi sono più flessibili quando si tratta di definire tipi di unione e intersezione. Con la parola chiave `type`, è possibile creare facilmente tipi di unione utilizzando l'operatore `|` e tipi di intersezione utilizzando l'operatore `&`. Sebbene le interfacce possano anche rappresentare tipi di unione indirettamente, non dispongono di supporto integrato per i tipi di intersezione.\n\n```typescript\ntype Department = 'dep-x' | 'dep-y'; // Unione\n\ntype Person = {\n    name: string;\n    age: number;\n};\n\ntype Employee = {\n    id: number;\n    department: Department;\n};\n\ntype EmployeeInfo = Person & Employee; // Intersezione\n```\n\nEsempio con interfacce:\n\n```typescript\ninterface A {\n    x: 'x';\n}\ninterface B {\n    y: 'y';\n}\n\ntype C = A | B; // Unione di interfacce\n```\n\n## Classe\n\n### Sintassi comune della classe\n\nLa parola chiave `class` viene utilizzata in TypeScript per definire una classe. Di seguito è riportato un esempio:\n\n```typescript\nclass Person {\n    private name: string;\n    private age: number;\n    constructor(name: string, age: number) {\n        this.name = name;\n        this.age = age;\n    }\n    public sayHi(): void {\n        console.log(`Ciao, mi chiamo ${this.name} e ho ${this.age} anni.`);\n    }\n}\n```\n\nLa parola chiave `class` viene utilizzata per definire una classe denominata \"Person\".\n\nLa classe ha due proprietà private: name di tipo `string` ed age di tipo `number`.\n\nIl costruttore viene definito utilizzando la parola chiave `constructor`. Accetta name ed age come parametri e li assegna alle proprietà corrispondenti.\n\nLa classe ha un metodo `public` denominato sayHi che registra un messaggio di saluto.\n\nPer creare un'istanza di una classe in TypeScript, è possibile utilizzare la parola chiave `new` seguita dal nome della classe, seguito da parentesi `()`. Ad esempio:\n\n<!-- skip -->\n```typescript\nconst myObject = new Person('John Doe', 25);\nmyObject.sayHi(); // Output: Ciao, mi chiamo John Doe e ho 25 anni.\n```\n\n### Costruttore\n\nI costruttori sono metodi speciali all'interno di una classe che vengono utilizzati per inizializzare le proprietà dell'oggetto quando viene creata un'istanza della classe.\n\n```typescript\nclass Person {\n    public name: string;\n    public age: number;\n\n    constructor(name: string, age: number) {\n        this.name = name;\n        this.age = age;\n    }\n\n    sayHello() {\n        console.log(`Ciao, mi chiamo ${this.name} e ho ${this.age} anni.`);\n    }\n}\n\nconst john = new Person('Simon', 17);\njohn.sayHello();\n```\n\nÈ possibile sovraccaricare un costruttore utilizzando la seguente sintassi:\n\n```typescript\ntype Sex = 'm' | 'f';\n\nclass Person {\n    name: string;\n    age: number;\n    sex: Sex;\n\n    constructor(name: string, age: number, sex?: Sex);\n    constructor(name: string, age: number, sex: Sex) {\n        this.name = name;\n        this.age = age;\n        this.sex = sex ?? 'm';\n    }\n}\n\nconst p1 = new Person('Simon', 17);\nconst p2 = new Person('Alice', 22, 'f');\n```\n\nIn TypeScript, è possibile definire più overload del costruttore, ma è possibile avere una sola implementazione che deve essere compatibile con tutti gli overload; questo si può ottenere utilizzando un parametro opzionale.\n\n```typescript\nclass Person {\n    name: string;\n    age: number;\n\n    constructor();\n    constructor(name: string);\n    constructor(name: string, age: number);\n    constructor(name?: string, age?: number) {\n        this.name = name ?? 'Sconosciuto';\n        this.age = age ?? 0;\n    }\n\n    displayInfo() {\n        console.log(`Nome: ${this.name}, Età: ${this.age}`);\n    }\n}\n\nconst person1 = new Person();\nperson1.displayInfo(); // Nome: unknown, Età: 0\n\nconst person2 = new Person('John');\nperson2.displayInfo(); // Nome: John, Età: 0\n\nconst person3 = new Person('Jane', 25);\nperson3.displayInfo(); // Nome: Jane, Età: 25\n```\n\n### Costruttori privati ​​e protetti\n\nIn TypeScript, i costruttori possono essere contrassegnati come privati ​​o protetti, il che ne limita l'accessibilità e l'utilizzo.\n\nCostruttori privati:\npossono essere chiamati solo all'interno della classe stessa. I costruttori privati ​​vengono spesso utilizzati in scenari in cui si desidera applicare un pattern singleton o limitare la creazione di istanze a un metodo factory all'interno della classe.\n\nCostruttori protetti:\nI costruttori protetti sono utili quando si desidera creare una classe base che non deve essere istanziata direttamente, ma può essere estesa tramite sottoclassi.\n\n```typescript\nclass BaseClass {\n    protected constructor() {}\n}\n\nclass DerivedClass extends BaseClass {\n    private value: number;\n\n    constructor(value: number) {\n        super();\n        this.value = value;\n    }\n}\n\n// Il tentativo di istanziare direttamente la classe base genererà un errore.\n// const baseObj = new BaseClass(); // Errore: il costruttore della classe 'BaseClass' è protetto.\n\n// Crea un'istanza della classe derivata\nconst derivedObj = new DerivedClass(10);\n```\n\n### Modificatori di accesso\n\nI modificatori di accesso `private`, `protected` e `public` vengono utilizzati per controllare la visibilità e l'accessibilità dei membri della classe, come proprietà e metodi, nelle classi TypeScript. Questi modificatori sono essenziali per applicare l'incapsulamento e stabilire limiti per l'accesso e la modifica dello stato interno di una classe.\n\nIl modificatore `private` limita l'accesso al membro della classe solo all'interno della classe contenitore.\n\nIl modificatore `protected` consente l'accesso al membro della classe all'interno della classe contenitore e delle sue classi derivate.\n\nIl modificatore `public` fornisce accesso illimitato al membro della classe, consentendone l'accesso da qualsiasi luogo.\n\n### Get e Set\n\nGetter e setter sono metodi speciali che consentono di definire un comportamento personalizzato di accesso e modifica per le proprietà della classe. Consentono di incapsulare lo stato interno di un oggetto e di fornire logica aggiuntiva durante l'ottenimento o l'impostazione dei valori delle proprietà.\nIn TypeScript, getter e setter sono definiti utilizzando rispettivamente le parole chiave `get` e `set`. Ecco un esempio:\n\n```typescript\nclass MyClass {\n    private _myProperty: string;\n\n    constructor(value: string) {\n        this._myProperty = value;\n    }\n    get myProperty(): string {\n        return this._myProperty;\n    }\n    set myProperty(value: string) {\n        this._myProperty = value;\n    }\n}\n```\n\n### Accessori automatici nelle classi\n\nTypeScript versione 4.9 aggiunge il supporto per auto-accessor, una funzionalità ECMAScript di prossima uscita. Assomigliano alle proprietà di classe, ma sono dichiarate con la parola chiave \"accessor\".\n\n```typescript\nclass Animal {\n    accessor name: string;\n\n    constructor(name: string) {\n        this.name = name;\n    }\n}\n```\n\nGli auto-accessor vengono \"de-sugared\" in accessor privati ​​`get` e `set`, che operano su una proprietà inaccessibile.\n\n<!-- skip -->\n```typescript\nclass Animal {\n    #__name: string;\n\n    get name() {\n        return this.#__name;\n    }\n    set name(value: string) {\n        this.#__name = name;\n    }\n\n    constructor(name: string) {\n        this.name = name;\n    }\n}\n```\n\n### this\n\nIn TypeScript, la parola chiave `this` si riferisce all'istanza corrente di una classe all'interno dei suoi metodi o costruttori. Permette di accedere e modificare le proprietà e i metodi della classe. dall'interno del proprio ambito.\nFornisce un modo per accedere e manipolare lo stato interno di un oggetto all'interno dei propri metodi.\n\n```typescript\nclass Person {\n    private name: string;\n    constructor(name: string) {\n        this.name = name;\n    }\n    public introduce(): void {\n        console.log(`Ciao, mi chiamo ${this.name}.`);\n    }\n}\n\nconst person1 = new Person('Alice');\nperson1.introduce(); // Ciao, mi chiamo Alice.\n```\n\n### Proprietà dei parametri\n\nLe proprietà dei parametri consentono di dichiarare e inizializzare le proprietà della classe direttamente all'interno dei parametri del costruttore, evitando codice boilerplate, ad esempio:\n\n```typescript\nclass Person {\n    constructor(\n        private name: string,\n        public age: number\n    ) {\n        // Le parole chiave \"private\" e \"public\" nel costruttore\n        // dichiarano e inizializzano automaticamente le proprietà della classe corrispondenti.\n    }\n    public introduce(): void {\n        console.log(`Ciao, mi chiamo ${this.name} e ho ${this.age} anni.`);\n    }\n}\nconst person = new Person('Alice', 25);\nperson.introduce();\n```\n\n### Classi astratte\n\nLe classi astratte sono utilizzate in TypeScript principalmente per l'ereditarietà, poiché forniscono un modo per definire proprietà e metodi comuni che possono essere ereditati dalle sottoclassi.\nQuesto è utile quando si desidera definire un comportamento comune e imporre alle sottoclassi di implementare determinati metodi. Forniscono un modo per creare una gerarchia di classi in cui la classe base astratta fornisce un'interfaccia condivisa e funzionalità comuni per le sottoclassi.\n\n```typescript\nabstract class Animal {\n    protected name: string;\n\n    constructor(name: string) {\n        this.name = name;\n    }\n\n    abstract makeSound(): void;\n}\n\nclass Cat extends Animal {\n    makeSound(): void {\n        console.log(`${this.name} miagola.`);\n    }\n}\n\nconst cat = new Cat('Whiskers');\ncat.makeSound(); // Output: Whiskers miagola.\n```\n\n### Con i generici\n\nLe classi con i generici consentono di definire classi riutilizzabili che possono funzionare con tipi diversi.\n\n```typescript\nclass Container<T> {\n    private item: T;\n\n    constructor(item: T) {\n        this.item = item;\n    }\n\n    getItem(): T {\n        return this.item;\n    }\n\n    setItem(item: T): void {\n        this.item = item;\n    }\n}\n\nconst container1 = new Container<number>(42);\nconsole.log(container1.getItem()); // 42\n\nconst container2 = new Container<string>('Hello');\ncontainer2.setItem('World');\nconsole.log(container2.getItem()); // Mondo\n```\n\n### Decoratori\n\nI decoratori forniscono un meccanismo per aggiungere metadati, modificare il comportamento, convalidare o estendere la funzionalità dell'elemento di destinazione. Sono funzioni che vengono eseguite in fase di esecuzione. È possibile applicare più decoratori a una dichiarazione.\n\nI decoratori sono funzionalità sperimentali e gli esempi seguenti sono compatibili solo con TypeScript versione 5 o successive che utilizzano ES6.\n\nPer le versioni di TypeScript precedenti alla 5, dovrebbero essere abilitati utilizzando la proprietà `experimentalDecorators` nel file `tsconfig.json` o utilizzando `--experimentalDecorators` nella riga di comando (ma l'esempio seguente non funzionerà).\n\nAlcuni dei casi d'uso comuni per i decoratori includono:\n\n* Monitoraggio delle modifiche delle proprietà.\n* Monitoraggio delle chiamate ai metodi.\n* Aggiunta di proprietà o metodi aggiuntivi.\n* Validazione in fase di esecuzione.\n* Serializzazione e deserializzazione automatica.\n* Registrazione.\n* Autorizzazione e autenticazione.\n* Protezione dagli errori.\n\nNota: i decoratori per la versione 5 non consentono parametri di decorazione.\n\nTipi di decoratori:\n\n#### Decoratori di classe\n\nI decoratori di classe sono utili per estendere una classe esistente, ad esempio aggiungendo proprietà o metodi o raccogliendo istanze di una classe. Nell'esempio seguente, aggiungiamo un metodo `toString` che converte la classe in una rappresentazione in formato stringa.\n\n```typescript\ntype Constructor<T = {}> = new (...args: any[]) => T;\n\nfunction toString<Class extends Constructor>(\n    Value: Class,\n    context: ClassDecoratorContext<Class>\n) {\n    return class extends Value {\n        constructor(...args: any[]) {\n            super(...args);\n            console.log(JSON.stringify(this));\n            console.log(JSON.stringify(context));\n        }\n    };\n}\n\n@toString\nclass Person {\n    name: string;\n\n    constructor(name: string) {\n        this.name = name;\n    }\n\n    greet() {\n        return 'Ciao,' + this.name;\n    }\n}\nconst person = new Person('Simon');\n/* Log:\n{\"name\":\"Simon\"}\n{\"kind\":\"class\",\"name\":\"Person\"}\n*/\n```\n\n#### Decoratore di proprietà\n\nI decoratori di proprietà sono utili per modificare il comportamento di una proprietà, ad esempio cambiando i valori di inizializzazione. Nel codice seguente, abbiamo uno script che imposta una proprietà in modo che sia sempre in maiuscolo:\n\n```typescript\nfunction upperCase<T>(\n    target: undefined,\n    context: ClassFieldDecoratorContext<T, string>\n) {\n    return function (this: T, value: string) {\n        return value.toUpperCase();\n    };\n}\n\nclass MyClass {\n    @upperCase\n    prop1 = 'hello!';\n}\n\nconsole.log(new MyClass().prop1); // Log: HELLO!\n```\n\n#### Decoratore di metodo\n\nI decoratori di metodo consentono di modificare o migliorare il comportamento dei metodi. Di seguito è riportato un esempio di un semplice logger:\n\n```typescript\nfunction log<This, Args extends any[], Return>(\n    target: (this: This, ...args: Args) => Return,\n    context: ClassMethodDecoratorContext<\n        This,\n        (this: This, ...args: Args) => Return\n    >\n) {\n    const methodName = String(context.name);\n\n    function replacementMethod(this: This, ...args: Args): Return {\n        console.log(`LOG: Accesso al metodo '${methodName}'.`);\n        const result = target.call(this, ...args);\n        console.log(`LOG: Uscita dal metodo '${methodName}'.`);\n        return result;\n    }\n\n    return replacementMethod;\n}\n\nclass MyClass {\n    @log\n    sayHello() {\n        console.log('Ciao!');\n    }\n}\n\nnew MyClass().sayHello();\n```\n\nRegistra:\n\n```shell\nLOG: Accesso al metodo 'sayHello'.\nCiao!\nLOG: Uscita dal metodo 'sayHello'.\n```\n\n#### Decoratori Getter e Setter\n\nI decoratori Getter e Setter consentono di modificare o migliorare il comportamento degli accessor di classe. Sono utili, ad esempio, per convalidare le assegnazioni di proprietà. Ecco un semplice esempio di decoratore getter:\n\n```typescript\nfunction range<This, Return extends number>(min: number, max: number) {\n    return function (\n        target: (this: This) => Return,\n        context: ClassGetterDecoratorContext<This, Return>\n    ) {\n        return function (this: This): Return {\n            const value = target.call(this);\n            if (value < min || value > max) {\n                throw 'Invalid';\n            }\n            Object.defineProperty(this, context.name, {\n                value,\n                enumerable: true,\n            });\n            return value;\n        };\n    };\n}\n\nclass MyClass {\n    private _value = 0;\n\n    constructor(value: number) {\n        this._value = value;\n    }\n    @range(1, 100)\n    get getValue(): number {\n        return this._value;\n    }\n}\n\nconst obj = new MyClass(10);\nconsole.log(obj.getValue); // Valido: 10\n\nconst obj2 = new MyClass(999);\nconsole.log(obj2.getValue); // Throw: Invalid!\n```\n\n#### Metadati del decoratore\n\nI metadati del decoratore semplificano il processo per i decoratori di applicare e utilizzare i metadati in qualsiasi classe. Possono accedere a una nuova proprietà metadati sull'oggetto contesto, che può fungere da chiave sia per le primitive che per gli oggetti.\nLe informazioni sui metadati sono accessibili sulla classe tramite `Symbol.metadata`.\n\nI metadati possono essere utilizzati per vari scopi, come il debug, la serializzazione o l'iniezione di dipendenze con i decoratori.\n\n```typescript\n//@ts-ignore\nSymbol.metadata ??= Symbol('Symbol.metadata'); // Simple polyfill\n\ntype Context =\n    | ClassFieldDecoratorContext\n    | ClassAccessorDecoratorContext\n    | ClassMethodDecoratorContext; // Il contesto contiene la proprietà metadati: DecoratorMetadata\n\nfunction setMetadata(_target: any, context: Context) {\n    // Imposta l'oggetto metadati con un valore primitivo\n    context.metadata[context.name] = true;\n}\n\nclass MyClass {\n    @setMetadata\n    a = 123;\n\n    @setMetadata\n    accessor b = 'b';\n\n    @setMetadata\n    fn() {}\n}\n\nconst metadata = MyClass[Symbol.metadata]; // Ottieni informazioni sui metadati\n\nconsole.log(JSON.stringify(metadata)); // {\"bar\":true,\"baz\":true,\"foo\":true}\n```\n\n### Ereditarietà\n\nL'ereditarietà si riferisce al meccanismo mediante il quale una classe può ereditare proprietà e metodi da un'altra classe, nota come classe base o superclasse. La classe derivata, chiamata anche classe figlia o sottoclasse, può estendere e specializzare le funzionalità della classe base aggiungendo nuove proprietà e metodi o sovrascrivendo quelli esistenti.\n\n```typescript\nclass Animal {\n    name: string;\n\n    constructor(name: string) {\n        this.name = name;\n    }\n\n    speak(): void {\n        console.log(\"L'animale emette un suono\");\n    }\n}\n\nclass Dog extends Animal {\n    breed: string;\n\n    constructor(name: string, breed: string) {\n        super(name);\n        this.breed = breed;\n    }\n\n    speak(): void {\n        console.log('Woof! Woof!');\n    }\n}\n\n// Crea un'istanza della classe base\nconst animal = new Animal('Animale generico');\nanimal.speak(); // L'animale emette un suono\n\n// Crea un'istanza della classe derivata\nconst dog = new Dog('Max', 'Labrador');\ndog.speak(); // Woof! Bau!\"\n```\n\nTypeScript non supporta l'ereditarietà multipla nel senso tradizionale, ma consente invece l'ereditarietà da una singola classe base.\nTypeScript supporta più interfacce. Un'interfaccia può definire un contratto per la struttura di un oggetto e una classe può implementare più interfacce. Questo consente a una classe di ereditare comportamento e struttura da più fonti.\n\n```typescript\ninterface Flyable {\n    fly(): void;\n}\n\ninterface Swimmable {\n    swim(): void;\n}\n\nclass FlyingFish implements Flyable, Swimmable {\n    fly() {\n        console.log('Flying...');\n    }\n\n    swim() {\n        console.log('Swimming...');\n    }\n}\n\nconst flyingFish = new FlyingFish();\nflyingFish.fly();\nflyingFish.swim();\n```\n\nLa parola chiave `class` in TypeScript, simile a JavaScript, è spesso definita \"syntactic sugar\". È stata introdotta in ECMAScript 2015 (ES6) offre una sintassi più familiare per la creazione e l'utilizzo di oggetti in modalità basata sulle classi. Tuttavia, è importante notare che TypeScript, essendo un superset di JavaScript, alla fine si compila in JavaScript, che rimane fondamentalmente basato sui prototipi.\n\n### Statiche\n\nTypeScript ha membri statici. Per accedere ai membri statici di una classe, è possibile utilizzare il nome della classe seguito da un punto, senza dover creare un oggetto.\n\n```typescript\nclass OfficeWorker {\n    static memberCount: number = 0;\n\n    constructor(private name: string) {\n        OfficeWorker.memberCount++;\n    }\n}\n\nconst w1 = new OfficeWorker('James');\nconst w2 = new OfficeWorker('Simon');\nconst total = OfficeWorker.memberCount;\nconsole.log(total); // 2\n```\n\n### Inizializzazione delle proprietà\n\nEsistono diversi modi per Inizializza le proprietà per una classe in TypeScript:\n\nInline:\n\nNell'esempio seguente, questi valori iniziali verranno utilizzati quando verrà creata un'istanza della classe.\n\n```typescript\nclass MyClass {\n    property1: string = 'default value';\n    property2: number = 42;\n}\n```\n\nNel costruttore:\n\n```typescript\nclass MyClass {\n    property1: string;\n    property2: number;\n\n    constructor() {\n        this.property1 = 'default value';\n        this.property2 = 42;\n    }\n}\n```\n\nUtilizzo dei parametri del costruttore:\n\n```typescript\nclass MyClass {\n    constructor(\n        private property1: string = 'default value',\n        public property2: number = 42\n    ) {\n        // Non è necessario assegnare esplicitamente i valori alle proprietà.\n    }\n    log() {\n        console.log(this.property2);\n    }\n}\nconst x = new MyClass();\nx.log();\n```\n\n### Sovraccarico dei metodi\n\nIl sovraccarico dei metodi consente a una classe di avere più metodi con lo stesso nome ma tipi di parametri diversi o un numero diverso di parametri. Questo ci permette di chiamare un metodo in modi diversi in base agli argomenti passati.\n\n```typescript\nclass MyClass {\n    add(a: number, b: number): number; // Firma di sovraccarico 1\n    add(a: string, b: string): string; // Firma di sovraccarico 2\n\n    add(a: number | string, b: number | string): number | string {\n        if (typeof a === 'number' && typeof b === 'number') {\n            return a + b;\n        }\n        if (typeof a === 'string' && typeof b === 'string') {\n            return a.concat(b);\n        }\n        throw new Error('Argomenti non validi');\n    }\n}\n\nconst r = new MyClass();\nconsole.log(r.add(10, 5)); // Log 15\n```\n\n## Generici\n\nI generici consentono di creare componenti e funzioni riutilizzabili che possono funzionare con più tipi. Con i generici, è possibile parametrizzare tipi, funzioni e interfacce, consentendo loro di operare su tipi diversi senza doverli specificare esplicitamente in anticipo.\n\nI generici consentono di rendere il codice più flessibile e riutilizzabile.\n\n### Tipo generico\n\nPer definire un tipo generico, si utilizzano le parentesi angolari (`<>`) per specificare i parametri di tipo, ad esempio:\n\n```typescript\nfunction identity<T>(arg: T): T {\n    return arg;\n}\nconst a = identity('x');\nconst b = identity(123);\n\nconst getLen = <T,>(data: ReadonlyArray<T>) => data.length;\nconst len = getLen([1, 2, 3]);\n```\n\n### Classi generiche\n\nI generici possono essere applicati anche alle classi, in questo modo possono lavorare con più tipi utilizzando parametri di tipo. Questo è utile per creare definizioni di classe riutilizzabili che possono operare su diversi tipi di dati mantenendo la sicurezza dei tipi.\n\n```typescript\nclass Container<T> {\n    private item: T;\n\n    constructor(item: T) {\n        this.item = item;\n    }\n\n    getItem(): T {\n        return this.item;\n    }\n}\n\nconst numberContainer = new Container<number>(123);\nconsole.log(numberContainer.getItem()); // 123\n\nconst stringContainer = new Container<string>('hello');\nconsole.log(stringContainer.getItem()); // ciao\n```\n\n### Vincoli generici\n\nI parametri generici possono essere vincolati utilizzando la parola chiave `extends` seguita da un tipo o un'interfaccia che il parametro di tipo deve soddisfare.\n\nNell'esempio seguente, T deve contenere una `length` appropriata per essere valido:\n\n<!-- skip -->\n```typescript\nconst printLen = <T extends { length: number }>(value: T): void => {\n    console.log(value.length);\n};\n\nprintLen('Ciao'); // 5\nprintLen([1, 2, 3]); // 3\nprintLen({ length: 10 }); // 10\nprintLen(123); // Non valido\n```\n\nUna caratteristica interessante di generic introdotta nella versione 3.4 RC è l'inferenza di tipo di funzione di ordine superiore, che ha introdotto argomenti di tipo generico propagati:\n\n```typescript\ndeclare function pipe<A extends any[], B, C>(\n    ab: (...args: A) => B,\n    bc: (b: B) => C\n): (...args: A) => C;\n\ndeclare function list<T>(a: T): T[];\ndeclare function box<V>(x: V): { value: V };\n\nconst listBox = pipe(list, box); // <T>(a: T) => { value: T[] }\nconst boxList = pipe(box, list); // <V>(x: V) => { value: V }[]\n```\n\nQuesta funzionalità consente una programmazione più semplice, sicura e senza punti, comune nella programmazione funzionale.\n\n### Restringimento contestuale generico\n\nIl restringimento contestuale per i generici è il meccanismo di TypeScript che consente al compilatore di restringere il tipo di un parametro generico in base al contesto in cui viene utilizzato. È utile quando si lavora con tipi generici in istruzioni condizionali:\n\n```typescript\nfunction process<T>(value: T): void {\n    if (typeof value === 'string') {\n        // Il valore viene ristretto al tipo 'string'\n        console.log(value.length);\n    } else if (typeof value === 'number') {\n        // Il valore viene ristretto al tipo 'number'\n        console.log(value.toFixed(2));\n    }\n}\n\nprocess('hello'); // 5\nprocess(3.14159); // 3.14\n```\n\n## Tipi strutturali cancellati\n\nIn TypeScript, gli oggetti non devono necessariamente corrispondere a un tipo specifico ed esatto. Ad esempio, se creiamo un oggetto che soddisfa i requisiti di un'interfaccia, possiamo utilizzare quell'oggetto nei punti in cui l'interfaccia è richiesta, anche se non esiste una connessione esplicita tra i due.\nEsempio:\n\n```typescript\ntype NameProp1 = {\n    prop1: string;\n};\n\nfunction log(x: NameProp1) {\n    console.log(x.prop1);\n}\n\nconst obj = {\n    prop2: 123,\n    prop1: 'Origin',\n};\n\nlog(obj); // Valido\n```\n\n## Namespace\n\nIn TypeScript, gli spazi dei nomi vengono utilizzati per organizzare il codice in contenitori logici, prevenendo collisioni di nomi e fornendo un modo per raggruppare il codice correlato.\nL'utilizzo delle parole chiave `export` consente l'accesso allo spazio dei nomi nei moduli \"esterni\".\n\n```typescript\nexport namespace MyNamespace {\n    export interface MyInterface1 {\n        prop1: boolean;\n    }\n    export interface MyInterface2 {\n        prop2: string;\n    }\n}\n\nconst a: MyNamespace.MyInterface1 = {\n    prop1: true,\n};\n```\n\n## Simboli\n\nI simboli sono un tipo di dati primitivo che rappresenta un valore immutabile la cui unicità globale è garantita per tutta la durata del programma.\n\nI simboli possono essere utilizzati come chiavi per le proprietà degli oggetti e forniscono un modo per creare proprietà non enumerabili.\n\n```typescript\nconst key1: symbol = Symbol('key1');\nconst key2: symbol = Symbol('key2');\n\nconst obj = {\n    [key1]: 'value 1',\n    [key2]: 'value 2',\n};\n\nconsole.log(obj[key1]); // valore 1\nconsole.log(obj[key2]); // valore 2\n```\n\nIn WeakMaps e WeakSet, i simboli sono ora consentiti come chiavi.\n\n## Direttive con tripla barra\n\nLe direttive con tripla barra sono commenti speciali che forniscono istruzioni al compilatore su come elaborare un file. Queste direttive iniziano con tre barre consecutive (`///`) e sono in genere posizionate all'inizio di un file TypeScript e non hanno alcun effetto sul comportamento in fase di esecuzione.\n\nLe direttive con tripla barra vengono utilizzate per fare riferimento a dipendenze esterne, specificare il comportamento di caricamento dei moduli, abilitare/disabilitare determinate funzionalità del compilatore e altro ancora. Alcuni esempi:\n\nRiferimento a un file di dichiarazione:\n\n<!-- skip -->\n```typescript\n/// <reference path=\"path/to/declaration/file.d.ts\" />\n```\n\nIndicare il formato del modulo:\n\n<!-- skip -->\n```typescript\n/// <amd|commonjs|system|umd|es6|es2015|none>\n```\n\nAbilitare le opzioni del compilatore, nell'esempio seguente, in modalità strict:\n\n<!-- skip -->\n```typescript\n/// <strict|noImplicitAny|noUnusedLocals|noUnusedParameters>\n```\n\n## Manipolazione dei tipi\n\n### Creazione di tipi da tipi\n\nÈ possibile creare nuovi tipi componendo, manipolando o trasformando tipi esistenti.\n\nTipi di intersezione (`&`):\n\nConsentono di combinare più tipi in un unico tipo:\n\n```typescript\ntype A = { foo: number };\ntype B = { bar: string };\ntype C = A & B; // Intersezione di A e B\nconst obj: C = { foo: 42, bar: 'hello' };\n```\n\nTipi di unione (`|`):\n\nConsente di definire un tipo che può essere di diversi tipi:\n\n```typescript\ntype Result = string | number;\nconst value1: Result = 'hello';\nconst value2: Result = 42;\n```\n\nTipi mappati:\n\nConsentono di trasformare le proprietà di un tipo esistente per crearne uno nuovo:\n\n```typescript\ntype Mutable<T> = {\n    readonly [P in keyof T]: T[P];\n};\ntype Person = {\n    name: string;\n    age: number;\n};\ntype ImmutablePerson = Mutable<Person>; // Le proprietà diventano di sola lettura\n```\n\nTipi condizionali:\n\nConsentono di creare tipi in base ad alcune condizioni:\n\n```typescript\ntype ExtractParam<T> = T extends (param: infer P) => any ? P : never;\ntype MyFunction = (name: string) => number;\ntype ParamType = ExtractParam<MyFunction>; // string\n```\n\n### Tipi di accesso indicizzati\n\nIn TypeScript è possibile accedere e manipolare i tipi di proprietà all'interno di un altro tipo utilizzando un indice, `Type[Key]`.\n\n```typescript\ntype Person = {\n    name: string;\n    age: number;\n};\n\ntype AgeType = Person['age']; // number\n```\n\n```typescript\ntype MyTuple = [string, number, boolean];\ntype MyType = MyTuple[2]; // boolean\n```\n\n### Tipi di utilità\n\nDiversi tipi di utilità predefiniti possono essere utilizzati per manipolare i tipi; di seguito è riportato un elenco dei più comuni:\n\n#### Awaited\\<T\\>\n\nCostruisce un tipo che esegue ricorsivamente l'unwrapping dei tipi Promise.\n\n```typescript\ntype A = Awaited<Promise<string>>; // string\n```\n\n#### Partial\\<T\\>\n\nCostruisce un tipo con tutte le proprietà di T impostate su optional.\n\n```typescript\ntype Person = {\n    name: string;\n    age: number;\n};\n\ntype A = Partial<Person>; // { name?: string | undefined; age?:number | undefined; }\n```\n\n#### Required\\<T\\>\n\nCostruisce un tipo con tutte le proprietà di T impostate su required.\n\n```typescript\ntype Person = {\n    name?: string;\n    age?: number;\n};\n\ntype A = Required<Person>; // { name: string; age:number; }\n```\n\n#### Readonly\\<T\\>\n\nCostruisce un tipo con tutte le proprietà di T impostate su readonly.\n\n<!-- skip -->\n```typescript\ntype Person = {\n    name: string;\n    age: number;\n};\n\ntype A = Readonly<Person>;\n\nconst a: A = { name: 'Simon', age: 17 };\na.name = 'John'; // Non valido\n```\n\n#### Record\\<K, T\\>\n\nCostruisce un tipo con un insieme di proprietà K di tipo T.\n\n```typescript\ntype Product = {\n    name: string;\n    price: number;\n};\n\nconst products: Record<string, Product> = {\n    apple: { name: 'Apple', price: 0.5 },\n    banana: { name: 'Banana', price: 0.25 },\n};\n\nconsole.log(products.apple); // { name: 'Apple', price: 0.5 }\n```\n\n#### Pick\\<T, K\\>\n\nCostruisce un tipo selezionando le proprietà specificate K da T.\n\n```typescript\ntype Product = {\n    name: string;\n    price: number;\n};\n\ntype Price = Pick<Product, 'price'>; // { price: number; }\n```\n\n#### Omit\\<T, K\\>\n\nCostruisce un tipo omettendo le proprietà specificate K da T.\n\n```typescript\ntype Product = {\n    name: string;\n    price: number;\n};\n\ntype Name = Omit<Product, 'price'>; // { name: string; }\n```\n\n#### Exclude\\<T, U\\>\n\nCostruisce un tipo escludendo tutti i valori di tipo U da T.\n\n```typescript\ntype Union = 'a' | 'b' | 'c';\ntype MyType = Exclude<Union, 'a' | 'c'>; // b\n```\n\n#### Extract\\<T, U\\>\n\nCostruisce un tipo estraendo tutti i valori di tipo U da T.\n\n```typescript\ntype Union = 'a' | 'b' | 'c';\ntype MyType = Extract<Union, 'a' | 'c'>; // a | c\n```\n\n#### NonNullable\\<T\\>\n\nCostruisce un tipo escludendo null e undefined da T.\n\n```typescript\ntype Union = 'a' | null | undefined | 'b';\ntype MyType = NonNullable<Union>; // 'a' | 'b'\n```\n\n#### Parameters\\<T\\>\n\nEstrae i tipi di parametro di una funzione di tipo T.\n\n```typescript\ntype Func = (a: string, b: number) => void;\ntype MyType = Parameters<Func>; // [a: string, b: number]\n```\n\n#### ConstructorParameters\\<T\\>\n\nEstrae i tipi di parametro di una funzione costruttore di tipo T.\n\n```typescript\nclass Person {\n    constructor(\n        public name: string,\n        public age: number\n    ) {}\n}\ntype PersonConstructorParams = ConstructorParameters<typeof Person>; // [name: string, age: number]\nconst params: PersonConstructorParams = ['John', 30];\nconst person = new Person(...params);\nconsole.log(person); // Person { name: 'John', age: 30 }\n```\n\n#### ReturnType\\<T\\>\n\nEstrae il tipo di ritorno di una funzione di tipo T.\n\n```typescript\ntype Func = (name: string) => number;\ntype MyType = ReturnType<Func>; // number\n```\n\n#### InstanceType\\<T\\>\n\nEstrae il tipo di istanza di una classe di tipo T.\n\n```typescript\nclass Person {\n    name: string;\n\n    constructor(name: string) {\n        this.name = name;\n    }\n\n    sayHello() {\n        console.log(`Ciao, mi chiamo ${this.name}!`);\n    }\n}\n\ntype PersonInstance = InstanceType<typeof Person>;\n\nconst person: PersonInstance = new Person('John');\n\nperson.sayHello(); // Ciao, mi chiamo John!\n```\n\n#### ThisParameterType\\<T\\>\n\nEstrae il tipo del parametro 'this' da una funzione di tipo T.\n\n```typescript\ninterface Person {\n    name: string;\n    greet(this: Person): void;\n}\ntype PersonThisType = ThisParameterType<Person['greet']>; // Person\n```\n\n#### OmitThisParameter\\<T\\>\n\nRimuove il parametro 'this' da una funzione di tipo T.\n\n```typescript\nfunction capitalize(this: String) {\n    return this[0].toUpperCase + this.substring(1).toLowerCase();\n}\n\ntype CapitalizeType = OmitThisParameter<typeof capitalize>; // () => string\n```\n\n#### ThisType\\<T\\>\n\nFunge da marcatore per un tipo `this` contestuale.\n\n<!-- skip -->\n```typescript\ntype Logger = {\n    log: (error: string) => void;\n};\n\nlet helperFunctions: { [name: string]: Function } & ThisType<Logger> = {\n    hello: function () {\n        this.log('some error'); // Valido poiché \"log\" è parte di \"this\".\n        this.update(); // Non valido\n    },\n};\n```\n\n#### Uppercase\\<T\\>\n\nRendi maiuscolo il nome del tipo di input T.\n\n```typescript\ntype MyType = Uppercase<'abc'>; // \"ABC\"\n```\n\n#### Lowercase\\<T\\>\n\nRendi minuscolo il nome del tipo di input T.\n\n```typescript\ntype MyType = Lowercase<'ABC'>; // \"abc\"\n```\n\n#### Capitalize\\<T\\>\n\nInserisci in maiuscolo il nome del tipo di input T.\n\n```typescript\ntype MyType = Capitalize<'abc'>; // \"Abc\"\n```\n\n#### Uncapitalize\\<T\\>\n\nInserisci in maiuscolo il nome del tipo di input T.\n\n```typescript\ntype MyType = Uncapitalize<'Abc'>; // \"abc\"\n```\n\n#### NoInfer\\<T\\>\n\nNoInfer è un tipo di utilità progettato per bloccare l'inferenza automatica dei tipi nell'ambito di una funzione generica.\n\nEsempio:\n\n```typescript\n// Inferenza automatica dei tipi nell'ambito di una funzione generica.\nfunction fn<T extends string>(x: T[], y: T) {\n    return x.concat(y);\n}\nconst r = fn(['a', 'b'], 'c'); // Il tipo qui è (\"a\" | \"b\" | \"c\")[]\n```\n\nCon NoInfer:\n\n<!-- skip -->\n```typescript\n// Funzione di esempio che utilizza NoInfer per impedire l'inferenza di tipo\nfunction fn2<T extends string>(x: T[], y: NoInfer<T>) {\n    return x.concat(y);\n}\n\nconst r2 = fn2(['a', 'b'], 'c'); // Errore: l'argomento di tipo '\"c\"' non è assegnabile al parametro di tipo '\"a\" | \"b\"'.\n```\n\n## Altri\n\n### Gestione degli errori e delle eccezioni\n\nTypeScript consente di rilevare e gestire gli errori utilizzando i meccanismi standard di gestione degli errori JavaScript:\n\nBlocchi Try-Catch-Finally:\n\n```typescript\ntry {\n    // Codice che potrebbe generare un errore\n} catch (error) {\n    // Gestisci l'errore\n} finally {\n    // Codice che viene sempre eseguito, finally è facoltativo\n}\n```\n\nÈ anche possibile gestire diversi tipi di errore:\n\n```typescript\ntry {\n    // Codice che potrebbe generare diversi tipi di errore\n} catch (error) {\n    if (error instanceof TypeError) {\n        // Gestisci TypeError\n    } else if (error instanceof RangeError) {\n        // Gestisci RangeError\n    } else {\n        // Gestisci altri errori\n    }\n}\n```\n\nTipi di errore personalizzati:\n\nÈ possibile specificare errori più specifici estendendo la classe `Error`:\n\n```typescript\nclass CustomError extends Error {\n    constructor(message: string) {\n        super(message);\n        this.name = 'CustomError';\n    }\n}\n\nthrow new CustomError('Questo è un errore personalizzato.');\n```\n\n### Classi Mixin\n\nLe classi Mixin consentono di combinare e comporre il comportamento di più classi in un'unica classe. Forniscono un modo per riutilizzare ed estendere le funzionalità senza la necessità di catene di ereditarietà profonde.\n\n```typescript\nabstract class Identificabile {\n    name: string = '';\n\n    logId() {\n        console.log('id:', this.name);\n    }\n}\n\nabstract class Selezionabile {\n    selected: boolean = false;\n\n    select() {\n        this.selected = true;\n        console.log('Select');\n    }\n\n    deselect() {\n        this.selected = false;\n        console.log('Deselect');\n    }\n}\n\nclass MyClass {\n    constructor() {}\n}\n\n// Estendi MyClass per includere il comportamento di Identificabile e Selezionabile\ninterface MyClass extends Identificabile, Selezionabile {}\n\n// Funzione per applicare i mixin a una classe\nfunction applyMixins(source: any, baseCtors: any[]) {\n    baseCtors.forEach(baseCtor => {\n        Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => {\n            const descriptor = Object.getOwnPropertyDescriptor(\n                baseCtor.prototype,\n                name\n            );\n            if (descriptor) {\n                Object.defineProperty(source.prototype, name, descriptor);\n            }\n        });\n    });\n}\n\n// Applica i mixin a MyClass\napplyMixins(MyClass, [Identificabile, Selezionabile]);\n\nlet o = new MyClass();\no.name = 'abc';\no.logId();\no.select();\n```\n\n### Funzionalità del linguaggio asincrono\n\nEssendo TypeScript un superset di JavaScript, integra funzionalità del linguaggio asincrono come:\n\nPromise:\n\nLe promise sono un modo per gestire le operazioni asincrone e i loro risultati utilizzando metodi come `.then()` e `.catch()` per gestire le condizioni di successo e di errore.\n\nPer saperne di più: [https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)\n\nAsync/await:\n\nLe parole chiave Async/await sono un modo per fornire una sintassi più sincrona per lavorare con le promise. La parola chiave `async` viene utilizzata per definire una funzione asincrona, mentre la parola chiave `await` viene utilizzata all'interno di una funzione asincrona per mettere in pausa l'esecuzione finché una Promise non viene risolta o rifiutata.\n\nPer saperne di più:\n[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function)\n[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await)\n\nLe seguenti API sono ben supportate in TypeScript:\n\nAPI Fetch:\n\n[https://developer.mozilla.org/it/docs/Web/API/Fetch_API](https://developer.mozilla.org/it/docs/Web/API/Fetch_API)\n\nWeb Worker:\n[https://developer.mozilla.org/it/docs/Web/API/Web_Workers_API](https://developer.mozilla.org/it/docs/Web/API/Web_Workers_API)\n\nCondiviso Worker:\n[https://developer.mozilla.org/en-US/docs/Web/API/SharedWorker](https://developer.mozilla.org/en-US/docs/Web/API/SharedWorker)\n\nWebSocket:\n[https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API)\n\n### Iteratori e Generatori\n\nSia gli Iteratori che i Generatori sono ben supportati in TypeScript.\n\nGli Iteratori sono oggetti che implementano il protocollo Iterator, fornendo un modo per accedere agli elementi di una collezione o sequenza uno alla volta. Si tratta di una struttura che contiene un puntatore all'elemento successivo nell'iterazione. Hanno un metodo `next()` che restituisce il valore successivo nella sequenza insieme a un valore booleano che indica se la sequenza è `completata`.\n\n```typescript\nclass NumberIterator implements Iterable<number> {\n    private current: number;\n\n    constructor(\n        private start: number,\n        private end: number\n    ) {\n        this.current = start;\n    }\n\n    public next(): IteratorResult<number> {\n        if (this.current <= this.end) {\n            const value = this.current;\n            this.current++;\n            return { value, done: false };\n        } else {\n            return { value: undefined, done: true };\n        }\n    }\n\n    [Symbol.iterator](): Iterator<number> {\n        return this;\n    }\n}\n\nconst iterator = new NumberIterator(1, 3);\n\nfor (const num of iterator) {\n    console.log(num);\n}\n```\n\nI generatori sono funzioni speciali definite utilizzando la sintassi `function*` che semplifica la creazione di iteratori. Utilizzano la parola chiave `yield` per definire la sequenza di valori e mettono automaticamente in pausa e riprendono l'esecuzione quando vengono richiesti valori.\n\nI generatori semplificano la creazione di iteratori e sono particolarmente utili per lavorare con sequenze di grandi dimensioni o infinite.\n\nEsempio:\n\n```typescript\nfunction* numberGenerator(start: number, end: number): Generator<number> {\n    for (let i = start; i <= end; i++) {\n        yield i;\n    }\n}\n\nconst generator = numberGenerator(1, 5);\n\nfor (const num of generator) {\n    console.log(num);\n}\n```\n\nTypeScript supporta anche iteratori e generatori asincroni.\n\nPer saperne di più:\n\n[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Generator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Generator)\n\n[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Iterator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Iterator)\n\n### Riferimento JSDoc di TsDocs\n\nQuando si lavora con una base di codice JavaScript, è possibile aiutare TypeScript a dedurre il tipo corretto utilizzando commenti JSDoc con annotazioni aggiuntive per fornire informazioni sul tipo.\n\nEsempio:\n\n```typescript\n/**\n * Calcola la potenza di un numero dato\n * @constructor\n * @param {number} base – Il valore base dell'espressione\n * @param {number} exponent – ​​Il valore esponente dell'espressione\n */\nfunction power(base: number, exponent: number) {\n    return Math.pow(base, exponent);\n}\npower(10, 2); // function power(base: number, exponent: number): number\n```\n\nLa documentazione completa è disponibile a questo link:\n\n[https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html](https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html)\n\nDalla versione 3.7 è possibile generare definizioni di tipo .d.ts dalla sintassi JavaScript JSDoc.\nUlteriori informazioni sono disponibili qui:\n[https://www.typescriptlang.org/docs/handbook/declaration-files/dts-from-js.html](https://www.typescriptlang.org/docs/handbook/declaration-files/dts-from-js.html)\n\n### @types\n\nI pacchetti nell'organizzazione @types sono convenzioni di denominazione speciali utilizzate per fornire definizioni di tipo per librerie o moduli JavaScript esistenti. Ad esempio, usando:\n\n```shell\nnpm install --save-dev @types/lodash\n```\n\nInstallerà le definizioni di tipo di `lodash` nel tuo progetto corrente.\n\nPer contribuire alle definizioni di tipo del pacchetto @types, invia una pull request a [https://github.com/DefinitelyTyped/DefinitelyTyped](https://github.com/DefinitelyTyped/DefinitelyTyped).\n\n### JSX\n\nJSX (JavaScript XML) è un'estensione della sintassi del linguaggio JavaScript che consente di scrivere codice simile a HTML all'interno dei file JavaScript o TypeScript. Viene comunemente utilizzato in React per definire la struttura HTML.\n\nTypeScript extends le funzionalità di JSX fornendo il controllo dei tipi e l'analisi statica.\n\nPer utilizzare JSX è necessario impostare l'opzione del compilatore `jsx` nel file `tsconfig.json`. Due opzioni di configurazione comuni:\n\n* \"preserve\": emette file .jsx con il JSX invariato. Questa opzione indica a TypeScript di mantenere la sintassi JSX così com'è e di non trasformarla durante il processo di compilazione. È possibile utilizzare questa opzione se si dispone di uno strumento separato, come Babel, che gestisce la trasformazione.\n* \"react\": abilita la trasformazione JSX integrata di TypeScript. Verrà utilizzato React.createElement.\n\nTutte le opzioni sono disponibili qui:\n[https://www.typescriptlang.org/tsconfig#jsx](https://www.typescriptlang.org/tsconfig#jsx)\n\n### Moduli ES6\n\nTypeScript supporta ES6 (ECMAScript 2015) e molte versioni successive. Ciò significa che è possibile utilizzare la sintassi ES6, come funzioni freccia, letterali template, classi, moduli, destrutturazione e altro ancora.\n\nPer abilitare le funzionalità ES6 nel progetto, è possibile specificare la proprietà `target` nel file tsconfig.json.\n\nUn esempio di configurazione:\n\n```json\n{\n  \"compilerOptions\": {\n    \"target\": \"es6\",\n    \"module\": \"es6\",\n    \"moduleResolution\": \"node\",\n    \"sourceMap\": true,\n    \"outDir\": \"dist\"\n  },\n  \"include\": [\"src\"]\n}\n```\n\n### Operatore di elevamento a potenza ES7\n\nL'operatore di elevamento a potenza (`**`) calcola il valore ottenuto elevando il primo operando alla potenza del secondo operando. Funziona in modo simile a `Math.pow()`, ma con la possibilità aggiuntiva di accettare BigInt come operandi.\nTypeScript supporta pienamente questo operatore, utilizzandolo come `target` nel file tsconfig.json `es2016` o versione successiva.\n\n```typescript\nconsole.log(2 ** (2 ** 2)); // 16\n```\n\n### L'istruzione for-await-of\n\nQuesta è una funzionalità JavaScript completamente supportata in TypeScript che consente di iterare su oggetti iterabili asincroni dalla versione target es2018.\n\n```typescript\nasync function* asyncNumbers(): AsyncIterableIterator<number> {\n    yield Promise.resolve(1);\n    yield Promise.resolve(2);\n    yield Promise.resolve(3);\n}\n\n(async () => {\n    for await (const num of asyncNumbers()) {\n        console.log(num);\n    }\n})();\n```\n\n### Nuova meta-proprietà target\n\nIn TypeScript è possibile utilizzare la meta-proprietà `new.target`, che consente di determinare se una funzione o un costruttore è stato invocato utilizzando l'operatore new. Permette inoltre di rilevare se un oggetto è stato creato a seguito di una chiamata al costruttore.\n\n```typescript\nclass Parent {\n    constructor() {\n        console.log(new.target); // Registra la funzione costruttore utilizzata per creare un'istanza\n    }\n}\n\nclass Child extends Parent {\n    constructor() {\n        super();\n    }\n}\n\nconst parentX = new Parent(); // [Function: Parent]\nconst child = new Child(); // [Function: Child]\n```\n\n### Espressioni di importazione dinamica\n\nÈ possibile caricare i moduli in modo condizionale o caricarli in modo differito su richiesta utilizzando la proposta ECMAScript per l'importazione dinamica, supportata in TypeScript.\n\nLa sintassi per le espressioni di importazione dinamica in TypeScript è la seguente:\n\n<!-- skip -->\n```typescript\nasync function renderWidget() {\n    const container = document.getElementById('widget');\n    if (container !== null) {\n        const widget = await import('./widget'); // Importazione dinamica\n        widget.render(container);\n    }\n}\n\nrenderWidget();\n```\n\n### \"tsc –watch\"\n\nQuesto comando avvia un compilatore TypeScript con il parametro `--watch`, con la possibilità di ricompilare automaticamente i file TypeScript ogni volta che vengono modificati.\n\n```shell\ntsc --watch\n```\n\nA partire dalla versione 4.9 di TypeScript, il monitoraggio dei file si basa principalmente sugli eventi del file system, ricorrendo automaticamente al polling se non è possibile stabilire un watcher basato sugli eventi.\n\n### Operatore di asserzione non nullo\n\nL'operatore di asserzione non nullo (Postfix !), noto anche come asserzione di assegnazione definita, è una funzionalità di TypeScript che consente di affermare che una variabile o una proprietà non è nulla o indefinita, anche se l'analisi statica dei tipi di TypeScript suggerisce che potrebbe esserlo. Con questa funzionalità è possibile rimuovere qualsiasi controllo esplicito.\n\n```typescript\ntype Person = {\n    name: string;\n};\n\nconst printName = (person?: Person) => {\n    console.log(`Name is ${person!.name}`);\n};\n```\n\n### Dichiarazioni predefinite\n\nLe dichiarazioni predefinite vengono utilizzate quando a una variabile o a un parametro viene assegnato un valore predefinito. Ciò significa che se non viene fornito alcun valore per quella variabile o parametro, verrà utilizzato il valore predefinito.\n\n```typescript\nfunction greet(name: string = 'Anonymous'): void {\n    console.log(`Ciao, ${name}!`);\n}\ngreet(); // Ciao, Anonymous!\ngreet('John'); // Ciao, John!\n```\n\n### Concatenamento opzionale\n\nL'operatore di concatenamento opzionale `?.` funziona come il normale operatore punto (`.`) per accedere a proprietà o metodi. Tuttavia, gestisce in modo elegante i valori nulli o indefiniti terminando l'espressione e restituendo `undefined`, invece di generare un errore.\n\n```typescript\ntype Person = {\n    name: string;\n    age?: number;\n    address?: {\n        street?: string;\n        city?: string;\n    };\n};\n\nconst person: Person = {\n    name: 'John',\n};\n\nconsole.log(person.address?.city); // indefinito\n```\n\n### Operatore di coalescenza nullo\n\nL'operatore di coalescenza nullo `??` restituisce il valore del lato destro se il lato sinistro è `null` o `undefined`; in caso contrario, restituisce il valore del lato sinistro.\n\n```typescript\nconst foo = null ?? 'foo';\nconsole.log(foo); // foo\n\nconst baz = 1 ?? 'baz';\nconst baz2 = 0 ?? 'baz';\nconsole.log(baz); // 1\nconsole.log(baz2); // 0\n```\n\n### Tipi letterali di template\n\nI tipi letterali modello consentono di manipolare i valori stringa a livello di tipo e di generare nuovi tipi stringa basati su quelli esistenti. Sono utili per creare tipi più espressivi e precisi da operazioni basate su stringhe.\n\n```typescript\ntype Department = 'engineering' | 'hr';\ntype Language = 'english' | 'spanish';\ntype Id = `${Department}-${Language}-id`; // \"engineering-english-id\" | \"engineering-spanish-id\" | \"hr-english-id\" | \"hr-spanish-id\"\n```\n\n### Sovraccarico di funzioni\n\nIl sovraccarico di funzioni consente di definire più firme di funzione per lo stesso nome di funzione, ciascuna con tipi di parametro e tipo di ritorno diversi.\nQuando si chiama una funzione sovraccaricata, TypeScript utilizza gli argomenti forniti per determinare la firma di funzione corretta:\n\n```typescript\nfunction makeGreeting(name: string): string;\nfunction makeGreeting(names: string[]): string[];\n\nfunction makeGreeting(person: unknown): unknown {\n    if (typeof person === 'string') {\n        return `Ciao ${person}!`;\n    } else if (Array.isArray(person)) {\n        return person.map(name => `Ciao, ${name}!`);\n    }\n    throw new Error('Impossibile salutare');\n}\n\nmakeGreeting('Simon');\nmakeGreeting(['Simone', 'John']);\n```\n\n### Tipi ricorsivi\n\nUn tipo ricorsivo è un tipo che può fare riferimento a se stesso. Questo è utile per definire strutture dati che hanno una struttura gerarchica o ricorsiva (annidamento potenzialmente infinito), come liste concatenate, alberi e grafi.\n\n```typescript\ntype ListNode<T> = {\n    data: T;\n    next: ListNode<T> | undefined;\n};\n```\n\n### Tipi condizionali ricorsivi\n\nÈ possibile definire relazioni di tipo complesse utilizzando la logica e la ricorsione in TypeScript.\nAnalizziamole in termini semplici:\n\nTipi condizionali: consente di definire tipi in base a condizioni booleane:\n\n```typescript\ntype CheckNumber<T> = T extends number ? 'Number' : 'Not a number';\ntype A = CheckNumber<123>; // 'Number'\ntype B = CheckNumber<'abc'>; // 'Not a number'\n```\n\nRicorsione: indica una definizione di tipo che fa riferimento a se stessa all'interno della propria definizione:\n\n```typescript\ntype Json = string | number | boolean | null | Json[] | { [key: string]: Json };\n\nconst data: Json = {\n    prop1: true,\n    prop2: 'prop2',\n    prop3: {\n        prop4: [],\n    },\n};\n```\n\nI tipi condizionali ricorsivi combinano sia la logica condizionale che la ricorsione. Ciò significa che una definizione di tipo può dipendere da se stessa tramite la logica condizionale, creando relazioni di tipo complesse e flessibili.\n\n```typescript\ntype Flatten<T> = T extends Array<infer U> ? Flatten<U> : T;\n\ntype NestedArray = [1, [2, [3, 4], 5], 6];\ntype FlattenedArray = Flatten<NestedArray>; // 2 | 3 | 4 | 5 | 1 | 6\n```\n\n### Supporto per i moduli ECMAScript in Node\n\nNode.js ha aggiunto il supporto per i moduli ECMAScript a partire dalla versione 15.3.0, mentre TypeScript supporta i moduli ECMAScript per Node.js dalla versione 4.7. Questo supporto può essere abilitato utilizzando la proprietà `module` con il valore `nodenext` nel file tsconfig.json. Ecco un esempio:\n\n```json\n{\n  \"compilerOptions\": {\n    \"module\": \"nodenext\",\n    \"outDir\": \"./lib\",\n    \"declaration\": true\n  }\n}\n```\n\nNode.js supporta due estensioni di file per i moduli: `.mjs` per i moduli ES e `.cjs` per i moduli CommonJS. Le estensioni di file equivalenti in TypeScript sono `.mts` per i moduli ES e `.cts` per i moduli CommonJS. Quando il compilatore TypeScript trascrive questi file in JavaScript, creerà i file `.mjs` e `.cjs`.\n\nSe desideri utilizzare moduli ES nel tuo progetto, puoi impostare la proprietà `type` su \"module\" nel file package.json. Questo indica a Node.js di trattare il progetto come un progetto di modulo ES.\n\nInoltre, TypeScript supporta anche le dichiarazioni di tipo nei file .d.ts. Questi file di dichiarazione forniscono informazioni sul tipo per librerie o moduli scritti in TypeScript, consentendo ad altri sviluppatori di utilizzarli con le funzionalità di controllo del tipo e di completamento automatico di TypeScript.\n\n### Funzioni di asserzione\n\nIn TypeScript, le funzioni di asserzione sono funzioni che indicano la verifica di una condizione specifica in base al loro valore di ritorno. Nella loro forma più semplice, una funzione di asserzione esamina un predicato fornito e genera un errore quando il predicato restituisce false.\n\n```typescript\nfunction isNumber(value: unknown): asserts value is number {\n    if (typeof value !== 'number') {\n        throw new Error('Not a number');\n    }\n}\n```\n\nOppure può essere dichiarato come espressione di funzione:\n\n```typescript\ntype AssertIsNumber = (value: unknown) => asserts value is number;\nconst isNumber: AssertIsNumber = value => {\n    if (typeof value !== 'number') {\n        throw new Error('Not a number');\n    }\n};\n```\n\nLe funzioni di asserzione condividono alcune somiglianze con le type guard. Le type guard sono state inizialmente introdotte per eseguire controlli in fase di esecuzione e garantire il tipo di un valore all'interno di un ambito specifico.\nNello specifico, una type guard è una funzione che valuta un predicato di tipo e restituisce un valore booleano che indica se il predicato è vero o falso. Questo differisce leggermente dalle funzioni di asserzione, in cui l'intenzione è quella di generare un errore anziché restituire false quando il predicato non è soddisfatto.\n\nEsempio di type guard:\n\n```typescript\nconst isNumber = (value: unknown): value is number => typeof value === 'number';\n```\n\n### Tipi di tupla variadici\n\nI tipi di tupla variadici sono una funzionalità introdotta nella versione 4.0 di TypeScript. Iniziamo a conoscerli ripassando cos'è una tupla:\n\nUn tipo di tupla è un array di lunghezza definita, di cui è noto il tipo di ogni elemento:\n\n```typescript\ntype Student = [string, number];\nconst [name, age]: Student = ['Simone', 20];\n```\n\nIl termine \"variadico\" significa indefinito (accetta un numero variabile di argomenti).\n\nUna tupla variadica è un tipo di tupla che ha tutte le proprietà di prima, ma la forma esatta non è ancora definita:\n\n```typescript\ntype Bar<T extends unknown[]> = [boolean, ...T, number];\n\ntype A = Bar<[boolean]>; // [booleano, booleano, numero]\ntype B = Bar<['a', 'b']>; // [boolean, 'a', 'b', number]\ntype C = Bar<[]>; // [boolean, number]\n```\n\nNel codice precedente possiamo vedere che la forma della tupla è definita dal generico `T` passato.\n\nLe tuple variadiche possono accettare più generici, il che le rende molto flessibili:\n\n```typescript\ntype Bar<T extends unknown[], G extends unknown[]> = [...T, boolean, ...G];\n\ntype A = Bar<[number], [string]>; // [number, boolean, string]\ntype B = Bar<['a', 'b'], [boolean]>; // [\"a\", \"b\", boolean, boolean]\n```\n\nCon le nuove tuple variadiche possiamo usare:\n\n* Gli spread nella sintassi dei tipi di tupla ora possono essere generici, quindi possiamo rappresentare operazioni di ordine superiore su tuple e array anche quando non conosciamo i tipi effettivi su cui stiamo operando.\n* Gli elementi rimanenti possono trovarsi ovunque in una tupla.\n\nEsempio:\n\n```typescript\ntype Items = readonly unknown[];\n\nfunction concat<T extends Items, U extends Items>(\n    arr1: T,\n    arr2: U\n): [...T, ...U] {\n    return [...arr1, ...arr2];\n}\n\nconcat([1, 2, 3], ['4', '5', '6']); // [1, 2, 3, \"4\", \"5\", \"6\"]\n```\n\n### Tipi boxed\n\nI tipi boxed si riferiscono agli oggetti wrapper utilizzati per rappresentare i tipi primitivi come oggetti. Questi oggetti wrapper forniscono funzionalità e metodi aggiuntivi che non sono disponibili direttamente sui valori primitivi.\n\nQuando si accede a un metodo come `charAt` o `normalize` su una primitiva `string`, JavaScript lo racchiude in un oggetto `String`, chiama il metodo e quindi elimina l'oggetto.\n\nDimostrazione:\n\n```typescript\nconst originalNormalize = String.prototype.normalize;\nString.prototype.normalize = function () {\n    console.log(this, typeof this);\n    return originalNormalize.call(this);\n};\nconsole.log('\\u0041'.normalize());\n```\n\nTypeScript rappresenta questa differenziazione fornendo tipi separati per le primitive e i corrispondenti wrapper di oggetti:\n\n* string => String\n* number => Number\n* boolean => Boolean\n* symbol => Symbol\n* bigint => BigInt\n\nI tipi boxed di solito non sono necessari. Evitare di utilizzare tipi boxed e utilizzare invece type per le primitive, ad esempio `string` invece di `String`.\n\n### Covarianza e Controvarianza in TypeScript\n\nCovarianza e Controvarianza vengono utilizzate per descrivere il funzionamento delle relazioni quando si ha a che fare con l'ereditarietà o l'assegnazione di tipi.\n\nCovarianza significa che una relazione di tipo preserva la direzione dell'ereditarietà o dell'assegnazione, quindi se un tipo A è un sottotipo del tipo B, anche un array di tipo A è considerato un sottotipo di un array di tipo B. La cosa importante da notare qui è che la relazione di sottotipo viene mantenuta, il che significa che Covarianza accetta il sottotipo ma non il supertipo.\n\nLa controvarianza significa che una relazione di tipo inverte la direzione dell'ereditarietà o dell'assegnazione, quindi se un tipo A è un sottotipo del tipo B, allora un array di tipo B è considerato un sottotipo di un array di tipo A. La relazione di sottotipo è invertita, il che significa che la controvarianza accetta il supertipo ma non il sottotipo.\n\nNote: La bivarianza significa accettare sia il supertipo che il sottotipo.\n\nEsempio: supponiamo di avere uno spazio per tutti gli animali e uno spazio separato solo per i cani.\n\nIn covarianza, puoi inserire tutti i cani nello spazio degli animali perché i cani sono un tipo di animale. Ma non puoi inserire tutti gli animali nello spazio dei cani perché potrebbero esserci altri animali mescolati.\n\nIn controvarianza, non puoi inserire tutti gli animali nello spazio dei cani perché lo spazio degli animali potrebbe contenere anche altri animali. Tuttavia, puoi inserire tutti i cani nello spazio degli animali perché tutti i cani sono anche animali.\n\n<!-- skip -->\n```typescript\n// Esempio di covarianza\nclass Animal {\n    name: string;\n    constructor(name: string) {\n        this.name = name;\n    }\n}\n\nclass Dog extends Animal {\n    breed: string;\n    constructor(name: string, breed: string) {\n        super(name);\n        this.breed = breed;\n    }\n}\n\nlet animals: Animal[] = [];\nlet dogs: Dog[] = [];\n\n// La covarianza consente di assegnare l'array del sottotipo (Dog) all'array del supertipo (Animal)\nanimals = dogs;\ndogs = animals; // Non valido: il tipo 'Animal[]' non è assegnabile al tipo 'Dog[]'\n\n// Esempio di controvarianza\ntype Feed<in T> = (animal: T) => void;\n\nlet feedAnimal: Feed<Animal> = (animal: Animal) => {\n    console.log(`Nome animale: ${animal.name}`);\n};\n\nlet feedDog: Feed<Dog> = (dog: Dog) => {\n    console.log(`Nome del cane: ${dog.name}, Razza: ${dog.breed}`);\n};\n\n// La controvarianza consente di assegnare la callback del supertipo (Animal) alla callback del sottotipo (Dog)\nfeedDog = feedAnimal;\nfeedAnimal = feedDog; // Non valido: il tipo 'Feed<Dog>' non è assegnabile al tipo 'Feed<Animal>'.\n```\n\nIn TypeScript, le relazioni di tipo per gli array sono covarianti, mentre le relazioni di tipo per i parametri di funzione sono controvarianti. Ciò significa che TypeScript presenta sia covarianza che controvarianza, a seconda del contesto.\n\n#### Annotazioni di varianza opzionali per i parametri di tipo\n\nA partire da TypeScript 4.7.0, possiamo usare le parole chiave `out` e `in` per specificare l'annotazione di varianza.\n\nPer la covarianza, usare la parola chiave `out`:\n\n```typescript\ntype AnimalCallback<out T> = () => T; // T è covariante in questo caso\n```\n\nE per la controvarianza, usare la parola chiave `in`:\n\n```typescript\ntype AnimalCallback<in T> = (value: T) => void; // T è controvariante in questo caso\n```\n\n### Firme di indice con pattern di stringhe modello\n\nLe firme di indice con pattern di stringhe modello ci consentono di definire firme di indice flessibili utilizzando pattern di stringhe modello. Questa funzionalità ci consente di creare oggetti che possono essere indicizzati con pattern specifici di chiavi stringa, offrendo maggiore controllo e specificità durante l'accesso e la manipolazione delle proprietà.\n\nTypeScript dalla versione 4.4 consente firme di indice per simboli e pattern di stringhe modello.\n\n```typescript\nconst uniqueSymbol = Symbol('description');\n\ntype MyKeys = `key-${string}`;\n\ntype MyObject = {\n    [uniqueSymbol]: string;\n    [key: MyKeys]: number;\n};\n\nconst obj: MyObject = {\n    [uniqueSymbol]: 'Chiave simbolo univoca',\n    'key-a': 123,\n    'key-b': 456,\n};\n\nconsole.log(obj[uniqueSymbol]); // Chiave simbolo univoca\nconsole.log(obj['key-a']); // 123\nconsole.log(obj['key-b']); // 456\n```\n\n### Operatore `satisfies`\n\nL'operatore `satisfies` consente di verificare se un dato tipo soddisfa una specifica interfaccia o condizione. In altre parole, garantisce che un tipo abbia tutte le proprietà e i metodi richiesti da una specifica interfaccia. È un modo per garantire che una variabile rientri nella definizione di un tipo.\nEcco un esempio:\n\n<!-- skip -->\n```typescript\ntype Columns = 'name' | 'nickName' | 'attributes';\n\ntype User = Record<Columns, string | string[] | undefined>;\n\n// Annotazione del tipo tramite `User`\nconst user: User = {\n    name: 'Simone',\n    nickName: undefined,\n    attributes: ['dev', 'admin'],\n};\n\n// Nelle righe seguenti, TypeScript non sarà in grado di dedurre correttamente\nuser.attributes?.map(console.log); // La proprietà 'map' non esiste sul tipo 'string | string[]'. La proprietà 'map' non esiste sul tipo 'string'.\nuser.nickName; // string | string[] | undefined\n\n// Asserzione di tipo tramite `as`\nconst user2 = {\n    name: 'Simon',\n    nickName: undefined,\n    attributes: ['dev', 'admin'],\n} as User;\n\n// Anche in questo caso, TypeScript non sarà in grado di dedurre correttamente\nuser2.attributes?.map(console.log); // La proprietà 'map' non esiste sul tipo 'string | string[]'. La proprietà 'map' non esiste sul tipo 'string'.\nuser2.nickName; // string | string[] | undefined\n\n// Utilizzando gli operatori `satisfies` ora possiamo dedurre correttamente i tipi\nconst user3 = {\n    name: 'Simon',\n    nickName: undefined,\n    attributes: ['dev', 'admin'],\n} satisfies User;\n\nuser3.attributes?.map(console.log); // TypeScript deduce correttamente: string[]\nuser3.nickName; // TypeScript deduce correttamente: undefined\n```\n\n### Importazioni ed esportazioni solo per tipo\n\nLe importazioni ed esportazioni solo per tipo consentono di importare o esportare tipi senza importare o esportare i valori o le funzioni associati a tali tipi. Questo può essere utile per ridurre le dimensioni del bundle.\n\nPer utilizzare le importazioni solo per tipo, è possibile utilizzare la parola chiave `import type`.\n\nTypeScript consente l'utilizzo di estensioni di file sia di dichiarazione che di implementazione (.ts, .mts, .cts e .tsx) nelle importazioni solo tipo, indipendentemente dalle impostazioni `allowImportingTsExtensions`.\n\nAd esempio:\n\n<!-- skip -->\n```typescript\nimport type { House } from './house.ts';\n```\n\nSono supportati i seguenti formati:\n\n<!-- skip -->\n```typescript\nimport type T from './mod';\nimport type { A, B } from './mod';\nimport type * as Types from './mod';\nexport type { T };\nexport type { T } from './mod';\n```\n\n### Dichiarazione using e Gestione Risorse Esplicita\n\nUna dichiarazione `using` è un binding immutabile con ambito a blocco, simile a `const`, utilizzato per la gestione delle risorse usa e getta. Quando inizializzato con un valore, il metodo `Symbol.dispose` di quel valore viene registrato e successivamente eseguito all'uscita dall'ambito del blocco che lo racchiude.\n\nQuesto si basa sulla funzionalità di Gestione Risorse di ECMAScript, utile per eseguire attività di pulizia essenziali dopo la creazione di oggetti, come la chiusura di connessioni, l'eliminazione di file e il rilascio di memoria.\n\nNote:\n\n* A causa della sua recente introduzione nella versione 5.2 di TypeScript, la maggior parte dei runtime non dispone di supporto nativo. Sono necessari polyfill per: `Symbol.dispose`, `Symbol.asyncDispose`, `DisposableStack`, `AsyncDisposableStack`, `SuppressedError`. \\* Inoltre, dovrai configurare il tuo file tsconfig.json come segue:\n\n```json\n{\n  \"compilerOptions\": {\n    \"target\": \"es2022\",\n    \"lib\": [\"es2022\", \"esnext.disposable\", \"dom\"]\n  }\n}\n```\n\nEsempio:\n\n<!-- skip -->\n```typescript\n//@ts-ignore\nSymbol.dispose ??= Symbol('Symbol.dispose'); // Simple polyfill\n\nconst doWork = (): Disposable => {\n    return {\n        [Symbol.dispose]: () => {\n            console.log('disposed');\n        },\n    };\n};\n\nconsole.log(1);\n\n{\n    using work = doWork(); // La risorsa è dichiarata\n    console.log(2);\n} // La risorsa viene eliminata (ad esempio, viene valutata `work[Symbol.dispose]()`)\n\nconsole.log(3);\n```\n\nIl codice registrerà:\n\n```shell\n1\n2\ndisposed\n3\n```\n\nUna risorsa idonea per l'eliminazione deve rispettare l'interfaccia `Disposable`:\n\n```typescript\n// lib.esnext.disposable.d.ts\ninterface Disposable {\n    [Symbol.dispose](): void;\n}\n```\n\nLe dichiarazioni `using` registrano le operazioni di eliminazione delle risorse in uno stack, assicurandosi che vengano eliminate nell'ordine inverso rispetto alla dichiarazione:\n\n<!-- skip -->\n```typescript\n{\n    using j = getA(),\n        y = getB();\n    using k = getC();\n} // elimina `C`, poi `B`, poi `A`.\n```\n\nÈ garantito che le risorse vengano eliminate, anche se si verificano codice o eccezioni successive. Questo potrebbe portare alla generazione di un'eccezione durante l'eliminazione, con la possibile soppressione di un'altra. Per conservare le informazioni sugli errori soppressi, è stata introdotta una nuova eccezione nativa, `SuppressedError`.\n\n#### dichiarazione await using\n\nUna dichiarazione `await using` gestisce una risorsa eliminabile in modo asincrono. Il valore deve avere un metodo `Symbol.asyncDispose`, che verrà atteso alla fine del blocco.\n\n<!-- skip -->\n```typescript\nasync function doWorkAsync() {\n    await using work = doWorkAsync(); // La risorsa viene dichiarata\n} // La risorsa viene eliminata (ad esempio, viene valutata `await work[Symbol.asyncDispose]()`)\n```\n\nPer una risorsa eliminabile in modo asincrono, deve aderire all'interfaccia `Disposable` o `AsyncDisposable`:\n\n```typescript\n// lib.esnext.disposable.d.ts\ninterface AsyncDisposable {\n    [Symbol.asyncDispose](): Promise<void>;\n}\n```\n\n<!-- skip -->\n```typescript\n//@ts-ignore\nSymbol.asyncDispose ??= Symbol('Symbol.asyncDispose'); // Simple polyfill\n\nclass DatabaseConnection implements AsyncDisposable {\n    // Un metodo che viene chiamato quando l'oggetto viene eliminato in modo asincrono\n    [Symbol.asyncDispose]() {\n        // Chiude la connessione e restituisce una promessa\n        return this.close();\n    }\n\n    async close() {\n        console.log('Chiusura della connessione...');\n        await new Promise(resolve => setTimeout(resolve, 1000));\n        console.log('Connessione chiusa.');\n    }\n}\n\nasync function doWork() {\n    // Crea una nuova connessione e la elimina in modo asincrono quando esce dall'ambito\n    await using connection = new DatabaseConnection(); // La risorsa viene dichiarata\n    console.log('Sto lavorando...');\n} // La risorsa viene eliminata (ad esempio, viene valutato `await connection[Symbol.asyncDispose]()`)\n\ndoWork();\n```\n\nIl codice registra:\n\n```shell\nSto lavorando...\nChiusura della connessione...\nConnessione chiusa.\n```\n\nLe dichiarazioni `using` e `await using` sono consentite nelle istruzioni: `for`, `for-in`, `for-of`, `for-await-of`, `switch`.\n\n### Attributi di importazione\n\nGli attributi di importazione di TypeScript 5.3 (etichette per le importazioni) indicano al runtime come gestire i moduli (JSON, ecc.). Questo migliora la sicurezza garantendo importazioni chiare e si allinea con la Content Security Policy (CSP) per un caricamento più sicuro delle risorse. TypeScript garantisce che siano validi, ma lascia che sia il runtime a gestirne l'interpretazione per la gestione di moduli specifici.\n\nEsempio:\n\n<!-- skip -->\n```typescript\nimport config from './config.json' with { type: 'json' };\n```\n\ncon importazione dinamica:\n\n<!-- skip -->\n```typescript\nconst config = import('./config.json', { with: { type: 'json' } });\n```\n"
  },
  {
    "path": "README-pt_BR.md",
    "content": "# O Livro Conciso de TypeScript\n\nO Livro Conciso de TypeScript fornece uma visão geral abrangente e sucinta dos recursos do TypeScript. Ele oferece explicações claras que abrangem todos os aspectos encontrados na versão mais recente da linguagem, desde o seu poderoso sistema de tipos até recursos avançados. Seja você um iniciante ou um desenvolvedor experiente, este livro é um recurso inestimável para aprimorar sua compreensão e proficiência em TypeScript.\n\nEste livro é completamente Gratuito e de Código Aberto (Open Source).\n\nAcredito que a educação técnica de alta qualidade deve ser acessível a todos, por isso mantenho este livro gratuito e aberto.\n\nSe o livro te ajudou a resolver um bug, entender um conceito difícil ou avançar em sua carreira, considere apoiar meu trabalho pagando quanto quiser (preço sugerido: 15 USD) ou patrocinando um café. Seu apoio me ajuda a manter o conteúdo atualizado e a expandi-lo com novos exemplos e explicações mais profundas.\n\n[![Buy Me a Coffee](https://img.shields.io/badge/buy_me_a_coffee-FFDD00?style=for-the-badge&logo=buy-me-a-coffee&logoColor=black)](https://www.buymeacoffee.com/simonepoggiali)\n\n[![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.com/donate/?business=QW82ZS956XLFY&no_recurring=0&currency_code=EUR)\n\n## Traduções\n\nEste livro foi traduzido para várias versões de idiomas, incluindo:\n\n[Chinês](https://github.com/gibbok/typescript-book/blob/main/README-zh_CN.md)\n\n[Italiano](https://github.com/gibbok/typescript-book/blob/main/README-it_IT.md)\n\n[Português (Brasil)](https://github.com/gibbok/typescript-book/blob/main/README-pt_BR.md)\n\n[Sueco](https://github.com/gibbok/typescript-book/blob/main/README-sv_SE.md)\n\n## Downloads e site\n\nVocê também pode baixar a versão Epub:\n\n[https://github.com/gibbok/typescript-book/tree/main/downloads](https://github.com/gibbok/typescript-book/tree/main/downloads)\n\nUma versão online está disponível em:\n\n[https://gibbok.github.io/typescript-book](https://gibbok.github.io/typescript-book)\n\n## Sumário\n\n<!-- markdownlint-disable MD004 -->\n- [O Livro Conciso de TypeScript](#o-livro-conciso-de-typescript)\n  - [Traduções](#traduções)\n  - [Downloads e site](#downloads-e-site)\n  - [Sumário](#sumário)\n  - [Introdução](#introdução)\n  - [Sobre o Autor](#sobre-o-autor)\n  - [Introdução ao TypeScript](#introdução-ao-typescript)\n    - [O que é TypeScript?](#o-que-é-typescript)\n    - [Por que TypeScript?](#por-que-typescript)\n    - [TypeScript e JavaScript](#typescript-e-javascript)\n    - [Geração de Código TypeScript](#geração-de-código-typescript)\n    - [JavaScript Moderno Agora (Downleveling)](#javascript-moderno-agora-downleveling)\n  - [Começando com TypeScript](#começando-com-typescript)\n    - [Instalação](#instalação)\n    - [Configuração](#configuração)\n    - [Arquivo de Configuração do TypeScript](#arquivo-de-configuração-do-typescript)\n      - [target](#target)\n      - [lib](#lib)\n      - [strict](#strict)\n      - [module](#module)\n      - [moduleResolution](#moduleresolution)\n      - [esModuleInterop](#esmoduleinterop)\n      - [jsx](#jsx)\n      - [skipLibCheck](#skiplibcheck)\n      - [files](#files)\n      - [include](#include)\n      - [exclude](#exclude)\n    - [importHelpers](#importhelpers)\n    - [Conselhos para Migração para TypeScript](#conselhos-para-migração-para-typescript)\n  - [Explorando o Sistema de Tipos](#explorando-o-sistema-de-tipos)\n    - [O Serviço de Linguagem do TypeScript](#o-serviço-de-linguagem-do-typescript)\n    - [Tipagem Estrutural](#tipagem-estrutural)\n    - [Regras Fundamentais de Comparação do TypeScript](#regras-fundamentais-de-comparação-do-typescript)\n    - [Tipos como Conjuntos](#tipos-como-conjuntos)\n    - [Atribuir um tipo: Declarações de Tipo e Asserções de Tipo](#atribuir-um-tipo-declarações-de-tipo-e-asserções-de-tipo)\n      - [Declaração de Tipo](#declaração-de-tipo)\n      - [Asserção de Tipo](#asserção-de-tipo)\n      - [Declarações de Ambiente (Ambient Declarations)](#declarações-de-ambiente-ambient-declarations)\n    - [Verificação de Propriedades e Verificação de Excesso de Propriedades](#verificação-de-propriedades-e-verificação-de-excesso-de-propriedades)\n    - [Tipos Fracos (Weak Types)](#tipos-fracos-weak-types)\n    - [Verificação Estrita de Objeto Literal (Freshness)](#verificação-estrita-de-objeto-literal-freshness)\n    - [Inferência de Tipo](#inferência-de-tipo)\n    - [Inferências Mais Avançadas](#inferências-mais-avançadas)\n    - [Alargamento de Tipo (Type Widening)](#alargamento-de-tipo-type-widening)\n    - [Const](#const)\n      - [Modificador Const em Parâmetros de Tipo](#modificador-const-em-parâmetros-de-tipo)\n      - [Asserção Const](#asserção-const-const-assertion)\n    - [Anotação de Tipo Explícita](#anotação-de-tipo-explícita)\n    - [Estreitamento de Tipo (Type Narrowing)](#estreitamento-de-tipo-type-narrowing)\n      - [Condições](#condições)\n      - [Lançando ou retornando](#lançando-ou-retornando)\n      - [União Discriminada](#união-discriminada)\n      - [Proteções de Tipo Definidas pelo Usuário (User-Defined Type Guards)](#proteções-de-tipo-definidas-pelo-usuário-user-defined-type-guards)\n  - [Tipos Primitivos](#tipos-primitivos)\n    - [string](#string)\n    - [boolean](#boolean)\n    - [number](#number)\n    - [bigInt](#bigint)\n    - [Symbol](#symbol)\n    - [null e undefined](#null-e-undefined)\n    - [Array](#array)\n    - [any](#any)\n  - [Anotações de Tipo](#anotações-de-tipo)\n  - [Propriedades Opcionais](#propriedades-opcionais)\n  - [Propriedades Somente Leitura (Readonly)](#propriedades-somente-leitura-readonly)\n  - [Assinaturas de Índice (Index Signatures)](#assinaturas-de-índice-index-signatures)\n  - [Estendendo Tipos](#estendendo-tipos)\n  - [Tipos Literais](#tipos-literais)\n  - [Inferência Literal](#inferência-literal)\n  - [strictNullChecks](#strictnullchecks)\n  - [Enums](#enums)\n    - [Enums numéricos](#enums-numéricos)\n    - [Enums de string](#enums-de-string)\n    - [Enums constantes](#enums-constantes)\n    - [Mapeamento reverso](#mapeamento-reverso)\n    - [Enums de ambiente](#enums-de-ambiente)\n    - [Membros computados e constantes](#membros-computados-e-constantes)\n  - [Estreitamento (Narrowing)](#estreitamento-narrowing)\n    - [typeof type guards](#typeof-type-guards)\n    - [Estreitamento de veracidade (Truthiness narrowing)](#estreitamento-de-veracidade-truthiness-narrowing)\n    - [Estreitamento de igualdade (Equality narrowing)](#estreitamento-de-igualdade-equality-narrowing)\n    - [Estreitamento com operador In](#estreitamento-com-operador-in)\n    - [Estreitamento com instanceof](#estreitamento-com-instanceof)\n  - [Atribuições](#atribuições)\n  - [Análise de Fluxo de Controle](#análise-de-fluxo-de-controle)\n  - [Predicados de Tipo](#predicados-de-tipo)\n  - [Uniões Discriminadas](#uniões-discriminadas)\n  - [O tipo never](#o-tipo-never)\n  - [Verificação de exaustividade](#verificação-de-exaustividade)\n  - [Tipos de Objeto](#tipos-de-objeto)\n  - [Tipo Tupla (Anônimo)](#tipo-tupla-anônimo)\n  - [Tipo Tupla Nomeado (Rotulado)](#tipo-tupla-nomeado-rotulado)\n  - [Tupla de Comprimento Fixo](#tupla-de-comprimento-fixo)\n  - [Tipo União](#tipo-união)\n  - [Tipos de Interseção](#tipos-de-interseção)\n  - [Indexação de Tipo](#indexação-de-tipo)\n  - [Tipo a partir de Valor](#tipo-a-partir-de-valor)\n  - [Tipo a partir de Retorno de Função](#tipo-a-partir-de-retorno-de-função)\n  - [Tipo a partir de Módulo](#tipo-a-partir-de-módulo)\n  - [Tipos Mapeados](#tipos-mapeados)\n  - [Modificadores de Tipos Mapeados](#modificadores-de-tipos-mapeados)\n  - [Tipos Condicionais](#tipos-condicionais-conditional-types)\n  - [Tipos Condicionais Distributivos](#tipos-condicionais-distributivos)\n  - [Inferência de tipo infer em Tipos Condicionais](#infer-inferência-de-tipo-em-tipos-condicionais)\n  - [Tipos Condicionais Predefinidos](#tipos-condicionais-predefinidos)\n  - [Tipos de União de Template](#tipos-de-união-de-template-template-union-types)\n  - [Tipo Any](#tipo-any)\n  - [Tipo Unknown](#tipo-unknown)\n  - [Tipo Void](#tipo-void)\n  - [Tipo Never](#tipo-never)\n  - [Interface e Tipo](#interface-e-type)\n    - [Sintaxe Comum](#sintaxe-comum)\n    - [Tipos Básicos](#tipos-básicos)\n    - [Objetos e Interfaces](#objetos-e-interfaces)\n    - [Tipos União e Interseção](#tipos-união-e-interseção)\n  - [Primitivos de Tipo Integrados](#tipos-primitivos-integrados)\n  - [Objetos JS Integrados Comuns](#objetos-js-integrados-comuns)\n  - [Sobrecargas](#sobrecargas-overloads)\n  - [Mesclagem e Extensão](#mesclagem-e-extensão)\n  - [Diferenças entre Type e Interface](#diferenças-entre-type-e-interface)\n    - [Classe](#classes)\n    - [Sintaxe Comum de Classe](#sintaxe-comum-de-classes)\n    - [Construtor](#construtor)\n    - [Construtores Privados e Protegidos](#construtores-privados-e-protegidos)\n    - [Modificadores de Acesso](#modificadores-de-acesso)\n    - [Get e Set](#get-e-set)\n    - [Auto-Accessors em Classes](#auto-acessores-em-classes)\n    - [this](#this)\n    - [Propriedades de Parâmetro](#propriedades-de-parâmetro)\n    - [Classes Abstratas](#classes-abstratas)\n    - [Com Genéricos](#com-genéricos)\n    - [Decoradores](#decoradores-decorators)\n      - [Decoradores de Classe](#decoradores-de-classe-class-decorators)\n      - [Decorador de Propriedade](#decorador- de-propriedade-property-decorator)\n      - [Decorador de Método](#decorador-de-método-method-decorator)\n      - [Decoradores de Getter e Setter](#decoradores-de-getter-e-setter)\n      - [Metadados de Decorador](#metadados-de-decorador-decorator-metadata)\n    - [Herança](#herança)\n    - [Estáticos](#estáticos-statics)\n    - [Inicialização de propriedade](#inicialização-de-propriedade)\n    - [Sobrecarga de método](#sobrecarga-de-método)\n  - [Genéricos](#genéricos-generics)\n    - [Tipo Genérico](#tipo-genérico)\n    - [Classes Genéricas](#classes-genéricas)\n    - [Restrições Genéricas](#restrições-genéricas-generic-constraints)\n    - [Estreitamento contextual genérico](#estreitamento-contextual-genérico)\n  - [Tipos Estruturais Apagados (Erased Structural Types)](#tipos-estruturais-apagados)\n  - [Namespacing](#namespacing)\n  - [Símbolos](#símbolos-symbols)\n  - [Diretivas de Barra Tripla](#diretivas-triple-slash)\n  - [Manipulação de Tipos](#manipulação-de-tipos)\n    - [Criando Tipos a partir de Tipos](#criando-tipos-a-partir-de-tipos)\n    - [Tipos de Acesso Indexado](#tipos-de-acesso-indexado-indexed-access-types)\n    - [Tipos Utilitários](#tipos-utilitários-utility-types)\n      - [Awaited\\<T\\>](#awaitedt)\n      - [Partial\\<T\\>](#partialt)\n      - [Required\\<T\\>](#requiredt)\n      - [Readonly\\<T\\>](#readonlyt)\n      - [Record\\<K, T\\>](#recordk-t)\n      - [Pick\\<T, K\\>](#pickt-k)\n      - [Omit\\<T, K\\>](#omitt-k)\n      - [Exclude\\<T, U\\>](#excludet-u)\n      - [Extract\\<T, U\\>](#extractt-u)\n      - [NonNullable\\<T\\>](#nonnullablet)\n      - [Parameters\\<T\\>](#parameterst)\n      - [ConstructorParameters\\<T\\>](#constructorparameterst)\n      - [ReturnType\\<T\\>](#returntypet)\n      - [InstanceType\\<T\\>](#instancetypet)\n      - [ThisParameterType\\<T\\>](#thisparametertypet)\n      - [OmitThisParameter\\<T\\>](#omitthisparametert)\n      - [ThisType\\<T\\>](#thistypet)\n      - [Uppercase\\<T\\>](#uppercaset)\n      - [Lowercase\\<T\\>](#lowercaset)\n      - [Capitalize\\<T\\>](#capitalizet)\n      - [Uncapitalize\\<T\\>](#uncapitalizet)\n      - [NoInfer\\<T\\>](#noinfert)\n  - [Outros](#outros)\n    - [Tratamento de Erros e Exceções](#erros-e-tratamento-de-exceções)\n    - [Classes Mixin](#classes-mixin-mixin-classes)\n    - [Recursos de Linguagem Assíncronos](#recursos-de-linguagem-assíncronos)\n    - [Iteradores e Geradores](#iteradores-e-geradores)\n    - [Referência JSDoc TsDocs](#referência-jsdoc-tsdocs)\n    - [@types](#types)\n    - [JSX](#jsx-1)\n    - [Módulos ES6](#módulos-es6)\n    - [Operador de Exponenciação ES7](#operador-de-exponenciação-es7)\n    - [A instrução for-await-of](#a-instrução-for-await-of)\n    - [Nova meta-propriedade target](#nova-meta-propriedade-target)\n    - [Expressões de Importação Dinâmica](#expressões-de-importação-dinâmica)\n    - [\"tsc –watch\"](#tsc-watch)\n    - [Operador de Asserção Não-nula](#operador-de-asserção-não-nulo-non-null-assertion-operator)\n    - [Declarações padronizadas](#declarações-com-valor-padrão-defaulted-declarations)\n    - [Encadeamento Opcional (Optional Chaining)](#encadeamento-opcional-optional-chaining)\n    - [Operador de coalescência nula](#operador-de-coalescência-nula-nullish-coalescing-operator)\n    - [Tipos de Literais de Template](#tipos-de-literal-de-template-template-literal-types)\n    - [Sobrecarga de função](#sobrecarga-de-função-function-overloading)\n    - [Tipos Recursivos](#tipos-recursivos)\n    - [Tipos Condicionais Recursivos](#tipos-condicionais-recursivos)\n    - [Suporte a Módulo ECMAScript no Node](#suporte-a-módulos-ecmascript-no-node)\n    - [Funções de Asserção](#funções-de-asserção-assertion-functions)\n    - [Tipos de Tupla Variádicos](#tipos-de-tupla-variádicos-variadic-tuple-types)\n    - [Tipos Boxed](#tipos-boxed-boxed-types)\n    - [Covariância e Contravariância no TypeScript](#covariância-e-contravariância-no-typescript)\n      - [Anotações de Variância Opcionais para Parâmetros de Tipo](#anotações-de-variância-opcionais-para-parâmetros-de-tipo)\n    - [Assinaturas de Índice de Padrão de String de Template](#assinaturas-de-índice-de-padrão-de-string-de-template-template-string-pattern-index-signatures)\n    - [O Operador satisfies](#o-operador-satisfies)\n    - [Importações e Exportações Apenas de Tipo](#importações-e-exportações-apenas-de-tipo-type-only-imports-and-export)\n    - [Declaração using e Gerenciamento Explícito de Recursos](#declaração-using-e-gerenciamento-explícito-de-recursos-explicit-resource-management)\n      - [Declaração await using](#declaração-await-using)\n    - [Atributos de Importação](#atributos-de-importação-import-attributes)\n<!-- markdownlint-enable MD004 -->\n\n## Introdução\n\nBem-vindo ao Livro Conciso de TypeScript! Este guia o equipa com conhecimentos essenciais e habilidades práticas para o desenvolvimento eficaz em TypeScript. Descubra conceitos e técnicas fundamentais para escrever código limpo e robusto. Seja você um iniciante ou um desenvolvedor experiente, este livro serve tanto como um guia abrangente quanto como uma referência prática para aproveitar o poder do TypeScript em seus projetos.\n\nEste livro cobre o TypeScript 5.2.\n\n## Sobre o Autor\n\nSimone Poggiali é um Engenheiro Staff experiente com paixão por escrever código de nível profissional desde os anos 90. Ao longo de sua carreira internacional, contribuiu para inúmeros projetos para uma ampla gama de clientes, de startups a grandes organizações. Empresas notáveis como HelloFresh, Siemens, O2, Leroy Merlin e Snowplow se beneficiaram de sua expertise e dedicação.\n\nVocê pode encontrar Simone Poggiali nas seguintes plataformas:\n\n* LinkedIn: [https://www.linkedin.com/in/simone-poggiali](https://www.linkedin.com/in/simone-poggiali)\n* GitHub: [https://github.com/gibbok](https://github.com/gibbok)\n* X.com: [https://x.com/gibbok_coding](https://x.com/gibbok_coding)\n* Email: gibbok.coding📧gmail.com\n\nLista completa de colaboradores: [https://github.com/gibbok/typescript-book/graphs/contributors](https://github.com/gibbok/typescript-book/graphs/contributors)\n\n## Introdução ao TypeScript\n\n### O que é TypeScript?\n\nTypeScript é uma linguagem de programação fortemente tipada que se baseia no JavaScript. Foi originalmente projetada por Anders Hejlsberg em 2012 e é atualmente desenvolvida e mantida pela Microsoft como um projeto de código aberto.\n\nO TypeScript compila para JavaScript e pode ser executado em qualquer ambiente de execução JavaScript (por exemplo, um navegador ou Node.js em um servidor).\n\nEle suporta múltiplos paradigmas de programação, como funcional, genérica, imperativa e orientada a objetos, e é uma linguagem compilada (transpilada) que é convertida em JavaScript antes da execução.\n\n### Por que TypeScript?\n\nTypeScript é uma linguagem fortemente tipada que ajuda a prevenir erros comuns de programação e a evitar certos tipos de erros em tempo de execução antes que o programa seja executado.\n\nUma linguagem fortemente tipada permite ao desenvolvedor especificar várias restrições e comportamentos do programa nas definições de tipos de dados, facilitando a capacidade de verificar a correção do software e prevenir defeitos. Isso é especialmente valioso em aplicações de larga escala.\n\nAlguns dos benefícios do TypeScript:\n\n* Tipagem estática, opcionalmente fortemente tipada\n* Inferência de Tipo\n* Acesso a recursos ES6 e ES7\n* Compatibilidade multiplataforma e entre navegadores\n* Suporte de ferramentas com IntelliSense\n\n### TypeScript e JavaScript\n\nArquivos TypeScript são escritos em arquivos `.ts` ou `.tsx`, enquanto arquivos JavaScript são escritos em `.js` ou `.jsx`.\n\nArquivos com a extensão `.tsx` ou `.jsx` podem conter a Extensão de Sintaxe JavaScript JSX, que é usada no React para desenvolvimento de UI.\n\nO TypeScript é um superconjunto tipado de JavaScript (ECMAScript 2015) em termos de sintaxe. Todo código JavaScript é código TypeScript válido, mas o inverso nem sempre é verdadeiro.\n\nPor exemplo, considere uma função em um arquivo JavaScript com a extensão `.js`, como a seguinte:\n\n<!-- skip -->\n```typescript\nconst sum = (a, b) => a + b;\n```\n\nA função pode ser convertida e usada no TypeScript alterando a extensão do arquivo para `.ts`. No entanto, se a mesma função for anotada com tipos TypeScript, ela não poderá ser executada em nenhum ambiente de execução JavaScript sem compilação. O seguinte código TypeScript produzirá um erro de sintaxe se não for compilado:\n\n<!-- skip -->\n```typescript\nconst sum = (a: number, b: number): number => a + b;\n```\n\nO TypeScript foi projetado para detectar possíveis exceções que podem ocorrer em tempo de execução durante o tempo de compilação, fazendo com que o desenvolvedor defina a intenção com anotações de tipo. Além disso, o TypeScript também pode capturar problemas se nenhuma anotação de tipo for fornecida. Por exemplo, o seguinte trecho de código não especifica nenhum tipo TypeScript:\n\n<!-- skip -->\n```typescript\nconst items = [{ x: 1 }, { x: 2 }];\nconst result = items.filter(item => item.y);\n```\n\nNeste caso, o TypeScript detecta um erro e informa:\n\n```text\nProperty 'y' does not exist on type '{ x: number; }'.\n```\n\nO sistema de tipos do TypeScript é amplamente influenciado pelo comportamento de tempo de execução do JavaScript. Por exemplo, o operador de adição (+), que no JavaScript pode realizar a concatenação de strings ou a adição numérica, é modelado da mesma forma no TypeScript:\n\n```typescript\nconst result = '1' + 1; // Result is of type string\n```\n\nA equipe por trás do TypeScript tomou a decisão deliberada de sinalizar o uso incomum do JavaScript como erros. Por exemplo, considere o seguinte código JavaScript válido:\n\n<!-- skip -->\n```typescript\nconst result = 1 + true; // In JavaScript, the result is equal 2\n```\n\nNo entanto, o TypeScript lança um erro:\n\n```text\nOperator '+' cannot be applied to types 'number' and 'boolean'.\n```\n\nEste erro ocorre porque o TypeScript impõe estritamente a compatibilidade de tipos e, neste caso, identifica uma operação inválida entre um número e um booleano.\n\n### Geração de Código TypeScript\n\nO compilador TypeScript tem duas responsabilidades principais: verificar se há erros de tipo e compilar para JavaScript. Esses dois processos são independentes um do outro. Os tipos não afetam a execução do código em um ambiente de execução JavaScript, pois são completamente apagados durante a compilação. O TypeScript ainda pode gerar JavaScript mesmo na presença de erros de tipo.\nAqui está um exemplo de código TypeScript com um erro de tipo:\n\n<!-- skip -->\n```typescript\nconst add = (a: number, b: number): number => a + b;\nconst result = add('x', 'y'); // Argument of type 'string' is not assignable to parameter of type 'number'.\n```\n\nNo entanto, ele ainda pode produzir uma saída JavaScript executável:\n\n<!-- skip -->\n```typescript\n'use strict';\nconst add = (a, b) => a + b;\nconst result = add('x', 'y'); // xy\n```\n\nNão é possível verificar tipos TypeScript em tempo de execução. Por exemplo:\n\n<!-- skip -->\n```typescript\ninterface Animal {\n    name: string;\n}\ninterface Dog extends Animal {\n    bark: () => void;\n}\ninterface Cat extends Animal {\n    meow: () => void;\n}\nconst makeNoise = (animal: Animal) => {\n    if (animal instanceof Dog) {\n        // 'Dog' only refers to a type, but is being used as a value here.\n        // ...\n    }\n};\n```\n\nComo os tipos são apagados após a compilação, não há como executar este código em JavaScript. Para reconhecer tipos em tempo de execução, precisamos usar outro mecanismo. O TypeScript fornece várias opções, sendo uma comum a \"união tagueada\" (tagged union). Por exemplo:\n\n```typescript\ninterface Dog {\n    kind: 'dog'; // Tagged union\n    bark: () => void;\n}\ninterface Cat {\n    kind: 'cat'; // Tagged union\n    meow: () => void;\n}\ntype Animal = Dog | Cat;\n\nconst makeNoise = (animal: Animal) => {\n    if (animal.kind === 'dog') {\n        animal.bark();\n    } else {\n        animal.meow();\n    }\n};\n\nconst dog: Dog = {\n    kind: 'dog',\n    bark: () => console.log('bark'),\n};\nmakeNoise(dog);\n```\n\nA propriedade \"kind\" é um valor que pode ser usado em tempo de execução para distinguir entre objetos em JavaScript.\n\nTambém é possível que um valor em tempo de execução tenha um tipo diferente daquele declarado na declaração de tipo. Por exemplo, se o desenvolvedor interpretou mal um tipo de API e o anotou incorretamente.\n\nO TypeScript é um superconjunto do JavaScript, portanto a palavra-chave \"class\" pode ser usada como um tipo e valor em tempo de execução.\n\n```typescript\nclass Animal {\n    constructor(public name: string) {}\n}\nclass Dog extends Animal {\n    constructor(\n        public name: string,\n        public bark: () => void\n    ) {\n        super(name);\n    }\n}\nclass Cat extends Animal {\n    constructor(\n        public name: string,\n        public meow: () => void\n    ) {\n        super(name);\n    }\n}\ntype Mammal = Dog | Cat;\n\nconst makeNoise = (mammal: Mammal) => {\n    if (mammal instanceof Dog) {\n        mammal.bark();\n    } else {\n        mammal.meow();\n    }\n};\n\nconst dog = new Dog('Fido', () => console.log('bark'));\nmakeNoise(dog);\n```\n\nNo JavaScript, uma \"classe\" tem uma propriedade \"prototype\", e o operador \"instanceof\" pode ser usado para testar se a propriedade prototype de um construtor aparece em qualquer lugar na cadeia de protótipos de um objeto.\n\nO TypeScript não tem efeito no desempenho em tempo de execução, pois todos os tipos serão apagados. No entanto, o TypeScript introduz alguma sobrecarga no tempo de compilação.\n\n### JavaScript Moderno Agora (Downleveling)\n\nO TypeScript pode compilar código para qualquer versão lançada do JavaScript desde o ECMAScript 3 (1999). Isso significa que o TypeScript pode transpilar o código dos recursos JavaScript mais recentes para versões mais antigas, um processo conhecido como *Downleveling*. Isso permite o uso do JavaScript moderno, mantendo a compatibilidade máxima com ambientes de execução mais antigos.\n\nÉ importante notar que durante a transpilação para uma versão mais antiga do JavaScript, o TypeScript pode gerar código que pode incorrer em uma sobrecarga de desempenho em comparação com as implementações nativas.\n\nAqui estão alguns dos recursos modernos do JavaScript que podem ser usados no TypeScript:\n\n* Módulos ECMAScript em vez de callbacks \"define\" no estilo AMD ou instruções \"require\" do CommonJS.\n* Classes em vez de protótipos.\n* Declaração de variáveis usando \"let\" ou \"const\" em vez de \"var\".\n* Loop \"for-of\" ou \".forEach\" em vez do loop \"for\" tradicional.\n* Funções de seta (Arrow functions) em vez de expressões de função.\n* Atribuição via desestruturação (Destructuring assignment).\n* Nomes de propriedade/método abreviados e nomes de propriedade computados.\n* Parâmetros de função padrão.\n\nAo aproveitar esses recursos modernos do JavaScript, os desenvolvedores podem escrever códigos mais expressivos e concisos no TypeScript.\n\n## Começando com TypeScript\n\n### Instalação\n\nO Visual Studio Code oferece excelente suporte para a linguagem TypeScript, mas não inclui o compilador TypeScript. Para instalar o compilador TypeScript, você pode usar um gerenciador de pacotes como npm ou yarn:\n\n```shell\nnpm install typescript --save-dev\n```\n\nou\n\n```shell\nyarn add typescript --dev\n```\n\nCertifique-se de realizar o commit do arquivo de bloqueio (lockfile) gerado para garantir que cada membro da equipe use a mesma versão do TypeScript.\n\nPara executar o compilador TypeScript, você pode usar os seguintes comandos:\n\n```shell\nnpx tsc\n```\n\nou\n\n```shell\nyarn tsc\n```\n\nRecomenda-se instalar o TypeScript por projeto em vez de globalmente, pois fornece um processo de construção mais previsível. No entanto, para ocasiões pontuais, você pode usar o seguinte comando:\n\n```shell\nnpx tsc\n```\n\nou instalá-lo globalmente:\n\n```shell\nnpm install -g typescript\n```\n\nSe você estiver usando o Microsoft Visual Studio, pode obter o TypeScript como um pacote no NuGet para seus projetos MSBuild. No Console do Gerenciador de Pacotes NuGet, execute o seguinte comando:\n\n```shell\nInstall-Package Microsoft.TypeScript.MSBuild\n```\n\nDurante a instalação do TypeScript, dois executáveis são instalados: \"tsc\" como o compilador TypeScript e \"tsserver\" como o servidor autônomo do TypeScript. O servidor autônomo contém o compilador e os serviços de linguagem que podem ser utilizados por editores e IDEs para fornecer completamento inteligente de código.\n\nAlém disso, existem vários transpiladores compatíveis com TypeScript disponíveis, como Babel (via um plugin) ou swc. Esses transpiladores podem ser usados para converter código TypeScript em outras linguagens ou versões de destino.\n\n### Configuração\n\nO TypeScript pode ser configurado usando as opções da CLI do tsc ou utilizando um arquivo de configuração dedicado chamado tsconfig.json localizado na raiz do projeto.\n\nPara gerar um arquivo tsconfig.json pré-preenchido com as configurações recomendadas, você pode usar o seguinte comando:\n\n```shell\ntsc --init\n```\n\nAo executar o comando `tsc` localmente, o TypeScript compilará o código usando a configuração especificada no arquivo tsconfig.json mais próximo.\n\nAqui estão alguns exemplos de comandos da CLI que rodam com as configurações padrão:\n\n```shell\ntsc main.ts // Compila um arquivo específico (main.ts) para JavaScript\ntsc src/*.ts // Compila todos os arquivos .ts na pasta 'src' para JavaScript\ntsc app.ts util.ts --outfile index.js // Compila dois arquivos TypeScript (app.ts e util.ts) em um único arquivo JavaScript (index.js)\n```\n\n### Arquivo de Configuração do TypeScript\n\nUm arquivo tsconfig.json é usado para configurar o Compilador TypeScript (tsc). Geralmente, ele é adicionado à raiz do projeto, junto com o arquivo `package.json`.\n\nNotas:\n\n* tsconfig.json aceita comentários, mesmo estando no formato json.\n* É aconselhável usar este arquivo de configuração em vez das opções de linha de comando.\n\nNo link a seguir você encontra a documentação completa e seu esquema:\n\n[https://www.typescriptlang.org/tsconfig](https://www.typescriptlang.org/tsconfig)\n\n[https://www.typescriptlang.org/tsconfig/](https://www.typescriptlang.org/tsconfig/)\n\nA seguir, apresentamos uma lista das configurações comuns e úteis:\n\n#### target\n\nA propriedade \"target\" é usada para especificar qual versão do JavaScript ECMAScript seu TypeScript deve emitir/compilar. Para navegadores modernos, o ES6 é uma boa opção; para navegadores mais antigos, o ES5 é recomendado.\n\n#### lib\n\nA propriedade \"lib\" é usada para especificar quais arquivos de biblioteca incluir no tempo de compilação. O TypeScript inclui automaticamente APIs para recursos especificados na propriedade \"target\", mas é possível omitir ou escolher bibliotecas específicas para necessidades particulares. Por exemplo, se você estiver trabalhando em um projeto de servidor, pode excluir a biblioteca \"DOM\", que é útil apenas em um ambiente de navegador.\n\n#### strict\n\nA propriedade \"strict\" habilita garantias mais fortes e aumenta a segurança de tipos. É aconselhável incluir sempre esta propriedade no arquivo tsconfig.json do seu projeto. Habilitar a propriedade \"strict\" permite que o TypeScript possa:\n\n* Emitir código usando \"use strict\" para cada arquivo de origem.\n* Considerar \"null\" e \"undefined\" no processo de verificação de tipos.\n* Desabilitar o uso do tipo \"any\" quando não houver anotações de tipo.\n* Levantar um erro sobre o uso da expressão \"this\", que de outra forma implicaria o tipo \"any\".\n\n#### module\n\nA propriedade \"module\" define o sistema de módulo suportado para o programa compilado. Durante o tempo de execução, um carregador de módulo é usado para localizar e executar dependências com base no sistema de módulo especificado.\n\nOs carregadores de módulos mais comuns usados no JavaScript são o CommonJS do Node.js para aplicações do lado do servidor e o RequireJS para módulos AMD em aplicações web baseadas em navegador. O TypeScript pode emitir código para vários sistemas de módulos, incluindo UMD, System, ESNext, ES2015/ES6 e ES2020.\n\nNota: O sistema de módulos deve ser escolhido com base no ambiente de destino e no mecanismo de carregamento de módulos disponível nesse ambiente.\n\n#### moduleResolution\n\nA propriedade \"moduleResolution\" especifica a estratégia de resolução de módulos. Use \"node\" para código TypeScript moderno; a estratégia \"classic\" é usada apenas para versões antigas do TypeScript (antes da 1.6).\n\n#### esModuleInterop\n\nA propriedade \"esModuleInterop\" permite a importação padrão de módulos CommonJS que não exportaram usando a propriedade \"default\"; esta propriedade fornece um shim para garantir a compatibilidade no JavaScript emitido. Após habilitar esta opção, podemos usar `import MyLibrary from \"my-library\"` em vez de `import * as MyLibrary from \"my-library\"`.\n\n#### jsx\n\nA propriedade \"jsx\" aplica-se apenas a arquivos .tsx usados no ReactJS e controla como as construções JSX são compiladas em JavaScript. Uma opção comum é \"preserve\", que compilará para um arquivo .jsx mantendo o JSX inalterado para que ele possa ser passado para diferentes ferramentas, como o Babel, para transformações posteriores.\n\n#### skipLibCheck\n\nA propriedade \"skipLibCheck\" evitará que o TypeScript verifique os tipos de todos os pacotes de terceiros importados. Esta propriedade reduzirá o tempo de compilação de um projeto. O TypeScript ainda verificará seu código em relação às definições de tipo fornecidas por esses pacotes.\n\n#### files\n\nA propriedade \"files\" indica ao compilador uma lista de arquivos que devem sempre ser incluídos no programa.\n\n#### include\n\n<!-- markdownlint-disable MD049 -->\nA propriedade \"include\" indica ao compilador uma lista de arquivos que gostaríamos de incluir. Esta propriedade permite padrões semelhantes a glob, como \"\\**\" para qualquer subdiretório, \"*\" para qualquer nome de arquivo e \"?\" para caracteres opcionais.\n<!-- markdownlint-enable MD049 -->\n\n#### exclude\n\nA propriedade \"exclude\" indica ao compilador uma lista de arquivos que não devem ser incluídos na compilação. Isso pode incluir arquivos como \"node_modules\" ou arquivos de teste.\nNota: tsconfig.json permite comentários.\n\n### importHelpers\n\nO TypeScript usa código auxiliar ao gerar código para certos recursos avançados ou de JavaScript com \"down-leveled\". Por padrão, esses auxiliares são duplicados nos arquivos que os utilizam. A opção `importHelpers` importa esses auxiliares do módulo `tslib`, tornando a saída do JavaScript mais eficiente.\n\n### Conselhos para Migração para TypeScript\n\nPara projetos grandes, recomenda-se adotar uma transição gradual onde o código TypeScript e JavaScript coexistirão inicialmente. Apenas projetos pequenos podem ser migrados para TypeScript de uma só vez.\n\nO primeiro passo desta transição é introduzir o TypeScript no processo da cadeia de construção. Isso pode ser feito usando a opção de compilador \"allowJs\", que permite que arquivos .ts e .tsx coexistam com arquivos JavaScript existentes. Como o TypeScript voltará para um tipo \"any\" para uma variável quando não puder inferir o tipo dos arquivos JavaScript, recomenda-se desabilitar \"noImplicitAny\" em suas opções de compilador no início da migração.\n\nO segundo passo é garantir que seus testes JavaScript funcionem junto com os arquivos TypeScript, para que você possa executar testes conforme converte cada módulo. Se estiver usando Jest, considere usar o `ts-jest`, que permite testar projetos TypeScript com Jest.\n\nO terceiro passo é incluir declarações de tipo para bibliotecas de terceiros em seu projeto. Essas declarações podem ser encontradas empacotadas ou no DefinitelyTyped. Você pode pesquisar por elas usando [https://www.typescriptlang.org/dt/search](https://www.typescriptlang.org/dt/search) e instalá-las usando:\n\n```shell\nnpm install --save-dev @types/package-name\n```\n\nou\n\n```shell\nyarn add --dev @types/package-name\n```\n\nO quarto passo é migrar módulo por módulo com uma abordagem de baixo para cima, seguindo seu Gráfico de Dependências começando pelas folhas. A ideia é começar convertendo Módulos que não dependem de outros Módulos. Para visualizar os gráficos de dependência, você pode usar a ferramenta \"madge\".\n\nBons módulos candidatos para essas conversões iniciais são funções utilitárias e código relacionado a APIs ou especificações externas. É possível gerar automaticamente definições de tipo TypeScript a partir de contratos Swagger, GraphQL ou esquemas JSON para serem incluídos em seu projeto.\n\nQuando não houver especificações ou esquemas oficiais disponíveis, você pode gerar tipos a partir de dados brutos, como JSON retornado por um servidor. No entanto, recomenda-se gerar tipos a partir de especificações em vez de dados para evitar perder casos extremos.\n\nDurante a migração, evite a refatoração de código e concentre-se apenas em adicionar tipos aos seus módulos.\n\nO quinto passo é habilitar o \"noImplicitAny\", que forçará que todos os tipos sejam conhecidos e definidos, proporcionando uma melhor experiência de TypeScript para seu projeto.\n\nDurante a migração, você pode usar a diretiva `@ts-check`, que habilita a verificação de tipos do TypeScript em um arquivo JavaScript. Esta diretiva fornece uma versão flexível de verificação de tipos e pode ser usada inicialmente para identificar problemas em arquivos JavaScript. Quando o `@ts-check` é incluído em um arquivo, o TypeScript tentará deduzir definições usando comentários no estilo JSDoc. No entanto, considere usar anotações JSDoc apenas em um estágio muito inicial da migração.\n\nConsidere manter o valor padrão de `noEmitOnError` no seu tsconfig.json como false. Isso permitirá gerar o código-fonte JavaScript mesmo se erros forem relatados.\n\n## Explorando o Sistema de Tipos\n\n### O Serviço de Linguagem do TypeScript\n\nO Serviço de Linguagem do TypeScript, também conhecido como tsserver, oferece vários recursos, como relatório de erros, diagnósticos, compilar ao salvar, renomeação, ir para definição, listas de preenchimento, ajuda de assinatura e muito mais. É usado principalmente por ambientes de desenvolvimento integrados (IDEs) para fornecer suporte ao IntelliSense. Ele se integra perfeitamente ao Visual Studio Code e é utilizado por ferramentas como Conquer of Completion (Coc).\n\nOs desenvolvedores podem aproveitar uma API dedicada e criar seus próprios plugins de serviço de linguagem personalizados para aprimorar a experiência de edição do TypeScript. Isso pode ser particularmente útil para implementar recursos especiais de linting ou habilitar o preenchimento automático para uma linguagem de modelagem personalizada.\n\n<!-- markdownlint-disable MD044 -->\nUm exemplo de plugin personalizado do mundo real é o \"typescript-styled-plugin\", que fornece relatórios de erros de sintaxe e suporte IntelliSense para propriedades CSS em componentes estilizados (styled components).\n<!-- markdownlint-enable MD044 -->\n\nPara mais informações e guias de início rápido, você pode consultar o Wiki oficial do TypeScript no GitHub: [https://github.com/microsoft/TypeScript/wiki/](https://github.com/microsoft/TypeScript/wiki/)\n\n### Tipagem Estrutural\n\nO TypeScript é baseado em um sistema de tipos estrutural. Isso significa que a compatibilidade e a equivalência de tipos são determinadas pela estrutura ou definição real do tipo, em vez de seu nome ou local de declaração, como em sistemas de tipos nominativos como C# ou C++.\n\nO sistema de tipos estrutural do TypeScript foi projetado com base em como o sistema de tipagem dinâmica \"duck typing\" do JavaScript funciona durante o tempo de execução.\n\nO exemplo a seguir é um código TypeScript válido. Como você pode observar, \"X\" e \"Y\" têm o mesmo membro \"a\", embora tenham nomes de declaração diferentes. Os tipos são determinados por suas estruturas e, neste caso, como as estruturas são as mesmas, eles são compatíveis e válidos.\n\n```typescript\ntype X = {\n    a: string;\n};\ntype Y = {\n    a: string;\n};\nconst x: X = { a: 'a' };\nconst y: Y = x; // Válido\n```\n\n### Regras Fundamentais de Comparação do TypeScript\n\nO processo de comparação do TypeScript é recursivo e executado em tipos aninhados em qualquer nível.\n\nUm tipo \"X\" é compatível com \"Y\" se \"Y\" tiver pelo menos os mesmos membros que \"X\".\n\n```typescript\ntype X = {\n    a: string;\n};\nconst y = { a: 'A', b: 'B' }; // Válido, pois tem pelo menos os mesmos membros que X\nconst r: X = y;\n```\n\nOs parâmetros da função são comparados por tipos, não por seus nomes:\n\n```typescript\ntype X = (a: number) => void;\ntype Y = (a: number) => void;\nlet x: X = (j: number) => undefined;\nlet y: Y = (k: number) => undefined;\ny = x; // Válido\nx = y; // Válido\n```\n\nOs tipos de retorno da função devem ser os mesmos:\n\n<!-- skip -->\n```typescript\ntype X = (a: number) => undefined;\ntype Y = (a: number) => number;\nlet x: X = (a: number) => undefined;\nlet y: Y = (a: number) => 1;\ny = x; // Inválido\nx = y; // Inválido\n```\n\nO tipo de retorno de uma função de origem deve ser um subtipo do tipo de retorno de uma função de destino:\n\n<!-- skip -->\n```typescript\nlet x = () => ({ a: 'A' });\nlet y = () => ({ a: 'A', b: 'B' });\nx = y; // Válido\ny = x; // Inválido, o membro b está faltando\n```\n\nDescartar parâmetros de função é permitido, pois é uma prática comum no JavaScript, por exemplo, usando \"Array.prototype.map()\":\n\n```typescript\n[1, 2, 3].map((element, _index, _array) => element + 'x');\n```\n\nPortanto, as seguintes declarações de tipo são completamente válidas:\n\n```typescript\ntype X = (a: number) => undefined;\ntype Y = (a: number, b: number) => undefined;\nlet x: X = (a: number) => undefined;\nlet y: Y = (a: number) => undefined; // Falta o parâmetro b\ny = x; // Válido\n```\n\nQuaisquer parâmetros opcionais adicionais do tipo de origem são válidos:\n\n```typescript\ntype X = (a: number, b?: number, c?: number) => undefined;\ntype Y = (a: number) => undefined;\nlet x: X = a => undefined;\nlet y: Y = a => undefined;\ny = x; // Válido\nx = y; // Válido\n```\n\nQuaisquer parâmetros opcionais do tipo de destino sem parâmetros correspondentes no tipo de origem são válidos e não constituem um erro:\n\n```typescript\ntype X = (a: number) => undefined;\ntype Y = (a: number, b?: number) => undefined;\nlet x: X = a => undefined;\nlet y: Y = a => undefined;\ny = x; // Válido\nx = y; // Válido\n```\n\nO parâmetro rest é tratado como uma série infinita de parâmetros opcionais:\n\n```typescript\ntype X = (a: number, ...rest: number[]) => undefined;\nlet x: X = a => undefined; // Válido\n```\n\nFunções com sobrecargas são válidas se a assinatura da sobrecarga for compatível com sua assinatura de implementação:\n\n<!-- skip -->\n```typescript\nfunction x(a: string): void;\nfunction x(a: string, b: number): void;\nfunction x(a: string, b?: number): void {\n    console.log(a, b);\n}\nx('a'); // Válido\nx('a', 1); // Válido\n\nfunction y(a: string): void; // Inválido, não compatível com a assinatura de implementação\nfunction y(a: string, b: number): void;\nfunction y(a: string, b: number): void {\n    console.log(a, b);\n}\ny('a');\ny('a', 1);\n```\n\nA comparação de parâmetros de função é bem-sucedida se os parâmetros de origem e de destino forem atribuíveis a supertipos ou subtipos (bivariância).\n\n```typescript\n// Supertipo\nclass X {\n    a: string;\n    constructor(value: string) {\n        this.a = value;\n    }\n}\n// Subtipo\nclass Y extends X {}\n// Subtipo\nclass Z extends X {}\n\ntype GetA = (x: X) => string;\nconst getA: GetA = x => x.a;\n\n// A bivariância aceita supertipos\nconsole.log(getA(new X('x'))); // Válido\nconsole.log(getA(new Y('Y'))); // Válido\nconsole.log(getA(new Z('z'))); // Válido\n```\n\nEnums são comparáveis e válidos com números e vice-versa, mas comparar valores de Enum de diferentes tipos de Enum é inválido.\n\n<!-- skip -->\n```typescript\nenum X {\n    A,\n    B,\n}\nenum Y {\n    A,\n    B,\n    C,\n}\nconst xa: number = X.A; // Válido\nconst ya: Y = 0; // Válido\nX.A === Y.A; // Inválido\n```\n\nInstâncias de uma classe estão sujeitas a uma verificação de compatibilidade para seus membros privados e protegidos:\n\n<!-- skip -->\n```typescript\nclass X {\n    public a: string;\n    constructor(value: string) {\n        this.a = value;\n    }\n}\n\nclass Y {\n    private a: string;\n    constructor(value: string) {\n        this.a = value;\n    }\n}\n\nlet x: X = new Y('y'); // Inválido\n```\n\nA verificação de comparação não leva em consideração as diferentes hierarquias de herança, por exemplo:\n\n```typescript\nclass X {\n    public a: string;\n    constructor(value: string) {\n        this.a = value;\n    }\n}\nclass Y extends X {\n    public a: string;\n    constructor(value: string) {\n        super(value);\n        this.a = value;\n    }\n}\nclass Z {\n    public a: string;\n    constructor(value: string) {\n        this.a = value;\n    }\n}\nlet x: X = new X('x');\nlet y: Y = new Y('y');\nlet z: Z = new Z('z');\nx === y; // Válido\nx === z; // Válido mesmo que z seja de uma hierarquia de herança diferente\n```\n\nGenéricos são comparados usando suas estruturas baseadas no tipo resultante após a aplicação do parâmetro genérico; apenas o resultado final é comparado como um tipo não genérico.\n\n<!-- skip -->\n```typescript\ninterface X<T> {\n    a: T;\n}\nlet x: X<number> = { a: 1 };\nlet y: X<string> = { a: 'a' };\nx === y; // Inválido, pois o argumento de tipo é usado na estrutura final\n```\n\n```typescript\ninterface X<T> {}\nconst x: X<number> = 1;\nconst y: X<string> = 'a';\nx === y; // Válido, pois o argumento de tipo não é usado na estrutura final\n```\n\nQuando os genéricos não têm seu argumento de tipo especificado, todos os argumentos não especificados são tratados como tipos com \"any\":\n\n```typescript\ntype X = <T>(x: T) => T;\ntype Y = <K>(y: K) => K;\nlet x: X = x => x;\nlet y: Y = y => y;\nx = y; // Válido\n```\n\nLembre-se:\n\n<!-- skip -->\n```typescript\nlet a: number = 1;\nlet b: number = 2;\na = b; // Válido, tudo é atribuível a si mesmo\n\nlet c: any;\nc = 1; // Válido, todos os tipos são atribuíveis a any\n\nlet d: unknown;\nd = 1; // Válido, todos os tipos são atribuíveis a unknown\n\nlet e: unknown;\nlet e1: unknown = e; // Válido, unknown só é atribuível a si mesmo e a any\nlet e2: any = e; // Válido\nlet e3: number = e; // Inválido\n\nlet f: never;\nf = 1; // Inválido, nada é atribuível a never\n\nlet g: void;\nlet g1: any;\ng = 1; // Inválido, void não é atribuível a nada, exceto any, nem nada é atribuível a ele\ng = g1; // Válido\n```\n\nObserve que quando \"strictNullChecks\" está habilitado, \"null\" e \"undefined\" são tratados de forma semelhante a \"void\"; caso contrário, são semelhantes a \"never\".\n\n### Tipos como Conjuntos\n\nNo TypeScript, um tipo é um conjunto de valores possíveis. Este conjunto também é conhecido como o domínio do tipo. Cada valor de um tipo pode ser visto como um elemento em um conjunto. Um tipo estabelece as restrições que cada elemento no conjunto deve satisfazer para ser considerado um membro desse conjunto.\nA principal tarefa do TypeScript é verificar se um conjunto é um subconjunto de outro.\n\nO TypeScript suporta vários tipos de conjuntos:\n\n| Termo do conjunto      | TypeScript                      | Notas                                                                                                                                  |\n| ---------------------- | ------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |\n| Conjunto vazio         | never                           | \"never\" não contém nada além de si mesmo                                                                                               |\n| Conjunto de elemento único | undefined / null / tipo literal |                                                                                                                                        |\n| Conjunto finito        | boolean / união                 |                                                                                                                                        |\n| Conjunto infinito      | string / number / objeto        |                                                                                                                                        |\n| Conjunto universal     | any / unknown                   | Cada elemento é um membro de \"any\" e cada conjunto é um subconjunto dele / \"unknown\" é uma contraparte segura em termos de tipo do \"any\" |\n\nAqui estão alguns exemplos:\n\n| TypeScript              | Termo do conjunto          | Exemplo                                                                               |\n| ----------------------- | -------------------------- | ------------------------------------------------------------------------------------- |\n| never                   | ∅ (conjunto vazio)         | const x: never = 'x'; // Erro: O tipo 'string' não pode ser atribuído ao tipo 'never' |\n|                         |                            |\n| Tipo literal            | Conjunto de elemento único | type X = 'X';                                                                         |\n|                         |                            | type Y = 7;                                                                           |\n|                         |                            |\n| Valor atribuível a T    | Valor ∈ T (membro de)      | type XY = 'X' \\| 'Y';                                                                 |\n|                         |                            | const x: XY = 'X';                                                                    |\n|                         |                            |\n| T1 atribuível a T2      | T1 ⊆ T2 (subconjunto de)   | type XY = 'X' \\| 'Y';                                                                 |\n|                         |                            | const x: XY = 'X';                                                                    |\n|                         |                            | const j: XY = 'J'; // O tipo '\"J\"' não pode ser atribuído ao tipo 'XY'.               |\n|                         |                            |                                                                                       |\n| T1 extends T2           | T1 ⊆ T2 (subconjunto de)   | type X = 'X' extends string ? true : false;                                           |\n|                         |                            |\n| T1 \\| T2                | T1 ∪ T2 (união)            | type XY = 'X' \\| 'Y';                                                                 |\n|                         |                            | type JK = 1 \\| 2;                                                                     |\n|                         |                            |\n| T1 & T2                 | T1 ∩ T2 (interseção)       | type X = \\{ a: string \\}                                                                |\n|                         |                            | type Y = \\{ b: string \\}                                                                |\n|                         |                            | type XY = X & Y                                                                       |\n|                         |                            | const x: XY = \\{ a: 'a', b: 'b' \\}                                                      |\n|                         |                            |\n| unknown                 | Conjunto universal         | const x: unknown = 1                                                                  |\n\nUma união, (T1 | T2), cria um conjunto mais amplo (ambos):\n\n```typescript\ntype X = {\n    a: string;\n};\ntype Y = {\n    b: string;\n};\ntype XY = X | Y;\nconst r: XY = { a: 'a', b: 'x' }; // Válido\n```\n\nUma interseção, (T1 & T2), cria um conjunto mais estreito (apenas o que é compartilhado):\n\n<!-- skip -->\n```typescript\ntype X = {\n    a: string;\n};\ntype Y = {\n    a: string;\n    b: string;\n};\ntype XY = X & Y;\nconst r: XY = { a: 'a' }; // Inválido\nconst j: XY = { a: 'a', b: 'b' }; // Válido\n```\n\nA palavra-chave `extends` pode ser considerada como \"subconjunto de\" neste contexto. Ela define uma restrição para um tipo. O `extends` usado com um genérico trata o genérico como um conjunto infinito e o restringe a um tipo mais específico.\nObserve que o `extends` nada tem a ver com hierarquia no sentido de Orientação a Objetos (não existe esse conceito no TypeScript).\nO TypeScript trabalha com conjuntos e não possui uma hierarquia estrita; de fato, como no exemplo abaixo, dois tipos podem se sobrepor sem que nenhum seja um subtipo do outro (o TypeScript considera a estrutura, a forma dos objetos).\n\n```typescript\ninterface X {\n    a: string;\n}\ninterface Y extends X {\n    b: string;\n}\ninterface Z extends Y {\n    c: string;\n}\nconst z: Z = { a: 'a', b: 'b', c: 'c' };\ninterface X1 {\n    a: string;\n}\ninterface Y1 {\n    a: string;\n    b: string;\n}\ninterface Z1 {\n    a: string;\n    b: string;\n    c: string;\n}\nconst z1: Z1 = { a: 'a', b: 'b', c: 'c' };\n\nconst r: Z1 = z; // Válido\n```\n\n### Atribuir um tipo: Declarações de Tipo e Asserções de Tipo\n\nUm tipo pode ser atribuído de diferentes maneiras no TypeScript:\n\n#### Declaração de Tipo\n\nNo exemplo a seguir, usamos x: X (\": Tipo\") para declarar um tipo para a variável x.\n\n```typescript\ntype X = {\n    a: string;\n};\n\n// Declaração de tipo\nconst x: X = {\n    a: 'a',\n};\n```\n\nSe a variável não estiver no formato especificado, o TypeScript relatará um erro. Por exemplo:\n\n<!-- skip -->\n```typescript\ntype X = {\n    a: string;\n};\n\nconst x: X = {\n    a: 'a',\n    b: 'b', // Erro: O objeto literal só pode especificar propriedades conhecidas\n};\n```\n\n#### Asserção de Tipo\n\nÉ possível adicionar uma asserção usando a palavra-chave `as`. Isso informa ao compilador que o desenvolvedor tem mais informações sobre um tipo e silencia quaisquer erros que possam ocorrer.\n\nPor exemplo:\n\n```typescript\ntype X = {\n    a: string;\n};\nconst x = {\n    a: 'a',\n    b: 'b',\n} as X;\n```\n\nNo exemplo acima, o objeto x é asseverado como tendo o tipo X usando a palavra-chave `as`. Isso informa ao compilador TypeScript que o objeto está em conformidade com o tipo especificado, embora tenha uma propriedade b adicional não presente na definição do tipo.\n\nAsserções de tipo são úteis em situações onde um tipo mais específico precisa ser especificado, especialmente ao trabalhar com o DOM. Por exemplo:\n\n```typescript\nconst myInput = document.getElementById('my_input') as HTMLInputElement;\n```\n\nAqui, a asserção de tipo `as HTMLInputElement` é usada para dizer ao TypeScript que o resultado de `getElementById` deve ser tratado como um `HTMLInputElement`.\nAsserções de tipo também podem ser usadas para mapear chaves novamente, conforme mostrado no exemplo abaixo com literais de template:\n\n```typescript\ntype J<Type> = {\n    [Property in keyof Type as `prefix_${string &\n        Property}`]: () => Type[Property];\n};\ntype X = {\n    a: string;\n    b: number;\n};\ntype Y = J<X>;\n```\n\nNeste exemplo, o tipo `J<Type>` usa um tipo mapeado com um literal de template para mapear as chaves de `Type`. Ele cria novas propriedades com um \"prefix_\" adicionado a cada chave, e seus valores correspondentes são funções que retornam os valores originais da propriedade.\n\nVale a pena notar que, ao usar uma asserção de tipo, o TypeScript não executará a verificação de excesso de propriedades. Portanto, geralmente é preferível usar uma Declaração de Tipo quando a estrutura do objeto for conhecida antecipadamente.\n\n#### Declarações de Ambiente (Ambient Declarations)\n\nDeclarações de ambiente são arquivos que descrevem tipos para código JavaScript; eles têm o formato de nome de arquivo `.d.ts`. Geralmente são importados e usados para anotar bibliotecas JavaScript existentes ou para adicionar tipos a arquivos JS existentes em seu projeto.\n\nMuitos tipos de bibliotecas comuns podem ser encontrados em:\n[https://github.com/DefinitelyTyped/DefinitelyTyped/](https://github.com/DefinitelyTyped/DefinitelyTyped/)\n\ne podem ser instalados usando:\n\n```shell\nnpm install --save-dev @types/nome-da-biblioteca\n```\n\nPara suas Declarações de Ambiente definidas, você pode importar usando a referência de \"barra tripla\":\n\n<!-- skip -->\n```typescript\n/// <reference path=\"./library-types.d.ts\" />\n```\n\nVocê pode usar Declarações de Ambiente até mesmo em arquivos JavaScript usando `// @ts-check`.\n\nA palavra-chave `declare` habilita definições de tipo para código JavaScript existente sem importá-lo, servindo como um marcador para tipos de outro arquivo ou globalmente.\n\n### Verificação de Propriedades e Verificação de Excesso de Propriedades\n\nO TypeScript é baseado em um sistema de tipos estrutural, mas a verificação de excesso de propriedades é um recurso do TypeScript que permite verificar se um objeto tem exatamente as propriedades especificadas no tipo.\n\nA Verificação de Excesso de Propriedades é executada ao atribuir objetos literais a variáveis ou ao passá-los como argumentos para funções, por exemplo.\n\n<!-- skip -->\n```typescript\ntype X = {\n    a: string;\n};\nconst y = { a: 'a', b: 'b' };\nconst x: X = y; // Válido por causa da tipagem estrutural\nconst w: X = { a: 'a', b: 'b' }; // Inválido por causa da verificação de excesso de propriedades\n```\n\n### Tipos Fracos (Weak Types)\n\nUm tipo é considerado fraco quando não contém nada além de um conjunto de todas as propriedades opcionais:\n\n```typescript\ntype X = {\n    a?: string;\n    b?: string;\n};\n```\n\nO TypeScript considera um erro atribuir qualquer coisa a um tipo fraco quando não há sobreposição; por exemplo, o seguinte lança um erro:\n\n<!-- skip -->\n```typescript\ntype Options = {\n    a?: string;\n    b?: string;\n};\n\nconst fn = (options: Options) => undefined;\n\nfn({ c: 'c' }); // Inválido\n```\n\nEmbora não recomendado, se necessário, é possível ignorar esta verificação usando asserção de tipo:\n\n```typescript\ntype Options = {\n    a?: string;\n    b?: string;\n};\nconst fn = (options: Options) => undefined;\nfn({ c: 'c' } as Options); // Válido\n```\n\nOu adicionando `unknown` à assinatura de índice do tipo fraco:\n\n```typescript\ntype Options = {\n    [prop: string]: unknown;\n    a?: string;\n    b?: string;\n};\n\nconst fn = (options: Options) => undefined;\nfn({ c: 'c' }); // Válido\n```\n\n### Verificação Estrita de Objeto Literal (Freshness)\n\nA verificação estrita de objeto literal, às vezes chamada de \"freshness\", é um recurso do TypeScript que ajuda a capturar propriedades em excesso ou com erro de ortografia que, de outra forma, passariam despercebidas em verificações normais de tipo estrutural.\n\nAo criar um objeto literal, o compilador TypeScript o considera \"fresco\" (fresh). Se o objeto literal for atribuído a uma variável ou passado como um parâmetro, o TypeScript lançará um erro se o objeto literal especificar propriedades que não existem no tipo de destino.\n\nNo entanto, a \"freshness\" desaparece quando um objeto literal é alargado ou quando uma asserção de tipo é usada.\n\nAqui estão alguns exemplos para ilustrar:\n\n<!-- skip -->\n```typescript\ntype X = { a: string };\ntype Y = { a: string; b: string };\n\nlet x: X;\nx = { a: 'a', b: 'b' }; // Verificação de Freshness: Atribuição inválida\nvar y: Y;\ny = { a: 'a', bx: 'bx' }; // Verificação de Freshness: Atribuição inválida\n\nconst fn = (x: X) => console.log(x.a);\n\nfn(x);\nfn(y); // Alargamento (Widening): Sem erros, estruturalmente compatível em termos de tipo\n\nfn({ a: 'a', bx: 'b' }); // Verificação de Freshness: Argumento inválido\n\nlet c: X = { a: 'a' };\nlet d: Y = { a: 'a', b: '' };\nc = d; // Alargamento: Sem verificação de Freshness\n```\n\n### Inferência de Tipo\n\nO TypeScript pode inferir tipos quando nenhuma anotação é fornecida durante a:\n\n* Inicialização da variável.\n* Inicialização de membros.\n* Definição de valores padrão para parâmetros.\n* Tipo de retorno da função.\n\nPor exemplo:\n\n```typescript\nlet x = 'x'; // O tipo inferido é string\n```\n\nO compilador TypeScript analisa o valor ou expressão e determina seu tipo com base nas informações disponíveis.\n\n### Inferências Mais Avançadas\n\nQuando várias expressões são usadas na inferência de tipo, o TypeScript procura pelos \"melhores tipos comuns\" (best common types). Por exemplo:\n\n```typescript\nlet x = [1, 'x', 1, null]; // O tipo inferido é: (string | number | null)[]\n```\n\nSe o compilador não conseguir encontrar os melhores tipos comuns, ele retorna um tipo de união. Por exemplo:\n\n```typescript\nlet x = [new RegExp('x'), new Date()]; // O tipo inferido é: (RegExp | Date)[]\n```\n\nO TypeScript utiliza a \"tipagem contextual\" baseada na localização da variável para inferir tipos. No exemplo a seguir, o compilador sabe que `e` é do tipo `MouseEvent` por causa do tipo de evento `click` definido no arquivo `lib.d.ts`, que contém declarações de ambiente para várias construções JavaScript comuns e o DOM:\n\n```typescript\nwindow.addEventListener('click', function (e) {}); // O tipo inferido de e é MouseEvent\n```\n\n### Alargamento de Tipo (Type Widening)\n\nO alargamento de tipo (type widening) é o processo no qual o TypeScript atribui um tipo a uma variável inicializada quando nenhuma anotação de tipo foi fornecida. Ele permite tipos de mais estreitos para mais amplos, mas não o contrário.\nNo exemplo a seguir:\n\n<!-- skip -->\n```typescript\nlet x = 'x'; // O TypeScript infere como string, um tipo amplo\nlet y: 'y' | 'x' = 'y'; // o tipo de y é uma união de tipos literais\ny = x; // Inválido: O tipo 'string' não pode ser atribuído ao tipo '\"x\" | \"y\"'.\n```\n\nO TypeScript atribui `string` a `x` com base no valor único fornecido durante a inicialização (`x`); este é um exemplo de alargamento.\n\nO TypeScript fornece maneiras de ter controle sobre o processo de alargamento, por exemplo, usando \"const\".\n\n### Const\n\nO uso da palavra-chave `const` ao declarar uma variável resulta em uma inferência de tipo mais estreita no TypeScript.\n\nPor exemplo:\n\n```typescript\nconst x = 'x'; // O TypeScript infere o tipo de x como 'x', um tipo mais estreito\nlet y: 'y' | 'x' = 'y';\ny = x; // Válido: O tipo de x é inferido como 'x'\n```\n\nAo usar `const` para declarar a variável x, seu tipo é estreitado para o valor literal específico 'x'. Como o tipo de x é estreitado, ele pode ser atribuído à variável y sem nenhum erro.\nA razão pela qual o tipo pode ser inferido é porque as variáveis `const` não podem ser reatribuídas, portanto seu tipo pode ser estreitado para um tipo literal específico, neste caso, o tipo literal 'x'.\n\n#### Modificador Const em Parâmetros de Tipo\n\nA partir da versão 5.0 do TypeScript, é possível especificar o atributo `const` em um parâmetro de tipo genérico. Isso permite inferir o tipo mais preciso possível. Vejamos um exemplo sem usar `const`:\n\n```typescript\nfunction identity<T>(value: T) {\n    // Sem const aqui\n    return value;\n}\nconst values = identity({ a: 'a', b: 'b' }); // O tipo inferido é: { a: string; b: string; }\n```\n\nComo você pode ver, as propriedades `a` e `b` são inferidas com o tipo `string`.\n\nAgora, vejamos a diferença com a versão `const`:\n\n```typescript\nfunction identity<const T>(value: T) {\n    // Usando modificador const em parâmetros de tipo\n    return value;\n}\nconst values = identity({ a: 'a', b: 'b' }); // O tipo inferido é: { a: \"a\"; b: \"b\"; }\n```\n\nAgora podemos ver que as propriedades `a` e `b` são inferidas como `const`, portanto `a` e `b` são tratados como literais de string em vez de apenas tipos `string`.\n\n#### Asserção Const (Const assertion)\n\nEste recurso permite declarar uma variável com um tipo literal mais preciso baseado em seu valor de inicialização, sinalizando ao compilador que o valor deve ser tratado como um literal imutável. Aqui estão alguns exemplos:\n\nEm uma única propriedade:\n\n```typescript\nconst v = {\n    x: 3 as const,\n};\nv.x = 3;\n```\n\nEm um objeto inteiro:\n\n```typescript\nconst v = {\n    x: 1,\n    y: 2,\n} as const;\n```\n\nIsso pode ser particularmente útil ao definir o tipo para uma tupla:\n\n```typescript\nconst x = [1, 2, 3]; // number[]\nconst y = [1, 2, 3] as const; // Tupla de readonly [1, 2, 3]\n```\n\n### Anotação de Tipo Explícita\n\nPodemos ser específicos e passar um tipo; no exemplo a seguir, a propriedade `x` é do tipo `number`:\n\n```typescript\nconst v = {\n    x: 1, // Tipo inferido: number (alargamento)\n};\nv.x = 3; // Válido\n```\n\nPodemos tornar a anotação de tipo mais específica usando uma união de tipos literais:\n\n<!-- skip -->\n```typescript\nconst v: { x: 1 | 2 | 3 } = {\n    x: 1, // x agora é uma união de tipos literais: 1 | 2 | 3\n};\nv.x = 3; // Válido\nv.x = 100; // Inválido\n```\n\n### Estreitamento de Tipo (Type Narrowing)\n\nO Estreitamento de Tipo (Type Narrowing) é o processo no TypeScript onde um tipo geral é estreitado para um tipo mais específico. Isso ocorre quando o TypeScript analisa o código e determina que certas condições ou operações podem refinar a informação do tipo.\n\nO estreitamento de tipos pode ocorrer de diferentes maneiras, incluindo:\n\n#### Condições\n\nAo usar instruções condicionais, como `if` ou `switch`, o TypeScript pode estreitar o tipo com base no resultado da condição. Por exemplo:\n\n```typescript\nlet x: number | undefined = 10;\n\nif (x !== undefined) {\n    x += 100; // O tipo é number, que foi estreitado pela condição\n}\n```\n\n#### Lançando ou retornando\n\nLançar um erro ou retornar cedo de uma ramificação pode ser usado para ajudar o TypeScript a estreitar um tipo. Por exemplo:\n\n```typescript\nlet x: number | undefined = 10;\n\nif (x === undefined) {\n    throw 'erro';\n}\nx += 100;\n```\n\nOutras formas de estreitar tipos no TypeScript incluem:\n\n* Operador `instanceof`: Usado para verificar se um objeto é uma instância de uma classe específica.\n* Operador `in`: Usado para verificar se uma propriedade existe em um objeto.\n* Operador `typeof`: Usado para verificar o tipo de um valor em tempo de execução.\n* Funções integradas como `Array.isArray()`: Usadas para verificar se um valor é um array.\n\n#### União Discriminada\n\nO uso de uma \"União Discriminada\" é um padrão no TypeScript onde uma \"tag\" explícita é adicionada aos objetos para distinguir entre diferentes tipos dentro de uma união. Este padrão também é conhecido como \"união tagueada\" (tagged union). No exemplo a seguir, a \"tag\" é representada pela propriedade \"type\":\n\n```typescript\ntype A = { type: 'type_a'; value: number };\ntype B = { type: 'type_b'; value: string };\n\nconst x = (input: A | B): string | number => {\n    switch (input.type) {\n        case 'type_a':\n            return input.value + 100; // o tipo é A\n        case 'type_b':\n            return input.value + 'extra'; // o tipo é B\n    }\n};\n```\n\n#### Proteções de Tipo Definidas pelo Usuário (User-Defined Type Guards)\n\nEm casos onde o TypeScript não é capaz de determinar um tipo, é possível escrever uma função auxiliar conhecida como \"proteção de tipo definida pelo usuário\" (user-defined type guard). No exemplo a seguir, utilizaremos um Predicado de Tipo para estreitar o tipo após aplicar certa filtragem:\n\n```typescript\nconst data = ['a', null, 'c', 'd', null, 'f'];\n\nconst r1 = data.filter(x => x != null); // O tipo é (string | null)[], o TypeScript não foi capaz de inferir o tipo corretamente\n\nconst isValid = (item: string | null): item is string => item !== null; // Protetor de tipo customizado\n\nconst r2 = data.filter(isValid); // O tipo está correto agora string[], ao usar o protetor de tipo predicado conseguimos estreitar o tipo\n```\n\n## Tipos Primitivos\n\nO TypeScript suporta 7 tipos primitivos. Um tipo de dado primitivo refere-se a um tipo que não é um objeto e não possui nenhum método associado a ele. No TypeScript, todos os tipos primitivos são imutáveis, o que significa que seus valores não podem ser alterados uma vez que são atribuídos.\n\n### string\n\nO tipo primitivo `string` armazena dados textuais, e o valor é sempre delimitado por aspas duplas ou simples.\n\n```typescript\nconst x: string = 'x';\nconst y: string = 'y';\n```\n\nAs strings podem abranger várias linhas se estiverem rodeadas pelo caractere de crase (`):\n\n```typescript\nlet sentence: string = `xxx,\n   yyy`;\n```\n\n### boolean\n\nO tipo de dado `boolean` no TypeScript armazena um valor binário, seja `true` ou `false`.\n\n```typescript\nconst isReady: boolean = true;\n```\n\n### number\n\nUm tipo de dado `number` no TypeScript é representado com um valor de ponto flutuante de 64 bits. Um tipo `number` pode representar inteiros e frações.\nO TypeScript também suporta hexadecimal, binário e octal, por exemplo:\n\n```typescript\nconst decimal: number = 10;\nconst hexadecimal: number = 0xa00d; // Hexadecimal começa com 0x\nconst binary: number = 0b1010; // Binário começa com 0b\nconst octal: number = 0o633; // Octal começa com 0o\n```\n\n### bigInt\n\nUm `bigInt` representa valores numéricos muito grandes (253 – 1) e que não podem ser representados com um `number`.\n\nUm `bigInt` pode ser criado chamando a função integrada `BigInt()` ou adicionando `n` ao final de qualquer literal numérico inteiro:\n\n```typescript\nconst x: bigint = BigInt(9007199254740991);\nconst y: bigint = 9007199254740991n;\n```\n\nNotas:\n\n* Valores `bigInt` não podem ser misturados com `number` e não podem ser usados com a função integrada `Math`; eles devem ser coagidos para o mesmo tipo.\n* Valores `bigInt` estão disponíveis apenas se a configuração da meta (target) for ES2020 ou superior.\n\n### Symbol\n\nSymbols são identificadores únicos que podem ser usados como chaves de propriedade em objetos para evitar conflitos de nomenclatura.\n\n```typescript\ntype Obj = {\n    [sym: symbol]: number;\n};\n\nconst a = Symbol('a');\nconst b = Symbol('b');\nlet obj: Obj = {};\nobj[a] = 123;\nobj[b] = 456;\n\nconsole.log(obj[a]); // 123\nconsole.log(obj[b]); // 456\n```\n\n### null e undefined\n\nOs tipos `null` e `undefined` representam a ausência de valor.\n\nO tipo `undefined` significa que o valor não foi atribuído ou inicializado, ou indica uma ausência não intencional de valor.\n\nO tipo `null` significa que sabemos que o campo não possui um valor, portanto o valor está indisponível; indica uma ausência intencional de valor.\n\n### Array\n\nUm `array` é um tipo de dado que pode armazenar múltiplos valores do mesmo tipo ou não. Ele pode ser definido usando a seguinte sintaxe:\n\n```typescript\nconst x: string[] = ['a', 'b'];\nconst y: Array<string> = ['a', 'b'];\nconst j: Array<string | number> = ['a', 1, 'b', 2]; // União\n```\n\nO TypeScript suporta arrays somente leitura (readonly) usando a seguinte sintaxe:\n\n<!-- skip -->\n```typescript\nconst x: readonly string[] = ['a', 'b']; // Modificador readonly\nconst y: ReadonlyArray<string> = ['a', 'b'];\nconst j: ReadonlyArray<string | number> = ['a', 1, 'b', 2];\nj.push('x'); // Inválido\n```\n\nO TypeScript suporta tupla e tupla somente leitura:\n\n```typescript\nconst x: [string, number] = ['a', 1];\nconst y: readonly [string, number] = ['a', 1];\n```\n\n### any\n\nO tipo de dado `any` representa literalmente \"qualquer\" valor; é o valor padrão quando o TypeScript não consegue inferir o tipo ou quando este não é especificado.\n\nAo usar `any`, o compilador TypeScript ignora a verificação de tipo, portanto não há segurança de tipo quando o `any` está sendo usado. Geralmente, não use `any` para silenciar o compilador quando ocorre um erro; em vez disso, concentre-se em corrigir o erro, pois ao usar `any` é possível quebrar contratos e perdemos os benefícios do preenchimento automático do TypeScript.\n\nO tipo `any` pode ser útil durante uma migração gradual de JavaScript para TypeScript, pois pode silenciar o compilador.\n\nPara novos projetos, use a configuração do TypeScript `noImplicitAny`, que permite que o TypeScript emita erros onde `any` é usado ou inferido.\n\nO tipo `any` é geralmente uma fonte de erros que podem mascarar problemas reais com seus tipos. Evite usá-lo o máximo possível.\n\n## Anotações de Tipo\n\nEm variáveis declaradas usando `var`, `let` e `const`, é possível adicionar opcionalmente um tipo:\n\n```typescript\nconst x: number = 1;\n```\n\nO TypeScript faz um bom trabalho ao inferir tipos, especialmente quando são simples, portanto essas declarações, na maioria dos casos, não são necessárias.\n\nEm funções, é possível adicionar anotações de tipo aos parâmetros:\n\n```typescript\nfunction sum(a: number, b: number) {\n    return a + b;\n}\n```\n\nO seguinte é um exemplo usando funções anônimas (as chamadas funções lambda):\n\n```typescript\nconst sum = (a: number, b: number) => a + b;\n```\n\nEssas anotações podem ser evitadas quando um valor padrão para um parâmetro está presente:\n\n```typescript\nconst sum = (a = 10, b: number) => a + b;\n```\n\nAnotações de tipo de retorno podem ser adicionadas às funções:\n\n```typescript\nconst sum = (a = 10, b: number): number => a + b;\n```\n\nIsso é útil especialmente para funções mais complexas, pois escrever explicitamente o tipo de retorno antes de uma implementação pode ajudar a pensar melhor sobre a função.\n\nGeralmente, considere anotar as assinaturas de tipo, mas não as variáveis locais do corpo, e sempre adicione tipos a objetos literais.\n\n## Propriedades Opcionais\n\nUm objeto pode especificar Propriedades Opcionais adicionando um ponto de interrogação `?` ao final do nome da propriedade:\n\n```typescript\ntype X = {\n    a: number;\n    b?: number; // Opcional\n};\n```\n\nÉ possível especificar um valor padrão quando uma propriedade é opcional:\n\n```typescript\ntype X = {\n    a: number;\n    b?: number;\n};\nconst x = ({ a, b = 100 }: X) => a + b;\n```\n\n## Propriedades Somente Leitura (Readonly)\n\nÉ possível impedir a escrita em uma propriedade usando o modificador `readonly`, que garante que a propriedade não possa ser reescrita, mas não fornece nenhuma garantia de imutabilidade total:\n\n```typescript\ninterface Y {\n    readonly a: number;\n}\n\ntype X = {\n    readonly a: number;\n};\n\ntype J = Readonly<{\n    a: number;\n}>;\n\ntype K = {\n    readonly [index: number]: string;\n};\n```\n\n## Assinaturas de Índice (Index Signatures)\n\nNo TypeScript, podemos usar como assinatura de índice `string`, `number` e `symbol`:\n\n```typescript\ntype K = {\n    [name: string | number]: string;\n};\nconst k: K = { x: 'x', 1: 'b' };\nconsole.log(k['x']);\nconsole.log(k[1]);\nconsole.log(k['1']); // Mesmo resultado que k[1]\n```\n\nObserve que o JavaScript converte automaticamente um índice com `number` em um índice com `string`, portanto `k[1]` ou `k[\"1\"]` retornam o mesmo valor.\n\n## Estendendo Tipos\n\nÉ possível estender uma `interface` (copiar membros de outro tipo):\n\n```typescript\ninterface X {\n    a: string;\n}\ninterface Y extends X {\n    b: string;\n}\n```\n\nTambém é possível estender de múltiplos tipos:\n\n```typescript\ninterface A {\n    a: string;\n}\ninterface B {\n    b: string;\n}\ninterface Y extends A, B {\n    y: string;\n}\n```\n\nA palavra-chave `extends` funciona apenas em interfaces e classes; para tipos, use uma interseção:\n\n```typescript\ntype A = {\n    a: number;\n};\ntype B = {\n    b: number;\n};\ntype C = A & B;\n```\n\nÉ possível estender um tipo usando uma inferência, mas não o contrário:\n\n```typescript\ntype A = {\n    a: string;\n};\ninterface B extends A {\n    b: string;\n}\n```\n\n## Tipos Literais\n\nUm Tipo Literal é um conjunto de elemento único a partir de um tipo coletivo; ele define um valor exato que é um primitivo do JavaScript.\n\nOs Tipos Literais no TypeScript são números, strings e booleanos.\n\nExemplo de literais:\n\n```typescript\nconst a = 'a'; // Tipo literal de string\nconst b = 1; // Tipo literal numérico\nconst c = true; // Tipo literal booleano\n```\n\nTipos Literais de String, Numéricos e Booleanos são usados em uniões, protetores de tipo (type guards) e apelidos de tipo (type aliases).\nNo exemplo a seguir, você pode ver um apelido de tipo de união. `O` consiste apenas nos valores especificados; nenhuma outra string é válida:\n\n```typescript\ntype O = 'a' | 'b' | 'c';\n```\n\n## Inferência Literal\n\nA Inferência Literal é um recurso do TypeScript que permite que o tipo de uma variável ou parâmetro seja inferido com base em seu valor.\n\nNo exemplo a seguir, podemos ver que o TypeScript considera `x` um tipo literal, pois o valor não pode ser alterado posteriormente, enquanto `y` é inferido como string, pois pode ser modificado posteriormente.\n\n```typescript\nconst x = 'x'; // Tipo literal de 'x', porque este valor não pode ser alterado\nlet y = 'y'; // Tipo string, pois podemos alterar este valor\n```\n\nNo exemplo a seguir, podemos ver que `o.x` foi inferido como uma `string` (e não um literal de `a`), pois o TypeScript considera que o valor pode ser alterado posteriormente.\n\n<!-- skip -->\n```typescript\ntype X = 'a' | 'b';\n\nlet o = {\n    x: 'a', // Esta é uma string mais ampla (wider string)\n};\n\nconst fn = (x: X) => `${x}-foo`;\n\nconsole.log(fn(o.x)); // Argument of type 'string' is not assignable to parameter of type 'X'\n```\n\nComo você pode observar, o código lança um erro ao passar `o.x` para `fn`, pois X é um tipo mais estreito (narrower).\n\nPodemos resolver este problema usando asserção de tipo com `const` ou o tipo `X`:\n\n<!-- skip -->\n```typescript\nlet o = {\n    x: 'a' as const,\n};\n```\n\nou:\n\n<!-- skip -->\n```typescript\nlet o = {\n    x: 'a' as X,\n};\n```\n\n## strictNullChecks\n\n`strictNullChecks` é uma opção do compilador TypeScript que impõe a verificação estrita de nulos. Quando esta opção está habilitada, variáveis e parâmetros só podem receber `null` | `undefined` se tiverem sido explicitamente declarados como sendo desse tipo usando o tipo de união `null` | `undefined`. Se uma variável ou parâmetro não for explicitamente declarado como anulável, o TypeScript gerará um erro para evitar possíveis erros de tempo de execução.\n\n## Enums\n\nNo TypeScript, um `enum` é um conjunto de valores constantes nomeados.\n\n```typescript\nenum Color {\n    Red = '#ff0000',\n    Green = '#00ff00',\n    Blue = '#0000ff',\n}\n```\n\nEnums podem ser definidos de diferentes maneiras:\n\n### Enums numéricos\n\nNo TypeScript, um Enum Numérico é um Enum onde cada constante recebe um valor numérico, começando em 0 por padrão.\n\n```typescript\nenum Size {\n    Small, // o valor começa de 0\n    Medium,\n    Large,\n}\n```\n\nÉ possível especificar valores personalizados atribuindo-os explicitamente:\n\n```typescript\nenum Size {\n    Small = 10,\n    Medium,\n    Large,\n}\nconsole.log(Size.Medium); // 11\n```\n\n### Enums de string\n\nNo TypeScript, um Enum de String é um Enum onde cada constante recebe um valor de string.\n\n```typescript\nenum Language {\n    English = 'EN',\n    Spanish = 'ES',\n}\n```\n\nNota: O TypeScript permite o uso de Enums heterogêneos, onde membros de string e numéricos podem coexistir.\n\n### Enums constantes\n\nUm enum constante (const enum) no TypeScript é um tipo especial de Enum onde todos os valores são conhecidos em tempo de compilação e são inseridos diretamente (inlined) onde quer que o enum seja usado, resultando em um código mais eficiente.\n\n```typescript\nconst enum Language {\n    English = 'EN',\n    Spanish = 'ES',\n}\nconsole.log(Language.English);\n```\n\nSerá compilado para:\n\n```typescript\nconsole.log('EN' /* Language.English */);\n```\n\nNotas:\nEnums Constantes têm valores fixos (hardcoded), apagando o Enum, o que pode ser mais eficiente em bibliotecas autocontidas, mas geralmente não é desejável. Além disso, enums constantes não podem ter membros computados.\n\n### Mapeamento reverso\n\nNo TypeScript, os mapeamentos reversos em Enums referem-se à capacidade de recuperar o nome do membro do Enum a partir de seu valor. Por padrão, os membros do Enum têm mapeamentos diretos (forward mappings) do nome para o valor, mas mapeamentos reversos podem ser criados definindo explicitamente os valores para cada membro. Os mapeamentos reversos são úteis quando você precisa procurar um membro do Enum pelo seu valor ou quando precisa iterar sobre todos os membros do Enum. Note que apenas membros de enums numéricos gerarão mapeamentos reversos, enquanto membros de Enums de String não possuem um mapeamento reverso gerado.\n\nO seguinte enum:\n\n```typescript\nenum Grade {\n    A = 90,\n    B = 80,\n    C = 70,\n    F = 'fail',\n}\n```\n\nCompila para:\n\n<!-- skip -->\n```javascript\n'use strict';\nvar Grade;\n(function (Grade) {\n    Grade[(Grade['A'] = 90)] = 'A';\n    Grade[(Grade['B'] = 80)] = 'B';\n    Grade[(Grade['C'] = 70)] = 'C';\n    Grade['F'] = 'fail';\n})(Grade || (Grade = {}));\n```\n\nPortanto, mapear valores para chaves funciona para membros de enums numéricos, mas não para membros de enums de string:\n\n<!-- skip -->\n```typescript\nenum Grade {\n    A = 90,\n    B = 80,\n    C = 70,\n    F = 'fail',\n}\nconst myGrade = Grade.A;\nconsole.log(Grade[myGrade]); // A\nconsole.log(Grade[90]); // A\n\nconst failGrade = Grade.F;\nconsole.log(failGrade); // fail\nconsole.log(Grade[failGrade]); // Element implicitly has an 'any' type because index expression is not of type 'number'.\n```\n\n### Enums de ambiente\n\nUm enum de ambiente no TypeScript é um tipo de Enum que é definido em um arquivo de declaração (*.d.ts) sem uma implementação associada. Ele permite definir um conjunto de constantes nomeadas que podem ser usadas de forma segura em relação aos tipos em diferentes arquivos, sem ter que importar os detalhes da implementação em cada arquivo.\n\n### Membros computados e constantes\n\nNo TypeScript, um membro computado é um membro de um Enum que possui um valor calculado em tempo de execução, enquanto um membro constante é um membro cujo valor é definido em tempo de compilação e não pode ser alterado durante o tempo de execução. Membros computados são permitidos em Enums regulares, enquanto membros constantes são permitidos tanto em enums regulares quanto em enums constantes (const enums).\n\n```typescript\n// Membros constantes\nenum Color {\n    Red = 1,\n    Green = 5,\n    Blue = Red + Green,\n}\nconsole.log(Color.Blue); // geração 6 em tempo de compilação\n```\n\n```typescript\n// Membros computados\nenum Color {\n    Red = 1,\n    Green = Math.pow(2, 2),\n    Blue = Math.floor(Math.random() * 3) + 1,\n}\nconsole.log(Color.Blue); // número aleatório gerado em tempo de execução\n```\n\nEnums são representados por uniões compostas pelos tipos de seus membros. Os valores de cada membro podem ser determinados por meio de expressões constantes ou não constantes, com membros que possuem valores constantes recebendo tipos literais. Para ilustrar, considere a declaração do tipo E e seus subtipos E.A, E.B e E.C. Neste caso, E representa a união E.A | E.B | E.C.\n\n```typescript\nconst identity = (value: number) => value;\n\nenum E {\n    A = 2 * 5, // Literal numérico\n    B = 'bar', // Literal de string\n    C = identity(42), // Computado opaco\n}\n\nconsole.log(E.C); //42\n```\n\n## Estreitamento (Narrowing)\n\nO estreitamento (narrowing) no TypeScript é o processo de refinar o tipo de uma variável dentro de um bloco condicional. Isso é útil ao trabalhar com tipos de união, onde uma variável pode ter mais de um tipo.\n\nO TypeScript reconhece várias maneiras de estreitar o tipo:\n\n### typeof type guards\n\nO protetor de tipo (type guard) `typeof` é um protetor de tipo específico no TypeScript que verifica o tipo de uma variável com base em seu tipo JavaScript integrado.\n\n```typescript\nconst fn = (x: number | string) => {\n    if (typeof x === 'number') {\n        return x + 1; // x é number\n    }\n    return -1;\n};\n```\n\n### Estreitamento de veracidade (Truthiness narrowing)\n\nO estreitamento de veracidade (truthiness narrowing) no TypeScript funciona verificando se uma variável é verdadeira (truthy) ou falsa (falsy) para estreitar seu tipo adequadamente.\n\n```typescript\nconst toUpperCase = (name: string | null) => {\n    if (name) {\n        return name.toUpperCase();\n    } else {\n        return null;\n    }\n};\n```\n\n### Estreitamento de igualdade (Equality narrowing)\n\nO estreitamento de igualdade (equality narrowing) no TypeScript funciona verificando se uma variável é igual a um valor específico ou não, para estreitar seu tipo adequadamente.\n\nÉ usado em conjunto com instruções `switch` e operadores de igualdade como `===`, `!==`, `==` e `!=` para estreitar os tipos.\n\n```typescript\nconst checkStatus = (status: 'success' | 'error') => {\n    switch (status) {\n        case 'success':\n            return true;\n        case 'error':\n            return null;\n    }\n};\n```\n\n### Estreitamento com operador In\n\nO estreitamento com o operador `in` no TypeScript é uma forma de estreitar o tipo de uma variável com base na existência de uma propriedade dentro do tipo da variável.\n\n```typescript\ntype Dog = {\n    name: string;\n    breed: string;\n};\n\ntype Cat = {\n    name: string;\n    likesCream: boolean;\n};\n\nconst getAnimalType = (pet: Dog | Cat) => {\n    if ('breed' in pet) {\n        return 'dog';\n    } else {\n        return 'cat';\n    }\n};\n```\n\n### Estreitamento com instanceof\n\nO estreitamento com o operador `instanceof` no TypeScript é uma forma de estreitar o tipo de uma variável com base em sua função construtora, verificando se um objeto é uma instância de uma determinada classe ou interface.\n\n```typescript\nclass Square {\n    constructor(public width: number) {}\n}\nclass Rectangle {\n    constructor(\n        public width: number,\n        public height: number\n    ) {}\n}\nfunction area(shape: Square | Rectangle) {\n    if (shape instanceof Square) {\n        return shape.width * shape.width;\n    } else {\n        return shape.width * shape.height;\n    }\n}\nconst square = new Square(5);\nconst rectangle = new Rectangle(5, 10);\nconsole.log(area(square)); // 25\nconsole.log(area(rectangle)); // 50\n```\n\n## Atribuições\n\nO estreitamento do TypeScript usando atribuições é uma forma de estreitar o tipo de uma variável com base no valor atribuído a ela. Quando uma variável recebe um valor, o TypeScript infere seu tipo com base no valor atribuído e estreita o tipo da variável para corresponder ao tipo inferido.\n\n```typescript\nlet value: string | number;\nvalue = 'hello';\nif (typeof value === 'string') {\n    console.log(value.toUpperCase());\n}\nvalue = 42;\nif (typeof value === 'number') {\n    console.log(value.toFixed(2));\n}\n```\n\n## Análise de Fluxo de Controle\n\nA Análise de Fluxo de Controle (Control Flow Analysis) no TypeScript é uma forma de analisar estaticamente o fluxo do código para inferir os tipos das variáveis, permitindo que o compilador estreite os tipos dessas variáveis conforme necessário, com base nos resultados da análise.\n\nAntes do TypeScript 4.4, a análise de fluxo de código só seria aplicada ao código dentro de uma instrução `if`, mas a partir do TypeScript 4.4, ela também pode ser aplicada a expressões condicionais e acessos a propriedades discriminantes referenciados indiretamente por meio de variáveis `const`.\n\nPor exemplo:\n\n```typescript\nconst f1 = (x: unknown) => {\n    const isString = typeof x === 'string';\n    if (isString) {\n        x.length;\n    }\n};\n\nconst f2 = (\n    obj: { kind: 'foo'; foo: string } | { kind: 'bar'; bar: number }\n) => {\n    const isFoo = obj.kind === 'foo';\n    if (isFoo) {\n        obj.foo;\n    } else {\n        obj.bar;\n    }\n};\n```\n\nAlguns exemplos onde o estreitamento não ocorre:\n\n<!-- skip -->\n```typescript\nconst f1 = (x: unknown) => {\n    let isString = typeof x === 'string';\n    if (isString) {\n        x.length; // Erro, sem estreitamento porque isString não é const\n    }\n};\n\nconst f6 = (\n    obj: { kind: 'foo'; foo: string } | { kind: 'bar'; bar: number }\n) => {\n    const isFoo = obj.kind === 'foo';\n    obj = obj;\n    if (isFoo) {\n        obj.foo; // Erro, sem estreitamento porque obj é atribuído no corpo da função\n    }\n};\n```\n\nNotas: Até cinco níveis de indireção são analisados em expressões condicionais.\n\n## Predicados de Tipo\n\nPredicados de Tipo (Type Predicates) no TypeScript são funções que retornam um valor booleano e são usadas para estreitar o tipo de uma variável para um tipo mais específico.\n\n```typescript\nconst isString = (value: unknown): value is string => typeof value === 'string';\n\nconst foo = (bar: unknown) => {\n    if (isString(bar)) {\n        console.log(bar.toUpperCase());\n    } else {\n        console.log('não é uma string');\n    }\n};\n```\n\n## Uniões Discriminadas\n\nUniões Discriminadas (Discriminated Unions) no TypeScript são um tipo de união que usa uma propriedade comum, conhecida como discriminante, para estreitar o conjunto de tipos possíveis para a união.\n\n```typescript\ntype Square = {\n    kind: 'square'; // Discriminante\n    size: number;\n};\n\ntype Circle = {\n    kind: 'circle'; // Discriminante\n    radius: number;\n};\n\ntype Shape = Square | Circle;\n\nconst area = (shape: Shape) => {\n    switch (shape.kind) {\n        case 'square':\n            return Math.pow(shape.size, 2);\n        case 'circle':\n            return Math.PI * Math.pow(shape.radius, 2);\n    }\n};\n\nconst square: Square = { kind: 'square', size: 5 };\nconst circle: Circle = { kind: 'circle', radius: 2 };\n\nconsole.log(area(square)); // 25\nconsole.log(area(circle)); // 12.566370614359172\n```\n\n## O tipo never\n\nQuando uma variável é estreitada para um tipo que não pode conter nenhum valor, o compilador TypeScript inferirá que a variável deve ser do tipo `never`. Isso ocorre porque o Tipo Never representa um valor que nunca pode ser produzido.\n\n```typescript\nconst printValue = (val: string | number) => {\n    if (typeof val === 'string') {\n        console.log(val.toUpperCase());\n    } else if (typeof val === 'number') {\n        console.log(val.toFixed(2));\n    } else {\n        // val tem o tipo never aqui porque nunca pode ser nada além de uma string ou um número\n        const neverVal: never = val;\n        console.log(`Valor inesperado: ${neverVal}`);\n    }\n};\n```\n\n## Verificação de exaustividade\n\nA verificação de exaustividade (exhaustiveness checking) é um recurso no TypeScript que garante que todos os casos possíveis de uma união discriminada sejam tratados em uma instrução `switch` ou `if`.\n\n```typescript\ntype Direction = 'up' | 'down';\n\nconst move = (direction: Direction) => {\n    switch (direction) {\n        case 'up':\n            console.log('Movendo para cima');\n            break;\n        case 'down':\n            console.log('Movendo para baixo');\n            break;\n        default:\n            const exhaustiveCheck: never = direction;\n            console.log(exhaustiveCheck); // Esta linha nunca será executada\n    }\n};\n```\n\nO tipo `never` é usado para garantir que o caso `default` seja exaustivo e que o TypeScript aponte um erro se um novo valor for adicionado ao tipo `Direction` sem ser tratado na instrução switch.\n\n## Tipos de Objeto\n\nNo TypeScript, os tipos de objeto descrevem a forma de um objeto. Eles especificam os nomes e tipos das propriedades do objeto, bem como se essas propriedades são obrigatórias ou opcionais.\n\nNo TypeScript, você pode definir tipos de objeto de duas maneiras principais:\n\nInterface, que define a forma de um objeto especificando os nomes, tipos e a opcionalidade de suas propriedades.\n\n```typescript\ninterface User {\n    name: string;\n    age: number;\n    email?: string;\n}\n```\n\nApelido de tipo (type alias), semelhante a uma interface, define a forma de um objeto. No entanto, ele também pode criar um novo tipo personalizado baseado em um tipo existente ou em uma combinação de tipos existentes. Isso inclui definir tipos de união, tipos de interseção e outros tipos complexos.\n\n```typescript\ntype Point = {\n    x: number;\n    y: number;\n};\n```\n\nTambém é possível definir um tipo anonimamente:\n\n```typescript\nconst sum = (x: { a: number; b: number }) => x.a + x.b;\nconsole.log(sum({ a: 5, b: 1 }));\n```\n\n## Tipo Tupla (Anônimo)\n\nUm Tipo Tupla (Tuple Type) é um tipo que representa um array com um número fixo de elementos e seus tipos correspondentes. Um tipo tupla impõe um número específico de elementos e seus respectivos tipos em uma ordem fixa. Os tipos tupla são úteis quando você deseja representar uma coleção de valores com tipos específicos, onde a posição de cada elemento no array tem um significado específico.\n\n```typescript\ntype Point = [number, number];\n```\n\n## Tipo Tupla Nomeado (Rotulado)\n\nOs tipos tupla podem incluir rótulos (labels) ou nomes opcionais para cada elemento. Esses rótulos são para legibilidade e assistência de ferramentas, e não afetam as operações que você pode realizar com eles.\n\n```typescript\ntype T = string;\ntype Tuple1 = [T, T];\ntype Tuple2 = [a: T, b: T];\ntype Tuple3 = [a: T, T]; // Tupla Nomeada mais Tupla Anônima\n```\n\n## Tupla de Comprimento Fixo\n\nUma Tupla de Comprimento Fixo é um tipo específico de tupla que impõe um número fixo de elementos de tipos específicos e proíbe quaisquer modificações no comprimento da tupla uma vez definida.\n\nTuplas de Comprimento Fixo são úteis quando você precisa representar uma coleção de valores com um número específico de elementos e tipos específicos, e deseja garantir que o comprimento e os tipos da tupla não possam ser alterados inadvertidamente.\n\n<!-- skip -->\n```typescript\nconst x = [10, 'hello'] as const;\nx.push(2); // Erro\n```\n\n## Tipo União\n\nUm Tipo União (Union Type) é um tipo que representa um valor que pode ser um de vários tipos. Tipos União são denotados usando o símbolo `|` entre cada tipo possível.\n\n```typescript\nlet x: string | number;\nx = 'hello'; // Válido\nx = 123; // Válido\n```\n\n## Tipos de Interseção\n\nUm Tipo de Interseção (Intersection Type) é um tipo que representa um valor que possui todas as propriedades de dois ou mais tipos. Tipos de Interseção são denotados usando o símbolo `&` entre cada tipo.\n\n```typescript\ntype X = {\n    a: string;\n};\n\ntype Y = {\n    b: string;\n};\n\ntype J = X & Y; // Interseção\n\nconst j: J = {\n    a: 'a',\n    b: 'b',\n};\n```\n\n## Indexação de Tipo\n\nIndexação de tipo (type indexing) refere-se à capacidade de definir tipos que podem ser indexados por uma chave não conhecida antecipadamente, usando uma assinatura de índice para especificar o tipo para propriedades que não são declaradas explicitamente.\n\n```typescript\ntype Dictionary<T> = {\n    [key: string]: T;\n};\nconst myDict: Dictionary<string> = { a: 'a', b: 'b' };\nconsole.log(myDict['a']); // Retorna a\n```\n\n## Tipo a partir de Valor\n\nTipo a partir de Valor (Type from Value) no TypeScript refere-se à inferência automática de um tipo a partir de um valor ou expressão através da inferência de tipos.\n\n```typescript\nconst x = 'x'; // O TypeScript infere 'x' como um literal de string com 'const' (imutável), mas alarga para 'string' com 'let' (atribuível novamente).\n```\n\n## Tipo a partir de Retorno de Função\n\nTipo a partir de Retorno de Função refere-se à capacidade de inferir automaticamente o tipo de retorno de uma função com base em sua implementação. Isso permite que o TypeScript determine o tipo do valor retornado pela função sem anotações de tipo explícitas.\n\n```typescript\nconst add = (x: number, y: number) => x + y; // O TypeScript pode inferir que o tipo de retorno da função é um número\n```\n\n## Tipo a partir de Módulo\n\nTipo a partir de Módulo refere-se à capacidade de usar os valores exportados de um módulo para inferir automaticamente seus tipos. Quando um módulo exporta um valor com um tipo específico, o TypeScript pode usar essa informação para inferir automaticamente o tipo desse valor quando ele é importado para outro módulo.\n\n<!-- skip -->\n```typescript\n// calc.ts\nexport const add = (x: number, y: number) => x + y;\n// index.ts\nimport { add } from 'calc';\nconst r = add(1, 2); // r é number\n```\n\n## Tipos Mapeados\n\nTipos Mapeados (Mapped Types) no TypeScript permitem criar novos tipos baseados em um tipo existente, transformando cada propriedade por meio de uma função de mapeamento. Ao mapear tipos existentes, você pode criar novos tipos que representam a mesma informação em um formato diferente. Para criar um tipo mapeado, você acessa as propriedades de um tipo existente usando o operador `keyof` e as altera para produzir um novo tipo.\nNo exemplo a seguir:\n\n```typescript\ntype MyMappedType<T> = {\n    [P in keyof T]: T[P][];\n};\ntype MyType = {\n    foo: string;\n    bar: number;\n};\ntype MyNewType = MyMappedType<MyType>;\nconst x: MyNewType = {\n    foo: ['hello', 'world'],\n    bar: [1, 2, 3],\n};\n```\n\ndefinimos `MyMappedType` para mapear sobre as propriedades de `T`, criando um novo tipo com cada propriedade sendo um array de seu tipo original. Usando isso, criamos `MyNewType` para representar a mesma informação que `MyType`, mas com cada propriedade como um array.\n\n## Modificadores de Tipos Mapeados\n\nOs Modificadores de Tipos Mapeados no TypeScript permitem a transformação de propriedades dentro de um tipo existente:\n\n* `readonly` ou `+readonly`: Torna uma propriedade no tipo mapeado como somente leitura.\n* `-readonly`: Permite que uma propriedade no tipo mapeado seja mutável.\n* `?`: Designa uma propriedade no tipo mapeado como opcional.\n\nExemplos:\n\n```typescript\ntype ReadOnly<T> = { readonly [P in keyof T]: T[P] }; // Todas as propriedades marcadas como somente leitura\n\ntype Mutable<T> = { -readonly [P in keyof T]: T[P] }; // Todas as propriedades marcadas como mutáveis\n\ntype MyPartial<T> = { [P in keyof T]?: T[P] }; // Todas as propriedades marcadas como opcionais\n```\n\n## Tipos Condicionais (Conditional Types)\n\nTipos Condicionais são uma forma de criar um tipo que depende de uma condição, onde o tipo a ser criado é determinado com base no resultado da condição. Eles são definidos usando a palavra-chave `extends` e um operador ternário para escolher condicionalmente entre dois tipos.\n\n```typescript\ntype IsArray<T> = T extends any[] ? true : false;\n\nconst myArray = [1, 2, 3];\nconst myNumber = 42;\n\ntype IsMyArrayAnArray = IsArray<typeof myArray>; // Tipo true\ntype IsMyNumberAnArray = IsArray<typeof myNumber>; // Tipo false\n```\n\n## Tipos Condicionais Distributivos\n\nTipos Condicionais Distributivos são um recurso que permite que um tipo seja distribuído sobre uma união de tipos, aplicando uma transformação a cada membro da união individualmente.\nIsso pode ser especialmente útil ao trabalhar com tipos mapeados ou tipos de ordem superior.\n\n```typescript\ntype Nullable<T> = T extends any ? T | null : never;\ntype NumberOrBool = number | boolean;\ntype NullableNumberOrBool = Nullable<NumberOrBool>; // number | boolean | null\n```\n\n## infer Inferência de Tipo em Tipos Condicionais\n\nA palavra-chave `infer` é usada em tipos condicionais para inferir (extrair) o tipo de um parâmetro genérico de um tipo que depende dele. Isso permite escrever definições de tipo mais flexíveis e reutilizáveis.\n\n```typescript\ntype ElementType<T> = T extends (infer U)[] ? U : never;\ntype Numbers = ElementType<number[]>; // number\ntype Strings = ElementType<string[]>; // string\n```\n\n## Tipos Condicionais Predefinidos\n\nNo TypeScript, os Tipos Condicionais Predefinidos são tipos condicionais integrados fornecidos pela linguagem. Eles são projetados para realizar transformações comuns de tipo com base nas características de um determinado tipo.\n\n`Exclude<UnionType, ExcludedType>`: Este tipo remove todos os tipos de Type que são atribuíveis a ExcludedType.\n\n`Extract<Type, Union>`: Este tipo extrai todos os tipos de Union que são atribuíveis a Type.\n\n`NonNullable<Type>`: Este tipo remove null e undefined de Type.\n\n`ReturnType<Type>`: Este tipo extrai o tipo de retorno de uma função Type.\n\n`Parameters<Type>`: Este tipo extrai os tipos de parâmetros de uma função Type.\n\n`Required<Type>`: Este tipo torna todas as propriedades em Type obrigatórias.\n\n`Partial<Type>`: Este tipo torna todas as propriedades em Type opcionais.\n\n`Readonly<Type>`: Este tipo torna todas as propriedades em Type somente leitura (readonly).\n\n## Tipos de União de Template (Template Union Types)\n\nTipos de união de template podem ser usados para mesclar e manipular texto dentro do sistema de tipos, por exemplo:\n\n```typescript\ntype Status = 'active' | 'inactive';\ntype Products = 'p1' | 'p2';\ntype ProductId = `id-${Products}-${Status}`; // \"id-p1-active\" | \"id-p1-inactive\" | \"id-p2-active\" | \"id-p2-inactive\"\n```\n\n## Tipo any\n\nO tipo `any` é um tipo especial (supertipo universal) que pode ser usado para representar qualquer tipo de valor (primitivos, objetos, arrays, funções, erros, símbolos). É frequentemente usado em situações onde o tipo de um valor não é conhecido em tempo de compilação, ou ao trabalhar com valores de APIs externas ou bibliotecas que não possuem tipagens TypeScript.\n\nAo utilizar o tipo `any`, você está indicando ao compilador TypeScript que os valores devem ser representados sem quaisquer limitações. Para maximizar a segurança de tipo em seu código, considere o seguinte:\n\n* Limite o uso de `any` a casos específicos onde o tipo é verdadeiramente desconhecido.\n* Não retorne tipos `any` de uma função, pois isso enfraquece a segurança de tipo no código que a utiliza.\n* Em vez de `any`, use `@ts-ignore` se precisar silenciar o compilador.\n\n```typescript\nlet value: any;\nvalue = true; // Válido\nvalue = 7; // Válido\n```\n\n## Tipo unknown\n\nNo TypeScript, o tipo `unknown` representa um valor que é de um tipo desconhecido. Ao contrário do tipo `any`, que permite qualquer tipo de valor, o `unknown` exige uma verificação de tipo ou asserção antes de poder ser usado de uma maneira específica, portanto nenhuma operação é permitida em um `unknown` sem primeiro asseverar ou estreitar para um tipo mais específico.\n\nO tipo `unknown` só é atribuível a si mesmo e ao tipo `any`; é uma alternativa segura em termos de tipos ao `any`.\n\n<!-- skip -->\n```typescript\nlet value: unknown;\n\nlet value1: unknown = value; // Válido\nlet value2: any = value; // Válido\nlet value3: boolean = value; // Inválido\nlet value4: number = value; // Inválido\n```\n\n```typescript\nconst add = (a: unknown, b: unknown): number | undefined =>\n    typeof a === 'number' && typeof b === 'number' ? a + b : undefined;\nconsole.log(add(1, 2)); // 3\nconsole.log(add('x', 2)); // undefined\n```\n\n## Tipo void\n\nO tipo `void` é usado para indicar que uma função não retorna um valor.\n\n```typescript\nconst sayHello = (): void => {\n    console.log('Hello!');\n};\n```\n\n## Tipo never\n\nO tipo `never` representa valores que nunca ocorrem. É usado para denotar funções ou expressões que nunca retornam ou que lançam um erro.\n\nPor exemplo, um loop infinito:\n\n```typescript\nconst infiniteLoop = (): never => {\n    while (true) {\n        // faz algo\n    }\n};\n```\n\nLançando um erro:\n\n```typescript\nconst throwError = (message: string): never => {\n    throw new Error(message);\n};\n```\n\nO tipo `never` é útil para garantir a segurança de tipos e capturar possíveis erros em seu código. Ele ajuda o TypeScript a analisar e inferir tipos mais precisos quando usado em combinação com outros tipos e instruções de fluxo de controle, por exemplo:\n\n```typescript\ntype Direction = 'up' | 'down';\nconst move = (direction: Direction): void => {\n    switch (direction) {\n        case 'up':\n            // move para cima\n            break;\n        case 'down':\n            // move para baixo\n            break;\n        default:\n            const exhaustiveCheck: never = direction;\n            throw new Error(`Direção não tratada: ${exhaustiveCheck}`);\n    }\n};\n```\n\n## Interface e Type\n\n### Sintaxe Comum\n\nNo TypeScript, as interfaces definem a estrutura de objetos, especificando os nomes e tipos de propriedades ou métodos que um objeto deve possuir. A sintaxe comum para definir uma interface no TypeScript é a seguinte:\n\n<!-- skip -->\n```typescript\ninterface InterfaceName {\n    property1: Type1;\n    // ...\n    method1(arg1: ArgType1, arg2: ArgType2): ReturnType;\n    // ...\n}\n```\n\nDa mesma forma para a definição de tipo (type):\n\n<!-- skip -->\n```typescript\ntype TypeName = {\n    property1: Type1;\n    // ...\n    method1(arg1: ArgType1, arg2: ArgType2): ReturnType;\n    // ...\n};\n```\n\n`interface InterfaceName` ou `type TypeName`: Define o nome da interface/tipo.\n`property1`: `Type1`: Especifica as propriedades da interface junto com seus tipos correspondentes. Múltiplas propriedades podem ser definidas, cada uma separada por um ponto e vírgula.\n`method1(arg1: ArgType1, arg2: ArgType2): ReturnType;`: Especifica os métodos da interface. Métodos são definidos com seus nomes, seguidos por uma lista de parâmetros entre parênteses e o tipo de retorno. Múltiplos métodos podem ser definidas, cada uma separada por um ponto e vírgula.\n\nExemplo de interface:\n\n```typescript\ninterface Person {\n    name: string;\n    age: number;\n    greet(): void;\n}\n```\n\nExemplo de tipo:\n\n```typescript\ntype TypeName = {\n    property1: string;\n    method1(arg1: string, arg2: string): string;\n};\n```\n\nNo TypeScript, os tipos são usados para definir a forma dos dados e impor a verificação de tipos. Existem várias sintaxes comuns para definir tipos, dependendo do caso de uso específico. Aqui estão alguns exemplos:\n\n### Tipos Básicos\n\n```typescript\nlet myNumber: number = 123; // tipo number\nlet myBoolean: boolean = true; // tipo boolean\nlet myArray: string[] = ['a', 'b']; // array de strings\nlet myTuple: [string, number] = ['a', 123]; // tupla\n```\n\n### Objetos e Interfaces\n\n```typescript\nconst x: { name: string; age: number } = { name: 'Simon', age: 7 };\n```\n\n### Tipos União e Interseção\n\n```typescript\ntype MyType = string | number; // Tipo União (Union type)\nlet myUnion: MyType = 'hello'; // Pode ser uma string\nmyUnion = 123; // Ou um número\n\ntype TypeA = { name: string };\ntype TypeB = { age: number };\ntype CombinedType = TypeA & TypeB; // Tipo Interseção (Intersection type)\nlet myCombined: CombinedType = { name: 'John', age: 25 }; // Objeto com as propriedades name e age\n```\n\n## Tipos Primitivos Integrados\n\nO TypeScript possui vários tipos primitivos integrados que podem ser usados para definir variáveis, parâmetros de função e tipos de retorno:\n\n* `number`: Representa valores numéricos, incluindo inteiros e números de ponto flutuante.\n* `string`: Representa dados textuais.\n* `boolean`: Representa valores lógicos, que podem ser true ou false.\n* `null`: Representa a ausência de um valor.\n* `undefined`: Representa um valor que não foi atribuído ou não foi definido.\n* `symbol`: Representa um identificador único. Symbols são normalmente usados como chaves para propriedades de objetos.\n* `bigint`: Representa inteiros de precisão arbitrária.\n* `any`: Representa um tipo dinâmico ou desconhecido. Variáveis do tipo any podem conter valores de qualquer tipo e ignoram a verificação de tipos.\n* `void`: Representa a ausência de qualquer tipo. É comumente usado como o tipo de retorno de funções que não retornam um valor.\n* `never`: Representa um tipo para valores que nunca ocorrem. É normalmente usado como o tipo de retorno de funções que lançam um erro ou entram em um loop infinito.\n\n## Objetos JS Integrados Comuns\n\nO TypeScript é um superconjunto do JavaScript e inclui todos os objetos integrados do JavaScript comumente usados. Você pode encontrar uma lista extensa desses objetos no site de documentação da Mozilla Developer Network (MDN):\n[https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects](https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects)\n\nAqui está uma lista de alguns objetos integrados do JavaScript comumente usados:\n\n* Function\n* Object\n* Boolean\n* Error\n* Number\n* BigInt\n* Math\n* Date\n* String\n* RegExp\n* Array\n* Map\n* Set\n* Promise\n* Intl\n\n## Sobrecargas (Overloads)\n\nAs sobrecargas de função (function overloads) no TypeScript permitem definir múltiplas assinaturas para um mesmo nome de função, permitindo que as funções sejam chamadas de diversas maneiras. Aqui está um exemplo:\n\n```typescript\n// Sobrecargas\nfunction sayHi(name: string): string;\nfunction sayHi(names: string[]): string[];\n\n// Implementação\nfunction sayHi(name: unknown): unknown {\n    if (typeof name === 'string') {\n        return `Hi, ${name}!`;\n    } else if (Array.isArray(name)) {\n        return name.map(name => `Hi, ${name}!`);\n    }\n    throw new Error('Valor inválido');\n}\n\nsayHi('xx'); // Válido\nsayHi(['aa', 'bb']); // Válido\n```\n\nAqui está outro exemplo de uso de sobrecargas de função dentro de uma `class`:\n\n```typescript\nclass Greeter {\n    message: string;\n\n    constructor(message: string) {\n        this.message = message;\n    }\n\n    // sobrecarga\n    sayHi(name: string): string;\n    sayHi(names: string[]): ReadonlyArray<string>;\n\n    // implementação\n    sayHi(name: unknown): unknown {\n        if (typeof name === 'string') {\n            return `${this.message}, ${name}!`;\n        } else if (Array.isArray(name)) {\n            return name.map(name => `${this.message}, ${name}!`);\n        }\n        throw new Error('o valor é inválido');\n    }\n}\nconsole.log(new Greeter('Hello').sayHi('Simon'));\n```\n\n## Mesclagem e Extensão\n\nMesclagem (merging) e extensão (extension) referem-se a dois conceitos diferentes relacionados ao trabalho com tipos e interfaces.\n\nA mesclagem permite combinar várias declarações do mesmo nome em uma única definição, por exemplo, quando você define uma interface com o mesmo nome várias vezes:\n\n```typescript\ninterface X {\n    a: string;\n}\n\ninterface X {\n    b: number;\n}\n\nconst person: X = {\n    a: 'a',\n    b: 7,\n};\n```\n\nA extensão refere-se à capacidade de estender ou herdar de tipos ou interfaces existentes para criar novos. É um mecanismo para adicionar propriedades ou métodos adicionais a um tipo existente sem modificar sua definição original. Exemplo:\n\n```typescript\ninterface Animal {\n    name: string;\n    eat(): void;\n}\n\ninterface Bird extends Animal {\n    sing(): void;\n}\n\nconst dog: Bird = {\n    name: 'Bird 1',\n    eat() {\n        console.log('Comendo');\n    },\n    sing() {\n        console.log('Cantando');\n    },\n};\n```\n\n## Diferenças entre Type e Interface\n\nMesclagem de declarações (aumento):\n\nAs interfaces suportam a mesclagem de declarações, o que significa que você pode definir várias interfaces com o mesmo nome, e o TypeScript as mesclará em uma única interface com as propriedades e métodos combinados. Por outro lado, os tipos (types) não suportam a mesclagem de declarações. Isso pode ser útil quando você deseja adicionar funcionalidades extras ou personalizar tipos existentes sem modificar as definições originais ou corrigir tipos ausentes ou incorretos.\n\n```typescript\ninterface A {\n    x: string;\n}\ninterface A {\n    y: string;\n}\nconst j: A = {\n    x: 'xx',\n    y: 'yy',\n};\n```\n\nEstendendo outros tipos/interfaces:\n\nTanto tipos quanto interfaces podem estender outros tipos/interfaces, mas a sintaxe é diferente. Com as interfaces, você usa a palavra-chave `extends` para herdar propriedades e métodos de outras interfaces. No entanto, uma interface não pode estender um tipo complexo, como um tipo união.\n\n```typescript\ninterface A {\n    x: string;\n    y: number;\n}\ninterface B extends A {\n    z: string;\n}\nconst car: B = {\n    x: 'x',\n    y: 123,\n    z: 'z',\n};\n```\n\nPara tipos, você usa o operador `&` para combinar múltiplos tipos em um único tipo (interseção).\n\n```typescript\ninterface A {\n    x: string;\n    y: number;\n}\n\ntype B = A & {\n    j: string;\n};\n\nconst c: B = {\n    x: 'x',\n    y: 123,\n    j: 'j',\n};\n```\n\nTipos União e Interseção:\n\nOs tipos (types) são mais flexíveis quando se trata de definir Tipos União e Interseção. Com a palavra-chave `type`, você pode criar facilmente tipos união usando o operador `|` e tipos interseção usando o operador `&`. Embora as interfaces também possam representar tipos união indiretamente, elas não possuem suporte integrado para tipos interseção.\n\n```typescript\ntype Department = 'dep-x' | 'dep-y'; // União\n\ntype Person = {\n    name: string;\n    age: number;\n};\n\ntype Employee = {\n    id: number;\n    department: Department;\n};\n\ntype EmployeeInfo = Person & Employee; // Interseção\n```\n\nExemplo com interfaces:\n\n```typescript\ninterface A {\n    x: 'x';\n}\ninterface B {\n    y: 'y';\n}\n\ntype C = A | B; // União de interfaces\n```\n\n## Classes\n\n### Sintaxe Comum de Classes\n\nA palavra-chave `class` é usada no TypeScript para definir uma classe. Abaixo, você pode ver um exemplo:\n\n```typescript\nclass Person {\n    private name: string;\n    private age: number;\n    constructor(name: string, age: number) {\n        this.name = name;\n        this.age = age;\n    }\n    public sayHi(): void {\n        console.log(\n            `Olá, meu nome é ${this.name} e eu tenho ${this.age} anos.`\n        );\n    }\n}\n```\n\nA palavra-chave `class` é usada para definir uma classe chamada \"Person\".\n\nA classe possui duas propriedades privadas: name do tipo `string` e age do tipo `number`.\n\nO construtor é definido usando a palavra-chave `constructor`. Ele recebe name e age como parâmetros e os atribui às propriedades correspondentes.\n\nA classe possui um método `public` chamado `sayHi` que registra uma mensagem de saudação.\n\nPara criar uma instância de uma classe no TypeScript, você pode usar a palavra-chave `new` seguida pelo nome da classe, seguida de parênteses `()`. Por exemplo:\n\n<!-- skip -->\n```typescript\nconst myObject = new Person('John Doe', 25);\nmyObject.sayHi(); // Saída: Olá, meu nome é John Doe e eu tenho 25 anos.\n```\n\n### Construtor\n\nOs construtores são métodos especiais dentro de uma classe que são usados para inicializar as propriedades do objeto quando uma instância da classe é criada.\n\n```typescript\nclass Person {\n    public name: string;\n    public age: number;\n\n    constructor(name: string, age: number) {\n        this.name = name;\n        this.age = age;\n    }\n\n    sayHello() {\n        console.log(\n            `Olá, meu nome é ${this.name} e eu tenho ${this.age} anos.`\n        );\n    }\n}\n\nconst john = new Person('Simon', 17);\njohn.sayHello();\n```\n\nÉ possível sobrecarregar um construtor usando a seguinte sintaxe:\n\n```typescript\ntype Sex = 'm' | 'f';\n\nclass Person {\n    name: string;\n    age: number;\n    sex: Sex;\n\n    constructor(name: string, age: number, sex?: Sex);\n    constructor(name: string, age: number, sex: Sex) {\n        this.name = name;\n        this.age = age;\n        this.sex = sex ?? 'm';\n    }\n}\n\nconst p1 = new Person('Simon', 17);\nconst p2 = new Person('Alice', 22, 'f');\n```\n\nNo TypeScript, é possível definir múltiplas sobrecargas de construtor, mas você pode ter apenas uma implementação que deve ser compatível com todas as sobrecargas, o que pode ser alcançado usando um parâmetro opcional.\n\n```typescript\nclass Person {\n    name: string;\n    age: number;\n\n    constructor();\n    constructor(name: string);\n    constructor(name: string, age: number);\n    constructor(name?: string, age?: number) {\n        this.name = name ?? 'Desconhecido';\n        this.age = age ?? 0;\n    }\n\n    displayInfo() {\n        console.log(`Nome: ${this.name}, Idade: ${this.age}`);\n    }\n}\n\nconst person1 = new Person();\nperson1.displayInfo(); // Nome: Desconhecido, Idade: 0\n\nconst person2 = new Person('John');\nperson2.displayInfo(); // Nome: John, Idade: 0\n\nconst person3 = new Person('Jane', 25);\nperson3.displayInfo(); // Nome: Jane, Idade: 25\n```\n\n### Construtores Privados e Protegidos\n\nNo TypeScript, os construtores podem ser marcados como privados ou protegidos, o que restringe sua acessibilidade e uso.\n\nConstrutores Privados (Private Constructors):\nPodem ser chamados apenas dentro da própria classe. Construtores privados são frequentemente usados em cenários onde você deseja impor um padrão singleton ou restringir a criação de instâncias a um método factual dentro da classe.\n\nConstrutores Protegidos (Protected Constructors):\nConstrutores protegidos são úteis quando você deseja criar uma classe base que não deve ser instanciada diretamente, mas pode ser estendida por subclasses.\n\n```typescript\nclass BaseClass {\n    protected constructor() {}\n}\n\nclass DerivedClass extends BaseClass {\n    private value: number;\n\n    constructor(value: number) {\n        super();\n        this.value = value;\n    }\n}\n\n// Tentar instanciar a classe base diretamente resultará em erro\n// const baseObj = new BaseClass(); // Erro: O construtor da classe 'BaseClass' é protegido.\n\n// Criar uma instância da classe derivada\nconst derivedObj = new DerivedClass(10);\n```\n\n### Modificadores de Acesso\n\nModificadores de Acesso `private`, `protected` e `public` são usados para controlar a visibilidade e acessibilidade dos membros da classe, como propriedades e métodos, em classes TypeScript. Esses modificadores são essenciais para impor o encapsulamento e estabelecer limites para acessar e modificar o estado interno de uma classe.\n\nO modificador `private` restringe o acesso ao membro da classe apenas dentro da classe que o contém.\n\nO modificador `protected` permite o acesso ao membro da classe dentro da classe que o contém e suas classes derivadas.\n\nO modificador `public` fornece acesso irrestrito ao membro da classe, permitindo que ele seja acessado de qualquer lugar.\n\n### Get e Set\n\nGetters e setters são métodos especiais que permitem definir comportamentos personalizados de acesso e modificação para propriedades de classe. Eles permitem encapsular o estado interno de um objeto e fornecer lógica adicional ao obter ou definir os valores das propriedades.\nNo TypeScript, os getters e setters são definidos usando as palavras-chave `get` e `set`, respectivamente. Aqui está um exemplo:\n\n```typescript\nclass MyClass {\n    private _myProperty: string;\n\n    constructor(value: string) {\n        this._myProperty = value;\n    }\n    get myProperty(): string {\n        return this._myProperty;\n    }\n    set myProperty(value: string) {\n        this._myProperty = value;\n    }\n}\n```\n\n### Auto-acessores em Classes\n\nO TypeScript versão 4.9 adiciona suporte para auto-acessores (auto-accessors), um recurso futuro do ECMAScript. Eles se assemelham a propriedades de classe, mas são declarados com a palavra-chave \"accessor\".\n\n```typescript\nclass Animal {\n    accessor name: string;\n\n    constructor(name: string) {\n        this.name = name;\n    }\n}\n```\n\nOs auto-acessores são transformados em acessores `get` e `set` privados, operando em uma propriedade inacessível.\n\n<!-- skip -->\n```typescript\nclass Animal {\n    #__name: string;\n\n    get name() {\n        return this.#__name;\n    }\n    set name(value: string) {\n        this.#__name = name;\n    }\n\n    constructor(name: string) {\n        this.name = name;\n    }\n}\n```\n\n### this\n\nNo TypeScript, a palavra-chave `this` refere-se à instância atual de uma classe dentro de seus métodos ou construtores. Ela permite acessar e modificar as propriedades e métodos da classe de dentro de seu próprio escopo.\nFornece uma maneira de acessar e manipular o estado interno de um objeto dentro de seus próprios métodos.\n\n```typescript\nclass Person {\n    private name: string;\n    constructor(name: string) {\n        this.name = name;\n    }\n    public introduce(): void {\n        console.log(`Olá, meu nome é ${this.name}.`);\n    }\n}\n\nconst person1 = new Person('Alice');\nperson1.introduce(); // Olá, meu nome é Alice.\n```\n\n### Propriedades de Parâmetro\n\nAs propriedades de parâmetro permitem declarar e inicializar propriedades de classe diretamente dentro dos parâmetros do construtor, evitando o código repetitivo (boilerplate). Exemplo:\n\n```typescript\nclass Person {\n    constructor(\n        private name: string,\n        public age: number\n    ) {\n        // As palavras-chave \"private\" e \"public\" no construtor\n        // declaram e inicializam automaticamente as propriedades de classe correspondentes.\n    }\n    public introduce(): void {\n        console.log(\n            `Olá, meu nome é ${this.name} e eu tenho ${this.age} anos.`\n        );\n    }\n}\nconst person = new Person('Alice', 25);\nperson.introduce();\n```\n\n### Classes Abstratas\n\nClasses Abstratas são usadas no TypeScript principalmente para herança; elas fornecem uma maneira de definir propriedades e métodos comuns que podem ser herdados por subclasses.\nIsso é útil quando você deseja definir um comportamento comum e garantir que as subclasses implementem certos métodos. Elas fornecem uma maneira de criar uma hierarquia de classes onde a classe base abstrata fornece uma interface compartilhada e funcionalidade comum para as subclasses.\n\n```typescript\nabstract class Animal {\n    protected name: string;\n\n    constructor(name: string) {\n        this.name = name;\n    }\n\n    abstract makeSound(): void;\n}\n\nclass Cat extends Animal {\n    makeSound(): void {\n        console.log(`${this.name} mia (meows).`);\n    }\n}\n\nconst cat = new Cat('Whiskers');\ncat.makeSound(); // Saída: Whiskers mia (meows).\n```\n\n### Com Genéricos\n\nClasses com genéricos permitem definir classes reutilizáveis que podem trabalhar com diferentes tipos.\n\n```typescript\nclass Container<T> {\n    private item: T;\n\n    constructor(item: T) {\n        this.item = item;\n    }\n\n    getItem(): T {\n        return this.item;\n    }\n\n    setItem(item: T): void {\n        this.item = item;\n    }\n}\n\nconst container1 = new Container<number>(42);\nconsole.log(container1.getItem()); //  42\n\nconst container2 = new Container<string>('Olá');\ncontainer2.setItem('Mundo');\nconsole.log(container2.getItem()); // Mundo\n```\n\n### Decoradores (Decorators)\n\nOs decoradores fornecem um mecanismo para adicionar metadados, modificar comportamentos, validar ou estender a funcionalidade do elemento alvo. São funções que são executadas em tempo de execução. Múltiplos decoradores podem ser aplicados a uma declaração.\n\nOs decoradores são recursos experimentais, e os exemplos a seguir são compatíveis apenas com a versão 5 do TypeScript ou superior usando ES6.\n\nPara versões do TypeScript anteriores à 5, eles devem ser habilitados usando a propriedade `experimentalDecorators` em seu `tsconfig.json` ou usando `--experimentalDecorators` na sua linha de comando (mas o exemplo a seguir não funcionará).\n\nAlguns dos casos de uso comuns para decoradores incluem:\n\n* Observar mudanças de propriedade.\n* Observar chamadas de métodos.\n* Adicionar propriedades ou métodos extras.\n* Validação em tempo de execução.\n* Serialização e desserialização automática.\n* Registro (Logging).\n* Autorização e autenticação.\n* Proteção contra erros (Error guarding).\n\nNota: Decoradores para a versão 5 não permitem decorar parâmetros.\n\nTipos de decoradores:\n\n#### Decoradores de Classe (Class Decorators)\n\nOs Decoradores de Classe são úteis para estender uma classe existente, como adicionar propriedades ou métodos, ou coletar instâncias de uma classe. No exemplo a seguir, adicionamos um método `toString` que converte a classe em uma representação de string.\n\n```typescript\ntype Constructor<T = {}> = new (...args: any[]) => T;\n\nfunction toString<Class extends Constructor>(\n    Value: Class,\n    context: ClassDecoratorContext<Class>\n) {\n    return class extends Value {\n        constructor(...args: any[]) {\n            super(...args);\n            console.log(JSON.stringify(this));\n            console.log(JSON.stringify(context));\n        }\n    };\n}\n\n@toString\nclass Person {\n    name: string;\n\n    constructor(name: string) {\n        this.name = name;\n    }\n\n    greet() {\n        return 'Hello, ' + this.name;\n    }\n}\nconst person = new Person('Simon');\n/* Registra:\n{\"name\":\"Simon\"}\n{\"kind\":\"class\",\"name\":\"Person\"}\n*/\n```\n\n#### Decorador de Propriedade (Property Decorator)\n\nOs decoradores de propriedade são úteis para modificar o comportamento de uma propriedade, como alterar os valores de inicialização. No código a seguir, temos um script que define uma propriedade para estar sempre em letras maiúsculas:\n\n```typescript\nfunction upperCase<T>(\n    target: undefined,\n    context: ClassFieldDecoratorContext<T, string>\n) {\n    return function (this: T, value: string) {\n        return value.toUpperCase();\n    };\n}\n\nclass MyClass {\n    @upperCase\n    prop1 = 'hello!';\n}\n\nconsole.log(new MyClass().prop1); // Registra: HELLO!\n```\n\n#### Decorador de Método (Method Decorator)\n\nOs decoradores de método permitem alterar ou aprimorar o comportamento dos métodos. Abaixo está um exemplo de um registrador (logger) simples:\n\n```typescript\nfunction log<This, Args extends any[], Return>(\n    target: (this: This, ...args: Args) => Return,\n    context: ClassMethodDecoratorContext<\n        This,\n        (this: This, ...args: Args) => Return\n    >\n) {\n    const methodName = String(context.name);\n\n    function replacementMethod(this: This, ...args: Args): Return {\n        console.log(`LOG: Entrando no método '${methodName}'.`);\n        const result = target.call(this, ...args);\n        console.log(`LOG: Saindo do método '${methodName}'.`);\n        return result;\n    }\n\n    return replacementMethod;\n}\n\nclass MyClass {\n    @log\n    sayHello() {\n        console.log('Hello!');\n    }\n}\n\nnew MyClass().sayHello();\n```\n\nIsso registra:\n\n```shell\nLOG: Entrando no método 'sayHello'.\nHello!\nLOG: Saindo do método 'sayHello'.\n```\n\n#### Decoradores de Getter e Setter\n\nDecoradores de getter e setter permitem alterar ou aprimorar o comportamento dos acessores de classe. Eles são úteis, por exemplo, para validar atribuições de propriedades. Aqui está um exemplo simples de um decorador de getter:\n\n```typescript\nfunction range<This, Return extends number>(min: number, max: number) {\n    return function (\n        target: (this: This) => Return,\n        context: ClassGetterDecoratorContext<This, Return>\n    ) {\n        return function (this: This): Return {\n            const value = target.call(this);\n            if (value < min || value > max) {\n                throw 'Invalid';\n            }\n            Object.defineProperty(this, context.name, {\n                value,\n                enumerable: true,\n            });\n            return value;\n        };\n    };\n}\n\nclass MyClass {\n    private _value = 0;\n\n    constructor(value: number) {\n        this._value = value;\n    }\n    @range(1, 100)\n    get getValue(): number {\n        return this._value;\n    }\n}\n\nconst obj = new MyClass(10);\nconsole.log(obj.getValue); // Válido: 10\n\nconst obj2 = new MyClass(999);\nconsole.log(obj2.getValue); // Lança: Invalid!\n```\n\n#### Metadados de Decorador (Decorator Metadata)\n\nOs Metadados de Decorador simplificam o processo para que os decoradores apliquem e utilizem metadados em qualquer classe. Eles podem acessar uma nova propriedade de metadados no objeto de contexto, que pode servir como uma chave para primitivos e objetos.\nAs informações de metadados podem ser acessadas na classe via `Symbol.metadata`.\n\nOs metadados podem ser usados para vários fins, como depuração, serialização ou injeção de dependência com decoradores.\n\n```typescript\n//@ts-ignore\nSymbol.metadata ??= Symbol('Symbol.metadata'); // Polify simples\n\ntype Context =\n    | ClassFieldDecoratorContext\n    | ClassAccessorDecoratorContext\n    | ClassMethodDecoratorContext; // O contexto contém os metadados da propriedade: DecoratorMetadata\n\nfunction setMetadata(_target: any, context: Context) {\n    // Define o objeto de metadados com um valor primitivo\n    context.metadata[context.name] = true;\n}\n\nclass MyClass {\n    @setMetadata\n    a = 123;\n\n    @setMetadata\n    accessor b = 'b';\n\n    @setMetadata\n    fn() {}\n}\n\nconst metadata = MyClass[Symbol.metadata]; // Obtém as informações de metadados\n\nconsole.log(JSON.stringify(metadata)); // {\"bar\":true,\"baz\":true,\"foo\":true}\n```\n\n### Herança\n\nHerança refere-se ao mecanismo pelo qual uma classe pode herdar propriedades e métodos de outra classe, conhecida como classe base ou superclasse. A classe derivada, também chamada de classe filha ou subclasse, pode estender e especializar a funcionalidade da classe base adicionando novas propriedades e métodos ou substituindo (overriding) os existentes.\n\n```typescript\nclass Animal {\n    name: string;\n\n    constructor(name: string) {\n        this.name = name;\n    }\n\n    speak(): void {\n        console.log('O animal faz um som');\n    }\n}\n\nclass Dog extends Animal {\n    breed: string;\n\n    constructor(name: string, breed: string) {\n        super(name);\n        this.breed = breed;\n    }\n\n    speak(): void {\n        console.log('Woof! Woof!');\n    }\n}\n\n// Cria uma instância da classe base\nconst animal = new Animal('Animal Genérico');\nanimal.speak(); // O animal faz um som\n\n// Cria uma instância da classe derivada\nconst dog = new Dog('Max', 'Labrador');\ndog.speak(); // Woof! Woof!\"\n```\n\nO TypeScript não suporta herança múltipla no sentido tradicional e, em vez disso, permite a herança de uma única classe base.\nO TypeScript suporta múltiplas interfaces. Uma interface pode definir um contrato para a estrutura de um objeto, e uma classe pode implementar múltiplas interfaces. Isso permite que uma classe herde comportamento e estrutura de múltiplas fontes.\n\n```typescript\ninterface Flyable {\n    fly(): void;\n}\n\ninterface Swimmable {\n    swim(): void;\n}\n\nclass FlyingFish implements Flyable, Swimmable {\n    fly() {\n        console.log('Voando...');\n    }\n\n    swim() {\n        console.log('Nadando...');\n    }\n}\n\nconst flyingFish = new FlyingFish();\nflyingFish.fly();\nflyingFish.swim();\n```\n\nA palavra-chave `class` no TypeScript, assim como no JavaScript, é frequentemente chamada de açúcar sintático (syntactic sugar). Ela foi introduzida no ECMAScript 2015 (ES6) para oferecer uma sintaxe mais familiar para criar e trabalhar com objetos de maneira baseada em classes. No entanto, é importante notar que o TypeScript, sendo um superconjunto do JavaScript, acaba sendo compilado para JavaScript, que permanece baseado em protótipos em seu núcleo.\n\n### Estáticos (Statics)\n\nO TypeScript possui membros estáticos. Para acessar os membros estáticos de uma classe, você pode usar o nome da classe seguido por um ponto, sem a necessidade de criar um objeto.\n\n```typescript\nclass OfficeWorker {\n    static memberCount: number = 0;\n\n    constructor(private name: string) {\n        OfficeWorker.memberCount++;\n    }\n}\n\nconst w1 = new OfficeWorker('James');\nconst w2 = new OfficeWorker('Simon');\nconst total = OfficeWorker.memberCount;\nconsole.log(total); // 2\n```\n\n### Inicialização de Propriedade\n\nExistem várias maneiras de inicializar propriedades de uma classe no TypeScript:\n\nEm linha (Inline):\n\nNo exemplo a seguir, esses valores iniciais serão usados quando uma instância da classe for criada.\n\n```typescript\nclass MyClass {\n    property1: string = 'valor padrão';\n    property2: number = 42;\n}\n```\n\nNo construtor:\n\n```typescript\nclass MyClass {\n    property1: string;\n    property2: number;\n\n    constructor() {\n        this.property1 = 'valor padrão';\n        this.property2 = 42;\n    }\n}\n```\n\nUsando parâmetros do construtor:\n\n```typescript\nclass MyClass {\n    constructor(\n        private property1: string = 'valor padrão',\n        public property2: number = 42\n    ) {\n        // Não há necessidade de atribuir os valores às propriedades explicitamente.\n    }\n    log() {\n        console.log(this.property2);\n    }\n}\nconst x = new MyClass();\nx.log();\n```\n\n### Sobrecarga de Método\n\nA sobrecarga de método permite que uma classe tenha múltiplos métodos com o mesmo nome, mas diferentes tipos de parâmetros ou um número diferente de parâmetros. Isso nos permite chamar um método de diferentes maneiras com base nos argumentos passados.\n\n```typescript\nclass MyClass {\n    add(a: number, b: number): number; // Assinatura de sobrecarga 1\n    add(a: string, b: string): string; // Assinatura de sobrecarga 2\n\n    add(a: number | string, b: number | string): number | string {\n        if (typeof a === 'number' && typeof b === 'number') {\n            return a + b;\n        }\n        if (typeof a === 'string' && typeof b === 'string') {\n            return a.concat(b);\n        }\n        throw new Error('Argumentos inválidos');\n    }\n}\n\nconst r = new MyClass();\nconsole.log(r.add(10, 5)); // Registra 15\n```\n\n## Genéricos (Generics)\n\nOs genéricos permitem que você crie componentes e funções reutilizáveis que podem trabalhar com múltiplos tipos. Com os genéricos, você pode parametrizar tipos, funções e interfaces, permitindo que operem em diferentes tipos sem especificá-los explicitamente de antemão.\n\nOs genéricos permitem tornar o código mais flexível e reutilizável.\n\n### Tipo Genérico\n\nPara definir um tipo genérico, você usa colchetes angulares (`<>`) para especificar os parâmetros de tipo, por exemplo:\n\n```typescript\nfunction identity<T>(arg: T): T {\n    return arg;\n}\nconst a = identity('x');\nconst b = identity(123);\n\nconst getLen = <T,>(data: ReadonlyArray<T>) => data.length;\nconst len = getLen([1, 2, 3]);\n```\n\n### Classes Genéricas\n\nOs genéricos também podem ser aplicados a classes, permitindo que trabalhem com múltiplos tipos por meio de parâmetros de tipo. Isso é útil para criar definições de classe reutilizáveis que podem operar em diferentes tipos de dados mantendo a segurança de tipo.\n\n```typescript\nclass Container<T> {\n    private item: T;\n\n    constructor(item: T) {\n        this.item = item;\n    }\n\n    getItem(): T {\n        return this.item;\n    }\n}\n\nconst numberContainer = new Container<number>(123);\nconsole.log(numberContainer.getItem()); // 123\n\nconst stringContainer = new Container<string>('hello');\nconsole.log(stringContainer.getItem()); // hello\n```\n\n### Restrições Genéricas (Generic Constraints)\n\nParâmetros genéricos podem ser restringidos usando a palavra-chave `extends` seguida por um tipo ou interface que o parâmetro de tipo deve satisfazer.\n\nNo exemplo a seguir, T deve conter uma propriedade `length` para ser válido:\n\n<!-- skip -->\n```typescript\nconst printLen = <T extends { length: number }>(value: T): void => {\n    console.log(value.length);\n};\n\nprintLen('Hello'); // 5\nprintLen([1, 2, 3]); // 3\nprintLen({ length: 10 }); // 10\nprintLen(123); // Inválido\n```\n\nUm recurso interessante de genéricos introduzido na versão 3.4 RC é a inferência de tipo de função de ordem superior, que introduziu argumentos de tipo genérico propagados:\n\n```typescript\ndeclare function pipe<A extends any[], B, C>(\n    ab: (...args: A) => B,\n    bc: (b: B) => C\n): (...args: A) => C;\n\ndeclare function list<T>(a: T): T[];\ndeclare function box<V>(x: V): { value: V };\n\nconst listBox = pipe(list, box); // <T>(a: T) => { value: T[] }\nconst boxList = pipe(box, list); // <V>(x: V) => { value: V }[]\n```\n\nEssa funcionalidade permite uma programação de estilo sem pontos (pointfree) com segurança de tipo mais fácil, o que é comum na programação funcional.\n\n### Estreitamento Contextual Genérico\n\nO estreitamento contextual (contextual narrowing) para genéricos é o mecanismo no TypeScript que permite ao compilador estreitar o tipo de um parâmetro genérico com base no contexto em que é usado. É útil ao trabalhar com tipos genéricos em declarações condicionais:\n\n```typescript\nfunction process<T>(value: T): void {\n    if (typeof value === 'string') {\n        // O valor é estreitado para o tipo 'string'\n        console.log(value.length);\n    } else if (typeof value === 'number') {\n        // O valor é estreitado para o tipo 'number'\n        console.log(value.toFixed(2));\n    }\n}\n\nprocess('hello'); // 5\nprocess(3.14159); // 3.14\n```\n\n## Tipos Estruturais Apagados\n\nNo TypeScript, os objetos não precisam corresponder a um tipo exato e específico. Por exemplo, se criarmos um objeto que satisfaça os requisitos de uma interface, podemos utilizar esse objeto em locais onde essa interface é necessária, mesmo que não haja uma conexão explícita entre eles.\nExemplo:\n\n```typescript\ntype NameProp1 = {\n    prop1: string;\n};\n\nfunction log(x: NameProp1) {\n    console.log(x.prop1);\n}\n\nconst obj = {\n    prop2: 123,\n    prop1: 'Origin',\n};\n\nlog(obj); // Válido\n```\n\n## Namespacing\n\nNo TypeScript, os namespaces são usados para organizar o código em contêineres lógicos, evitando colisões de nomes e fornecendo uma maneira de agrupar códigos relacionados.\nO uso das palavras-chave `export` permite o acesso ao namespace em módulos externos.\n\n```typescript\nexport namespace MyNamespace {\n    export interface MyInterface1 {\n        prop1: boolean;\n    }\n    export interface MyInterface2 {\n        prop2: string;\n    }\n}\n\nconst a: MyNamespace.MyInterface1 = {\n    prop1: true,\n};\n```\n\n## Símbolos (Symbols)\n\nSímbolos são um tipo de dado primitivo que representa um valor imutável que é garantido ser globalmente único durante todo o tempo de execução do programa.\n\nSímbolos podem ser usados como chaves para propriedades de objetos e fornecem uma maneira de criar propriedades não enumeráveis.\n\n```typescript\nconst key1: symbol = Symbol('key1');\nconst key2: symbol = Symbol('key2');\n\nconst obj = {\n    [key1]: 'value 1',\n    [key2]: 'value 2',\n};\n\nconsole.log(obj[key1]); // value 1\nconsole.log(obj[key2]); // value 2\n```\n\nEm WeakMaps e WeakSets, símbolos agora são permitidos como chaves.\n\n## Diretivas Triple-Slash\n\nAs diretivas triple-slash são comentários especiais que fornecem instruções ao compilador sobre como processar um arquivo. Essas diretivas começam com três barras consecutivas (`///`) e são normalmente colocadas no topo de um arquivo TypeScript e não têm efeitos no comportamento em tempo de execução.\n\nAs diretivas triple-slash são usadas para referenciar dependências externas, especificar o comportamento de carregamento de módulos, habilitar/desabilitar certos recursos do compilador e muito mais. Alguns exemplos:\n\nReferenciando um arquivo de declaração:\n\n<!-- skip -->\n```typescript\n/// <reference path=\"caminho/para/arquivo/de/declaracao.d.ts\" />\n```\n\nIndicar o formato do módulo:\n\n<!-- skip -->\n```typescript\n/// <amd|commonjs|system|umd|es6|es2015|none>\n```\n\nHabilitar opções do compilador, no exemplo a seguir, o modo estrito:\n\n<!-- skip -->\n```typescript\n/// <strict|noImplicitAny|noUnusedLocals|noUnusedParameters>\n```\n\n## Manipulação de Tipos\n\n### Criando Tipos a partir de Tipos\n\nÉ possível criar novos tipos compondo, manipulando ou transformando tipos existentes.\n\nTipos Interseção (`&`):\n\nPermitem combinar múltiplos tipos em um único tipo:\n\n```typescript\ntype A = { foo: number };\ntype B = { bar: string };\ntype C = A & B; // Interseção de A e B\nconst obj: C = { foo: 42, bar: 'hello' };\n```\n\nTipos União (`|`):\n\nPermitem definir um tipo que pode ser um de vários tipos:\n\n```typescript\ntype Result = string | number;\nconst value1: Result = 'hello';\nconst value2: Result = 42;\n```\n\nTipos Mapeados:\n\nPermitem transformar as propriedades de um tipo existente para criar um novo tipo:\n\n```typescript\ntype Mutable<T> = {\n    readonly [P in keyof T]: T[P];\n};\ntype Person = {\n    name: string;\n    age: number;\n};\ntype ImmutablePerson = Mutable<Person>; // As propriedades tornam-se somente leitura\n```\n\nTipos Condicionais:\n\nPermitem criar tipos com base em algumas condições:\n\n```typescript\ntype ExtractParam<T> = T extends (param: infer P) => any ? P : never;\ntype MyFunction = (name: string) => number;\ntype ParamType = ExtractParam<MyFunction>; // string\n```\n\n### Tipos de Acesso Indexado (Indexed Access Types)\n\nNo TypeScript, é possível acessar e manipular os tipos de propriedades dentro de outro tipo usando um índice, `Type[Key]`.\n\n```typescript\ntype Person = {\n    name: string;\n    age: number;\n};\n\ntype AgeType = Person['age']; // number\n```\n\n```typescript\ntype MyTuple = [string, number, boolean];\ntype MyType = MyTuple[2]; // boolean\n```\n\n### Tipos Utilitários (Utility Types)\n\nVários tipos utilitários integrados podem ser usados para manipular tipos, abaixo uma lista dos mais comuns:\n\n#### Awaited\\<T\\>\n\nConstrói um tipo que descompacta recursivamente tipos Promise.\n\n```typescript\ntype A = Awaited<Promise<string>>; // string\n```\n\n#### Partial\\<T\\>\n\nConstrói um tipo com todas as propriedades de T definidas como opcionais.\n\n```typescript\ntype Person = {\n    name: string;\n    age: number;\n};\n\ntype A = Partial<Person>; // { name?: string | undefined; age?: number | undefined; }\n```\n\n#### Required\\<T\\>\n\nConstrói um tipo com todas as propriedades de T definidas como obrigatórias.\n\n```typescript\ntype Person = {\n    name?: string;\n    age?: number;\n};\n\ntype A = Required<Person>; // { name: string; age: number; }\n```\n\n#### Readonly\\<T\\>\n\nConstrói um tipo com todas as propriedades de T definidas como somente leitura.\n\n<!-- skip -->\n```typescript\ntype Person = {\n    name: string;\n    age: number;\n};\n\ntype A = Readonly<Person>;\n\nconst a: A = { name: 'Simon', age: 17 };\na.name = 'John'; // Inválido\n```\n\n#### Record\\<K, T\\>\n\nConstrói um tipo com um conjunto de propriedades K do tipo T.\n\n```typescript\ntype Product = {\n    name: string;\n    price: number;\n};\n\nconst products: Record<string, Product> = {\n    apple: { name: 'Apple', price: 0.5 },\n    banana: { name: 'Banana', price: 0.25 },\n};\n\nconsole.log(products.apple); // { name: 'Apple', price: 0.5 }\n```\n\n#### Pick\\<T, K\\>\n\nConstrói um tipo selecionando as propriedades especificadas K de T.\n\n```typescript\ntype Product = {\n    name: string;\n    price: number;\n};\n\ntype Price = Pick<Product, 'price'>; // { price: number; }\n```\n\n#### Omit\\<T, K\\>\n\nConstrói um tipo omitindo as propriedades especificadas K de T.\n\n```typescript\ntype Product = {\n    name: string;\n    price: number;\n};\n\ntype Name = Omit<Product, 'price'>; // { name: string; }\n```\n\n#### Exclude\\<T, U\\>\n\nConstrói um tipo excluindo todos os valores do tipo U de T.\n\n```typescript\ntype Union = 'a' | 'b' | 'c';\ntype MyType = Exclude<Union, 'a' | 'c'>; // b\n```\n\n#### Extract\\<T, U\\>\n\nConstrói um tipo extraindo todos os valores do tipo U de T.\n\n```typescript\ntype Union = 'a' | 'b' | 'c';\ntype MyType = Extract<Union, 'a' | 'c'>; // a | c\n```\n\n#### NonNullable\\<T\\>\n\nConstrói um tipo excluindo null e undefined de T.\n\n```typescript\ntype Union = 'a' | null | undefined | 'b';\ntype MyType = NonNullable<Union>; // 'a' | 'b'\n```\n\n#### Parameters\\<T\\>\n\nExtrai os tipos de parâmetros de um tipo de função T.\n\n```typescript\ntype Func = (a: string, b: number) => void;\ntype MyType = Parameters<Func>; // [a: string, b: number]\n```\n\n#### ConstructorParameters\\<T\\>\n\nExtrai os tipos de parâmetros de um tipo de função construtora T.\n\n```typescript\nclass Person {\n    constructor(\n        public name: string,\n        public age: number\n    ) {}\n}\ntype PersonConstructorParams = ConstructorParameters<typeof Person>; // [name: string, age: number]\nconst params: PersonConstructorParams = ['John', 30];\nconst person = new Person(...params);\nconsole.log(person); // Person { name: 'John', age: 30 }\n```\n\n#### ReturnType\\<T\\>\n\nExtrai o tipo de retorno de um tipo de função T.\n\n```typescript\ntype Func = (name: string) => number;\ntype MyType = ReturnType<Func>; // number\n```\n\n#### InstanceType\\<T\\>\n\nExtrai o tipo de instância de um tipo de classe T.\n\n```typescript\nclass Person {\n    name: string;\n\n    constructor(name: string) {\n        this.name = name;\n    }\n\n    sayHello() {\n        console.log(`Olá, meu nome é ${this.name}!`);\n    }\n}\n\ntype PersonInstance = InstanceType<typeof Person>;\n\nconst person: PersonInstance = new Person('John');\n\nperson.sayHello(); // Olá, meu nome é John!\n```\n\n#### ThisParameterType\\<T\\>\n\nExtrai o tipo do parâmetro 'this' de um tipo de função T.\n\n```typescript\ninterface Person {\n    name: string;\n    greet(this: Person): void;\n}\ntype PersonThisType = ThisParameterType<Person['greet']>; // Person\n```\n\n#### OmitThisParameter\\<T\\>\n\nRemove o parâmetro 'this' de um tipo de função T.\n\n```typescript\nfunction capitalize(this: String) {\n    return this[0].toUpperCase + this.substring(1).toLowerCase();\n}\n\ntype CapitalizeType = OmitThisParameter<typeof capitalize>; // () => string\n```\n\n#### ThisType\\<T\\>\n\nServe como um marcador para um tipo `this` contextual.\n\n<!-- skip -->\n```typescript\ntype Logger = {\n    log: (error: string) => void;\n};\n\nlet helperFunctions: { [name: string]: Function } & ThisType<Logger> = {\n    hello: function () {\n        this.log('some error'); // Válido, pois \"log\" faz parte de \"this\".\n        this.update(); // Inválido\n    },\n};\n```\n\n#### Uppercase\\<T\\>\n\nConverte para maiúsculas o nome do tipo de entrada T.\n\n```typescript\ntype MyType = Uppercase<'abc'>; // \"ABC\"\n```\n\n#### Lowercase\\<T\\>\n\nConverte para minúsculas o nome do tipo de entrada T.\n\n```typescript\ntype MyType = Lowercase<'ABC'>; // \"abc\"\n```\n\n#### Capitalize\\<T\\>\n\nColoca a primeira letra em maiúscula no nome do tipo de entrada T.\n\n```typescript\ntype MyType = Capitalize<'abc'>; // \"Abc\"\n```\n\n#### Uncapitalize\\<T\\>\n\nColoca a primeira letra em minúscula no nome do tipo de entrada T.\n\n```typescript\ntype MyType = Uncapitalize<'Abc'>; // \"abc\"\n```\n\n#### NoInfer\\<T\\>\n\n`NoInfer` é um tipo utilitário projetado para bloquear a inferência automática de tipos dentro do escopo de uma função genérica.\n\nExemplo:\n\n```typescript\n// Inferência automática de tipos dentro do escopo de uma função genérica.\nfunction fn<T extends string>(x: T[], y: T) {\n    return x.concat(y);\n}\nconst r = fn(['a', 'b'], 'c'); // O tipo aqui é (\"a\" | \"b\" | \"c\")[]\n```\n\nCom NoInfer:\n\n<!-- skip -->\n```typescript\n// Exemplo de função que usa NoInfer para evitar inferência de tipo\nfunction fn2<T extends string>(x: T[], y: NoInfer<T>) {\n    return x.concat(y);\n}\n\nconst r2 = fn2(['a', 'b'], 'c'); // Erro: Argumento de tipo '\"c\"' não é atribuível ao parâmetro do tipo '\"a\" | \"b\"'.\n```\n\n## Outros\n\n### Erros e Tratamento de Exceções\n\nO TypeScript permite capturar e tratar erros usando os mecanismos padrão de tratamento de erros do JavaScript:\n\nBlocos Try-Catch-Finally:\n\n```typescript\ntry {\n    // Código que pode lançar um erro\n} catch (error) {\n    // Trata o erro\n} finally {\n    // Código que sempre executa, finally é opcional\n}\n```\n\nVocê também pode tratar diferentes tipos de erro:\n\n```typescript\ntry {\n    // Código que pode lançar diferentes tipos de erros\n} catch (error) {\n    if (error instanceof TypeError) {\n        // Trata TypeError\n    } else if (error instanceof RangeError) {\n        // Trata RangeError\n    } else {\n        // Trata outros erros\n    }\n}\n```\n\nTipos de Erro Personalizados:\n\nÉ possível especificar erros mais específicos estendendo a `class` Error:\n\n```typescript\nclass CustomError extends Error {\n    constructor(message: string) {\n        super(message);\n        this.name = 'CustomError';\n    }\n}\n\nthrow new CustomError('Este é um erro personalizado.');\n```\n\n### Classes Mixin (Mixin classes)\n\nAs classes mixin permitem combinar e compor comportamentos de múltiplas classes em uma única classe. Elas fornecem uma maneira de reutilizar e estender funcionalidades sem a necessidade de cadeias de herança profundas.\n\n```typescript\nabstract class Identifiable {\n    name: string = '';\n    logId() {\n        console.log('id:', this.name);\n    }\n}\nabstract class Selectable {\n    selected: boolean = false;\n    select() {\n        this.selected = true;\n        console.log('Select');\n    }\n    deselect() {\n        this.selected = false;\n        console.log('Deselect');\n    }\n}\nclass MyClass {\n    constructor() {}\n}\n\n// Estende MyClass para incluir o comportamento de Identifiable e Selectable\ninterface MyClass extends Identifiable, Selectable {}\n\n// Função para aplicar mixins a uma classe\nfunction applyMixins(source: any, baseCtors: any[]) {\n    baseCtors.forEach(baseCtor => {\n        Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => {\n            let descriptor = Object.getOwnPropertyDescriptor(\n                baseCtor.prototype,\n                name\n            );\n            if (descriptor) {\n                Object.defineProperty(source.prototype, name, descriptor);\n            }\n        });\n    });\n}\n\n// Aplica os mixins a MyClass\napplyMixins(MyClass, [Identifiable, Selectable]);\nlet o = new MyClass();\no.name = 'abc';\no.logId();\no.select();\n```\n\n### Recursos de Linguagem Assíncronos\n\nComo o TypeScript é um superconjunto do JavaScript, ele possui recursos de linguagem assíncronos integrados do JavaScript como:\n\nPromises:\n\nPromises são uma maneira de lidar com operações assíncronas e seus resultados usando métodos como `.then()` e `.catch()` para lidar com condições de sucesso e erro.\n\nPara saber mais: [https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/Promise](https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/Promise)\n\nAsync/await:\n\nAs palavras-chave async/await são uma maneira de fornecer uma sintaxe com aparência mais síncrona para trabalhar com Promises. A palavra-chave `async` é usada para definir uma função assíncrona, e a palavra-chave `await` é usada dentro de uma função async para pausar a execução até que uma Promise seja resolvida ou rejeitada.\n\nPara saber mais:\n[https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Statements/async_function](https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Statements/async_function)\n[https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Operators/await](https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Operators/await)\n\nAs seguintes APIs são bem suportadas no TypeScript:\n\nFetch API:\n[https://developer.mozilla.org/pt-BR/docs/Web/API/Fetch_API](https://developer.mozilla.org/pt-BR/docs/Web/API/Fetch_API)\n\nWeb Workers:\n[https://developer.mozilla.org/pt-BR/docs/Web/API/Web_Workers_API](https://developer.mozilla.org/pt-BR/docs/Web/API/Web_Workers_API)\n\nShared Workers:\n[https://developer.mozilla.org/pt-BR/docs/Web/API/SharedWorker](https://developer.mozilla.org/pt-BR/docs/Web/API/SharedWorker)\n\nWebSocket:\n[https://developer.mozilla.org/pt-BR/docs/Web/API/WebSockets_API](https://developer.mozilla.org/pt-BR/docs/Web/API/WebSockets_API)\n\n### Iteradores e Geradores\n\nTanto Iteradores quanto Geradores são bem suportados no TypeScript.\n\nIteradores são objetos que implementam o protocolo iterador, fornecendo uma maneira de acessar elementos de uma coleção ou sequência um por um. É uma estrutura que contém um ponteiro para o próximo elemento na iteração. Eles possuem um método `next()` que retorna o próximo valor na sequência junto com um booleano indicando se a sequência terminou (`done`).\n\n```typescript\nclass NumberIterator implements Iterable<number> {\n    private current: number;\n\n    constructor(\n        private start: number,\n        private end: number\n    ) {\n        this.current = start;\n    }\n\n    public next(): IteratorResult<number> {\n        if (this.current <= this.end) {\n            const value = this.current;\n            this.current++;\n            return { value, done: false };\n        } else {\n            return { value: undefined, done: true };\n        }\n    }\n\n    [Symbol.iterator](): Iterator<number> {\n        return this;\n    }\n}\n\nconst iterator = new NumberIterator(1, 3);\n\nfor (const num of iterator) {\n    console.log(num);\n}\n```\n\nGeradores são funções especiais definidas usando a sintaxe `function*` que simplifica a criação de iteradores. Eles usam a palavra-chave `yield` para definir a sequência de valores e pausar e retomar automaticamente a execução quando os valores são solicitados.\n\nGeradores facilitam a criação de iteradores e são especialmente úteis para trabalhar com sequências grandes ou infinitas.\n\nExemplo:\n\n```typescript\nfunction* numberGenerator(start: number, end: number): Generator<number> {\n    for (let i = start; i <= end; i++) {\n        yield i;\n    }\n}\n\nconst generator = numberGenerator(1, 5);\n\nfor (const num of generator) {\n    console.log(num);\n}\n```\n\nO TypeScript também suporta iteradores assíncronos e geradores assíncronos.\n\nPara saber mais:\n\n[https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/Generator](https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/Generator)\n\n[https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/Iterator](https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/Iterator)\n\n### Referência JSDoc TsDocs\n\nAo trabalhar com uma base de código JavaScript, é possível ajudar o TypeScript a inferir o tipo correto usando comentários JSDoc com anotações adicionais para fornecer informações de tipo.\n\nExemplo:\n\n```typescript\n/**\n * Computa a potência de um dado número\n * @constructor\n * @param {number} base – O valor da base da expressão\n * @param {number} exponent – O valor do expoente da expressão\n */\nfunction power(base: number, exponent: number) {\n    return Math.pow(base, exponent);\n}\npower(10, 2); // function power(base: number, exponent: number): number\n```\n\nA documentação completa é fornecida neste link:\n[https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html](https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html)\n\nA partir da versão 3.7, é possível gerar definições de tipo .d.ts a partir da sintaxe JSDoc do JavaScript.\nMais informações podem ser encontradas aqui:\n[https://www.typescriptlang.org/docs/handbook/declaration-files/dts-from-js.html](https://www.typescriptlang.org/docs/handbook/declaration-files/dts-from-js.html)\n\n### @types\n\nPacotes sob a organização @types são convenções especiais de nomenclatura de pacotes usadas para fornecer definições de tipo para bibliotecas ou módulos JavaScript existentes. Por exemplo, usando:\n\n```shell\nnpm install --save-dev @types/lodash\n```\n\nInstalará as definições de tipo de `lodash` em seu projeto atual.\n\nPara contribuir com as definições de tipo do pacote @types, envie um pull request para [https://github.com/DefinitelyTyped/DefinitelyTyped](https://github.com/DefinitelyTyped/DefinitelyTyped).\n\n### JSX\n\nJSX (JavaScript XML) é uma extensão da sintaxe da linguagem JavaScript que permite escrever código semelhante a HTML em seus arquivos JavaScript ou TypeScript. É comumente usado no React para definir a estrutura HTML.\n\nO TypeScript estende as capacidades do JSX fornecendo verificação de tipos e análise estática.\n\nPara usar JSX, você precisa definir a opção de compilador `jsx` em seu arquivo `tsconfig.json`. Duas opções de configuração comuns:\n\n* \"preserve\": emite arquivos .jsx com o JSX inalterado. Esta opção diz ao TypeScript para manter a sintaxe JSX como está e não transformá-la durante o processo de compilação. Você pode usar esta opção se tiver uma ferramenta separada, como o Babel, que lida com a transformação.\n* \"react\": habilita a transformação JSX integrada do TypeScript. `React.createElement` será usado.\n\nTodas as opções estão disponíveis aqui:\n[https://www.typescriptlang.org/tsconfig#jsx](https://www.typescriptlang.org/tsconfig#jsx)\n\n### Módulos ES6\n\nO TypeScript suporta ES6 (ECMAScript 2015) e muitas versões subsequentes. Isso significa que você pode usar a sintaxe ES6, como arrow functions, template literals, classes, módulos, desestruturação e muito mais.\n\nPara habilitar recursos do ES6 em seu projeto, você pode especificar a propriedade `target` no tsconfig.json.\n\nUm exemplo de configuração:\n\n```json\n{\n  \"compilerOptions\": {\n    \"target\": \"es6\",\n    \"module\": \"es6\",\n    \"moduleResolution\": \"node\",\n    \"sourceMap\": true,\n    \"outDir\": \"dist\"\n  },\n  \"include\": [\"src\"]\n}\n```\n\n### Operador de Exponenciação ES7\n\nO operador de exponenciação (`**`) calcula o valor obtido elevando o primeiro operando à potência do segundo operando. Ele funciona de forma semelhante a `Math.pow()`, mas com a capacidade adicional de aceitar BigInts como operandos.\nO TypeScript suporta totalmente este operador usando como `target` no seu arquivo tsconfig.json a versão `es2016` ou superior.\n\n```typescript\nconsole.log(2 ** (2 ** 2)); // 16\n```\n\n### A Instrução for-await-of\n\nEste é um recurso do JavaScript totalmente suportado no TypeScript que permite iterar sobre objetos iteráveis assíncronos a partir da versão de destino es2018.\n\n```typescript\nasync function* asyncNumbers(): AsyncIterableIterator<number> {\n    yield Promise.resolve(1);\n    yield Promise.resolve(2);\n    yield Promise.resolve(3);\n}\n\n(async () => {\n    for await (const num of asyncNumbers()) {\n        console.log(num);\n    }\n})();\n```\n\n### Nova meta-propriedade target\n\nVocê pode usar no TypeScript a meta-propriedade `new.target` que permite determinar se uma função ou construtor foi invocado usando o operador `new`. Ela permite detectar se um objeto foi criado como resultado de uma chamada de construtor.\n\n```typescript\nclass Parent {\n    constructor() {\n        console.log(new.target); // Registra a função construtora usada para criar uma instância\n    }\n}\n\nclass Child extends Parent {\n    constructor() {\n        super();\n    }\n}\n\nconst parentX = new Parent(); // [Function: Parent]\nconst child = new Child(); // [Function: Child]\n```\n\n### Expressões de Importação Dinâmica\n\nÉ possível carregar módulos condicionalmente ou carregá-los sob demanda (lazy load) usando a proposta do ECMAScript para importação dinâmica, que é suportada no TypeScript.\n\nA sintaxe para expressões de importação dinâmica no TypeScript é as seguinte:\n\n<!-- skip -->\n```typescript\nasync function renderWidget() {\n    const container = document.getElementById('widget');\n    if (container !== null) {\n        const widget = await import('./widget'); // Importação dinâmica\n        widget.render(container);\n    }\n}\n\nrenderWidget();\n```\n\n### \"tsc –watch\"\n\nEste comando inicia o compilador TypeScript com o parâmetro `--watch`, com a capacidade de recompilar automaticamente os arquivos TypeScript sempre que forem modificados.\n\n```shell\ntsc --watch\n```\n\nA partir da versão 4.9 do TypeScript, o monitoramento de arquivos depende principalmente de eventos do sistema de arquivos, recorrendo automaticamente à sondagem (polling) se um observador baseado em eventos não puder ser estabelecido.\n\n### Operador de Asserção Não-Nulo (Non-null Assertion Operator)\n\nO Operador de Asserção Não-Nulo (Postfix !) também chamado de Asserções de Atribuição Definitiva (Definite Assignment Assertions) é um recurso do TypeScript que permite asseverar que uma variável ou propriedade não é nula ou indefinida, mesmo que a análise de tipo estática do TypeScript sugira que poderia ser. Com este recurso, é possível remover qualquer verificação explícita.\n\n```typescript\ntype Person = {\n    name: string;\n};\n\nconst printName = (person?: Person) => {\n    console.log(`O nome é ${person!.name}`);\n};\n```\n\n### Declarações com Valor Padrão (Defaulted declarations)\n\nDeclarações com valor padrão são usadas quando uma variável ou parâmetro recebe um valor padrão. Isso significa que se nenhum valor for fornecido para essa variável ou parâmetro, o valor padrão será usado no lugar.\n\n```typescript\nfunction greet(name: string = 'Anônimo'): void {\n    console.log(`Olá, ${name}!`);\n}\ngreet(); // Olá, Anônimo!\ngreet('John'); // Olá, John!\n```\n\n### Encadeamento Opcional (Optional Chaining)\n\nO operador de encadeamento opcional `?.` funciona como o operador de ponto regular (`.`) para acessar propriedades ou métodos. No entanto, ele trata graciosamente valores nulos ou indefinidos terminando a expressão e retornando `undefined`, em vez de lançar um erro.\n\n```typescript\ntype Person = {\n    name: string;\n    age?: number;\n    address?: {\n        street?: string;\n        city?: string;\n    };\n};\n\nconst person: Person = {\n    name: 'John',\n};\n\nconsole.log(person.address?.city); // undefined\n```\n\n### Operador de Coalescência Nula (Nullish coalescing operator)\n\nO operador de coalescência nula `??` retorna o valor do lado direito se o lado esquerdo for `null` ou `undefined`; caso contrário, retorna o valor do lado esquerdo.\n\n```typescript\nconst foo = null ?? 'foo';\nconsole.log(foo); // foo\n\nconst baz = 1 ?? 'baz';\nconst baz2 = 0 ?? 'baz';\nconsole.log(baz); // 1\nconsole.log(baz2); // 0\n```\n\n### Tipos de Literal de Template (Template Literal Types)\n\nTipos de Literal de Template permitem manipular valores de string em nível de tipo e gerar novos tipos de string baseados em existentes. Eles são úteis para criar tipos mais expressivos e precisos a partir de operações baseadas em string.\n\n```typescript\ntype Department = 'engineering' | 'hr';\ntype Language = 'english' | 'spanish';\ntype Id = `${Department}-${Language}-id`; // \"engineering-english-id\" | \"engineering-spanish-id\" | \"hr-english-id\" | \"hr-spanish-id\"\n```\n\n### Sobrecarga de Função (Function overloading)\n\nA sobrecarga de função permite definir múltiplas assinaturas de função para o mesmo nome de função, cada uma com diferentes tipos de parâmetros e tipo de retorno.\nQuando você chama uma função sobrecarregada, o TypeScript usa os argumentos fornecidos para determinar a assinatura de função correta:\n\n```typescript\nfunction makeGreeting(name: string): string;\nfunction makeGreeting(names: string[]): string[];\n\nfunction makeGreeting(person: unknown): unknown {\n    if (typeof person === 'string') {\n        return `Hi ${person}!`;\n    } else if (Array.isArray(person)) {\n        return person.map(name => `Hi, ${name}!`);\n    }\n    throw new Error('Não foi possível saudar');\n}\n\nmakeGreeting('Simon');\nmakeGreeting(['Simone', 'John']);\n```\n\n### Tipos Recursivos\n\nUm Tipo Recursivo é um tipo que pode se referir a si mesmo. Isso é útil para definir estruturas de dados que possuem uma estrutura hierárquica ou recursiva (aninhamento potencialmente infinito), como listas ligadas, árvores e grafos.\n\n```typescript\ntype ListNode<T> = {\n    data: T;\n    next: ListNode<T> | undefined;\n};\n```\n\n### Tipos Condicionais Recursivos\n\nÉ possível definir relacionamentos de tipo complexos usando lógica e recursão no TypeScript.\nVamos detalhar em termos simples:\n\nTipos Condicionais: permite definir tipos baseados em condições booleanas:\n\n```typescript\ntype CheckNumber<T> = T extends number ? 'Número' : 'Não é um número';\ntype A = CheckNumber<123>; // 'Número'\ntype B = CheckNumber<'abc'>; // 'Não é um número'\n```\n\nRecursão: significa uma definição de tipo que se refere a si mesma dentro de sua própria definição:\n\n```typescript\ntype Json = string | number | boolean | null | Json[] | { [key: string]: Json };\n\nconst data: Json = {\n    prop1: true,\n    prop2: 'prop2',\n    prop3: {\n        prop4: [],\n    },\n};\n```\n\nTipos Condicionais Recursivos combinam lógica condicional e recursão. Isso significa que uma definição de tipo pode depender de si mesma através de lógica condicional, criando relacionamentos de tipo complexos e flexíveis.\n\n```typescript\ntype Flatten<T> = T extends Array<infer U> ? Flatten<U> : T;\n\ntype NestedArray = [1, [2, [3, 4], 5], 6];\ntype FlattenedArray = Flatten<NestedArray>; // 2 | 3 | 4 | 5 | 1 | 6\n```\n\n### Suporte a Módulos ECMAScript no Node\n\nO Node.js adicionou suporte para Módulos ECMAScript a partir da versão 15.3.0, e o TypeScript tem suporte a Módulos ECMAScript para Node.js desde a versão 4.7. Este suporte pode ser habilitado usando a propriedade `module` com o valor `nodenext` no arquivo tsconfig.json. Aqui está um exemplo:\n\n```json\n{\n  \"compilerOptions\": {\n    \"module\": \"nodenext\",\n    \"outDir\": \"./lib\",\n    \"declaration\": true\n  }\n}\n```\n\nO Node.js suporta duas extensões de arquivo para módulos: `.mjs` para módulos ES e `.cjs` para módulos CommonJS. As extensões de arquivo equivalentes no TypeScript são `.mts` para módulos ES e `.cts` para módulos CommonJS. Quando o compilador TypeScript transpila esses arquivos para JavaScript, ele criará arquivos `.mjs` e `.cjs`.\n\nSe você quiser usar módulos ES em seu projeto, você pode definir a propriedade `type` como \"module\" em seu arquivo package.json. Isso instrui o Node.js a tratar o projeto como um projeto de módulo ES.\n\nAlém disso, o TypeScript também suporta declarações de tipo em arquivos .d.ts. Esses arquivos de declaração fornecem informações de tipo para bibliotecas ou módulos escritos em TypeScript, permitindo que outros desenvolvedores os utilizem com a verificação de tipo e os recursos de preenchimento automático do TypeScript.\n\n### Funções de Asserção (Assertion Functions)\n\nNo TypeScript, funções de asserção são funções que indicam a verificação de uma condição específica com base em seu valor de retorno. Em sua forma mais simples, uma função assert examina um predicado fornecido e lança um erro quando o predicado é avaliado como falso.\n\n```typescript\nfunction isNumber(value: unknown): asserts value is number {\n    if (typeof value !== 'number') {\n        throw new Error('Não é um número');\n    }\n}\n```\n\nOu pode ser declarada como uma expressão de função:\n\n```typescript\ntype AssertIsNumber = (value: unknown) => asserts value is number;\nconst isNumber: AssertIsNumber = value => {\n    if (typeof value !== 'number') {\n        throw new Error('Não é um número');\n    }\n};\n```\n\nFunções de asserção compartilham semelhanças com guardas de tipo (type guards). As guardas de tipo foram inicialmente introduzidas para realizar verificações em tempo de execução e garantir o tipo de um valor dentro de um escopo específico.\nEspecificamente, uma guarda de tipo é uma função que avalia um predicado de tipo e retorna um valor booleano indicando se the predicado é verdadeiro ou falso. Isso difere ligeiramente das funções de asserção, onde a intenção é lançar um erro em vez de retornar falso quando o predicado não for satisfeito.\n\nExemplo de guarda de tipo:\n\n```typescript\nconst isNumber = (value: unknown): value is number => typeof value === 'number';\n```\n\n### Tipos de Tupla Variádicos (Variadic Tuple Types)\n\nTipos de Tupla Variádicos são recursos introduzidos na versão 4.0 do TypeScript. Vamos começar revisando o que é uma tupla:\n\nUm tipo tupla é um array que possui um comprimento definido, e onde o tipo de cada elemento é conhecido:\n\n```typescript\ntype Student = [string, number];\nconst [name, age]: Student = ['Simone', 20];\n```\n\nO termo \"variádico\" significa aridade indefinida (aceita um número variável de argumentos).\n\nUma tupla variádica é um tipo tupla que possui todas as propriedades anteriores, mas o formato exato ainda não está definido:\n\n```typescript\ntype Bar<T extends unknown[]> = [boolean, ...T, number];\n\ntype A = Bar<[boolean]>; // [boolean, boolean, number]\ntype B = Bar<['a', 'b']>; // [boolean, 'a', 'b', number]\ntype C = Bar<[]>; // [boolean, number]\n```\n\nNo código anterior, podemos ver que o formato da tupla é definido pelo genérico `T` passado.\n\nTuplas variádicas podem aceitar múltiplos genéricos, tornando-as muito flexíveis:\n\n```typescript\ntype Bar<T extends unknown[], G extends unknown[]> = [...T, boolean, ...G];\n\ntype A = Bar<[number], [string]>; // [number, boolean, string]\ntype B = Bar<['a', 'b'], [boolean]>; // [\"a\", \"b\", boolean, boolean]\n```\n\nCom as novas tuplas variádicas podemos usar:\n\n* Os espalhamentos (spreads) na sintaxe de tipo tupla agora podem ser genéricos, assim podemos representar operações de ordem superior em tuplas e arrays mesmo quando não conhecemos os tipos reais sobre os quais estamos operando.\n* Os elementos de resto (rest elements) podem ocorrer em qualquer lugar em uma tupla.\n\nExemplo:\n\n```typescript\ntype Items = readonly unknown[];\n\nfunction concat<T extends Items, U extends Items>(\n    arr1: T,\n    arr2: U\n): [...T, ...U] {\n    return [...arr1, ...arr2];\n}\n\nconcat([1, 2, 3], ['4', '5', '6']); // [1, 2, 3, \"4\", \"5\", \"6\"]\n```\n\n### Tipos Boxed (Boxed types)\n\nTipos boxed referem-se aos objetos de empacotamento que são usados para representar tipos primitivos como objetos. Esses objetos de empacotamento fornecem funcionalidades e métodos adicionais que não estão disponíveis diretamente nos valores primitivos.\n\nQuando você acessa um método como `charAt` ou `normalize` em um primitivo `string`, o JavaScript o empacota em um objeto `String`, chama o método e depois descarta o objeto.\n\nDemonstração:\n\n```typescript\nconst originalNormalize = String.prototype.normalize;\nString.prototype.normalize = function () {\n    console.log(this, typeof this);\n    return originalNormalize.call(this);\n};\nconsole.log('\\u0041'.normalize());\n```\n\nO TypeScript representa essa diferenciação fornecendo tipos separados para os primitivos e seus empacotadores de objeto correspondentes:\n\n* string => String\n* number => Number\n* boolean => Boolean\n* symbol => Symbol\n* bigint => BigInt\n\nOs tipos boxed geralmente não são necessários. Evite usar tipos boxed e, em vez disso, use o tipo para os primitivos, por exemplo, `string` em vez de `String`.\n\n### Covariância e Contravariância no TypeScript\n\nCovariância e Contravariância são usadas para descrever como os relacionamentos funcionam ao lidar com herança ou atribuição de tipos.\n\nCovariância significa que um relacionamento de tipo preserva a direção da herança ou atribuição, então se um tipo A é um subtipo do tipo B, então um array do tipo A também é considerado um subtipo de um array do tipo B. O importante a notar aqui é que o relacionamento de subtipo é mantido; isso significa que a Covariância aceita subtipo mas não aceita supertipo.\n\nContravariância significa que um relacionamento de tipo inverte a direção da herança ou atribuição, então se um tipo A é um subtipo do tipo B, então um array do tipo B é considerado um subtipo de um array do tipo A. O relacionamento de subtipo é invertido; isso significa que a Contravariância aceita supertipo mas não aceita subtipo.\n\nNotas: Bivariância significa aceitar tanto supertipo quanto subtipo.\n\nExemplo: Digamos que tenhamos um espaço para todos os animais e um espaço separado apenas para cachorros.\n\nNa Covariância, você pode colocar todos os cachorros no espaço dos animais porque cachorros são um tipo de animal. Mas você não pode colocar todos os animais no espaço dos cachorros porque pode haver outros animais misturados.\n\nNa Contravariância, você não pode colocar todos os animais no espaço dos cachorros porque o espaço dos animais também pode conter outros animais. No entanto, você pode colocar todos os cachorros no espaço dos animais porque todos os cachorros também são animais.\n\n<!-- skip -->\n```typescript\n// Exemplo de Covariância\nclass Animal {\n    name: string;\n    constructor(name: string) {\n        this.name = name;\n    }\n}\n\nclass Dog extends Animal {\n    breed: string;\n    constructor(name: string, breed: string) {\n        super(name);\n        this.breed = breed;\n    }\n}\n\nlet animals: Animal[] = [];\nlet dogs: Dog[] = [];\n\n// Covariância permite atribuir array de subtipo (Dog) a array de supertipo (Animal)\nanimals = dogs;\ndogs = animals; // Inválido: Tipo 'Animal[]' não é atribuível ao tipo 'Dog[]'\n\n// Exemplo de Contravariância\ntype Feed<in T> = (animal: T) => void;\n\nlet feedAnimal: Feed<Animal> = (animal: Animal) => {\n    console.log(`Nome do animal: ${animal.name}`);\n};\n\nlet feedDog: Feed<Dog> = (dog: Dog) => {\n    console.log(`Nome do cachorro: ${dog.name}, Raça: ${dog.breed}`);\n};\n\n// Contravariância permite atribuir callback de supertipo (Animal) a callback de subtipo (Dog)\nfeedDog = feedAnimal;\nfeedAnimal = feedDog; // Inválido: Tipo 'Feed<Dog>' não é atribuível ao tipo 'Feed<Animal>'.\n```\n\nNo TypeScript, relacionamentos de tipo para arrays são covariantes, enquanto relacionamentos de tipo para parâmetros de função são contravariantes. Isso significa que o TypeScript exibe tanto covariância quanto contravariância, dependendo do contexto.\n\n#### Anotações de Variância Opcionais para Parâmetros de Tipo\n\nA partir do TypeScript 4.7.0, podemos usar as palavras-chave `out` e `in` para sermos específicos sobre a anotação de variância.\n\nPara Covariante, use a palavra-chave `out`:\n\n```typescript\ntype AnimalCallback<out T> = () => T; // T é Covariante aqui\n```\n\nE para Contravariante, use a palavra-chave `in`:\n\n```typescript\ntype AnimalCallback<in T> = (value: T) => void; // T é Contravariante aqui\n```\n\n### Assinaturas de Índice de Padrão de String de Template (Template String Pattern Index Signatures)\n\nAssinaturas de índice de padrão de string de template permitem definir assinaturas de índice flexíveis usando padrões de string de template. Este recurso nos permite criar objetos que podem ser indexados com padrões específicos de chaves de string, fornecendo mais controle e especificidade ao acessar e manipular propriedades.\n\nO TypeScript a partir da versão 4.4 permite assinaturas de índice para símbolos e padrões de string de template.\n\n```typescript\nconst uniqueSymbol = Symbol('description');\n\ntype MyKeys = `key-${string}`;\n\ntype MyObject = {\n    [uniqueSymbol]: string;\n    [key: MyKeys]: number;\n};\n\nconst obj: MyObject = {\n    [uniqueSymbol]: 'Chave de símbolo único',\n    'key-a': 123,\n    'key-b': 456,\n};\n\nconsole.log(obj[uniqueSymbol]); // Chave de símbolo único\nconsole.log(obj['key-a']); // 123\nconsole.log(obj['key-b']); // 456\n```\n\n### O Operador satisfies\n\nO `satisfies` permite verificar se um determinado tipo satisfaz uma interface ou condição específica. Em outras palavras, ele garante que um tipo possui todas as propriedades e métodos exigidos de uma interface específica. É uma maneira de garantir que uma variável se encaixe na definição de um tipo.\nAqui está um exemplo:\n\n<!-- skip -->\n```typescript\ntype Columns = 'name' | 'nickName' | 'attributes';\n\ntype User = Record<Columns, string | string[] | undefined>;\n\n// Anotação de Tipo usando `User`\nconst user: User = {\n    name: 'Simone',\n    nickName: undefined,\n    attributes: ['dev', 'admin'],\n};\n\n// Nas linhas seguintes, o TypeScript não conseguirá inferir corretamente\nuser.attributes?.map(console.log); // A propriedade 'map' não existe no tipo 'string | string[]'. A propriedade 'map' não existe no tipo 'string'.\nuser.nickName; // string | string[] | undefined\n\n// Asserção de tipo usando `as`\nconst user2 = {\n    name: 'Simon',\n    nickName: undefined,\n    attributes: ['dev', 'admin'],\n} as User;\n\n// Aqui também, o TypeScript não conseguirá inferir corretamente\nuser2.attributes?.map(console.log); // A propriedade 'map' não existe no tipo 'string | string[]'. A propriedade 'map' não existe no tipo 'string'.\nuser2.nickName; // string | string[] | undefined\n\n// Usando operadores `satisfies` podemos inferir os tipos corretamente agora\nconst user3 = {\n    name: 'Simon',\n    nickName: undefined,\n    attributes: ['dev', 'admin'],\n} satisfies User;\n\nuser3.attributes?.map(console.log); // TypeScript infere corretamente: string[]\nuser3.nickName; // TypeScript infere corretamente: undefined\n```\n\n### Importações e Exportações Apenas de Tipo (Type-Only Imports and Export)\n\nImportações e Exportações Apenas de Tipo permitem importar ou exportar tipos sem importar ou exportar os valores ou funções associados a esses tipos. Isso pode ser útil para reduzir o tamanho do seu bundle.\n\nPara usar importações apenas de tipo, você pode usar a palavra-chave `import type`.\n\nO TypeScript permite usar extensões de arquivo de declaração e implementação (.ts, .mts, .cts e .tsx) em importações apenas de tipo, independentemente das configurações de `allowImportingTsExtensions`.\n\nPor exemplo:\n\n<!-- skip -->\n```typescript\nimport type { House } from './house.ts';\n```\n\nAs seguintes são formas suportadas:\n\n<!-- skip -->\n```typescript\nimport type T from './mod';\nimport type { A, B } from './mod';\nimport type * as Types from './mod';\nexport type { T };\nexport type { T } from './mod';\n```\n\n### declaração using e Gerenciamento Explícito de Recursos (Explicit Resource Management)\n\nUma declaração `using` é um vínculo imutável com escopo de bloco, semelhante ao `const`, usado para gerenciar recursos descartáveis (disposable). Quando inicializado com um valor, o método `Symbol.dispose` desse valor é registrado e subsequentemente executado ao sair do escopo de bloco envolvente.\n\nIsso é baseado no recurso de Gerenciamento de Recursos do ECMAScript, que é útil para realizar tarefas essenciais de limpeza após a criação do objeto, como fechar conexões, excluir arquivos e liberar memória.\n\nNotas:\n\n* Devido à sua introdução recente na versão 5.2 do TypeScript, a maioria dos ambientes de execução carece de suporte nativo. Você precisará de polyfills para: `Symbol.dispose`, `Symbol.asyncDispose`, `DisposableStack`, `AsyncDisposableStack`, `SuppressedError`.\n* Além disso, você precisará configurar seu tsconfig.json da seguinte forma:\n\n```json\n{\n    \"compilerOptions\": {\n        \"target\": \"es2022\",\n        \"lib\": [\"es2022\", \"esnext.disposable\", \"dom\"]\n    }\n}\n```\n\nExemplo:\n\n<!-- skip -->\n```typescript\n//@ts-ignore\nSymbol.dispose ??= Symbol('Symbol.dispose'); // Polyfill simples\n\nconst doWork = (): Disposable => {\n    return {\n        [Symbol.dispose]: () => {\n            console.log('disposto (disposed)');\n        },\n    };\n};\n\nconsole.log(1);\n\n{\n    using work = doWork(); // Recurso é declarado\n    console.log(2);\n} // Recurso é descartado (ex: `work[Symbol.dispose]()` é avaliado)\n\nconsole.log(3);\n```\n\nO código registrará:\n\n```shell\n1\n2\ndisposto (disposed)\n3\n```\n\nUm recurso elegível para descarte deve aderir à interface `Disposable`:\n\n```typescript\n// lib.esnext.disposable.d.ts\ninterface Disposable {\n    [Symbol.dispose](): void;\n}\n```\n\nAs declarações `using` registram as operações de descarte de recursos em uma pilha, garantindo que sejam descartadas na ordem inversa da declaração:\n\n<!-- skip -->\n```typescript\n{\n    using j = getA(),\n        y = getB();\n    using k = getC();\n} // descarta `C`, depois `B`, depois `A`.\n```\n\nOs recursos têm garantia de serem descartados, mesmo que ocorra código subsequente ou exceções. Isso pode levar o descarte a potencialmente lançar uma exceção, possivelmente suprimindo outra. Para manter informações sobre erros suprimidos, uma nova exceção nativa, `SuppressedError`, é introduzida.\n\n#### declaração await using\n\nUma declaração `await using` lida com um recurso descartável de forma assíncrona. O valor deve ter um método `Symbol.asyncDispose`, que será aguardado ao final do bloco.\n\n<!-- skip -->\n```typescript\nasync function doWorkAsync() {\n    await using work = doWorkAsync(); // Recurso é declarado\n} // Recurso é descartado (ex: `await work[Symbol.asyncDispose]()` é avaliado)\n```\n\nPara um recurso descartável de forma assíncrona, ele deve aderir à interface `Disposable` ou `AsyncDisposable`:\n\n```typescript\n// lib.esnext.disposable.d.ts\ninterface AsyncDisposable {\n    [Symbol.asyncDispose](): Promise<void>;\n}\n```\n\n<!-- skip -->\n```typescript\n//@ts-ignore\nSymbol.asyncDispose ??= Symbol('Symbol.asyncDispose'); // Polyfill simples\n\nclass DatabaseConnection implements AsyncDisposable {\n    // Um método que é chamado quando o objeto é descartado assincronamente\n    [Symbol.asyncDispose]() {\n        // Fecha a conexão e retorna uma promise\n        return this.close();\n    }\n\n    async close() {\n        console.log('Fechando a conexão...');\n        await new Promise(resolve => setTimeout(resolve, 1000));\n        console.log('Conexão fechada.');\n    }\n}\n\nasync function doWork() {\n    // Cria uma nova conexão e descarte-a assincronamente quando ela sair do escopo\n    await using connection = new DatabaseConnection(); // Recurso é declarado\n    console.log('Fazendo algum trabalho...');\n} // Recurso é descartado (ex: `await connection[Symbol.asyncDispose]()` é avaliado)\n\ndoWork();\n```\n\nO código registra:\n\n```shell\nFazendo algum trabalho...\nFechando a conexão...\nConexão fechada.\n```\n\nAs declarações `using` e `await using` são permitidas em Instruções: `for`, `for-in`, `for-of`, `for-await-of`, `switch`.\n\n### Atributos de Importação (Import Attributes)\n\nOs Atributos de Importação do TypeScript 5.3 (rótulos para importações) dizem ao ambiente de execução como lidar com módulos (JSON, etc.). Isso melhora a segurança garantindo importações claras e se alinha com a Política de Segurança de Conteúdo (CSP) para carregamento de recursos mais seguro. O TypeScript garante que eles sejam válidos, mas deixa o ambiente de execução lidar com sua interpretação para manipulação específica de módulos.\n\nExemplo:\n\n<!-- skip -->\n```typescript\nimport config from './config.json' with { type: 'json' };\n```\n\ncom importação dinâmica:\n\n<!-- skip -->\n```typescript\nconst config = import('./config.json', { with: { type: 'json' } });\n```\n"
  },
  {
    "path": "README-sv_SE.md",
    "content": "# Den koncisa TypeScript-boken\n\nDen koncisa TypeScript-boken ger en omfattande och kortfattad översikt över TypeScripts kapaciteter. Den erbjuder tydliga förklaringar som täcker alla aspekter i den senaste versionen av språket, från dess kraftfulla typsystem till avancerade funktioner. Oavsett om du är nybörjare eller en erfaren utvecklare är denna bok en ovärderlig resurs för att förbättra din förståelse och skicklighet i TypeScript.\n\nDenna bok är helt gratis och öppen källkod.\n\nJag tror att teknisk utbildning av hög kvalitet bör vara tillgänglig för alla, vilket är anledningen till att jag håller denna bok gratis och öppen.\n\nOm boken hjälpte dig att lösa en bugg, förstå ett knepigt koncept eller avancera i din karriär, vänligen överväg att stödja mitt arbete genom att betala vad du vill (föreslaget pris: 15 USD) eller sponsra en kaffe. Ditt stöd hjälper mig att hålla innehållet uppdaterat och utöka det med nya exempel och djupare förklaringar.\n\n[![Buy Me a Coffee](https://img.shields.io/badge/buy_me_a_coffee-FFDD00?style=for-the-badge&logo=buy-me-a-coffee&logoColor=black)](https://www.buymeacoffee.com/simonepoggiali)\n\n[![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.com/donate/?business=QW82ZS956XLFY&no_recurring=0&currency_code=EUR)\n\n## Översättningar\n\nDenna bok har översatts till flera språkversioner, inklusive:\n\n[Kinesiska](https://github.com/gibbok/typescript-book/blob/main/README-zh_CN.md)\n\n[Italienska](https://github.com/gibbok/typescript-book/blob/main/README-it_IT.md)\n\n[Portugisiska (Brasilien)](https://github.com/gibbok/typescript-book/blob/main/README-pt_BR.md)\n\n[Svenska](https://github.com/gibbok/typescript-book/blob/main/README-sv_SE.md)\n\n## Nedladdningar och webbplats\n\nDu kan också ladda ner Epub-versionen:\n\n[https://github.com/gibbok/typescript-book/tree/main/downloads](https://github.com/gibbok/typescript-book/tree/main/downloads)\n\nEn onlineversion finns tillgänglig på:\n\n[https://gibbok.github.io/typescript-book](https://gibbok.github.io/typescript-book)\n\n## Innehållsförteckning\n\n<!-- markdownlint-disable MD004 -->\n- [Den koncisa TypeScript-boken](#den-koncisa-typescript-boken)\n  - [Översättningar](#översättningar)\n  - [Nedladdningar och webbplats](#nedladdningar-och-webbplats)\n  - [Innehållsförteckning](#innehållsförteckning)\n  - [Introduktion](#introduktion)\n  - [Om författaren](#om-författaren)\n  - [Introduktion till TypeScript](#introduktion-till-typescript)\n    - [Vad är TypeScript?](#vad-är-typescript)\n    - [Varför TypeScript?](#varför-typescript)\n    - [TypeScript och JavaScript](#typescript-och-javascript)\n    - [TypeScript-kodgenerering](#typescript-kodgenerering)\n    - [Modernt JavaScript nu (Downleveling)](#modernt-javascript-nu-downleveling)\n  - [Komma igång med TypeScript](#komma-igång-med-typescript)\n    - [Installation](#installation)\n    - [Konfiguration](#konfiguration)\n    - [TypeScript-konfigurationsfil](#typescript-konfigurationsfil)\n      - [target](#target)\n      - [lib](#lib)\n      - [strict](#strict)\n      - [module](#module)\n      - [moduleResolution](#moduleresolution)\n      - [esModuleInterop](#esmoduleinterop)\n      - [jsx](#jsx)\n      - [skipLibCheck](#skiplibcheck)\n      - [files](#files)\n      - [include](#include)\n      - [exclude](#exclude)\n    - [importHelpers](#importhelpers)\n    - [Råd vid migrering till TypeScript](#råd-vid-migrering-till-typescript)\n  - [Utforska typsystemet](#utforska-typsystemet)\n    - [TypeScript-språktjänsten](#typescript-språktjänsten)\n    - [Strukturell typning](#strukturell-typning)\n    - [Grundläggande jämförelseregler i TypeScript](#grundläggande-jämförelseregler-i-typescript)\n    - [Typer som mängder](#typer-som-mängder)\n    - [Tilldela en typ: Typdeklarationer och typpåståenden](#tilldela-en-typ-typdeklarationer-och-typpåståenden)\n      - [Typdeklaration](#typdeklaration)\n      - [Typpåstående](#typpåstående)\n      - [Omgivande deklarationer](#omgivande-deklarationer)\n    - [Egenskapskontroll och kontroll av överskottsegenskaper](#egenskapskontroll-och-kontroll-av-överskottsegenskaper)\n    - [Svaga typer](#svaga-typer)\n    - [Strikt kontroll av objektliteraler (Freshness)](#strikt-kontroll-av-objektliteraler-freshness)\n    - [Typinferens](#typinferens)\n    - [Mer avancerade inferenser](#mer-avancerade-inferenser)\n    - [Typbreddning](#typbreddning)\n    - [Const](#const)\n      - [Const-modifierare på typparametrar](#const-modifierare-på-typparametrar)\n      - [Const-påstående](#const-påstående)\n    - [Explicit typannotering](#explicit-typannotering)\n    - [Typavsmalnande](#typavsmalnande)\n      - [Villkor](#villkor)\n      - [Kasta eller returnera](#kasta-eller-returnera)\n      - [Diskriminerad union](#diskriminerad-union)\n      - [Användardefinierade typvakter](#användardefinierade-typvakter)\n  - [Primitiva typer](#primitiva-typer)\n    - [string](#string)\n    - [boolean](#boolean)\n    - [number](#number)\n    - [bigInt](#bigint)\n    - [Symbol](#symbol)\n    - [null och undefined](#null-och-undefined)\n    - [Array](#array)\n    - [any](#any)\n  - [Typannoteringar](#typannoteringar)\n  - [Valfria egenskaper](#valfria-egenskaper)\n  - [Skrivskyddade egenskaper](#skrivskyddade-egenskaper)\n  - [Indexsignaturer](#indexsignaturer)\n  - [Utöka typer](#utöka-typer)\n  - [Literaltyper](#literaltyper)\n  - [Literalhärledning](#literalhärledning)\n  - [strictNullChecks](#strictnullchecks)\n  - [Enums](#enums)\n    - [Numeriska enums](#numeriska-enums)\n    - [Sträng-enums](#sträng-enums)\n    - [Konstanta enums](#konstanta-enums)\n    - [Omvänd mappning](#omvänd-mappning)\n    - [Omgivande enums](#omgivande-enums)\n    - [Beräknade och konstanta medlemmar](#beräknade-och-konstanta-medlemmar)\n  - [Avsmalning](#avsmalning)\n    - [typeof-typvakter](#typeof-typvakter)\n    - [Sanningsvärdesavsmalning](#sanningsvärdesavsmalning)\n    - [Likhetsavsmalning](#likhetsavsmalning)\n    - [In-operatoravsmalning](#in-operatoravsmalning)\n    - [instanceof-avsmalning](#instanceof-avsmalning)\n  - [Tilldelningar](#tilldelningar)\n  - [Kontrollflödesanalys](#kontrollflödesanalys)\n  - [Typpredikat](#typpredikat)\n  - [Diskriminerade unioner](#diskriminerade-unioner)\n  - [Never-typen](#never-typen)\n  - [Uttömmande kontroll](#uttömmande-kontroll)\n  - [Objekttyper](#objekttyper)\n  - [Tuppeltyp (Anonym)](#tuppeltyp-anonym)\n  - [Namngiven tuppeltyp (Märkt)](#namngiven-tuppeltyp-märkt)\n  - [Tuppel med fast längd](#tuppel-med-fast-längd)\n  - [Unionstyp](#unionstyp)\n  - [Intersektionstyper](#intersektionstyper)\n  - [Typindexering](#typindexering)\n  - [Typ från värde](#typ-från-värde)\n  - [Typ från funktionsreturvärde](#typ-från-funktionsreturvärde)\n  - [Typ från modul](#typ-från-modul)\n  - [Mappade typer](#mappade-typer)\n  - [Modifierare för mappade typer](#modifierare-för-mappade-typer)\n  - [Villkorliga typer](#villkorliga-typer)\n  - [Distributiva villkorliga typer](#distributiva-villkorliga-typer)\n  - [infer-typinferens i villkorliga typer](#infer-typinferens-i-villkorliga-typer)\n  - [Fördefinierade villkorliga typer](#fördefinierade-villkorliga-typer)\n  - [Mall-unionstyper](#mall-unionstyper)\n  - [Any-typen](#any-typen)\n  - [Unknown-typen](#unknown-typen)\n  - [Void-typen](#void-typen)\n  - [Never-typen](#never-typen)\n  - [Användning av Never-typen](#användning-av-never-typen)\n  - [Interface och Type](#interface-och-type)\n    - [Gemensam syntax](#gemensam-syntax)\n    - [Grundläggande typer](#grundläggande-typer)\n    - [Objekt och Interface](#objekt-och-interface)\n    - [Union- och Intersection-typer](#union--och-intersection-typer)\n  - [Inbyggda primitiva typer](#inbyggda-primitiva-typer)\n  - [Vanliga inbyggda JS-objekt](#vanliga-inbyggda-js-objekt)\n  - [Överlagringar](#överlagringar)\n  - [Sammanslagning och utökning](#sammanslagning-och-utökning)\n  - [Skillnader mellan Type och Interface](#skillnader-mellan-type-och-interface)\n  - [Klass](#klass)\n    - [Vanlig klasssyntax](#vanlig-klasssyntax)\n    - [Konstruktor](#konstruktor)\n    - [Privata och skyddade konstruktorer](#privata-och-skyddade-konstruktorer)\n    - [Åtkomstmodifierare](#åtkomstmodifierare)\n    - [Get och Set](#get-och-set)\n    - [Auto-accessorer i klasser](#auto-accessorer-i-klasser)\n    - [this](#this)\n    - [Parameteregenskaper](#parameteregenskaper)\n    - [Abstrakta klasser](#abstrakta-klasser)\n    - [Med generics](#med-generics)\n    - [Dekoratörer](#dekoratörer)\n      - [Klassdekoratörer](#klassdekoratörer)\n      - [Egenskapsdekoratör](#egenskapsdekoratör)\n      - [Metoddekoratör](#metoddekoratör)\n      - [Getter- och setter-dekoratörer](#getter--och-setter-dekoratörer)\n      - [Dekoratörmetadata](#dekoratörmetadata)\n    - [Arv](#arv)\n    - [Statiska medlemmar](#statiska-medlemmar)\n    - [Egenskapsinitiering](#egenskapsinitiering)\n    - [Metodöverlagring](#metodöverlagring)\n  - [Generics](#generics)\n    - [Generisk typ](#generisk-typ)\n    - [Generiska klasser](#generiska-klasser)\n    - [Generiska begränsningar](#generiska-begränsningar)\n    - [Generisk kontextuell avsmalning](#generisk-kontextuell-avsmalning)\n  - [Raderade strukturella typer](#raderade-strukturella-typer)\n  - [Namnrymder](#namnrymder)\n  - [Symboler](#symboler)\n  - [Trippelsnedstreck-direktiv](#trippelsnedstreck-direktiv)\n  - [Typmanipulation](#typmanipulation)\n    - [Skapa typer från typer](#skapa-typer-från-typer)\n    - [Indexerade åtkomsttyper](#indexerade-åtkomsttyper)\n    - [Verktygstyper](#verktygstyper)\n      - [Awaited\\<T\\>](#awaitedt)\n      - [Partial\\<T\\>](#partialt)\n      - [Required\\<T\\>](#requiredt)\n      - [Readonly\\<T\\>](#readonlyt)\n      - [Record\\<K, T\\>](#recordk-t)\n      - [Pick\\<T, K\\>](#pickt-k)\n      - [Omit\\<T, K\\>](#omitt-k)\n      - [Exclude\\<T, U\\>](#excludet-u)\n      - [Extract\\<T, U\\>](#extractt-u)\n      - [NonNullable\\<T\\>](#nonnullablet)\n      - [Parameters\\<T\\>](#parameterst)\n      - [ConstructorParameters\\<T\\>](#constructorparameterst)\n      - [ReturnType\\<T\\>](#returntypet)\n      - [InstanceType\\<T\\>](#instancetypet)\n      - [ThisParameterType\\<T\\>](#thisparametertypet)\n      - [OmitThisParameter\\<T\\>](#omitthisparametert)\n      - [ThisType\\<T\\>](#thistypet)\n      - [Uppercase\\<T\\>](#uppercaset)\n      - [Lowercase\\<T\\>](#lowercaset)\n      - [Capitalize\\<T\\>](#capitalizet)\n      - [Uncapitalize\\<T\\>](#uncapitalizet)\n      - [NoInfer\\<T\\>](#noinfert)\n  - [Övrigt](#övrigt)\n    - [Fel och undantagshantering](#fel-och-undantagshantering)\n    - [Mixin-klasser](#mixin-klasser)\n    - [Asynkrona språkfunktioner](#asynkrona-språkfunktioner)\n    - [Iteratorer och generatorer](#iteratorer-och-generatorer)\n    - [TsDocs JSDoc-referens](#tsdocs-jsdoc-referens)\n    - [@types](#types)\n    - [JSX](#jsx-1)\n    - [ES6-moduler](#es6-moduler)\n    - [ES7 exponentiationsoperator](#es7-exponentiationsoperator)\n    - [for-await-of-satsen](#for-await-of-satsen)\n    - [Metaegenskapen new.target](#metaegenskapen-newtarget)\n    - [Dynamiska importuttryck](#dynamiska-importuttryck)\n    - [\"tsc –watch\"](#tsc-watch)\n    - [Non-null Assertion Operator](#non-null-assertion-operator)\n    - [Standarddeklarationer](#standarddeklarationer)\n    - [Valfri kedjning (Optional Chaining)](#valfri-kedjning-optional-chaining)\n    - [Nullish coalescing-operatorn](#nullish-coalescing-operatorn)\n    - [Mallsträngslitteraltyper (Template Literal Types)](#mallsträngslitteraltyper-template-literal-types)\n    - [Funktionsöverlagring](#funktionsöverlagring)\n    - [Rekursiva typer](#rekursiva-typer)\n    - [Rekursiva villkorstyper](#rekursiva-villkorstyper)\n    - [Stöd för ECMAScript-moduler i Node](#stöd-för-ecmascript-moduler-i-node)\n    - [Assertionsfunktioner](#assertionsfunktioner)\n    - [Variadiska tuppeltyper](#variadiska-tuppeltyper)\n    - [Inkapslingstyper (Boxed types)](#inkapslingstyper-boxed-types)\n    - [Kovarians och kontravarians i TypeScript](#kovarians-och-kontravarians-i-typescript)\n      - [Valfria variansannotationer för typparametrar](#valfria-variansannotationer-för-typparametrar)\n    - [Mallsträngsmönsterindexsignaturer](#mallsträngsmönsterindexsignaturer)\n    - [satisfies-operatorn](#satisfies-operatorn)\n    - [Importer och exporter av enbart typer](#importer-och-exporter-av-enbart-typer)\n    - [using-deklaration och explicit resurshantering](#using-deklaration-och-explicit-resurshantering)\n      - [await using-deklaration](#await-using-deklaration)\n    - [Importattribut](#importattribut)\n<!-- markdownlint-enable MD004 -->\n\n## Introduktion\n\nVälkommen till Den koncisa TypeScript-boken! Denna guide utrustar dig med väsentlig kunskap och praktiska färdigheter för effektiv TypeScript-utveckling. Upptäck nyckelkoncept och tekniker för att skriva ren, robust kod. Oavsett om du är nybörjare eller en erfaren utvecklare fungerar denna bok både som en omfattande guide och en praktisk referens för att utnyttja TypeScripts kraft i dina projekt.\n\nDenna bok täcker TypeScript 5.2.\n\n## Om författaren\n\nSimone Poggiali är en erfaren Staff Engineer med en passion för att skriva professionell kod sedan 90-talet. Under sin internationella karriär har han bidragit till många projekt för ett brett spektrum av kunder, från startups till stora organisationer. Framstående företag som HelloFresh, Siemens, O2, Leroy Merlin och Snowplow har dragit nytta av hans expertis och engagemang.\n\nDu kan nå Simone Poggiali på följande plattformar:\n\n* LinkedIn: [https://www.linkedin.com/in/simone-poggiali](https://www.linkedin.com/in/simone-poggiali)\n* GitHub: [https://github.com/gibbok](https://github.com/gibbok)\n* X.com: [https://x.com/gibbok_coding](https://x.com/gibbok_coding)\n* E-post: gibbok.coding📧gmail.com\n\nFullständig lista över bidragsgivare: [https://github.com/gibbok/typescript-book/graphs/contributors](https://github.com/gibbok/typescript-book/graphs/contributors)\n\n## Introduktion till TypeScript\n\n### Vad är TypeScript?\n\nTypeScript är ett starkt typat programmeringsspråk som bygger på JavaScript. Det designades ursprungligen av Anders Hejlsberg 2012 och utvecklas och underhålls för närvarande av Microsoft som ett öppen källkod-projekt.\n\nTypeScript kompileras till JavaScript och kan köras i vilken JavaScript-runtime som helst (t.ex. en webbläsare eller Node.js på en server).\n\nDet stöder flera programmeringsparadigm såsom funktionell, generisk, imperativ och objektorienterad programmering, och är ett kompilerat (transpilerat) språk som konverteras till JavaScript före exekvering.\n\n### Varför TypeScript?\n\nTypeScript är ett starkt typat språk som hjälper till att förhindra vanliga programmeringsmisstag och undvika vissa typer av körtidsfel innan programmet körs.\n\nEtt starkt typat språk gör det möjligt för utvecklaren att specificera olika programbegränsningar och beteenden i datatypsdefinitionerna, vilket underlättar möjligheten att verifiera programvarans korrekthet och förhindra defekter. Detta är särskilt värdefullt i storskaliga applikationer.\n\nNågra av fördelarna med TypeScript:\n\n* Statisk typning, valfritt starkt typad\n* Typinferens\n* Tillgång till ES6- och ES7-funktioner\n* Plattforms- och webbläsarkompatibilitet\n* Verktygsstöd med IntelliSense\n\n### TypeScript och JavaScript\n\nTypeScript skrivs i `.ts`- eller `.tsx`-filer, medan JavaScript-filer skrivs i `.js`- eller `.jsx`-filer.\n\nFiler med tillägget `.tsx` eller `.jsx` kan innehålla JavaScript Syntax Extension JSX, som används i React för UI-utveckling.\n\nTypeScript är en typad supermängd av JavaScript (ECMAScript 2015) vad gäller syntax. All JavaScript-kod är giltig TypeScript-kod, men det omvända är inte alltid sant.\n\nBetrakta till exempel en funktion i en JavaScript-fil med tillägget `.js`, som följande:\n\n<!-- skip -->\n```typescript\nconst sum = (a, b) => a + b;\n```\n\nFunktionen kan konverteras och användas i TypeScript genom att ändra filtillägget till `.ts`. Men om samma funktion annoteras med TypeScript-typer kan den inte köras i någon JavaScript-runtime utan kompilering. Följande TypeScript-kod kommer att producera ett syntaxfel om den inte kompileras:\n\n<!-- skip -->\n```typescript\nconst sum = (a: number, b: number): number => a + b;\n```\n\nTypeScript designades för att upptäcka möjliga undantag som kan uppstå vid körning under kompileringstiden genom att låta utvecklaren definiera avsikten med typannoteringar. Dessutom kan TypeScript också fånga problem om ingen typannotering tillhandahålls. Till exempel specificerar följande kodavsnitt inga TypeScript-typer:\n\n<!-- skip -->\n```typescript\nconst items = [{ x: 1 }, { x: 2 }];\nconst result = items.filter(item => item.y);\n```\n\nI detta fall upptäcker TypeScript ett fel och rapporterar:\n\n```text\nProperty 'y' does not exist on type '{ x: number; }'.\n```\n\nTypeScripts typsystem är till stor del influerat av körtidsbeteendet hos JavaScript. Till exempel kan additionsoperatorn (+), som i JavaScript kan utföra antingen strängkonkatenering eller numerisk addition, modelleras på samma sätt i TypeScript:\n\n```typescript\nconst result = '1' + 1; // Result is of type string\n```\n\nTeamet bakom TypeScript har fattat ett medvetet beslut att flagga ovanlig användning av JavaScript som fel. Betrakta till exempel följande giltiga JavaScript-kod:\n\n<!-- skip -->\n```typescript\nconst result = 1 + true; // In JavaScript, the result is equal 2\n```\n\nDock kastar TypeScript ett fel:\n\n```text\nOperator '+' cannot be applied to types 'number' and 'boolean'.\n```\n\nDetta fel uppstår eftersom TypeScript strikt upprätthåller typkompatibilitet, och i detta fall identifierar det en ogiltig operation mellan en number och en boolean.\n\n### TypeScript-kodgenerering\n\nTypeScript-kompilatorn har två huvudansvar: kontrollera typfel och kompilera till JavaScript. Dessa två processer är oberoende av varandra. Typer påverkar inte kodens exekvering i en JavaScript-runtime, eftersom de raderas helt under kompileringen. TypeScript kan fortfarande producera JavaScript även vid typfel.\nHär är ett exempel på TypeScript-kod med ett typfel:\n\n<!-- skip -->\n```typescript\nconst add = (a: number, b: number): number => a + b;\nconst result = add('x', 'y'); // Argument of type 'string' is not assignable to parameter of type 'number'.\n```\n\nTrots detta kan den fortfarande producera körbar JavaScript-utdata:\n\n<!-- skip -->\n```typescript\n'use strict';\nconst add = (a, b) => a + b;\nconst result = add('x', 'y'); // xy\n```\n\nDet är inte möjligt att kontrollera TypeScript-typer vid körning. Till exempel:\n\n<!-- skip -->\n```typescript\ninterface Animal {\n    name: string;\n}\ninterface Dog extends Animal {\n    bark: () => void;\n}\ninterface Cat extends Animal {\n    meow: () => void;\n}\nconst makeNoise = (animal: Animal) => {\n    if (animal instanceof Dog) {\n        // 'Dog' only refers to a type, but is being used as a value here.\n        // ...\n    }\n};\n```\n\nEftersom typerna raderas efter kompilering finns det inget sätt att köra denna kod i JavaScript. För att känna igen typer vid körning behöver vi använda en annan mekanism. TypeScript erbjuder flera alternativ, där ett vanligt är \"tagged union\". Till exempel:\n\n```typescript\ninterface Dog {\n    kind: 'dog'; // Tagged union\n    bark: () => void;\n}\ninterface Cat {\n    kind: 'cat'; // Tagged union\n    meow: () => void;\n}\ntype Animal = Dog | Cat;\n\nconst makeNoise = (animal: Animal) => {\n    if (animal.kind === 'dog') {\n        animal.bark();\n    } else {\n        animal.meow();\n    }\n};\n\nconst dog: Dog = {\n    kind: 'dog',\n    bark: () => console.log('bark'),\n};\nmakeNoise(dog);\n```\n\nEgenskapen \"kind\" är ett värde som kan användas vid körning för att särskilja mellan objekt i JavaScript.\n\nDet är också möjligt att ett värde vid körning har en annan typ än den som deklarerades i typdeklarationen. Till exempel om utvecklaren har misstolkat en API-typ och annoterat den felaktigt.\n\nTypeScript är en supermängd av JavaScript, så nyckelordet \"class\" kan användas som en typ och ett värde vid körning.\n\n```typescript\nclass Animal {\n    constructor(public name: string) {}\n}\nclass Dog extends Animal {\n    constructor(\n        public name: string,\n        public bark: () => void\n    ) {\n        super(name);\n    }\n}\nclass Cat extends Animal {\n    constructor(\n        public name: string,\n        public meow: () => void\n    ) {\n        super(name);\n    }\n}\ntype Mammal = Dog | Cat;\n\nconst makeNoise = (mammal: Mammal) => {\n    if (mammal instanceof Dog) {\n        mammal.bark();\n    } else {\n        mammal.meow();\n    }\n};\n\nconst dog = new Dog('Fido', () => console.log('bark'));\nmakeNoise(dog);\n```\n\nI JavaScript har en \"class\" en \"prototype\"-egenskap, och \"instanceof\"-operatorn kan användas för att testa om prototype-egenskapen för en konstruktor förekommer någonstans i prototypkedjan för ett objekt.\n\nTypeScript har ingen effekt på körtidsprestanda, eftersom alla typer raderas. Dock introducerar TypeScript viss overhead vid byggtid.\n\n### Modernt JavaScript nu (Downleveling)\n\nTypeScript kan kompilera kod till vilken utgiven version av JavaScript som helst sedan ECMAScript 3 (1999). Detta innebär att TypeScript kan transpilera kod från de senaste JavaScript-funktionerna till äldre versioner, en process som kallas Downleveling. Detta möjliggör användning av modernt JavaScript samtidigt som maximal kompatibilitet med äldre körtidsmiljöer bibehålls.\n\nDet är viktigt att notera att vid transpilering till en äldre version av JavaScript kan TypeScript generera kod som kan medföra en prestandaoverhead jämfört med nativa implementeringar.\n\nHär är några av de moderna JavaScript-funktioner som kan användas i TypeScript:\n\n* ECMAScript-moduler istället för AMD-style \"define\"-callbacks eller CommonJS \"require\"-satser.\n* Klasser istället för prototyper.\n* Variabeldeklaration med \"let\" eller \"const\" istället för \"var\".\n* \"for-of\"-loop eller \".forEach\" istället för den traditionella \"for\"-loopen.\n* Pilfunktioner istället för funktionsuttryck.\n* Destruktureringstilldelning.\n* Förkortade egenskaps-/metodnamn och beräknade egenskapsnamn.\n* Standardparametrar för funktioner.\n\nGenom att utnyttja dessa moderna JavaScript-funktioner kan utvecklare skriva mer uttrycksfull och koncis kod i TypeScript.\n\n## Komma igång med TypeScript\n\n### Installation\n\nVisual Studio Code erbjuder utmärkt stöd för TypeScript-språket men inkluderar inte TypeScript-kompilatorn. För att installera TypeScript-kompilatorn kan du använda en pakethanterare som npm eller yarn:\n\n```shell\nnpm install typescript --save-dev\n```\n\neller\n\n```shell\nyarn add typescript --dev\n```\n\nSe till att committa den genererade lockfilen för att säkerställa att varje teammedlem använder samma version av TypeScript.\n\nFör att köra TypeScript-kompilatorn kan du använda följande kommandon\n\n```shell\nnpx tsc\n```\n\neller\n\n```shell\nyarn tsc\n```\n\nDet rekommenderas att installera TypeScript projektvis snarare än globalt, eftersom det ger en mer förutsägbar byggprocess. För enstaka tillfällen kan du dock använda följande kommando:\n\n```shell\nnpx tsc\n```\n\neller installera det globalt:\n\n```shell\nnpm install -g typescript\n```\n\nOm du använder Microsoft Visual Studio kan du hämta TypeScript som ett paket i NuGet för dina MSBuild-projekt. I NuGet Package Manager Console kör du följande kommando:\n\n```shell\nInstall-Package Microsoft.TypeScript.MSBuild\n```\n\nUnder TypeScript-installationen installeras två körbara filer: \"tsc\" som TypeScript-kompilatorn och \"tsserver\" som den fristående TypeScript-servern. Den fristående servern innehåller kompilatorn och språktjänster som kan användas av redigerare och IDE:er för att tillhandahålla intelligent kodkomplettering.\n\nDessutom finns det flera TypeScript-kompatibla transpilerare tillgängliga, såsom Babel (via ett plugin) eller swc. Dessa transpilerare kan användas för att konvertera TypeScript-kod till andra målspråk eller versioner.\n\n### Konfiguration\n\nTypeScript kan konfigureras med hjälp av tsc CLI-alternativ eller genom att använda en dedikerad konfigurationsfil kallad tsconfig.json som placeras i projektets rot.\n\nFör att generera en tsconfig.json-fil förfylld med rekommenderade inställningar kan du använda följande kommando:\n\n```shell\ntsc --init\n```\n\nNär kommandot `tsc` körs lokalt kommer TypeScript att kompilera koden med den konfiguration som anges i den närmaste tsconfig.json-filen.\n\nHär är några exempel på CLI-kommandon som körs med standardinställningarna:\n\n```shell\ntsc main.ts // Compile a specific file (main.ts) to JavaScript\ntsc src/*.ts // Compile any .ts files under the 'src' folder to JavaScript\ntsc app.ts util.ts --outfile index.js // Compile two TypeScript files (app.ts and util.ts) into a single JavaScript file (index.js)\n```\n\n### TypeScript-konfigurationsfil\n\nEn tsconfig.json-fil används för att konfigurera TypeScript-kompilatorn (tsc). Vanligtvis läggs den till i projektets rot, tillsammans med filen `package.json`.\n\nObservera:\n\n* tsconfig.json accepterar kommentarer även om det är i json-format.\n* Det är tillrådligt att använda denna konfigurationsfil istället för kommandoradsalternativ.\n\nPå följande länk hittar du den fullständiga dokumentationen och dess schema:\n\n[https://www.typescriptlang.org/tsconfig](https://www.typescriptlang.org/tsconfig)\n\n[https://www.typescriptlang.org/tsconfig/](https://www.typescriptlang.org/tsconfig/)\n\nFöljande representerar en lista över de vanligaste och mest användbara konfigurationerna:\n\n#### target\n\nEgenskapen \"target\" används för att ange vilken version av JavaScript ECMAScript-version din TypeScript ska generera/kompilera till. För moderna webbläsare är ES6 ett bra alternativ, för äldre webbläsare rekommenderas ES5.\n\n#### lib\n\nEgenskapen \"lib\" används för att ange vilka biblioteksfiler som ska inkluderas vid kompilering. TypeScript inkluderar automatiskt API:er för funktioner som anges i \"target\"-egenskapen, men det är möjligt att utelämna eller välja specifika bibliotek för särskilda behov. Till exempel, om du arbetar med ett serverprojekt kan du exkludera \"DOM\"-biblioteket, som bara är användbart i en webbläsarmiljö.\n\n#### strict\n\nEgenskapen \"strict\" möjliggör starkare garantier och förbättrar typsäkerheten. Det är tillrådligt att alltid inkludera denna egenskap i ditt projekts tsconfig.json-fil. Att aktivera egenskapen \"strict\" gör att TypeScript:\n\n* Genererar kod med \"use strict\" för varje källfil.\n* Beaktar \"null\" och \"undefined\" i typkontrollprocessen.\n* Inaktiverar användningen av typen \"any\" när inga typannoteringar finns.\n* Ger ett fel vid användning av \"this\"-uttrycket, som annars skulle innebära typen \"any\".\n\n#### module\n\nEgenskapen \"module\" anger det modulsystem som stöds för det kompilerade programmet. Vid körning används en modulladdare för att lokalisera och köra beroenden baserat på det angivna modulsystemet.\n\nDe vanligaste modulladdarna som används i JavaScript är Node.js CommonJS för serversidans applikationer och RequireJS för AMD-moduler i webbläsarbaserade webbapplikationer. TypeScript kan generera kod för olika modulsystem, inklusive UMD, System, ESNext, ES2015/ES6 och ES2020.\n\nObservera: Modulsystemet bör väljas baserat på målmiljön och den modulladdningsmekanism som finns tillgänglig i den miljön.\n\n#### moduleResolution\n\nEgenskapen \"moduleResolution\" anger strategin för modulupplösning. Använd \"node\" för modern TypeScript-kod, strategin \"classic\" används bara för gamla versioner av TypeScript (före 1.6).\n\n#### esModuleInterop\n\nEgenskapen \"esModuleInterop\" gör det möjligt att importera standard från CommonJS-moduler som inte exporterade med \"default\"-egenskapen. Denna egenskap tillhandahåller en shim för att säkerställa kompatibilitet i den genererade JavaScript-koden. Efter att ha aktiverat detta alternativ kan vi använda `import MyLibrary from \"my-library\"` istället för `import * as MyLibrary from \"my-library\"`.\n\n#### jsx\n\nEgenskapen \"jsx\" gäller bara för .tsx-filer som används i ReactJS och styr hur JSX-konstruktioner kompileras till JavaScript. Ett vanligt alternativ är \"preserve\" som kompilerar till en .jsx-fil och behåller JSX oförändrat så att det kan skickas vidare till olika verktyg som Babel för ytterligare transformationer.\n\n#### skipLibCheck\n\nEgenskapen \"skipLibCheck\" hindrar TypeScript från att typkontrollera hela importerade tredjepartspaket. Denna egenskap minskar kompileringstiden för ett projekt. TypeScript kommer fortfarande att kontrollera din kod mot typdefinitionerna som tillhandahålls av dessa paket.\n\n#### files\n\nEgenskapen \"files\" anger för kompilatorn en lista med filer som alltid måste inkluderas i programmet.\n\n#### include\n\n<!-- markdownlint-disable MD049 -->\nEgenskapen \"include\" anger för kompilatorn en lista med filer som vi vill inkludera. Denna egenskap tillåter glob-liknande mönster, såsom \"\\*_\" för valfri underkatalog, \"_\" för valfritt filnamn och \"?\" för valfria tecken.\n<!-- markdownlint-enable MD049 -->\n\n#### exclude\n\nEgenskapen \"exclude\" anger för kompilatorn en lista med filer som inte bör inkluderas i kompileringen. Detta kan inkludera filer som \"node_modules\" eller testfiler.\nObservera: tsconfig.json tillåter kommentarer.\n\n### importHelpers\n\nTypeScript använder hjälpkod när det genererar kod för vissa avancerade eller nedåtkompatibla JavaScript-funktioner. Som standard dupliceras dessa hjälpfunktioner i filer som använder dem. Alternativet `importHelpers` importerar dessa hjälpfunktioner från modulen `tslib` istället, vilket gör JavaScript-utdata mer effektiv.\n\n### Råd vid migrering till TypeScript\n\nFör stora projekt rekommenderas en gradvis övergång där TypeScript- och JavaScript-kod initialt samexisterar. Bara små projekt kan migreras till TypeScript på en gång.\n\nDet första steget i denna övergång är att introducera TypeScript i byggkedjeprocessen. Detta kan göras genom att använda kompilatoralternativet \"allowJs\", som tillåter att .ts- och .tsx-filer samexisterar med befintliga JavaScript-filer. Eftersom TypeScript faller tillbaka till typen \"any\" för en variabel när det inte kan härleda typen från JavaScript-filer, rekommenderas det att inaktivera \"noImplicitAny\" i dina kompilatoralternativ i början av migreringen.\n\nDet andra steget är att säkerställa att dina JavaScript-tester fungerar tillsammans med TypeScript-filer så att du kan köra tester allt eftersom du konverterar varje modul. Om du använder Jest, överväg att använda `ts-jest`, som gör det möjligt att testa TypeScript-projekt med Jest.\n\nDet tredje steget är att inkludera typdeklarationer för tredjepartsbibliotek i ditt projekt. Dessa deklarationer kan hittas antingen medföljande eller på DefinitelyTyped. Du kan söka efter dem med [https://www.typescriptlang.org/dt/search](https://www.typescriptlang.org/dt/search) och installera dem med:\n\n```shell\nnpm install --save-dev @types/package-name\n```\n\neller\n\n```shell\nyarn add --dev @types/package-name\n```\n\nDet fjärde steget är att migrera modul för modul med en nedifrån-och-upp-metod, genom att följa ditt beroendeträd med start från löven. Tanken är att börja konvertera moduler som inte är beroende av andra moduler. För att visualisera beroendegrafer kan du använda verktyget \"madge\".\n\nBra kandidatmoduler för dessa initiala konverteringar är hjälpfunktioner och kod relaterad till externa API:er eller specifikationer. Det är möjligt att automatiskt generera TypeScript-typdefinitioner från Swagger-kontrakt, GraphQL- eller JSON-scheman som kan inkluderas i ditt projekt.\n\nNär det inte finns några specifikationer eller officiella scheman tillgängliga kan du generera typer från rådata, såsom JSON som returneras av en server. Det rekommenderas dock att generera typer från specifikationer istället för data för att undvika att missa specialfall.\n\nUnder migreringen bör du avstå från kodrefaktorisering och fokusera enbart på att lägga till typer i dina moduler.\n\nDet femte steget är att aktivera \"noImplicitAny\", vilket kommer att se till att alla typer är kända och definierade, vilket ger en bättre TypeScript-upplevelse för ditt projekt.\n\nUnder migreringen kan du använda direktivet `@ts-check`, som aktiverar TypeScript-typkontroll i en JavaScript-fil. Detta direktiv tillhandahåller en lös version av typkontroll och kan initialt användas för att identifiera problem i JavaScript-filer. När `@ts-check` inkluderas i en fil kommer TypeScript att försöka härleda definitioner med hjälp av kommentarer i JSDoc-stil. Överväg dock att använda JSDoc-annoteringar bara i ett mycket tidigt skede av migreringen.\n\nÖverväg att behålla standardvärdet för `noEmitOnError` i din tsconfig.json som false. Detta gör att du kan generera JavaScript-källkod även om fel rapporteras.\n\n## Utforska typsystemet\n\n### TypeScript-språktjänsten\n\nTypeScript-språktjänsten, även känd som tsserver, erbjuder olika funktioner såsom felrapportering, diagnostik, kompilera-vid-sparning, namnbyte, gå till definition, kompletteringslistor, signaturhjälp och mer. Den används främst av integrerade utvecklingsmiljöer (IDE:er) för att ge IntelliSense-stöd. Den integreras sömlöst med Visual Studio Code och används av verktyg som Conquer of Completion (Coc).\n\nUtvecklare kan utnyttja ett dedikerat API och skapa sina egna anpassade språktjänstplugin för att förbättra TypeScript-redigeringsupplevelsen. Detta kan vara särskilt användbart för att implementera speciella linting-funktioner eller möjliggöra automatisk komplettering för ett anpassat mallspråk.\n\n<!-- markdownlint-disable MD044 -->\nEtt exempel på ett verkligt anpassat plugin är \"typescript-styled-plugin\", som tillhandahåller syntaxfelrapportering och IntelliSense-stöd för CSS-egenskaper i styled components.\n<!-- markdownlint-enable MD044 -->\n\nFör mer information och snabbstartsguider kan du hänvisa till den officiella TypeScript-wikin på GitHub: [https://github.com/microsoft/TypeScript/wiki/](https://github.com/microsoft/TypeScript/wiki/)\n\n### Strukturell typning\n\nTypeScript är baserat på ett strukturellt typsystem. Detta innebär att kompatibiliteten och ekvivalensen hos typer bestäms av typens faktiska struktur eller definition, snarare än dess namn eller plats för deklaration, som i nominativa typsystem som C# eller C.\n\nTypeScripts strukturella typsystem designades baserat på hur JavaScripts dynamiska duck typing-system fungerar vid körning.\n\nFöljande exempel är giltig TypeScript-kod. Som du kan observera har \"X\" och \"Y\" samma medlem \"a\", även om de har olika deklarationsnamn. Typerna bestäms av deras strukturer, och i detta fall, eftersom strukturerna är desamma, är de kompatibla och giltiga.\n\n```typescript\ntype X = {\n    a: string;\n};\ntype Y = {\n    a: string;\n};\nconst x: X = { a: 'a' };\nconst y: Y = x; // Valid\n```\n\n### Grundläggande jämförelseregler i TypeScript\n\nTypeScripts jämförelseprocess är rekursiv och utförs på typer som är nästlade på valfri nivå.\n\nEn typ \"X\" är kompatibel med \"Y\" om \"Y\" har åtminstone samma medlemmar som \"X\".\n\n```typescript\ntype X = {\n    a: string;\n};\nconst y = { a: 'A', b: 'B' }; // Valid, as it has at least the same members as X\nconst r: X = y;\n```\n\nFunktionsparametrar jämförs efter typer, inte efter deras namn:\n\n```typescript\ntype X = (a: number) => void;\ntype Y = (a: number) => void;\nlet x: X = (j: number) => undefined;\nlet y: Y = (k: number) => undefined;\ny = x; // Valid\nx = y; // Valid\n```\n\nFunktionens returtyper måste vara desamma:\n\n<!-- skip -->\n```typescript\ntype X = (a: number) => undefined;\ntype Y = (a: number) => number;\nlet x: X = (a: number) => undefined;\nlet y: Y = (a: number) => 1;\ny = x; // Invalid\nx = y; // Invalid\n```\n\nReturtypen för en källfunktion måste vara en undertyp av returtypen för en målfunktion:\n\n<!-- skip -->\n```typescript\nlet x = () => ({ a: 'A' });\nlet y = () => ({ a: 'A', b: 'B' });\nx = y; // Valid\ny = x; // Invalid member b is missing\n```\n\nAtt utelämna funktionsparametrar är tillåtet, eftersom det är vanlig praxis i JavaScript, till exempel vid användning av \"Array.prototype.map()\":\n\n```typescript\n[1, 2, 3].map((element, _index, _array) => element + 'x');\n```\n\nDärför är följande typdeklarationer helt giltiga:\n\n```typescript\ntype X = (a: number) => undefined;\ntype Y = (a: number, b: number) => undefined;\nlet x: X = (a: number) => undefined;\nlet y: Y = (a: number) => undefined; // Missing b parameter\ny = x; // Valid\n```\n\nEventuella ytterligare valfria parametrar i källtypen är giltiga:\n\n```typescript\ntype X = (a: number, b?: number, c?: number) => undefined;\ntype Y = (a: number) => undefined;\nlet x: X = a => undefined;\nlet y: Y = a => undefined;\ny = x; // Valid\nx = y; //Valid\n```\n\nEventuella valfria parametrar i måltypen utan motsvarande parametrar i källtypen är giltiga och utgör inte ett fel:\n\n```typescript\ntype X = (a: number) => undefined;\ntype Y = (a: number, b?: number) => undefined;\nlet x: X = a => undefined;\nlet y: Y = a => undefined;\ny = x; // Valid\nx = y; // Valid\n```\n\nRest-parametern behandlas som en oändlig serie av valfria parametrar:\n\n```typescript\ntype X = (a: number, ...rest: number[]) => undefined;\nlet x: X = a => undefined; //valid\n```\n\nFunktioner med överlagringar är giltiga om överlagringssignaturen är kompatibel med dess implementeringssignatur:\n\n<!-- skip -->\n```typescript\nfunction x(a: string): void;\nfunction x(a: string, b: number): void;\nfunction x(a: string, b?: number): void {\n    console.log(a, b);\n}\nx('a'); // Valid\nx('a', 1); // Valid\n\nfunction y(a: string): void; // Invalid, not compatible with implementation signature\nfunction y(a: string, b: number): void;\nfunction y(a: string, b: number): void {\n    console.log(a, b);\n}\ny('a');\ny('a', 1);\n```\n\nJämförelse av funktionsparametrar lyckas om käll- och målparametrarna kan tilldelas supertyper eller undertyper (bivarians).\n\n```typescript\n// Supertype\nclass X {\n    a: string;\n    constructor(value: string) {\n        this.a = value;\n    }\n}\n// Subtype\nclass Y extends X {}\n// Subtype\nclass Z extends X {}\n\ntype GetA = (x: X) => string;\nconst getA: GetA = x => x.a;\n\n// Bivariance does accept supertypes\nconsole.log(getA(new X('x'))); // Valid\nconsole.log(getA(new Y('Y'))); // Valid\nconsole.log(getA(new Z('z'))); // Valid\n```\n\nEnums är jämförbara och giltiga med tal och vice versa, men att jämföra Enum-värden från olika Enum-typer är ogiltigt.\n\n<!-- skip -->\n```typescript\nenum X {\n    A,\n    B,\n}\nenum Y {\n    A,\n    B,\n    C,\n}\nconst xa: number = X.A; // Valid\nconst ya: Y = 0; // Valid\nX.A === Y.A; // Invalid\n```\n\nInstanser av en klass genomgår en kompatibilitetskontroll för sina privata och skyddade medlemmar:\n\n<!-- skip -->\n```typescript\nclass X {\n    public a: string;\n    constructor(value: string) {\n        this.a = value;\n    }\n}\n\nclass Y {\n    private a: string;\n    constructor(value: string) {\n        this.a = value;\n    }\n}\n\nlet x: X = new Y('y'); // Invalid\n```\n\nJämförelsekontrollen tar inte hänsyn till den olika arvshierarkin, till exempel:\n\n```typescript\nclass X {\n    public a: string;\n    constructor(value: string) {\n        this.a = value;\n    }\n}\nclass Y extends X {\n    public a: string;\n    constructor(value: string) {\n        super(value);\n        this.a = value;\n    }\n}\nclass Z {\n    public a: string;\n    constructor(value: string) {\n        this.a = value;\n    }\n}\nlet x: X = new X('x');\nlet y: Y = new Y('y');\nlet z: Z = new Z('z');\nx === y; // Valid\nx === z; // Valid even if z is from a different inheritance hierarchy\n```\n\nGenerics jämförs med hjälp av deras strukturer baserat på den resulterande typen efter tillämpning av den generiska parametern. Bara slutresultatet jämförs som en icke-generisk typ.\n\n<!-- skip -->\n```typescript\ninterface X<T> {\n    a: T;\n}\nlet x: X<number> = { a: 1 };\nlet y: X<string> = { a: 'a' };\nx === y; // Invalid as the type argument is used in the final structure\n```\n\n```typescript\ninterface X<T> {}\nconst x: X<number> = 1;\nconst y: X<string> = 'a';\nx === y; // Valid as the type argument is not used in the final structure\n```\n\nNär generics inte har sitt typargument specificerat behandlas alla ospecificerade argument som typer med \"any\":\n\n```typescript\ntype X = <T>(x: T) => T;\ntype Y = <K>(y: K) => K;\nlet x: X = x => x;\nlet y: Y = y => y;\nx = y; // Valid\n```\n\nKom ihåg:\n\n<!-- skip -->\n```typescript\nlet a: number = 1;\nlet b: number = 2;\na = b; // Valid, everything is assignable to itself\n\nlet c: any;\nc = 1; // Valid, all types are assignable to any\n\nlet d: unknown;\nd = 1; // Valid, all types are assignable to unknown\n\nlet e: unknown;\nlet e1: unknown = e; // Valid, unknown is only assignable to itself and any\nlet e2: any = e; // Valid\nlet e3: number = e; // Invalid\n\nlet f: never;\nf = 1; // Invalid, nothing is assignable to never\n\nlet g: void;\nlet g1: any;\ng = 1; // Invalid, void is not assignable to or from anything expect any\ng = g1; // Valid\n```\n\nObservera att när \"strictNullChecks\" är aktiverat behandlas \"null\" och \"undefined\" på liknande sätt som \"void\"; annars liknar de \"never\".\n\n### Typer som mängder\n\nI TypeScript är en typ en mängd av möjliga värden. Denna mängd kallas även typens domän. Varje värde av en typ kan ses som ett element i en mängd. En typ fastställer de begränsningar som varje element i mängden måste uppfylla för att betraktas som en medlem av den mängden.\nTypeScripts primära uppgift är att kontrollera och verifiera om en mängd är en delmängd av en annan.\n\nTypeScript stöder olika typer av mängder:\n\n| Mängdterm              | TypeScript                      | Anteckningar                                                                                                       |\n| ---------------------- | ------------------------------- | ------------------------------------------------------------------------------------------------------------------ |\n| Tom mängd              | never                           | \"never\" innehåller ingenting förutom sig själv                                                                     |\n| Enelement-mängd        | undefined / null / literal type |                                                                                                                    |\n| Ändlig mängd           | boolean / union                 |                                                                                                                    |\n| Oändlig mängd          | string / number / object        |                                                                                                                    |\n| Universell mängd       | any / unknown                   | Varje element är medlem i \"any\" och varje mängd är en delmängd av den / \"unknown\" är en typsäker motsvarighet till \"any\" |\n\nHär är några exempel:\n\n| TypeScript            | Mängdterm              | Exempel                                                                         |\n| --------------------- | ---------------------- | ------------------------------------------------------------------------------- |\n| never                 | ∅ (tom mängd)          | const x: never = 'x'; // Error: Type 'string' is not assignable to type 'never' |\n|                       |                        |\n| Literal type          | Enelement-mängd        | type X = 'X';                                                                   |\n|                       |                        | type Y = 7;                                                                     |\n|                       |                        |\n| Värde tilldelbart till T | Värde ∈ T (medlem av)  | type XY = 'X' \\| 'Y';                                                           |\n|                       |                        | const x: XY = 'X';                                                              |\n|                       |                        |\n| T1 tilldelbart till T2   | T1 ⊆ T2 (delmängd av)  | type XY = 'X' \\| 'Y';                                                           |\n|                       |                        | const x: XY = 'X';                                                              |\n|                       |                        | const j: XY = 'J'; // Type '\"J\"' is not assignable to type 'XY'.                |\n|                       |                        |                                                                                 |\n| T1 extends T2         | T1 ⊆ T2 (delmängd av)  | type X = 'X' extends string ? true : false;                                     |\n|                       |                        |\n| T1 \\| T2              | T1 ∪ T2 (union)        | type XY = 'X' \\| 'Y';                                                           |\n|                       |                        | type JK = 1 \\| 2;                                                               |\n|                       |                        |\n| T1 & T2               | T1 ∩ T2 (snitt)        | type X = \\{ a: string \\}                                                          |\n|                       |                        | type Y = \\{ b: string \\}                                                          |\n|                       |                        | type XY = X & Y                                                                 |\n|                       |                        | const x: XY = \\{ a: 'a', b: 'b' \\}                                                |\n|                       |                        |\n| unknown               | Universell mängd       | const x: unknown = 1                                                            |\n\nEn union, (T1 | T2) skapar en bredare mängd (båda):\n\n```typescript\ntype X = {\n    a: string;\n};\ntype Y = {\n    b: string;\n};\ntype XY = X | Y;\nconst r: XY = { a: 'a', b: 'x' }; // Valid\n```\n\nEn intersektion, (T1 & T2) skapar en smalare mängd (endast delade):\n\n<!-- skip -->\n```typescript\ntype X = {\n    a: string;\n};\ntype Y = {\n    a: string;\n    b: string;\n};\ntype XY = X & Y;\nconst r: XY = { a: 'a' }; // Invalid\nconst j: XY = { a: 'a', b: 'b' }; // Valid\n```\n\nNyckelordet `extends` kan betraktas som \"delmängd av\" i detta sammanhang. Det sätter en begränsning för en typ. När extends används med en generisk typ, behandlas den generiska typen som en oändlig mängd och begränsas till en mer specifik typ.\nObservera att `extends` inte har något att göra med hierarki i OOP-bemärkelse (det finns inget sådant koncept i TypeScript).\nTypeScript arbetar med mängder och har ingen strikt hierarki. Faktum är att, som i exemplet nedan, två typer kan överlappa utan att någon av dem är en undertyp av den andra (TypeScript betraktar strukturen, formen på objekten).\n\n```typescript\ninterface X {\n    a: string;\n}\ninterface Y extends X {\n    b: string;\n}\ninterface Z extends Y {\n    c: string;\n}\nconst z: Z = { a: 'a', b: 'b', c: 'c' };\ninterface X1 {\n    a: string;\n}\ninterface Y1 {\n    a: string;\n    b: string;\n}\ninterface Z1 {\n    a: string;\n    b: string;\n    c: string;\n}\nconst z1: Z1 = { a: 'a', b: 'b', c: 'c' };\n\nconst r: Z1 = z; // Valid\n```\n\n### Tilldela en typ: Typdeklarationer och Typpåståenden\n\nEn typ kan tilldelas på olika sätt i TypeScript:\n\n#### Typdeklaration\n\nI följande exempel använder vi x: X (\": Type\") för att deklarera en typ för variabeln x.\n\n```typescript\ntype X = {\n    a: string;\n};\n\n// Type declaration\nconst x: X = {\n    a: 'a',\n};\n```\n\nOm variabeln inte har det angivna formatet kommer TypeScript att rapportera ett fel. Till exempel:\n\n<!-- skip -->\n```typescript\ntype X = {\n    a: string;\n};\n\nconst x: X = {\n    a: 'a',\n    b: 'b', // Error: Object literal may only specify known properties\n};\n```\n\n#### Typpåstående\n\nDet är möjligt att lägga till ett påstående genom att använda nyckelordet `as`. Detta talar om för kompilatorn att utvecklaren har mer information om en typ och tystar eventuella fel som kan uppstå.\n\nTill exempel:\n\n```typescript\ntype X = {\n    a: string;\n};\nconst x = {\n    a: 'a',\n    b: 'b',\n} as X;\n```\n\nI exemplet ovan påstås objektet x ha typen X med hjälp av nyckelordet as. Detta informerar TypeScript-kompilatorn om att objektet överensstämmer med den angivna typen, även om det har en extra egenskap b som inte finns i typdefinitionen.\n\nTyppåståenden är användbara i situationer där en mer specifik typ behöver anges, särskilt vid arbete med DOM:en. Till exempel:\n\n```typescript\nconst myInput = document.getElementById('my_input') as HTMLInputElement;\n```\n\nHär används typpåståendet as HTMLInputElement för att tala om för TypeScript att resultatet av getElementById ska behandlas som ett HTMLInputElement.\nTyppåståenden kan också användas för att mappa om nycklar, som visas i exemplet nedan med malliteraler:\n\n```typescript\ntype J<Type> = {\n    [Property in keyof Type as `prefix_${string &\n        Property}`]: () => Type[Property];\n};\ntype X = {\n    a: string;\n    b: number;\n};\ntype Y = J<X>;\n```\n\nI detta exempel använder typen `J<Type>` en mappad typ med en malliteral för att mappa om nycklarna i Type. Den skapar nya egenskaper med ett \"prefix_\" tillagt till varje nyckel, och deras motsvarande värden är funktioner som returnerar de ursprungliga egenskapsvärdena.\n\nDet är värt att notera att när man använder ett typpåstående kommer TypeScript inte att utföra kontroll av överskottsegenskaper. Därför är det generellt att föredra att använda en typdeklaration när objektets struktur är känd i förväg.\n\n#### Omgivande deklarationer\n\nOmgivande deklarationer är filer som beskriver typer för JavaScript-kod. De har filnamnsformatet `.d.ts`. De importeras vanligtvis och används för att annotera befintliga JavaScript-bibliotek eller för att lägga till typer till befintliga JS-filer i ditt projekt.\n\nMånga vanliga bibliotekstyper finns på:\n[https://github.com/DefinitelyTyped/DefinitelyTyped/](https://github.com/DefinitelyTyped/DefinitelyTyped/)\n\noch kan installeras med:\n\n```shell\nnpm install --save-dev @types/library-name\n```\n\nFör dina egna omgivande deklarationer kan du importera dem med \"triple-slash\"-referensen:\n\n<!-- skip -->\n```typescript\n/// <reference path=\"./library-types.d.ts\" />\n```\n\nDu kan använda omgivande deklarationer även i JavaScript-filer med `// @ts-check`.\n\nNyckelordet `declare` möjliggör typdefinitioner för befintlig JavaScript-kod utan att importera den, och fungerar som en platshållare för typer från en annan fil eller globalt.\n\n### Egenskapskontroll och kontroll av överskottsegenskaper\n\nTypeScript bygger på ett strukturellt typsystem, men kontroll av överskottsegenskaper är en egenskap hos TypeScript som gör det möjligt att kontrollera om ett objekt har exakt de egenskaper som anges i typen.\n\nKontroll av överskottsegenskaper utförs vid tilldelning av objektliteraler till variabler eller när de skickas som argument till funktionens överskottsegenskap, till exempel.\n\n<!-- skip -->\n```typescript\ntype X = {\n    a: string;\n};\nconst y = { a: 'a', b: 'b' };\nconst x: X = y; // Valid because structural typing\nconst w: X = { a: 'a', b: 'b' }; // Invalid because excess property checking\n```\n\n### Svaga typer\n\nEn typ anses vara svag när den inte innehåller annat än en uppsättning helt valfria egenskaper:\n\n```typescript\ntype X = {\n    a?: string;\n    b?: string;\n};\n```\n\nTypeScript betraktar det som ett fel att tilldela något till en svag typ när det inte finns någon överlappning. Till exempel ger följande ett fel:\n\n<!-- skip -->\n```typescript\ntype Options = {\n    a?: string;\n    b?: string;\n};\n\nconst fn = (options: Options) => undefined;\n\nfn({ c: 'c' }); // Invalid\n```\n\nÄven om det inte rekommenderas, är det möjligt att kringgå denna kontroll genom att använda typpåstående om det behövs:\n\n```typescript\ntype Options = {\n    a?: string;\n    b?: string;\n};\nconst fn = (options: Options) => undefined;\nfn({ c: 'c' } as Options); // Valid\n```\n\nEller genom att lägga till `unknown` i indexsignaturen till den svaga typen:\n\n```typescript\ntype Options = {\n    [prop: string]: unknown;\n    a?: string;\n    b?: string;\n};\n\nconst fn = (options: Options) => undefined;\nfn({ c: 'c' }); // Valid\n```\n\n### Strikt kontroll av objektliteraler (Freshness)\n\nStrikt kontroll av objektliteraler, ibland kallad \"freshness\", är en funktion i TypeScript som hjälper till att fånga överskotts- eller felstavade egenskaper som annars skulle gå obemärkta vid normala strukturella typkontroller.\n\nNär man skapar en objektliteral betraktar TypeScript-kompilatorn den som \"fresh\". Om objektliteralen tilldelas till en variabel eller skickas som parameter kommer TypeScript att ge ett fel om objektliteralen anger egenskaper som inte finns i måltypen.\n\nDock försvinner \"freshness\" när en objektliteral breddas eller ett typpåstående används.\n\nHär är några exempel för att illustrera:\n\n<!-- skip -->\n```typescript\ntype X = { a: string };\ntype Y = { a: string; b: string };\n\nlet x: X;\nx = { a: 'a', b: 'b' }; // Freshness check: Invalid assignment\nvar y: Y;\ny = { a: 'a', bx: 'bx' }; // Freshness check: Invalid assignment\n\nconst fn = (x: X) => console.log(x.a);\n\nfn(x);\nfn(y); // Widening: No errors, structurally type compatible\n\nfn({ a: 'a', bx: 'b' }); // Freshness check: Invalid argument\n\nlet c: X = { a: 'a' };\nlet d: Y = { a: 'a', b: '' };\nc = d; // Widening: No Freshness check\n```\n\n### Typinferens\n\nTypeScript kan härleda typer när ingen annotering tillhandahålls vid:\n\n* Variabelinitiering.\n* Medlemsinitiering.\n* Inställning av standardvärden för parametrar.\n* Funktionens returtyp.\n\nTill exempel:\n\n```typescript\nlet x = 'x'; // The type inferred is string\n```\n\nTypeScript-kompilatorn analyserar värdet eller uttrycket och bestämmer dess typ baserat på tillgänglig information.\n\n### Mer avancerade inferenser\n\nNär flera uttryck används vid typinferens letar TypeScript efter de \"bästa gemensamma typerna\". Till exempel:\n\n```typescript\nlet x = [1, 'x', 1, null]; // The type inferred is: (string | number | null)[]\n```\n\nOm kompilatorn inte kan hitta de bästa gemensamma typerna returnerar den en unionstyp. Till exempel:\n\n```typescript\nlet x = [new RegExp('x'), new Date()]; // Type inferred is: (RegExp | Date)[]\n```\n\nTypeScript använder \"kontextuell typning\" baserat på variabelns placering för att härleda typer. I följande exempel vet kompilatorn att `e` är av typen `MouseEvent` på grund av händelsetypen `click` som definieras i filen lib.d.ts, vilken innehåller omgivande deklarationer för olika vanliga JavaScript-konstruktioner och DOM:en:\n\n```typescript\nwindow.addEventListener('click', function (e) {}); // The inferred type of e is MouseEvent\n```\n\n### Typbreddning\n\nTypbreddning är den process där TypeScript tilldelar en typ till en variabel som initierats utan att en typannotering angavs. Den tillåter övergång från smal till bredare typ men inte tvärtom.\nI följande exempel:\n\n<!-- skip -->\n```typescript\nlet x = 'x'; // TypeScript infers as string, a wide type\nlet y: 'y' | 'x' = 'y'; // y types is a union of literal types\ny = x; // Invalid Type 'string' is not assignable to type '\"x\" | \"y\"'.\n```\n\nTypeScript tilldelar `string` till `x` baserat på det enda värde som angavs vid initieringen (`x`), detta är ett exempel på breddning.\n\nTypeScript tillhandahåller sätt att kontrollera breddningsprocessen, till exempel genom att använda \"const\".\n\n### Const\n\nAtt använda nyckelordet `const` vid deklaration av en variabel resulterar i en smalare typinferens i TypeScript.\n\nTill exempel:\n\n```typescript\nconst x = 'x'; // TypeScript infers the type of x as 'x', a narrower type\nlet y: 'y' | 'x' = 'y';\ny = x; // Valid: The type of x is inferred as 'x'\n```\n\nGenom att använda `const` för att deklarera variabeln x, smalnas dess typ av till det specifika literalvärdet 'x'. Eftersom typen av x är avsmalnad kan den tilldelas till variabeln y utan något fel.\nAnledningen till att typen kan härledas är att `const`-variabler inte kan omtilldelas, så deras typ kan smalnas av till en specifik literaltyp, i detta fall literaltypen 'x'.\n\n#### Const-modifierare på typparametrar\n\nFrån version 5.0 av TypeScript är det möjligt att ange attributet `const` på en generisk typparameter. Detta möjliggör härledning av den mest precisa typen möjligt. Låt oss se ett exempel utan att använda `const`:\n\n```typescript\nfunction identity<T>(value: T) {\n    // No const here\n    return value;\n}\nconst values = identity({ a: 'a', b: 'b' }); // Type infered is: { a: string; b: string; }\n```\n\nSom du kan se härleddes egenskaperna `a` och `b` med typen `string`.\n\nLåt oss nu se skillnaden med `const`-versionen:\n\n```typescript\nfunction identity<const T>(value: T) {\n    // Using const modifier on type parameters\n    return value;\n}\nconst values = identity({ a: 'a', b: 'b' }); // Type infered is: { a: \"a\"; b: \"b\"; }\n```\n\nNu kan vi se att egenskaperna `a` och `b` härleddes som `const`, så `a` och `b` behandlas som strängliteraler snarare än bara `string`-typer.\n\n#### Const-påstående\n\nDenna funktion låter dig deklarera en variabel med en mer precis literaltyp baserat på dess initieringsvärde, och signalerar till kompilatorn att värdet ska behandlas som en oföränderlig literal. Här är några exempel:\n\nPå en enskild egenskap:\n\n```typescript\nconst v = {\n    x: 3 as const,\n};\nv.x = 3;\n```\n\nPå ett helt objekt:\n\n```typescript\nconst v = {\n    x: 1,\n    y: 2,\n} as const;\n```\n\nDetta kan vara särskilt användbart vid definition av typen för en tupel:\n\n```typescript\nconst x = [1, 2, 3]; // number[]\nconst y = [1, 2, 3] as const; // Tuple of readonly [1, 2, 3]\n```\n\n### Explicit typannotering\n\nVi kan vara specifika och ange en typ. I följande exempel är egenskapen `x` av typen `number`:\n\n```typescript\nconst v = {\n    x: 1, // Inferred type: number (widening)\n};\nv.x = 3; // Valid\n```\n\nVi kan göra typannoteringen mer specifik genom att använda en union av literaltyper:\n\n<!-- skip -->\n```typescript\nconst v: { x: 1 | 2 | 3 } = {\n    x: 1, // x is now a union of literal types: 1 | 2 | 3\n};\nv.x = 3; // Valid\nv.x = 100; // Invalid\n```\n\n### Typavsmalnande\n\nTypavsmalnande är den process i TypeScript där en generell typ smalnas av till en mer specifik typ. Detta sker när TypeScript analyserar koden och avgör att vissa villkor eller operationer kan förfina typinformationen.\n\nAvsmalnande av typer kan ske på olika sätt, bland annat:\n\n#### Villkor\n\nGenom att använda villkorssatser, som `if` eller `switch`, kan TypeScript smalna av typen baserat på utfallet av villkoret. Till exempel:\n\n```typescript\nlet x: number | undefined = 10;\n\nif (x !== undefined) {\n    x += 100; // The type is number, which had been narrowed by the condition\n}\n```\n\n#### Kasta eller returnera\n\nAtt kasta ett fel eller returnera tidigt från en gren kan användas för att hjälpa TypeScript smalna av en typ. Till exempel:\n\n```typescript\nlet x: number | undefined = 10;\n\nif (x === undefined) {\n    throw 'error';\n}\nx += 100;\n```\n\nAndra sätt att smalna av typer i TypeScript inkluderar:\n\n* `instanceof`-operatorn: Används för att kontrollera om ett objekt är en instans av en specifik klass.\n* `in`-operatorn: Används för att kontrollera om en egenskap finns i ett objekt.\n* `typeof`-operatorn: Används för att kontrollera typen av ett värde vid körning.\n* Inbyggda funktioner som `Array.isArray()`: Används för att kontrollera om ett värde är en array.\n\n#### Diskriminerad union\n\nAtt använda en \"diskriminerad union\" är ett mönster i TypeScript där en explicit \"tagg\" läggs till objekt för att skilja mellan olika typer inom en union. Detta mönster kallas också en \"taggad union\". I följande exempel representeras \"taggen\" av egenskapen \"type\":\n\n```typescript\ntype A = { type: 'type_a'; value: number };\ntype B = { type: 'type_b'; value: string };\n\nconst x = (input: A | B): string | number => {\n    switch (input.type) {\n        case 'type_a':\n            return input.value + 100; // type is A\n        case 'type_b':\n            return input.value + 'extra'; // type is B\n    }\n};\n```\n\n#### Användardefinierade typvakter\n\nI fall där TypeScript inte kan avgöra en typ är det möjligt att skriva en hjälpfunktion känd som en \"användardefinierad typvakt\". I följande exempel kommer vi att använda ett typpredikat för att smalna av typen efter att viss filtrering har tillämpats:\n\n```typescript\nconst data = ['a', null, 'c', 'd', null, 'f'];\n\nconst r1 = data.filter(x => x != null); // The type is (string | null)[], TypeScript was not able to infer the type properly\n\nconst isValid = (item: string | null): item is string => item !== null; // Custom type guard\n\nconst r2 = data.filter(isValid); // The type is fine now string[], by using the predicate type guard we were able to narrow the type\n```\n\n## Primitiva typer\n\nTypeScript stöder 7 primitiva typer. En primitiv datatyp avser en typ som inte är ett objekt och som inte har några metoder kopplade till sig. I TypeScript är alla primitiva typer oföränderliga, vilket innebär att deras värden inte kan ändras efter att de har tilldelats.\n\n### string\n\nDen primitiva typen `string` lagrar textdata, och värdet omges alltid av dubbla eller enkla citattecken.\n\n```typescript\nconst x: string = 'x';\nconst y: string = 'y';\n```\n\nSträngar kan sträcka sig över flera rader om de omges av backtick-tecknet (`):\n\n```typescript\nlet sentence: string = `xxx,\n   yyy`;\n```\n\n### boolean\n\nDatatypen `boolean` i TypeScript lagrar ett binärt värde, antingen `true` eller `false`.\n\n```typescript\nconst isReady: boolean = true;\n```\n\n### number\n\nEn `number`-datatyp i TypeScript representeras med ett 64-bitars flyttalsvärde. En `number`-typ kan representera heltal och bråktal.\nTypeScript stöder även hexadecimala, binära och oktala tal, till exempel:\n\n```typescript\nconst decimal: number = 10;\nconst hexadecimal: number = 0xa00d; // Hexadecimal starts with 0x\nconst binary: number = 0b1010; // Binary starts with 0b\nconst octal: number = 0o633; // Octal starts with 0o\n```\n\n### bigInt\n\nEn `bigInt` representerar numeriska värden som är mycket stora (253 – 1) och inte kan representeras med en `number`.\n\nEn `bigInt` kan skapas genom att anropa den inbyggda funktionen `BigInt()` eller genom att lägga till `n` i slutet av ett heltalsliteral:\n\n```typescript\nconst x: bigint = BigInt(9007199254740991);\nconst y: bigint = 9007199254740991n;\n```\n\nNoteringar:\n\n* `bigInt`-värden kan inte blandas med `number` och kan inte användas med inbyggd `Math`, de måste konverteras till samma typ.\n* `bigInt`-värden är bara tillgängliga om målkonfigurationen är ES2020 eller högre.\n\n### Symbol\n\nSymboler är unika identifierare som kan användas som egenskapsnycklar i objekt för att förhindra namnkonflikter.\n\n```typescript\ntype Obj = {\n    [sym: symbol]: number;\n};\n\nconst a = Symbol('a');\nconst b = Symbol('b');\nlet obj: Obj = {};\nobj[a] = 123;\nobj[b] = 456;\n\nconsole.log(obj[a]); // 123\nconsole.log(obj[b]); // 456\n```\n\n### null och undefined\n\n`null` och `undefined`-typerna representerar båda inget värde eller frånvaron av något värde.\n\nTypen `undefined` betyder att värdet inte är tilldelat eller initierat och indikerar en oavsiktlig frånvaro av värde.\n\nTypen `null` betyder att vi vet att fältet inte har något värde, alltså är värdet otillgängligt, och det indikerar en avsiktlig frånvaro av värde.\n\n### Array\n\nEn `array` är en datatyp som kan lagra flera värden av samma typ eller inte. Den kan definieras med följande syntax:\n\n```typescript\nconst x: string[] = ['a', 'b'];\nconst y: Array<string> = ['a', 'b'];\nconst j: Array<string | number> = ['a', 1, 'b', 2]; // Union\n```\n\nTypeScript stöder skrivskyddade arrayer med följande syntax:\n\n<!-- skip -->\n```typescript\nconst x: readonly string[] = ['a', 'b']; // Readonly modifier\nconst y: ReadonlyArray<string> = ['a', 'b'];\nconst j: ReadonlyArray<string | number> = ['a', 1, 'b', 2];\nj.push('x'); // Invalid\n```\n\nTypeScript stöder tupler och skrivskyddade tupler:\n\n```typescript\nconst x: [string, number] = ['a', 1];\nconst y: readonly [string, number] = ['a', 1];\n```\n\n### any\n\nDatatypen `any` representerar bokstavligen \"vilket som helst\" värde, det är standardvärdet när TypeScript inte kan härleda typen eller den inte är specificerad.\n\nNär `any` används hoppar TypeScript-kompilatorn över typkontrollen, så det finns ingen typsäkerhet när `any` används. Använd i allmänhet inte `any` för att tysta kompilatorn när ett fel uppstår, fokusera istället på att åtgärda felet eftersom det med `any` är möjligt att bryta kontrakt och vi förlorar fördelarna med TypeScripts autokomplettering.\n\nTypen `any` kan vara användbar vid en gradvis migrering från JavaScript till TypeScript, eftersom den kan tysta kompilatorn.\n\nFör nya projekt, använd TypeScript-konfigurationen `noImplicitAny` som gör att TypeScript ger fel där `any` används eller härleds.\n\nTypen `any` är vanligtvis en källa till fel som kan dölja verkliga problem med dina typer. Undvik att använda den så mycket som möjligt.\n\n## Typannoteringar\n\nPå variabler som deklareras med `var`, `let` och `const` är det möjligt att valfritt lägga till en typ:\n\n```typescript\nconst x: number = 1;\n```\n\nTypeScript är bra på att härleda typer, särskilt enkla sådana, så dessa deklarationer är i de flesta fall inte nödvändiga.\n\nPå funktioner är det möjligt att lägga till typannoteringar på parametrar:\n\n```typescript\nfunction sum(a: number, b: number) {\n    return a + b;\n}\n```\n\nFöljande är ett exempel med en anonym funktion (så kallad lambda-funktion):\n\n```typescript\nconst sum = (a: number, b: number) => a + b;\n```\n\nDessa annoteringar kan undvikas när ett standardvärde för en parameter finns:\n\n```typescript\nconst sum = (a = 10, b: number) => a + b;\n```\n\nReturtypannoteringar kan läggas till på funktioner:\n\n```typescript\nconst sum = (a = 10, b: number): number => a + b;\n```\n\nDetta är särskilt användbart för mer komplexa funktioner eftersom det att explicit skriva returtypen före en implementation kan hjälpa till att bättre tänka igenom funktionen.\n\nGenerellt sett, överväg att annotera typsignaturer men inte lokala variabler i funktionskroppen, och lägg alltid till typer på objektliteraler.\n\n## Valfria egenskaper\n\nEtt objekt kan specificera valfria egenskaper genom att lägga till ett frågetecken `?` i slutet av egenskapsnamnet:\n\n```typescript\ntype X = {\n    a: number;\n    b?: number; // Optional\n};\n```\n\nDet är möjligt att ange ett standardvärde när en egenskap är valfri:\n\n```typescript\ntype X = {\n    a: number;\n    b?: number;\n};\nconst x = ({ a, b = 100 }: X) => a + b;\n```\n\n## Skrivskyddade egenskaper\n\nDet är möjligt att förhindra skrivning till en egenskap genom att använda modifieraren `readonly` som ser till att egenskapen inte kan skrivas om, men den ger ingen garanti för total oföränderlighet:\n\n```typescript\ninterface Y {\n    readonly a: number;\n}\n\ntype X = {\n    readonly a: number;\n};\n\ntype J = Readonly<{\n    a: number;\n}>;\n\ntype K = {\n    readonly [index: number]: string;\n};\n```\n\n## Indexsignaturer\n\nI TypeScript kan vi använda `string`, `number` och `symbol` som indexsignatur:\n\n```typescript\ntype K = {\n    [name: string | number]: string;\n};\nconst k: K = { x: 'x', 1: 'b' };\nconsole.log(k['x']);\nconsole.log(k[1]);\nconsole.log(k['1']); // Same result as k[1]\n```\n\nObservera att JavaScript automatiskt konverterar ett index med `number` till ett index med `string`, så `k[1]` eller `k[\"1\"]` returnerar samma värde.\n\n## Utöka typer\n\nDet är möjligt att utöka ett `interface` (kopiera medlemmar från en annan typ):\n\n```typescript\ninterface X {\n    a: string;\n}\ninterface Y extends X {\n    b: string;\n}\n```\n\nDet är också möjligt att utöka från flera typer:\n\n```typescript\ninterface A {\n    a: string;\n}\ninterface B {\n    b: string;\n}\ninterface Y extends A, B {\n    y: string;\n}\n```\n\nNyckelordet `extends` fungerar bara på interface och klasser, för typer använd en intersektion:\n\n```typescript\ntype A = {\n    a: number;\n};\ntype B = {\n    b: number;\n};\ntype C = A & B;\n```\n\nDet är möjligt att utöka en typ med hjälp av en härledning men inte tvärtom:\n\n```typescript\ntype A = {\n    a: string;\n};\ninterface B extends A {\n    b: string;\n}\n```\n\n## Literaltyper\n\nEn literaltyp är en enskild elementuppsättning från en kollektiv typ, den definierar ett mycket exakt värde som är en JavaScript-primitiv.\n\nLiteraltyper i TypeScript är tal, strängar och booleaner.\n\nExempel på literaler:\n\n```typescript\nconst a = 'a'; // String literal type\nconst b = 1; // Numeric literal type\nconst c = true; // Boolean literal type\n```\n\nSträng-, numeriska och booleska literaltyper används i unioner, typvakter och typalias.\nI följande exempel kan du se ett unionstypealias. `O` består bara av de angivna värdena, ingen annan sträng är giltig:\n\n```typescript\ntype O = 'a' | 'b' | 'c';\n```\n\n## Literalhärledning\n\nLiteralhärledning är en funktion i TypeScript som gör att typen av en variabel eller parameter kan härledas baserat på dess värde.\n\nI följande exempel kan vi se att TypeScript betraktar `x` som en literaltyp eftersom värdet inte kan ändras senare, medan `y` härleds som sträng eftersom det kan ändras när som helst.\n\n```typescript\nconst x = 'x'; // Literal type of 'x', because this value cannot be changed\nlet y = 'y'; // Type string, as we can change this value\n```\n\nI följande exempel kan vi se att `o.x` härleds som en `string` (och inte en literal av `a`) eftersom TypeScript anser att värdet kan ändras när som helst.\n\n<!-- skip -->\n```typescript\ntype X = 'a' | 'b';\n\nlet o = {\n    x: 'a', // This is a wider string\n};\n\nconst fn = (x: X) => `${x}-foo`;\n\nconsole.log(fn(o.x)); // Argument of type 'string' is not assignable to parameter of type 'X'\n```\n\nSom du kan se ger koden ett fel när `o.x` skickas till `fn` eftersom X är en smalare typ.\n\nVi kan lösa detta problem genom att använda typbekräftelse med `const` eller typen `X`:\n\n<!-- skip -->\n```typescript\nlet o = {\n    x: 'a' as const,\n};\n```\n\neller:\n\n<!-- skip -->\n```typescript\nlet o = {\n    x: 'a' as X,\n};\n```\n\n## strictNullChecks\n\n`strictNullChecks` är ett TypeScript-kompilatoralternativ som framtvingar strikt null-kontroll. När detta alternativ är aktiverat kan variabler och parametrar bara tilldelas `null` eller `undefined` om de uttryckligen har deklarerats att vara av den typen med hjälp av unionstypen `null` | `undefined`. Om en variabel eller parameter inte uttryckligen deklareras som nullable kommer TypeScript att generera ett fel för att förhindra potentiella körtidsfel.\n\n## Enums\n\nI TypeScript är en `enum` en uppsättning namngivna konstantvärden.\n\n```typescript\nenum Color {\n    Red = '#ff0000',\n    Green = '#00ff00',\n    Blue = '#0000ff',\n}\n```\n\nEnums kan definieras på olika sätt:\n\n### Numeriska enums\n\nI TypeScript är en numerisk Enum en Enum där varje konstant tilldelas ett numeriskt värde, med start från 0 som standard.\n\n```typescript\nenum Size {\n    Small, // value starts from 0\n    Medium,\n    Large,\n}\n```\n\nDet är möjligt att ange anpassade värden genom att explicit tilldela dem:\n\n```typescript\nenum Size {\n    Small = 10,\n    Medium,\n    Large,\n}\nconsole.log(Size.Medium); // 11\n```\n\n### Sträng-enums\n\nI TypeScript är en sträng-Enum en Enum där varje konstant tilldelas ett strängvärde.\n\n```typescript\nenum Language {\n    English = 'EN',\n    Spanish = 'ES',\n}\n```\n\nNotera: TypeScript tillåter användning av heterogena Enums där sträng- och numeriska medlemmar kan samexistera.\n\n### Konstanta enums\n\nEn konstant enum i TypeScript är en speciell typ av Enum där alla värden är kända vid kompileringstid och infogas överallt där enum:en används, vilket resulterar i mer effektiv kod.\n\n```typescript\nconst enum Language {\n    English = 'EN',\n    Spanish = 'ES',\n}\nconsole.log(Language.English);\n```\n\nKommer att kompileras till:\n\n```typescript\nconsole.log('EN' /* Language.English */);\n```\n\nNoteringar:\nKonstanta Enums har hårdkodade värden som raderar Enum:en, vilket kan vara mer effektivt i fristående bibliotek men är i allmänhet inte önskvärt. Dessutom kan konstanta enums inte ha beräknade medlemmar.\n\n### Omvänd mappning\n\nI TypeScript avser omvänd mappning i Enums möjligheten att hämta Enum-medlemmens namn från dess värde. Som standard har Enum-medlemmar framåtmappningar från namn till värde, men omvända mappningar kan skapas genom att explicit ange värden för varje medlem. Omvända mappningar är användbara när du behöver slå upp en Enum-medlem efter dess värde, eller när du behöver iterera över alla Enum-medlemmar. Observera att bara numeriska Enum-medlemmar genererar omvända mappningar, medan sträng-Enum-medlemmar inte genererar någon omvänd mappning alls.\n\nFöljande enum:\n\n```typescript\nenum Grade {\n    A = 90,\n    B = 80,\n    C = 70,\n    F = 'fail',\n}\n```\n\nKompileras till:\n\n<!-- skip -->\n```javascript\n'use strict';\nvar Grade;\n(function (Grade) {\n    Grade[(Grade['A'] = 90)] = 'A';\n    Grade[(Grade['B'] = 80)] = 'B';\n    Grade[(Grade['C'] = 70)] = 'C';\n    Grade['F'] = 'fail';\n})(Grade || (Grade = {}));\n```\n\nDärför fungerar mappning av värden till nycklar för numeriska enum-medlemmar, men inte för sträng-enum-medlemmar:\n\n<!-- skip -->\n```typescript\nenum Grade {\n    A = 90,\n    B = 80,\n    C = 70,\n    F = 'fail',\n}\nconst myGrade = Grade.A;\nconsole.log(Grade[myGrade]); // A\nconsole.log(Grade[90]); // A\n\nconst failGrade = Grade.F;\nconsole.log(failGrade); // fail\nconsole.log(Grade[failGrade]); // Element implicitly has an 'any' type because index expression is not of type 'number'.\n```\n\n### Omgivande enums\n\nEn omgivande enum i TypeScript är en typ av Enum som definieras i en deklarationsfil (*.d.ts) utan en associerad implementation. Den låter dig definiera en uppsättning namngivna konstanter som kan användas på ett typsäkert sätt över olika filer utan att behöva importera implementationsdetaljerna i varje fil.\n\n### Beräknade och konstanta medlemmar\n\nI TypeScript är en beräknad medlem en medlem av en Enum som har ett värde som beräknas vid körning, medan en konstant medlem är en medlem vars värde sätts vid kompileringstid och inte kan ändras under körning. Beräknade medlemmar är tillåtna i vanliga Enums, medan konstanta medlemmar är tillåtna i både vanliga och const enums.\n\n```typescript\n// Constant members\nenum Color {\n    Red = 1,\n    Green = 5,\n    Blue = Red + Green,\n}\nconsole.log(Color.Blue); // 6 generation at compilation time\n```\n\n```typescript\n// Computed members\nenum Color {\n    Red = 1,\n    Green = Math.pow(2, 2),\n    Blue = Math.floor(Math.random() * 3) + 1,\n}\nconsole.log(Color.Blue); // random number generated at run time\n```\n\nEnums betecknas av unioner som består av deras medlemstyper. Värdena för varje medlem kan bestämmas genom konstanta eller icke-konstanta uttryck, där medlemmar med konstanta värden tilldelas literaltyper. För att illustrera, betrakta deklarationen av typ E och dess undertyper E.A, E.B och E.C. I detta fall representerar E unionen E.A | E.B | E.C.\n\n```typescript\nconst identity = (value: number) => value;\n\nenum E {\n    A = 2 * 5, // Numeric literal\n    B = 'bar', // String literal\n    C = identity(42), // Opaque computed\n}\n\nconsole.log(E.C); //42\n```\n\n## Avsmalning\n\nTypeScript-avsmalning är processen att förfina typen av en variabel inom ett villkorsblock. Detta är användbart när man arbetar med unionstyper, där en variabel kan ha mer än en typ.\n\nTypeScript känner igen flera sätt att avsmalna typen:\n\n### typeof-typvakter\n\ntypeof-typvakten är en specifik typvakt i TypeScript som kontrollerar typen av en variabel baserat på dess inbyggda JavaScript-typ.\n\n```typescript\nconst fn = (x: number | string) => {\n    if (typeof x === 'number') {\n        return x + 1; // x is number\n    }\n    return -1;\n};\n```\n\n### Sanningsvärdesavsmalning\n\nSanningsvärdesavsmalning i TypeScript fungerar genom att kontrollera om en variabel är sann eller falsk för att avsmalna dess typ därefter.\n\n```typescript\nconst toUpperCase = (name: string | null) => {\n    if (name) {\n        return name.toUpperCase();\n    } else {\n        return null;\n    }\n};\n```\n\n### Likhetsavsmalning\n\nLikhetsavsmalning i TypeScript fungerar genom att kontrollera om en variabel är lika med ett specifikt värde eller inte, för att avsmalma dess typ därefter.\n\nDen används tillsammans med `switch`-satser och likhetsoperatorer som `===`, `!==`, `==` och `!=` för att avsmalma typer.\n\n```typescript\nconst checkStatus = (status: 'success' | 'error') => {\n    switch (status) {\n        case 'success':\n            return true;\n        case 'error':\n            return null;\n    }\n};\n```\n\n### In-operatoravsmalning\n\n`in`-operatoravsmalning i TypeScript är ett sätt att avsmalma typen av en variabel baserat på om en egenskap finns inom variabelns typ.\n\n```typescript\ntype Dog = {\n    name: string;\n    breed: string;\n};\n\ntype Cat = {\n    name: string;\n    likesCream: boolean;\n};\n\nconst getAnimalType = (pet: Dog | Cat) => {\n    if ('breed' in pet) {\n        return 'dog';\n    } else {\n        return 'cat';\n    }\n};\n```\n\n### instanceof-avsmalning\n\n`instanceof`-operatoravsmalning i TypeScript är ett sätt att avsmalma typen av en variabel baserat på dess konstruktorfunktion, genom att kontrollera om ett objekt är en instans av en viss klass eller gränssnitt.\n\n```typescript\nclass Square {\n    constructor(public width: number) {}\n}\nclass Rectangle {\n    constructor(\n        public width: number,\n        public height: number\n    ) {}\n}\nfunction area(shape: Square | Rectangle) {\n    if (shape instanceof Square) {\n        return shape.width * shape.width;\n    } else {\n        return shape.width * shape.height;\n    }\n}\nconst square = new Square(5);\nconst rectangle = new Rectangle(5, 10);\nconsole.log(area(square)); // 25\nconsole.log(area(rectangle)); // 50\n```\n\n## Tilldelningar\n\nTypeScript-avsmalning med hjälp av tilldelningar är ett sätt att avsmalma typen av en variabel baserat på det tilldelade värdet. När en variabel tilldelas ett värde härleder TypeScript dess typ baserat på det tilldelade värdet, och avsmalmar variabelns typ för att matcha den härledda typen.\n\n```typescript\nlet value: string | number;\nvalue = 'hello';\nif (typeof value === 'string') {\n    console.log(value.toUpperCase());\n}\nvalue = 42;\nif (typeof value === 'number') {\n    console.log(value.toFixed(2));\n}\n```\n\n## Kontrollflödesanalys\n\nKontrollflödesanalys i TypeScript är ett sätt att statiskt analysera kodflödet för att härleda typer av variabler, vilket gör det möjligt för kompilatorn att avsmalma typerna av dessa variabler efter behov, baserat på resultaten av analysen.\n\nFöre TypeScript 4.4 tillämpades kodflödesanalys enbart på kod inom en if-sats, men från och med TypeScript 4.4 kan den även tillämpas på villkorliga uttryck och diskriminantegenskapsåtkomster som indirekt refereras genom const-variabler.\n\nTill exempel:\n\n```typescript\nconst f1 = (x: unknown) => {\n    const isString = typeof x === 'string';\n    if (isString) {\n        x.length;\n    }\n};\n\nconst f2 = (\n    obj: { kind: 'foo'; foo: string } | { kind: 'bar'; bar: number }\n) => {\n    const isFoo = obj.kind === 'foo';\n    if (isFoo) {\n        obj.foo;\n    } else {\n        obj.bar;\n    }\n};\n```\n\nNågra exempel där avsmalning inte sker:\n\n<!-- skip -->\n```typescript\nconst f1 = (x: unknown) => {\n    let isString = typeof x === 'string';\n    if (isString) {\n        x.length; // Error, no narrowing because isString it is not const\n    }\n};\n\nconst f6 = (\n    obj: { kind: 'foo'; foo: string } | { kind: 'bar'; bar: number }\n) => {\n    const isFoo = obj.kind === 'foo';\n    obj = obj;\n    if (isFoo) {\n        obj.foo; // Error, no narrowing because obj is assigned in function body\n    }\n};\n```\n\nObservera: Upp till fem nivåer av indirektion analyseras i villkorliga uttryck.\n\n## Typpredikat\n\nTyppredikat i TypeScript är funktioner som returnerar ett booleskt värde och används för att avsmalma typen av en variabel till en mer specifik typ.\n\n```typescript\nconst isString = (value: unknown): value is string => typeof value === 'string';\n\nconst foo = (bar: unknown) => {\n    if (isString(bar)) {\n        console.log(bar.toUpperCase());\n    } else {\n        console.log('not a string');\n    }\n};\n```\n\n## Diskriminerade unioner\n\nDiskriminerade unioner i TypeScript är en typ av unionstyp som använder en gemensam egenskap, känd som diskriminanten, för att avsmalma uppsättningen av möjliga typer för unionen.\n\n```typescript\ntype Square = {\n    kind: 'square'; // Discriminant\n    size: number;\n};\n\ntype Circle = {\n    kind: 'circle'; // Discriminant\n    radius: number;\n};\n\ntype Shape = Square | Circle;\n\nconst area = (shape: Shape) => {\n    switch (shape.kind) {\n        case 'square':\n            return Math.pow(shape.size, 2);\n        case 'circle':\n            return Math.PI * Math.pow(shape.radius, 2);\n    }\n};\n\nconst square: Square = { kind: 'square', size: 5 };\nconst circle: Circle = { kind: 'circle', radius: 2 };\n\nconsole.log(area(square)); // 25\nconsole.log(area(circle)); // 12.566370614359172\n```\n\n## Never-typen\n\nNär en variabel avsmalnas till en typ som inte kan innehålla några värden, kommer TypeScript-kompilatorn att härleda att variabeln måste vara av typen `never`. Detta beror på att never-typen representerar ett värde som aldrig kan produceras.\n\n```typescript\nconst printValue = (val: string | number) => {\n    if (typeof val === 'string') {\n        console.log(val.toUpperCase());\n    } else if (typeof val === 'number') {\n        console.log(val.toFixed(2));\n    } else {\n        // val has type never here because it can never be anything other than a string or a number\n        const neverVal: never = val;\n        console.log(`Unexpected value: ${neverVal}`);\n    }\n};\n```\n\n## Uttömmande kontroll\n\nUttömmande kontroll är en funktion i TypeScript som säkerställer att alla möjliga fall av en diskriminerad union hanteras i en `switch`-sats eller en `if`-sats.\n\n```typescript\ntype Direction = 'up' | 'down';\n\nconst move = (direction: Direction) => {\n    switch (direction) {\n        case 'up':\n            console.log('Moving up');\n            break;\n        case 'down':\n            console.log('Moving down');\n            break;\n        default:\n            const exhaustiveCheck: never = direction;\n            console.log(exhaustiveCheck); // This line will never be executed\n    }\n};\n```\n\n`never`-typen används för att säkerställa att default-fallet är uttömmande och att TypeScript kommer att ge ett fel om ett nytt värde läggs till i Direction-typen utan att det hanteras i switch-satsen.\n\n## Objekttyper\n\nI TypeScript beskriver objekttyper formen på ett objekt. De specificerar namnen och typerna på objektets egenskaper, samt huruvida dessa egenskaper är obligatoriska eller valfria.\n\nI TypeScript kan du definiera objekttyper på två primära sätt:\n\nInterface som definierar formen på ett objekt genom att specificera namnen, typerna och valfrihet hos dess egenskaper.\n\n```typescript\ninterface User {\n    name: string;\n    age: number;\n    email?: string;\n}\n```\n\nTypalias, liknande ett interface, definierar formen på ett objekt. Det kan dock även skapa en ny anpassad typ som baseras på en befintlig typ eller en kombination av befintliga typer. Detta inkluderar att definiera unionstyper, intersektionstyper och andra komplexa typer.\n\n```typescript\ntype Point = {\n    x: number;\n    y: number;\n};\n```\n\nDet är också möjligt att definiera en typ anonymt:\n\n```typescript\nconst sum = (x: { a: number; b: number }) => x.a + x.b;\nconsole.log(sum({ a: 5, b: 1 }));\n```\n\n## Tuppeltyp (Anonym)\n\nEn tuppeltyp är en typ som representerar en array med ett fast antal element och deras motsvarande typer. En tuppeltyp tvingar fram ett specifikt antal element och deras respektive typer i en fast ordning. Tuppeltyper är användbara när du vill representera en samling värden med specifika typer, där positionen för varje element i arrayen har en specifik betydelse.\n\n```typescript\ntype Point = [number, number];\n```\n\n## Namngiven tuppeltyp (Märkt)\n\nTuppeltyper kan inkludera valfria etiketter eller namn för varje element. Dessa etiketter är till för läsbarhet och verktygsstöd, och påverkar inte de operationer du kan utföra med dem.\n\n```typescript\ntype T = string;\ntype Tuple1 = [T, T];\ntype Tuple2 = [a: T, b: T];\ntype Tuple3 = [a: T, T]; // Named Tuple plus Anonymous Tuple\n```\n\n## Tuppel med fast längd\n\nEn tuppel med fast längd är en specifik typ av tuppel som tvingar fram ett fast antal element av specifika typer, och tillåter inte några ändringar av tuppelns längd efter att den har definierats.\n\nTupplar med fast längd är användbara när du behöver representera en samling värden med ett specifikt antal element och specifika typer, och du vill säkerställa att längden och typerna av tuppeln inte kan ändras oavsiktligt.\n\n<!-- skip -->\n```typescript\nconst x = [10, 'hello'] as const;\nx.push(2); // Error\n```\n\n## Unionstyp\n\nEn unionstyp är en typ som representerar ett värde som kan vara en av flera typer. Unionstyper betecknas med symbolen `|` mellan varje möjlig typ.\n\n```typescript\nlet x: string | number;\nx = 'hello'; // Valid\nx = 123; // Valid\n```\n\n## Intersektionstyper\n\nEn intersektionstyp är en typ som representerar ett värde som har alla egenskaper hos två eller flera typer. Intersektionstyper betecknas med symbolen `&` mellan varje typ.\n\n```typescript\ntype X = {\n    a: string;\n};\n\ntype Y = {\n    b: string;\n};\n\ntype J = X & Y; // Intersection\n\nconst j: J = {\n    a: 'a',\n    b: 'b',\n};\n```\n\n## Typindexering\n\nTypindexering avser möjligheten att definiera typer som kan indexeras med en nyckel som inte är känd i förväg, genom att använda en indexsignatur för att specificera typen för egenskaper som inte uttryckligen deklarerats.\n\n```typescript\ntype Dictionary<T> = {\n    [key: string]: T;\n};\nconst myDict: Dictionary<string> = { a: 'a', b: 'b' };\nconsole.log(myDict['a']); // Returns a\n```\n\n## Typ från värde\n\nTyp från värde i TypeScript avser den automatiska härledningen av en typ från ett värde eller uttryck genom typinferens.\n\n```typescript\nconst x = 'x'; // TypeScript infers 'x' as a string literal with 'const' (immutable), but widens it to 'string' with 'let' (reassignable).\n```\n\n## Typ från funktionsreturvärde\n\nTyp från funktionsreturvärde avser möjligheten att automatiskt härleda returtypen av en funktion baserat på dess implementation. Detta gör att TypeScript kan bestämma typen av det värde som returneras av funktionen utan explicita typannoteringar.\n\n```typescript\nconst add = (x: number, y: number) => x + y; // TypeScript can infer that the return type of the function is a number\n```\n\n## Typ från modul\n\nTyp från modul avser möjligheten att använda en moduls exporterade värden för att automatiskt härleda deras typer. När en modul exporterar ett värde med en specifik typ kan TypeScript använda den informationen för att automatiskt härleda typen av det värdet när det importeras till en annan modul.\n\n<!-- skip -->\n```typescript\n// calc.ts\nexport const add = (x: number, y: number) => x + y;\n// index.ts\nimport { add } from 'calc';\nconst r = add(1, 2); // r is number\n```\n\n## Mappade typer\n\nMappade typer i TypeScript låter dig skapa nya typer baserade på en befintlig typ genom att transformera varje egenskap med hjälp av en mappningsfunktion. Genom att mappa befintliga typer kan du skapa nya typer som representerar samma information i ett annat format. För att skapa en mappad typ kommer du åt egenskaperna hos en befintlig typ med `keyof`-operatorn och ändrar dem sedan för att producera en ny typ.\nI följande exempel:\n\n```typescript\ntype MyMappedType<T> = {\n    [P in keyof T]: T[P][];\n};\ntype MyType = {\n    foo: string;\n    bar: number;\n};\ntype MyNewType = MyMappedType<MyType>;\nconst x: MyNewType = {\n    foo: ['hello', 'world'],\n    bar: [1, 2, 3],\n};\n```\n\ndefinierar vi MyMappedType för att mappa över T:s egenskaper och skapa en ny typ där varje egenskap är en array av sin ursprungliga typ. Med hjälp av detta skapar vi MyNewType för att representera samma information som MyType, men med varje egenskap som en array.\n\n## Modifierare för mappade typer\n\nModifierare för mappade typer i TypeScript möjliggör transformation av egenskaper inom en befintlig typ:\n\n* `readonly` eller `+readonly`: Detta gör en egenskap i den mappade typen skrivskyddad.\n* `-readonly`: Detta gör att en egenskap i den mappade typen kan ändras.\n* `?`: Detta gör en egenskap i den mappade typen valfri.\n\nExempel:\n\n```typescript\ntype ReadOnly<T> = { readonly [P in keyof T]: T[P] }; // All properties marked as read-only\n\ntype Mutable<T> = { -readonly [P in keyof T]: T[P] }; // All properties marked as mutable\n\ntype MyPartial<T> = { [P in keyof T]?: T[P] }; // All properties marked as optional\n```\n\n## Villkorliga typer\n\nVillkorliga typer är ett sätt att skapa en typ som beror på ett villkor, där typen som ska skapas bestäms baserat på resultatet av villkoret. De definieras med nyckelordet `extends` och en ternär operator för att villkorligt välja mellan två typer.\n\n```typescript\ntype IsArray<T> = T extends any[] ? true : false;\n\nconst myArray = [1, 2, 3];\nconst myNumber = 42;\n\ntype IsMyArrayAnArray = IsArray<typeof myArray>; // Type true\ntype IsMyNumberAnArray = IsArray<typeof myNumber>; // Type false\n```\n\n## Distributiva villkorliga typer\n\nDistributiva villkorliga typer är en funktion som gör det möjligt att distribuera en typ över en union av typer, genom att tillämpa en transformation på varje medlem av unionen individuellt.\nDetta kan vara särskilt användbart vid arbete med mappade typer eller typer av högre ordning.\n\n```typescript\ntype Nullable<T> = T extends any ? T | null : never;\ntype NumberOrBool = number | boolean;\ntype NullableNumberOrBool = Nullable<NumberOrBool>; // number | boolean | null\n```\n\n## infer-typinferens i villkorliga typer\n\nNyckelordet `infer` används i villkorliga typer för att härleda (extrahera) typen av en generisk parameter från en typ som beror på den. Detta gör att du kan skriva mer flexibla och återanvändbara typdefinitioner.\n\n```typescript\ntype ElementType<T> = T extends (infer U)[] ? U : never;\ntype Numbers = ElementType<number[]>; // number\ntype Strings = ElementType<string[]>; // string\n```\n\n## Fördefinierade villkorliga typer\n\nI TypeScript är fördefinierade villkorliga typer inbyggda villkorliga typer som tillhandahålls av språket. De är utformade för att utföra vanliga typtransformationer baserade på egenskaperna hos en given typ.\n\n`Exclude<UnionType, ExcludedType>`: Denna typ tar bort alla typer från Type som kan tilldelas till ExcludedType.\n\n`Extract<Type, Union>`: Denna typ extraherar alla typer från Union som kan tilldelas till Type.\n\n`NonNullable<Type>`: Denna typ tar bort null och undefined från Type.\n\n`ReturnType<Type>`: Denna typ extraherar returtypen av en funktionstyp Type.\n\n`Parameters<Type>`: Denna typ extraherar parametertyperna av en funktionstyp Type.\n\n`Required<Type>`: Denna typ gör alla egenskaper i Type obligatoriska.\n\n`Partial<Type>`: Denna typ gör alla egenskaper i Type valfria.\n\n`Readonly<Type>`: Denna typ gör alla egenskaper i Type skrivskyddade.\n\n## Mall-unionstyper\n\nMall-unionstyper kan användas för att slå samman och manipulera text inuti typsystemet, till exempel:\n\n```typescript\ntype Status = 'active' | 'inactive';\ntype Products = 'p1' | 'p2';\ntype ProductId = `id-${Products}-${Status}`; // \"id-p1-active\" | \"id-p1-inactive\" | \"id-p2-active\" | \"id-p2-inactive\"\n```\n\n## Any-typen\n\n`any`-typen är en speciell typ (universell supertyp) som kan användas för att representera vilken typ av värde som helst (primitiver, objekt, arrayer, funktioner, fel, symboler). Den används ofta i situationer där typen av ett värde inte är känd vid kompilering, eller vid arbete med värden från externa API:er eller bibliotek som inte har TypeScript-typningar.\n\nGenom att använda `any`-typen indikerar du för TypeScript-kompilatorn att värden ska representeras utan några begränsningar. För att maximera typsäkerheten i din kod, överväg följande:\n\n* Begränsa användningen av `any` till specifika fall där typen verkligen är okänd.\n* Returnera inte `any`-typer från en funktion, eftersom detta försvagar typsäkerheten i kod som använder den.\n* Istället för `any`, använd `@ts-ignore` om du behöver tysta kompilatorn.\n\n```typescript\nlet value: any;\nvalue = true; // Valid\nvalue = 7; // Valid\n```\n\n## Unknown-typen\n\nI TypeScript representerar `unknown`-typen ett värde av en okänd typ. Till skillnad från `any`-typen, som tillåter vilken typ av värde som helst, kräver `unknown` en typkontroll eller assertion innan den kan användas på ett specifikt sätt, så inga operationer är tillåtna på en `unknown` utan att först göra en assertion eller avsmalning till en mer specifik typ.\n\n`unknown`-typen kan bara tilldelas till any-typen och `unknown`-typen själv, den är ett typsäkert alternativ till `any`.\n<!-- skip -->\n```typescript\nlet value: unknown;\n\nlet value1: unknown = value; // Valid\nlet value2: any = value; // Valid\nlet value3: boolean = value; // Invalid\nlet value4: number = value; // Invalid\n```\n\n```typescript\nconst add = (a: unknown, b: unknown): number | undefined =>\n    typeof a === 'number' && typeof b === 'number' ? a + b : undefined;\nconsole.log(add(1, 2)); // 3\nconsole.log(add('x', 2)); // undefined\n```\n\n## Void-typen\n\nTypen `void` används för att indikera att en funktion inte returnerar något värde.\n\n```typescript\nconst sayHello = (): void => {\n    console.log('Hello!');\n};\n```\n\n## Användning av Never-typen\n\nTypen `never` representerar värden som aldrig förekommer. Den används för att beteckna funktioner eller uttryck som aldrig returnerar eller kastar ett fel.\n\nTill exempel en oändlig loop:\n\n```typescript\nconst infiniteLoop = (): never => {\n    while (true) {\n        // do something\n    }\n};\n```\n\nKasta ett fel:\n\n```typescript\nconst throwError = (message: string): never => {\n    throw new Error(message);\n};\n```\n\nTypen `never` är användbar för att säkerställa typsäkerhet och fånga potentiella fel i din kod. Den hjälper TypeScript att analysera och härleda mer precisa typer när den används i kombination med andra typer och kontrollflödessatser, till exempel:\n\n```typescript\ntype Direction = 'up' | 'down';\nconst move = (direction: Direction): void => {\n    switch (direction) {\n        case 'up':\n            // move up\n            break;\n        case 'down':\n            // move down\n            break;\n        default:\n            const exhaustiveCheck: never = direction;\n            throw new Error(`Unhandled direction: ${exhaustiveCheck}`);\n    }\n};\n```\n\n## Interface och Type\n\n### Gemensam syntax\n\nI TypeScript definierar interface strukturen hos objekt och specificerar namnen och typerna på egenskaper eller metoder som ett objekt måste ha. Den gemensamma syntaxen för att definiera ett interface i TypeScript är följande:\n\n<!-- skip -->\n```typescript\ninterface InterfaceName {\n    property1: Type1;\n    // ...\n    method1(arg1: ArgType1, arg2: ArgType2): ReturnType;\n    // ...\n}\n```\n\nPå liknande sätt för typdefinition:\n\n<!-- skip -->\n```typescript\ntype TypeName = {\n    property1: Type1;\n    // ...\n    method1(arg1: ArgType1, arg2: ArgType2): ReturnType;\n    // ...\n};\n```\n\n`interface InterfaceName` eller `type TypeName`: Definierar namnet på interfacet.\n`property1`: `Type1`: Specificerar interfacets egenskaper tillsammans med deras motsvarande typer. Flera egenskaper kan definieras, var och en separerad med ett semikolon.\n`method1(arg1: ArgType1, arg2: ArgType2): ReturnType;`: Specificerar interfacets metoder. Metoder definieras med sina namn, följt av en parameterlista inom parenteser och returtypen. Flera metoder kan definieras, var och en separerad med ett semikolon.\n\nExempel på interface:\n\n```typescript\ninterface Person {\n    name: string;\n    age: number;\n    greet(): void;\n}\n```\n\nExempel på type:\n\n```typescript\ntype TypeName = {\n    property1: string;\n    method1(arg1: string, arg2: string): string;\n};\n```\n\nI TypeScript används typer för att definiera formen på data och upprätthålla typkontroll. Det finns flera vanliga syntaxer för att definiera typer i TypeScript, beroende på det specifika användningsfallet. Här är några exempel:\n\n### Grundläggande typer\n\n```typescript\nlet myNumber: number = 123; // number type\nlet myBoolean: boolean = true; // boolean type\nlet myArray: string[] = ['a', 'b']; // array of strings\nlet myTuple: [string, number] = ['a', 123]; // tuple\n```\n\n### Objekt och Interface\n\n```typescript\nconst x: { name: string; age: number } = { name: 'Simon', age: 7 };\n```\n\n### Union- och Intersection-typer\n\n```typescript\ntype MyType = string | number; // Union type\nlet myUnion: MyType = 'hello'; // Can be a string\nmyUnion = 123; // Or a number\n\ntype TypeA = { name: string };\ntype TypeB = { age: number };\ntype CombinedType = TypeA & TypeB; // Intersection type\nlet myCombined: CombinedType = { name: 'John', age: 25 }; // Object with both name and age properties\n```\n\n## Inbyggda primitiva typer\n\nTypeScript har flera inbyggda primitiva typer som kan användas för att definiera variabler, funktionsparametrar och returtyper:\n\n* `number`: Representerar numeriska värden, inklusive heltal och flyttal.\n* `string`: Representerar textdata.\n* `boolean`: Representerar logiska värden, som kan vara antingen true eller false.\n* `null`: Representerar frånvaron av ett värde.\n* `undefined`: Representerar ett värde som inte har tilldelats eller inte har definierats.\n* `symbol`: Representerar en unik identifierare. Symboler används vanligtvis som nycklar för objektegenskaper.\n* `bigint`: Representerar heltal med godtycklig precision.\n* `any`: Representerar en dynamisk eller okänd typ. Variabler av typen any kan innehålla värden av vilken typ som helst, och de kringgår typkontroll.\n* `void`: Representerar frånvaron av någon typ. Den används vanligtvis som returtyp för funktioner som inte returnerar ett värde.\n* `never`: Representerar en typ för värden som aldrig förekommer. Den används vanligtvis som returtyp för funktioner som kastar ett fel eller går in i en oändlig loop.\n\n## Vanliga inbyggda JS-objekt\n\nTypeScript är en utökning av JavaScript och inkluderar alla vanligt använda inbyggda JavaScript-objekt. Du kan hitta en utförlig lista över dessa objekt på Mozilla Developer Networks (MDN) dokumentationswebbplats:\n[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects)\n\nHär är en lista över några vanligt använda inbyggda JavaScript-objekt:\n\n* Function\n* Object\n* Boolean\n* Error\n* Number\n* BigInt\n* Math\n* Date\n* String\n* RegExp\n* Array\n* Map\n* Set\n* Promise\n* Intl\n\n## Överlagringar\n\nFunktionsöverlagringar i TypeScript låter dig definiera flera funktionssignaturer för ett enda funktionsnamn, vilket gör det möjligt att definiera funktioner som kan anropas på flera sätt. Här är ett exempel:\n\n```typescript\n// Overloads\nfunction sayHi(name: string): string;\nfunction sayHi(names: string[]): string[];\n\n// Implementation\nfunction sayHi(name: unknown): unknown {\n    if (typeof name === 'string') {\n        return `Hi, ${name}!`;\n    } else if (Array.isArray(name)) {\n        return name.map(name => `Hi, ${name}!`);\n    }\n    throw new Error('Invalid value');\n}\n\nsayHi('xx'); // Valid\nsayHi(['aa', 'bb']); // Valid\n```\n\nHär är ytterligare ett exempel på användning av funktionsöverlagringar inom en `class`:\n\n```typescript\nclass Greeter {\n    message: string;\n\n    constructor(message: string) {\n        this.message = message;\n    }\n\n    // overload\n    sayHi(name: string): string;\n    sayHi(names: string[]): ReadonlyArray<string>;\n\n    // implementation\n    sayHi(name: unknown): unknown {\n        if (typeof name === 'string') {\n            return `${this.message}, ${name}!`;\n        } else if (Array.isArray(name)) {\n            return name.map(name => `${this.message}, ${name}!`);\n        }\n        throw new Error('value is invalid');\n    }\n}\nconsole.log(new Greeter('Hello').sayHi('Simon'));\n```\n\n## Sammanslagning och utökning\n\nSammanslagning och utökning avser två olika koncept relaterade till att arbeta med typer och interface.\n\nSammanslagning låter dig kombinera flera deklarationer med samma namn till en enda definition, till exempel när du definierar ett interface med samma namn flera gånger:\n\n```typescript\ninterface X {\n    a: string;\n}\n\ninterface X {\n    b: number;\n}\n\nconst person: X = {\n    a: 'a',\n    b: 7,\n};\n```\n\nUtökning avser möjligheten att utöka eller ärva från befintliga typer eller interface för att skapa nya. Det är en mekanism för att lägga till ytterligare egenskaper eller metoder till en befintlig typ utan att ändra dess ursprungliga definition. Exempel:\n\n```typescript\ninterface Animal {\n    name: string;\n    eat(): void;\n}\n\ninterface Bird extends Animal {\n    sing(): void;\n}\n\nconst dog: Bird = {\n    name: 'Bird 1',\n    eat() {\n        console.log('Eating');\n    },\n    sing() {\n        console.log('Singing');\n    },\n};\n```\n\n## Skillnader mellan Type och Interface\n\nDeklarationssammanslagning (augmentering):\n\nInterface stöder deklarationssammanslagning, vilket innebär att du kan definiera flera interface med samma namn, och TypeScript kommer att slå samman dem till ett enda interface med de kombinerade egenskaperna och metoderna. Å andra sidan stöder typer inte deklarationssammanslagning. Detta kan vara användbart när du vill lägga till extra funktionalitet eller anpassa befintliga typer utan att ändra de ursprungliga definitionerna eller korrigera saknade eller felaktiga typer.\n\n```typescript\ninterface A {\n    x: string;\n}\ninterface A {\n    y: string;\n}\nconst j: A = {\n    x: 'xx',\n    y: 'yy',\n};\n```\n\nUtökning av andra typer/interface:\n\nBåde typer och interface kan utöka andra typer/interface, men syntaxen är annorlunda. Med interface använder du nyckelordet `extends` för att ärva egenskaper och metoder från andra interface. Ett interface kan dock inte utöka en komplex typ som en union-typ.\n\n```typescript\ninterface A {\n    x: string;\n    y: number;\n}\ninterface B extends A {\n    z: string;\n}\nconst car: B = {\n    x: 'x',\n    y: 123,\n    z: 'z',\n};\n```\n\nFör typer använder du operatorn & för att kombinera flera typer till en enda typ (intersection).\n\n```typescript\ninterface A {\n    x: string;\n    y: number;\n}\n\ntype B = A & {\n    j: string;\n};\n\nconst c: B = {\n    x: 'x',\n    y: 123,\n    j: 'j',\n};\n```\n\nUnion- och Intersection-typer:\n\nTyper är mer flexibla när det gäller att definiera union- och intersection-typer. Med nyckelordet `type` kan du enkelt skapa union-typer med operatorn `|` och intersection-typer med operatorn `&`. Även om interface också kan representera union-typer indirekt, har de inget inbyggt stöd för intersection-typer.\n\n```typescript\ntype Department = 'dep-x' | 'dep-y'; // Union\n\ntype Person = {\n    name: string;\n    age: number;\n};\n\ntype Employee = {\n    id: number;\n    department: Department;\n};\n\ntype EmployeeInfo = Person & Employee; // Intersection\n```\n\nExempel med interface:\n\n```typescript\ninterface A {\n    x: 'x';\n}\ninterface B {\n    y: 'y';\n}\n\ntype C = A | B; // Union of interfaces\n```\n\n## Klass\n\n### Vanlig klasssyntax\n\nNyckelordet `class` används i TypeScript för att definiera en klass. Nedan kan du se ett exempel:\n\n```typescript\nclass Person {\n    private name: string;\n    private age: number;\n    constructor(name: string, age: number) {\n        this.name = name;\n        this.age = age;\n    }\n    public sayHi(): void {\n        console.log(\n            `Hello, my name is ${this.name} and I am ${this.age} years old.`\n        );\n    }\n}\n```\n\nNyckelordet `class` används för att definiera en klass som heter \"Person\".\n\nKlassen har två privata egenskaper: name av typen `string` och age av typen `number`.\n\nKonstruktorn definieras med nyckelordet `constructor`. Den tar name och age som parametrar och tilldelar dem till motsvarande egenskaper.\n\nKlassen har en `public` metod som heter sayHi som loggar ett hälsningsmeddelande.\n\nFör att skapa en instans av en klass i TypeScript kan du använda nyckelordet `new` följt av klassnamnet, följt av parenteser `()`. Till exempel:\n\n<!-- skip -->\n```typescript\nconst myObject = new Person('John Doe', 25);\nmyObject.sayHi(); // Output: Hello, my name is John Doe and I am 25 years old.\n```\n\n### Konstruktor\n\nKonstruktorer är speciella metoder inom en klass som används för att initiera objektets egenskaper när en instans av klassen skapas.\n\n```typescript\nclass Person {\n    public name: string;\n    public age: number;\n\n    constructor(name: string, age: number) {\n        this.name = name;\n        this.age = age;\n    }\n\n    sayHello() {\n        console.log(\n            `Hello, my name is ${this.name} and I'm ${this.age} years old.`\n        );\n    }\n}\n\nconst john = new Person('Simon', 17);\njohn.sayHello();\n```\n\nDet är möjligt att överlagra en konstruktor med följande syntax:\n\n```typescript\ntype Sex = 'm' | 'f';\n\nclass Person {\n    name: string;\n    age: number;\n    sex: Sex;\n\n    constructor(name: string, age: number, sex?: Sex);\n    constructor(name: string, age: number, sex: Sex) {\n        this.name = name;\n        this.age = age;\n        this.sex = sex ?? 'm';\n    }\n}\n\nconst p1 = new Person('Simon', 17);\nconst p2 = new Person('Alice', 22, 'f');\n```\n\nI TypeScript är det möjligt att definiera flera konstruktoröverlagringar, men du kan bara ha en implementering som måste vara kompatibel med alla överlagringar. Detta kan uppnås genom att använda en valfri parameter.\n\n```typescript\nclass Person {\n    name: string;\n    age: number;\n\n    constructor();\n    constructor(name: string);\n    constructor(name: string, age: number);\n    constructor(name?: string, age?: number) {\n        this.name = name ?? 'Unknown';\n        this.age = age ?? 0;\n    }\n\n    displayInfo() {\n        console.log(`Name: ${this.name}, Age: ${this.age}`);\n    }\n}\n\nconst person1 = new Person();\nperson1.displayInfo(); // Name: Unknown, Age: 0\n\nconst person2 = new Person('John');\nperson2.displayInfo(); // Name: John, Age: 0\n\nconst person3 = new Person('Jane', 25);\nperson3.displayInfo(); // Name: Jane, Age: 25\n```\n\n### Privata och skyddade konstruktorer\n\nI TypeScript kan konstruktorer markeras som privata eller skyddade, vilket begränsar deras åtkomlighet och användning.\n\nPrivata konstruktorer:\nKan bara anropas inom själva klassen. Privata konstruktorer används ofta i scenarier där du vill upprätthålla ett singleton-mönster eller begränsa skapandet av instanser till en fabriksmetod inom klassen.\n\nSkyddade konstruktorer:\nSkyddade konstruktorer är användbara när du vill skapa en basklass som inte ska instansieras direkt men kan utökas av underklasser.\n\n```typescript\nclass BaseClass {\n    protected constructor() {}\n}\n\nclass DerivedClass extends BaseClass {\n    private value: number;\n\n    constructor(value: number) {\n        super();\n        this.value = value;\n    }\n}\n\n// Attempting to instantiate the base class directly will result in an error\n// const baseObj = new BaseClass(); // Error: Constructor of class 'BaseClass' is protected.\n\n// Create an instance of the derived class\nconst derivedObj = new DerivedClass(10);\n```\n\n### Åtkomstmodifierare\n\nÅtkomstmodifierarna `private`, `protected` och `public` används för att styra synligheten och åtkomsten till klassmedlemmar, såsom egenskaper och metoder, i TypeScript-klasser. Dessa modifierare är viktiga för att upprätthålla inkapsling och för att etablera gränser för åtkomst och modifiering av en klass interna tillstånd.\n\nModifieraren `private` begränsar åtkomsten till klassmedlemmen enbart inom den innehållande klassen.\n\nModifieraren `protected` tillåter åtkomst till klassmedlemmen inom den innehållande klassen och dess härledda klasser.\n\nModifieraren `public` ger obegränsad åtkomst till klassmedlemmen och tillåter att den nås från var som helst.\n\n### Get och Set\n\nGetters och setters är speciella metoder som låter dig definiera anpassat åtkomst- och ändringsbeteende för klassegenskaper. De gör det möjligt att kapsla in det interna tillståndet hos ett objekt och tillhandahålla ytterligare logik vid hämtning eller inställning av egenskapsvärden.\nI TypeScript definieras getters och setters med nyckelorden `get` respektive `set`. Här är ett exempel:\n\n```typescript\nclass MyClass {\n    private _myProperty: string;\n\n    constructor(value: string) {\n        this._myProperty = value;\n    }\n    get myProperty(): string {\n        return this._myProperty;\n    }\n    set myProperty(value: string) {\n        this._myProperty = value;\n    }\n}\n```\n\n### Auto-accessorer i klasser\n\nTypeScript version 4.9 lägger till stöd för auto-accessorer, en kommande ECMAScript-funktion. De liknar klassegenskaper men deklareras med nyckelordet \"accessor\".\n\n```typescript\nclass Animal {\n    accessor name: string;\n\n    constructor(name: string) {\n        this.name = name;\n    }\n}\n```\n\nAuto-accessorer \"avsockras\" till privata `get`- och `set`-accessorer som opererar på en otillgänglig egenskap.\n\n<!-- skip -->\n```typescript\nclass Animal {\n    #__name: string;\n\n    get name() {\n        return this.#__name;\n    }\n    set name(value: string) {\n        this.#__name = name;\n    }\n\n    constructor(name: string) {\n        this.name = name;\n    }\n}\n```\n\n### this\n\nI TypeScript refererar nyckelordet `this` till den aktuella instansen av en klass inom dess metoder eller konstruktorer. Det ger dig möjlighet att komma åt och modifiera klassens egenskaper och metoder inifrån dess eget scope.\nDet erbjuder ett sätt att komma åt och manipulera det interna tillståndet hos ett objekt inom dess egna metoder.\n\n```typescript\nclass Person {\n    private name: string;\n    constructor(name: string) {\n        this.name = name;\n    }\n    public introduce(): void {\n        console.log(`Hello, my name is ${this.name}.`);\n    }\n}\n\nconst person1 = new Person('Alice');\nperson1.introduce(); // Hello, my name is Alice.\n```\n\n### Parameteregenskaper\n\nParameteregenskaper gör det möjligt att deklarera och initiera klassegenskaper direkt i konstruktorns parametrar, vilket undviker överflödig kod. Exempel:\n\n```typescript\nclass Person {\n    constructor(\n        private name: string,\n        public age: number\n    ) {\n        // The \"private\" and \"public\" keywords in the constructor\n        // automatically declare and initialize the corresponding class properties.\n    }\n    public introduce(): void {\n        console.log(\n            `Hello, my name is ${this.name} and I am ${this.age} years old.`\n        );\n    }\n}\nconst person = new Person('Alice', 25);\nperson.introduce();\n```\n\n### Abstrakta klasser\n\nAbstrakta klasser används i TypeScript främst för arv; de erbjuder ett sätt att definiera gemensamma egenskaper och metoder som kan ärvas av underklasser.\nDetta är användbart när du vill definiera gemensamt beteende och säkerställa att underklasser implementerar vissa metoder. De ger ett sätt att skapa en hierarki av klasser där den abstrakta basklassen tillhandahåller ett delat gränssnitt och gemensam funktionalitet för underklasserna.\n\n```typescript\nabstract class Animal {\n    protected name: string;\n\n    constructor(name: string) {\n        this.name = name;\n    }\n\n    abstract makeSound(): void;\n}\n\nclass Cat extends Animal {\n    makeSound(): void {\n        console.log(`${this.name} meows.`);\n    }\n}\n\nconst cat = new Cat('Whiskers');\ncat.makeSound(); // Output: Whiskers meows.\n```\n\n### Med generics\n\nKlasser med generics gör det möjligt att definiera återanvändbara klasser som kan arbeta med olika typer.\n\n```typescript\nclass Container<T> {\n    private item: T;\n\n    constructor(item: T) {\n        this.item = item;\n    }\n\n    getItem(): T {\n        return this.item;\n    }\n\n    setItem(item: T): void {\n        this.item = item;\n    }\n}\n\nconst container1 = new Container<number>(42);\nconsole.log(container1.getItem()); //  42\n\nconst container2 = new Container<string>('Hello');\ncontainer2.setItem('World');\nconsole.log(container2.getItem()); // World\n```\n\n### Dekoratörer\n\nDekoratörer tillhandahåller en mekanism för att lägga till metadata, ändra beteende, validera eller utöka funktionaliteten hos målelementet. De är funktioner som körs vid körning. Flera dekoratörer kan tillämpas på en deklaration.\n\nDekoratörer är experimentella funktioner, och följande exempel är bara kompatibla med TypeScript version 5 eller senare med ES6.\n\nFör TypeScript-versioner före 5 bör de aktiveras med egenskapen `experimentalDecorators` i din `tsconfig.json` eller genom att använda `--experimentalDecorators` på kommandoraden (men följande exempel kommer inte att fungera).\n\nNågra vanliga användningsfall för dekoratörer inkluderar:\n\n* Övervakning av egenskapsändringar.\n* Övervakning av metodanrop.\n* Tillägg av extra egenskaper eller metoder.\n* Validering vid körning.\n* Automatisk serialisering och deserialisering.\n* Loggning.\n* Auktorisering och autentisering.\n* Felhantering.\n\nObservera: Dekoratörer för version 5 tillåter inte dekorering av parametrar.\n\nTyper av dekoratörer:\n\n#### Klassdekoratörer\n\nKlassdekoratörer är användbara för att utöka en befintlig klass, till exempel genom att lägga till egenskaper eller metoder, eller samla instanser av en klass. I följande exempel lägger vi till en `toString`-metod som konverterar klassen till en strängrepresentation.\n\n```typescript\ntype Constructor<T = {}> = new (...args: any[]) => T;\n\nfunction toString<Class extends Constructor>(\n    Value: Class,\n    context: ClassDecoratorContext<Class>\n) {\n    return class extends Value {\n        constructor(...args: any[]) {\n            super(...args);\n            console.log(JSON.stringify(this));\n            console.log(JSON.stringify(context));\n        }\n    };\n}\n\n@toString\nclass Person {\n    name: string;\n\n    constructor(name: string) {\n        this.name = name;\n    }\n\n    greet() {\n        return 'Hello, ' + this.name;\n    }\n}\nconst person = new Person('Simon');\n/* Logs:\n{\"name\":\"Simon\"}\n{\"kind\":\"class\",\"name\":\"Person\"}\n*/\n```\n\n#### Egenskapsdekoratör\n\nEgenskapsdekoratörer är användbara för att ändra beteendet hos en egenskap, till exempel genom att ändra initieringsvärden. I följande kod har vi ett skript som ställer in en egenskap till att alltid vara i versaler:\n\n```typescript\nfunction upperCase<T>(\n    target: undefined,\n    context: ClassFieldDecoratorContext<T, string>\n) {\n    return function (this: T, value: string) {\n        return value.toUpperCase();\n    };\n}\n\nclass MyClass {\n    @upperCase\n    prop1 = 'hello!';\n}\n\nconsole.log(new MyClass().prop1); // Logs: HELLO!\n```\n\n#### Metoddekoratör\n\nMetoddekoratörer låter dig ändra eller förbättra beteendet hos metoder. Nedan följer ett exempel på en enkel logger:\n\n```typescript\nfunction log<This, Args extends any[], Return>(\n    target: (this: This, ...args: Args) => Return,\n    context: ClassMethodDecoratorContext<\n        This,\n        (this: This, ...args: Args) => Return\n    >\n) {\n    const methodName = String(context.name);\n\n    function replacementMethod(this: This, ...args: Args): Return {\n        console.log(`LOG: Entering method '${methodName}'.`);\n        const result = target.call(this, ...args);\n        console.log(`LOG: Exiting method '${methodName}'.`);\n        return result;\n    }\n\n    return replacementMethod;\n}\n\nclass MyClass {\n    @log\n    sayHello() {\n        console.log('Hello!');\n    }\n}\n\nnew MyClass().sayHello();\n```\n\nDet loggar:\n\n```shell\nLOG: Entering method 'sayHello'.\nHello!\nLOG: Exiting method 'sayHello'.\n```\n\n#### Getter- och setter-dekoratörer\n\nGetter- och setter-dekoratörer låter dig ändra eller förbättra beteendet hos klass-accessorer. De är användbara, till exempel, för validering av egenskapstilldelningar. Här är ett enkelt exempel på en getter-dekoratör:\n\n```typescript\nfunction range<This, Return extends number>(min: number, max: number) {\n    return function (\n        target: (this: This) => Return,\n        context: ClassGetterDecoratorContext<This, Return>\n    ) {\n        return function (this: This): Return {\n            const value = target.call(this);\n            if (value < min || value > max) {\n                throw 'Invalid';\n            }\n            Object.defineProperty(this, context.name, {\n                value,\n                enumerable: true,\n            });\n            return value;\n        };\n    };\n}\n\nclass MyClass {\n    private _value = 0;\n\n    constructor(value: number) {\n        this._value = value;\n    }\n    @range(1, 100)\n    get getValue(): number {\n        return this._value;\n    }\n}\n\nconst obj = new MyClass(10);\nconsole.log(obj.getValue); // Valid: 10\n\nconst obj2 = new MyClass(999);\nconsole.log(obj2.getValue); // Throw: Invalid!\n```\n\n#### Dekoratörmetadata\n\nDekoratörmetadata förenklar processen för dekoratörer att tillämpa och använda metadata i valfri klass. De kan komma åt en ny metadataegenskap på kontextobjektet, som kan fungera som en nyckel för både primitiva värden och objekt.\nMetadatainformation kan nås på klassen via `Symbol.metadata`.\n\nMetadata kan användas för olika ändamål, till exempel felsökning, serialisering eller beroendeinjektion med dekoratörer.\n\n```typescript\n//@ts-ignore\nSymbol.metadata ??= Symbol('Symbol.metadata'); // Simple polify\n\ntype Context =\n    | ClassFieldDecoratorContext\n    | ClassAccessorDecoratorContext\n    | ClassMethodDecoratorContext; // Context contains property metadata: DecoratorMetadata\n\nfunction setMetadata(_target: any, context: Context) {\n    // Set the metadata object with a primitive value\n    context.metadata[context.name] = true;\n}\n\nclass MyClass {\n    @setMetadata\n    a = 123;\n\n    @setMetadata\n    accessor b = 'b';\n\n    @setMetadata\n    fn() {}\n}\n\nconst metadata = MyClass[Symbol.metadata]; // Get metadata information\n\nconsole.log(JSON.stringify(metadata)); // {\"bar\":true,\"baz\":true,\"foo\":true}\n```\n\n### Arv\n\nArv avser mekanismen genom vilken en klass kan ärva egenskaper och metoder från en annan klass, känd som basklassen eller superklassen. Den härledda klassen, även kallad barnklassen eller underklassen, kan utöka och specialisera basklassens funktionalitet genom att lägga till nya egenskaper och metoder eller åsidosätta befintliga.\n\n```typescript\nclass Animal {\n    name: string;\n\n    constructor(name: string) {\n        this.name = name;\n    }\n\n    speak(): void {\n        console.log('The animal makes a sound');\n    }\n}\n\nclass Dog extends Animal {\n    breed: string;\n\n    constructor(name: string, breed: string) {\n        super(name);\n        this.breed = breed;\n    }\n\n    speak(): void {\n        console.log('Woof! Woof!');\n    }\n}\n\n// Create an instance of the base class\nconst animal = new Animal('Generic Animal');\nanimal.speak(); // The animal makes a sound\n\n// Create an instance of the derived class\nconst dog = new Dog('Max', 'Labrador');\ndog.speak(); // Woof! Woof!\"\n```\n\nTypeScript stöder inte multipelt arv i traditionell bemärkelse utan tillåter istället arv från en enda basklass.\nTypeScript stöder flera gränssnitt. Ett gränssnitt kan definiera ett kontrakt för strukturen hos ett objekt, och en klass kan implementera flera gränssnitt. Detta gör det möjligt för en klass att ärva beteende och struktur från flera källor.\n\n```typescript\ninterface Flyable {\n    fly(): void;\n}\n\ninterface Swimmable {\n    swim(): void;\n}\n\nclass FlyingFish implements Flyable, Swimmable {\n    fly() {\n        console.log('Flying...');\n    }\n\n    swim() {\n        console.log('Swimming...');\n    }\n}\n\nconst flyingFish = new FlyingFish();\nflyingFish.fly();\nflyingFish.swim();\n```\n\nNyckelordet `class` i TypeScript, liknande JavaScript, kallas ofta för syntaktiskt socker. Det introducerades i ECMAScript 2015 (ES6) för att erbjuda en mer välbekant syntax för att skapa och arbeta med objekt på ett klassbaserat sätt. Det är dock viktigt att notera att TypeScript, som en utökning av JavaScript, slutligen kompileras ner till JavaScript, som i grunden förblir prototypbaserat.\n\n### Statiska medlemmar\n\nTypeScript har statiska medlemmar. För att komma åt de statiska medlemmarna i en klass kan du använda klassnamnet följt av en punkt, utan att behöva skapa ett objekt.\n\n```typescript\nclass OfficeWorker {\n    static memberCount: number = 0;\n\n    constructor(private name: string) {\n        OfficeWorker.memberCount++;\n    }\n}\n\nconst w1 = new OfficeWorker('James');\nconst w2 = new OfficeWorker('Simon');\nconst total = OfficeWorker.memberCount;\nconsole.log(total); // 2\n```\n\n### Egenskapsinitiering\n\nDet finns flera sätt att initiera egenskaper för en klass i TypeScript:\n\nInline:\n\nI följande exempel kommer dessa initiala värden att användas när en instans av klassen skapas.\n\n```typescript\nclass MyClass {\n    property1: string = 'default value';\n    property2: number = 42;\n}\n```\n\nI konstruktorn:\n\n```typescript\nclass MyClass {\n    property1: string;\n    property2: number;\n\n    constructor() {\n        this.property1 = 'default value';\n        this.property2 = 42;\n    }\n}\n```\n\nAnvända konstruktorparametrar:\n\n```typescript\nclass MyClass {\n    constructor(\n        private property1: string = 'default value',\n        public property2: number = 42\n    ) {\n        // There is no need to assign the values to the properties explicitly.\n    }\n    log() {\n        console.log(this.property2);\n    }\n}\nconst x = new MyClass();\nx.log();\n```\n\n### Metodöverlagring\n\nMetodöverlagring gör det möjligt för en klass att ha flera metoder med samma namn men olika parametertyper eller ett annat antal parametrar. Detta gör att vi kan anropa en metod på olika sätt baserat på de argument som skickas.\n\n```typescript\nclass MyClass {\n    add(a: number, b: number): number; // Overload signature 1\n    add(a: string, b: string): string; // Overload signature 2\n\n    add(a: number | string, b: number | string): number | string {\n        if (typeof a === 'number' && typeof b === 'number') {\n            return a + b;\n        }\n        if (typeof a === 'string' && typeof b === 'string') {\n            return a.concat(b);\n        }\n        throw new Error('Invalid arguments');\n    }\n}\n\nconst r = new MyClass();\nconsole.log(r.add(10, 5)); // Logs 15\n```\n\n## Generics\n\nGenerics gör det möjligt att skapa återanvändbara komponenter och funktioner som kan arbeta med flera typer. Med generics kan du parameterisera typer, funktioner och gränssnitt, vilket gör att de kan arbeta med olika typer utan att explicit specificera dem i förväg.\n\nGenerics gör det möjligt att göra koden mer flexibel och återanvändbar.\n\n### Generisk typ\n\nFör att definiera en generisk typ använder du vinkelparenteser (`<>`) för att specificera typparametrarna, till exempel:\n\n```typescript\nfunction identity<T>(arg: T): T {\n    return arg;\n}\nconst a = identity('x');\nconst b = identity(123);\n\nconst getLen = <T,>(data: ReadonlyArray<T>) => data.length;\nconst len = getLen([1, 2, 3]);\n```\n\n### Generiska klasser\n\nGenerics kan även tillämpas på klasser, på så sätt kan de arbeta med flera typer genom att använda typparametrar. Detta är användbart för att skapa återanvändbara klassdefinitioner som kan arbeta med olika datatyper samtidigt som typsäkerheten bibehålls.\n\n```typescript\nclass Container<T> {\n    private item: T;\n\n    constructor(item: T) {\n        this.item = item;\n    }\n\n    getItem(): T {\n        return this.item;\n    }\n}\n\nconst numberContainer = new Container<number>(123);\nconsole.log(numberContainer.getItem()); // 123\n\nconst stringContainer = new Container<string>('hello');\nconsole.log(stringContainer.getItem()); // hello\n```\n\n### Generiska begränsningar\n\nGeneriska parametrar kan begränsas med nyckelordet `extends` följt av en typ eller ett gränssnitt som typparametern måste uppfylla.\n\nI följande exempel måste T innehålla en egenskap `length` för att vara giltig:\n\n<!-- skip -->\n```typescript\nconst printLen = <T extends { length: number }>(value: T): void => {\n    console.log(value.length);\n};\n\nprintLen('Hello'); // 5\nprintLen([1, 2, 3]); // 3\nprintLen({ length: 10 }); // 10\nprintLen(123); // Invalid\n```\n\nEn intressant funktion hos generics som introducerades i version 3.4 RC är typinferens för högre ordningens funktioner, vilket introducerade propagerade generiska typargument:\n\n```typescript\ndeclare function pipe<A extends any[], B, C>(\n    ab: (...args: A) => B,\n    bc: (b: B) => C\n): (...args: A) => C;\n\ndeclare function list<T>(a: T): T[];\ndeclare function box<V>(x: V): { value: V };\n\nconst listBox = pipe(list, box); // <T>(a: T) => { value: T[] }\nconst boxList = pipe(box, list); // <V>(x: V) => { value: V }[]\n```\n\nDenna funktionalitet möjliggör enklare typsäker punktfri programmering (pointfree style) vilket är vanligt inom funktionell programmering.\n\n### Generisk kontextuell avsmalning\n\nKontextuell avsmalning för generics är mekanismen i TypeScript som gör det möjligt för kompilatorn att smalna av typen för en generisk parameter baserat på det sammanhang där den används. Det är användbart vid arbete med generiska typer i villkorssatser:\n\n```typescript\nfunction process<T>(value: T): void {\n    if (typeof value === 'string') {\n        // Value is narrowed down to type 'string'\n        console.log(value.length);\n    } else if (typeof value === 'number') {\n        // Value is narrowed down to type 'number'\n        console.log(value.toFixed(2));\n    }\n}\n\nprocess('hello'); // 5\nprocess(3.14159); // 3.14\n```\n\n## Raderade strukturella typer\n\nI TypeScript behöver objekt inte matcha en specifik, exakt typ. Till exempel, om vi skapar ett objekt som uppfyller ett gränssnitts krav, kan vi använda det objektet på platser där det gränssnittet krävs, även om det inte finns någon explicit koppling mellan dem.\nExempel:\n\n```typescript\ntype NameProp1 = {\n    prop1: string;\n};\n\nfunction log(x: NameProp1) {\n    console.log(x.prop1);\n}\n\nconst obj = {\n    prop2: 123,\n    prop1: 'Origin',\n};\n\nlog(obj); // Valid\n```\n\n## Namnrymder\n\nI TypeScript används namnrymder (namespaces) för att organisera kod i logiska behållare, förhindra namnkollisioner och ge ett sätt att gruppera relaterad kod tillsammans.\nAnvändningen av nyckelordet `export` tillåter åtkomst till namnrymden i \"utomstående\" moduler.\n\n```typescript\nexport namespace MyNamespace {\n    export interface MyInterface1 {\n        prop1: boolean;\n    }\n    export interface MyInterface2 {\n        prop2: string;\n    }\n}\n\nconst a: MyNamespace.MyInterface1 = {\n    prop1: true,\n};\n```\n\n## Symboler\n\nSymboler är en primitiv datatyp som representerar ett oföränderligt värde som garanterat är globalt unikt under hela programmets livstid.\n\nSymboler kan användas som nycklar för objektegenskaper och ger ett sätt att skapa icke-uppräkningsbara egenskaper.\n\n```typescript\nconst key1: symbol = Symbol('key1');\nconst key2: symbol = Symbol('key2');\n\nconst obj = {\n    [key1]: 'value 1',\n    [key2]: 'value 2',\n};\n\nconsole.log(obj[key1]); // value 1\nconsole.log(obj[key2]); // value 2\n```\n\nI WeakMaps och WeakSets är symboler nu tillåtna som nycklar.\n\n## Trippelsnedstreck-direktiv\n\nTrippelsnedstreck-direktiv är speciella kommentarer som ger instruktioner till kompilatorn om hur en fil ska bearbetas. Dessa direktiv börjar med tre på varandra följande snedstreck (`///`) och placeras vanligtvis överst i en TypeScript-fil och har ingen effekt på körbeteendet.\n\nTrippelsnedstreck-direktiv används för att referera till externa beroenden, specificera modulinläsningsbeteende, aktivera/inaktivera vissa kompilatorfunktioner, med mera. Några exempel:\n\nReferera till en deklarationsfil:\n\n<!-- skip -->\n```typescript\n/// <reference path=\"path/to/declaration/file.d.ts\" />\n```\n\nAnge modulformat:\n\n<!-- skip -->\n```typescript\n/// <amd|commonjs|system|umd|es6|es2015|none>\n```\n\nAktivera kompilatoralternativ, i följande exempel strikt läge:\n\n<!-- skip -->\n```typescript\n/// <strict|noImplicitAny|noUnusedLocals|noUnusedParameters>\n```\n\n## Typmanipulation\n\n### Skapa typer från typer\n\nDet är möjligt att skapa nya typer genom att komponera, manipulera eller transformera befintliga typer.\n\nIntersektionstyper (`&`):\n\nGör det möjligt att kombinera flera typer till en enda typ:\n\n```typescript\ntype A = { foo: number };\ntype B = { bar: string };\ntype C = A & B; // Intersection of A and B\nconst obj: C = { foo: 42, bar: 'hello' };\n```\n\nUnionstyper (`|`):\n\nGör det möjligt att definiera en typ som kan vara en av flera typer:\n\n```typescript\ntype Result = string | number;\nconst value1: Result = 'hello';\nconst value2: Result = 42;\n```\n\nMappade typer:\n\nGör det möjligt att transformera egenskaperna hos en befintlig typ för att skapa en ny typ:\n\n```typescript\ntype Mutable<T> = {\n    readonly [P in keyof T]: T[P];\n};\ntype Person = {\n    name: string;\n    age: number;\n};\ntype ImmutablePerson = Mutable<Person>; // Properties become read-only\n```\n\nVillkorliga typer:\n\nGör det möjligt att skapa typer baserat på vissa villkor:\n\n```typescript\ntype ExtractParam<T> = T extends (param: infer P) => any ? P : never;\ntype MyFunction = (name: string) => number;\ntype ParamType = ExtractParam<MyFunction>; // string\n```\n\n### Indexerade åtkomsttyper\n\nI TypeScript är det möjligt att komma åt och manipulera typerna av egenskaper inom en annan typ med hjälp av ett index, `Type[Key]`.\n\n```typescript\ntype Person = {\n    name: string;\n    age: number;\n};\n\ntype AgeType = Person['age']; // number\n```\n\n```typescript\ntype MyTuple = [string, number, boolean];\ntype MyType = MyTuple[2]; // boolean\n```\n\n### Verktygstyper\n\nFlera inbyggda verktygstyper kan användas för att manipulera typer. Nedan följer en lista över de mest använda:\n\n#### Awaited\\<T\\>\n\nKonstruerar en typ som rekursivt packar upp Promise-typer.\n\n```typescript\ntype A = Awaited<Promise<string>>; // string\n```\n\n#### Partial\\<T\\>\n\nKonstruerar en typ där alla egenskaper i T är satta som valfria.\n\n```typescript\ntype Person = {\n    name: string;\n    age: number;\n};\n\ntype A = Partial<Person>; // { name?: string | undefined; age?: number | undefined; }\n```\n\n#### Required\\<T\\>\n\nKonstruerar en typ där alla egenskaper i T är satta som obligatoriska.\n\n```typescript\ntype Person = {\n    name?: string;\n    age?: number;\n};\n\ntype A = Required<Person>; // { name: string; age: number; }\n```\n\n#### Readonly\\<T\\>\n\nKonstruerar en typ där alla egenskaper i T är satta som skrivskyddade.\n\n<!-- skip -->\n```typescript\ntype Person = {\n    name: string;\n    age: number;\n};\n\ntype A = Readonly<Person>;\n\nconst a: A = { name: 'Simon', age: 17 };\na.name = 'John'; // Invalid\n```\n\n#### Record\\<K, T\\>\n\nKonstruerar en typ med en uppsättning egenskaper K av typen T.\n\n```typescript\ntype Product = {\n    name: string;\n    price: number;\n};\n\nconst products: Record<string, Product> = {\n    apple: { name: 'Apple', price: 0.5 },\n    banana: { name: 'Banana', price: 0.25 },\n};\n\nconsole.log(products.apple); // { name: 'Apple', price: 0.5 }\n```\n\n#### Pick\\<T, K\\>\n\nKonstruerar en typ genom att välja ut de angivna egenskaperna K från T.\n\n```typescript\ntype Product = {\n    name: string;\n    price: number;\n};\n\ntype Price = Pick<Product, 'price'>; // { price: number; }\n```\n\n#### Omit\\<T, K\\>\n\nKonstruerar en typ genom att utelämna de angivna egenskaperna K från T.\n\n```typescript\ntype Product = {\n    name: string;\n    price: number;\n};\n\ntype Name = Omit<Product, 'price'>; // { name: string; }\n```\n\n#### Exclude\\<T, U\\>\n\nKonstruerar en typ genom att exkludera alla värden av typen U från T.\n\n```typescript\ntype Union = 'a' | 'b' | 'c';\ntype MyType = Exclude<Union, 'a' | 'c'>; // b\n```\n\n#### Extract\\<T, U\\>\n\nKonstruerar en typ genom att extrahera alla värden av typen U från T.\n\n```typescript\ntype Union = 'a' | 'b' | 'c';\ntype MyType = Extract<Union, 'a' | 'c'>; // a | c\n```\n\n#### NonNullable\\<T\\>\n\nKonstruerar en typ genom att exkludera null och undefined från T.\n\n```typescript\ntype Union = 'a' | null | undefined | 'b';\ntype MyType = NonNullable<Union>; // 'a' | 'b'\n```\n\n#### Parameters\\<T\\>\n\nExtraherar parametertyperna för en funktionstyp T.\n\n```typescript\ntype Func = (a: string, b: number) => void;\ntype MyType = Parameters<Func>; // [a: string, b: number]\n```\n\n#### ConstructorParameters\\<T\\>\n\nExtraherar parametertyperna för en konstruktorfunktionstyp T.\n\n```typescript\nclass Person {\n    constructor(\n        public name: string,\n        public age: number\n    ) {}\n}\ntype PersonConstructorParams = ConstructorParameters<typeof Person>; // [name: string, age: number]\nconst params: PersonConstructorParams = ['John', 30];\nconst person = new Person(...params);\nconsole.log(person); // Person { name: 'John', age: 30 }\n```\n\n#### ReturnType\\<T\\>\n\nExtraherar returtypen för en funktionstyp T.\n\n```typescript\ntype Func = (name: string) => number;\ntype MyType = ReturnType<Func>; // number\n```\n\n#### InstanceType\\<T\\>\n\nExtraherar instanstypen för en klasstyp T.\n\n```typescript\nclass Person {\n    name: string;\n\n    constructor(name: string) {\n        this.name = name;\n    }\n\n    sayHello() {\n        console.log(`Hello, my name is ${this.name}!`);\n    }\n}\n\ntype PersonInstance = InstanceType<typeof Person>;\n\nconst person: PersonInstance = new Person('John');\n\nperson.sayHello(); // Hello, my name is John!\n```\n\n#### ThisParameterType\\<T\\>\n\nExtraherar typen av 'this'-parametern från en funktionstyp T.\n\n```typescript\ninterface Person {\n    name: string;\n    greet(this: Person): void;\n}\ntype PersonThisType = ThisParameterType<Person['greet']>; // Person\n```\n\n#### OmitThisParameter\\<T\\>\n\nTar bort 'this'-parametern från en funktionstyp T.\n\n```typescript\nfunction capitalize(this: String) {\n    return this[0].toUpperCase + this.substring(1).toLowerCase();\n}\n\ntype CapitalizeType = OmitThisParameter<typeof capitalize>; // () => string\n```\n\n#### ThisType\\<T\\>\n\nFungerar som en markör för en kontextuell `this`-typ.\n\n<!-- skip -->\n```typescript\ntype Logger = {\n    log: (error: string) => void;\n};\n\nlet helperFunctions: { [name: string]: Function } & ThisType<Logger> = {\n    hello: function () {\n        this.log('some error'); // Valid as \"log\" is a part of \"this\".\n        this.update(); // Invalid\n    },\n};\n```\n\n#### Uppercase\\<T\\>\n\nGör namnet på indatatypen T till versaler.\n\n```typescript\ntype MyType = Uppercase<'abc'>; // \"ABC\"\n```\n\n#### Lowercase\\<T\\>\n\nGör namnet på indatatypen T till gemener.\n\n```typescript\ntype MyType = Lowercase<'ABC'>; // \"abc\"\n```\n\n#### Capitalize\\<T\\>\n\nGör första bokstaven i namnet på indatatypen T till versal.\n\n```typescript\ntype MyType = Capitalize<'abc'>; // \"Abc\"\n```\n\n#### Uncapitalize\\<T\\>\n\nGör första bokstaven i namnet på indatatypen T till gemen.\n\n```typescript\ntype MyType = Uncapitalize<'Abc'>; // \"abc\"\n```\n\n#### NoInfer\\<T\\>\n\nNoInfer är en verktygstyp utformad för att blockera automatisk typinferens inom ramen för en generisk funktion.\n\nExempel:\n\n```typescript\n// Automatic inference of types within the scope of a generic function.\nfunction fn<T extends string>(x: T[], y: T) {\n    return x.concat(y);\n}\nconst r = fn(['a', 'b'], 'c'); // Type here is (\"a\" | \"b\" | \"c\")[]\n```\n\nMed NoInfer:\n\n<!-- skip -->\n```typescript\n// Example function that uses NoInfer to prevent type inference\nfunction fn2<T extends string>(x: T[], y: NoInfer<T>) {\n    return x.concat(y);\n}\n\nconst r2 = fn2(['a', 'b'], 'c'); // Error: Type Argument of type '\"c\"' is not assignable to parameter of type '\"a\" | \"b\"'.\n```\n\n## Övrigt\n\n### Fel och undantagshantering\n\nTypeScript låter dig fånga och hantera fel med hjälp av JavaScripts standardmekanismer för felhantering:\n\nTry-Catch-Finally-block:\n\n```typescript\ntry {\n    // Code that might throw an error\n} catch (error) {\n    // Handle the error\n} finally {\n    // Code that always executes, finally is optional\n}\n```\n\nDu kan också hantera olika typer av fel:\n\n```typescript\ntry {\n    // Code that might throw different types of errors\n} catch (error) {\n    if (error instanceof TypeError) {\n        // Handle TypeError\n    } else if (error instanceof RangeError) {\n        // Handle RangeError\n    } else {\n        // Handle other errors\n    }\n}\n```\n\nAnpassade feltyper:\n\nDet är möjligt att specificera mer specifika fel genom att utöka `Error`-klassen:\n\n```typescript\nclass CustomError extends Error {\n    constructor(message: string) {\n        super(message);\n        this.name = 'CustomError';\n    }\n}\n\nthrow new CustomError('This is a custom error.');\n```\n\n### Mixin-klasser\n\nMixin-klasser låter dig kombinera och komponera beteende från flera klasser till en enda klass. De erbjuder ett sätt att återanvända och utöka funktionalitet utan behov av djupa arvskedjor.\n\n```typescript\nabstract class Identifiable {\n    name: string = '';\n    logId() {\n        console.log('id:', this.name);\n    }\n}\nabstract class Selectable {\n    selected: boolean = false;\n    select() {\n        this.selected = true;\n        console.log('Select');\n    }\n    deselect() {\n        this.selected = false;\n        console.log('Deselect');\n    }\n}\nclass MyClass {\n    constructor() {}\n}\n\n// Extend MyClass to include the behavior of Identifiable and Selectable\ninterface MyClass extends Identifiable, Selectable {}\n\n// Function to apply mixins to a class\nfunction applyMixins(source: any, baseCtors: any[]) {\n    baseCtors.forEach(baseCtor => {\n        Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => {\n            let descriptor = Object.getOwnPropertyDescriptor(\n                baseCtor.prototype,\n                name\n            );\n            if (descriptor) {\n                Object.defineProperty(source.prototype, name, descriptor);\n            }\n        });\n    });\n}\n\n// Apply the mixins to MyClass\napplyMixins(MyClass, [Identifiable, Selectable]);\nlet o = new MyClass();\no.name = 'abc';\no.logId();\no.select();\n```\n\n### Asynkrona språkfunktioner\n\nEftersom TypeScript är en superset av JavaScript har det inbyggda asynkrona språkfunktioner från JavaScript som:\n\nPromises:\n\nPromises är ett sätt att hantera asynkrona operationer och deras resultat med hjälp av metoder som `.then()` och `.catch()` för att hantera framgångs- och feltillstånd.\n\nLäs mer: [https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)\n\nAsync/await:\n\nNyckelorden async/await erbjuder en mer synkront utseende syntax för att arbeta med Promises. Nyckelordet `async` används för att definiera en asynkron funktion, och nyckelordet `await` används inom en async-funktion för att pausa körningen tills ett Promise har lösts eller avvisats.\n\nLäs mer:\n[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function)\n[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await)\n\nFöljande API:er stöds väl i TypeScript:\n\nFetch API:\n[https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API)\n\nWeb Workers:\n[https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API)\n\nShared Workers:\n[https://developer.mozilla.org/en-US/docs/Web/API/SharedWorker](https://developer.mozilla.org/en-US/docs/Web/API/SharedWorker)\n\nWebSocket:\n[https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API)\n\n### Iteratorer och generatorer\n\nBåde iteratorer och generatorer stöds väl i TypeScript.\n\nIteratorer är objekt som implementerar iteratorprotokollet och erbjuder ett sätt att komma åt element i en samling eller sekvens ett i taget. Det är en struktur som innehåller en pekare till nästa element i iterationen. De har en `next()`-metod som returnerar nästa värde i sekvensen tillsammans med en boolean som anger om sekvensen är `done` (klar).\n\n```typescript\nclass NumberIterator implements Iterable<number> {\n    private current: number;\n\n    constructor(\n        private start: number,\n        private end: number\n    ) {\n        this.current = start;\n    }\n\n    public next(): IteratorResult<number> {\n        if (this.current <= this.end) {\n            const value = this.current;\n            this.current++;\n            return { value, done: false };\n        } else {\n            return { value: undefined, done: true };\n        }\n    }\n\n    [Symbol.iterator](): Iterator<number> {\n        return this;\n    }\n}\n\nconst iterator = new NumberIterator(1, 3);\n\nfor (const num of iterator) {\n    console.log(num);\n}\n```\n\nGeneratorer är speciella funktioner definierade med syntaxen `function*` som förenklar skapandet av iteratorer. De använder nyckelordet `yield` för att definiera sekvensen av värden och pausar och återupptar automatiskt körningen när värden efterfrågas.\n\nGeneratorer gör det enklare att skapa iteratorer och är särskilt användbara för att arbeta med stora eller oändliga sekvenser.\n\nExempel:\n\n```typescript\nfunction* numberGenerator(start: number, end: number): Generator<number> {\n    for (let i = start; i <= end; i++) {\n        yield i;\n    }\n}\n\nconst generator = numberGenerator(1, 5);\n\nfor (const num of generator) {\n    console.log(num);\n}\n```\n\nTypeScript stöder också asynkrona iteratorer och asynkrona generatorer.\n\nLäs mer:\n\n[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Generator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Generator)\n\n[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Iterator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Iterator)\n\n### TsDocs JSDoc-referens\n\nNär man arbetar med en JavaScript-kodbas är det möjligt att hjälpa TypeScript att härleda rätt typ genom att använda JSDoc-kommentarer med ytterligare annotationer för att ge typinformation.\n\nExempel:\n\n```typescript\n/**\n * Computes the power of a given number\n * @constructor\n * @param {number} base – The base value of the expression\n * @param {number} exponent – The exponent value of the expression\n */\nfunction power(base: number, exponent: number) {\n    return Math.pow(base, exponent);\n}\npower(10, 2); // function power(base: number, exponent: number): number\n```\n\nFullständig dokumentation finns på denna länk:\n[https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html](https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html)\n\nFrån version 3.7 är det möjligt att generera .d.ts-typdefinitioner från JavaScript JSDoc-syntax.\nMer information finns här:\n[https://www.typescriptlang.org/docs/handbook/declaration-files/dts-from-js.html](https://www.typescriptlang.org/docs/handbook/declaration-files/dts-from-js.html)\n\n### @types\n\nPaket under @types-organisationen är speciella paketnamnkonventioner som används för att tillhandahålla typdefinitioner för befintliga JavaScript-bibliotek eller moduler. Till exempel genom att använda:\n\n```shell\nnpm install --save-dev @types/lodash\n```\n\nInstalleras typdefinitionerna för `lodash` i ditt nuvarande projekt.\n\nFör att bidra till typdefinitionerna för @types-paket, skicka in en pull request till [https://github.com/DefinitelyTyped/DefinitelyTyped](https://github.com/DefinitelyTyped/DefinitelyTyped).\n\n### JSX\n\nJSX (JavaScript XML) är en utökning av JavaScript-språksyntaxen som låter dig skriva HTML-liknande kod i dina JavaScript- eller TypeScript-filer. Det används vanligtvis i React för att definiera HTML-strukturen.\n\nTypeScript utökar JSX:s kapacitet genom att tillhandahålla typkontroll och statisk analys.\n\nFör att använda JSX behöver du ställa in kompileringsalternativet `jsx` i din `tsconfig.json`-fil. Två vanliga konfigurationsalternativ:\n\n* \"preserve\": genererar .jsx-filer med JSX oförändrad. Detta alternativ talar om för TypeScript att behålla JSX-syntaxen som den är och inte transformera den under kompileringsprocessen. Du kan använda detta alternativ om du har ett separat verktyg, som Babel, som hanterar transformationen.\n* \"react\": aktiverar TypeScripts inbyggda JSX-transformation. React.createElement kommer att användas.\n\nAlla alternativ finns tillgängliga här:\n[https://www.typescriptlang.org/tsconfig#jsx](https://www.typescriptlang.org/tsconfig#jsx)\n\n### ES6-moduler\n\nTypeScript stöder ES6 (ECMAScript 2015) och många efterföljande versioner. Det innebär att du kan använda ES6-syntax, såsom pilfunktioner, mallsträngar, klasser, moduler, destrukturering och mer.\n\nFör att aktivera ES6-funktioner i ditt projekt kan du ange egenskapen `target` i tsconfig.json.\n\nEtt konfigurationsexempel:\n\n```json\n{\n  \"compilerOptions\": {\n    \"target\": \"es6\",\n    \"module\": \"es6\",\n    \"moduleResolution\": \"node\",\n    \"sourceMap\": true,\n    \"outDir\": \"dist\"\n  },\n  \"include\": [\"src\"]\n}\n```\n\n### ES7 exponentiationsoperator\n\nExponentiationsoperatorn (`**`) beräknar värdet som erhålls genom att upphöja den första operanden till den andra operandens potens. Den fungerar på liknande sätt som `Math.pow()`, men med den ytterligare förmågan att acceptera BigInts som operander.\nTypeScript stöder denna operator fullt ut genom att använda `es2016` eller en senare version som `target` i din tsconfig.json-fil.\n\n```typescript\nconsole.log(2 ** (2 ** 2)); // 16\n```\n\n### for-await-of-satsen\n\nDetta är en JavaScript-funktion som stöds fullt ut i TypeScript och som låter dig iterera över asynkrona iterbara objekt från målversion es2018.\n\n```typescript\nasync function* asyncNumbers(): AsyncIterableIterator<number> {\n    yield Promise.resolve(1);\n    yield Promise.resolve(2);\n    yield Promise.resolve(3);\n}\n\n(async () => {\n    for await (const num of asyncNumbers()) {\n        console.log(num);\n    }\n})();\n```\n\n### Metaegenskapen new.target\n\nDu kan i TypeScript använda metaegenskapen `new.target` som gör det möjligt att avgöra om en funktion eller konstruktor anropades med new-operatorn. Det låter dig upptäcka om ett objekt skapades som ett resultat av ett konstruktoranrop.\n\n```typescript\nclass Parent {\n    constructor() {\n        console.log(new.target); // Logs the constructor function used to create an instance\n    }\n}\n\nclass Child extends Parent {\n    constructor() {\n        super();\n    }\n}\n\nconst parentX = new Parent(); // [Function: Parent]\nconst child = new Child(); // [Function: Child]\n```\n\n### Dynamiska importuttryck\n\nDet är möjligt att villkorligt ladda moduler eller lat-ladda dem vid behov med hjälp av ECMAScript-förslaget för dynamisk import som stöds i TypeScript.\n\nSyntaxen för dynamiska importuttryck i TypeScript är följande:\n\n<!-- skip -->\n```typescript\nasync function renderWidget() {\n    const container = document.getElementById('widget');\n    if (container !== null) {\n        const widget = await import('./widget'); // Dynamic import\n        widget.render(container);\n    }\n}\n\nrenderWidget();\n```\n\n### \"tsc –watch\"\n\nDetta kommando startar TypeScript-kompilatorn med parametern `--watch`, med möjligheten att automatiskt kompilera om TypeScript-filer när de ändras.\n\n```shell\ntsc --watch\n```\n\nFrån och med TypeScript version 4.9 förlitar sig filövervakning främst på filsystemhändelser och faller automatiskt tillbaka till polling om en händelsebaserad övervakare inte kan upprättas.\n\n### Non-null Assertion Operator\n\nNon-null Assertion Operator (Postfix !) även kallad Definite Assignment Assertions är en TypeScript-funktion som låter dig försäkra att en variabel eller egenskap inte är null eller undefined, även om TypeScripts statiska typanalys antyder att den kan vara det. Med denna funktion är det möjligt att ta bort all explicit kontroll.\n\n```typescript\ntype Person = {\n    name: string;\n};\n\nconst printName = (person?: Person) => {\n    console.log(`Name is ${person!.name}`);\n};\n```\n\n### Standarddeklarationer\n\nStandarddeklarationer används när en variabel eller parameter tilldelas ett standardvärde. Det innebär att om inget värde anges för den variabeln eller parametern, kommer standardvärdet att användas istället.\n\n```typescript\nfunction greet(name: string = 'Anonymous'): void {\n    console.log(`Hello, ${name}!`);\n}\ngreet(); // Hello, Anonymous!\ngreet('John'); // Hello, John!\n```\n\n### Valfri kedjning (Optional Chaining)\n\nDen valfria kedjningsoperatorn `?.` fungerar som den vanliga punktoperatorn (`.`) för att komma åt egenskaper eller metoder. Den hanterar dock null- eller undefined-värden smidigt genom att avsluta uttrycket och returnera `undefined`, istället för att kasta ett fel.\n\n```typescript\ntype Person = {\n    name: string;\n    age?: number;\n    address?: {\n        street?: string;\n        city?: string;\n    };\n};\n\nconst person: Person = {\n    name: 'John',\n};\n\nconsole.log(person.address?.city); // undefined\n```\n\n### Nullish coalescing-operatorn\n\nNullish coalescing-operatorn `??` returnerar högerledet om vänsterledet är `null` eller `undefined`; annars returnerar den vänsterledets värde.\n\n```typescript\nconst foo = null ?? 'foo';\nconsole.log(foo); // foo\n\nconst baz = 1 ?? 'baz';\nconst baz2 = 0 ?? 'baz';\nconsole.log(baz); // 1\nconsole.log(baz2); // 0\n```\n\n### Mallsträngslitteraltyper (Template Literal Types)\n\nMallsträngslitteraltyper gör det möjligt att manipulera strängvärden på typnivå och generera nya strängtyper baserade på befintliga. De är användbara för att skapa mer uttrycksfulla och precisa typer från strängbaserade operationer.\n\n```typescript\ntype Department = 'engineering' | 'hr';\ntype Language = 'english' | 'spanish';\ntype Id = `${Department}-${Language}-id`; // \"engineering-english-id\" | \"engineering-spanish-id\" | \"hr-english-id\" | \"hr-spanish-id\"\n```\n\n### Funktionsöverlagring\n\nFunktionsöverlagring låter dig definiera flera funktionssignaturer för samma funktionsnamn, var och en med olika parametertyper och returtyp.\nNär du anropar en överlagrad funktion använder TypeScript de angivna argumenten för att avgöra rätt funktionssignatur:\n\n```typescript\nfunction makeGreeting(name: string): string;\nfunction makeGreeting(names: string[]): string[];\n\nfunction makeGreeting(person: unknown): unknown {\n    if (typeof person === 'string') {\n        return `Hi ${person}!`;\n    } else if (Array.isArray(person)) {\n        return person.map(name => `Hi, ${name}!`);\n    }\n    throw new Error('Unable to greet');\n}\n\nmakeGreeting('Simon');\nmakeGreeting(['Simone', 'John']);\n```\n\n### Rekursiva typer\n\nEn rekursiv typ är en typ som kan referera till sig själv. Detta är användbart för att definiera datastrukturer som har en hierarkisk eller rekursiv struktur (potentiellt oändlig nästning), såsom länkade listor, träd och grafer.\n\n```typescript\ntype ListNode<T> = {\n    data: T;\n    next: ListNode<T> | undefined;\n};\n```\n\n### Rekursiva villkorstyper\n\nDet är möjligt att definiera komplexa typrelationer med hjälp av logik och rekursion i TypeScript.\nLåt oss bryta ner det i enkla termer:\n\nVillkorstyper: låter dig definiera typer baserade på booleska villkor:\n\n```typescript\ntype CheckNumber<T> = T extends number ? 'Number' : 'Not a number';\ntype A = CheckNumber<123>; // 'Number'\ntype B = CheckNumber<'abc'>; // 'Not a number'\n```\n\nRekursion: innebär en typdefinition som refererar till sig själv inom sin egen definition:\n\n```typescript\ntype Json = string | number | boolean | null | Json[] | { [key: string]: Json };\n\nconst data: Json = {\n    prop1: true,\n    prop2: 'prop2',\n    prop3: {\n        prop4: [],\n    },\n};\n```\n\nRekursiva villkorstyper kombinerar både villkorslogik och rekursion. Det innebär att en typdefinition kan bero på sig själv genom villkorslogik, vilket skapar komplexa och flexibla typrelationer.\n\n```typescript\ntype Flatten<T> = T extends Array<infer U> ? Flatten<U> : T;\n\ntype NestedArray = [1, [2, [3, 4], 5], 6];\ntype FlattenedArray = Flatten<NestedArray>; // 2 | 3 | 4 | 5 | 1 | 6\n```\n\n### Stöd för ECMAScript-moduler i Node\n\nNode.js lade till stöd för ECMAScript-moduler från och med version 15.3.0, och TypeScript har haft stöd för ECMAScript-moduler i Node.js sedan version 4.7. Detta stöd kan aktiveras genom att använda egenskapen `module` med värdet `nodenext` i tsconfig.json-filen. Här är ett exempel:\n\n```json\n{\n  \"compilerOptions\": {\n    \"module\": \"nodenext\",\n    \"outDir\": \"./lib\",\n    \"declaration\": true\n  }\n}\n```\n\nNode.js stöder två filändelser för moduler: `.mjs` för ES-moduler och `.cjs` för CommonJS-moduler. Motsvarande filändelser i TypeScript är `.mts` för ES-moduler och `.cts` för CommonJS-moduler. När TypeScript-kompilatorn transpilerar dessa filer till JavaScript skapar den `.mjs`- och `.cjs`-filer.\n\nOm du vill använda ES-moduler i ditt projekt kan du ställa in egenskapen `type` till \"module\" i din package.json-fil. Detta instruerar Node.js att behandla projektet som ett ES-modulprojekt.\n\nDessutom stöder TypeScript även typdeklarationer i .d.ts-filer. Dessa deklarationsfiler tillhandahåller typinformation för bibliotek eller moduler skrivna i TypeScript, vilket låter andra utvecklare använda dem med TypeScripts typkontroll och autokompletteringsfunktioner.\n\n### Assertionsfunktioner\n\nI TypeScript är assertionsfunktioner funktioner som indikerar verifieringen av ett specifikt villkor baserat på sitt returvärde. I sin enklaste form undersöker en assert-funktion ett givet predikat och kastar ett fel när predikatet utvärderas till false.\n\n```typescript\nfunction isNumber(value: unknown): asserts value is number {\n    if (typeof value !== 'number') {\n        throw new Error('Not a number');\n    }\n}\n```\n\nDe kan också deklareras som funktionsuttryck:\n\n```typescript\ntype AssertIsNumber = (value: unknown) => asserts value is number;\nconst isNumber: AssertIsNumber = value => {\n    if (typeof value !== 'number') {\n        throw new Error('Not a number');\n    }\n};\n```\n\nAssertionsfunktioner delar likheter med typskydd (type guards). Typskydd introducerades ursprungligen för att utföra körtidskontroller och säkerställa typen av ett värde inom ett specifikt scope.\nSpecifikt är ett typskydd en funktion som utvärderar ett typpredikat och returnerar ett booleskt värde som anger om predikatet är sant eller falskt. Detta skiljer sig något från assertionsfunktioner, där avsikten är att kasta ett fel snarare än att returnera false när predikatet inte uppfylls.\n\nExempel på typskydd:\n\n```typescript\nconst isNumber = (value: unknown): value is number => typeof value === 'number';\n```\n\n### Variadiska tuppeltyper\n\nVariadiska tuppeltyper är en funktion som introducerades i TypeScript version 4.0. Låt oss börja med att repetera vad en tuppel är:\n\nEn tuppeltyp är en array som har en definierad längd, och där typen av varje element är känd:\n\n```typescript\ntype Student = [string, number];\nconst [name, age]: Student = ['Simone', 20];\n```\n\nTermen \"variadisk\" betyder obestämd aritet (accepterar ett variabelt antal argument).\n\nEn variadisk tuppel är en tuppeltyp som har alla egenskaper som ovan men vars exakta form ännu inte är definierad:\n\n```typescript\ntype Bar<T extends unknown[]> = [boolean, ...T, number];\n\ntype A = Bar<[boolean]>; // [boolean, boolean, number]\ntype B = Bar<['a', 'b']>; // [boolean, 'a', 'b', number]\ntype C = Bar<[]>; // [boolean, number]\n```\n\nI den föregående koden kan vi se att tuppelns form definieras av den generiska typen `T` som skickas in.\n\nVariadiska tuppler kan acceptera flera generiska typer vilket gör dem mycket flexibla:\n\n```typescript\ntype Bar<T extends unknown[], G extends unknown[]> = [...T, boolean, ...G];\n\ntype A = Bar<[number], [string]>; // [number, boolean, string]\ntype B = Bar<['a', 'b'], [boolean]>; // [\"a\", \"b\", boolean, boolean]\n```\n\nMed de nya variadiska tupplerna kan vi använda:\n\n* Spridningar i tuppeltypssyntax kan nu vara generiska, så vi kan representera högre ordningens operationer på tuppler och arrayer även när vi inte känner till de faktiska typerna vi opererar på.\n* Restelement kan förekomma var som helst i en tuppel.\n\nExempel:\n\n```typescript\ntype Items = readonly unknown[];\n\nfunction concat<T extends Items, U extends Items>(\n    arr1: T,\n    arr2: U\n): [...T, ...U] {\n    return [...arr1, ...arr2];\n}\n\nconcat([1, 2, 3], ['4', '5', '6']); // [1, 2, 3, \"4\", \"5\", \"6\"]\n```\n\n### Inkapslingstyper (Boxed types)\n\nInkapslingstyper refererar till omslagsobjekten som används för att representera primitiva typer som objekt. Dessa omslagsobjekt tillhandahåller ytterligare funktionalitet och metoder som inte är direkt tillgängliga på de primitiva värdena.\n\nNär du anropar en metod som `charAt` eller `normalize` på en primitiv `string`, omsluter JavaScript den i ett `String`-objekt, anropar metoden och kastar sedan bort objektet.\n\nDemonstration:\n\n```typescript\nconst originalNormalize = String.prototype.normalize;\nString.prototype.normalize = function () {\n    console.log(this, typeof this);\n    return originalNormalize.call(this);\n};\nconsole.log('\\u0041'.normalize());\n```\n\nTypeScript representerar denna skillnad genom att tillhandahålla separata typer för primitiverna och deras motsvarande objektomslag:\n\n* string => String\n* number => Number\n* boolean => Boolean\n* symbol => Symbol\n* bigint => BigInt\n\nInkapslingstyperna behövs vanligtvis inte. Undvik att använda inkapslingstyper och använd istället typer för primitiverna, till exempel `string` istället för `String`.\n\n### Kovarians och kontravarians i TypeScript\n\nKovarians och kontravarians används för att beskriva hur relationer fungerar vid hantering av arv eller tilldelning av typer.\n\nKovarians innebär att en typrelation bevarar riktningen för arv eller tilldelning, så om en typ A är en subtyp av typ B, anses också en array av typ A vara en subtyp av en array av typ B. Det viktiga att notera här är att subtyprelationen bibehålls, vilket innebär att kovarians accepterar subtyper men inte accepterar supertyper.\n\nKontravarians innebär att en typrelation vänder riktningen för arv eller tilldelning, så om en typ A är en subtyp av typ B, anses en array av typ B vara en subtyp av en array av typ A. Subtyprelationen är omvänd, vilket innebär att kontravarians accepterar supertyper men inte accepterar subtyper.\n\nNotera: Bivarians innebär att både supertyper och subtyper accepteras.\n\nExempel: Låt oss säga att vi har ett utrymme för alla djur och ett separat utrymme bara för hundar.\n\nVid kovarians kan du placera alla hundar i djurutrymmet eftersom hundar är en typ av djur. Men du kan inte placera alla djur i hundutrymmet eftersom det kan finnas andra djur inblandade.\n\nVid kontravarians kan du inte placera alla djur i hundutrymmet eftersom djurutrymmet kan innehålla andra djur också. Däremot kan du placera alla hundar i djurutrymmet eftersom alla hundar också är djur.\n\n<!-- skip -->\n```typescript\n// Covariance example\nclass Animal {\n    name: string;\n    constructor(name: string) {\n        this.name = name;\n    }\n}\n\nclass Dog extends Animal {\n    breed: string;\n    constructor(name: string, breed: string) {\n        super(name);\n        this.breed = breed;\n    }\n}\n\nlet animals: Animal[] = [];\nlet dogs: Dog[] = [];\n\n// Covariance allows assigning subtype (Dog) array to supertype (Animal) array\nanimals = dogs;\ndogs = animals; // Invalid: Type 'Animal[]' is not assignable to type 'Dog[]'\n\n// Contravariance example\ntype Feed<in T> = (animal: T) => void;\n\nlet feedAnimal: Feed<Animal> = (animal: Animal) => {\n    console.log(`Animal name: ${animal.name}`);\n};\n\nlet feedDog: Feed<Dog> = (dog: Dog) => {\n    console.log(`Dog name: ${dog.name}, Breed: ${dog.breed}`);\n};\n\n// Contravariance allows assigning supertype (Animal) callback to subtype (Dog) callback\nfeedDog = feedAnimal;\nfeedAnimal = feedDog; // Invalid: Type 'Feed<Dog>' is not assignable to type 'Feed<Animal>'.\n```\n\nI TypeScript är typrelationer för arrayer kovarianta, medan typrelationer för funktionsparametrar är kontravarianta. Det innebär att TypeScript uppvisar både kovarians och kontravarians beroende på sammanhanget.\n\n#### Valfria variansannotationer för typparametrar\n\nFrån och med TypeScript 4.7.0 kan vi använda nyckelorden `out` och `in` för att vara specifika med variansannotationer.\n\nFör kovarians, använd nyckelordet `out`:\n\n```typescript\ntype AnimalCallback<out T> = () => T; // T is Covariant here\n```\n\nOch för kontravarians, använd nyckelordet `in`:\n\n```typescript\ntype AnimalCallback<in T> = (value: T) => void; // T is Contravariance here\n```\n\n### Mallsträngsmönsterindexsignaturer\n\nMallsträngsmönsterindexsignaturer gör det möjligt att definiera flexibla indexsignaturer med hjälp av mallsträngsmönster. Denna funktion gör det möjligt att skapa objekt som kan indexeras med specifika mönster av strängnycklar, vilket ger mer kontroll och specificitet vid åtkomst och manipulering av egenskaper.\n\nTypeScript tillåter från version 4.4 indexsignaturer för symboler och mallsträngsmönster.\n\n```typescript\nconst uniqueSymbol = Symbol('description');\n\ntype MyKeys = `key-${string}`;\n\ntype MyObject = {\n    [uniqueSymbol]: string;\n    [key: MyKeys]: number;\n};\n\nconst obj: MyObject = {\n    [uniqueSymbol]: 'Unique symbol key',\n    'key-a': 123,\n    'key-b': 456,\n};\n\nconsole.log(obj[uniqueSymbol]); // Unique symbol key\nconsole.log(obj['key-a']); // 123\nconsole.log(obj['key-b']); // 456\n```\n\n### satisfies-operatorn\n\nOperatorn `satisfies` låter dig kontrollera om en given typ uppfyller ett specifikt gränssnitt eller villkor. Med andra ord säkerställer den att en typ har alla nödvändiga egenskaper och metoder för ett specifikt gränssnitt. Det är ett sätt att säkerställa att en variabel passar in i en typdefinition.\nHär är ett exempel:\n\n<!-- skip -->\n```typescript\ntype Columns = 'name' | 'nickName' | 'attributes';\n\ntype User = Record<Columns, string | string[] | undefined>;\n\n// Type Annotation using `User`\nconst user: User = {\n    name: 'Simone',\n    nickName: undefined,\n    attributes: ['dev', 'admin'],\n};\n\n// In the following lines, TypeScript won't be able to infer properly\nuser.attributes?.map(console.log); // Property 'map' does not exist on type 'string | string[]'. Property 'map' does not exist on type 'string'.\nuser.nickName; // string | string[] | undefined\n\n// Type assertion using `as`\nconst user2 = {\n    name: 'Simon',\n    nickName: undefined,\n    attributes: ['dev', 'admin'],\n} as User;\n\n// Here too, TypeScript won't be able to infer properly\nuser2.attributes?.map(console.log); // Property 'map' does not exist on type 'string | string[]'. Property 'map' does not exist on type 'string'.\nuser2.nickName; // string | string[] | undefined\n\n// Using `satisfies` operators we can properly infer the types now\nconst user3 = {\n    name: 'Simon',\n    nickName: undefined,\n    attributes: ['dev', 'admin'],\n} satisfies User;\n\nuser3.attributes?.map(console.log); // TypeScript infers correctly: string[]\nuser3.nickName; // TypeScript infers correctly: undefined\n```\n\n### Importer och exporter av enbart typer\n\nImporter och exporter av enbart typer låter dig importera eller exportera typer utan att importera eller exportera de värden eller funktioner som är associerade med dessa typer. Detta kan vara användbart för att minska storleken på ditt paket.\n\nFör att använda importer av enbart typer kan du använda nyckelordet `import type`.\n\nTypeScript tillåter användning av både deklarations- och implementationsfiländelser (.ts, .mts, .cts och .tsx) i importer av enbart typer, oavsett inställningarna för `allowImportingTsExtensions`.\n\nTill exempel:\n\n<!-- skip -->\n```typescript\nimport type { House } from './house.ts';\n```\n\nFöljande former stöds:\n\n<!-- skip -->\n```typescript\nimport type T from './mod';\nimport type { A, B } from './mod';\nimport type * as Types from './mod';\nexport type { T };\nexport type { T } from './mod';\n```\n\n### using-deklaration och explicit resurshantering\n\nEn `using`-deklaration är en blockomfattande, oföränderlig bindning, liknande `const`, som används för att hantera disponibla resurser. När den initialiseras med ett värde registreras värdets `Symbol.dispose`-metod och körs sedan vid utgång ur det omslutande blockomfånget.\n\nDetta baseras på ECMAScripts resurshanteringsfunktion, som är användbar för att utföra väsentliga uppstädningsuppgifter efter objektskapande, såsom att stänga anslutningar, radera filer och frigöra minne.\n\nNoteringar:\n\n* På grund av dess nyliga introduktion i TypeScript version 5.2 saknar de flesta körmiljöer inbyggt stöd. Du behöver polyfills för: `Symbol.dispose`, `Symbol.asyncDispose`, `DisposableStack`, `AsyncDisposableStack`, `SuppressedError`.\n* Dessutom behöver du konfigurera din tsconfig.json enligt följande:\n\n```json\n{\n    \"compilerOptions\": {\n        \"target\": \"es2022\",\n        \"lib\": [\"es2022\", \"esnext.disposable\", \"dom\"]\n    }\n}\n```\n\nExempel:\n\n<!-- skip -->\n```typescript\n//@ts-ignore\nSymbol.dispose ??= Symbol('Symbol.dispose'); // Simple polify\n\nconst doWork = (): Disposable => {\n    return {\n        [Symbol.dispose]: () => {\n            console.log('disposed');\n        },\n    };\n};\n\nconsole.log(1);\n\n{\n    using work = doWork(); // Resource is declared\n    console.log(2);\n} // Resource is disposed (e.g., `work[Symbol.dispose]()` is evaluated)\n\nconsole.log(3);\n```\n\nKoden loggar:\n\n```shell\n1\n2\ndisposed\n3\n```\n\nEn resurs som kan disponeras måste följa `Disposable`-gränssnittet:\n\n```typescript\n// lib.esnext.disposable.d.ts\ninterface Disposable {\n    [Symbol.dispose](): void;\n}\n```\n\n`using`-deklarationer registrerar resursavyttringsoperationer i en stack, vilket säkerställer att de disponeras i omvänd ordning mot deklarationen:\n\n<!-- skip -->\n```typescript\n{\n    using j = getA(),\n        y = getB();\n    using k = getC();\n} // disposes `C`, then `B`, then `A`.\n```\n\nResurser garanteras att disponeras, även om efterföljande kod eller undantag uppstår. Detta kan leda till att avyttringen potentiellt kastar ett undantag, som eventuellt undertrycker ett annat. För att behålla information om undertryckta fel introduceras ett nytt inbyggt undantag, `SuppressedError`.\n\n#### await using-deklaration\n\nEn `await using`-deklaration hanterar en asynkront disponibel resurs. Värdet måste ha en `Symbol.asyncDispose`-metod, som kommer att inväntas vid blockets slut.\n\n<!-- skip -->\n```typescript\nasync function doWorkAsync() {\n    await using work = doWorkAsync(); // Resource is declared\n} // Resource is disposed (e.g., `await work[Symbol.asyncDispose]()` is evaluated)\n```\n\nFör en asynkront disponibel resurs måste den följa antingen `Disposable`- eller `AsyncDisposable`-gränssnittet:\n\n```typescript\n// lib.esnext.disposable.d.ts\ninterface AsyncDisposable {\n    [Symbol.asyncDispose](): Promise<void>;\n}\n```\n\n<!-- skip -->\n```typescript\n//@ts-ignore\nSymbol.asyncDispose ??= Symbol('Symbol.asyncDispose'); // Simple polify\n\nclass DatabaseConnection implements AsyncDisposable {\n    // A method that is called when the object is disposed asynchronously\n    [Symbol.asyncDispose]() {\n        // Close the connection and return a promise\n        return this.close();\n    }\n\n    async close() {\n        console.log('Closing the connection...');\n        await new Promise(resolve => setTimeout(resolve, 1000));\n        console.log('Connection closed.');\n    }\n}\n\nasync function doWork() {\n    // Create a new connection and dispose it asynchronously when it goes out of scope\n    await using connection = new DatabaseConnection(); //  Resource is declared\n    console.log('Doing some work...');\n} // Resource is disposed (e.g., `await connection[Symbol.asyncDispose]()` is evaluated)\n\ndoWork();\n```\n\nKoden loggar:\n\n```shell\nDoing some work...\nClosing the connection...\nConnection closed.\n```\n\nDeklarationerna `using` och `await using` är tillåtna i följande satser: `for`, `for-in`, `for-of`, `for-await-of`, `switch`.\n\n### Importattribut\n\nTypeScript 5.3:s importattribut (etiketter för importer) talar om för körmiljön hur moduler (JSON, etc.) ska hanteras. Detta förbättrar säkerheten genom att säkerställa tydliga importer och överensstämmer med Content Security Policy (CSP) för säkrare resursladdning. TypeScript säkerställer att de är giltiga men låter körmiljön hantera deras tolkning för specifik modulhantering.\n\nExempel:\n\n<!-- skip -->\n```typescript\nimport config from './config.json' with { type: 'json' };\n```\n\nmed dynamisk import:\n\n<!-- skip -->\n```typescript\nconst config = import('./config.json', { with: { type: 'json' } });\n```\n"
  },
  {
    "path": "README-zh_CN.md",
    "content": "# 简洁的TypeScript之书\n\n《Concise TypeScript Book》全面而简洁地概述了 TypeScript 的功能。它提供了清晰的解释，涵盖了该语言最新版本中的所有方面，从强大的类型系统到高级功能。无论您是初学者还是经验丰富的开发人员，本书都是增强您对 TypeScript 的理解和熟练程度的宝贵资源。\n\n本书完全免费且开源。\n\n我相信高质量的技术教育应该惠及所有人，因此我坚持本书免费开源。\n\n如果本书帮助您解决了 bug、理解了棘手的概念或提升了您的职业发展，请考虑以您认为合适的金额（建议价格：15 美元）或请我喝杯咖啡来支持我的工作。您的支持将帮助我保持内容更新，并添加新的示例和更深入的解释。\n\n[![Buy Me a Coffee](https://img.shields.io/badge/buy_me_a_coffee-FFDD00?style=for-the-badge&logo=buy-me-a-coffee&logoColor=black)](https://www.buymeacoffee.com/simonepoggiali)\n\n[![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.com/donate/?business=QW82ZS956XLFY&no_recurring=0&currency_code=EUR)\n\n## 翻译\n\n本书已被翻译成多种语言版本，包括：\n\n[中文](https://github.com/gibbok/typescript-book/blob/main/README-zh_CN.md)\n\n[意大利](https://github.com/gibbok/typescript-book/blob/main/README-it_IT.md)\n\n[葡萄牙语（巴西）](https://github.com/gibbok/typescript-book/blob/main/README-pt_BR.md)\n\n[瑞典语](https://github.com/gibbok/typescript-book/blob/main/README-sv_SE.md)\n\n## 下载和网站\n\n您还可以下载 Epub 版本：\n\n[https://github.com/gibbok/typescript-book/tree/main/downloads](https://github.com/gibbok/typescript-book/tree/main/downloads)\n\n在线版本可在以下位置获得：\n\n[https://gibbok.github.io/typescript-book](https://gibbok.github.io/typescript-book)\n\n## 目录表\n\n<!-- markdownlint-disable MD004 -->\n- [简洁的TypeScript之书](#简洁的typescript之书)\n  - [翻译](#翻译)\n  - [下载和网站](#下载和网站)\n  - [目录表](#目录表)\n  - [介绍](#介绍)\n  - [关于作者](#关于作者)\n  - [TypeScript简介](#typescript简介)\n    - [什么是TypeScript？](#什么是typescript)\n    - [为什么选择 TypeScript？](#为什么选择-typescript)\n    - [TypeScript 和 JavaScript](#typescript-和-javascript)\n    - [TypeScript 代码生成](#typescript-代码生成)\n    - [现在的现代 JavaScript（降级）](#现在的现代-javascript降级)\n  - [TypeScript 入门](#typescript-入门)\n    - [安装](#安装)\n    - [配置](#配置)\n    - [TypeScript 的配置文件](#typescript-的配置文件)\n      - [target](#target)\n      - [lib](#lib)\n      - [strict](#strict)\n      - [module](#module)\n      - [moduleResolution](#moduleresolution)\n      - [esModuleInterop](#esmoduleinterop)\n      - [jsx](#jsx)\n      - [skipLibCheck](#skiplibcheck)\n      - [files](#files)\n      - [include](#include)\n      - [exclude](#exclude)\n    - [importHelpers](#importhelpers)\n    - [迁移到 TypeScript 的建议](#迁移到-typescript-的建议)\n  - [探索类型系统](#探索类型系统)\n    - [TypeScript 的语言服务](#typescript-的语言服务)\n    - [结构类型](#结构类型)\n    - [TypeScript 的基本比较规则](#typescript-的基本比较规则)\n    - [类型作为集合](#类型作为集合)\n    - [赋值类型：类型声明和类型断言](#赋值类型类型声明和类型断言)\n      - [类型声明](#类型声明)\n      - [类型断言](#类型断言)\n      - [非空断言](#非空断言)\n      - [环境声明](#环境声明)\n    - [属性检测和多余属性检测](#属性检测和多余属性检测)\n    - [弱类型](#弱类型)\n    - [严格的对象字面量检测 (Freshness)](#严格的对象字面量检测-freshness)\n    - [类型推断](#类型推断)\n    - [更高级的推断](#更高级的推断)\n    - [类型加宽](#类型加宽)\n    - [常量](#常量)\n      - [类型参数的 const 修饰符](#类型参数的-const-修饰符)\n    - [常量断言](#常量断言)\n    - [显式类型注释](#显式类型注释)\n    - [类型缩小](#类型缩小)\n      - [条件](#条件)\n      - [抛错或者返回](#抛错或者返回)\n      - [可区分联合](#可区分联合)\n      - [用户定义的类型保护](#用户定义的类型保护)\n  - [原始类型](#原始类型)\n    - [string](#string)\n    - [boolean](#boolean)\n    - [number](#number)\n    - [bigInt](#bigint)\n    - [symbol](#symbol)\n    - [null and undefined](#null-and-undefined)\n    - [Array](#array)\n    - [any](#any)\n  - [类型注释](#类型注释)\n  - [可选属性](#可选属性)\n  - [只读属性](#只读属性)\n  - [索引签名](#索引签名)\n  - [扩展类型](#扩展类型)\n  - [字面量类型](#字面量类型)\n  - [字面量推断](#字面量推断)\n  - [严格空检查](#严格空检查)\n  - [枚举](#枚举)\n    - [数字枚举](#数字枚举)\n    - [字符串枚举](#字符串枚举)\n    - [常量枚举](#常量枚举)\n    - [反向映射](#反向映射)\n    - [环境枚举](#环境枚举)\n    - [计算成员和常量成员](#计算成员和常量成员)\n  - [缩小范围](#缩小范围)\n    - [typeof 类型保护](#typeof-类型保护)\n    - [真实性缩小](#真实性缩小)\n    - [相等缩小](#相等缩小)\n    - [In运算符缩小](#in运算符缩小)\n    - [instanceof 缩小](#instanceof-缩小)\n  - [赋值](#赋值)\n  - [控制流分析](#控制流分析)\n  - [类型谓词](#类型谓词)\n  - [可区分联合](#可区分联合-1)\n  - [never 类型](#never-类型)\n  - [详尽性检查](#详尽性检查)\n  - [对象类型](#对象类型)\n  - [元组类型（匿名）](#元组类型匿名)\n  - [命名元组类型（已标记）](#命名元组类型已标记)\n  - [固定长度元组](#固定长度元组)\n  - [联合类型](#联合类型)\n  - [交集类型](#交集类型)\n  - [类型索引](#类型索引)\n  - [值的类型](#值的类型)\n  - [Func 返回值的类型](#func-返回值的类型)\n  - [模块的类型](#模块的类型)\n  - [映射类型](#映射类型)\n  - [映射类型修饰符](#映射类型修饰符)\n  - [条件类型](#条件类型)\n  - [分配条件类型](#分配条件类型)\n  - [infer 条件类型中的类型推断](#infer-条件类型中的类型推断)\n  - [预定义条件类型](#预定义条件类型)\n  - [模板联合类型](#模板联合类型)\n  - [任意类型](#任意类型)\n  - [未知类型](#未知类型)\n  - [空类型](#空类型)\n  - [Never类型](#never类型)\n  - [接口及类型](#接口及类型)\n    - [通用语法](#通用语法)\n    - [基本类型](#基本类型)\n    - [对象和接口](#对象和接口)\n    - [并集和交集类型](#并集和交集类型)\n  - [内置原始数据类型](#内置原始数据类型)\n  - [常见的内置JS对象](#常见的内置js对象)\n  - [重载](#重载)\n  - [合并与扩展](#合并与扩展)\n  - [类型和接口之间的差异](#类型和接口之间的差异)\n  - [Class](#class)\n    - [通用语法](#通用语法-1)\n    - [构造函数](#构造函数)\n    - [私有和受保护的构造函数](#私有和受保护的构造函数)\n    - [访问修饰符](#访问修饰符)\n    - [Get 与 Set](#get-与-set)\n    - [类中的自动访问器](#类中的自动访问器)\n    - [this](#this)\n    - [参数属性](#参数属性)\n    - [抽象类](#抽象类)\n    - [使用泛型](#使用泛型)\n    - [装饰器](#装饰器)\n      - [类装饰器](#类装饰器)\n      - [属性装饰器](#属性装饰器)\n      - [方法装饰器](#方法装饰器)\n      - [Getter 和 Setter 装饰器](#getter-和-setter-装饰器)\n    - [装饰器元数据](#装饰器元数据)\n    - [继承](#继承)\n    - [静态成员](#静态成员)\n    - [属性初始化](#属性初始化)\n    - [方法重载](#方法重载)\n  - [泛型](#泛型)\n    - [泛型类型](#泛型类型)\n    - [泛型类](#泛型类)\n    - [泛型约束](#泛型约束)\n    - [泛型上下文缩小](#泛型上下文缩小)\n  - [擦除的结构类型](#擦除的结构类型)\n  - [命名空间](#命名空间)\n  - [Symbols](#symbols)\n  - [三斜杠指令](#三斜杠指令)\n  - [类型操作](#类型操作)\n    - [从类型创建类型](#从类型创建类型)\n    - [索引访问类型](#索引访问类型)\n    - [工具类型](#工具类型)\n      - [Awaited\\<T\\>](#awaitedt)\n      - [Partial\\<T\\>](#partialt)\n      - [Required\\<T\\>](#requiredt)\n      - [Readonly\\<T\\>](#readonlyt)\n      - [Record\\<K, T\\>](#recordk-t)\n      - [Pick\\<T, K\\>](#pickt-k)\n      - [Omit\\<T, K\\>](#omitt-k)\n      - [Exclude\\<T, U\\>](#excludet-u)\n      - [Extract\\<T, U\\>](#extractt-u)\n      - [NonNullable\\<T\\>](#nonnullablet)\n      - [Parameters\\<T\\>](#parameterst)\n      - [ConstructorParameters\\<T\\>](#constructorparameterst)\n      - [ReturnType\\<T\\>](#returntypet)\n      - [InstanceType\\<T\\>](#instancetypet)\n      - [ThisParameterType\\<T\\>](#thisparametertypet)\n      - [OmitThisParameter\\<T\\>](#omitthisparametert)\n      - [ThisType\\<T\\>](#thistypet)\n      - [Uppercase\\<T\\>](#uppercaset)\n      - [Lowercase\\<T\\>](#lowercaset)\n      - [Capitalize\\<T\\>](#capitalizet)\n      - [Uncapitalize\\<T\\>](#uncapitalizet)\n      - [NoInfer\\<T\\>](#noinfert)\n  - [其他](#其他)\n    - [错误和异常处理](#错误和异常处理)\n    - [混合类](#混合类)\n    - [异步语言特性](#异步语言特性)\n    - [迭代器和生成器](#迭代器和生成器)\n    - [TsDocs JSDoc 参考](#tsdocs-jsdoc-参考)\n    - [@types](#types)\n    - [JSX](#jsx-1)\n    - [ES6 模块](#es6-模块)\n    - [ES7 求幂运算符](#es7-求幂运算符)\n    - [for-await-of 语句](#for-await-of-语句)\n    - [New target 元属性](#new-target-元属性)\n    - [动态导入表达式](#动态导入表达式)\n    - [\"tsc –watch\"](#tsc-watch)\n    - [默认声明](#默认声明)\n    - [可选链](#可选链)\n    - [空合并运算符](#空合并运算符)\n    - [模板字符串类型](#模板字符串类型)\n    - [函数重载](#函数重载)\n    - [递归类型](#递归类型)\n    - [递归条件类型](#递归条件类型)\n    - [Node 中的 ECMAScript 模块支持](#node-中的-ecmascript-模块支持)\n    - [断言函数](#断言函数)\n    - [可变参数元组类型](#可变参数元组类型)\n    - [装箱类型](#装箱类型)\n    - [TypeScript 中的协变和逆变](#typescript-中的协变和逆变)\n      - [类型参数的可选方差注释](#类型参数的可选方差注释)\n    - [模板字符串模式索引签名](#模板字符串模式索引签名)\n    - [satisfies操作符](#satisfies操作符)\n    - [仅类型导入和导出](#仅类型导入和导出)\n    - [使用声明和显式资源管理](#使用声明和显式资源管理)\n      - [使用声明等待](#使用声明等待)\n    - [导入属性](#导入属性)\n<!-- markdownlint-enable MD004 -->\n\n## 介绍\n\n欢迎来到简洁的TypeScript之书！本指南为您提供有效 TypeScript 开发的基本知识和实践技能。发现编写干净、健壮的代码的关键概念和技术。无论您是初学者还是经验丰富的开发人员，本书都可以作为在项目中利用 TypeScript 强大功能的综合指南和便捷参考。\n\n本书涵盖了 TypeScript 5.2。\n\n## 关于作者\n\nSimone Poggiali 是一位经验丰富的资深工程师，自 90 年代以来便对编写专业级代码充满热情。在他的国际职业生涯中，他曾为众多客户（从初创公司到大型企业）参与过各种项目。HelloFresh、西门子、O2、Leroy Merlin 和 Snowplow 等知名公司都曾受益于他的专业知识和敬业精神。\n\n您可以通过以下平台联系 Simone Poggiali：\n\n* 领英: [https://www.linkedin.com/in/simone-poggiali](https://www.linkedin.com/in/simone-poggiali)\n* GitHub: [https://github.com/gibbok](https://github.com/gibbok)\n* X.com: [https://x.com/gibbok_coding](https://x.com/gibbok_coding)\n* 电子邮箱: gibbok.coding📧gmail.com\n\n完整的贡献者名单：[https://github.com/gibbok/typescript-book/graphs/contributors](https://github.com/gibbok/typescript-book/graphs/contributors)\n\n## TypeScript简介\n\n### 什么是TypeScript？\n\nTypeScript 是一种基于 JavaScript 的强类型编程语言。它最初由 Anders Hejlsberg 于 2012 年设计，目前由微软开发和维护，是一个开源项目。\n\nTypeScript 会被编译成 JavaScript，并可在任何 JavaScript 运行时环境（例如浏览器或服务器上的 Node.js）中执行。\n\n它支持多种编程范式，例如函数式编程、泛型编程、命令式编程和面向对象编程。TypeScript 是一种编译型（转译型）语言，在执行前会被转换为 JavaScript。\n\n### 为什么选择 TypeScript？\n\nTypeScript 是一种强类型语言，有助于防止常见的编程错误，并在程序执行之前避免某些类型的运行时错误。\n\n强类型语言允许开发人员在数据类型定义中指定各种程序约束和行为，从而有助于验证软件的正确性并防止缺陷。这在大规模应用中尤其有价值。\n\nTypeScript 的一些好处\n\n* 静态类型，可选强类型\n* 类型推断\n* 能使用ES6和ES7的新功能\n* 跨平台和跨浏览器兼容性 \\* IntelliSense 工具支持\n\n### TypeScript 和 JavaScript\n\nTypeScript是用`.ts`或`.tsx`文件编写的, 而JavaScript是用`.js`或`.jsx`文件编写的。\n\n扩展名为.tsx或.jsx的文件可以包含 JavaScript 语法扩展 JSX，该扩展在 React 中用于 UI 开发。\n\n就语法而言，TypeScript 是 JavaScript (ECMAScript 2015) 的类型化超集。所有 JavaScript 代码都是有效的 TypeScript 代码，但反之则不然。\n\n例如，考虑 JavaScript 文件中具有.js扩展名的函数，如下所示：\n\n<!-- skip -->\n```typescript\nconst sum = (a, b) => a + b;\n```\n\n该函数可以通过将文件扩展名更改为 .TypeScript 来转换和使用.ts。但是，如果同一个函数使用 TypeScript 类型进行注释，则未经编译就无法在任何 JavaScript 运行时中执行。如果未编译以下 TypeScript 代码，将会产生语法错误\n\n<!-- skip -->\n```typescript\nconst sum = (a: number, b: number): number => a + b;\n```\n\nTypeScript 旨在通过让开发人员使用类型注释定义意图来检测编译期间运行时可能发生的异常。此外，如果没有提供类型注释，TypeScript 也可以捕获问题。例如，以下代码片段未指定任何 TypeScript 类型：\n\n<!-- skip -->\n```typescript\nconst items = [{ x: 1 }, { x: 2 }];\nconst result = items.filter(item => item.y);\n```\n\n在这种情况下，TypeScript 检测到错误并报告：\n\n```text\n类型 '{ x: number; }' 上不存在属性 'y' 。\n```\n\nTypeScript 的类型系统很大程度上受到 JavaScript 运行时行为的影响。例如，加法运算符 (+) 在 JavaScript 中可以执行字符串连接或数字加法，在 TypeScript 中以相同的方式建模：\n\n```typescript\nconst result = '1' + 1; // 结果是string类型\n```\n\nTypeScript 背后的团队经过深思熟虑，决定将 JavaScript 的异常使用标记为错误。例如，考虑以下有效的 JavaScript 代码：\n\n<!-- skip -->\n```typescript\nconst result = 1 + true; // 在JavaScript中, 结果等于2\n```\n\n但是，TypeScript 会抛出错误：\n\n```text\n运算符\"+\"不能应用于类型\"number\"和\"boolean\"。\n``````\n\n出现此错误的原因是 TypeScript 严格强制执行类型兼容性，在这种情况下，它标识了数字和布尔值之间的无效操作。\n\n### TypeScript 代码生成\n\nTypeScript 编译器有两个主要职责：检查类型错误和编译为 JavaScript。这两个过程是相互独立的。类型不会影响 JavaScript 运行时中代码的执行，因为它们在编译过程中会被完全擦除。即使存在类型错误，TypeScript 仍然可以输出 JavaScript。以下是存在类型错误的 TypeScript 代码示例：\n\n<!-- skip -->\n```typescript\nconst add = (a: number, b: number): number => a + b;\nconst result = add('x', 'y'); // \"字符串\"类型的参数不可赋值给\"数字\"类型的参数\n```\n\n但是，它仍然可以生成可执行的 JavaScript 输出：\n\n<!-- skip -->\n```typescript\n'use strict';\nconst add = (a, b) => a + b;\nconst result = add('x', 'y'); // xy\n```\n\n无法在运行时检查 TypeScript 类型。例如：\n\n<!-- skip -->\n```typescript\ninterface Animal {\n    name: string;\n}\ninterface Dog extends Animal {\n    bark: () => void;\n}\ninterface Cat extends Animal {\n    meow: () => void;\n}\nconst makeNoise = (animal: Animal) => {\n    if (animal instanceof Dog) {\n        // \"Dog\"仅指一种类型，但在这里用作值。\n        // ...\n    }\n};\n```\n\n由于编译后类型被删除，因此无法在 JavaScript 中运行此代码。为了在运行时识别类型，我们需要使用另一种机制。TypeScript 提供了多种选项，其中常见的一个是 \"标签联合（tagged union）\"。例如：\n\n```typescript\ninterface Dog {\n    kind: 'dog'; // 标签联合\n    bark: () => void;\n}\ninterface Cat {\n    kind: 'cat'; // 标签联合\n    meow: () => void;\n}\ntype Animal = Dog | Cat;\n\nconst makeNoise = (animal: Animal) => {\n    if (animal.kind === 'dog') {\n        animal.bark();\n    } else {\n        animal.meow();\n    }\n};\n\nconst dog: Dog = {\n    kind: 'dog',\n    bark: () => console.log('bark'),\n};\nmakeNoise(dog);\n```\n\n属性\"kind\"是一个可以在运行时用来区分 JavaScript 中的对象的值。\n\n运行时的值也可能具有与类型声明中声明的类型不同的类型。例如，如果开发人员误解了 API 类型并对其进行了错误注释。\n\nTypeScript 是 JavaScript 的超集，因此\"class\"关键字可以在运行时用作类型和值。\n\n```typescript\nclass Animal {\n    constructor(public name: string) {}\n}\nclass Dog extends Animal {\n    constructor(\n        public name: string,\n        public bark: () => void\n    ) {\n        super(name);\n    }\n}\nclass Cat extends Animal {\n    constructor(\n        public name: string,\n        public meow: () => void\n    ) {\n        super(name);\n    }\n}\ntype Mammal = Dog | Cat;\n\nconst makeNoise = (mammal: Mammal) => {\n    if (mammal instanceof Dog) {\n        mammal.bark();\n    } else {\n        mammal.meow();\n    }\n};\n\nconst dog = new Dog('Fido', () => console.log('bark'));\nmakeNoise(dog);\n```\n\n在 JavaScript 中，\"类\"具有\"prototype\"属性，\"instanceof\"运算符可用于测试构造函数的原型属性是否出现在对象原型链中的任何位置。\n\nTypeScript 对运行时性能没有影响，因为所有类型都将被删除。然而，TypeScript 确实引入了一些构建时间开销。\n\n### 现在的现代 JavaScript（降级）\n\nTypeScript 可以将代码编译为自 ECMAScript 3 (1999) 以来任何已发布的 JavaScript 版本。这意味着 TypeScript 可以将代码从最新的 JavaScript 功能转换为旧版本，这一过程称为降级。这允许使用现代 JavaScript，同时保持与旧运行时环境的最大兼容性。\n\n值得注意的是，在转换为旧版本 JavaScript 的过程中，TypeScript 可能会生成与本机实现相比会产生性能开销的代码。\n\n以下是一些可以在 TypeScript 中使用的现代 JavaScript 功能：\n\n* ECMAScript 模块，而不是 AMD 风格的\"define\"回调或 CommonJS 的\"require\"语句。\n* 用类代替原型。\n* 变量声明使用\"let\"或\"const\"而不是\"var\"。\n* \"for-of\"循环或\".forEach\"而不是传统的\"for\"循环。\n* 用箭头函数代替函数表达式。\n* 解构赋值。\n* 简写属性/方法名称和计算属性名称。\n* 默认函数参数。\n\n通过利用这些现代 JavaScript 功能，开发人员可以在 TypeScript 中编写更具表现力和简洁的代码。\n\n## TypeScript 入门\n\n### 安装\n\nVisual Studio Code 为 TypeScript 语言提供了出色的支持，但不包含 TypeScript 编译器。要安装 TypeScript 编译器，您可以使用包管理器，例如 npm 或yarn：\n\n```shell\nnpm install typescript --save-dev\n```\n\n或者\n\n```shell\nyarn add typescript --dev\n```\n\n确保提交生成的锁定文件，以确保每个团队成员使用相同版本的 TypeScript。\n\n要运行TypeScript编译器，可以使用以下命令\n\n```shell\nnpx tsc\n```\n\n或者\n\n```shell\nyarn tsc\n```\n\n建议按项目安装 TypeScript，而不是全局安装，因为它提供了更可预测的构建过程。但是，对于一次性情况，您可以使用以下命令：\n\n```shell\nnpx tsc\n```\n\n或者安装到全局：\n\n```shell\nnpm install -g typescript\n```\n\n如果您使用的是 Microsoft Visual Studio，则可以在 NuGet 中为 MSBuild 项目获取作为包的 TypeScript。在 NuGet 包管理器控制台中，运行以下命令：\n\n```shell\nInstall-Package Microsoft.TypeScript.MSBuild\n```\n\n在 TypeScript 安装过程中，会安装两个可执行文件：\"tsc\"作为 TypeScript 编译器，\"tsserver\"作为 TypeScript 独立服务器。独立服务器包含编译器和语言服务，编辑器和 IDE 可以利用它们来提供智能代码补全。\n\n此外，还有几种兼容 TypeScript 的转译器可用，例如 Babel（通过插件）或 swc。这些转译器可用于将 TypeScript 代码转换为其他目标语言或版本。\n\n### 配置\n\n可以使用 tsc CLI 选项或利用位于项目根目录中名为 tsconfig.json 的专用配置文件来配置 TypeScript。\n\n要生成预填充推荐设置的 tsconfig.json 文件，您可以使用以下命令：\n\n```shell\ntsc --init\n```\n\n在本地执行tsc命令时，TypeScript 将使用最近的 tsconfig.json 文件中指定的配置来编译代码。\n\n以下是使用默认设置运行的 CLI 命令的一些示例：\n\n```shell\ntsc main.ts // 将一个特定的文件 (main.ts) 编译成 JavaScript\ntsc src/*.ts // 将 'src' 文件夹下任意的 .ts 文件编译成 JavaScript\ntsc app.ts util.ts --outfile index.js // 将 2 个 TypeScript 文件 (app.ts 和 util.ts) 编译成 1 个 JavaScript 文件 (index.js)\n```\n\n### TypeScript 的配置文件\n\ntsconfig.json 文件用于配置 TypeScript 编译器 (tsc)。通常，它与文件一起添加到项目的根目录中package.json。\n\n注意：\n\n* tsconfig.json 即使是 json 格式也接受注释。\n* 建议使用此配置文件而不是命令行选项。\n\n在以下链接中，您可以找到完整的文档及其配置示例：\n\n[https://www.typescriptlang.org/tsconfig](https://www.typescriptlang.org/tsconfig)\n\n[https://www.typescriptlang.org/tsconfig/](https://www.typescriptlang.org/tsconfig/)\n\n以下列出了常见且有用的配置：\n\n#### target\n\n\"target\"属性用于指定 TypeScript 应发出/编译到哪个版本的 JavaScript ECMAScript 版本。对于现代浏览器，ES6是一个不错的选择，对于较旧的浏览器，建议使用ES5。\n\n#### lib\n\n\"lib\"属性用于指定编译时要包含哪些库文件。TypeScript 自动包含\"目标\"属性中指定功能的 API，但可以根据特定需求省略或选择特定库。例如，如果您正在开发服务器项目，则可以排除\"DOM\"库，该库仅在浏览器环境中有用。\n\n#### strict\n\n\"strict\"属性可以提供更强有力的保证并增强类型安全性。建议始终将此属性包含在项目的 tsconfig.json 文件中。启用\"strict\"属性允许 TypeScript ：\n\n* 触发每个源文件的代码使用\"use strict\"。\n* 在类型检查过程中考虑\"null\"和\"undefined\"\n* 当不存在类型注释时禁用\"any\"类型的使用。\n* 在使用\"this\"表达式时引发错误，否则\"this\"会被视为任意类型。\n\n#### module\n\n\"module\"属性设置编译程序支持的模块系统。在运行时，模块加载器用于根据指定的模块系统定位并执行依赖项。\nJavaScript 中最常见的模块加载器是用于服务器端应用程序的 Node.js 的CommonJS和用于基于浏览器的 Web 应用程序中的 AMD 模块的 RequireJS。\nTypeScript 可以为各种模块系统生成代码，包括 UMD、System、ESNext、ES2015/ES6 和 ES2020。\n\n注意：应根据目标环境和该环境中可用的模块加载机制来选择模块系统。\n\n#### moduleResolution\n\n\"moduleResolution\"属性指定模块解析策略。对现代TypeScript代码使用\"node\"，\"classic\"仅用于旧版本的 TypeScript（1.6 之前）。\n\n#### esModuleInterop\n\n\"esModuleInterop\"属性允许从未使用\"default\"属性导出的 CommonJS 模块导入默认值，此属性提供了一个兼容以确保生成的 JavaScript 的兼容性。启用此选项后，我们可以使用 `import MyLibrary from \"my-library\"` 而不是 `import * as MyLibrary from \"my-library\"`。\n\n#### jsx\n\n\"jsx\"属性仅适用于 ReactJS 中使用的 .tsx 文件，并控制 JSX 构造如何编译为 JavaScript。一个常见的选项是\"preserve\"，它将编译为 .jsx 文件，保持 JSX 不变，以便可以将其传递给 Babel 等不同工具进行进一步转换。\n\n#### skipLibCheck\n\n\"skipLibCheck\"属性将阻止 TypeScript 对整个导入的第三方包进行类型检查。此属性将减少项目的编译时间。TypeScript 仍会根据这些包提供的类型定义检查您的代码。\n\n#### files\n\n\"files\"属性向编译器指示必须始终包含在程序中的文件列表。\n\n#### include\n\n<!-- markdownlint-disable MD049 -->\n\"include\"属性向编译器指示我们想要包含的文件列表。此属性允许类似 glob 的模式，例如 \"\\*_\" 表示任何子目录，\"_\" 表示任何文件名，\"?\" 表示可选字符。\n<!-- markdownlint-enable MD049 -->\n\n#### exclude\n\n\"exclude\"属性向编译器指示不应包含在编译中的文件列表。这可以包括\"node_modules\"等文件或测试文件\n注意：tsconfig.json 允许注释。\n\n### importHelpers\n\nTypeScript 在为某些高级或低级 JavaScript 功能生成代码时使用帮助程序代码。 默认情况下，这些助手会在使用它们的文件中复制。 `importHelpers` 选项从 `tslib` 模块导入这些帮助器，从而使 JavaScript 输出更加高效。\n\n### 迁移到 TypeScript 的建议\n\n对于大型项目，建议采用逐渐过渡的方式，其中 TypeScript 和 JavaScript 代码最初共存。只有小型项目才能一次性迁移到 TypeScript。\n\n此转变的第一步是将 TypeScript 引入构建链过程。这可以通过使用\"allowJs\"编译器选项来完成，该选项允许 .ts 和 .tsx 文件与现有 JavaScript 文件共存。由于当 TypeScript 无法从 JavaScript 文件推断类型时，它会回退到变量的\"any\"类型，因此建议在迁移开始时在编译器选项中禁用\"noImplicitAny\"。\n\n第二步是确保您的 JavaScript 测试与 TypeScript 文件一起工作，以便您可以在转换每个模块时运行测试。如果您正在使用 Jest，请考虑使用ts-jest，它允许您使用 Jest 测试 TypeScript 项目。\n\n第三步是在项目中包含第三方库的类型声明。 这些声明可以第三方库的类型声明文件或专门的声明包中找到，你能通过 [https://www.typescriptlang.org/dt/search](https://www.typescriptlang.org/dt/search) 搜索并安装它们。:\n\n```shell\nnpm install --save-dev @types/package-name\n```\n\n或者\n\n```shell\nyarn add --dev @types/package-name\n```\n\n第四步是使用自下而上的方法逐个模块地迁移，遵循从叶开始的依赖关系图。这个想法是开始转换不依赖于其他模块的模块。要可视化依赖关系图，您可以使用该madge工具。\n\n有一些对于转换成 TypeScript 比较友好的模块（外部 API 或规范相关的实用函数和代码），比如Swagger、GraphQL 或 JSONSchema 自动生成 TypeScript 类型定义，并使用在您的项目中。\n\n当没有可用的规范或官方架构时，您可以从原始数据生成类型，例如服务器返回的 JSON。但是，建议从规范而不是数据生成类型，以避免丢失边缘情况。\n\n在迁移过程中，不要进行代码重构，而只专注于向模块添加类型。\n\n第五步是启用\"noImplicitAny\"，这将强制所有类型都是已知和定义的，从而为您的项目提供更好的 TypeScript 体验。\n\n在迁移过程中，您可以使用该@ts-check指令，该指令在 JavaScript 文件中启用 TypeScript 类型检查。该指令提供了宽松版本的类型检查，最初可用于识别 JavaScript 文件中的问题。当@ts-check包含在文件中时，TypeScript 将尝试使用 JSDoc 风格的注释来推断定义。但是，仅在迁移的早期阶段考虑使用 JSDoc 注释。\n\n考虑在你的tsconfig.json文件中将 `noEmitOnError` 设置为 false，即使报告错误，这也将允许您输出 JavaScript 源代码。\n\n## 探索类型系统\n\n### TypeScript 的语言服务\n\nTypeScript 的语言服务, 也被称为 tsserver，提供了各种功能，例如错误报告、诊断、保存时编译、重命名、跳转到定义、补全列表、签名帮助等。 它主要由集成开发环境 (IDE) 使用来提供 IntelliSense 支持。它与 Visual Studio Code 无缝集成，并由 Conquer of Completion (Coc) 等工具使用。\n\n开发人员可以利用专用 API 并创建自己的自定义语言服务插件来增强 TypeScript 编辑体验。这对于实现特殊的 linting 功能或启用自定义模板语言的自动完成特别有用。\n\n<!-- markdownlint-disable MD044 -->\n现实世界中的自定义插件的一个示例是\"typescript-styled-plugin\"，它为样式组件中的 CSS 属性提供语法错误报告和 IntelliSense 支持。\n<!-- markdownlint-enable MD044 -->\n\n有关更多信息和快速入门指南，您可以参考 GitHub 上的官方 TypeScript Wiki： [https://github.com/microsoft/TypeScript/wiki/](https://github.com/microsoft/TypeScript/wiki/)\n\n### 结构类型\n\nTypeScript 基于结构类型系统。这意味着类型的兼容性和等效性由类型的实际结构或定义决定，而不是由其名称或声明位置决定，如 C# 或 C 等主要类型系统中那样。\n\nTypeScript 的结构类型系统是基于 JavaScript 的动态 duck 类型系统在运行时的工作方式而设计的。\n\n以下示例是有效的 TypeScript 代码。正如您所观察到的，\"X\"和\"Y\"具有相同的成员\"a\"，尽管它们具有不同的声明名称。类型由其结构决定，在这种情况下，由于结构相同，因此它们是兼容且有效的。\n\n```typescript\ntype X = {\n    a: string;\n};\ntype Y = {\n    a: string;\n};\nconst x: X = { a: 'a' };\nconst y: Y = x; // 有效\n```\n\n### TypeScript 的基本比较规则\n\nTypeScript 比较过程是递归的，并在任何级别嵌套的类型上执行。\n\n如果\"Y\"至少具有与\"X\"相同的成员，则类型\"X\"与\"Y\"兼容。\n\n```typescript\ntype X = {\n    a: string;\n};\nconst y = { a: 'A', b: 'B' }; // 有效, 至少它拥有相同的成员 X\nconst r: X = y;\n```\n\n函数参数按类型进行比较，而不是按名称进行比较：\n\n```typescript\ntype X = (a: number) => void;\ntype Y = (a: number) => void;\nlet x: X = (j: number) => undefined;\nlet y: Y = (k: number) => undefined;\ny = x; // 有效\nx = y; // 有效\n```\n\n函数返回类型必须相同：\n\n<!-- skip -->\n```typescript\ntype X = (a: number) => undefined;\ntype Y = (a: number) => number;\nlet x: X = (a: number) => undefined;\nlet y: Y = (a: number) => 1;\ny = x; // 无效\nx = y; // 无效\n```\n\n源函数的返回类型必须是目标函数的返回类型的子类型：\n\n<!-- skip -->\n```typescript\nlet x = () => ({ a: 'A' });\nlet y = () => ({ a: 'A', b: 'B' });\nx = y; // 有效\ny = x; // 无效，缺少 b 成员\n```\n\n允许丢弃函数参数，因为这是 JavaScript 中的常见做法，例如使用 \"Array.prototype.map()\"：\n\n```typescript\n[1, 2, 3].map((element, _index, _array) => element + 'x');\n```\n\n因此，以下类型声明是完全有效的：\n\n```typescript\ntype X = (a: number) => undefined;\ntype Y = (a: number, b: number) => undefined;\nlet x: X = (a: number) => undefined;\nlet y: Y = (a: number) => undefined; // 缺少 b 参数\ny = x; // 有效\n```\n\n源类型的任何附加可选参数都是有效的：\n\n```typescript\ntype X = (a: number, b?: number, c?: number) => undefined;\ntype Y = (a: number) => undefined;\nlet x: X = a => undefined;\nlet y: Y = a => undefined;\ny = x; // 有效\nx = y; // 有效\n```\n\n目标类型的任何可选参数在源类型中没有对应的参数都是有效的并且不是错误：\n\n```typescript\ntype X = (a: number) => undefined;\ntype Y = (a: number, b?: number) => undefined;\nlet x: X = a => undefined;\nlet y: Y = a => undefined;\ny = x; // 有效\nx = y; // 有效\n```\n\n其余参数被视为无限系列的可选参数：\n\n```typescript\ntype X = (a: number, ...rest: number[]) => undefined;\nlet x: X = a => undefined; // 有效\n```\n\n如果重载签名与其实现签名兼容，则具有重载的函数有效：\n\n<!-- skip -->\n```typescript\nfunction x(a: string): void;\nfunction x(a: string, b: number): void;\nfunction x(a: string, b?: number): void {\n    console.log(a, b);\n}\nx('a'); // 有效\nx('a', 1); // 有效\n\nfunction y(a: string): void; // 无效, 不兼容重载的签名\nfunction y(a: string, b: number): void;\nfunction y(a: string, b: number): void {\n    console.log(a, b);\n}\ny('a');\ny('a', 1);\n```\n\n如果源参数和目标参数可赋值给超类型或子类型（Bivariance 双变），则函数参数比较成功。\n\n```typescript\n// 超类\nclass X {\n    a: string;\n    constructor(value: string) {\n        this.a = value;\n    }\n}\n// 子类\nclass Y extends X {}\n// 子类\nclass Z extends X {}\n\ntype GetA = (x: X) => string;\nconst getA: GetA = x => x.a;\n\n// 双变（Bivariance） 确实接收超类\nconsole.log(getA(new X('x'))); // 有效\nconsole.log(getA(new Y('Y'))); // 有效\nconsole.log(getA(new Z('z'))); // 有效\n```\n\n枚举与数字具有可比性和有效性，反之亦然，但比较不同枚举类型的枚举值是无效的。\n\n<!-- skip -->\n```typescript\nenum X {\n    A,\n    B,\n}\nenum Y {\n    A,\n    B,\n    C,\n}\nconst xa: number = X.A; // 有效\nconst ya: Y = 0; // 有效\nX.A === Y.A; // 无效\n```\n\n类的实例需要对其私有成员和受保护成员进行兼容性检查：\n\n<!-- skip -->\n```typescript\nclass X {\n    public a: string;\n    constructor(value: string) {\n        this.a = value;\n    }\n}\n\nclass Y {\n    private a: string;\n    constructor(value: string) {\n        this.a = value;\n    }\n}\n\nlet x: X = new Y('y'); // 无效\n```\n\n比较检查不考虑不同的继承层次结构，例如：\n\n```typescript\nclass X {\n    public a: string;\n    constructor(value: string) {\n        this.a = value;\n    }\n}\nclass Y extends X {\n    public a: string;\n    constructor(value: string) {\n        super(value);\n        this.a = value;\n    }\n}\nclass Z {\n    public a: string;\n    constructor(value: string) {\n        this.a = value;\n    }\n}\nlet x: X = new X('x');\nlet y: Y = new Y('y');\nlet z: Z = new Z('z');\nx === y; // 有效\nx === z; // 有效即使 z 来自不同的继承层次结构\n```\n\n泛型根据应用泛型参数后的结果类型使用其结构进行比较，仅将最终结果作为非泛型类型进行比较。\n\n<!-- skip -->\n```typescript\ninterface X<T> {\n    a: T;\n}\nlet x: X<number> = { a: 1 };\nlet y: X<string> = { a: 'a' };\nx === y; // 无效，因为最终结构中使用了类型参数\n```\n\n```typescript\ninterface X<T> {}\nconst x: X<number> = 1;\nconst y: X<string> = 'a';\nx === y; // 有效，因为最终结构中没有使用类型参数\n```\n\n当泛型未指定其类型参数时，所有未指定的参数都将被视为带有\"any\"的类型：\n\n```typescript\ntype X = <T>(x: T) => T;\ntype Y = <K>(y: K) => K;\nlet x: X = x => x;\nlet y: Y = y => y;\nx = y; // 有效\n```\n\n记住：\n\n<!-- skip -->\n```typescript\nlet a: number = 1;\nlet b: number = 2;\na = b; // 有效，一切都可以赋值给自己\n\nlet c: any;\nc = 1; // 有效，所有类型都可以赋值给any\n\nlet d: unknown;\nd = 1; // 有效，所有类型都可以赋值给unknown\n\nlet e: unknown;\nlet e1: unknown = e; // 有效, unknown只能赋值给自己和any\nlet e2: any = e; // 有效\nlet e3: number = e; // 无效\n\nlet f: never;\nf = 1; // 无效, 所有类型不能赋值给never\n\nlet g: void;\nlet g1: any;\ng = 1; // 无效, void不可赋值给除\"any\"之外的任何内容或从任何内容赋值\ng = g1; // 有效\n```\n\n请注意，当启用\"strictNullChecks\"时，\"null\"和\"undefined\"的处理方式与\"void\"类似；否则，它们类似于\"never\"。\n\n### 类型作为集合\n\n在 TypeScript 中，类型是一组可能的值。该集合也称为类型的域。类型的每个值都可以被视为集合中的一个元素。类型建立了集合中的每个元素必须满足才能被视为该集合的成员的约束。TypeScript 的主要任务是检查并验证一组是否是另一组的子集。\n\nTypeScript 支持各种类型的集合：\n\n| Set term | TypeScript                      | Notes                                                                          |\n| -------- | ------------------------------- | ------------------------------------------------------------------------------ |\n| 空集     | never                           | \"never\" 包含除自身之外的任何类型                                               |\n| 单元素集 | undefined / null / literal type |                                                                                |\n| 有限集   | boolean / union                 |                                                                                |\n| 无限集   | string / number / object        |                                                                                |\n| 通用集   | any / unknown                   | 每个元素都是\"any\"的成员，每个集合都是它的子集/\"unknown\"是\"any\"的类型安全对应项 |\n\n这里有几个例子：\n\n| TypScript             | Set term         | Example                                                          |\n| --------------------- | ---------------- | ---------------------------------------------------------------- |\n| never                 | ∅ (空集)         | const x: never = 'x'; // 错误: 'string'类似不能赋值给'never'类型 |\n|                       |                  |\n| Literal type          | 单元素集         | type X = 'X';                                                    |\n|                       |                  | type Y = 7;                                                      |\n|                       |                  |\n| Value assignable to T | Value ∈ T (属于) | type XY = 'X' \\| 'Y';                                            |\n|                       |                  | const x: XY = 'X';                                               |\n|                       |                  |\n| T1 assignable to T2   | T1 ⊆ T2 (子集)   | type XY = 'X' \\| 'Y';                                            |\n|                       |                  | const x: XY = 'X';                                               |\n|                       |                  | const j: XY = 'J'; // 类型'\"J\"' 不能赋值给 'XY' 类型.            |\n|                       |                  |                                                                  |\n| T1 extends T2         | T1 ⊆ T2 (子集)   | type X = 'X' extends string ? true : false;                      |\n|                       |                  |\n| T1 \\| T2              | T1 ∪ T2 (并集)   | type XY = 'X' \\| 'Y';                                            |\n|                       |                  | type JK = 1 \\| 2;                                                |\n|                       |                  |\n| T1 & T2               | T1 ∩ T2 (交集)   | type X = \\{ a: string \\}                                           |\n|                       |                  | type Y = \\{ b: string \\}                                           |\n|                       |                  | type XY = X & Y                                                  |\n|                       |                  | const x: XY = \\{ a: 'a', b: 'b' \\}                                 |\n|                       |                  |\n| unknown               | 通用集           | const x: unknown = 1                                             |\n\n并集 (T1 | T2) 创建一个更广泛的集合（两者）：\n\n```typescript\ntype X = {\n    a: string;\n};\ntype Y = {\n    b: string;\n};\ntype XY = X | Y;\nconst r: XY = { a: 'a', b: 'x' }; // 有效\n```\n\n交集（T1 & T2）创建一个更窄的集合（仅共享）：\n\n<!-- skip -->\n```typescript\ntype X = {\n    a: string;\n};\ntype Y = {\n    a: string;\n    b: string;\n};\ntype XY = X & Y;\nconst r: XY = { a: 'a' }; // 无效\nconst j: XY = { a: 'a', b: 'b' }; // 有效\n```\n\n在这种情况下，关键字extends可以被视为\"的子集\"。它为类型设置约束。与泛型一起使用的扩展将泛型视为无限集，并将其限制为更具体的类型。请注意，这extends与 OOP 意义上的层次结构无关（TypScript 中没有这个概念）。TypeScript 使用集合并且没有严格的层次结构，事实上，如下面的示例所示，两种类型可以重叠，而不会成为另一种类型的子类型（TypScript 考虑对象的结构和形状）。\n\n```typescript\ninterface X {\n    a: string;\n}\ninterface Y extends X {\n    b: string;\n}\ninterface Z extends Y {\n    c: string;\n}\nconst z: Z = { a: 'a', b: 'b', c: 'c' };\ninterface X1 {\n    a: string;\n}\ninterface Y1 {\n    a: string;\n    b: string;\n}\ninterface Z1 {\n    a: string;\n    b: string;\n    c: string;\n}\nconst z1: Z1 = { a: 'a', b: 'b', c: 'c' };\n\nconst r: Z1 = z; // 有效\n```\n\n### 赋值类型：类型声明和类型断言\n\n在 TypeScript 中可以通过不同的方式赋值类型：\n\n#### 类型声明\n\n在下面的示例中，我们使用 x:X(\":Type\") 来声明变量 x 的类型。\n\n```typescript\ntype X = {\n    a: string;\n};\n\n// 类型声明\nconst x: X = {\n    a: 'a',\n};\n```\n\n如果变量不是指定的格式，TypeScript 将报告错误。例如：\n\n<!-- skip -->\n```typescript\ntype X = {\n    a: string;\n};\n\nconst x: X = {\n    a: 'a',\n    b: 'b', // 错误: 对象字面量只能指定已知属性\n};\n```\n\n#### 类型断言\n\n可以使用as关键字添加断言。这告诉编译器开发人员拥有有关类型的更多信息并消除可能发生的任何错误。\n\n例如：\n\n```typescript\ntype X = {\n    a: string;\n};\nconst x = {\n    a: 'a',\n    b: 'b',\n} as X;\n```\n\n在上面的示例中，使用 as 关键字将对象 x 断言为类型 X。这通知 TypeScript 编译器该对象符合指定的类型，即使它具有类型定义中不存在的附加属性 b。\n\n类型断言在需要指定更具体类型的情况下非常有用，尤其是在使用 DOM 时。例如：\n\n```typescript\nconst myInput = document.getElementById('my_input') as HTMLInputElement;\n```\n\n此处，类型断言 HTMLInputElement 用于告诉 TypeScript getElementById 的结果应被视为 HTMLInputElement。类型断言还可以用于重新映射键，如下面使用模板文字的示例所示：\n\n```typescript\ntype J<Type> = {\n    [Property in keyof Type as `prefix_${string &\n        Property}`]: () => Type[Property];\n};\ntype X = {\n    a: string;\n    b: number;\n};\ntype Y = J<X>;\n```\n\n在此示例中，类型 J 使用带有模板文字的映射类型来重新映射 Type 的键。它创建新属性，并在每个键上添加 prefix_ ，它们对应的值是返回原始属性值的函数。\n\n值得注意的是，当使用类型断言时，TypeScript 不会执行多余的属性检查。因此，当预先知道对象的结构时，通常最好使用类型声明。\n\n#### 非空断言\n\n此断言是使用后缀表达式!运算符应用的，它告诉 TypeScript 值不能为 null 或未定义。\n\n```typescript\nlet x: null | number;\nlet y = x!; // number\n```\n\n#### 环境声明\n\n环境声明是描述 JavaScript 代码类型的文件，它们的文件名格式为.d.ts.. 它们通常被导入并用于注释现有的 JavaScript 库或向项目中的现有 JS 文件添加类型。\n\n许多常见的库类型可以在以下位置找到：\n[https://github.com/DefinitelyTyped/DefinitelyTyped/](https://github.com/DefinitelyTyped/DefinitelyTyped/)\n\n```shell\nnpm install --save-dev @types/library-name\n```\n\n对于您定义的环境声明，您可以使用\"三斜杠\"引用导入：\n\n<!-- skip -->\n```typescript\n/// <reference path=\"./library-types.d.ts\" />\n```\n\n即使在 JavaScript 文件中，您也可以通过 `// @ts-check` 使用环境声明。\n\n`declare` 关键字可以为现有的 JavaScript 代码启用类型定义，而无需导入它，作为来自另一个文件或全局的类型的占位符。\n\n### 属性检测和多余属性检测\n\nTypeScript 基于结构类型系统，但过多的属性检查是 TypeScript 的一个属性，它允许它检查对象是否具有类型中指定的确切属性。\n\n例如，在将对象字面量赋值给变量或将它们作为参数传递给函数的多余属性时，会执行多余属性检查。\n\n<!-- skip -->\n```typescript\ntype X = {\n    a: string;\n};\nconst y = { a: 'a', b: 'b' };\nconst x: X = y; // 有效，因为结构类型\nconst w: X = { a: 'a', b: 'b' }; // 无效，因为多余属性检测\n```\n\n### 弱类型\n\n当一个类型只包含一组全可选属性时，该类型被认为是弱类型：\n\n```typescript\ntype X = {\n    a?: string;\n    b?: string;\n};\n```\n\n当没有重叠时，TypeScript 认为将任何内容赋值给弱类型是错误的，例如，以下会引发错误：\n\n<!-- skip -->\n```typescript\ntype Options = {\n    a?: string;\n    b?: string;\n};\n\nconst fn = (options: Options) => undefined;\n\nfn({ c: 'c' }); // 无效\n```\n\n尽管不推荐，但如果需要，可以使用类型断言绕过此检查：\n\n```typescript\ntype Options = {\n    a?: string;\n    b?: string;\n};\nconst fn = (options: Options) => undefined;\nfn({ c: 'c' } as Options); // 有效\n```\n\n或者通过将unknown索引签名添加到弱类型：\n\n```typescript\ntype Options = {\n    [prop: string]: unknown;\n    a?: string;\n    b?: string;\n};\n\nconst fn = (options: Options) => undefined;\nfn({ c: 'c' }); // 有效\n```\n\n### 严格的对象字面量检测 (Freshness)\n\n严格的对象字面量检查（有时称为“新鲜度”）是 TypeScript 中的一项功能，有助于捕获多余或拼写错误的属性，否则这些属性在正常结构类型检查中会被忽视。\n\n创建对象字面量时，TypeScript 编译器认为它是“新鲜的”。 如果将对象字面量分配给变量或作为参数传递，并且对象字面量指定目标类型中不存在的属性，则 TypeScript 将引发错误。\n\n然而，当扩展对象文字或使用类型断言时，“新鲜感”就会消失。\n\n下面举一些例子来说明：\n\n<!-- skip -->\n```typescript\ntype X = { a: string };\ntype Y = { a: string; b: string };\n\nlet x: X;\nx = { a: 'a', b: 'b' }; // 严格的对象字面量检查：无效的赋值\nvar y: Y;\ny = { a: 'a', bx: 'bx' }; // 严格的对象字面量检查：无效的赋值\n\nconst fn = (x: X) => console.log(x.a);\n\nfn(x);\nfn(y); // 类型加宽：没有错误, 结构类型兼容\n\nfn({ a: 'a', bx: 'b' }); // 严格的对象字面量检查：无效的参数\n\nlet c: X = { a: 'a' };\nlet d: Y = { a: 'a', b: '' };\nc = d; // 类型加宽：没有严格的对象字面量检查\n```\n\n### 类型推断\n\n当在以下期间未提供注释时，TypeScript 可以推断类型：\n\n* 变量初始化\n* 成员初始化。\n* 设置参数的默认值。\n* 函数返回类型。\n\n例如：\n\n```typescript\nlet x = 'x'; // 推断的类型是 string\n```\n\nTypeScript 编译器分析值或表达式并根据可用信息确定其类型。\n\n### 更高级的推断\n\n当在类型推断中使用多个表达式时，TypeScript 会查找\"最佳常见类型\"。例如：\n\n```typescript\nlet x = [1, 'x', 1, null]; // 类型推断为: (string | number | null)[]\n```\n\n如果编译器找不到最佳通用类型，它将返回联合类型。例如：\n\n```typescript\nlet x = [new RegExp('x'), new Date()]; // 类型推断为: (RegExp | Date)[]\n```\n\nTypeScript 利用基于变量位置的\"上下文类型\"来推断类型。在下面的示例中，编译器知道它的e类型是MouseEvent，因为在lib.d.ts 文件中定义了click事件类型，该文件包含各种常见 JavaScript 构造和 DOM 的环境声明：\n\n```typescript\nwindow.addEventListener('click', function (e) {}); // e 的类型被推断为 MouseEvent\n```\n\n### 类型加宽\n\n类型加宽是 TypeScript 将类型分配给未提供类型注释时初始化的变量的过程。它允许从窄到宽的类型，但反之则不然。在以下示例中：\n\n<!-- skip -->\n```typescript\nlet x = 'x'; // TypeScript 推断为字符串，一种宽类型\nlet y: 'y' | 'x' = 'y'; // y 类型是字面量类型的联合\ny = x; // 无效，字符串不可分配给类型 'x' | 'y'。\n```\n\nTypeScript根据初始化期间提供的单个值（`x`），将 `string` 赋予给 `x`，这是一个扩展的示例。\n\nTypeScript 提供了控制加宽过程的方法，例如使用\"const\"。\n\n### 常量\n\n在声明变量时使用 `const` 关键字会导致 TypeScript 中的类型推断范围更窄。\n\nFor example:\n\n```typescript\nconst x = 'x'; // TypeScript 将 'x' 推断为带有 'const'（不可变）的字符串字面量，但将其扩展为带有 'let'（可重新赋值）的 'string'。\nlet y: 'y' | 'x' = 'y';\ny = x; // 有效: x的类型推断为 'x'\n```\n\n通过使用 const 声明变量 x，其类型被缩小为特定的文字值\"x\"。由于 x 的类型被缩小，因此可以将其赋值给变量 y 而不会出现任何错误。可以推断类型的原因是因为 const 变量无法重新分配，因此它们的类型可以缩小到特定的文字类型，在本例中为字面量类型\"x\"。\n\n#### 类型参数的 const 修饰符\n\n从 TypeScript 5.0 版本开始，可以 `const` 在泛型类型参数上指定属性。这可以推断出最精确的类型。让我们看一个不使用 `const` 的示例：\n\n```typescript\nfunction identity<T>(value: T) {\n    // 这里没有const\n    return value;\n}\nconst values = identity({ a: 'a', b: 'b' }); // 类型推断为: { a: string; b: string; }\n```\n\n正如您所看到的，属性a和b是通过 类型推断出来的string 。\n\n现在，让我们看看 `const` 版本的差异：\n\n```typescript\nfunction identity<const T>(value: T) {\n    // 对类型参数使用 const 修饰符\n    return value;\n}\nconst values = identity({ a: 'a', b: 'b' }); // 类型推断为: { a: \"a\"; b: \"b\"; }\n```\n\n现在我们可以看到属性 `a` 和 `b` 被推断为const，因此 `a` 和 `b`被视为字符串文字而不仅仅是 `string` 类型。\n\n### 常量断言\n\n此功能允许您根据变量的初始化值声明具有更精确的文字类型的变量，这向编译器表明该值应被视为不可变文字。 这里有一些例子：\n\n在单个属性上：\n\n```typescript\nconst v = {\n    x: 3 as const,\n};\nv.x = 3;\n```\n\n在整个对象上：\n\n```typescript\nconst v = {\n    x: 1,\n    y: 2,\n} as const;\n```\n\n这在定义元组的类型时特别有用：\n\n```typescript\nconst x = [1, 2, 3]; // number[]\nconst y = [1, 2, 3] as const; // 只读数组 [1, 2, 3]\n```\n\n### 显式类型注释\n\n我们可以具体地传递一个类型，在下面的示例中，属性x的类型是number：\n\n```typescript\nconst v = {\n    x: 1, // 推断类型: number (加宽了)\n};\nv.x = 3; // 有效\n```\n\n我们可以通过使用字面量类型的联合使类型注释更加具体：\n\n<!-- skip -->\n```typescript\nconst v: { x: 1 | 2 | 3 } = {\n    x: 1, // x 现在是字面量的联合类型： 1 | 2 | 3\n};\nv.x = 3; // 有效\nv.x = 100; // 无效的\n```\n\n### 类型缩小\n\n类型缩小是 TypeScript 中的一个过程，其中一般类型缩小为更具体的类型。当 TypeScript 分析代码并确定某些条件或操作可以细化类型信息时，就会发生这种情况。\n\n缩小类型可以通过不同的方式发生，包括：\n\n#### 条件\n\n通过使用条件语句（比如 `if` 或 `switch`），TypeScript 可以根据条件的结果缩小类型范围。例如：\n\n```typescript\nlet x: number | undefined = 10;\n\nif (x !== undefined) {\n    x += 100; // 由于条件判断，类型被缩小为 number\n}\n```\n\n#### 抛错或者返回\n\n抛出错误或从分支提前返回可用于帮助 TypeScript 缩小类型范围。例如：\n\n```typescript\nlet x: number | undefined = 10;\n\nif (x === undefined) {\n    throw 'error';\n}\nx += 100;\n```\n\n在 TypeScript 中缩小类型范围的其他方法包括：\n\n* `instanceof` 操作: 用于检查对象是否是特定类的实例。\n* `in` 操作: 用于检查对象中是否存在属性。\n* `typeof` 操作: 用于在运行时检查值的类型。\n* 内部函数，比如: `Array.isArray()`: 用于检查值是否为数组。\n\n#### 可区分联合\n\n使用\"可区分联合\"是 TypeScript 中的一种模式，其中向对象添加显式\"标签\"以区分联合内的不同类型。该模式也称为\"标记联合\"。在以下示例中，\"tag\"由属性\"type\"表示：\n\n```typescript\ntype A = { type: 'type_a'; value: number };\ntype B = { type: 'type_b'; value: string };\n\nconst x = (input: A | B): string | number => {\n    switch (input.type) {\n        case 'type_a':\n            return input.value + 100; // 类型为 A\n        case 'type_b':\n            return input.value + 'extra'; // 类型为 B\n    }\n};\n```\n\n#### 用户定义的类型保护\n\n在 TypeScript 无法确定类型的情况下，可以编写一个称为\"用户定义类型保护\"的辅助函数。在下面的示例中，我们将在应用某些过滤后利用类型谓词来缩小类型范围：\n\n```typescript\nconst data = ['a', null, 'c', 'd', null, 'f'];\n\nconst r1 = data.filter(x => x != null); // 类型为 (string | null)[], TypeScript 不能准确推断类型\n\nconst isValid = (item: string | null): item is string => item !== null; // 自定义类型保护\n\nconst r2 = data.filter(isValid); // 类型现在为 string[], 通过使用断言类型保护，我们能够缩小类型\n```\n\n## 原始类型\n\nTypeScript 支持 7 种基本类型。原始数据类型是指不是对象并且没有任何与其关联的方法的类型。在 TypeScript 中，所有原始类型都是不可变的，这意味着它们的值一旦分配就无法更改。\n\n### string\n\n原始 `string` 类型存储文本数据，并且值始终是双引号或单引号的。\n\n```typescript\nconst x: string = 'x';\nconst y: string = 'y';\n```\n\n如果字符串被反引号 (`) 字符包围，则字符串可以跨越多行：\n\n```typescript\nlet sentence: string = `xxx,\n   yyy`;\n```\n\n### boolean\n\nTypeScript 中的数据 `boolean` 类型存储二进制值，或者true或false。\n\n```typescript\nconst isReady: boolean = true;\n```\n\n### number\n\nTypeScript 中的数据类型 `number` 用 64 位浮点值表示。类型 `number` 可以表示整数和分数。TypeScript 还支持十六进制、二进制和八进制，例如：\n\n```typescript\nconst decimal: number = 10;\nconst hexadecimal: number = 0xa00d; // 十六进制数以 0x 开始\nconst binary: number = 0b1010; // 二进制数以 0b 开始\nconst octal: number = 0o633; // 八进制数以 0o 开始\n```\n\n### bigInt\n\n`bigInt` 表示无法用 `number` 表示的非常大的数值 (253 – 1)。\n\n`bigInt` 可以通过调用内置函数 `BigInt()` 或添加 `n` 到任何整数数字字面量的末尾来创建：\n\n```typescript\nconst x: bigint = BigInt(9007199254740991);\nconst y: bigint = 9007199254740991n;\n```\n\n笔记：\n\n* `bigInt` 值不能与 `number` 混合，也不能与内置的 `Math` 一起使用，它们必须强制为相同的类型。\n* 仅当目标配置为 ES2020 或更高版本时，“bigInt”值才可用。\n\n### symbol\n\nJavaScript 有一个原始函数 Symbol()，它创建一个全局唯一的引用。\n\n```typescript\nlet sym = Symbol('x'); // symbol 类型\n```\n\n### null and undefined\n\n`null`和 `undefined` 类型都表示没有值或不存在任何值。\n\n`undefined` 类型意味着该值未分配或初始化，或者指示无意中缺少值。\n\n`null` 类型意味着我们知道该字段没有值，因此值不可用，这表明故意不存在值。\n\n### Array\n\n`array` 是一种可以存储多个相同类型或不同类型的值的数据类型。可以使用以下语法定义它：\n\n```typescript\nconst x: string[] = ['a', 'b'];\nconst y: Array<string> = ['a', 'b'];\nconst j: Array<string | number> = ['a', 1, 'b', 2];\n```\n\nTypeScript 使用以下语法支持只读数组：\n\n<!-- skip -->\n```typescript\nconst x: readonly string[] = ['a', 'b']; // 只读修饰符\nconst y: ReadonlyArray<string> = ['a', 'b'];\nconst j: ReadonlyArray<string | number> = ['a', 1, 'b', 2];\nj.push('x'); // 有效\n```\n\nTypeScript 支持数组和只读数组：\n\n```typescript\nconst x: [string, number] = ['a', 1];\nconst y: readonly [string, number] = ['a', 1];\n```\n\n### any\n\n数据 `any` 类型字面上代表\"任何\"值，当 TypeScript 无法推断类型或未指定时，它是默认值。\n\n使用 `any` 时，TypeScript编译器会跳过类型检查，因此 `any` 使用时不存在类型安全。通常，当发生错误时不要使用 `any` 静默编译器，而是专注于修复错误，因为使用 `any` 它可能会破坏契约，并且我们会失去 TypeScript 自动完成的好处。\n\n在从 JavaScript 逐步迁移到 TypeScript 的过程中，该 `any` 类型可能很有用，因为它可以让编译器保持沉默。\n\n对于新项目，请使用 TypeScript 配置 `noImplicitAny` ，该配置使 TypeScript 能够在any使用或推断时发出错误。\n\n`any` 通常是错误的来源，它可以掩盖类型的实际问题。尽可能避免使用它。\n\n## 类型注释\n\n在使用 `var` 、 `let` 和 `const` 声明变量时，可以选择添加类型：\n\n```typescript\nconst x: number = 1;\n```\n\nTypeScript 在推断类型方面做得很好，尤其是简单类型时，因此在大多数情况下这些声明是不必要的。\n\n在函数上可以向参数添加类型注释：\n\n```typescript\nfunction sum(a: number, b: number) {\n    return a + b;\n}\n```\n\n以下是使用匿名函数（所谓的 lambda 函数）的示例：\n\n```typescript\nconst sum = (a: number, b: number) => a + b;\n```\n\n当参数存在默认值时可以避免这些注释：\n\n```typescript\nconst sum = (a = 10, b: number) => a + b;\n```\n\n可以将返回类型注释添加到函数中：\n\n```typescript\nconst sum = (a = 10, b: number): number => a + b;\n```\n\n这对于更复杂的函数尤其有用，因为在实现之前编写显式返回类型可以帮助更好地思考该函数。\n\n通常考虑注释类型签名，但不注释主体局部变量，并始终将类型添加到对象字面量中。\n\n## 可选属性\n\n对象可以通过在属性名称末尾添加问号 `?` 来指定可选属性：\n\n```typescript\ntype X = {\n    a: number;\n    b?: number; // 可选的\n};\n```\n\n当属性是可选的时，可以指定默认值\n\n```typescript\ntype X = {\n    a: number;\n    b?: number;\n};\nconst x = ({ a, b = 100 }: X) => a + b;\n```\n\n## 只读属性\n\n是否可以通过使用修饰符来防止对属性进行写入，`readonly` 以确保该属性不能被重写，但不提供任何完全不变性的保证：\n\n```typescript\ninterface Y {\n    readonly a: number;\n}\n\ntype X = {\n    readonly a: number;\n};\n\ntype J = Readonly<{\n    a: number;\n}>;\n\ntype K = {\n    readonly [index: number]: string;\n};\n```\n\n## 索引签名\n\n在 TypeScript 中，我们可以使用 `string` 、`number` 和 `symbol` 作为索引签名：\n\n```typescript\ntype K = {\n    [name: string | number]: string;\n};\nconst k: K = { x: 'x', 1: 'b' };\nconsole.log(k['x']);\nconsole.log(k[1]);\nconsole.log(k['1']); // 同 k[1] 的结果相同\n```\n\n请注意，JavaScript 会自动将 `number` 的索引转换相同值的 'string'索引, 比如 `k[1]` 和 `k[\"1\"]` 返回相同值。\n\n## 扩展类型\n\n可以扩展 `interface`（从另一种类型复制成员）：\n\n```typescript\ninterface X {\n    a: string;\n}\ninterface Y extends X {\n    b: string;\n}\n```\n\n还可以从多种 `interface` 进行扩展：\n\n```typescript\ninterface A {\n    a: string;\n}\ninterface B {\n    b: string;\n}\ninterface Y extends A, B {\n    y: string;\n}\n```\n\n该 `extends` 关键字仅适用于 `interface`，因为 `type` 使用交集：\n\n```typescript\ntype A = {\n    a: number;\n};\ntype B = {\n    b: number;\n};\ntype C = A & B;\n```\n\n可以使用 `interface` 来扩展类 `type`，但反之则不然：\n\n```typescript\ntype A = {\n    a: string;\n};\ninterface B extends A {\n    b: string;\n}\n```\n\n## 字面量类型\n\n文字类型是来自集体类型的单个元素集，它定义了一个非常精确的值，即 JavaScript 原始数据。\n\nTypeScript 中的文字类型是数字、字符串和布尔值。\n\n示例如下:\n\n```typescript\nconst a = 'a'; // 字符串字面量类型\nconst b = 1; // 数字字面量类型\nconst c = true; // 布尔字面量类型\n```\n\n在以下示例中，您可以看到联合类型别名。`O` 仅包含指定的值，其他字符串均无效：\n\n```typescript\ntype O = 'a' | 'b' | 'c';\n```\n\n## 字面量推断\n\n字面量推断是 TypeScript 中的一项功能，允许根据变量或参数的值推断其类型。\n\n在下面的示例中，我们可以看到 TypeScript 认为x文字类型是因为该值以后不能随时更改，而y被推断为字符串，因为它以后可以随时修改。\n\n```typescript\nconst x = 'x'; // x 为字面量类型, 因为值不能改变\nlet y = 'y'; // string, 我们能改变这个值\n```\n\n在下面的示例中，我们可以看到 `o.x` 被推断为 `string`（而不是字面量的a），因为 TypeScript 认为该值可以在以后随时更改。\n\n<!-- skip -->\n```typescript\ntype X = 'a' | 'b';\n\nlet o = {\n    x: 'a', // 这是一个更宽的 string\n};\n\nconst fn = (x: X) => `${x}-foo`;\n\nconsole.log(fn(o.x)); // 'string' 类型的参数不能赋值给 'X' 类型的参数\n```\n\n正如你所看到的代码在传递 `o.x` 给 `fn` 作为一个狭窄类型时，抛出了一个错误。\n\n我们能通过使用 `const` 或者 `X` 来借助类型推断解决这个问题：\n\n<!-- skip -->\n```typescript\nlet o = {\n    x: 'a' as const,\n};\n```\n\nor:\n\n<!-- skip -->\n```typescript\nlet o = {\n    x: 'a' as X,\n};\n```\n\n## 严格空检查\n\n`strictNullChecks` 是一个 TypeScript 编译器选项，强制执行严格的 null 检查。启用此选项后，只有在变量和参数已使用联合类型 `null` | `undefined` 显式声明为该类型时，才可以对其进行赋值`null` 或者 `undefined`。如果变量或参数未显式声明为可为空，TypeScript 将生成错误以防止潜在的运行时错误。\n\n## 枚举\n\n在 TypeScript 中，枚举是一组命名常量值。\n\n```typescript\nenum Color {\n    Red = '#ff0000',\n    Green = '#00ff00',\n    Blue = '#0000ff',\n}\n```\n\n枚举可以用不同的方式定义：\n\n### 数字枚举\n\n在 TypeScript 中，数字枚举是一个枚举，其中每个常量都分配有一个数值，默认从 0 开始。\n\n```typescript\nenum Size {\n    Small, // 值从 0 开始\n    Medium,\n    Large,\n}\n```\n\n可以通过显式分配来指定自定义值：\n\n```typescript\nenum Size {\n    Small = 10,\n    Medium,\n    Large,\n}\nconsole.log(Size.Medium); // 11\n```\n\n### 字符串枚举\n\n在 TypeScript 中，字符串枚举是每个常量都分配有一个字符串值的枚举。\n\n```typescript\nenum Language {\n    English = 'EN',\n    Spanish = 'ES',\n}\n```\n\n注意：TypeScript 允许使用异构枚举，其中字符串和数字成员可以共存。\n\n### 常量枚举\n\nTypeScript 中的常量枚举是一种特殊类型的枚举，其中所有值在编译时都是已知的，并且在使用枚举的任何地方都会内联，从而产生更高效的代码。\n\n```typescript\nconst enum Language {\n    English = 'EN',\n    Spanish = 'ES',\n}\nconsole.log(Language.English);\n```\n\n将被编译成：\n\n```typescript\nconsole.log('EN' /* Language.English */);\n```\n\n注意：常量枚举具有硬编码值，擦除枚举，这在独立库中可能更有效，但通常是不可取的。此外，常量枚举不能有计算成员。\n\n### 反向映射\n\n在 TypeScript 中，枚举中的反向映射是指从值中检索枚举成员名称的能力。默认情况下，枚举成员具有从名称到值的正向映射，但可以通过为每个成员显式设置值来创建反向映射。当您需要按枚举成员的值查找枚举成员，或者需要迭代所有枚举成员时，反向映射非常有用。需要注意的是，只有数字类型的枚举成员会生成反向映射，字符串类型的枚举成员则不会。\n\n以下枚举：\n\n```typescript\nenum Grade {\n    A = 90,\n    B = 80,\n    C = 70,\n    F = 'fail',\n}\n```\n\n编译为：\n\n<!-- skip -->\n```javascript\n'use strict';\nvar Grade;\n(function (Grade) {\n    Grade[(Grade['A'] = 90)] = 'A';\n    Grade[(Grade['B'] = 80)] = 'B';\n    Grade[(Grade['C'] = 70)] = 'C';\n    Grade['F'] = 'fail';\n})(Grade || (Grade = {}));\n```\n\n由此可见，对数字类型的枚举成员，可以从枚举值映射回枚举名称，但对字符串类型的枚举成员无法这样做。\n\n<!-- skip -->\n```typescript\nenum Grade {\n    A = 90,\n    B = 80,\n    C = 70,\n    F = 'fail',\n}\nconst myGrade = Grade.A;\nconsole.log(Grade[myGrade]); // A\nconsole.log(Grade[90]); // A\n\nconst failGrade = Grade.F;\nconsole.log(failGrade); // fail\nconsole.log(Grade[failGrade]); // 因为索引表达式的类型不是 'number'，所以元素是隐式的 'any' 类型。\n```\n\n### 环境枚举\n\nTypeScript 中的环境枚举是一种在声明文件 (*.d.ts) 中定义的枚举类型，没有关联的实现。它允许您定义一组命名常量，这些常量可以在不同文件中以类型安全的方式使用，而无需在每个文件中导入实现细节。\n\n### 计算成员和常量成员\n\n在 TypeScript 中，计算成员是枚举的成员，其值在运行时计算，而常量成员是其值在编译时设置且在运行时无法更改的成员。常规枚举中允许使用计算成员，而常规枚举和常量枚举中都允许使用常量成员。\n\n```typescript\n// 常量成员\nenum Color {\n    Red = 1,\n    Green = 5,\n    Blue = Red + Green,\n}\nconsole.log(Color.Blue); // 6 编译时生成\n```\n\n```typescript\n// 计算成员\nenum Color {\n    Red = 1,\n    Green = Math.pow(2, 2),\n    Blue = Math.floor(Math.random() * 3) + 1,\n}\nconsole.log(Color.Blue); // 运行时生成的随机数\n```\n\n枚举由包含其成员类型的联合表示。每个成员的值可以通过常量或非常量表达式确定，拥有常量值的成员被分配字面量类型。为了说明这一点，请考虑类型 E 及其子类型 E.A、E.B 和 E.C 的声明。在本例中，E 表​​示联合 E.A | E.B | E.C 。\n\n```typescript\nconst identity = (value: number) => value;\n\nenum E {\n    A = 2 * 5, // 数字字面量\n    B = 'bar', // 字符串字面量\n    C = identity(42), // 不透明计算\n}\n\nconsole.log(E.C); //42\n```\n\n## 缩小范围\n\nTypeScript 缩小范围是细化条件块内变量类型的过程。这在使用联合类型时很有用，其中一个变量可以有多个类型。\n\nTypeScript 可识别多种缩小类型范围的方法：\n\n### typeof 类型保护\n\ntypeof 类型保护是 TypeScript 中的一种特定类型保护，它根据变量的内置 JavaScript 类型检查变量的类型。\n\n```typescript\nconst fn = (x: number | string) => {\n    if (typeof x === 'number') {\n        return x + 1; // x 是数字\n    }\n    return -1;\n};\n```\n\n### 真实性缩小\n\nTypeScript 中的真实性缩小是通过检查变量是真还是假来相应地缩小其类型来实现的。\n\n```typescript\nconst toUpperCase = (name: string | null) => {\n    if (name) {\n        return name.toUpperCase();\n    } else {\n        return null;\n    }\n};\n```\n\n### 相等缩小\n\nTypeScript 中的相等缩小通过检查变量是否等于特定值来相应缩小其类型。\n\n它与`switch`语句和等号运算符（例如`===`、`!==`、`==`和`!=`）结合使用来缩小类型范围。\n\n```typescript\nconst checkStatus = (status: 'success' | 'error') => {\n    switch (status) {\n        case 'success':\n            return true;\n        case 'error':\n            return null;\n    }\n};\n```\n\n### In运算符缩小\n\nTypeScript 中的 `in` 运算符缩小范围是一种根据变量类型中是否存在属性来缩小变量类型的方法。\n\n```typescript\ntype Dog = {\n    name: string;\n    breed: string;\n};\n\ntype Cat = {\n    name: string;\n    likesCream: boolean;\n};\n\nconst getAnimalType = (pet: Dog | Cat) => {\n    if ('breed' in pet) {\n        return 'dog';\n    } else {\n        return 'cat';\n    }\n};\n```\n\n### instanceof 缩小\n\nTypeScript 中的 `instanceof` 运算符缩小是一种根据变量的构造函数缩小变量类型的方法，方法是检查对象是否是某个类或接口的实例。\n\n```typescript\nclass Square {\n    constructor(public width: number) {}\n}\nclass Rectangle {\n    constructor(\n        public width: number,\n        public height: number\n    ) {}\n}\nfunction area(shape: Square | Rectangle) {\n    if (shape instanceof Square) {\n        return shape.width * shape.width;\n    } else {\n        return shape.width * shape.height;\n    }\n}\nconst square = new Square(5);\nconst rectangle = new Rectangle(5, 10);\nconsole.log(area(square)); // 25\nconsole.log(area(rectangle)); // 50\n```\n\n## 赋值\n\n使用赋值缩小 TypeScript 是一种根据分配给变量的值来缩小变量类型的方法。当为变量分配值时，TypeScript 会根据分配的值推断其类型，并缩小变量的类型以匹配推断的类型。\n\n```typescript\nlet value: string | number;\nvalue = 'hello';\nif (typeof value === 'string') {\n    console.log(value.toUpperCase());\n}\nvalue = 42;\nif (typeof value === 'number') {\n    console.log(value.toFixed(2));\n}\n```\n\n## 控制流分析\n\nTypeScript 中的控制流分析是一种静态分析代码流以推断变量类型的方法，允许编译器根据分析结果根据需要缩小这些变量的类型。\n\n在 TypeScript 4.4 之前，代码流分析仅适用于 if 语句中的代码，但从 TypeScript 4.4 开始，它还可以应用于条件表达式和通过 const 变量间接引用的判别式属性访问。\n\n例如：\n\n```typescript\nconst f1 = (x: unknown) => {\n    const isString = typeof x === 'string';\n    if (isString) {\n        x.length;\n    }\n};\n\nconst f2 = (\n    obj: { kind: 'foo'; foo: string } | { kind: 'bar'; bar: number }\n) => {\n    const isFoo = obj.kind === 'foo';\n    if (isFoo) {\n        obj.foo;\n    } else {\n        obj.bar;\n    }\n};\n```\n\n一些未发生缩小的示例：\n\n<!-- skip -->\n```typescript\nconst f1 = (x: unknown) => {\n    let isString = typeof x === 'string';\n    if (isString) {\n        x.length; // 错误, 没有缩小，因为 isString 不是常量\n    }\n};\n\nconst f6 = (\n    obj: { kind: 'foo'; foo: string } | { kind: 'bar'; bar: number }\n) => {\n    const isFoo = obj.kind === 'foo';\n    obj = obj;\n    if (isFoo) {\n        obj.foo; // 错误, 没有缩小，因为 obj 在函数体中被赋值\n    }\n};\n```\n\n注意： 在条件表达式中最多分析五个间接级别。\n\n## 类型谓词\n\nTypeScript 中的类型谓词是返回布尔值的函数，用于将变量的类型缩小为更具体的类型。\n\n```typescript\nconst isString = (value: unknown): value is string => typeof value === 'string';\n\nconst foo = (bar: unknown) => {\n    if (isString(bar)) {\n        console.log(bar.toUpperCase());\n    } else {\n        console.log('not a string');\n    }\n};\n```\n\n## 可区分联合\n\nTypeScript 中的可区分联合是一种联合类型，它使用称为判别式的公共属性来缩小联合的可能类型集。\n\n```typescript\ntype Square = {\n    kind: 'square'; // 判别式\n    size: number;\n};\n\ntype Circle = {\n    kind: 'circle'; // 判别式\n    radius: number;\n};\n\ntype Shape = Square | Circle;\n\nconst area = (shape: Shape) => {\n    switch (shape.kind) {\n        case 'square':\n            return Math.pow(shape.size, 2);\n        case 'circle':\n            return Math.PI * Math.pow(shape.radius, 2);\n    }\n};\n\nconst square: Square = { kind: 'square', size: 5 };\nconst circle: Circle = { kind: 'circle', radius: 2 };\n\nconsole.log(area(square)); // 25\nconsole.log(area(circle)); // 12.566370614359172\n```\n\n## never 类型\n\n当变量缩小为不能包含任何值的类型时，TypeScript 编译器将推断该变量必须属于该never类型。这是因为 never 类型代表永远无法生成的值。\n\n```typescript\nconst printValue = (val: string | number) => {\n    if (typeof val === 'string') {\n        console.log(val.toUpperCase());\n    } else if (typeof val === 'number') {\n        console.log(val.toFixed(2));\n    } else {\n        // val 在这里的类型为 never，因为它只能是字符串或数字\n        const neverVal: never = val;\n        console.log(`Unexpected value: ${neverVal}`);\n    }\n};\n```\n\n## 详尽性检查\n\n详尽性检查是 TypeScript 中的一项功能，可确保在 `switch` 语句或 `if` 语句中处理可区分联合的所有可能情况。\n\n```typescript\ntype Direction = 'up' | 'down';\n\nconst move = (direction: Direction) => {\n    switch (direction) {\n        case 'up':\n            console.log('Moving up');\n            break;\n        case 'down':\n            console.log('Moving down');\n            break;\n        default:\n            const exhaustiveCheck: never = direction;\n            console.log(exhaustiveCheck); // 这行永远不会被执行\n    }\n};\n```\n\n该 `never` 类型用于确保默认情况是详尽的，并且如果将新值添加到 Direction 类型而未在 switch 语句中进行处理，则 TypeScript 将引发错误。\n\n## 对象类型\n\n在 TypeScript 中，对象类型描述对象的形状。它们指定对象属性的名称和类型，以及这些属性是必需的还是可选的。\n\n在 TypeScript 中，您可以通过两种主要方式定义对象类型：\n\n通过指定对象属性的名称、类型和可选性来定义对象的形状的接口。\n\n```typescript\ninterface User {\n    name: string;\n    age: number;\n    email?: string;\n}\n```\n\n类型别名与接口类似，定义了对象的形状。但是，它还可以基于现有类型或现有类型的组合创建新的自定义类型。这包括定义联合类型、交集类型和其他复杂类型。\n\n```typescript\ntype Point = {\n    x: number;\n    y: number;\n};\n```\n\n也可以匿名定义类型：\n\n```typescript\nconst sum = (x: { a: number; b: number }) => x.a + x.b;\nconsole.log(sum({ a: 5, b: 1 }));\n```\n\n## 元组类型（匿名）\n\n元组类型是一种表示具有固定数量的元素及其相应类型的数组的类型。元组类型以固定顺序强制执行特定数量的元素及其各自的类型。当您想要表示具有特定类型的值的集合时，元组类型非常有用，其中数组中每个元素的位置都有特定的含义。\n\n```typescript\ntype Point = [number, number];\n```\n\n## 命名元组类型（已标记）\n\n元组类型可以包含每个元素的可选标签或名称。 这些标签用于提高可读性和工具帮助，不会影响您可以使用它们执行的操作。\n\n```typescript\ntype T = string;\ntype Tuple1 = [T, T];\ntype Tuple2 = [a: T, b: T];\ntype Tuple3 = [a: T, T]; // 命名元组加匿名元组\n```\n\n## 固定长度元组\n\n固定长度元组是一种特定类型的元组，它强制执行特定类型的固定数量的元素，并且一旦定义元组就不允许对其长度进行任何修改。\n\n当您需要表示具有特定数量的元素和特定类型的值的集合，并且您希望确保元组的长度和类型不会无意中更改时，固定长度元组非常有用。\n\n<!-- skip -->\n```typescript\nconst x = [10, 'hello'] as const;\nx.push(2); // 错误\n```\n\n## 联合类型\n\n联合类型是一种表示值的类型，该值可以是多种类型之一。联合类型使用 `|` 表示 每种可能类型之间的符号。\n\n```typescript\nlet x: string | number;\nx = 'hello'; // 有效\nx = 123; // 有效\n```\n\n## 交集类型\n\n交集类型是表示具有两种或多种类型的所有属性的值的类型。交叉类型在每种类型之间使用 & 符号表示。\n\n```typescript\ntype X = {\n    a: string;\n};\n\ntype Y = {\n    b: string;\n};\n\ntype J = X & Y; // 交集\n\nconst j: J = {\n    a: 'a',\n    b: 'b',\n};\n```\n\n## 类型索引\n\n类型索引是指能够通过预先未知的键来定义可以索引的类型，使用索引签名来指定未显式声明的属性的类型。\n\n```typescript\ntype Dictionary<T> = {\n    [key: string]: T;\n};\nconst myDict: Dictionary<string> = { a: 'a', b: 'b' };\nconsole.log(myDict['a']); // 返回 a\n```\n\n## 值的类型\n\nTypeScript 中的\"Type from Value\"是指通过类型推断从值或表达式自动推断出类型。\n\n```typescript\nconst x = 'x'; // TypeScript 可以自动推断变量的类型是 string\n```\n\n## Func 返回值的类型\n\nFunc Return 中的类型是指根据函数的实现自动推断函数的返回类型的能力。这允许 TypeScript 无需显式类型注释即可确定函数返回值的类型。\n\n```typescript\nconst add = (x: number, y: number) => x + y; // TypeScript 可以推断函数的返回类型是数字\n```\n\n## 模块的类型\n\n模块的类型是指使用模块的导出值自动推断其类型的能力。当模块导出特定类型的值时，TypeScript 可以使用该信息在将该值导入到另一个模块时自动推断该值的类型。\n\n<!-- skip -->\n```typescript\nexport const add = (x: number, y: number) => x + y;\n// index.ts\nimport { add } from 'calc';\nconst r = add(1, 2); // r 是 number 类型\n```\n\n## 映射类型\n\nTypeScript 中的映射类型允许您通过使用映射函数转换每个属性来基于现有类型创建新类型。通过映射现有类型，您可以创建以不同格式表示相同信息的新类型。要创建映射类型，您可以使用运算符访问现有类型的属性 `keyof` ，然后更改它们以生成新类型。在以下示例中：\n\n```typescript\ntype MyMappedType<T> = {\n    [P in keyof T]: T[P][];\n};\ntype MyType = {\n    foo: string;\n    bar: number;\n};\ntype MyNewType = MyMappedType<MyType>;\nconst x: MyNewType = {\n    foo: ['hello', 'world'],\n    bar: [1, 2, 3],\n};\n```\n\n我们定义 MyMappedType 来映射 T 的属性，创建一个新类型，其中每个属性都是其原始类型的数组。使用它，我们创建 MyNewType 来表示与 MyType 相同的信息，但每个属性都是一个数组。\n\n## 映射类型修饰符\n\nTypeScript 中的映射类型修饰符支持对现有类型中的属性进行转换：\n\n* `readonly` 或 `+readonly`：这会将映射类型中的属性呈现为只读。\n* `-readonly`：这允许映射类型中的属性是可变的。\n* `?`：这将映射类型中的属性指定为可选。\n\n例子：\n\n```typescript\ntype ReadOnly<T> = { readonly [P in keyof T]: T[P] }; // 所有属性标记为只读\n\ntype Mutable<T> = { -readonly [P in keyof T]: T[P] }; // 所有标记为可变的属性\n\ntype MyPartial<T> = { [P in keyof T]?: T[P] }; // 所有标记为可选的属性\n````\n\n## 条件类型\n\n条件类型是一种创建依赖于条件的类型的方法，其中要创建的类型是根据条件的结果确定的。它们是使用 `extends` 关键字和三元运算符来定义的，以便有条件地在两种类型之间进行选择。\n\n```typescript\ntype IsArray<T> = T extends any[] ? true : false;\n\nconst myArray = [1, 2, 3];\nconst myNumber = 42;\n\ntype IsMyArrayAnArray = IsArray<typeof myArray>; // true 类型\ntype IsMyNumberAnArray = IsArray<typeof myNumber>; // false 类型\n```\n\n## 分配条件类型\n\n分布式条件类型是一种功能，通过单独对联合的每个成员应用转换，允许类型分布在类型的联合上。当使用映射类型或高阶类型时，这尤其有用。\n\n```typescript\ntype Nullable<T> = T extends any ? T | null : never;\ntype NumberOrBool = number | boolean;\ntype NullableNumberOrBool = Nullable<NumberOrBool>; // number | boolean | null\n```\n\n## infer 条件类型中的类型推断\n\n`infer` 关键字在条件类型中使用，用于从依赖于泛型参数的类型中推断（提取）泛型参数的类型。这允许您编写更灵活且可重用的类型定义。\n\n```typescript\ntype ElementType<T> = T extends (infer U)[] ? U : never;\ntype Numbers = ElementType<number[]>; // number\ntype Strings = ElementType<string[]>; // string\n```\n\n## 预定义条件类型\n\n在 TypeScript 中，预定义的条件类型是语言提供的内置条件类型。它们旨在根据给定类型的特征执行常见的类型转换。\n\n`Exclude<UnionType, ExcludedType>`: 此类型从 Type 中删除可分配给 ExcludedType 的所有类型。\n\n`Extract<Type, Union>`: 此类型从 Union 中提取可分配给 Type 的所有类型。\n\n`NonNullable<Type>`: 此类型从 Type 中删除 null 和 undefined。\n\n`ReturnType<Type>`: 此类型提取函数 Type 的返回类型。\n\n`Parameters<Type>`: 该类型提取函数类型的参数类型。\n\n`Required<Type>`: 此类型使 Type 中的所有属性成为必需。\n\n`Partial<Type>`: 此类型使 Type 中的所有属性都是可选的。\n\n`Readonly<Type>`: 此类型使 Type 中的所有属性变为只读。\n\n## 模板联合类型\n\n模板联合类型可用于合并和操作类型系统内的文本，例如：\n\n```typescript\ntype Status = 'active' | 'inactive';\ntype Products = 'p1' | 'p2';\ntype ProductId = `id-${Products}-${Status}`; // \"id-p1-active\" | \"id-p1-inactive\" | \"id-p2-active\" | \"id-p2-inactive\"\n```\n\n## 任意类型\n\n`any` 类型是一种特殊类型（通用超类型），可用于表示任何类型的值（基元、对象、数组、函数、错误、符号）。它通常用于编译时未知值类型的情况，或者使用来自没有 TypeScript 类型的外部 API 或库的值时。\n\n使用 `any` 类型，就等于告诉 TypeScript 编译器，值应该不受任何限制地表示。为了最大限度地提高代码的类型安全性，请考虑以下几点：\n\n* 将 `any` 的使用限制在类型确实未知的特定情况下。\n* 不要从函数返回 `any` 类型，因为这会削弱使用该函数的代码的类型安全性。\n* 如果您需要使编译器保持沉默，请使用 `@ts-ignore` 而不是 `any`。\n\n```typescript\nlet value: any;\nvalue = true; // 有效\nvalue = 7; // 有效\n```\n\n## 未知类型\n\n在 TypeScript 中，未知类型表示未知类型的值。与允许任何类型值的 `any` 类型不同，`unknown` 需要在以特定方式使用它之前进行类型检查或断言，因此在未首先断言或缩小到更具体的类型的情况下，不允许对 `unknown` 进行任何操作 。\n\n`unknown` 类型只能分配给任何类型和未知类型本身，它是any 的类型安全替代方案。\n\n<!-- skip -->\n```typescript\nlet value: unknown;\n\nlet value1: unknown = value; // 有效\nlet value2: any = value; // 有效\nlet value3: boolean = value; // 无效\nlet value4: number = value; // 无效\n```\n\n```typescript\nconst add = (a: unknown, b: unknown): number | undefined =>\n    typeof a === 'number' && typeof b === 'number' ? a + b : undefined;\nconsole.log(add(1, 2)); // 3\nconsole.log(add('x', 2)); // undefined\n```\n\n## 空类型\n\n`void` 类型用于指示函数不返回值。\n\n```typescript\nconst sayHello = (): void => {\n    console.log('Hello!');\n};\n```\n\n## Never类型\n\n`never` 类型表示从未出现过的值。它用于表示从不返回或抛出错误的函数或表达式。\n\n例如无限循环：\n\n```typescript\nconst infiniteLoop = (): never => {\n    while (true) {\n        // 做点什么\n    }\n};\n```\n\n抛出错误：\n\n```typescript\nconst throwError = (message: string): never => {\n    throw new Error(message);\n};\n```\n\n`never` 类型对于确保类型安全和捕获代码中的潜在错误很有用。当与其他类型和控制流语句结合使用时，它可以帮助 TypeScript 分析和推断更精确的类型，例如：\n\n```typescript\ntype Direction = 'up' | 'down';\nconst move = (direction: Direction): void => {\n    switch (direction) {\n        case 'up':\n            // 向上移动\n            break;\n        case 'down':\n            // 向下移动\n            break;\n        default:\n            const exhaustiveCheck: never = direction;\n            throw new Error(`Unhandled direction: ${exhaustiveCheck}`);\n    }\n};\n```\n\n## 接口及类型\n\n### 通用语法\n\n在 TypeScript 中，接口定义对象的结构，指定对象必须具有的属性或方法的名称和类型。在 TypeScript 中定义接口的常用语法如下：\n\n<!-- skip -->\n```typescript\ninterface InterfaceName {\n    property1: Type1;\n    // ...\n    method1(arg1: ArgType1, arg2: ArgType2): ReturnType;\n    // ...\n}\n```\n\n类型定义也类似：\n\n<!-- skip -->\n```typescript\ntype TypeName = {\n    property1: Type1;\n    // ...\n    method1(arg1: ArgType1, arg2: ArgType2): ReturnType;\n    // ...\n};\n```\n\n`interface InterfaceName` 或者 `type TypeName`: 定义接口的名称。\n`property1`: `Type1`: 指定接口的属性及其相应的类型。可以定义多个属性，每个属性用分号分隔。\n`method1(arg1: ArgType1, arg2: ArgType2): ReturnType;`: 指定接口的方法。方法用其名称进行定义，后跟括号中的参数列表和返回类型。可以定义多个方法，每个方法用分号分隔。\n\n接口示例:\n\n```typescript\ninterface Person {\n    name: string;\n    age: number;\n    greet(): void;\n}\n```\n\n类型示例:\n\n```typescript\ntype TypeName = {\n    property1: string;\n    method1(arg1: string, arg2: string): string;\n};\n```\n\n在 TypeScript 中，类型用于定义数据的形状并强制执行类型检查。在 TypeScript 中定义类型有几种常见的语法，具体取决于具体的用例。这里有些例子：\n\n### 基本类型\n\n```typescript\nlet myNumber: number = 123; // 数字类型\nlet myBoolean: boolean = true; // 布尔类型\nlet myArray: string[] = ['a', 'b']; // 字符串数组\nlet myTuple: [string, number] = ['a', 123]; // 元组\n```\n\n### 对象和接口\n\n```typescript\nconst x: { name: string; age: number } = { name: 'Simon', age: 7 };\n```\n\n### 并集和交集类型\n\n```typescript\ntype MyType = string | number; // 并集\nlet myUnion: MyType = 'hello'; // 可以是字符串\nmyUnion = 123; // 或者是一个数字\n\ntype TypeA = { name: string };\ntype TypeB = { age: number };\ntype CombinedType = TypeA & TypeB; // 交集\nlet myCombined: CombinedType = { name: 'John', age: 25 }; // 对象同时有name和age属性\n```\n\n## 内置原始数据类型\n\nTypeScript 有几个内置的原属数据类型，可用于定义变量、函数参数和返回类型：\n\n`number`: 表示数值，包括整数和浮点数。\n`string`: 代表文本数据。\n`boolean`: 代表逻辑值，可以是 true 或 false。\n`null`:  表示没有值。\n`undefined`: 表示尚未赋值或未定义的值。\n`symbol`: 代表唯一标识符。符号通常用作对象属性的键。\n`bigint`: 表示任意精度整数。\n`any`: 代表动态或未知类型。any 类型的变量可以保存任何类型的值，并且它们绕过类型检查。\n`void`: 表示不存在任何类型。它通常用作不返回值的函数的返回类型。\n`never`: 表示从未出现过的值的类型。它通常用作引发错误或进入无限循环的函数的返回类型。\n\n## 常见的内置JS对象\n\nTypeScript 是 JavaScript 的超集，它包含所有常用的内置 JavaScript 对象。您可以在 Mozilla 开发者网络 (MDN) 文档网站上找到这些对象的详细列表：\n[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects)\n\n以下是一些常用的内置 JavaScript 对象的列表：\n\n* Function\n* Object\n* Boolean\n* Error\n* Number\n* BigInt\n* Math\n* Date\n* String\n* RegExp\n* Array\n* Map\n* Set\n* Promise\n* Intl\n\n## 重载\n\nTypeScript 中的函数重载允许您为单个函数名称定义多个函数签名，从而使您能够定义可以多种方式调用的函数。这是一个例子：\n\n```typescript\n// 重载\nfunction sayHi(name: string): string;\nfunction sayHi(names: string[]): string[];\n\n// 实现\nfunction sayHi(name: unknown): unknown {\n    if (typeof name === 'string') {\n        return `Hi, ${name}!`;\n    } else if (Array.isArray(name)) {\n        return name.map(name => `Hi, ${name}!`);\n    }\n    throw new Error('Invalid value');\n}\n\nsayHi('xx'); // 有效\nsayHi(['aa', 'bb']); // 有效\n```\n\n这是在 `class` 中使用函数重载的另一个示例：\n\n```typescript\nclass Greeter {\n    message: string;\n\n    constructor(message: string) {\n        this.message = message;\n    }\n\n    // 重载\n    sayHi(name: string): string;\n    sayHi(names: string[]): ReadonlyArray<string>;\n\n    // 实现\n    sayHi(name: unknown): unknown {\n        if (typeof name === 'string') {\n            return `${this.message}, ${name}!`;\n        } else if (Array.isArray(name)) {\n            return name.map(name => `${this.message}, ${name}!`);\n        }\n        throw new Error('value is invalid');\n    }\n}\nconsole.log(new Greeter('Hello').sayHi('Simon'));\n```\n\n## 合并与扩展\n\n合并和扩展是指与使用类型和接口相关的两个不同概念。\n\n合并允许您将多个同名声明合并到一个定义中，例如，当您多次定义同名接口时：\n\n```typescript\ninterface X {\n    a: string;\n}\n\ninterface X {\n    b: number;\n}\n\nconst person: X = {\n    a: 'a',\n    b: 7,\n};\n```\n\n扩展是指扩展或继承现有类型或接口以创建新类型或接口的能力。它是一种向现有类型添加附加属性或方法而不修改其原始定义的机制。例子：\n\n```typescript\ninterface Animal {\n    name: string;\n    eat(): void;\n}\n\ninterface Bird extends Animal {\n    sing(): void;\n}\n\nconst dog: Bird = {\n    name: 'Bird 1',\n    eat() {\n        console.log('Eating');\n    },\n    sing() {\n        console.log('Singing');\n    },\n};\n```\n\n## 类型和接口之间的差异\n\n声明合并（增强）：\n\n接口支持声明合并，这意味着您可以定义多个具有相同名称的接口，TypeScript 会将它们合并为具有组合属性和方法的单个接口。 另一方面，类型不支持声明合并。 当您想要添加额外的功能或自定义现有类型而不修改原始定义或修补丢失或不正确的类型时，这可能会很有帮助。\n\n```typescript\ninterface A {\n    x: string;\n}\ninterface A {\n    y: string;\n}\nconst j: A = {\n    x: 'xx',\n    y: 'yy',\n};\n```\n\n扩展其他类型/接口：\n\n类型和接口都可以扩展其他类型/接口，但语法不同。 对于接口，您可以使用“extends”关键字从其他接口继承属性和方法。 但是，接口无法扩展像联合类型这样的复杂类型。\n\n```typescript\ninterface A {\n    x: string;\n    y: number;\n}\ninterface B extends A {\n    z: string;\n}\nconst car: B = {\n    x: 'x',\n    y: 123,\n    z: 'z',\n};\n```\n\n对于类型，您可以使用 & 运算符将多个类型合并为单个类型（交集）。\n\n```typescript\ninterface A {\n    x: string;\n    y: number;\n}\n\ntype B = A & {\n    j: string;\n};\n\nconst c: B = {\n    x: 'x',\n    y: 123,\n    j: 'j',\n};\n```\n\n并集和交集类型：\n\n在定义并集和交集类型时，类型更加灵活。 通过“type”关键字，您可以使用“|”运算符轻松创建联合类型，并使用“&”运算符创建交集类型。 虽然接口也可以间接表示联合类型，但它们没有对交集类型的内置支持。\n\n```typescript\ntype Department = 'dep-x' | 'dep-y'; // 并集\n\ntype Person = {\n    name: string;\n    age: number;\n};\n\ntype Employee = {\n    id: number;\n    department: Department;\n};\n\ntype EmployeeInfo = Person & Employee; // 交集\n```\n\n接口示例：\n\n```typescript\ninterface A {\n    x: 'x';\n}\ninterface B {\n    y: 'y';\n}\n\ntype C = A | B; // 接口的并集\n```\n\n## Class\n\n### 通用语法\n\nTypeScript 中使用关键字 `class` 来定义类。下面，您可以看到一个示例：\n\n```typescript\nclass Person {\n    private name: string;\n    private age: number;\n    constructor(name: string, age: number) {\n        this.name = name;\n        this.age = age;\n    }\n    public sayHi(): void {\n        console.log(\n            `Hello, my name is ${this.name} and I am ${this.age} years old.`\n        );\n    }\n}\n```\n\n`class` 关键字用于定义名为 `Person` 的类。\n\n该类有两个私有属性：类型名称 `string` 和类型年龄 `number`。\n\n构造函数是使用 `constructor` 关键字定义的。它将姓名和年龄作为参数并将它们分配给相应的属性。\n\n该类有一个 `public` 名为 `sayHi` 的方法，用于记录问候消息。\n\n要在 TypeScript 中创建类的实例，可以使用 `new` 关键字，后跟类名，然后使用括号 `()`。例如：\n\n<!-- skip -->\n```typescript\nconst myObject = new Person('John Doe', 25);\nmyObject.sayHi(); // 输出：Hello, my name is John Doe and I am 25 years old.\n```\n\n### 构造函数\n\n构造函数是类中的特殊方法，用于在创建类的实例时初始化对象的属性。\n\n```typescript\nclass Person {\n    public name: string;\n    public age: number;\n\n    constructor(name: string, age: number) {\n        this.name = name;\n        this.age = age;\n    }\n\n    sayHello() {\n        console.log(\n            `Hello, my name is ${this.name} and I'm ${this.age} years old.`\n        );\n    }\n}\n\nconst john = new Person('Simon', 17);\njohn.sayHello();\n```\n\n可以使用以下语法重载构造函数：\n\n```typescript\ntype Sex = 'm' | 'f';\n\nclass Person {\n    name: string;\n    age: number;\n    sex: Sex;\n\n    constructor(name: string, age: number, sex?: Sex);\n    constructor(name: string, age: number, sex: Sex) {\n        this.name = name;\n        this.age = age;\n        this.sex = sex ?? 'm';\n    }\n}\n\nconst p1 = new Person('Simon', 17);\nconst p2 = new Person('Alice', 22, 'f');\n```\n\n在 TypeScript 中，可以定义多个构造函数重载，但只能有一个必须与所有重载兼容的实现，这可以通过使用可选参数来实现。\n\n```typescript\nclass Person {\n    name: string;\n    age: number;\n\n    constructor();\n    constructor(name: string);\n    constructor(name: string, age: number);\n    constructor(name?: string, age?: number) {\n        this.name = name ?? 'Unknown';\n        this.age = age ?? 0;\n    }\n\n    displayInfo() {\n        console.log(`Name: ${this.name}, Age: ${this.age}`);\n    }\n}\n\nconst person1 = new Person();\nperson1.displayInfo(); // Name: Unknown, Age: 0\n\nconst person2 = new Person('John');\nperson2.displayInfo(); // Name: John, Age: 0\n\nconst person3 = new Person('Jane', 25);\nperson3.displayInfo(); // Name: Jane, Age: 25\n```\n\n### 私有和受保护的构造函数\n\n在 TypeScript 中，构造函数可以标记为私有或受保护，这限制了它们的可访问性和使用。\n\n私有构造函数：只能在类本身内调用。私有构造函数通常用于以下场景：您想要强制执行单例模式或将实例的创建限制为类中的工厂方法\n\n受保护的构造函数：当您想要创建一个不应直接实例化但可以由子类扩展的基类时，受保护的构造函数非常有用。\n\n```typescript\nclass BaseClass {\n    protected constructor() {}\n}\n\nclass DerivedClass extends BaseClass {\n    private value: number;\n\n    constructor(value: number) {\n        super();\n        this.value = value;\n    }\n}\n\n// 尝试直接实例化基类将导致错误\n// const baseObj = new BaseClass(); // 错误：类\"BaseClass\"的构造函数受到保护。\n\n// 创建派生类的实例\nconst derivedObj = new DerivedClass(10);\n```\n\n### 访问修饰符\n\n访问修饰符 `private` 、`protected` 和 `public` 用于控制 TypeScript 类中类成员（例如属性和方法）的可见性和可访问性。这些修饰符对于强制封装以及建立访问和修改类内部状态的边界至关重要。\n\n修饰符 `private` 仅限制对包含类中的类成员的访问。\n\n修饰符 `protected` 允许访问包含类及其派生类中的类成员。\n\n修饰符 `public` 提供对类成员的不受限制的访问，允许从任何地方访问它。\n\n### Get 与 Set\n\nGetter 和 Setter 是特殊方法，允许您定义类属性的自定义访问和修改行为。它们使您能够封装对象的内部状态，并在获取或设置属性值时提供附加逻辑。在 TypeScript 中，getter 和 setter 分别使用 `get` 和 `set` 关键字定义。这是一个例子：\n\n```typescript\nclass MyClass {\n    private _myProperty: string;\n\n    constructor(value: string) {\n        this._myProperty = value;\n    }\n    get myProperty(): string {\n        return this._myProperty;\n    }\n    set myProperty(value: string) {\n        this._myProperty = value;\n    }\n}\n```\n\n### 类中的自动访问器\n\nTypeScript 版本 4.9 添加了对自动访问器的支持，这是即将推出的 ECMAScript 功能。它们类似于类属性，但使用\"accessor\"关键字声明。\n\n```typescript\nclass Animal {\n    accessor name: string;\n\n    constructor(name: string) {\n        this.name = name;\n    }\n}\n```\n\n自动访问器被\"脱糖\"为私有get访问set器，在无法访问的属性上运行。\n\n<!-- skip -->\n```typescript\nclass Animal {\n    #__name: string;\n\n    get name() {\n        return this.#__name;\n    }\n    set name(value: string) {\n        this.#__name = name;\n    }\n\n    constructor(name: string) {\n        this.name = name;\n    }\n}\n```\n\n### this\n\n在 TypeScript 中，`this` 关键字指的是类的方法或构造函数中的当前实例。它允许您在类自己的范围内访问和修改类的属性和方法。它提供了一种在对象自己的方法中访问和操作对象内部状态的方法。\n\n```typescript\nclass Person {\n    private name: string;\n    constructor(name: string) {\n        this.name = name;\n    }\n    public introduce(): void {\n        console.log(`Hello, my name is ${this.name}.`);\n    }\n}\n\nconst person1 = new Person('Alice');\nperson1.introduce(); // Hello, my name is Alice.\n```\n\n### 参数属性\n\n参数属性允许您直接在构造函数参数中声明和初始化类属性，从而避免样板代码，例如：\n\n```typescript\nclass Person {\n    constructor(\n        private name: string,\n        public age: number\n    ) {\n        // 构造函数中的\"private\"和\"public\"关键字自动声明并初始化相应的类属性。\n    }\n    public introduce(): void {\n        console.log(\n            `Hello, my name is ${this.name} and I am ${this.age} years old.`\n        );\n    }\n}\nconst person = new Person('Alice', 25);\nperson.introduce();\n```\n\n### 抽象类\n\n抽象类在 TypeScript 中主要用于继承，它们提供了一种定义可由子类继承的公共属性和方法的方法。当您想要定义常见行为并强制子类实现某些方法时，这非常有用。它们提供了一种创建类层次结构的方法，其中抽象基类为子类提供共享接口和通用功能。\n\n```typescript\nabstract class Animal {\n    protected name: string;\n\n    constructor(name: string) {\n        this.name = name;\n    }\n\n    abstract makeSound(): void;\n}\n\nclass Cat extends Animal {\n    makeSound(): void {\n        console.log(`${this.name} meows.`);\n    }\n}\n\nconst cat = new Cat('Whiskers');\ncat.makeSound(); // 输出：Whiskers meows.\n```\n\n### 使用泛型\n\n具有泛型的类允许您定义可以与不同类型一起使用的可重用类。\n\n```typescript\nclass Container<T> {\n    private item: T;\n\n    constructor(item: T) {\n        this.item = item;\n    }\n\n    getItem(): T {\n        return this.item;\n    }\n\n    setItem(item: T): void {\n        this.item = item;\n    }\n}\n\nconst container1 = new Container<number>(42);\nconsole.log(container1.getItem()); //  42\n\nconst container2 = new Container<string>('Hello');\ncontainer2.setItem('World');\nconsole.log(container2.getItem()); // World\n```\n\n### 装饰器\n\n装饰器提供了一种添加元数据、修改行为、验证或扩展目标元素功能的机制。它们是在运行时执行的函数。多个装饰器可以应用于一个声明。\n\n装饰器是实验性功能，以下示例仅与使用 ES6 的 TypeScript 版本 5 或更高版本兼容。\n\n对于 5 之前的 TypeScript 版本，应在您的 `tsconfig.json` 中使用使`experimentalDecorators` 或在命令行中使用 `--experimentalDecorators` 来启用它们（但以下示例不起作用）。\n\n装饰器的一些常见用例包括：\n\n* 观察属性变化。\n* 观察方法调用。\n* 添加额外的属性或方法。\n* 运行时验证。\n* 自动序列化和反序列化。\n* 日志记录。\n* 授权和认证。\n* 错误防护。\n\n注意：版本 5 的装饰器不允许装饰参数。\n\n装饰器的类型：\n\n#### 类装饰器\n\n类装饰器对于扩展现有类非常有用，例如添加属性或方法，或者收集类的实例。在下面的示例中，我们添加一个 `toString` 将类转换为字符串表示形式的方法。\n\n```typescript\ntype Constructor<T = {}> = new (...args: any[]) => T;\n\nfunction toString<Class extends Constructor>(\n    Value: Class,\n    context: ClassDecoratorContext<Class>\n) {\n    return class extends Value {\n        constructor(...args: any[]) {\n            super(...args);\n            console.log(JSON.stringify(this));\n            console.log(JSON.stringify(context));\n        }\n    };\n}\n\n@toString\nclass Person {\n    name: string;\n\n    constructor(name: string) {\n        this.name = name;\n    }\n\n    greet() {\n        return 'Hello, ' + this.name;\n    }\n}\nconst person = new Person('Simon');\n/* Logs:\n{\"name\":\"Simon\"}\n{\"kind\":\"class\",\"name\":\"Person\"}\n*/\n```\n\n#### 属性装饰器\n\n属性装饰器对于修改属性的行为非常有用，例如更改初始化值。在下面的代码中，我们有一个脚本将属性设置为始终大写：\n\n```typescript\nfunction upperCase<T>(\n    target: undefined,\n    context: ClassFieldDecoratorContext<T, string>\n) {\n    return function (this: T, value: string) {\n        return value.toUpperCase();\n    };\n}\n\nclass MyClass {\n    @upperCase\n    prop1 = 'hello!';\n}\n\nconsole.log(new MyClass().prop1); // 日志：HELLO!\n```\n\n#### 方法装饰器\n\n方法装饰器允许您更改或增强方法的行为。下面是一个简单记录器的示例：\n\n```typescript\nfunction log<This, Args extends any[], Return>(\n    target: (this: This, ...args: Args) => Return,\n    context: ClassMethodDecoratorContext<\n        This,\n        (this: This, ...args: Args) => Return\n    >\n) {\n    const methodName = String(context.name);\n\n    function replacementMethod(this: This, ...args: Args): Return {\n        console.log(`LOG: Entering method '${methodName}'.`);\n        const result = target.call(this, ...args);\n        console.log(`LOG: Exiting method '${methodName}'.`);\n        return result;\n    }\n\n    return replacementMethod;\n}\n\nclass MyClass {\n    @log\n    sayHello() {\n        console.log('Hello!');\n    }\n}\n\nnew MyClass().sayHello();\n```\n\n它记录：\n\n```shell\nLOG: Entering method 'sayHello'.\nHello!\nLOG: Exiting method 'sayHello'.\n```\n\n#### Getter 和 Setter 装饰器\n\ngetter 和 setter 装饰器允许您更改或增强类访问器的行为。例如，它们对于验证属性分配很有用。这是 getter 装饰器的一个简单示例：\n\n```typescript\nfunction range<This, Return extends number>(min: number, max: number) {\n    return function (\n        target: (this: This) => Return,\n        context: ClassGetterDecoratorContext<This, Return>\n    ) {\n        return function (this: This): Return {\n            const value = target.call(this);\n            if (value < min || value > max) {\n                throw 'Invalid';\n            }\n            Object.defineProperty(this, context.name, {\n                value,\n                enumerable: true,\n            });\n            return value;\n        };\n    };\n}\n\nclass MyClass {\n    private _value = 0;\n\n    constructor(value: number) {\n        this._value = value;\n    }\n    @range(1, 100)\n    get getValue(): number {\n        return this._value;\n    }\n}\n\nconst obj = new MyClass(10);\nconsole.log(obj.getValue); // 有效: 10\n\nconst obj2 = new MyClass(999);\nconsole.log(obj2.getValue); // 抛出异常: Invalid!\n```\n\n### 装饰器元数据\n\n装饰器元数据简化了装饰器在任何类中应用和利用元数据的过程。 他们可以访问上下文对象上的新元数据属性，该属性可以充当基元和对象的密钥。\n可以通过\"Symbol.metadata\"在类上访问元数据信息。\n\n元数据可用于各种目的，例如调试、序列化或使用装饰器的依赖项注入。\n\n```typescript\n//@ts-ignore\nSymbol.metadata ??= Symbol('Symbol.metadata'); // 简单的兼容性填充\n\ntype Context =\n    | ClassFieldDecoratorContext\n    | ClassAccessorDecoratorContext\n    | ClassMethodDecoratorContext; // 上下文对象包含属性元数据: 装饰器元数据\n\nfunction setMetadata(_target: any, context: Context) {\n    // 使用基本类型值设置元数据对象\n    context.metadata[context.name] = true;\n}\n\nclass MyClass {\n    @setMetadata\n    a = 123;\n\n    @setMetadata\n    accessor b = 'b';\n\n    @setMetadata\n    fn() {}\n}\n\nconst metadata = MyClass[Symbol.metadata]; // 获取元数据对象信息\n\nconsole.log(JSON.stringify(metadata)); // {\"bar\":true,\"baz\":true,\"foo\":true}\n```\n\n### 继承\n\n继承是指一个类可以从另一个类（称为基类或超类）继承属性和方法的机制。派生类也称为子类或子类，可以通过添加新的属性和方法或重写现有的属性和方法来扩展和专门化基类的功能。\n\n```typescript\nclass Animal {\n    name: string;\n\n    constructor(name: string) {\n        this.name = name;\n    }\n\n    speak(): void {\n        console.log('The animal makes a sound');\n    }\n}\n\nclass Dog extends Animal {\n    breed: string;\n\n    constructor(name: string, breed: string) {\n        super(name);\n        this.breed = breed;\n    }\n\n    speak(): void {\n        console.log('Woof! Woof!');\n    }\n}\n\n// 创建基类的一个实例\nconst animal = new Animal('Generic Animal');\nanimal.speak(); // The animal makes a sound\n\n// 创建派生类的一个实例\nconst dog = new Dog('Max', 'Labrador');\ndog.speak(); // Woof! Woof!\"\n```\n\nTypeScript 不支持传统意义上的多重继承，而是允许从单个基类继承。TypeScript 支持多种接口。接口可以定义对象结构的契约，类可以实现多个接口。这允许类从多个源继承行为和结构。\n\n```typescript\ninterface Flyable {\n    fly(): void;\n}\n\ninterface Swimmable {\n    swim(): void;\n}\n\nclass FlyingFish implements Flyable, Swimmable {\n    fly() {\n        console.log('Flying...');\n    }\n\n    swim() {\n        console.log('Swimming...');\n    }\n}\n\nconst flyingFish = new FlyingFish();\nflyingFish.fly();\nflyingFish.swim();\n```\n\nTypeScript 中的关键字 `class` 与 JavaScript 类似，通常被称为语法糖。它是在 ECMAScript 2015 (ES6) 中引入的，旨在提供更熟悉的语法，以基于类的方式创建和使用对象。然而，值得注意的是，TypeScript 作为 JavaScript 的超集，最终会编译为 JavaScript，而 JavaScript 的核心仍然是基于原型的。\n\n### 静态成员\n\nTypeScript 有静态成员。要访问类的静态成员，可以使用类名后跟一个点，而不需要创建对象。\n\n```typescript\nclass OfficeWorker {\n    static memberCount: number = 0;\n\n    constructor(private name: string) {\n        OfficeWorker.memberCount++;\n    }\n}\n\nconst w1 = new OfficeWorker('James');\nconst w2 = new OfficeWorker('Simon');\nconst total = OfficeWorker.memberCount;\nconsole.log(total); // 2\n```\n\n### 属性初始化\n\n在 TypeScript 中初始化类的属性有多种方法：\n\n内嵌：\n\n在下面的示例中，创建类的实例时将使用这些初始值。\n\n```typescript\nclass MyClass {\n    property1: string = 'default value';\n    property2: number = 42;\n}\n```\n\n在构造函数中：\n\n```typescript\nclass MyClass {\n    property1: string;\n    property2: number;\n\n    constructor() {\n        this.property1 = 'default value';\n        this.property2 = 42;\n    }\n}\n```\n\n使用构造函数参数：\n\n```typescript\nclass MyClass {\n    constructor(\n        private property1: string = 'default value',\n        public property2: number = 42\n    ) {\n        // 无需显式地将值分配给属性。\n    }\n    log() {\n        console.log(this.property2);\n    }\n}\nconst x = new MyClass();\nx.log();\n```\n\n### 方法重载\n\n方法重载允许一个类有多个名称相同但参数类型不同或参数数量不同的方法。这允许我们根据传递的参数以不同的方式调用方法。\n\n```typescript\nclass MyClass {\n    add(a: number, b: number): number; // 重载签名 1\n    add(a: string, b: string): string; // 重载签名 2\n\n    add(a: number | string, b: number | string): number | string {\n        if (typeof a === 'number' && typeof b === 'number') {\n            return a + b;\n        }\n        if (typeof a === 'string' && typeof b === 'string') {\n            return a.concat(b);\n        }\n        throw new Error('Invalid arguments');\n    }\n}\n\nconst r = new MyClass();\nconsole.log(r.add(10, 5)); // 日志：15\n```\n\n## 泛型\n\n泛型允许您创建可与多种类型一起使用的可重用组件和函数。使用泛型，您可以参数化类型、函数和接口，从而允许它们对不同类型进行操作，而无需事先显式指定它们。\n\n泛型允许您使代码更加灵活和可重用。\n\n### 泛型类型\n\n要定义泛型类型，可以使用尖括号 (`<>`) 来指定类型参数，例如：\n\n```typescript\nfunction identity<T>(arg: T): T {\n    return arg;\n}\nconst a = identity('x');\nconst b = identity(123);\n\nconst getLen = <T,>(data: ReadonlyArray<T>) => data.length;\nconst len = getLen([1, 2, 3]);\n```\n\n### 泛型类\n\n泛型也可以应用于类，这样它们就可以通过使用类型参数来处理多种类型。这对于创建可重用的类定义非常有用，这些定义可以在保持类型安全的同时对不同的数据类型进行操作。\n\n```typescript\nclass Container<T> {\n    private item: T;\n\n    constructor(item: T) {\n        this.item = item;\n    }\n\n    getItem(): T {\n        return this.item;\n    }\n}\n\nconst numberContainer = new Container<number>(123);\nconsole.log(numberContainer.getItem()); // 123\n\nconst stringContainer = new Container<string>('hello');\nconsole.log(stringContainer.getItem()); // hello\n```\n\n### 泛型约束\n\n可以使用关键字 `extends` 后跟类型参数必须满足的类型或接口来约束泛型参数。\n\n在下面的示例中，T 必须正确包含 `length` 才能有效：\n\n<!-- skip -->\n```typescript\nconst printLen = <T extends { length: number }>(value: T): void => {\n    console.log(value.length);\n};\n\nprintLen('Hello'); // 5\nprintLen([1, 2, 3]); // 3\nprintLen({ length: 10 }); // 10\nprintLen(123); // 无效\n```\n\n3.4 RC 版中引入的泛型的一个有趣功能是高阶函数类型推断，它引入了传播泛型类型参数：\n\n```typescript\ndeclare function pipe<A extends any[], B, C>(\n    ab: (...args: A) => B,\n    bc: (b: B) => C\n): (...args: A) => C;\n\ndeclare function list<T>(a: T): T[];\ndeclare function box<V>(x: V): { value: V };\n\nconst listBox = pipe(list, box); // <T>(a: T) => { value: T[] }\nconst boxList = pipe(box, list); // <V>(x: V) => { value: V }[]\n```\n\n此功能允许更轻松地键入安全的无点风格编程，这在函数式编程中很常见。\n\n### 泛型上下文缩小\n\n泛型上下文缩小是 TypeScript 中的机制，允许编译器根据使用泛型参数的上下文来缩小泛型参数的类型，在条件语句中使用泛型类型时非常有用：\n\n```typescript\nfunction process<T>(value: T): void {\n    if (typeof value === 'string') {\n        // Value 的类型被缩小到 'string' 类型\n        console.log(value.length);\n    } else if (typeof value === 'number') {\n        // Value 的类型被缩小到 'number' 类型\n        console.log(value.toFixed(2));\n    }\n}\n\nprocess('hello'); // 5\nprocess(3.14159); // 3.14\n```\n\n## 擦除的结构类型\n\n在 TypeScript 中，对象不必匹配特定的、精确的类型。例如，如果我们创建一个满足接口要求的对象，我们就可以在需要该接口的地方使用该对象，即使它们之间没有显式连接。例子：\n\n```typescript\ntype NameProp1 = {\n    prop1: string;\n};\n\nfunction log(x: NameProp1) {\n    console.log(x.prop1);\n}\n\nconst obj = {\n    prop2: 123,\n    prop1: 'Origin',\n};\n\nlog(obj); // 有效\n```\n\n## 命名空间\n\n在 TypeScript 中，命名空间用于将代码组织到逻辑容器中，防止命名冲突并提供一种将相关代码分组在一起的方法。使用关键字 `export` 允许在\"外部\"模块中访问名称空间。\n\n```typescript\nexport namespace MyNamespace {\n    export interface MyInterface1 {\n        prop1: boolean;\n    }\n    export interface MyInterface2 {\n        prop2: string;\n    }\n}\n\nconst a: MyNamespace.MyInterface1 = {\n    prop1: true,\n};\n```\n\n## Symbols\n\n符号是一种原始数据类型，表示不可变值，保证在程序的整个生命周期中全局唯一。\n\n符号可以用作对象属性的键，并提供一种创建不可枚举属性的方法。\n\n```typescript\nconst key1: symbol = Symbol('key1');\nconst key2: symbol = Symbol('key2');\n\nconst obj = {\n    [key1]: 'value 1',\n    [key2]: 'value 2',\n};\n\nconsole.log(obj[key1]); // value 1\nconsole.log(obj[key2]); // value 2\n```\n\n在 WeakMap 和 WeakSet 中，现在允许符号作为键。\n\n## 三斜杠指令\n\n三斜杠指令是特殊注释，为编译器提供有关如何处理文件的说明。这些指令以三个连续斜杠 (`///`) 开头，通常放置在 TypeScript 文件的顶部，对运行时行为没有影响。\n\n三斜杠指令用于引用外部依赖项、指定模块加载行为、启用/禁用某些编译器功能等等。几个例子：\n\n引用声明文件：\n\n<!-- skip -->\n```typescript\n/// <reference path=\"path/to/declaration/file.d.ts\" />\n```\n\n指明模块格式：\n\n<!-- skip -->\n```typescript\n/// <amd|commonjs|system|umd|es6|es2015|none>\n```\n\n启用编译器选项，在以下示例中严格模式：\n\n<!-- skip -->\n```typescript\n/// <strict|noImplicitAny|noUnusedLocals|noUnusedParameters>\n```\n\n## 类型操作\n\n### 从类型创建类型\n\n是否可以通过组合、操作或转换现有类型来创建新类型。\n\n交集类型 ( &):\n\n允许您将多种类型组合成单一类型：\n\n```typescript\ntype A = { foo: number };\ntype B = { bar: string };\ntype C = A & B; // A和B的交集\nconst obj: C = { foo: 42, bar: 'hello' };\n```\n\n联合类型 (`|`):\n\n允许您定义可以是以下几种类型之一的类型\n\n```typescript\ntype Result = string | number;\nconst value1: Result = 'hello';\nconst value2: Result = 42;\n```\n\n映射类型：\n\n允许您转换现有类型的属性以创建新类型：\n\n```typescript\ntype Mutable<T> = {\n    readonly [P in keyof T]: T[P];\n};\ntype Person = {\n    name: string;\n    age: number;\n};\ntype ImmutablePerson = Mutable<Person>; // 属性变为只读\n```\n\n条件类型：\n\n允许您根据某些条件创建类型：\n\n```typescript\ntype ExtractParam<T> = T extends (param: infer P) => any ? P : never;\ntype MyFunction = (name: string) => number;\ntype ParamType = ExtractParam<MyFunction>; // string\n```\n\n### 索引访问类型\n\n在 TypeScript 中，可以使用索引访问和操作另一个类型中的属性类型 `Type[Key]`。\n\n```typescript\ntype Person = {\n    name: string;\n    age: number;\n};\n\ntype AgeType = Person['age']; // number\n```\n\n```typescript\ntype MyTuple = [string, number, boolean];\ntype MyType = MyTuple[2]; // boolean\n```\n\n### 工具类型\n\n可以使用几种内置工具来操作类型，下面列出了最常用的：\n\n#### Awaited\\<T\\>\n\n构造一个递归解包 Promise 类型的类型。\n\n```typescript\ntype A = Awaited<Promise<string>>; // string\n```\n\n#### Partial\\<T\\>\n\n构造一个类型，并将 T 的所有属性设置为可选。\n\n```typescript\ntype Person = {\n    name: string;\n    age: number;\n};\n\ntype A = Partial<Person>; // { name?: string | undefined; age?: number | undefined; }\n```\n\n#### Required\\<T\\>\n\n构造一个类型，并将 T 的所有属性设置为必需。\n\n```typescript\ntype Person = {\n    name?: string;\n    age?: number;\n};\n\ntype A = Required<Person>; // { name: string; age: number; }\n```\n\n#### Readonly\\<T\\>\n\n构造一个类型，并将 T 的所有属性设置为只读。\n\n<!-- skip -->\n```typescript\ntype Person = {\n    name: string;\n    age: number;\n};\n\ntype A = Readonly<Person>;\n\nconst a: A = { name: 'Simon', age: 17 };\na.name = 'John'; // 无效\n```\n\n#### Record\\<K, T\\>\n\n构造一个具有类型 T 的一组属性 K 的类型。\n\n```typescript\ntype Product = {\n    name: string;\n    price: number;\n};\n\nconst products: Record<string, Product> = {\n    apple: { name: 'Apple', price: 0.5 },\n    banana: { name: 'Banana', price: 0.25 },\n};\n\nconsole.log(products.apple); // { name: 'Apple', price: 0.5 }\n```\n\n#### Pick\\<T, K\\>\n\n通过从 T 中选取指定属性 K 来构造类型。\n\n```typescript\ntype Product = {\n    name: string;\n    price: number;\n};\n\ntype Price = Pick<Product, 'price'>; // { price: number; }\n```\n\n#### Omit\\<T, K\\>\n\n通过从 T 中省略指定属性 K 来构造类型。\n\n```typescript\ntype Product = {\n    name: string;\n    price: number;\n};\n\ntype Name = Omit<Product, 'price'>; // { name: string; }\n```\n\n#### Exclude\\<T, U\\>\n\n通过从 T 中排除类型 U 的所有值来构造类型。\n\n```typescript\ntype Union = 'a' | 'b' | 'c';\ntype MyType = Exclude<Union, 'a' | 'c'>; // b\n```\n\n#### Extract\\<T, U\\>\n\n通过从 T 中提取类型 U 的所有值来构造类型。\n\n```typescript\ntype Union = 'a' | 'b' | 'c';\ntype MyType = Extract<Union, 'a' | 'c'>; // a | c\n```\n\n#### NonNullable\\<T\\>\n\n通过从 T 中排除 null 和 undefined 来构造类型。\n\n```typescript\ntype Union = 'a' | null | undefined | 'b';\ntype MyType = NonNullable<Union>; // 'a' | 'b'\n```\n\n#### Parameters\\<T\\>\n\n提取函数类型 T 的参数类型。\n\n```typescript\ntype Func = (a: string, b: number) => void;\ntype MyType = Parameters<Func>; // [a: string, b: number]\n```\n\n#### ConstructorParameters\\<T\\>\n\n提取构造函数类型 T 的参数类型。\n\n```typescript\nclass Person {\n    constructor(\n        public name: string,\n        public age: number\n    ) {}\n}\ntype PersonConstructorParams = ConstructorParameters<typeof Person>; // [name: string, age: number]\nconst params: PersonConstructorParams = ['John', 30];\nconst person = new Person(...params);\nconsole.log(person); // Person { name: 'John', age: 30 }\n```\n\n#### ReturnType\\<T\\>\n\n提取函数类型 T 的返回类型。\n\n```typescript\ntype Func = (name: string) => number;\ntype MyType = ReturnType<Func>; // number\n```\n\n#### InstanceType\\<T\\>\n\n提取类类型 T 的实例类型。\n\n```typescript\nclass Person {\n    name: string;\n\n    constructor(name: string) {\n        this.name = name;\n    }\n\n    sayHello() {\n        console.log(`Hello, my name is ${this.name}!`);\n    }\n}\n\ntype PersonInstance = InstanceType<typeof Person>;\n\nconst person: PersonInstance = new Person('John');\n\nperson.sayHello(); // Hello, my name is John!\n```\n\n#### ThisParameterType\\<T\\>\n\n从函数类型 T 中提取\"this\"参数的类型。\n\n```typescript\ninterface Person {\n    name: string;\n    greet(this: Person): void;\n}\ntype PersonThisType = ThisParameterType<Person['greet']>; // Person\n```\n\n#### OmitThisParameter\\<T\\>\n\n从函数类型 T 中删除\"this\"参数。\n\n```typescript\nfunction capitalize(this: String) {\n    return this[0].toUpperCase + this.substring(1).toLowerCase();\n}\n\ntype CapitalizeType = OmitThisParameter<typeof capitalize>; // () => string\n```\n\n#### ThisType\\<T\\>\n\n作为上下文类型 `this` 的一部分。\n\n<!-- skip -->\n```typescript\ntype Logger = {\n    log: (error: string) => void;\n};\n\nlet helperFunctions: { [name: string]: Function } & ThisType<Logger> = {\n    hello: function () {\n        this.log('some error'); // 有效，因为\"log\"是\"this\"的一部分\n        this.update(); // 无效\n    },\n};\n```\n\n#### Uppercase\\<T\\>\n\n将输入类型 T 的名称设为大写。\n\n```typescript\ntype MyType = Uppercase<'abc'>; // \"ABC\"\n```\n\n#### Lowercase\\<T\\>\n\n将输入类型 T 的名称设为小写。\n\n```typescript\ntype MyType = Lowercase<'ABC'>; // \"abc\"\n```\n\n#### Capitalize\\<T\\>\n\n输入类型 T 的名称大写。\n\n```typescript\ntype MyType = Capitalize<'abc'>; // \"Abc\"\n```\n\n#### Uncapitalize\\<T\\>\n\n将输入类型 T 的名称取消大写。\n\n```typescript\ntype MyType = Uncapitalize<'Abc'>; // \"abc\"\n```\n\n#### NoInfer\\<T\\>\n\nNoInfer 是一种实用类型，旨在阻止泛型函数范围内类型的自动推断。\n\n示例：\n\n```typescript\n// 泛型函数范围内类型的自动推断。\nfunction fn<T extends string>(x: T[], y: T) {\n    return x.concat(y);\n}\nconst r = fn(['a', 'b'], 'c'); // 此处的类型为 (\"a\" | \"b\" | \"c\")[]\n```\n\n使用 NoInfer：\n\n<!-- skip -->\n```typescript\n// 使用 NoInfer 阻止类型推断的示例函数\nfunction fn2<T extends string>(x: T[], y: NoInfer<T>) {\n    return x.concat(y);\n}\n\nconst r2 = fn2(['a', 'b'], 'c'); // 错误：类型为“c”的类型参数不能分配给类型为“a”|“b”的参数。\n```\n\n## 其他\n\n### 错误和异常处理\n\nTypeScript 允许您使用标准 JavaScript 错误处理机制捕获和处理错误：\n\nTry-Catch-Finally 块：\n\n```typescript\ntry {\n    // 可能会抛出异常的代码\n} catch (error) {\n    // 处理错误\n} finally {\n    // 总是会执行的代码, finally 是可选的\n}\n```\n\n您还可以处理不同类型的错误：\n\n```typescript\ntry {\n    // 可能会抛出不同类型错误的代码\n} catch (error) {\n    if (error instanceof TypeError) {\n        // 处理 TypeError\n    } else if (error instanceof RangeError) {\n        // 处理 RangeError\n    } else {\n        // 处理其他的错误\n    }\n}\n```\n\n自定义错误类型：\n\n可以通过扩展 Error 来指定更具体的错误 `class` ：\n\n```typescript\nclass CustomError extends Error {\n    constructor(message: string) {\n        super(message);\n        this.name = 'CustomError';\n    }\n}\n\nthrow new CustomError('This is a custom error.');\n```\n\n### 混合类\n\nMixin 类允许您将多个类的行为组合并组合成一个类。它们提供了一种重用和扩展功能的方法，而不需要深层继承链。\n\n```typescript\nabstract class Identifiable {\n    name: string = '';\n    logId() {\n        console.log('id:', this.name);\n    }\n}\nabstract class Selectable {\n    selected: boolean = false;\n    select() {\n        this.selected = true;\n        console.log('Select');\n    }\n    deselect() {\n        this.selected = false;\n        console.log('Deselect');\n    }\n}\nclass MyClass {\n    constructor() {}\n}\n\n// 扩展 MyClass 以包含可识别和可选择的行为\ninterface MyClass extends Identifiable, Selectable {}\n\n// 将 mixins 应用于类的函数\nfunction applyMixins(source: any, baseCtors: any[]) {\n    baseCtors.forEach(baseCtor => {\n        Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => {\n            let descriptor = Object.getOwnPropertyDescriptor(\n                baseCtor.prototype,\n                name\n            );\n            if (descriptor) {\n                Object.defineProperty(source.prototype, name, descriptor);\n            }\n        });\n    });\n}\n\n// 将 mixins 应用到 MyClass\napplyMixins(MyClass, [Identifiable, Selectable]);\nlet o = new MyClass();\no.name = 'abc';\no.logId();\no.select();\n```\n\n### 异步语言特性\n\n由于 TypeScript 是 JavaScript 的超集，因此它内置了 JavaScript 的异步语言功能，例如：\n\nPromises：\n\nPromise 是一种处理异步操作及其结果的方法，使用 `.then()`和等方法 `.catch()` 来处理成功和错误条件。\n\n要了解更多信息： [https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)\n\nAsync/await:\n\nAsync/await 关键字是一种为处理 Promise 提供看起来更同步的语法的方法。`async` 关键字用于定义异步函数，并且 `await` 关键字在异步函数中使用以暂停执行，直到 Promise 被解决或拒绝。\n\n要了解更多信息：\n[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function)\n[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await)\n\nTypeScript 很好地支持以下 API：\n\nFetch API:\n[https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API)\n\nWeb Workers:\n[https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API)\n\nShared Workers:\n[https://developer.mozilla.org/en-US/docs/Web/API/SharedWorker](https://developer.mozilla.org/en-US/docs/Web/API/SharedWorker)\n\nWebSocket:\n[https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API)\n\n### 迭代器和生成器\n\nTypeScript 对迭代器和生成器都提供了很好的支持。\n\n迭代器是实现迭代器协议的对象，提供了一种逐个访问集合或序列元素的方法。它是一个包含指向迭代中下一个元素的指针的结构。他们有一个 `next()` 方法返回序列中的下一个值以及指示序列是否为 的布尔值 `done` 。\n\n```typescript\nclass NumberIterator implements Iterable<number> {\n    private current: number;\n\n    constructor(\n        private start: number,\n        private end: number\n    ) {\n        this.current = start;\n    }\n\n    public next(): IteratorResult<number> {\n        if (this.current <= this.end) {\n            const value = this.current;\n            this.current++;\n            return { value, done: false };\n        } else {\n            return { value: undefined, done: true };\n        }\n    }\n\n    [Symbol.iterator](): Iterator<number> {\n        return this;\n    }\n}\n\nconst iterator = new NumberIterator(1, 3);\n\nfor (const num of iterator) {\n    console.log(num);\n}\n```\n\n生成器是使用 `function*` 简化迭代器创建的语法定义的特殊函数。它们使用 `yield` 关键字来定义值的序列，并在请求值时自动暂停和恢复执行。\n\n生成器使创建迭代器变得更加容易，并且对于处理大型或无限序列特别有用。\n\n例子：\n\n```typescript\nfunction* numberGenerator(start: number, end: number): Generator<number> {\n    for (let i = start; i <= end; i++) {\n        yield i;\n    }\n}\n\nconst generator = numberGenerator(1, 5);\n\nfor (const num of generator) {\n    console.log(num);\n}\n```\n\nTypeScript 还支持异步迭代器和异步生成器。\n\n要了解更多信息：\n\n[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Generator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Generator)\n\n[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Iterator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Iterator)\n\n### TsDocs JSDoc 参考\n\n使用 JavaScript 代码库时，可以通过使用 JSDoc 注释和附加注释来提供类型信息，帮助 TypeScript 推断正确的类型。\n\n例子：\n\n```typescript\n/**\n * Computes the power of a given number\n * @constructor\n * @param {number} base – The base value of the expression\n * @param {number} exponent – The exponent value of the expression\n */\nfunction power(base: number, exponent: number) {\n    return Math.pow(base, exponent);\n}\npower(10, 2); // function power(base: number, exponent: number): number\n```\n\n此链接提供了完整文档：\n[https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html](https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html)\n\n从版本 3.7 开始，可以从 JavaScript JSDoc 语法生成 .d.ts 类型定义。更多信息可以在这里找到：\n[https://www.typescriptlang.org/docs/handbook/declaration-files/dts-from-js.html](https://www.typescriptlang.org/docs/handbook/declaration-files/dts-from-js.html)\n\n### @types\n\n@types 组织下的包是特殊的包命名约定，用于为现有 JavaScript 库或模块提供类型定义。例如使用：\n\n```shell\nnpm install --save-dev @types/lodash\n```\n\n将在您当前的项目中安装 `lodash` 的类型定义。\n\n要为 @types 包的类型定义做出贡献，请向 [https://github.com/DefinitelyTyped/DefinitelyTyped](https://github.com/DefinitelyTyped/DefinitelyTyped) 提交pr请求。\n\n### JSX\n\nJSX (JavaScript XML) 是 JavaScript 语言语法的扩展，允许您在 JavaScript 或 TypeScript 文件中编写类似 HTML 的代码。它通常在 React 中用来定义 HTML 结构。\n\nTypeScript 通过提供类型检查和静态分析来扩展 JSX 的功能。\n\n要使用 JSX，您需要在文件 `tsconfig.json` 中设置 `jsx` 编译器选项。两个常见的配置选项：\n\n* \"preserve\": 触发 .jsx 文件且 JSX 不变. 此选项告诉 TypeScript 按原样保留 JSX 语法，而不是在编译过程中对其进行转换。 如果您有单独的工具（例如 Babel）来处理转换，则可以使用此选项。\n* \"react\": 启用 TypeScript 的内置 JSX 转换。 将使用 React.createElement 。\n\n所有选项均可在此处使用：\n[https://www.typescriptlang.org/tsconfig#jsx](https://www.typescriptlang.org/tsconfig#jsx)\n\n### ES6 模块\n\nTypeScript 确实支持 ES6 (ECMAScript 2015) 和许多后续版本。这意味着您可以使用 ES6 语法，例如箭头函数、模板文字、类、模块、解构等等。\n\n要在项目中启用 ES6 功能，您可以在 `tsconfig.json` 中指定 `target` 属性。\n\n配置示例：\n\n```json\n{\n  \"compilerOptions\": {\n    \"target\": \"es6\",\n    \"module\": \"es6\",\n    \"moduleResolution\": \"node\",\n    \"sourceMap\": true,\n    \"outDir\": \"dist\"\n  },\n  \"include\": [\"src\"]\n}\n```\n\n### ES7 求幂运算符\n\n求幂 (`**`) 运算符计算通过将第一个操作数进行第二个操作数的幂获得的值。它的功能与 `Math.pow()` 类似，但增加了接受 BigInts 作为操作数的功能。TypeScript 完全支持在 `tsconfig.json` 文件中设置 `target` 为 `es2016`或更大版本来使用此运算符。\n\n```typescript\nconsole.log(2 ** (2 ** 2)); // 16\n```\n\n### for-await-of 语句\n\n这是 TypeScript 完全支持的 JavaScript 功能，它允许您从目标版本 `es2018` 迭代异步可迭代对象。\n\n```typescript\nasync function* asyncNumbers(): AsyncIterableIterator<number> {\n    yield Promise.resolve(1);\n    yield Promise.resolve(2);\n    yield Promise.resolve(3);\n}\n\n(async () => {\n    for await (const num of asyncNumbers()) {\n        console.log(num);\n    }\n})();\n```\n\n### New target 元属性\n\n您可以在 TypeScript 中使用 `new.target` 元属性，该属性使您能够确定是否使用 new 运算符调用函数或构造函数。它允许您检测对象是否是由于构造函数调用而创建的。\n\n```typescript\nclass Parent {\n    constructor() {\n        console.log(new.target); // 记录用于创建实例的构造函数\n    }\n}\n\nclass Child extends Parent {\n    constructor() {\n        super();\n    }\n}\n\nconst parentX = new Parent(); // [Function: Parent]\nconst child = new Child(); // [Function: Child]\n```\n\n### 动态导入表达式\n\n可以使用 TypeScript 支持的动态导入 ECMAScript 建议有条件地加载模块或按需延迟加载模块。\n\nTypeScript 中动态导入表达式的语法如下：\n\n<!-- skip -->\n```typescript\nasync function renderWidget() {\n    const container = document.getElementById('widget');\n    if (container !== null) {\n        const widget = await import('./widget'); // 动态导入\n        widget.render(container);\n    }\n}\n\nrenderWidget();\n```\n\n### \"tsc –watch\"\n\n此命令使用 `--watch` 参数启动 TypeScript 编译器，能够在修改 TypeScript 文件时自动重新编译它们。\n\n```shell\ntsc --watch\n```\n\n从 TypeScript 4.9 版本开始，文件监控主要依赖于文件系统事件，如果无法建立基于事件的观察程序，则会自动诉诸轮询。\n\n### 默认声明\n\n当为变量或参数分配默认值时，将使用默认声明。这意味着如果没有为该变量或参数提供值，则将使用默认值。\n\n```typescript\nfunction greet(name: string = 'Anonymous'): void {\n    console.log(`Hello, ${name}!`);\n}\ngreet(); // Hello, Anonymous!\ngreet('John'); // Hello, John!\n```\n\n### 可选链\n\n可选的链接运算符 `?.` 与常规点运算符 (`.`) 一样用于访问属性或方法。但是，它通过优雅处理 `undefined` 和 `null` 来终止表达式并返回 `undefined`，而不是抛出错误。\n\n```typescript\ntype Person = {\n    name: string;\n    age?: number;\n    address?: {\n        street?: string;\n        city?: string;\n    };\n};\n\nconst person: Person = {\n    name: 'John',\n};\n\nconsole.log(person.address?.city); // undefined\n```\n\n### 空合并运算符\n\n如果 `??` 左侧是 `null` 或者 `undefined` ，则空合并运算符返回右侧值，否则，它返回左侧值。\n\n```typescript\nconst foo = null ?? 'foo';\nconsole.log(foo); // foo\n\nconst baz = 1 ?? 'baz';\nconst baz2 = 0 ?? 'baz';\nconsole.log(baz); // 1\nconsole.log(baz2); // 0\n```\n\n### 模板字符串类型\n\n模板字符串类型允许在类型级别操作字符串值并基于现有字符串生成新的字符串类型。它们对于从基于字符串的操作创建更具表现力和更精确的类型非常有用。\n\n```typescript\ntype Department = 'enginnering' | 'hr';\ntype Language = 'english' | 'spanish';\ntype Id = `${Department}-${Language}-id`; // \"enginnering-english-id\" | \"enginnering-spanish-id\" | \"hr-english-id\" | \"hr-spanish-id\"\n```\n\n### 函数重载\n\n函数重载允许您为同一函数名定义多个函数签名，每个函数签名具有不同的参数类型和返回类型。当您调用重载函数时，TypeScript 使用提供的参数来确定正确的函数签名：\n\n```typescript\nfunction makeGreeting(name: string): string;\nfunction makeGreeting(names: string[]): string[];\n\nfunction makeGreeting(person: unknown): unknown {\n    if (typeof person === 'string') {\n        return `Hi ${person}!`;\n    } else if (Array.isArray(person)) {\n        return person.map(name => `Hi, ${name}!`);\n    }\n    throw new Error('Unable to greet');\n}\n\nmakeGreeting('Simon');\nmakeGreeting(['Simone', 'John']);\n```\n\n### 递归类型\n\n递归类型是可以引用自身的类型。 这对于定义具有分层或递归结构（可能无限嵌套）的数据结构非常有用，例如链表、树和图。\n\n```typescript\ntype ListNode<T> = {\n    data: T;\n    next: ListNode<T> | undefined;\n};\n```\n\n### 递归条件类型\n\n可以使用 TypeScript 中的逻辑和递归来定义复杂的类型关系。让我们简单地分解一下：\n\n条件类型：允许您基于布尔条件定义类型：\n\n```typescript\ntype CheckNumber<T> = T extends number ? 'Number' : 'Not a number';\ntype A = CheckNumber<123>; // 'Number'\ntype B = CheckNumber<'abc'>; // 'Not a number'\n```\n\n递归：是指在自己的定义中引用自身的类型定义：\n\n```typescript\ntype Json = string | number | boolean | null | Json[] | { [key: string]: Json };\n\nconst data: Json = {\n    prop1: true,\n    prop2: 'prop2',\n    prop3: {\n        prop4: [],\n    },\n};\n```\n\n递归条件类型结合了条件逻辑和递归。这意味着类型定义可以通过条件逻辑依赖于自身，从而创建复杂且灵活的类型关系。\n\n```typescript\ntype Flatten<T> = T extends Array<infer U> ? Flatten<U> : T;\n\ntype NestedArray = [1, [2, [3, 4], 5], 6];\ntype FlattenedArray = Flatten<NestedArray>; // 2 | 3 | 4 | 5 | 1 | 6\n```\n\n### Node 中的 ECMAScript 模块支持\n\nNode.js 从 15.3.0 版本开始添加了对 ECMAScript 模块的支持，而 TypeScript 从 4.7 版本开始增加了对 Node.js 的 ECMAScript 模块支持。可以通过将 `tsconfig.json` 文件中的`module`属性的值设置为 `nodenext` 来启用此支持。这是一个例子：\n\n```json\n{\n  \"compilerOptions\": {\n    \"module\": \"nodenext\",\n    \"outDir\": \"./lib\",\n    \"declaration\": true\n  }\n}\n```\n\nNode.js 支持两种模块文件扩展名：`.mjs` 的ES 模块和 `.cjs` 的CommonJS 模块。TypeScript 中的等效文件扩展名适用 `.mts` 于 ES 模块和 `.cts` 于CommonJS 模块。当 TypeScript 编译器将这些文件转译为 JavaScript 时，它将分别创建 `.mjs` 和 `.cjs` 文件。\n\n如果您想在项目中使用 ES 模块，可以type在 package.json 文件中将该属性设置为\"module\"。这指示 Node.js 将项目视为 ES 模块项目。\n\n此外，TypeScript 还支持 .d.ts 文件中的类型声明。这些声明文件为用 TypeScript 编写的库或模块提供类型信息，允许其他开发人员通过 TypeScript 的类型检查和自动完成功能来利用它们。\n\n### 断言函数\n\n在 TypeScript 中，断言函数是根据返回值指示特定条件验证的函数。在最简单的形式中，断言函数检查提供的谓词，并在谓词计算结果为 false 时引发错误。\n\n```typescript\nfunction isNumber(value: unknown): asserts value is number {\n    if (typeof value !== 'number') {\n        throw new Error('Not a number');\n    }\n}\n```\n\n或者可以声明为函数表达式：\n\n```typescript\ntype AssertIsNumber = (value: unknown) => asserts value is number;\nconst isNumber: AssertIsNumber = value => {\n    if (typeof value !== 'number') {\n        throw new Error('Not a number');\n    }\n};\n```\n\n断言函数与类型保护有相似之处。类型保护最初是为了执行运行时检查并确保值的类型在特定范围内而引入的。具体来说，类型保护是一个计算类型谓词并返回指示谓词是真还是假的布尔值的函数。这与断言函数略有不同，断言函数的目的是在不满足谓词时抛出错误而不是返回 false。\n\n类型保护示例：\n\n```typescript\nconst isNumber = (value: unknown): value is number => typeof value === 'number';\n```\n\n### 可变参数元组类型\n\n可变元组类型是 TypeScript 4.0 版本中引入的一个功能，让我们通过回顾什么是元组来开始学习它们：\n\n元组类型是一个具有定义长度的数组，并且每个元素的类型已知：\n\n```typescript\ntype Student = [string, number];\nconst [name, age]: Student = ['Simone', 20];\n```\n\n术语\"可变参数\"意味着不定数量（接受可变数量的参数）。\n\n可变参数元组是一种元组类型，它具有以前的所有属性，但确切的形状尚未定义：\n\n```typescript\ntype Bar<T extends unknown[]> = [boolean, ...T, number];\n\ntype A = Bar<[boolean]>; // [boolean, boolean, number]\ntype B = Bar<['a', 'b']>; // [boolean, 'a', 'b', number]\ntype C = Bar<[]>; // [boolean, number]\n```\n\n在前面的代码中我们可以看到元组形状是由T传入的泛型定义的。\n\n可变参数元组可以接受多个泛型，这使得它们非常灵活：\n\n```typescript\ntype Bar<T extends unknown[], G extends unknown[]> = [...T, boolean, ...G];\n\ntype A = Bar<[number], [string]>; // [number, boolean, string]\ntype B = Bar<['a', 'b'], [boolean]>; // [\"a\", \"b\", boolean, boolean]\n```\n\n使用新的可变参数元组，我们可以使用：\n\n* 元组类型语法中的扩展现在可以是通用的，因此即使我们不知道我们正在操作的实际类型，我们也可以表示元组和数组上的高阶操作\n* 其余元素可以出现在元组中的任何位置。\n\n例子：\n\n```typescript\ntype Items = readonly unknown[];\n\nfunction concat<T extends Items, U extends Items>(\n    arr1: T,\n    arr2: U\n): [...T, ...U] {\n    return [...arr1, ...arr2];\n}\n\nconcat([1, 2, 3], ['4', '5', '6']); // [1, 2, 3, \"4\", \"5\", \"6\"]\n```\n\n### 装箱类型\n\n装箱类型是指用于将基本类型表示为对象的包装对象。这些包装器对象提供了原始值无法直接使用的附加功能和方法。\n\n当你访问原始 `string` 上的 `charAt` 或者 `normalize` 方法时，JavaScript 将其包装在 `String` 类型的对象中，调用该方法，然后丢弃该对象\n\n示范：\n\n```typescript\nconst originalNormalize = String.prototype.normalize;\nString.prototype.normalize = function () {\n    console.log(this, typeof this);\n    return originalNormalize.call(this);\n};\nconsole.log('\\u0041'.normalize());\n```\n\nTypeScript 通过为原语及其相应的对象包装器提供单独的类型来表示这种区别：\n\n* string => String\n* number => Number\n* boolean => Boolean\n* symbol => Symbol\n* bigint => BigInt\n\n通常不需要盒装类型。避免使用装箱类型，而是使用基元类型，例如 `string` 代替 `String`。\n\n### TypeScript 中的协变和逆变\n\n协变和逆变用于描述在处理类型的继承或赋值时关系如何工作。\n\n协变意味着类型关系保留继承或赋值的方向，因此如果类型 A 是类型 B 的子类型，则类型 A 的数组也被视为类型 B 的数组的子类型。这里需要注意的重要事项是维持子类型关系，这意味着协变接受子类型但不接受超类型。\n\n逆变意味着类型关系颠倒了继承或赋值的方向，因此如果类型 A 是类型 B 的子类型，则类型 B 的数组被视为类型 A 数组的子类型。子类型关系颠倒了，这意味着该逆变接受超类型但不接受子类型。\n\n注意：双变量意味着同时接受超类型和子类型。\n\n示例：假设我们有一个适合所有动物的空间和一个专门适合狗的单独空间。\n\n在协方差中，您可以将所有狗放入动物空间中，因为狗是一种动物。但你不能把所有的动物都放在狗的空间里，因为可能还有其他动物混在一起。\n\n在逆变中，您不能将所有动物放入狗空间中，因为动物空间也可能包含其他动物。然而，你可以把所有的狗都放在动物空间里，因为所有的狗也是动物。\n\n<!-- skip -->\n```typescript\n// 协变示例\nclass Animal {\n    name: string;\n    constructor(name: string) {\n        this.name = name;\n    }\n}\n\nclass Dog extends Animal {\n    breed: string;\n    constructor(name: string, breed: string) {\n        super(name);\n        this.breed = breed;\n    }\n}\n\nlet animals: Animal[] = [];\nlet dogs: Dog[] = [];\n\n// 协变允许将子类型（狗）数组分配给超类型（动物）数组\nanimals = dogs;\ndogs = animals; // 无效: 'Animal[]' 不能赋值给 'Dog[]'\n\n// 逆变示例\ntype Feed<in T> = (animal: T) => void;\n\nlet feedAnimal: Feed<Animal> = (animal: Animal) => {\n    console.log(`Animal name: ${animal.name}`);\n};\n\nlet feedDog: Feed<Dog> = (dog: Dog) => {\n    console.log(`Dog name: ${dog.name}, Breed: ${dog.breed}`);\n};\n\n// 逆变允许将超类型（动物）回调赋值给子类型（狗）回调\nfeedDog = feedAnimal;\nfeedAnimal = feedDog; // 无效: Type 'Feed<Dog>' 不能赋值给 'Feed<Animal>'.\n```\n\n在 TypeScript 中，数组的类型关系是协变的，而函数参数的类型关系是逆变的。这意味着 TypeScript 同时表现出协变和逆变，具体取决于上下文。\n\n#### 类型参数的可选方差注释\n\n从 TypeScript 4.7.0 开始，我们可以使用out和in关键字来具体说明方差注释。\n\n对于协变，使用out关键字：\n\n```typescript\ntype AnimalCallback<out T> = () => T; // 此处 T 是协变的\n```\n\n对于逆变，使用in关键字：\n\n```typescript\ntype AnimalCallback<in T> = (value: T) => void; // 此处 T 是逆变的\n```\n\n### 模板字符串模式索引签名\n\n模板字符串模式索引签名允许我们使用模板字符串模式定义灵活的索引签名。 此功能使我们能够创建可以使用特定字符串键模式进行索引的对象，从而在访问和操作属性时提供更多控制和特异性。\n\nTypeScript 4.4 版开始允许符号和模板字符串模式的索引签名。\n\n```typescript\nconst uniqueSymbol = Symbol('description');\n\ntype MyKeys = `key-${string}`;\n\ntype MyObject = {\n    [uniqueSymbol]: string;\n    [key: MyKeys]: number;\n};\n\nconst obj: MyObject = {\n    [uniqueSymbol]: 'Unique symbol key',\n    'key-a': 123,\n    'key-b': 456,\n};\n\nconsole.log(obj[uniqueSymbol]); // Unique symbol key\nconsole.log(obj['key-a']); // 123\nconsole.log(obj['key-b']); // 456\n```\n\n### satisfies操作符\n\n`satisfies` 允许您检查给定类型是否满足特定接口或条件。换句话说，它确保类型具有特定接口所需的所有属性和方法。这是确保变量适合类型定义的一种方法。\n\n下面是一个示例：\n\n<!-- skip -->\n```typescript\ntype Columns = 'name' | 'nickName' | 'attributes';\n\ntype User = Record<Columns, string | string[] | undefined>;\n\n// `User`的类型注释\nconst user: User = {\n    name: 'Simone',\n    nickName: undefined,\n    attributes: ['dev', 'admin'],\n};\n\n// 在以下几行中，TypeScript 将无法正确推断\nuser.attributes?.map(console.log); // 'string | string[]' 中不存在属性 'map'。'string' 中不存在属性 'map'。\nuser.nickName; // string | string[] | undefined\n\n// 类型断言 `as`\nconst user2 = {\n    name: 'Simon',\n    nickName: undefined,\n    attributes: ['dev', 'admin'],\n} as User;\n\n// 这里也一样的， TypeScript 将无法正确推断\nuser2.attributes?.map(console.log); //'string | string[]' 中不存在属性 'map'。'string' 中不存在属性 'map'。\nuser2.nickName; // string | string[] | undefined\n\n// 使用\"satisfies\"运算符我们现在可以正确推断类型\nconst user3 = {\n    name: 'Simon',\n    nickName: undefined,\n    attributes: ['dev', 'admin'],\n} satisfies User;\n\nuser3.attributes?.map(console.log); // TypeScript 推断正确: string[]\nuser3.nickName; // TypeScript 推断正确: undefined\n```\n\n### 仅类型导入和导出\n\n仅类型导入和导出允许您导入或导出类型，而无需导入或导出与这些类型关联的值或函数。 这对于减小捆绑包的大小很有用。\n\n要使用仅类型导入，您可以使用`import type`关键字。\n\nTypeScript 允许在仅类型导入中使用声明和实现文件扩展名（.ts、.mts、.cts 和 .tsx），无论`allowImportingTsExtensions`设置如何。\n\n例如：\n\n<!-- skip -->\n```typescript\nimport type { House } from './house.ts';\n```\n\n以下是支持的形式：\n\n<!-- skip -->\n```typescript\nimport type T from './mod';\nimport type { A, B } from './mod';\nimport type * as Types from './mod';\nexport type { T };\nexport type { T } from './mod';\n```\n\n### 使用声明和显式资源管理\n\n\"using\"声明是块范围的、不可变的绑定，类似于\"const\"，用于管理一次性资源。 当使用值初始化时，该值的\"Symbol.dispose\"方法将被记录，并随后在退出封闭块作用域时执行。\n\n这是基于 ECMAScript 的资源管理功能，该功能对于在对象创建后执行基本的清理任务非常有用，例如关闭连接、删除文件和释放内存。\n\n笔记：\n\n* 由于最近在 TypeScript 5.2 版中引入，大多数运行时缺乏本机支持。 您将需要以下功能的填充：`Symbol.dispose`、`Symbol.asyncDispose`、`DisposableStack`、`AsyncDisposableStack`、`SuppressedError`。\n* 此外，您需要按如下方式配置 tsconfig.json：\n\n```json\n{\n    \"compilerOptions\": {\n        \"target\": \"es2022\",\n        \"lib\": [\"es2022\", \"esnext.disposable\", \"dom\"]\n    }\n}\n````\n\n例子：\n\n<!-- skip -->\n```typescript\n//@ts-ignore\nSymbol.dispose ??= Symbol('Symbol.dispose'); // 简单的兼容性填充\n\nconst doWork = (): Disposable => {\n    return {\n        [Symbol.dispose]: () => {\n            console.log('disposed');\n        },\n    };\n};\n\nconsole.log(1);\n\n{\n    using work = doWork(); // 资源被声明\n    console.log(2);\n} // 资源被释放 (例如, `work[Symbol.dispose]()` 被执行)\n\nconsole.log(3);\n```\n\n该代码将记录：\n\n```shell\n1\n2\ndisposed\n3\n```\n\n符合处置条件的资源必须遵守 `Disposable` 接口：\n\n```typescript\n// lib.esnext.disposable.d.ts\ninterface Disposable {\n    [Symbol.dispose](): void;\n}\n```\n\n\"using\"声明在堆栈中记录资源处置操作，确保它们以与声明相反的顺序处置：\n\n<!-- skip -->\n```typescript\n{\n    using j = getA(),\n        y = getB();\n    using k = getC();\n} // 先释放 `C`, 然后 `B`, 然后 `A`.\n```\n\n即使发生后续代码或异常，也保证会释放资源。 这可能会导致处置可能引发异常，并可能抑制另一个异常。 为了保留有关被抑制错误的信息，引入了一个新的本机异常\"SuppressedError\"。\n\n#### 使用声明等待\n\n\"await using\"声明处理异步一次性资源。 该值必须具有\"Symbol.asyncDispose\"方法，该方法将在块末尾等待。\n\n<!-- skip -->\n```typescript\nasync function doWorkAsync() {\n    await using work = doWorkAsync(); // 资源被声明\n} // // 资源被释放 (例如, `await work[Symbol.asyncDispose]()` 被执行)\n```\n\n对于异步可处置资源，它必须遵守\"Disposable\"或\"AsyncDisposable\"接口：\n\n```typescript\n// lib.esnext.disposable.d.ts\ninterface AsyncDisposable {\n    [Symbol.asyncDispose](): Promise<void>;\n}\n```\n\n<!-- skip -->\n```typescript\n//@ts-ignore\nSymbol.asyncDispose ??= Symbol('Symbol.asyncDispose'); // Simple polify\n\nclass DatabaseConnection implements AsyncDisposable {\n    // 当对象被异步释放时会被调用的方法\n    [Symbol.asyncDispose]() {\n        // Close the connection and return a promise\n        return this.close();\n    }\n\n    async close() {\n        console.log('Closing the connection...');\n        await new Promise(resolve => setTimeout(resolve, 1000));\n        console.log('Connection closed.');\n    }\n}\n\nasync function doWork() {\n    // 创建一个新的连接，并在其超出作用域时进行异步释放\n    await using connection = new DatabaseConnection(); // 资源被声明\n    console.log('Doing some work...');\n} // 资源被释放 (例如, `await connection[Symbol.asyncDispose]()` 被执行)\n\ndoWork();\n```\n\n代码日志：\n\n```shell\nDoing some work...\nClosing the connection...\nConnection closed.\n```\n\n语句中允许使用\"using\"和\"await using\"声明：\"for\"、\"for-in\"、\"for-of\"、\"for-await-of\"、\"switch\"。\n\n### 导入属性\n\nTypeScript 5.3 的导入属性（导入标签）告诉运行时如何处理模块（JSON 等）。这通过确保干净的导入来提高安全性，并与内容安全策略 (CSP) 保持一致，以实现更安全的资源加载。TypeScript 确保它们有效，但让运行时处理它们的解释以进行特定的模块处理。\n\n示例：\n\n<!-- skip -->\n```typescript\nimport config from './config.json' with { type: 'json' };\n```\n\n使用动态导入：\n\n<!-- skip -->\n```typescript\nconst config = import('./config.json', { with: { type: 'json' } });\n```\n"
  },
  {
    "path": "README.md",
    "content": "# The Concise TypeScript Book\n\nThe Concise TypeScript Book provides a comprehensive and succinct overview of TypeScript's capabilities. It offers clear explanations covering all aspects found in the latest version of the language, from its powerful type system to advanced features. Whether you're a beginner or an experienced developer, this book is an invaluable resource to enhance your understanding and proficiency in TypeScript.\n\nThis book is completely Free and Open Source.\n\nI believe that high-quality technical education should be accessible to everyone, which is why I keep this book free and open.\n\nIf the book helped you squash a bug, understand a tricky concept, or advance in your career, please consider supporting my work by paying what you want (suggested price: 15 USD) or sponsoring a coffee. Your support helps me keep the content up to date and expand it with new examples and deeper explanations.\n\n[![Buy Me a Coffee](https://img.shields.io/badge/buy_me_a_coffee-FFDD00?style=for-the-badge&logo=buy-me-a-coffee&logoColor=black)](https://www.buymeacoffee.com/simonepoggiali)\n\n[![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.com/donate/?business=QW82ZS956XLFY&no_recurring=0&currency_code=EUR)\n\n## Translations\n\nThis book has been translated into several language versions, including:\n\n[Chinese](https://github.com/gibbok/typescript-book/blob/main/README-zh_CN.md)\n\n[Italian](https://github.com/gibbok/typescript-book/blob/main/README-it_IT.md)\n\n[Portuguese (Brazil)](https://github.com/gibbok/typescript-book/blob/main/README-pt_BR.md)\n\n[Swedish](https://github.com/gibbok/typescript-book/blob/main/README-sv_SE.md)\n\n## Downloads and website\n\nYou can also download the Epub version:\n\n[https://github.com/gibbok/typescript-book/tree/main/downloads](https://github.com/gibbok/typescript-book/tree/main/downloads)\n\nAn online version is available at:\n\n[https://gibbok.github.io/typescript-book](https://gibbok.github.io/typescript-book)\n\n## Table of Contents\n\n<!-- markdownlint-disable MD004 -->\n- [The Concise TypeScript Book](#the-concise-typescript-book)\n  - [Translations](#translations)\n  - [Downloads and website](#downloads-and-website)\n  - [Table of Contents](#table-of-contents)\n  - [Introduction](#introduction)\n  - [About the Author](#about-the-author)\n  - [TypeScript Introduction](#typescript-introduction)\n    - [What is TypeScript?](#what-is-typescript)\n    - [Why TypeScript?](#why-typescript)\n    - [TypeScript and JavaScript](#typescript-and-javascript)\n    - [TypeScript Code Generation](#typescript-code-generation)\n    - [Modern JavaScript Now (Downleveling)](#modern-javascript-now-downleveling)\n  - [Getting Started With TypeScript](#getting-started-with-typescript)\n    - [Installation](#installation)\n    - [Configuration](#configuration)\n    - [TypeScript Configuration File](#typescript-configuration-file)\n      - [target](#target)\n      - [lib](#lib)\n      - [strict](#strict)\n      - [module](#module)\n      - [moduleResolution](#moduleresolution)\n      - [esModuleInterop](#esmoduleinterop)\n      - [jsx](#jsx)\n      - [skipLibCheck](#skiplibcheck)\n      - [files](#files)\n      - [include](#include)\n      - [exclude](#exclude)\n    - [importHelpers](#importhelpers)\n    - [Migration to TypeScript Advice](#migration-to-typescript-advice)\n  - [Exploring the Type System](#exploring-the-type-system)\n    - [The TypeScript Language Service](#the-typescript-language-service)\n    - [Structural Typing](#structural-typing)\n    - [TypeScript Fundamental Comparison Rules](#typescript-fundamental-comparison-rules)\n    - [Types as Sets](#types-as-sets)\n    - [Assign a type: Type Declarations and Type Assertions](#assign-a-type-type-declarations-and-type-assertions)\n      - [Type Declaration](#type-declaration)\n      - [Type Assertion](#type-assertion)\n      - [Ambient Declarations](#ambient-declarations)\n    - [Property Checking and Excess Property Checking](#property-checking-and-excess-property-checking)\n    - [Weak Types](#weak-types)\n    - [Strict Object Literal Checking (Freshness)](#strict-object-literal-checking-freshness)\n    - [Type Inference](#type-inference)\n    - [More Advanced Inferences](#more-advanced-inferences)\n    - [Type Widening](#type-widening)\n    - [Const](#const)\n      - [Const Modifier on Type Parameters](#const-modifier-on-type-parameters)\n      - [Const assertion](#const-assertion)\n    - [Explicit Type Annotation](#explicit-type-annotation)\n    - [Type Narrowing](#type-narrowing)\n      - [Conditions](#conditions)\n      - [Throwing or returning](#throwing-or-returning)\n      - [Discriminated Union](#discriminated-union)\n      - [User-Defined Type Guards](#user-defined-type-guards)\n  - [Primitive Types](#primitive-types)\n    - [string](#string)\n    - [boolean](#boolean)\n    - [number](#number)\n    - [bigInt](#bigint)\n    - [Symbol](#symbol)\n    - [null and undefined](#null-and-undefined)\n    - [Array](#array)\n    - [any](#any)\n  - [Type Annotations](#type-annotations)\n  - [Optional Properties](#optional-properties)\n  - [Readonly Properties](#readonly-properties)\n  - [Index Signatures](#index-signatures)\n  - [Extending Types](#extending-types)\n  - [Literal Types](#literal-types)\n  - [Literal Inference](#literal-inference)\n  - [strictNullChecks](#strictnullchecks)\n  - [Enums](#enums)\n    - [Numeric enums](#numeric-enums)\n    - [String enums](#string-enums)\n    - [Constant enums](#constant-enums)\n    - [Reverse mapping](#reverse-mapping)\n    - [Ambient enums](#ambient-enums)\n    - [Computed and constant members](#computed-and-constant-members)\n  - [Narrowing](#narrowing)\n    - [typeof type guards](#typeof-type-guards)\n    - [Truthiness narrowing](#truthiness-narrowing)\n    - [Equality narrowing](#equality-narrowing)\n    - [In Operator narrowing](#in-operator-narrowing)\n    - [instanceof narrowing](#instanceof-narrowing)\n  - [Assignments](#assignments)\n  - [Control Flow Analysis](#control-flow-analysis)\n  - [Type Predicates](#type-predicates)\n  - [Discriminated Unions](#discriminated-unions)\n  - [The never Type](#the-never-type)\n  - [Exhaustiveness checking](#exhaustiveness-checking)\n  - [Object Types](#object-types)\n  - [Tuple Type (Anonymous)](#tuple-type-anonymous)\n  - [Named Tuple Type (Labeled)](#named-tuple-type-labeled)\n  - [Fixed Length Tuple](#fixed-length-tuple)\n  - [Union Type](#union-type)\n  - [Intersection Types](#intersection-types)\n  - [Type Indexing](#type-indexing)\n  - [Type from Value](#type-from-value)\n  - [Type from Func Return](#type-from-func-return)\n  - [Type from Module](#type-from-module)\n  - [Mapped Types](#mapped-types)\n  - [Mapped Type Modifiers](#mapped-type-modifiers)\n  - [Conditional Types](#conditional-types)\n  - [Distributive Conditional Types](#distributive-conditional-types)\n  - [infer Type Inference in Conditional Types](#infer-type-inference-in-conditional-types)\n  - [Predefined Conditional Types](#predefined-conditional-types)\n  - [Template Union Types](#template-union-types)\n  - [Any type](#any-type)\n  - [Unknown type](#unknown-type)\n  - [Void type](#void-type)\n  - [Never type](#never-type)\n  - [Interface and Type](#interface-and-type)\n    - [Common Syntax](#common-syntax)\n    - [Basic Types](#basic-types)\n    - [Objects and Interfaces](#objects-and-interfaces)\n    - [Union and Intersection Types](#union-and-intersection-types)\n  - [Built-in Type Primitives](#built-in-type-primitives)\n  - [Common Built-in JS Objects](#common-built-in-js-objects)\n  - [Overloads](#overloads)\n  - [Merging and Extension](#merging-and-extension)\n  - [Differences between Type and Interface](#differences-between-type-and-interface)\n  - [Class](#class)\n    - [Class Common Syntax](#class-common-syntax)\n    - [Constructor](#constructor)\n    - [Private and Protected Constructors](#private-and-protected-constructors)\n    - [Access Modifiers](#access-modifiers)\n    - [Get and Set](#get-and-set)\n    - [Auto-Accessors in Classes](#auto-accessors-in-classes)\n    - [this](#this)\n    - [Parameter Properties](#parameter-properties)\n    - [Abstract Classes](#abstract-classes)\n    - [With Generics](#with-generics)\n    - [Decorators](#decorators)\n      - [Class Decorators](#class-decorators)\n      - [Property Decorator](#property-decorator)\n      - [Method Decorator](#method-decorator)\n      - [Getter and Setter Decorators](#getter-and-setter-decorators)\n      - [Decorator Metadata](#decorator-metadata)\n    - [Inheritance](#inheritance)\n    - [Statics](#statics)\n    - [Property initialization](#property-initialization)\n    - [Method overloading](#method-overloading)\n  - [Generics](#generics)\n    - [Generic Type](#generic-type)\n    - [Generic Classes](#generic-classes)\n    - [Generic Constraints](#generic-constraints)\n    - [Generic contextual narrowing](#generic-contextual-narrowing)\n  - [Erased Structural Types](#erased-structural-types)\n  - [Namespacing](#namespacing)\n  - [Symbols](#symbols)\n  - [Triple-Slash Directives](#triple-slash-directives)\n  - [Type Manipulation](#type-manipulation)\n    - [Creating Types from Types](#creating-types-from-types)\n    - [Indexed Access Types](#indexed-access-types)\n    - [Utility Types](#utility-types)\n      - [Awaited\\<T\\>](#awaitedt)\n      - [Partial\\<T\\>](#partialt)\n      - [Required\\<T\\>](#requiredt)\n      - [Readonly\\<T\\>](#readonlyt)\n      - [Record\\<K, T\\>](#recordk-t)\n      - [Pick\\<T, K\\>](#pickt-k)\n      - [Omit\\<T, K\\>](#omitt-k)\n      - [Exclude\\<T, U\\>](#excludet-u)\n      - [Extract\\<T, U\\>](#extractt-u)\n      - [NonNullable\\<T\\>](#nonnullablet)\n      - [Parameters\\<T\\>](#parameterst)\n      - [ConstructorParameters\\<T\\>](#constructorparameterst)\n      - [ReturnType\\<T\\>](#returntypet)\n      - [InstanceType\\<T\\>](#instancetypet)\n      - [ThisParameterType\\<T\\>](#thisparametertypet)\n      - [OmitThisParameter\\<T\\>](#omitthisparametert)\n      - [ThisType\\<T\\>](#thistypet)\n      - [Uppercase\\<T\\>](#uppercaset)\n      - [Lowercase\\<T\\>](#lowercaset)\n      - [Capitalize\\<T\\>](#capitalizet)\n      - [Uncapitalize\\<T\\>](#uncapitalizet)\n      - [NoInfer\\<T\\>](#noinfert)\n  - [Others](#others)\n    - [Errors and Exception Handling](#errors-and-exception-handling)\n    - [Mixin classes](#mixin-classes)\n    - [Asynchronous Language Features](#asynchronous-language-features)\n    - [Iterators and Generators](#iterators-and-generators)\n    - [TsDocs JSDoc Reference](#tsdocs-jsdoc-reference)\n    - [@types](#types)\n    - [JSX](#jsx-1)\n    - [ES6 Modules](#es6-modules)\n    - [ES7 Exponentiation Operator](#es7-exponentiation-operator)\n    - [The for-await-of Statement](#the-for-await-of-statement)\n    - [New target meta-property](#new-target-meta-property)\n    - [Dynamic Import Expressions](#dynamic-import-expressions)\n    - [\"tsc –watch\"](#tsc-watch)\n    - [Non-null Assertion Operator](#non-null-assertion-operator)\n    - [Defaulted declarations](#defaulted-declarations)\n    - [Optional Chaining](#optional-chaining)\n    - [Nullish coalescing operator](#nullish-coalescing-operator)\n    - [Template Literal Types](#template-literal-types)\n    - [Function overloading](#function-overloading)\n    - [Recursive Types](#recursive-types)\n    - [Recursive Conditional Types](#recursive-conditional-types)\n    - [ECMAScript Module Support in Node](#ecmascript-module-support-in-node)\n    - [Assertion Functions](#assertion-functions)\n    - [Variadic Tuple Types](#variadic-tuple-types)\n    - [Boxed types](#boxed-types)\n    - [Covariance and Contravariance in TypeScript](#covariance-and-contravariance-in-typescript)\n      - [Optional Variance Annotations for Type Parameters](#optional-variance-annotations-for-type-parameters)\n    - [Template String Pattern Index Signatures](#template-string-pattern-index-signatures)\n    - [The satisfies Operator](#the-satisfies-operator)\n    - [Type-Only Imports and Export](#type-only-imports-and-export)\n    - [using declaration and Explicit Resource Management](#using-declaration-and-explicit-resource-management)\n      - [await using declaration](#await-using-declaration)\n    - [Import Attributes](#import-attributes)\n<!-- markdownlint-enable MD004 -->\n\n## Introduction\n\nWelcome to The Concise TypeScript Book! This guide equips you with essential knowledge and practical skills for effective TypeScript development. Discover key concepts and techniques to write clean, robust code. Whether you're a beginner or an experienced developer, this book serves as both a comprehensive guide and a handy reference for leveraging TypeScript's power in your projects.\n\nThis book covers TypeScript 5.2.\n\n## About the Author\n\nSimone Poggiali is an experienced Staff Engineer with a passion for writing professional-grade code since the 90s. Throughout his international career, he has contributed to numerous projects for a wide range of clients, from startups to large organizations. Notable companies such as HelloFresh, Siemens, O2, Leroy Merlin and Snowplow have benefited from his expertise and dedication.\n\nYou can reach Simone Poggiali on the following platforms:\n\n* LinkedIn: [https://www.linkedin.com/in/simone-poggiali](https://www.linkedin.com/in/simone-poggiali)\n* GitHub: [https://github.com/gibbok](https://github.com/gibbok)\n* X.com: [https://x.com/gibbok_coding](https://x.com/gibbok_coding)\n* Email: gibbok.coding📧gmail.com\n\nFull list of contributors: [https://github.com/gibbok/typescript-book/graphs/contributors](https://github.com/gibbok/typescript-book/graphs/contributors)\n\n## TypeScript Introduction\n\n### What is TypeScript?\n\nTypeScript is a strongly typed programming language that builds on JavaScript. It was originally designed by Anders Hejlsberg in 2012 and is currently developed and maintained by Microsoft as an open source project.\n\nTypeScript compiles to JavaScript and can be executed in any JavaScript runtime (e.g., a browser or Node.js on a server).\n\nIt supports multiple programming paradigms such as functional, generic, imperative, and object-oriented programming, and is a compiled (transpiled) language that is converted into JavaScript before execution.\n\n### Why TypeScript?\n\nTypeScript is a strongly typed language that helps prevent common programming mistakes and avoid certain kinds of run-time errors before the program is executed.\n\nA strongly typed language allows the developer to specify various program constraints and behaviors in the data type definitions, facilitating the ability to verify the correctness of the software and prevent defects. This is especially valuable in large-scale applications.\n\nSome of the benefits of TypeScript:\n\n* Static typing, optionally strongly typed\n* Type Inference\n* Access to ES6 and ES7 features\n* Cross-Platform and Cross-browser Compatibility\n* Tooling support with IntelliSense\n\n### TypeScript and JavaScript\n\nTypeScript is written in `.ts` or `.tsx` files, while JavaScript files are written in `.js` or `.jsx`.\n\nFiles with the extension `.tsx` or `.jsx` can contain JavaScript Syntax Extension JSX, which is used in React for UI development.\n\nTypeScript is a typed superset of JavaScript (ECMAScript 2015) in terms of syntax. All JavaScript code is valid TypeScript code, but the reverse is not always true.\n\nFor instance, consider a function in a JavaScript file with the `.js` extension, such as the following:\n\n<!-- skip -->\n```typescript\nconst sum = (a, b) => a + b;\n```\n\nThe function can be converted and used in TypeScript by changing the file extension to `.ts`. However, if the same function is annotated with TypeScript types, it cannot be executed in any JavaScript runtime without compilation. The following TypeScript code will produce a syntax error if it is not compiled:\n\n<!-- skip -->\n```typescript\nconst sum = (a: number, b: number): number => a + b;\n```\n\nTypeScript was designed to detect possible exceptions that can occur at runtime during compilation time by having the developer define the intent with type annotations. In addition, TypeScript can also catch issues if no type annotation is provided. For instance, the following code snippet does not specify any TypeScript types:\n\n<!-- skip -->\n```typescript\nconst items = [{ x: 1 }, { x: 2 }];\nconst result = items.filter(item => item.y);\n```\n\nIn this case, TypeScript detects an error and reports:\n\n```text\nProperty 'y' does not exist on type '{ x: number; }'.\n```\n\nTypeScript's type system is largely influenced by the runtime behavior of JavaScript. For example, the addition operator (+), which in JavaScript can either perform string concatenation or numeric addition, is modeled in the same way in TypeScript:\n\n```typescript\nconst result = '1' + 1; // Result is of type string\n```\n\nThe team behind TypeScript has made a deliberate decision to flag unusual usage of JavaScript as errors. For instance, consider the following valid JavaScript code:\n\n<!-- skip -->\n```typescript\nconst result = 1 + true; // In JavaScript, the result is equal 2\n```\n\nHowever, TypeScript throws an error:\n\n```text\nOperator '+' cannot be applied to types 'number' and 'boolean'.\n```\n\nThis error occurs because TypeScript strictly enforces type compatibility, and in this case, it identifies an invalid operation between a number and a boolean.\n\n### TypeScript Code Generation\n\nThe TypeScript compiler has two main responsibilities: checking for type errors and compiling to JavaScript. These two processes are independent of each other. Types do not affect the execution of the code in a JavaScript runtime, as they are completely erased during compilation. TypeScript can still output JavaScript even in the presence of type errors.\nHere is an example of TypeScript code with a type error:\n\n<!-- skip -->\n```typescript\nconst add = (a: number, b: number): number => a + b;\nconst result = add('x', 'y'); // Argument of type 'string' is not assignable to parameter of type 'number'.\n```\n\nHowever, it can still produce executable JavaScript output:\n\n<!-- skip -->\n```typescript\n'use strict';\nconst add = (a, b) => a + b;\nconst result = add('x', 'y'); // xy\n```\n\nIt is not possible to check TypeScript types at runtime. For example:\n\n<!-- skip -->\n```typescript\ninterface Animal {\n    name: string;\n}\ninterface Dog extends Animal {\n    bark: () => void;\n}\ninterface Cat extends Animal {\n    meow: () => void;\n}\nconst makeNoise = (animal: Animal) => {\n    if (animal instanceof Dog) {\n        // 'Dog' only refers to a type, but is being used as a value here.\n        // ...\n    }\n};\n```\n\nAs the types are erased after compilation, there is no way to run this code in JavaScript. To recognize types at runtime, we need to use another mechanism. TypeScript provides several options, with a common one being \"tagged union\". For example:\n\n```typescript\ninterface Dog {\n    kind: 'dog'; // Tagged union\n    bark: () => void;\n}\ninterface Cat {\n    kind: 'cat'; // Tagged union\n    meow: () => void;\n}\ntype Animal = Dog | Cat;\n\nconst makeNoise = (animal: Animal) => {\n    if (animal.kind === 'dog') {\n        animal.bark();\n    } else {\n        animal.meow();\n    }\n};\n\nconst dog: Dog = {\n    kind: 'dog',\n    bark: () => console.log('bark'),\n};\nmakeNoise(dog);\n```\n\nThe property \"kind\" is a value that can be used at runtime to distinguish between objects in JavaScript.\n\nIt is also possible for a value at runtime to have a type different from the one declared in the type declaration. For instance, if the developer has misinterpreted an API type and annotated it incorrectly.\n\nTypeScript is a superset of JavaScript, so the \"class\" keyword can be used as a type and value at runtime.\n\n```typescript\nclass Animal {\n    constructor(public name: string) {}\n}\nclass Dog extends Animal {\n    constructor(\n        public name: string,\n        public bark: () => void\n    ) {\n        super(name);\n    }\n}\nclass Cat extends Animal {\n    constructor(\n        public name: string,\n        public meow: () => void\n    ) {\n        super(name);\n    }\n}\ntype Mammal = Dog | Cat;\n\nconst makeNoise = (mammal: Mammal) => {\n    if (mammal instanceof Dog) {\n        mammal.bark();\n    } else {\n        mammal.meow();\n    }\n};\n\nconst dog = new Dog('Fido', () => console.log('bark'));\nmakeNoise(dog);\n```\n\nIn JavaScript, a \"class\" has a \"prototype\" property, and the \"instanceof\" operator can be used to test if the prototype property of a constructor appears anywhere in the prototype chain of an object.\n\nTypeScript has no effect on runtime performance, as all types will be erased. However, TypeScript does introduce some build time overhead.\n\n### Modern JavaScript Now (Downleveling)\n\nTypeScript can compile code to any released version of JavaScript since ECMAScript 3 (1999). This means that TypeScript can transpile code from the latest JavaScript features to older versions, a process known as Downleveling. This allows the usage of modern JavaScript while maintaining maximum compatibility with older runtime environments.\n\nIt's important to note that during transpilation to an older version of JavaScript, TypeScript may generate code that could incur a performance overhead compared to native implementations.\n\nHere are some of the modern JavaScript features that can be used in TypeScript:\n\n* ECMAScript modules instead of AMD-style \"define\" callbacks or CommonJS \"require\" statements.\n* Classes instead of prototypes.\n* Variables declaration using \"let\" or \"const\" instead of \"var\".\n* \"for-of\" loop or \".forEach\" instead of the traditional \"for\" loop.\n* Arrow functions instead of function expressions.\n* Destructuring assignment.\n* Shorthand property/method names and computed property names.\n* Default function parameters.\n\nBy leveraging these modern JavaScript features, developers can write more expressive and concise code in TypeScript.\n\n## Getting Started With TypeScript\n\n### Installation\n\nVisual Studio Code provides excellent support for the TypeScript language but does not include the TypeScript compiler. To install the TypeScript compiler, you can use a package manager like npm or yarn:\n\n```shell\nnpm install typescript --save-dev\n```\n\nor\n\n```shell\nyarn add typescript --dev\n```\n\nMake sure to commit the generated lockfile to ensure that every team member uses the same version of TypeScript.\n\nTo run the TypeScript compiler, you can use the following commands\n\n```shell\nnpx tsc\n```\n\nor\n\n```shell\nyarn tsc\n```\n\nIt is recommended to install TypeScript project-wise rather than globally, as it provides a more predictable build process. However, for one-off occasions, you can use the following command:\n\n```shell\nnpx tsc\n```\n\nor installing it globally:\n\n```shell\nnpm install -g typescript\n```\n\nIf you are using Microsoft Visual Studio, you can obtain TypeScript as a package in NuGet for your MSBuild projects. In the NuGet Package Manager Console, run the following command:\n\n```shell\nInstall-Package Microsoft.TypeScript.MSBuild\n```\n\nDuring the TypeScript installation, two executables are installed: \"tsc\" as the TypeScript compiler and \"tsserver\" as the TypeScript standalone server. The standalone server contains the compiler and language services that can be utilized by editors and IDEs to provide intelligent code completion.\n\nAdditionally, there are several TypeScript-compatible transpilers available, such as Babel (via a plugin) or swc. These transpilers can be used to convert TypeScript code into other target languages or versions.\n\n### Configuration\n\nTypeScript can be configured using the tsc CLI options or by utilizing a dedicated configuration file called tsconfig.json placed in the root of the project.\n\nTo generate a tsconfig.json file prepopulated with recommended settings, you can use the following command:\n\n```shell\ntsc --init\n```\n\nWhen executing the `tsc` command locally, TypeScript will compile the code using the configuration specified in the nearest tsconfig.json file.\n\nHere are some examples of CLI commands that run with the default settings:\n\n```shell\ntsc main.ts // Compile a specific file (main.ts) to JavaScript\ntsc src/*.ts // Compile any .ts files under the 'src' folder to JavaScript\ntsc app.ts util.ts --outfile index.js // Compile two TypeScript files (app.ts and util.ts) into a single JavaScript file (index.js)\n```\n\n### TypeScript Configuration File\n\nA tsconfig.json file is used to configure the TypeScript Compiler (tsc). Usually, it is added to the root of the project, together with the `package.json` file.\n\nNotes:\n\n* tsconfig.json accepts comments even if it is in json format.\n* It is advisable to use this configuration file instead of the command-line options.\n\nAt the following link you can find the complete documentation and its schema:\n\n[https://www.typescriptlang.org/tsconfig](https://www.typescriptlang.org/tsconfig)\n\n[https://www.typescriptlang.org/tsconfig/](https://www.typescriptlang.org/tsconfig/)\n\nThe following represents a list of the common and useful configurations:\n\n#### target\n\nThe \"target\" property is used to specify which version of JavaScript ECMAScript version your TypeScript should emit/compile into. For modern browsers ES6 is a good option, for older browsers, ES5 is recommended.\n\n#### lib\n\nThe \"lib\" property is used to specify which library files to include at compilation time. TypeScript automatically includes APIs for features specified in the \"target\" property, but it is possible to omit or pick specific libraries for particular needs. For instance, if you are working on a server project, you could exclude the \"DOM\" library, which is useful only in a browser environment.\n\n#### strict\n\nThe \"strict\" property enables stronger guarantees and enhances type safety. It is advisable to always include this property in your project's tsconfig.json file. Enabling the \"strict\" property allows TypeScript to:\n\n* Emit code using \"use strict\" for each source file.\n* Consider \"null\" and \"undefined\" in the type checking process.\n* Disable the usage of the \"any\" type when no type annotations are present.\n* Raise an error on the usage of the \"this\" expression, which would otherwise imply the \"any\" type.\n\n#### module\n\nThe \"module\" property sets the module system supported for the compiled program. During runtime, a module loader is used to locate and execute dependencies based on the specified module system.\n\nThe most common module loaders used in JavaScript are Node.js CommonJS for server-side applications and RequireJS for AMD modules in browser-based web applications. TypeScript can emit code for various module systems, including UMD, System, ESNext, ES2015/ES6, and ES2020.\n\nNote: The module system should be chosen based on the target environment and the module loading mechanism available in that environment.\n\n#### moduleResolution\n\nThe \"moduleResolution\" property specifies the module resolution strategy. Use \"node\" for modern TypeScript code, the \"classic\" strategy is used only for old versions of TypeScript (before 1.6).\n\n#### esModuleInterop\n\nThe \"esModuleInterop\" property allows import default from CommonJS modules that did not export using the \"default\" property, this property provides a shim to ensure compatibility in the emitted JavaScript. After enabling this option we can use `import MyLibrary from \"my-library\"` instead of `import * as MyLibrary from \"my-library\"`.\n\n#### jsx\n\nThe \"jsx\" property applies only to .tsx files used in ReactJS and controls how JSX constructs are compiled into JavaScript. A common option is \"preserve\" which will compile to a .jsx file keeping unchanged the JSX so it can be passed to different tools like Babel for further transformations.\n\n#### skipLibCheck\n\nThe \"skipLibCheck'' property will prevent TypeScript from type-checking the entire imported third-party packages. This property will reduce the compile time of a project. TypeScript will still check your code against the type definitions provided by these packages.\n\n#### files\n\nThe \"files\" property indicates to the compiler a list of files that must always be included in the program.\n\n#### include\n\n<!-- markdownlint-disable MD049 -->\nThe \"include\" property indicates to the compiler a list of files that we would like to include. This property allows glob-like patterns, such as \"\\*_\" for any subdirectory, \"_\" for any file name, and \"?\" for optional characters.\n<!-- markdownlint-enable MD049 -->\n\n#### exclude\n\nThe \"exclude\" property indicates to the compiler a list of files that should not be included in the compilation. This can include files such as \"node_modules\" or test files.\nNote: tsconfig.json allows comments.\n\n### importHelpers\n\nTypeScript uses helper code when generating code for certain advanced or down-leveled JavaScript features. By default, these helpers are duplicated in files using them. The `importHelpers` option imports these helpers from the `tslib` module instead, making the JavaScript output more efficient.\n\n### Migration to TypeScript Advice\n\nFor large projects, it is recommended to adopt a gradual transition where TypeScript and JavaScript code will initially coexist. Only small projects can be migrated to TypeScript in one go.\n\nThe first step of this transition is to introduce TypeScript into the build chain process. This can be done by using the \"allowJs\" compiler option, which permits .ts and .tsx files to coexist with existing JavaScript files. As TypeScript will fall back to a type of \"any\" for a variable when it cannot infer the type from JavaScript files, it is recommended to disable \"noImplicitAny\" in your compiler options at the beginning of the migration.\n\nThe second step is to ensure that your JavaScript tests work alongside TypeScript files so that you can run tests as you convert each module. If you are using Jest, consider using `ts-jest`, which allows you to test TypeScript projects with Jest.\n\nThe third step is to include type declarations for third-party libraries in your project. These declarations can be found either bundled or on DefinitelyTyped. You can search for them using [https://www.typescriptlang.org/dt/search](https://www.typescriptlang.org/dt/search) and install them using:\n\n```shell\nnpm install --save-dev @types/package-name\n```\n\nor\n\n```shell\nyarn add --dev @types/package-name\n```\n\nThe fourth step is to migrate module by module with a bottom-up approach, following your Dependency Graph starting with the leaves. The idea is to start converting Modules that do not depend on other Modules. To visualize the dependency graphs, you can use the \"madge\" tool.\n\nGood candidate modules for these initial conversions are utility functions and code related to external APIs or specifications. It is possible to automatically generate TypeScript type definitions from Swagger contracts, GraphQL or JSON schemas to be included in your project.\n\nWhen there are no specifications or official schemas available, you can generate types from raw data, such as JSON returned by a server. However, it is recommended to generate types from specifications instead of data to avoid missing edge cases.\n\nDuring the migration, refrain from code refactoring and focus only on adding types to your modules.\n\nThe fifth step is to enable \"noImplicitAny,\" which will enforce that all types are known and defined, providing a better TypeScript experience for your project.\n\nDuring the migration, you can use the `@ts-check` directive, which enables TypeScript type checking in a JavaScript file. This directive provides a loose version of type checking and can be initially used to identify issues in JavaScript files. When `@ts-check` is included in a file, TypeScript will try to deduce definitions using JSDoc-style comments. However, consider using JSDoc annotations only at a very early stage of the migration.\n\nConsider keeping the default value of `noEmitOnError` in your tsconfig.json as false. This will allow you to output JavaScript source code even if errors are reported.\n\n## Exploring the Type System\n\n### The TypeScript Language Service\n\nThe TypeScript Language Service, also known as tsserver, offers various features such as error reporting, diagnostics, compile-on-save, renaming, go to definition, completion lists, signature help, and more. It is primarily used by integrated development environments (IDEs) to provide IntelliSense support. It seamlessly integrates with Visual Studio Code and is utilized by tools like Conquer of Completion (Coc).\n\nDevelopers can leverage a dedicated API and create their own custom language service plugins to enhance the TypeScript editing experience. This can be particularly useful for implementing special linting features or enabling auto-completion for a custom templating language.\n\n<!-- markdownlint-disable MD044 -->\nAn example of a real-world custom plugin is \"typescript-styled-plugin\", which provides syntax error reporting and IntelliSense support for CSS properties in styled components.\n<!-- markdownlint-enable MD044 -->\n\nFor more information and quick start guides, you can refer to the official TypeScript Wiki on GitHub: [https://github.com/microsoft/TypeScript/wiki/](https://github.com/microsoft/TypeScript/wiki/)\n\n### Structural Typing\n\nTypeScript is based on a structural type system. This means that the compatibility and equivalence of types are determined by the type's actual structure or definition, rather than its name or place of declaration, as in nominative type systems like C# or C.\n\nTypeScript's structural type system was designed based on how JavaScript's dynamic duck typing system works during runtime.\n\nThe following example is valid TypeScript code. As you can observe, \"X\" and \"Y\" have the same member \"a,\" even though they have different declaration names. The types are determined by their structures, and in this case, since the structures are the same, they are compatible and valid.\n\n```typescript\ntype X = {\n    a: string;\n};\ntype Y = {\n    a: string;\n};\nconst x: X = { a: 'a' };\nconst y: Y = x; // Valid\n```\n\n### TypeScript Fundamental Comparison Rules\n\nThe TypeScript comparison process is recursive and executed on types nested at any level.\n\nA type \"X\" is compatible with \"Y\" if \"Y\" has at least the same members as \"X\".\n\n```typescript\ntype X = {\n    a: string;\n};\nconst y = { a: 'A', b: 'B' }; // Valid, as it has at least the same members as X\nconst r: X = y;\n```\n\nFunction parameters are compared by types, not by their names:\n\n```typescript\ntype X = (a: number) => void;\ntype Y = (a: number) => void;\nlet x: X = (j: number) => undefined;\nlet y: Y = (k: number) => undefined;\ny = x; // Valid\nx = y; // Valid\n```\n\nFunction return types must be the same:\n\n<!-- skip -->\n```typescript\ntype X = (a: number) => undefined;\ntype Y = (a: number) => number;\nlet x: X = (a: number) => undefined;\nlet y: Y = (a: number) => 1;\ny = x; // Invalid\nx = y; // Invalid\n```\n\nThe return type of a source function must be a subtype of the return type of a target function:\n\n<!-- skip -->\n```typescript\nlet x = () => ({ a: 'A' });\nlet y = () => ({ a: 'A', b: 'B' });\nx = y; // Valid\ny = x; // Invalid member b is missing\n```\n\nDiscarding function parameters is allowed, as it is a common practice in JavaScript, for instance using \"Array.prototype.map()\":\n\n```typescript\n[1, 2, 3].map((element, _index, _array) => element + 'x');\n```\n\nTherefore, the following type declarations are completely valid:\n\n```typescript\ntype X = (a: number) => undefined;\ntype Y = (a: number, b: number) => undefined;\nlet x: X = (a: number) => undefined;\nlet y: Y = (a: number) => undefined; // Missing b parameter\ny = x; // Valid\n```\n\nAny additional optional parameters of the source type are valid:\n\n```typescript\ntype X = (a: number, b?: number, c?: number) => undefined;\ntype Y = (a: number) => undefined;\nlet x: X = a => undefined;\nlet y: Y = a => undefined;\ny = x; // Valid\nx = y; //Valid\n```\n\nAny optional parameters of the target type without corresponding parameters in the source type are valid and not an error:\n\n```typescript\ntype X = (a: number) => undefined;\ntype Y = (a: number, b?: number) => undefined;\nlet x: X = a => undefined;\nlet y: Y = a => undefined;\ny = x; // Valid\nx = y; // Valid\n```\n\nThe rest parameter is treated as an infinite series of optional parameters:\n\n```typescript\ntype X = (a: number, ...rest: number[]) => undefined;\nlet x: X = a => undefined; //valid\n```\n\nFunctions with overloads are valid if the overload signature is compatible with its implementation signature:\n\n<!-- skip -->\n```typescript\nfunction x(a: string): void;\nfunction x(a: string, b: number): void;\nfunction x(a: string, b?: number): void {\n    console.log(a, b);\n}\nx('a'); // Valid\nx('a', 1); // Valid\n\nfunction y(a: string): void; // Invalid, not compatible with implementation signature\nfunction y(a: string, b: number): void;\nfunction y(a: string, b: number): void {\n    console.log(a, b);\n}\ny('a');\ny('a', 1);\n```\n\nFunction parameter comparison succeeds if the source and target parameters are assignable to supertypes or subtypes (bivariance).\n\n```typescript\n// Supertype\nclass X {\n    a: string;\n    constructor(value: string) {\n        this.a = value;\n    }\n}\n// Subtype\nclass Y extends X {}\n// Subtype\nclass Z extends X {}\n\ntype GetA = (x: X) => string;\nconst getA: GetA = x => x.a;\n\n// Bivariance does accept supertypes\nconsole.log(getA(new X('x'))); // Valid\nconsole.log(getA(new Y('Y'))); // Valid\nconsole.log(getA(new Z('z'))); // Valid\n```\n\nEnums are comparable and valid with numbers and vice versa, but comparing Enum values from different Enum types is invalid.\n\n<!-- skip -->\n```typescript\nenum X {\n    A,\n    B,\n}\nenum Y {\n    A,\n    B,\n    C,\n}\nconst xa: number = X.A; // Valid\nconst ya: Y = 0; // Valid\nX.A === Y.A; // Invalid\n```\n\nInstances of a class are subject to a compatibility check for their private and protected members:\n\n<!-- skip -->\n```typescript\nclass X {\n    public a: string;\n    constructor(value: string) {\n        this.a = value;\n    }\n}\n\nclass Y {\n    private a: string;\n    constructor(value: string) {\n        this.a = value;\n    }\n}\n\nlet x: X = new Y('y'); // Invalid\n```\n\nThe comparison check does not take into consideration the different inheritance hierarchy, for instance:\n\n```typescript\nclass X {\n    public a: string;\n    constructor(value: string) {\n        this.a = value;\n    }\n}\nclass Y extends X {\n    public a: string;\n    constructor(value: string) {\n        super(value);\n        this.a = value;\n    }\n}\nclass Z {\n    public a: string;\n    constructor(value: string) {\n        this.a = value;\n    }\n}\nlet x: X = new X('x');\nlet y: Y = new Y('y');\nlet z: Z = new Z('z');\nx === y; // Valid\nx === z; // Valid even if z is from a different inheritance hierarchy\n```\n\nGenerics are compared using their structures based on the resulting type after applying the generic parameter, only the final result is compared as a non-generic type.\n\n<!-- skip -->\n```typescript\ninterface X<T> {\n    a: T;\n}\nlet x: X<number> = { a: 1 };\nlet y: X<string> = { a: 'a' };\nx === y; // Invalid as the type argument is used in the final structure\n```\n\n```typescript\ninterface X<T> {}\nconst x: X<number> = 1;\nconst y: X<string> = 'a';\nx === y; // Valid as the type argument is not used in the final structure\n```\n\nWhen generics do not have their type argument specified, all the unspecified arguments are treated as types with \"any\":\n\n```typescript\ntype X = <T>(x: T) => T;\ntype Y = <K>(y: K) => K;\nlet x: X = x => x;\nlet y: Y = y => y;\nx = y; // Valid\n```\n\nRemember:\n\n<!-- skip -->\n```typescript\nlet a: number = 1;\nlet b: number = 2;\na = b; // Valid, everything is assignable to itself\n\nlet c: any;\nc = 1; // Valid, all types are assignable to any\n\nlet d: unknown;\nd = 1; // Valid, all types are assignable to unknown\n\nlet e: unknown;\nlet e1: unknown = e; // Valid, unknown is only assignable to itself and any\nlet e2: any = e; // Valid\nlet e3: number = e; // Invalid\n\nlet f: never;\nf = 1; // Invalid, nothing is assignable to never\n\nlet g: void;\nlet g1: any;\ng = 1; // Invalid, void is not assignable to or from anything expect any\ng = g1; // Valid\n```\n\nPlease note that when \"strictNullChecks\" is enabled, \"null\" and \"undefined\" are treated similarly to \"void\"; otherwise, they are similar to \"never\".\n\n### Types as Sets\n\nIn TypeScript, a type is a set of possible values. This set is also referred to as the domain of the type. Each value of a type can be viewed as an element in a set. A type establishes the constraints that every element in the set must satisfy to be considered a member of that set.\nThe primary task of TypeScript is to check and verify whether one set is a subset of another.\n\nTypeScript supports various types of sets:\n\n| Set term           | TypeScript                      | Notes                                                                                                              |\n| ------------------ | ------------------------------- | ------------------------------------------------------------------------------------------------------------------ |\n| Empty set          | never                           | \"never\" contains anything apart itself                                                                             |\n| Single element set | undefined / null / literal type |                                                                                                                    |\n| Finite set         | boolean / union                 |                                                                                                                    |\n| Infinite set       | string / number / object        |                                                                                                                    |\n| Universal set      | any / unknown                   | Every element is a member of \"any\" and every set is a subset of it / \"unknown\" is a type-safe counterpart of \"any\" |\n\nHere few examples:\n\n| TypeScript            | Set term               | Example                                                                         |\n| --------------------- | ---------------------- | ------------------------------------------------------------------------------- |\n| never                 | ∅ (empty set)          | const x: never = 'x'; // Error: Type 'string' is not assignable to type 'never' |\n|                       |                        |\n| Literal type          | Single element set     | type X = 'X';                                                                   |\n|                       |                        | type Y = 7;                                                                     |\n|                       |                        |\n| Value assignable to T | Value ∈ T (member of)  | type XY = 'X' \\| 'Y';                                                           |\n|                       |                        | const x: XY = 'X';                                                              |\n|                       |                        |\n| T1 assignable to T2   | T1 ⊆ T2 (subset of)    | type XY = 'X' \\| 'Y';                                                           |\n|                       |                        | const x: XY = 'X';                                                              |\n|                       |                        | const j: XY = 'J'; // Type '\"J\"' is not assignable to type 'XY'.                |\n|                       |                        |                                                                                 |\n| T1 extends T2         | T1 ⊆ T2 (subset of)    | type X = 'X' extends string ? true : false;                                     |\n|                       |                        |\n| T1 \\| T2              | T1 ∪ T2 (union)        | type XY = 'X' \\| 'Y';                                                           |\n|                       |                        | type JK = 1 \\| 2;                                                               |\n|                       |                        |\n| T1 & T2               | T1 ∩ T2 (intersection) | type X = \\{ a: string \\}                                                          |\n|                       |                        | type Y = \\{ b: string \\}                                                          |\n|                       |                        | type XY = X & Y                                                                 |\n|                       |                        | const x: XY = \\{ a: 'a', b: 'b' \\}                                                |\n|                       |                        |\n| unknown               | Universal set          | const x: unknown = 1                                                            |\n\nAn union, (T1 | T2) creates a wider set (both):\n\n```typescript\ntype X = {\n    a: string;\n};\ntype Y = {\n    b: string;\n};\ntype XY = X | Y;\nconst r: XY = { a: 'a', b: 'x' }; // Valid\n```\n\nAn intersection, (T1 & T2) create a narrower set (only shared):\n\n<!-- skip -->\n```typescript\ntype X = {\n    a: string;\n};\ntype Y = {\n    a: string;\n    b: string;\n};\ntype XY = X & Y;\nconst r: XY = { a: 'a' }; // Invalid\nconst j: XY = { a: 'a', b: 'b' }; // Valid\n```\n\nThe `extends` keyword could be considered as a \"subset of\" in this context. It sets a constraint for a type. The extends used with a generic, take the generic as an infinite set and it will constrain it to a more specific type.\nPlease note that `extends` has nothing to do with hierarchy in a OOP sense (there is no this concept in TypeScript).\nTypeScript works with sets and does not have a strict hierarchy, infact, as in the example below, two types could overlap without either being a subtype of the other type (TypeScript considers the structure, shape of the objects).\n\n```typescript\ninterface X {\n    a: string;\n}\ninterface Y extends X {\n    b: string;\n}\ninterface Z extends Y {\n    c: string;\n}\nconst z: Z = { a: 'a', b: 'b', c: 'c' };\ninterface X1 {\n    a: string;\n}\ninterface Y1 {\n    a: string;\n    b: string;\n}\ninterface Z1 {\n    a: string;\n    b: string;\n    c: string;\n}\nconst z1: Z1 = { a: 'a', b: 'b', c: 'c' };\n\nconst r: Z1 = z; // Valid\n```\n\n### Assign a type: Type Declarations and Type Assertions\n\nA type can be assigned in different ways in TypeScript:\n\n#### Type Declaration\n\nIn the following example, we use x: X (\": Type\") to declare a type for the variable x.\n\n```typescript\ntype X = {\n    a: string;\n};\n\n// Type declaration\nconst x: X = {\n    a: 'a',\n};\n```\n\nIf the variable is not in the specified format, TypeScript will report an error. For instance:\n\n<!-- skip -->\n```typescript\ntype X = {\n    a: string;\n};\n\nconst x: X = {\n    a: 'a',\n    b: 'b', // Error: Object literal may only specify known properties\n};\n```\n\n#### Type Assertion\n\nIt is possible to add an assertion by using the `as` keyword. This tells the compiler that the developer has more information about a type and silences any errors that may occur.\n\nFor example:\n\n```typescript\ntype X = {\n    a: string;\n};\nconst x = {\n    a: 'a',\n    b: 'b',\n} as X;\n```\n\nIn the above example, the object x is asserted to have the type X using the as keyword. This informs the TypeScript compiler that the object conforms to the specified type, even though it has an additional property b not present in the type definition.\n\nType assertions are useful in situations where a more specific type needs to be specified, especially when working with the DOM. For instance:\n\n```typescript\nconst myInput = document.getElementById('my_input') as HTMLInputElement;\n```\n\nHere, the type assertion as HTMLInputElement is used to tell TypeScript that the result of getElementById should be treated as an HTMLInputElement.\nType assertions can also be used to remap keys, as shown in the example below with template literals:\n\n```typescript\ntype J<Type> = {\n    [Property in keyof Type as `prefix_${string &\n        Property}`]: () => Type[Property];\n};\ntype X = {\n    a: string;\n    b: number;\n};\ntype Y = J<X>;\n```\n\nIn this example, the type `J<Type>` uses a mapped type with a template literal to remap the keys of Type. It creates new properties with a \"prefix_\" added to each key, and their corresponding values are functions returning the original property values.\n\nIt is worth noting that when using a type assertion, TypeScript will not execute excess property checking. Therefore, it is generally preferable to use a Type Declaration when the structure of the object is known in advance.\n\n#### Ambient Declarations\n\nAmbient declarations are files that describe types for JavaScript code, they have a file name format as `.d.ts.`. They are usually imported and used to annotate existing JavaScript libraries or to add types to existing JS files in your project.\n\nMany common libraries types can be found at:\n[https://github.com/DefinitelyTyped/DefinitelyTyped/](https://github.com/DefinitelyTyped/DefinitelyTyped/)\n\nand can be installed using:\n\n```shell\nnpm install --save-dev @types/library-name\n```\n\nFor your defined Ambient Declarations, you can import using the \"triple-slash\" reference:\n\n<!-- skip -->\n```typescript\n/// <reference path=\"./library-types.d.ts\" />\n```\n\nYou can use Ambient Declarations even within JavaScript files using `// @ts-check`.\n\nThe `declare` keyword enables type definitions for existing JavaScript code without importing it, serving as a placeholder for types from another file or globally.\n\n### Property Checking and Excess Property Checking\n\nTypeScript is based on a structural type system but excess property checking is a property of TypeScript which allows it to check whether an object has the exact properties specified in the type.\n\nExcess Property Checking is performed when assigning object literals to variables or when passing them as arguments to the function's excess property, for instance.\n\n<!-- skip -->\n```typescript\ntype X = {\n    a: string;\n};\nconst y = { a: 'a', b: 'b' };\nconst x: X = y; // Valid because structural typing\nconst w: X = { a: 'a', b: 'b' }; // Invalid because excess property checking\n```\n\n### Weak Types\n\nA type is considered weak when it contains nothing but a set of all-optional properties:\n\n```typescript\ntype X = {\n    a?: string;\n    b?: string;\n};\n```\n\nTypeScript considers an error to assign anything to a weak type when there is no overlap, for instance, the following throws an error:\n\n<!-- skip -->\n```typescript\ntype Options = {\n    a?: string;\n    b?: string;\n};\n\nconst fn = (options: Options) => undefined;\n\nfn({ c: 'c' }); // Invalid\n```\n\nAlthough not recommended, if needed, it is possible to bypass this check by using type assertion:\n\n```typescript\ntype Options = {\n    a?: string;\n    b?: string;\n};\nconst fn = (options: Options) => undefined;\nfn({ c: 'c' } as Options); // Valid\n```\n\nOr by adding `unknown` to the index signature to the weak type:\n\n```typescript\ntype Options = {\n    [prop: string]: unknown;\n    a?: string;\n    b?: string;\n};\n\nconst fn = (options: Options) => undefined;\nfn({ c: 'c' }); // Valid\n```\n\n### Strict Object Literal Checking (Freshness)\n\nStrict object literal checking, sometimes referred to as \"freshness\", is a feature in TypeScript that helps catch excess or misspelled properties that would otherwise go unnoticed in normal structural type checks.\n\nWhen creating an object literal, the TypeScript compiler considers it \"fresh.\" If the object literal is assigned to a variable or passed as a parameter, TypeScript will throw an error if the object literal specifies properties that do not exist in the target type.\n\nHowever, \"freshness\" disappears when an object literal is widened or a type assertion is used.\n\nHere are some examples to illustrate:\n\n<!-- skip -->\n```typescript\ntype X = { a: string };\ntype Y = { a: string; b: string };\n\nlet x: X;\nx = { a: 'a', b: 'b' }; // Freshness check: Invalid assignment\nvar y: Y;\ny = { a: 'a', bx: 'bx' }; // Freshness check: Invalid assignment\n\nconst fn = (x: X) => console.log(x.a);\n\nfn(x);\nfn(y); // Widening: No errors, structurally type compatible\n\nfn({ a: 'a', bx: 'b' }); // Freshness check: Invalid argument\n\nlet c: X = { a: 'a' };\nlet d: Y = { a: 'a', b: '' };\nc = d; // Widening: No Freshness check\n```\n\n### Type Inference\n\nTypeScript can infer types when no annotation is provided during:\n\n* Variable initialization.\n* Member initialization.\n* Setting defaults for parameters.\n* Function return type.\n\nFor example:\n\n```typescript\nlet x = 'x'; // The type inferred is string\n```\n\nThe TypeScript compiler analyzes the value or expression and determines its type based on the available information.\n\n### More Advanced Inferences\n\nWhen multiple expressions are used in type inference, TypeScript looks for the \"best common types.\" For instance:\n\n```typescript\nlet x = [1, 'x', 1, null]; // The type inferred is: (string | number | null)[]\n```\n\nIf the compiler cannot find the best common types, it returns a union type. For example:\n\n```typescript\nlet x = [new RegExp('x'), new Date()]; // Type inferred is: (RegExp | Date)[]\n```\n\nTypeScript utilizes \"contextual typing\" based on the variable's location to infer types. In the following example, the compiler knows that `e` is of type `MouseEvent` because of the `click` event type defined in the lib.d.ts file, which contains ambient declarations for various common JavaScript constructs and the DOM:\n\n```typescript\nwindow.addEventListener('click', function (e) {}); // The inferred type of e is MouseEvent\n```\n\n### Type Widening\n\nType widening is the process in which TypeScript assigns a type to a variable initialized when no type annotation was provided. It allows narrow to wider types but not vice versa.\nIn the following example:\n\n<!-- skip -->\n```typescript\nlet x = 'x'; // TypeScript infers as string, a wide type\nlet y: 'y' | 'x' = 'y'; // y types is a union of literal types\ny = x; // Invalid Type 'string' is not assignable to type '\"x\" | \"y\"'.\n```\n\nTypeScript assigns `string` to `x` based on the single value provided during initialization (`x`), this is an example of widening.\n\nTypeScript provides ways to have control of the widening process, for instance using \"const\".\n\n### Const\n\nUsing the `const` keyword when declaring a variable results in a narrower type inference in TypeScript.\n\nFor example:\n\n```typescript\nconst x = 'x'; // TypeScript infers the type of x as 'x', a narrower type\nlet y: 'y' | 'x' = 'y';\ny = x; // Valid: The type of x is inferred as 'x'\n```\n\nBy using `const` to declare the variable x, its type is narrowed to the specific literal value 'x'. Since the type of x is narrowed, it can be assigned to the variable y without any error.\nThe reason the type can be inferred is because `const` variables cannot be reassigned, so their type can be narrowed down to a specific literal type, in this case, the literal type 'x'.\n\n#### Const Modifier on Type Parameters\n\nFrom version 5.0 of TypeScript, it is possible to specify the `const` attribute on a generic type parameter. This allows for inferring the most precise type possible. Let's see an example without using `const`:\n\n```typescript\nfunction identity<T>(value: T) {\n    // No const here\n    return value;\n}\nconst values = identity({ a: 'a', b: 'b' }); // Type infered is: { a: string; b: string; }\n```\n\nAs you can see, the properties `a` and `b` are inferred with a type of `string`   .\n\nNow, let's see the difference with the `const` version:\n\n```typescript\nfunction identity<const T>(value: T) {\n    // Using const modifier on type parameters\n    return value;\n}\nconst values = identity({ a: 'a', b: 'b' }); // Type infered is: { a: \"a\"; b: \"b\"; }\n```\n\nNow we can see that the properties `a` and `b` are inferred as `const`, so `a` and `b` are treated as string literals rather than just `string` types.\n\n#### Const assertion\n\nThis feature allows you to declare a variable with a more precise literal type based on its initialization value, signifying to the compiler that the value should be treated as an immutable literal. Here are a few examples:\n\nOn a single property:\n\n```typescript\nconst v = {\n    x: 3 as const,\n};\nv.x = 3;\n```\n\nOn an entire object:\n\n```typescript\nconst v = {\n    x: 1,\n    y: 2,\n} as const;\n```\n\nThis can be particularly useful when defining the type for a tuple:\n\n```typescript\nconst x = [1, 2, 3]; // number[]\nconst y = [1, 2, 3] as const; // Tuple of readonly [1, 2, 3]\n```\n\n### Explicit Type Annotation\n\nWe can be specific and pass a type, in the following example property `x` is of type `number`:\n\n```typescript\nconst v = {\n    x: 1, // Inferred type: number (widening)\n};\nv.x = 3; // Valid\n```\n\nWe can make the type annotation more specific by using a union of literal types:\n\n<!-- skip -->\n```typescript\nconst v: { x: 1 | 2 | 3 } = {\n    x: 1, // x is now a union of literal types: 1 | 2 | 3\n};\nv.x = 3; // Valid\nv.x = 100; // Invalid\n```\n\n### Type Narrowing\n\nType Narrowing is the process in TypeScript where a general type is narrowed down to a more specific type. This occurs when TypeScript analyzes the code and determines that certain conditions or operations can refine the type information.\n\nNarrowing types can occur in different ways, including:\n\n#### Conditions\n\nBy using conditional statements, such as `if` or `switch`, TypeScript can narrow down the type based on the outcome of the condition. For example:\n\n```typescript\nlet x: number | undefined = 10;\n\nif (x !== undefined) {\n    x += 100; // The type is number, which had been narrowed by the condition\n}\n```\n\n#### Throwing or returning\n\nThrowing an error or returning early from a branch can be used to help TypeScript narrow down a type. For example:\n\n```typescript\nlet x: number | undefined = 10;\n\nif (x === undefined) {\n    throw 'error';\n}\nx += 100;\n```\n\nOther ways to narrow down types in TypeScript include:\n\n* `instanceof` operator: Used to check if an object is an instance of a specific class.\n* `in` operator: Used to check if a property exists in an object.\n* `typeof` operator: Used to check the type of a value at runtime.\n* Built-in functions like `Array.isArray()`: Used to check if a value is an array.\n\n#### Discriminated Union\n\nUsing a \"Discriminated Union\" is a pattern in TypeScript where an explicit \"tag\" is added to objects to distinguish between different types within a union. This pattern is also referred to as a \"tagged union.\" In the following example, the \"tag\" is represented by the property \"type\":\n\n```typescript\ntype A = { type: 'type_a'; value: number };\ntype B = { type: 'type_b'; value: string };\n\nconst x = (input: A | B): string | number => {\n    switch (input.type) {\n        case 'type_a':\n            return input.value + 100; // type is A\n        case 'type_b':\n            return input.value + 'extra'; // type is B\n    }\n};\n```\n\n#### User-Defined Type Guards\n\nIn cases where TypeScript is unable to determine a type, it is possible to write a helper function known as a \"user-defined type guard.\" In the following example, we will utilize a Type Predicate to narrow down the type after applying certain filtering:\n\n```typescript\nconst data = ['a', null, 'c', 'd', null, 'f'];\n\nconst r1 = data.filter(x => x != null); // The type is (string | null)[], TypeScript was not able to infer the type properly\n\nconst isValid = (item: string | null): item is string => item !== null; // Custom type guard\n\nconst r2 = data.filter(isValid); // The type is fine now string[], by using the predicate type guard we were able to narrow the type\n```\n\n## Primitive Types\n\nTypeScript supports 7 primitive types. A primitive data type refers to a type that is not an object and does not have any methods associated with it. In TypeScript, all primitive types are immutable, meaning their values cannot be changed once they are assigned.\n\n### string\n\nThe `string` primitive type stores textual data, and the value is always double or single-quoted.\n\n```typescript\nconst x: string = 'x';\nconst y: string = 'y';\n```\n\nStrings can span multiple lines if surrounded by the backtick (`) character:\n\n```typescript\nlet sentence: string = `xxx,\n   yyy`;\n```\n\n### boolean\n\nThe `boolean` data type in TypeScript stores a binary value, either `true` or `false`.\n\n```typescript\nconst isReady: boolean = true;\n```\n\n### number\n\nA `number` data type in TypeScript is represented with a 64-bit floating point value. A `number` type can represent integers and fractions.\nTypeScript also supports hexadecimal, binary, and octal, for instance:\n\n```typescript\nconst decimal: number = 10;\nconst hexadecimal: number = 0xa00d; // Hexadecimal starts with 0x\nconst binary: number = 0b1010; // Binary starts with 0b\nconst octal: number = 0o633; // Octal starts with 0o\n```\n\n### bigInt\n\nA `bigInt` represents numeric values that are very large (253 – 1) and cannot be represented with a `number`.\n\nA `bigInt` can be created by calling the built-in function `BigInt()` or by adding `n` to the end of any integer numeric literal:\n\n```typescript\nconst x: bigint = BigInt(9007199254740991);\nconst y: bigint = 9007199254740991n;\n```\n\nNotes:\n\n* `bigInt` values cannot be mixed with `number` and cannot be used with built-in `Math`, they must be coerced to the same type.\n* `bigInt` values are available only if target configuration is ES2020 or higher.\n\n### Symbol\n\nSymbols are unique identifiers that can be used as property keys in objects to prevent naming conflicts.\n\n```typescript\ntype Obj = {\n    [sym: symbol]: number;\n};\n\nconst a = Symbol('a');\nconst b = Symbol('b');\nlet obj: Obj = {};\nobj[a] = 123;\nobj[b] = 456;\n\nconsole.log(obj[a]); // 123\nconsole.log(obj[b]); // 456\n```\n\n### null and undefined\n\n`null` and `undefined` types both represent no value or the absence of any value.\n\nThe `undefined` type means the value is not assigned or initialized or indicates an unintentional absence of value.\n\nThe `null` type means that we know that the field does not have a value, so value is unavailable, it indicates an intentional absence of value.\n\n### Array\n\nAn `array` is a data type that can store multiple values of the same type or not. It can be defined using the following syntax:\n\n```typescript\nconst x: string[] = ['a', 'b'];\nconst y: Array<string> = ['a', 'b'];\nconst j: Array<string | number> = ['a', 1, 'b', 2]; // Union\n```\n\nTypeScript supports readonly arrays using the following syntax:\n\n<!-- skip -->\n```typescript\nconst x: readonly string[] = ['a', 'b']; // Readonly modifier\nconst y: ReadonlyArray<string> = ['a', 'b'];\nconst j: ReadonlyArray<string | number> = ['a', 1, 'b', 2];\nj.push('x'); // Invalid\n```\n\nTypeScript supports tuple and readonly tuple:\n\n```typescript\nconst x: [string, number] = ['a', 1];\nconst y: readonly [string, number] = ['a', 1];\n```\n\n### any\n\nThe `any` data type represents literally \"any\" value, it is the default value when TypeScript cannot infer the type or is not specified.\n\nWhen using `any` TypeScript compiler skips the type checking so there is no type safety when `any` is being used. Generally do not use `any` to silence the compiler when an error occurs, instead focus on fixing the error as with using `any`  it is possible to break contracts and we lose the benefits of TypeScript autocomplete.\n\nThe `any` type could be useful during a gradual migration from JavaScript to TypeScript, as it can silence the compiler.\n\nFor new projects use TypeScript configuration `noImplicitAny` which enables TypeScript to issue errors where `any` is used or inferred.\n\nThe `any`type  is usually a source of errors which can mask real problems with your types. Avoid using it as much as possible.\n\n## Type Annotations\n\nOn variables declared using `var`, `let` and `const`, it is possible to optionally add a type:\n\n```typescript\nconst x: number = 1;\n```\n\nTypeScript does a good job of inferring types, especially when simple one, so these declarations in most cases are not necessary.\n\nOn functions is possible to add type annotations to parameters:\n\n```typescript\nfunction sum(a: number, b: number) {\n    return a + b;\n}\n```\n\nThe following is an example using a anonymous functions (so called lambda function):\n\n```typescript\nconst sum = (a: number, b: number) => a + b;\n```\n\nThese annotation can be avoided when a default value for a parameter is present:\n\n```typescript\nconst sum = (a = 10, b: number) => a + b;\n```\n\nReturn type annotations can be added to functions:\n\n```typescript\nconst sum = (a = 10, b: number): number => a + b;\n```\n\nThis is useful especially for  more complex functions as writing expliciting the return type before an implementation can help better think about the function.\n\nGenerally consider annotating type signatures but not the body local variables and add types always to object literals.\n\n## Optional Properties\n\nAn object can specify Optional Properties by adding a question mark `?` to the end of the property name:\n\n```typescript\ntype X = {\n    a: number;\n    b?: number; // Optional\n};\n```\n\nIt is possible to specify a default value when a property is optional:\n\n```typescript\ntype X = {\n    a: number;\n    b?: number;\n};\nconst x = ({ a, b = 100 }: X) => a + b;\n```\n\n## Readonly Properties\n\nIs it possible to prevent writing on a property by using the modifier `readonly`which  makes sure that the property cannot be re-written but does not provide any guarantee of total immutability:\n\n```typescript\ninterface Y {\n    readonly a: number;\n}\n\ntype X = {\n    readonly a: number;\n};\n\ntype J = Readonly<{\n    a: number;\n}>;\n\ntype K = {\n    readonly [index: number]: string;\n};\n```\n\n## Index Signatures\n\nIn TypeScript we can use as index signature `string`, `number`, and `symbol`:\n\n```typescript\ntype K = {\n    [name: string | number]: string;\n};\nconst k: K = { x: 'x', 1: 'b' };\nconsole.log(k['x']);\nconsole.log(k[1]);\nconsole.log(k['1']); // Same result as k[1]\n```\n\nPlease note that JavaScript automatically converts an index with `number` to an index with `string` so `k[1]` or `k[\"1\"]` return the same value.\n\n## Extending Types\n\nIt is possible to extend an `interface` (copy members from another type):\n\n```typescript\ninterface X {\n    a: string;\n}\ninterface Y extends X {\n    b: string;\n}\n```\n\nIt is also possible to extend from multiple types:\n\n```typescript\ninterface A {\n    a: string;\n}\ninterface B {\n    b: string;\n}\ninterface Y extends A, B {\n    y: string;\n}\n```\n\nThe `extends` keyword works only on interfaces and classes, for types use an intersection:\n\n```typescript\ntype A = {\n    a: number;\n};\ntype B = {\n    b: number;\n};\ntype C = A & B;\n```\n\nIt is possible to extend a type using an inference but not vice versa:\n\n```typescript\ntype A = {\n    a: string;\n};\ninterface B extends A {\n    b: string;\n}\n```\n\n## Literal Types\n\nA Literal Type is a single element set from a collective type, it defines a very exact value that is a JavaScript primitive.\n\nLiteral Types in TypeScript are numbers, strings, and booleans.\n\nExample of literals:\n\n```typescript\nconst a = 'a'; // String literal type\nconst b = 1; // Numeric literal type\nconst c = true; // Boolean literal type\n```\n\nString, Numeric, and Boolean Literal Types are used in unions, type guards, and type aliases.\nIn the following example, you can see a union type alias. `O` consists of only the specified values, no other string is valid:\n\n```typescript\ntype O = 'a' | 'b' | 'c';\n```\n\n## Literal Inference\n\nLiteral Inference is a feature in TypeScript that allows the type of a variable or parameter to be inferred based on its value.\n\nIn the following example we can see that TypeScript considers `x` a literal type as the value cannot be changed any time later, when instead `y` is inferred as string as it can be modified any time later.\n\n```typescript\nconst x = 'x'; // Literal type of 'x', because this value cannot be changed\nlet y = 'y'; // Type string, as we can change this value\n```\n\nIn the following example we can see that `o.x` was inferred as a `string` (and not a literal of `a`) as TypeScript considers that the value can be changed any time later.\n\n<!-- skip -->\n```typescript\ntype X = 'a' | 'b';\n\nlet o = {\n    x: 'a', // This is a wider string\n};\n\nconst fn = (x: X) => `${x}-foo`;\n\nconsole.log(fn(o.x)); // Argument of type 'string' is not assignable to parameter of type 'X'\n```\n\nAs you can see the code throws an error when passing `o.x` to `fn` as X is a narrower type.\n\nWe can solve this issue by using type assertion using `const` or the `X` type:\n\n<!-- skip -->\n```typescript\nlet o = {\n    x: 'a' as const,\n};\n```\n\nor:\n\n<!-- skip -->\n```typescript\nlet o = {\n    x: 'a' as X,\n};\n```\n\n## strictNullChecks\n\n`strictNullChecks` is a TypeScript compiler option that enforces strict null checking. When this option is enabled, variables and parameters can only be assigned `null` or `undefined` if they have been explicitly declared to be of that type using the union type `null` | `undefined`. If a variable or parameter is not explicitly declared as nullable, TypeScript will generate an error to prevent potential runtime errors.\n\n## Enums\n\nIn TypeScript, an `enum` is a set of named constant values.\n\n```typescript\nenum Color {\n    Red = '#ff0000',\n    Green = '#00ff00',\n    Blue = '#0000ff',\n}\n```\n\nEnums can be defined in different ways:\n\n### Numeric enums\n\nIn TypeScript, a Numeric Enum is an Enum where each constant is assigned a numeric value, starting from 0 by default.\n\n```typescript\nenum Size {\n    Small, // value starts from 0\n    Medium,\n    Large,\n}\n```\n\nIt is possible to specify custom values by explicitly assigning them:\n\n```typescript\nenum Size {\n    Small = 10,\n    Medium,\n    Large,\n}\nconsole.log(Size.Medium); // 11\n```\n\n### String enums\n\nIn TypeScript, a String enum is an Enum where each constant is assigned a string value.\n\n```typescript\nenum Language {\n    English = 'EN',\n    Spanish = 'ES',\n}\n```\n\nNote: TypeScript allows the usage of heterogeneous Enums where string and numeric members can coexist.\n\n### Constant enums\n\nA constant enum in TypeScript is a special type of Enum where all the values are known at compile time and are inlined wherever the enum is used, resulting in more efficient code.\n\n```typescript\nconst enum Language {\n    English = 'EN',\n    Spanish = 'ES',\n}\nconsole.log(Language.English);\n```\n\nWill be compiled into:\n\n```typescript\nconsole.log('EN' /* Language.English */);\n```\n\nNotes:\nConst Enums have hardcoded values, erasing the Enum, which can be more efficient in self-contained libraries but is generally not desirable. Also, Const enums cannot have computed members.\n\n### Reverse mapping\n\nIn TypeScript, reverse mappings in Enums refer to the ability to retrieve the Enum member name from its value. By default, Enum members have forward mappings from name to value, but reverse mappings can be created by explicitly setting values for each member. Reverse mappings are useful when you need to look up an Enum member by its value, or when you need to iterate over all the Enum members. Note that only numeric enums members will generate reverse mappings, while String Enum members do not get a reverse mapping generated at all.\n\nThe following enum:\n\n```typescript\nenum Grade {\n    A = 90,\n    B = 80,\n    C = 70,\n    F = 'fail',\n}\n```\n\nCompiles to:\n\n<!-- skip -->\n```javascript\n'use strict';\nvar Grade;\n(function (Grade) {\n    Grade[(Grade['A'] = 90)] = 'A';\n    Grade[(Grade['B'] = 80)] = 'B';\n    Grade[(Grade['C'] = 70)] = 'C';\n    Grade['F'] = 'fail';\n})(Grade || (Grade = {}));\n```\n\nTherefore, mapping values to keys works for numeric enum members, but not for string enum members:\n\n<!-- skip -->\n```typescript\nenum Grade {\n    A = 90,\n    B = 80,\n    C = 70,\n    F = 'fail',\n}\nconst myGrade = Grade.A;\nconsole.log(Grade[myGrade]); // A\nconsole.log(Grade[90]); // A\n\nconst failGrade = Grade.F;\nconsole.log(failGrade); // fail\nconsole.log(Grade[failGrade]); // Element implicitly has an 'any' type because index expression is not of type 'number'.\n```\n\n### Ambient enums\n\nAn ambient enum in TypeScript is a type of Enum that is defined in a declaration file (*.d.ts) without an associated implementation. It allows you to define a set of named constants that can be used in a type-safe way across different files without having to import the implementation details in each file.\n\n### Computed and constant members\n\nIn TypeScript, a computed member is a member of an Enum that has a value calculated at runtime, while a constant member is a member whose value is set at compile-time and cannot be changed during runtime. Computed members are allowed in regular Enums, while constant members are allowed in both regular and const enums.\n\n```typescript\n// Constant members\nenum Color {\n    Red = 1,\n    Green = 5,\n    Blue = Red + Green,\n}\nconsole.log(Color.Blue); // 6 generation at compilation time\n```\n\n```typescript\n// Computed members\nenum Color {\n    Red = 1,\n    Green = Math.pow(2, 2),\n    Blue = Math.floor(Math.random() * 3) + 1,\n}\nconsole.log(Color.Blue); // random number generated at run time\n```\n\nEnums are denoted by unions comprising their member types. The values of each member can be determined through constant or non-constant expressions, with members possessing constant values being assigned literal types. To illustrate, consider the declaration of type E and its subtypes E.A, E.B, and E.C. In this case, E represents the union E.A | E.B | E.C.\n\n```typescript\nconst identity = (value: number) => value;\n\nenum E {\n    A = 2 * 5, // Numeric literal\n    B = 'bar', // String literal\n    C = identity(42), // Opaque computed\n}\n\nconsole.log(E.C); //42\n```\n\n## Narrowing\n\nTypeScript narrowing is the process of refining the type of a variable within a conditional block. This is useful when working with union types, where a variable can have more than one type.\n\nTypeScript recognizes several ways to narrow the type:\n\n### typeof type guards\n\nThe typeof type guard is one specific type guard in TypeScript that checks the type of a variable based on its built-in JavaScript type.\n\n```typescript\nconst fn = (x: number | string) => {\n    if (typeof x === 'number') {\n        return x + 1; // x is number\n    }\n    return -1;\n};\n```\n\n### Truthiness narrowing\n\nTruthiness narrowing in TypeScript works by checking whether a variable is truthy or falsy to narrow its type accordingly.\n\n```typescript\nconst toUpperCase = (name: string | null) => {\n    if (name) {\n        return name.toUpperCase();\n    } else {\n        return null;\n    }\n};\n```\n\n### Equality narrowing\n\nEquality narrowing in TypeScript works by checking whether a variable is equal to a specific value or not, to narrow its type accordingly.\n\nIt is used in conjunction with `switch` statements and equality operators such as `===`, `!==`, `==`, and `!=` to narrow down types.\n\n```typescript\nconst checkStatus = (status: 'success' | 'error') => {\n    switch (status) {\n        case 'success':\n            return true;\n        case 'error':\n            return null;\n    }\n};\n```\n\n### In Operator narrowing\n\nThe `in` Operator narrowing in TypeScript is a way to narrow the type of a variable based on whether a property exists within the variable's type.\n\n```typescript\ntype Dog = {\n    name: string;\n    breed: string;\n};\n\ntype Cat = {\n    name: string;\n    likesCream: boolean;\n};\n\nconst getAnimalType = (pet: Dog | Cat) => {\n    if ('breed' in pet) {\n        return 'dog';\n    } else {\n        return 'cat';\n    }\n};\n```\n\n### instanceof narrowing\n\nThe `instanceof` operator narrowing in TypeScript is a way to narrow the type of a variable based on its constructor function, by checking if an object is an instance of a certain class or interface.\n\n```typescript\nclass Square {\n    constructor(public width: number) {}\n}\nclass Rectangle {\n    constructor(\n        public width: number,\n        public height: number\n    ) {}\n}\nfunction area(shape: Square | Rectangle) {\n    if (shape instanceof Square) {\n        return shape.width * shape.width;\n    } else {\n        return shape.width * shape.height;\n    }\n}\nconst square = new Square(5);\nconst rectangle = new Rectangle(5, 10);\nconsole.log(area(square)); // 25\nconsole.log(area(rectangle)); // 50\n```\n\n## Assignments\n\nTypeScript narrowing using assignments is a way to narrow the type of a variable based on the value assigned to it. When a variable is assigned a value, TypeScript infers its type based on the assigned value, and it narrows the type of the variable to match the inferred type.\n\n```typescript\nlet value: string | number;\nvalue = 'hello';\nif (typeof value === 'string') {\n    console.log(value.toUpperCase());\n}\nvalue = 42;\nif (typeof value === 'number') {\n    console.log(value.toFixed(2));\n}\n```\n\n## Control Flow Analysis\n\nControl Flow Analysis in TypeScript is a way to statically analyze the code flow to infer the types of variables, allowing the compiler to narrow the types of those variables as needed, based on the results of the analysis.\n\nPrior to TypeScript 4.4, code flow analysis would only be applied to code within an if statement, but from TypeScript 4.4, it can also be applied to conditional expressions and discriminant property accesses indirectly referenced through const variables.\n\nFor example:\n\n```typescript\nconst f1 = (x: unknown) => {\n    const isString = typeof x === 'string';\n    if (isString) {\n        x.length;\n    }\n};\n\nconst f2 = (\n    obj: { kind: 'foo'; foo: string } | { kind: 'bar'; bar: number }\n) => {\n    const isFoo = obj.kind === 'foo';\n    if (isFoo) {\n        obj.foo;\n    } else {\n        obj.bar;\n    }\n};\n```\n\nSome examples where narrowing does not occur:\n\n<!-- skip -->\n```typescript\nconst f1 = (x: unknown) => {\n    let isString = typeof x === 'string';\n    if (isString) {\n        x.length; // Error, no narrowing because isString it is not const\n    }\n};\n\nconst f6 = (\n    obj: { kind: 'foo'; foo: string } | { kind: 'bar'; bar: number }\n) => {\n    const isFoo = obj.kind === 'foo';\n    obj = obj;\n    if (isFoo) {\n        obj.foo; // Error, no narrowing because obj is assigned in function body\n    }\n};\n```\n\nNotes: Up to five levels of indirection are analyzed in conditional expressions.\n\n## Type Predicates\n\nType Predicates in TypeScript are functions that return a boolean value and are used to narrow the type of a variable to a more specific type.\n\n```typescript\nconst isString = (value: unknown): value is string => typeof value === 'string';\n\nconst foo = (bar: unknown) => {\n    if (isString(bar)) {\n        console.log(bar.toUpperCase());\n    } else {\n        console.log('not a string');\n    }\n};\n```\n\n## Discriminated Unions\n\nDiscriminated Unions in TypeScript are a type of union type that uses a common property, known as the discriminant, to narrow down the set of possible types for the union.\n\n```typescript\ntype Square = {\n    kind: 'square'; // Discriminant\n    size: number;\n};\n\ntype Circle = {\n    kind: 'circle'; // Discriminant\n    radius: number;\n};\n\ntype Shape = Square | Circle;\n\nconst area = (shape: Shape) => {\n    switch (shape.kind) {\n        case 'square':\n            return Math.pow(shape.size, 2);\n        case 'circle':\n            return Math.PI * Math.pow(shape.radius, 2);\n    }\n};\n\nconst square: Square = { kind: 'square', size: 5 };\nconst circle: Circle = { kind: 'circle', radius: 2 };\n\nconsole.log(area(square)); // 25\nconsole.log(area(circle)); // 12.566370614359172\n```\n\n## The never Type\n\nWhen a variable is narrowed to a type that cannot contain any values, the TypeScript compiler will infer that the variable must be of the `never` type. This is because The never Type represents a value that can never be produced.\n\n```typescript\nconst printValue = (val: string | number) => {\n    if (typeof val === 'string') {\n        console.log(val.toUpperCase());\n    } else if (typeof val === 'number') {\n        console.log(val.toFixed(2));\n    } else {\n        // val has type never here because it can never be anything other than a string or a number\n        const neverVal: never = val;\n        console.log(`Unexpected value: ${neverVal}`);\n    }\n};\n```\n\n## Exhaustiveness checking\n\nExhaustiveness checking is a feature in TypeScript that ensures all possible cases of a discriminated union are handled in a `switch` statement or an `if` statement.\n\n```typescript\ntype Direction = 'up' | 'down';\n\nconst move = (direction: Direction) => {\n    switch (direction) {\n        case 'up':\n            console.log('Moving up');\n            break;\n        case 'down':\n            console.log('Moving down');\n            break;\n        default:\n            const exhaustiveCheck: never = direction;\n            console.log(exhaustiveCheck); // This line will never be executed\n    }\n};\n```\n\nThe `never` type is used to ensure that the default case is exhaustive and that TypeScript will raise an error if a new value is added to the Direction type without being handled in the switch statement.\n\n## Object Types\n\nIn TypeScript, object types describe the shape of an object. They specify the names and types of the object's properties, as well as whether those properties are required or optional.\n\nIn TypeScript, you can define object types in two primary ways:\n\nInterface which defines the shape of an object by specifying the names, types, and optionality of its properties.\n\n```typescript\ninterface User {\n    name: string;\n    age: number;\n    email?: string;\n}\n```\n\nType alias, similar to an interface, defines the shape of an object. However, it can also create a new custom type that is based on an existing type or a combination of existing types. This includes defining union types, intersection types, and other complex types.\n\n```typescript\ntype Point = {\n    x: number;\n    y: number;\n};\n```\n\nIt also possible to define a type anonymously:\n\n```typescript\nconst sum = (x: { a: number; b: number }) => x.a + x.b;\nconsole.log(sum({ a: 5, b: 1 }));\n```\n\n## Tuple Type (Anonymous)\n\nA Tuple Type is a type that represents an array with a fixed number of elements and their corresponding types. A tuple type enforces a specific number of elements and their respective types in a fixed order. Tuple types are useful when you want to represent a collection of values with specific types, where the position of each element in the array has a specific meaning.\n\n```typescript\ntype Point = [number, number];\n```\n\n## Named Tuple Type (Labeled)\n\nTuple types can include optional labels or names for each element. These labels are for readability and tooling assistance, and do not affect the operations you can perform with them.\n\n```typescript\ntype T = string;\ntype Tuple1 = [T, T];\ntype Tuple2 = [a: T, b: T];\ntype Tuple3 = [a: T, T]; // Named Tuple plus Anonymous Tuple\n```\n\n## Fixed Length Tuple\n\nA Fixed Length Tuple is a specific type of tuple that enforces a fixed number of elements of specific types, and disallows any modifications to the length of the tuple once it is defined.\n\nFixed Length Tuples are useful when you need to represent a collection of values with a specific number of elements and specific types, and you want to ensure that the length and types of the tuple cannot be changed inadvertently.\n\n<!-- skip -->\n```typescript\nconst x = [10, 'hello'] as const;\nx.push(2); // Error\n```\n\n## Union Type\n\nA Union Type is a type that represents a value that can be one of several types. Union Types are denoted using the `|` symbol between each possible type.\n\n```typescript\nlet x: string | number;\nx = 'hello'; // Valid\nx = 123; // Valid\n```\n\n## Intersection Types\n\nAn Intersection Type is a type that represents a value that has all the properties of two or more types. Intersection Types are denoted using the `&` symbol between each type.\n\n```typescript\ntype X = {\n    a: string;\n};\n\ntype Y = {\n    b: string;\n};\n\ntype J = X & Y; // Intersection\n\nconst j: J = {\n    a: 'a',\n    b: 'b',\n};\n```\n\n## Type Indexing\n\nType indexing refers to the ability to define types that can be indexed by a key that is not known in advance, using an index signature to specify the type for properties that are not explicitly declared.\n\n```typescript\ntype Dictionary<T> = {\n    [key: string]: T;\n};\nconst myDict: Dictionary<string> = { a: 'a', b: 'b' };\nconsole.log(myDict['a']); // Returns a\n```\n\n## Type from Value\n\nType from Value in TypeScript refers to the automatic inference of a type from a value or expression through type inference.\n\n```typescript\nconst x = 'x'; // TypeScript infers 'x' as a string literal with 'const' (immutable), but widens it to 'string' with 'let' (reassignable).\n```\n\n## Type from Func Return\n\nType from Func Return refers to the ability to automatically infer the return type of a function based on its implementation. This allows TypeScript to determine the type of the value returned by the function without explicit type annotations.\n\n```typescript\nconst add = (x: number, y: number) => x + y; // TypeScript can infer that the return type of the function is a number\n```\n\n## Type from Module\n\nType from Module refers to the ability to use a module's exported values to automatically infer their types. When a module exports a value with a specific type, TypeScript can use that information to automatically infer the type of that value when it is imported into another module.\n\n<!-- skip -->\n```typescript\n// calc.ts\nexport const add = (x: number, y: number) => x + y;\n// index.ts\nimport { add } from 'calc';\nconst r = add(1, 2); // r is number\n```\n\n## Mapped Types\n\nMapped Types in TypeScript allow you to create new types based on an existing type by transforming each property using a mapping function. By mapping existing types, you can create new types that represent the same information in a different format. To create a mapped type, you access the properties of an existing type using the `keyof` operator and then alter them to produce a new type.\nIn the following example:\n\n```typescript\ntype MyMappedType<T> = {\n    [P in keyof T]: T[P][];\n};\ntype MyType = {\n    foo: string;\n    bar: number;\n};\ntype MyNewType = MyMappedType<MyType>;\nconst x: MyNewType = {\n    foo: ['hello', 'world'],\n    bar: [1, 2, 3],\n};\n```\n\nwe define MyMappedType to map over T's properties, creating a new type with each property as an array of its original type. Using this, we create MyNewType to represent the same info as MyType, but with each property as an array.\n\n## Mapped Type Modifiers\n\nMapped Type Modifiers in TypeScript enable the transformation of properties within an existing type:\n\n* `readonly` or `+readonly`: This renders a property in the mapped type as read-only.\n* `-readonly`: This allows a property in the mapped type to be mutable.\n* `?`: This designates a property in the mapped type as optional.\n\nExamples:\n\n```typescript\ntype ReadOnly<T> = { readonly [P in keyof T]: T[P] }; // All properties marked as read-only\n\ntype Mutable<T> = { -readonly [P in keyof T]: T[P] }; // All properties marked as mutable\n\ntype MyPartial<T> = { [P in keyof T]?: T[P] }; // All properties marked as optional\n```\n\n## Conditional Types\n\nConditional Types are a way to create a type that depends on a condition, where the type to be created is determined based on the result of the condition. They are defined using the `extends` keyword and a ternary operator to conditionally choose between two types.\n\n```typescript\ntype IsArray<T> = T extends any[] ? true : false;\n\nconst myArray = [1, 2, 3];\nconst myNumber = 42;\n\ntype IsMyArrayAnArray = IsArray<typeof myArray>; // Type true\ntype IsMyNumberAnArray = IsArray<typeof myNumber>; // Type false\n```\n\n## Distributive Conditional Types\n\nDistributive Conditional Types are a feature that allow a type to be distributed over a union of types, by applying a transformation to each member of the union individually.\nThis can be especially useful when working with mapped types or higher-order types.\n\n```typescript\ntype Nullable<T> = T extends any ? T | null : never;\ntype NumberOrBool = number | boolean;\ntype NullableNumberOrBool = Nullable<NumberOrBool>; // number | boolean | null\n```\n\n## infer Type Inference in Conditional Types\n\nThe `infer`keyword is used in conditional types to infer (extract) the type of a generic parameter from a type that depends on it. This allows you to write more flexible and reusable type definitions.\n\n```typescript\ntype ElementType<T> = T extends (infer U)[] ? U : never;\ntype Numbers = ElementType<number[]>; // number\ntype Strings = ElementType<string[]>; // string\n```\n\n## Predefined Conditional Types\n\nIn TypeScript, Predefined Conditional Types are built-in conditional types provided by the language. They are designed to perform common type transformations based on the characteristics of a given type.\n\n`Exclude<UnionType, ExcludedType>`: This type removes all the types from Type that are assignable to ExcludedType.\n\n`Extract<Type, Union>`: This type extracts all the types from Union that are assignable to Type.\n\n`NonNullable<Type>`: This type removes null and undefined from Type.\n\n`ReturnType<Type>`: This type extracts the return type of a function Type.\n\n`Parameters<Type>`: This type extracts the parameter types of a function Type.\n\n`Required<Type>`: This type makes all properties in Type required.\n\n`Partial<Type>`: This type makes all properties in Type optional.\n\n`Readonly<Type>`: This type makes all properties in Type readonly.\n\n## Template Union Types\n\nTemplate union types can be used to merge and manipulate text inside the type system for instance:\n\n```typescript\ntype Status = 'active' | 'inactive';\ntype Products = 'p1' | 'p2';\ntype ProductId = `id-${Products}-${Status}`; // \"id-p1-active\" | \"id-p1-inactive\" | \"id-p2-active\" | \"id-p2-inactive\"\n```\n\n## Any type\n\nThe `any` type is a special type (universal supertype) that can be used to represent any type of value (primitives, objects, arrays, functions, errors, symbols). It is often used in situations where the type of a value is not known at compile time, or when working with values from external APIs or libraries that do not have TypeScript typings.\n\nBy utilizing `any` type, you are indicating to the TypeScript compiler that values should be represented without any limitations. To maximize type safety in your code, consider the following:\n\n* Limit the usage of `any` to specific cases where the type is truly unknown.\n* Do not return `any` types from a function, as this weakens type safety in code that uses it.\n* Instead of `any` use `@ts-ignore` if you need to silence the compiler.\n\n```typescript\nlet value: any;\nvalue = true; // Valid\nvalue = 7; // Valid\n```\n\n## Unknown type\n\nIn TypeScript, the `unknown` type represents a value that is of an unknown type. Unlike `any` type, which allows for any type of value, `unknown` requires a type check or assertion before it can be used in a specific way so no operations are permitted on an `unknown` without first asserting or narrowing to a more specific type.\n\nThe `unknown` type is only assignable to any type and the `unknown` type itself, it is a type-safe alternative to `any`.\n\n<!-- skip -->\n```typescript\nlet value: unknown;\n\nlet value1: unknown = value; // Valid\nlet value2: any = value; // Valid\nlet value3: boolean = value; // Invalid\nlet value4: number = value; // Invalid\n```\n\n```typescript\nconst add = (a: unknown, b: unknown): number | undefined =>\n    typeof a === 'number' && typeof b === 'number' ? a + b : undefined;\nconsole.log(add(1, 2)); // 3\nconsole.log(add('x', 2)); // undefined\n```\n\n## Void type\n\nThe `void` type is used to indicate that a function does not return a value.\n\n```typescript\nconst sayHello = (): void => {\n    console.log('Hello!');\n};\n```\n\n## Never type\n\nThe `never` type represents values that never occur. It is used to denote functions or expressions that never return or throw an error.\n\nFor instance an infinite loop:\n\n```typescript\nconst infiniteLoop = (): never => {\n    while (true) {\n        // do something\n    }\n};\n```\n\nThrowing an error:\n\n```typescript\nconst throwError = (message: string): never => {\n    throw new Error(message);\n};\n```\n\nThe `never` type is useful in ensuring type safety and catching potential errors in your code. It helps TypeScript analyze and infer more precise types when used in combination with other types and control flow statements, for instance:\n\n```typescript\ntype Direction = 'up' | 'down';\nconst move = (direction: Direction): void => {\n    switch (direction) {\n        case 'up':\n            // move up\n            break;\n        case 'down':\n            // move down\n            break;\n        default:\n            const exhaustiveCheck: never = direction;\n            throw new Error(`Unhandled direction: ${exhaustiveCheck}`);\n    }\n};\n```\n\n## Interface and Type\n\n### Common Syntax\n\nIn TypeScript, interfaces define the structure of objects, specifying the names and types of properties or methods that an object must have. The common syntax for defining an interface in TypeScript is as follows:\n\n<!-- skip -->\n```typescript\ninterface InterfaceName {\n    property1: Type1;\n    // ...\n    method1(arg1: ArgType1, arg2: ArgType2): ReturnType;\n    // ...\n}\n```\n\nSimilarly for type definition:\n\n<!-- skip -->\n```typescript\ntype TypeName = {\n    property1: Type1;\n    // ...\n    method1(arg1: ArgType1, arg2: ArgType2): ReturnType;\n    // ...\n};\n```\n\n`interface InterfaceName` or `type TypeName`: Defines the name of the interface.\n`property1`: `Type1`: Specifies the properties of the interface along with their corresponding types. Multiple properties can be defined, each separated by a semicolon.\n`method1(arg1: ArgType1, arg2: ArgType2): ReturnType;`: Specifies the methods of the interface. Methods are defined with their names, followed by a parameter list in parentheses and the return type. Multiple methods can be defined, each separated by a semicolon.\n\nExample interface:\n\n```typescript\ninterface Person {\n    name: string;\n    age: number;\n    greet(): void;\n}\n```\n\nExample of type:\n\n```typescript\ntype TypeName = {\n    property1: string;\n    method1(arg1: string, arg2: string): string;\n};\n```\n\nIn TypeScript, types are used to define the shape of data and enforce type checking. There are several common syntaxes for defining types in TypeScript, depending on the specific use case. Here are some examples:\n\n### Basic Types\n\n```typescript\nlet myNumber: number = 123; // number type\nlet myBoolean: boolean = true; // boolean type\nlet myArray: string[] = ['a', 'b']; // array of strings\nlet myTuple: [string, number] = ['a', 123]; // tuple\n```\n\n### Objects and Interfaces\n\n```typescript\nconst x: { name: string; age: number } = { name: 'Simon', age: 7 };\n```\n\n### Union and Intersection Types\n\n```typescript\ntype MyType = string | number; // Union type\nlet myUnion: MyType = 'hello'; // Can be a string\nmyUnion = 123; // Or a number\n\ntype TypeA = { name: string };\ntype TypeB = { age: number };\ntype CombinedType = TypeA & TypeB; // Intersection type\nlet myCombined: CombinedType = { name: 'John', age: 25 }; // Object with both name and age properties\n```\n\n## Built-in Type Primitives\n\nTypeScript has several built-in type primitives that can be used to define variables, function parameters, and return types:\n\n* `number`: Represents numeric values, including integers and floating-point numbers.\n* `string`: Represents textual data\n* `boolean`: Represents logical values, which can be either true or false.\n* `null`: Represents the absence of a value.\n* `undefined`: Represents a value that has not been assigned or has not been defined.\n* `symbol`: Represents a unique identifier. Symbols are typically used as keys for object properties.\n* `bigint`: Represents arbitrary-precision integers.\n* `any`: Represents a dynamic or unknown type. Variables of type any can hold values of any type, and they bypass type checking.\n* `void`: Represents the absence of any type. It is commonly used as the return type of functions that do not return a value.\n* `never`: Represents a type for values that never occur. It is typically used as the return type of functions that throw an error or enter an infinite loop.\n\n## Common Built-in JS Objects\n\nTypeScript is a superset of JavaScript, it includes all the commonly used built-in JavaScript objects. You can find an extensive list of these objects on the Mozilla Developer Network (MDN) documentation website:\n[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects)\n\nHere is a list of some commonly used built-in JavaScript objects:\n\n* Function\n* Object\n* Boolean\n* Error\n* Number\n* BigInt\n* Math\n* Date\n* String\n* RegExp\n* Array\n* Map\n* Set\n* Promise\n* Intl\n\n## Overloads\n\nFunction overloads in TypeScript allow you to define multiple function signatures for a single function name, enabling you to define functions that can be called in multiple ways. Here's an example:\n\n```typescript\n// Overloads\nfunction sayHi(name: string): string;\nfunction sayHi(names: string[]): string[];\n\n// Implementation\nfunction sayHi(name: unknown): unknown {\n    if (typeof name === 'string') {\n        return `Hi, ${name}!`;\n    } else if (Array.isArray(name)) {\n        return name.map(name => `Hi, ${name}!`);\n    }\n    throw new Error('Invalid value');\n}\n\nsayHi('xx'); // Valid\nsayHi(['aa', 'bb']); // Valid\n```\n\nHere's another example of using function overloads within a `class`:\n\n```typescript\nclass Greeter {\n    message: string;\n\n    constructor(message: string) {\n        this.message = message;\n    }\n\n    // overload\n    sayHi(name: string): string;\n    sayHi(names: string[]): ReadonlyArray<string>;\n\n    // implementation\n    sayHi(name: unknown): unknown {\n        if (typeof name === 'string') {\n            return `${this.message}, ${name}!`;\n        } else if (Array.isArray(name)) {\n            return name.map(name => `${this.message}, ${name}!`);\n        }\n        throw new Error('value is invalid');\n    }\n}\nconsole.log(new Greeter('Hello').sayHi('Simon'));\n```\n\n## Merging and Extension\n\nMerging and extension refer to two different concepts related to working with types and interfaces.\n\nMerging allows you to combine multiple declarations of the same name into a single definition, for example, when you define an interface with the same name multiple times:\n\n```typescript\ninterface X {\n    a: string;\n}\n\ninterface X {\n    b: number;\n}\n\nconst person: X = {\n    a: 'a',\n    b: 7,\n};\n```\n\nExtension refers to the ability to extend or inherit from existing types or interfaces to create new ones. It is a mechanism to add additional properties or methods to an existing type without modifying its original definition. Example:\n\n```typescript\ninterface Animal {\n    name: string;\n    eat(): void;\n}\n\ninterface Bird extends Animal {\n    sing(): void;\n}\n\nconst dog: Bird = {\n    name: 'Bird 1',\n    eat() {\n        console.log('Eating');\n    },\n    sing() {\n        console.log('Singing');\n    },\n};\n```\n\n## Differences between Type and Interface\n\nDeclaration merging (augmentation):\n\nInterfaces support declaration merging, which means that you can define multiple interfaces with the same name, and TypeScript will merge them into a single interface with the combined properties and methods. On the other hand, types do not support declaration merging. This can be helpful when you want to add extra functionality or customize existing types without modifying the original definitions or patching missing or incorrect types.\n\n```typescript\ninterface A {\n    x: string;\n}\ninterface A {\n    y: string;\n}\nconst j: A = {\n    x: 'xx',\n    y: 'yy',\n};\n```\n\nExtending other types/interfaces:\n\nBoth types and interfaces can extend other types/interfaces, but the syntax is different. With interfaces, you use the `extends` keyword to inherit properties and methods from other interfaces. However, an interface cannot extend a complex type like a union type.\n\n```typescript\ninterface A {\n    x: string;\n    y: number;\n}\ninterface B extends A {\n    z: string;\n}\nconst car: B = {\n    x: 'x',\n    y: 123,\n    z: 'z',\n};\n```\n\nFor types, you use the & operator to combine multiple types into a single type (intersection).\n\n```typescript\ninterface A {\n    x: string;\n    y: number;\n}\n\ntype B = A & {\n    j: string;\n};\n\nconst c: B = {\n    x: 'x',\n    y: 123,\n    j: 'j',\n};\n```\n\nUnion and Intersection Types:\n\nTypes are more flexible when it comes to defining Union and Intersection Types. With the `type` keyword, you can easily create union types using the `|` operator and intersection types using the `&` operator. While interfaces can also represent union types indirectly, they don't have built-in support for intersection types.\n\n```typescript\ntype Department = 'dep-x' | 'dep-y'; // Union\n\ntype Person = {\n    name: string;\n    age: number;\n};\n\ntype Employee = {\n    id: number;\n    department: Department;\n};\n\ntype EmployeeInfo = Person & Employee; // Intersection\n```\n\nExample with interfaces:\n\n```typescript\ninterface A {\n    x: 'x';\n}\ninterface B {\n    y: 'y';\n}\n\ntype C = A | B; // Union of interfaces\n```\n\n## Class\n\n### Class Common Syntax\n\nThe `class` keyword is used in TypeScript to define a class. Below, you can see an example:\n\n```typescript\nclass Person {\n    private name: string;\n    private age: number;\n    constructor(name: string, age: number) {\n        this.name = name;\n        this.age = age;\n    }\n    public sayHi(): void {\n        console.log(\n            `Hello, my name is ${this.name} and I am ${this.age} years old.`\n        );\n    }\n}\n```\n\nThe `class` keyword is used to define a class named \"Person\".\n\nThe class has two private properties: name of type `string` and age of type `number`.\n\nThe constructor is defined using the `constructor` keyword. It takes name and age as parameters and assigns them to the corresponding properties.\n\nThe class has a `public` method named sayHi that logs a greeting message.\n\nTo create an instance of a class in TypeScript, you can use the `new` keyword followed by the class name, followed by parentheses `()`. For instance:\n\n<!-- skip -->\n```typescript\nconst myObject = new Person('John Doe', 25);\nmyObject.sayHi(); // Output: Hello, my name is John Doe and I am 25 years old.\n```\n\n### Constructor\n\nConstructors are special methods within a class that are used to initialize the object's properties when an instance of the class is created.\n\n```typescript\nclass Person {\n    public name: string;\n    public age: number;\n\n    constructor(name: string, age: number) {\n        this.name = name;\n        this.age = age;\n    }\n\n    sayHello() {\n        console.log(\n            `Hello, my name is ${this.name} and I'm ${this.age} years old.`\n        );\n    }\n}\n\nconst john = new Person('Simon', 17);\njohn.sayHello();\n```\n\nIt is possible to overload a constructor using the following syntax:\n\n```typescript\ntype Sex = 'm' | 'f';\n\nclass Person {\n    name: string;\n    age: number;\n    sex: Sex;\n\n    constructor(name: string, age: number, sex?: Sex);\n    constructor(name: string, age: number, sex: Sex) {\n        this.name = name;\n        this.age = age;\n        this.sex = sex ?? 'm';\n    }\n}\n\nconst p1 = new Person('Simon', 17);\nconst p2 = new Person('Alice', 22, 'f');\n```\n\nIn TypeScript, it is possible to define multiple constructor overloads, but you can have only one implementation that must be compatible with all the overloads, this can be achieved  by using an optional parameter.\n\n```typescript\nclass Person {\n    name: string;\n    age: number;\n\n    constructor();\n    constructor(name: string);\n    constructor(name: string, age: number);\n    constructor(name?: string, age?: number) {\n        this.name = name ?? 'Unknown';\n        this.age = age ?? 0;\n    }\n\n    displayInfo() {\n        console.log(`Name: ${this.name}, Age: ${this.age}`);\n    }\n}\n\nconst person1 = new Person();\nperson1.displayInfo(); // Name: Unknown, Age: 0\n\nconst person2 = new Person('John');\nperson2.displayInfo(); // Name: John, Age: 0\n\nconst person3 = new Person('Jane', 25);\nperson3.displayInfo(); // Name: Jane, Age: 25\n```\n\n### Private and Protected Constructors\n\nIn TypeScript, constructors can be marked as private or protected, which restricts their accessibility and usage.\n\nPrivate Constructors:\nCan be called only within the class itself. Private constructors are often used in scenarios where you want to enforce a singleton pattern or restrict the creation of instances to a factory method within the class\n\nProtected Constructors:\nProtected constructors are useful when you want to create a base class that should not be instantiated directly but can be extended by subclasses.\n\n```typescript\nclass BaseClass {\n    protected constructor() {}\n}\n\nclass DerivedClass extends BaseClass {\n    private value: number;\n\n    constructor(value: number) {\n        super();\n        this.value = value;\n    }\n}\n\n// Attempting to instantiate the base class directly will result in an error\n// const baseObj = new BaseClass(); // Error: Constructor of class 'BaseClass' is protected.\n\n// Create an instance of the derived class\nconst derivedObj = new DerivedClass(10);\n```\n\n### Access Modifiers\n\nAccess Modifiers `private`, `protected`, and `public` are used to control the visibility and accessibility of class members, such as properties and methods, in TypeScript classes. These modifiers are essential for enforcing encapsulation and establishing boundaries for accessing and modifying the internal state of a class.\n\nThe `private` modifier restricts access to the class member only within the containing class.\n\nThe `protected` modifier allows access to the class member within the containing class and its derived classes.\n\nThe `public` modifier provides unrestricted access to the class member, allowing it to be accessed from anywhere.\"\n\n### Get and Set\n\nGetters and setters are special methods that allow you to define custom access and modification behavior for class properties. They enable you to encapsulate the internal state of an object and provide additional logic when getting or setting the values of properties.\nIn TypeScript, getters and setters are defined using the `get` and `set` keywords respectively. Here's an example:\n\n```typescript\nclass MyClass {\n    private _myProperty: string;\n\n    constructor(value: string) {\n        this._myProperty = value;\n    }\n    get myProperty(): string {\n        return this._myProperty;\n    }\n    set myProperty(value: string) {\n        this._myProperty = value;\n    }\n}\n```\n\n### Auto-Accessors in Classes\n\nTypeScript version 4.9 adds support for auto-accessors, a forthcoming ECMAScript feature. They resemble class properties but are declared with the \"accessor\" keyword.\n\n```typescript\nclass Animal {\n    accessor name: string;\n\n    constructor(name: string) {\n        this.name = name;\n    }\n}\n```\n\nAuto-accessors are \"de-sugared\" into private `get` and `set` accessors, operating on an inaccessible property.\n\n<!-- skip -->\n```typescript\nclass Animal {\n    #__name: string;\n\n    get name() {\n        return this.#__name;\n    }\n    set name(value: string) {\n        this.#__name = name;\n    }\n\n    constructor(name: string) {\n        this.name = name;\n    }\n}\n```\n\n### this\n\nIn TypeScript, the `this` keyword refers to the current instance of a class within its methods or constructors. It allows you to access and modify the properties and methods of the class from within its own scope.\nIt provides a way to access and manipulate the internal state of an object within its own methods.\n\n```typescript\nclass Person {\n    private name: string;\n    constructor(name: string) {\n        this.name = name;\n    }\n    public introduce(): void {\n        console.log(`Hello, my name is ${this.name}.`);\n    }\n}\n\nconst person1 = new Person('Alice');\nperson1.introduce(); // Hello, my name is Alice.\n```\n\n### Parameter Properties\n\nParameter properties allow you to declare and initialize class properties directly within the constructor parameters avoiding boilerplate code, example:\n\n```typescript\nclass Person {\n    constructor(\n        private name: string,\n        public age: number\n    ) {\n        // The \"private\" and \"public\" keywords in the constructor\n        // automatically declare and initialize the corresponding class properties.\n    }\n    public introduce(): void {\n        console.log(\n            `Hello, my name is ${this.name} and I am ${this.age} years old.`\n        );\n    }\n}\nconst person = new Person('Alice', 25);\nperson.introduce();\n```\n\n### Abstract Classes\n\nAbstract Classes are used in TypeScript mainly for inheritance, they provide a way to define common properties and methods that can be inherited by subclasses.\nThis is useful when you want to define common behavior and enforce that subclasses implement certain methods. They provide a way to create a hierarchy of classes where the abstract base class provides a shared interface and common functionality for the subclasses.\n\n```typescript\nabstract class Animal {\n    protected name: string;\n\n    constructor(name: string) {\n        this.name = name;\n    }\n\n    abstract makeSound(): void;\n}\n\nclass Cat extends Animal {\n    makeSound(): void {\n        console.log(`${this.name} meows.`);\n    }\n}\n\nconst cat = new Cat('Whiskers');\ncat.makeSound(); // Output: Whiskers meows.\n```\n\n### With Generics\n\nClasses with generics allow you to define reusable classes which can work with different types.\n\n```typescript\nclass Container<T> {\n    private item: T;\n\n    constructor(item: T) {\n        this.item = item;\n    }\n\n    getItem(): T {\n        return this.item;\n    }\n\n    setItem(item: T): void {\n        this.item = item;\n    }\n}\n\nconst container1 = new Container<number>(42);\nconsole.log(container1.getItem()); //  42\n\nconst container2 = new Container<string>('Hello');\ncontainer2.setItem('World');\nconsole.log(container2.getItem()); // World\n```\n\n### Decorators\n\nDecorators provide a mechanism to add metadata, modify behavior, validate, or extend the functionality of the target element. They are functions that execute at runtime. Multiple decorators can be applied to a declaration.\n\nDecorators are experimental features, and the following examples are only compatible with TypeScript version 5 or above using ES6.\n\nFor TypeScript versions prior to 5, they should be enabled using the `experimentalDecorators` property in your `tsconfig.json` or by using `--experimentalDecorators` in your command line (but the following example won't work).\n\nSome of the common use cases for decorators include:\n\n* Watching property changes.\n* Watching method calls.\n* Adding extra properties or methods.\n* Runtime validation.\n* Automatic serialization and deserialization.\n* Logging.\n* Authorization and authentication.\n* Error guarding.\n\nNote: Decorators for version 5 do not allow decorating parameters.\n\nTypes of decorators:\n\n#### Class Decorators\n\nClass Decorators are useful for extending an existing class, such as adding properties or methods, or collecting instances of a class. In the following example, we add a `toString` method that converts the class into a string representation.\n\n```typescript\ntype Constructor<T = {}> = new (...args: any[]) => T;\n\nfunction toString<Class extends Constructor>(\n    Value: Class,\n    context: ClassDecoratorContext<Class>\n) {\n    return class extends Value {\n        constructor(...args: any[]) {\n            super(...args);\n            console.log(JSON.stringify(this));\n            console.log(JSON.stringify(context));\n        }\n    };\n}\n\n@toString\nclass Person {\n    name: string;\n\n    constructor(name: string) {\n        this.name = name;\n    }\n\n    greet() {\n        return 'Hello, ' + this.name;\n    }\n}\nconst person = new Person('Simon');\n/* Logs:\n{\"name\":\"Simon\"}\n{\"kind\":\"class\",\"name\":\"Person\"}\n*/\n```\n\n#### Property Decorator\n\nProperty decorators are useful for modifying the behavior of a property, such as changing the initialization values. In the following code, we have a script that sets a property to always be in uppercase:\n\n```typescript\nfunction upperCase<T>(\n    target: undefined,\n    context: ClassFieldDecoratorContext<T, string>\n) {\n    return function (this: T, value: string) {\n        return value.toUpperCase();\n    };\n}\n\nclass MyClass {\n    @upperCase\n    prop1 = 'hello!';\n}\n\nconsole.log(new MyClass().prop1); // Logs: HELLO!\n```\n\n#### Method Decorator\n\nMethod decorators allow you to change or enhance the behavior of methods. Below is an example of a simple logger:\n\n```typescript\nfunction log<This, Args extends any[], Return>(\n    target: (this: This, ...args: Args) => Return,\n    context: ClassMethodDecoratorContext<\n        This,\n        (this: This, ...args: Args) => Return\n    >\n) {\n    const methodName = String(context.name);\n\n    function replacementMethod(this: This, ...args: Args): Return {\n        console.log(`LOG: Entering method '${methodName}'.`);\n        const result = target.call(this, ...args);\n        console.log(`LOG: Exiting method '${methodName}'.`);\n        return result;\n    }\n\n    return replacementMethod;\n}\n\nclass MyClass {\n    @log\n    sayHello() {\n        console.log('Hello!');\n    }\n}\n\nnew MyClass().sayHello();\n```\n\nIt logs:\n\n```shell\nLOG: Entering method 'sayHello'.\nHello!\nLOG: Exiting method 'sayHello'.\n```\n\n#### Getter and Setter Decorators\n\nGetter and setter decorators allow you to change or enhance the behavior of class accessors. They are useful, for instance, for validating property assignments. Here's a simple example for a getter decorator:\n\n```typescript\nfunction range<This, Return extends number>(min: number, max: number) {\n    return function (\n        target: (this: This) => Return,\n        context: ClassGetterDecoratorContext<This, Return>\n    ) {\n        return function (this: This): Return {\n            const value = target.call(this);\n            if (value < min || value > max) {\n                throw 'Invalid';\n            }\n            Object.defineProperty(this, context.name, {\n                value,\n                enumerable: true,\n            });\n            return value;\n        };\n    };\n}\n\nclass MyClass {\n    private _value = 0;\n\n    constructor(value: number) {\n        this._value = value;\n    }\n    @range(1, 100)\n    get getValue(): number {\n        return this._value;\n    }\n}\n\nconst obj = new MyClass(10);\nconsole.log(obj.getValue); // Valid: 10\n\nconst obj2 = new MyClass(999);\nconsole.log(obj2.getValue); // Throw: Invalid!\n```\n\n#### Decorator Metadata\n\nDecorator Metadata simplifies the process for decorators to apply and utilize metadata in any class. They can access a new metadata property on the context object, which can serve as a key for both primitives and objects.\nMetadata information can be accessed on the class via `Symbol.metadata`.\n\nMetadata can be used for various purposes, such as debugging, serialization, or dependency injection with decorators.\n\n```typescript\n//@ts-ignore\nSymbol.metadata ??= Symbol('Symbol.metadata'); // Simple polify\n\ntype Context =\n    | ClassFieldDecoratorContext\n    | ClassAccessorDecoratorContext\n    | ClassMethodDecoratorContext; // Context contains property metadata: DecoratorMetadata\n\nfunction setMetadata(_target: any, context: Context) {\n    // Set the metadata object with a primitive value\n    context.metadata[context.name] = true;\n}\n\nclass MyClass {\n    @setMetadata\n    a = 123;\n\n    @setMetadata\n    accessor b = 'b';\n\n    @setMetadata\n    fn() {}\n}\n\nconst metadata = MyClass[Symbol.metadata]; // Get metadata information\n\nconsole.log(JSON.stringify(metadata)); // {\"bar\":true,\"baz\":true,\"foo\":true}\n```\n\n### Inheritance\n\nInheritance refers to the mechanism by which a class can inherit properties and methods from another class, known as the base class or superclass. The derived class, also called the child class or subclass, can extend and specialize the functionality of the base class by adding new properties and methods or overriding existing ones.\n\n```typescript\nclass Animal {\n    name: string;\n\n    constructor(name: string) {\n        this.name = name;\n    }\n\n    speak(): void {\n        console.log('The animal makes a sound');\n    }\n}\n\nclass Dog extends Animal {\n    breed: string;\n\n    constructor(name: string, breed: string) {\n        super(name);\n        this.breed = breed;\n    }\n\n    speak(): void {\n        console.log('Woof! Woof!');\n    }\n}\n\n// Create an instance of the base class\nconst animal = new Animal('Generic Animal');\nanimal.speak(); // The animal makes a sound\n\n// Create an instance of the derived class\nconst dog = new Dog('Max', 'Labrador');\ndog.speak(); // Woof! Woof!\"\n```\n\nTypeScript does not support multiple inheritance in the traditional sense and instead allows inheritance from a single base class.\nTypeScript supports multiple interfaces. An interface can define a contract for the structure of an object, and a class can implement multiple interfaces. This allows a class to inherit behavior and structure from multiple sources.\n\n```typescript\ninterface Flyable {\n    fly(): void;\n}\n\ninterface Swimmable {\n    swim(): void;\n}\n\nclass FlyingFish implements Flyable, Swimmable {\n    fly() {\n        console.log('Flying...');\n    }\n\n    swim() {\n        console.log('Swimming...');\n    }\n}\n\nconst flyingFish = new FlyingFish();\nflyingFish.fly();\nflyingFish.swim();\n```\n\nThe `class` keyword in TypeScript, similar to JavaScript, is often referred to as syntactic sugar. It was introduced in ECMAScript 2015 (ES6) to offer a more familiar syntax for creating and working with objects in a class-based manner. However, it's important to note that TypeScript, being a superset of JavaScript, ultimately compiles down to JavaScript, which remains prototype-based at its core.\n\n### Statics\n\nTypeScript has static members. To access the static members of a class, you can use the class name followed by a dot, without the need to create an object.\n\n```typescript\nclass OfficeWorker {\n    static memberCount: number = 0;\n\n    constructor(private name: string) {\n        OfficeWorker.memberCount++;\n    }\n}\n\nconst w1 = new OfficeWorker('James');\nconst w2 = new OfficeWorker('Simon');\nconst total = OfficeWorker.memberCount;\nconsole.log(total); // 2\n```\n\n### Property initialization\n\nThere are several ways how you can initialize properties for a class in TypeScript:\n\nInline:\n\nIn the following example these initial values will be used when an instance of the class is created.\n\n```typescript\nclass MyClass {\n    property1: string = 'default value';\n    property2: number = 42;\n}\n```\n\nIn the constructor:\n\n```typescript\nclass MyClass {\n    property1: string;\n    property2: number;\n\n    constructor() {\n        this.property1 = 'default value';\n        this.property2 = 42;\n    }\n}\n```\n\nUsing constructor parameters:\n\n```typescript\nclass MyClass {\n    constructor(\n        private property1: string = 'default value',\n        public property2: number = 42\n    ) {\n        // There is no need to assign the values to the properties explicitly.\n    }\n    log() {\n        console.log(this.property2);\n    }\n}\nconst x = new MyClass();\nx.log();\n```\n\n### Method overloading\n\nMethod overloading allows a class to have multiple methods with the same name but different parameter types or a different number of parameters. This allows us to call a method in different ways based on the arguments passed.\n\n```typescript\nclass MyClass {\n    add(a: number, b: number): number; // Overload signature 1\n    add(a: string, b: string): string; // Overload signature 2\n\n    add(a: number | string, b: number | string): number | string {\n        if (typeof a === 'number' && typeof b === 'number') {\n            return a + b;\n        }\n        if (typeof a === 'string' && typeof b === 'string') {\n            return a.concat(b);\n        }\n        throw new Error('Invalid arguments');\n    }\n}\n\nconst r = new MyClass();\nconsole.log(r.add(10, 5)); // Logs 15\n```\n\n## Generics\n\nGenerics allow you to create reusable components and functions that can work with multiple types. With generics, you can parameterize types, functions, and interfaces, allowing them to operate on different types without explicitly specifying them beforehand.\n\nGenerics allow you to make code more flexible and reusable.\n\n### Generic Type\n\nTo define a generic type, you use angle brackets (`<>`) to specify the type parameters, for instance:\n\n```typescript\nfunction identity<T>(arg: T): T {\n    return arg;\n}\nconst a = identity('x');\nconst b = identity(123);\n\nconst getLen = <T,>(data: ReadonlyArray<T>) => data.length;\nconst len = getLen([1, 2, 3]);\n```\n\n### Generic Classes\n\nGenerics can be applied also to classes, in this way they can work with multiple types by using type parameters. This is useful to create reusable class definitions that can operate on different data types while maintaining type safety.\n\n```typescript\nclass Container<T> {\n    private item: T;\n\n    constructor(item: T) {\n        this.item = item;\n    }\n\n    getItem(): T {\n        return this.item;\n    }\n}\n\nconst numberContainer = new Container<number>(123);\nconsole.log(numberContainer.getItem()); // 123\n\nconst stringContainer = new Container<string>('hello');\nconsole.log(stringContainer.getItem()); // hello\n```\n\n### Generic Constraints\n\nGeneric parameters can be constrained using the `extends` keyword followed by a type or interface that the type parameter must satisfy.\n\nIn the following example T it is must containing a properly `length` in order to be valid:\n\n<!-- skip -->\n```typescript\nconst printLen = <T extends { length: number }>(value: T): void => {\n    console.log(value.length);\n};\n\nprintLen('Hello'); // 5\nprintLen([1, 2, 3]); // 3\nprintLen({ length: 10 }); // 10\nprintLen(123); // Invalid\n```\n\nAn interesting feature of generic introduced in version 3.4 RC is Higher order function type inference which introduced  propagated generic type arguments:\n\n```typescript\ndeclare function pipe<A extends any[], B, C>(\n    ab: (...args: A) => B,\n    bc: (b: B) => C\n): (...args: A) => C;\n\ndeclare function list<T>(a: T): T[];\ndeclare function box<V>(x: V): { value: V };\n\nconst listBox = pipe(list, box); // <T>(a: T) => { value: T[] }\nconst boxList = pipe(box, list); // <V>(x: V) => { value: V }[]\n```\n\nThis functionality allows more easily typed safe pointfree style programming which is common in functional programming.\n\n### Generic contextual narrowing\n\nContextual narrowing for generics is the mechanism in TypeScript that allows the compiler to narrow down the type of a generic parameter based on the context in which it is used, it is useful when working with generic types in conditional statements:\n\n```typescript\nfunction process<T>(value: T): void {\n    if (typeof value === 'string') {\n        // Value is narrowed down to type 'string'\n        console.log(value.length);\n    } else if (typeof value === 'number') {\n        // Value is narrowed down to type 'number'\n        console.log(value.toFixed(2));\n    }\n}\n\nprocess('hello'); // 5\nprocess(3.14159); // 3.14\n```\n\n## Erased Structural Types\n\nIn TypeScript, objects do not have to match a specific, exact type. For instance, if we create an object that fulfills an interface's requirements, we can utilize that object in places where that interface is required, even if there was no explicit connection between them.\nExample:\n\n```typescript\ntype NameProp1 = {\n    prop1: string;\n};\n\nfunction log(x: NameProp1) {\n    console.log(x.prop1);\n}\n\nconst obj = {\n    prop2: 123,\n    prop1: 'Origin',\n};\n\nlog(obj); // Valid\n```\n\n## Namespacing\n\nIn TypeScript, namespaces are used to organize code into logical containers, preventing naming collisions and providing a way to group related code together.\nThe usage of the `export` keywords allows access to the namespace in \"outside\" modules.\n\n```typescript\nexport namespace MyNamespace {\n    export interface MyInterface1 {\n        prop1: boolean;\n    }\n    export interface MyInterface2 {\n        prop2: string;\n    }\n}\n\nconst a: MyNamespace.MyInterface1 = {\n    prop1: true,\n};\n```\n\n## Symbols\n\nSymbols are a primitive data type that represents an immutable value which is guaranteed to be globally unique throughout the lifetime of the program.\n\nSymbols can be used as keys for object properties and provide a way to create non-enumerable properties.\n\n```typescript\nconst key1: symbol = Symbol('key1');\nconst key2: symbol = Symbol('key2');\n\nconst obj = {\n    [key1]: 'value 1',\n    [key2]: 'value 2',\n};\n\nconsole.log(obj[key1]); // value 1\nconsole.log(obj[key2]); // value 2\n```\n\nIn WeakMaps and WeakSets, symbols are now permissible as keys.\n\n## Triple-Slash Directives\n\nTriple-slash directives are special comments that provide instructions to the compiler about how to process a file. These directives begin with three consecutive slashes (`///`) and are typically placed at the top of a TypeScript file and have no effects on the runtime behavior.\n\nTriple-slash directives are used to reference external dependencies, specify module loading behavior, enable/disable certain compiler features, and more. Few examples:\n\nReferencing a declaration file:\n\n<!-- skip -->\n```typescript\n/// <reference path=\"path/to/declaration/file.d.ts\" />\n```\n\nIndicate the module format:\n\n<!-- skip -->\n```typescript\n/// <amd|commonjs|system|umd|es6|es2015|none>\n```\n\nEnable compiler options, in the following example strict mode:\n\n<!-- skip -->\n```typescript\n/// <strict|noImplicitAny|noUnusedLocals|noUnusedParameters>\n```\n\n## Type Manipulation\n\n### Creating Types from Types\n\nIs it possible to create new types composing, manipulating or transforming existing types.\n\nIntersection Types (`&`):\n\nAllow you to combine multiple types into a single  type:\n\n```typescript\ntype A = { foo: number };\ntype B = { bar: string };\ntype C = A & B; // Intersection of A and B\nconst obj: C = { foo: 42, bar: 'hello' };\n```\n\nUnion Types (`|`):\n\nAllow you to define a type that can be one of several types:\n\n```typescript\ntype Result = string | number;\nconst value1: Result = 'hello';\nconst value2: Result = 42;\n```\n\nMapped Types:\n\nAllow you to transform the properties of an existing type to create new type:\n\n```typescript\ntype Mutable<T> = {\n    readonly [P in keyof T]: T[P];\n};\ntype Person = {\n    name: string;\n    age: number;\n};\ntype ImmutablePerson = Mutable<Person>; // Properties become read-only\n```\n\nConditional types:\n\nAllow you to create types based on some conditions:\n\n```typescript\ntype ExtractParam<T> = T extends (param: infer P) => any ? P : never;\ntype MyFunction = (name: string) => number;\ntype ParamType = ExtractParam<MyFunction>; // string\n```\n\n### Indexed Access Types\n\nIn TypeScript is it possible to access and manipulate  the types of properties within another type using an index, `Type[Key]`.\n\n```typescript\ntype Person = {\n    name: string;\n    age: number;\n};\n\ntype AgeType = Person['age']; // number\n```\n\n```typescript\ntype MyTuple = [string, number, boolean];\ntype MyType = MyTuple[2]; // boolean\n```\n\n### Utility Types\n\nSeveral built-in utility types can be used to manipulate types, below a list of the most common used:\n\n#### Awaited\\<T\\>\n\nConstructs a type that recursively unwraps Promise types.\n\n```typescript\ntype A = Awaited<Promise<string>>; // string\n```\n\n#### Partial\\<T\\>\n\nConstructs a type with all properties of T set to optional.\n\n```typescript\ntype Person = {\n    name: string;\n    age: number;\n};\n\ntype A = Partial<Person>; // { name?: string | undefined; age?: number | undefined; }\n```\n\n#### Required\\<T\\>\n\nConstructs a type with all properties of T set to required.\n\n```typescript\ntype Person = {\n    name?: string;\n    age?: number;\n};\n\ntype A = Required<Person>; // { name: string; age: number; }\n```\n\n#### Readonly\\<T\\>\n\nConstructs a type with all properties of T set to readonly.\n\n<!-- skip -->\n```typescript\ntype Person = {\n    name: string;\n    age: number;\n};\n\ntype A = Readonly<Person>;\n\nconst a: A = { name: 'Simon', age: 17 };\na.name = 'John'; // Invalid\n```\n\n#### Record\\<K, T\\>\n\nConstructs a type with a set of properties K of type T.\n\n```typescript\ntype Product = {\n    name: string;\n    price: number;\n};\n\nconst products: Record<string, Product> = {\n    apple: { name: 'Apple', price: 0.5 },\n    banana: { name: 'Banana', price: 0.25 },\n};\n\nconsole.log(products.apple); // { name: 'Apple', price: 0.5 }\n```\n\n#### Pick\\<T, K\\>\n\nConstructs a type by picking the specified properties K from T.\n\n```typescript\ntype Product = {\n    name: string;\n    price: number;\n};\n\ntype Price = Pick<Product, 'price'>; // { price: number; }\n```\n\n#### Omit\\<T, K\\>\n\nConstructs a type by omitting the specified properties K from T.\n\n```typescript\ntype Product = {\n    name: string;\n    price: number;\n};\n\ntype Name = Omit<Product, 'price'>; // { name: string; }\n```\n\n#### Exclude\\<T, U\\>\n\nConstructs a type by excluding all values of type U from T.\n\n```typescript\ntype Union = 'a' | 'b' | 'c';\ntype MyType = Exclude<Union, 'a' | 'c'>; // b\n```\n\n#### Extract\\<T, U\\>\n\nConstructs a type by extracting all values of type U from T.\n\n```typescript\ntype Union = 'a' | 'b' | 'c';\ntype MyType = Extract<Union, 'a' | 'c'>; // a | c\n```\n\n#### NonNullable\\<T\\>\n\nConstructs a type by excluding null and undefined from T.\n\n```typescript\ntype Union = 'a' | null | undefined | 'b';\ntype MyType = NonNullable<Union>; // 'a' | 'b'\n```\n\n#### Parameters\\<T\\>\n\nExtracts the parameter types of a function type T.\n\n```typescript\ntype Func = (a: string, b: number) => void;\ntype MyType = Parameters<Func>; // [a: string, b: number]\n```\n\n#### ConstructorParameters\\<T\\>\n\nExtracts the parameter types of a constructor function type T.\n\n```typescript\nclass Person {\n    constructor(\n        public name: string,\n        public age: number\n    ) {}\n}\ntype PersonConstructorParams = ConstructorParameters<typeof Person>; // [name: string, age: number]\nconst params: PersonConstructorParams = ['John', 30];\nconst person = new Person(...params);\nconsole.log(person); // Person { name: 'John', age: 30 }\n```\n\n#### ReturnType\\<T\\>\n\nExtracts the return type of a function type T.\n\n```typescript\ntype Func = (name: string) => number;\ntype MyType = ReturnType<Func>; // number\n```\n\n#### InstanceType\\<T\\>\n\nExtracts the instance type of a class type T.\n\n```typescript\nclass Person {\n    name: string;\n\n    constructor(name: string) {\n        this.name = name;\n    }\n\n    sayHello() {\n        console.log(`Hello, my name is ${this.name}!`);\n    }\n}\n\ntype PersonInstance = InstanceType<typeof Person>;\n\nconst person: PersonInstance = new Person('John');\n\nperson.sayHello(); // Hello, my name is John!\n```\n\n#### ThisParameterType\\<T\\>\n\nExtracts the type of 'this' parameter from a function type T.\n\n```typescript\ninterface Person {\n    name: string;\n    greet(this: Person): void;\n}\ntype PersonThisType = ThisParameterType<Person['greet']>; // Person\n```\n\n#### OmitThisParameter\\<T\\>\n\nRemoves the 'this' parameter from a function type T.\n\n```typescript\nfunction capitalize(this: String) {\n    return this[0].toUpperCase + this.substring(1).toLowerCase();\n}\n\ntype CapitalizeType = OmitThisParameter<typeof capitalize>; // () => string\n```\n\n#### ThisType\\<T\\>\n\nServers as a market for a contextual `this` type.\n\n<!-- skip -->\n```typescript\ntype Logger = {\n    log: (error: string) => void;\n};\n\nlet helperFunctions: { [name: string]: Function } & ThisType<Logger> = {\n    hello: function () {\n        this.log('some error'); // Valid as \"log\" is a part of \"this\".\n        this.update(); // Invalid\n    },\n};\n```\n\n#### Uppercase\\<T\\>\n\nMake uppercase the name of the input type T.\n\n```typescript\ntype MyType = Uppercase<'abc'>; // \"ABC\"\n```\n\n#### Lowercase\\<T\\>\n\nMake lowercase the name of the input type T.\n\n```typescript\ntype MyType = Lowercase<'ABC'>; // \"abc\"\n```\n\n#### Capitalize\\<T\\>\n\nCapitalize the name of the input type T.\n\n```typescript\ntype MyType = Capitalize<'abc'>; // \"Abc\"\n```\n\n#### Uncapitalize\\<T\\>\n\nUncapitalize the name of the input type T.\n\n```typescript\ntype MyType = Uncapitalize<'Abc'>; // \"abc\"\n```\n\n#### NoInfer\\<T\\>\n\nNoInfer is a utility type designed to block the automatic inference of types within the scope of a generic function.\n\nExample:\n\n```typescript\n// Automatic inference of types within the scope of a generic function.\nfunction fn<T extends string>(x: T[], y: T) {\n    return x.concat(y);\n}\nconst r = fn(['a', 'b'], 'c'); // Type here is (\"a\" | \"b\" | \"c\")[]\n```\n\nWith NoInfer:\n\n<!-- skip -->\n```typescript\n// Example function that uses NoInfer to prevent type inference\nfunction fn2<T extends string>(x: T[], y: NoInfer<T>) {\n    return x.concat(y);\n}\n\nconst r2 = fn2(['a', 'b'], 'c'); // Error: Type Argument of type '\"c\"' is not assignable to parameter of type '\"a\" | \"b\"'.\n```\n\n## Others\n\n### Errors and Exception Handling\n\nTypeScript allows you to catch and handle errors using standard JavaScript error handling mechanisms:\n\nTry-Catch-Finally Blocks:\n\n```typescript\ntry {\n    // Code that might throw an error\n} catch (error) {\n    // Handle the error\n} finally {\n    // Code that always executes, finally is optional\n}\n```\n\nYou can also handle different types of error:\n\n```typescript\ntry {\n    // Code that might throw different types of errors\n} catch (error) {\n    if (error instanceof TypeError) {\n        // Handle TypeError\n    } else if (error instanceof RangeError) {\n        // Handle RangeError\n    } else {\n        // Handle other errors\n    }\n}\n```\n\nCustom Error Types:\n\nIt is possible to specify more specific error by extending on the Error `class`:\n\n```typescript\nclass CustomError extends Error {\n    constructor(message: string) {\n        super(message);\n        this.name = 'CustomError';\n    }\n}\n\nthrow new CustomError('This is a custom error.');\n```\n\n### Mixin classes\n\nMixin classes allow you to combine and compose behavior from multiple classes into a single class. They provide a way to reuse and extend functionality without the need for deep inheritance chains.\n\n```typescript\nabstract class Identifiable {\n    name: string = '';\n    logId() {\n        console.log('id:', this.name);\n    }\n}\nabstract class Selectable {\n    selected: boolean = false;\n    select() {\n        this.selected = true;\n        console.log('Select');\n    }\n    deselect() {\n        this.selected = false;\n        console.log('Deselect');\n    }\n}\nclass MyClass {\n    constructor() {}\n}\n\n// Extend MyClass to include the behavior of Identifiable and Selectable\ninterface MyClass extends Identifiable, Selectable {}\n\n// Function to apply mixins to a class\nfunction applyMixins(source: any, baseCtors: any[]) {\n    baseCtors.forEach(baseCtor => {\n        Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => {\n            let descriptor = Object.getOwnPropertyDescriptor(\n                baseCtor.prototype,\n                name\n            );\n            if (descriptor) {\n                Object.defineProperty(source.prototype, name, descriptor);\n            }\n        });\n    });\n}\n\n// Apply the mixins to MyClass\napplyMixins(MyClass, [Identifiable, Selectable]);\nlet o = new MyClass();\no.name = 'abc';\no.logId();\no.select();\n```\n\n### Asynchronous Language Features\n\nAs TypeScript is a superset of JavaScript, it has built-in asynchronous language features of JavaScript as:\n\nPromises:\n\nPromises are a way to handle asynchronous operations and their results using methods like `.then()` and `.catch()` to handle success and error conditions.\n\nTo learn more: [https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)\n\nAsync/await:\n\nAsync/await keywords are a way to provide a more synchronous-looking syntax for working with Promises. The `async` keyword is used to define an asynchronous function, and the `await` keyword is used within an async function to pause execution until a Promise is resolved or rejected.\n\nTo learn more:\n[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function)\n[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await)\n\nThe following API are well supported in TypeScript:\n\nFetch API:\n[https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API)\n\nWeb Workers:\n[https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API)\n\nShared Workers:\n[https://developer.mozilla.org/en-US/docs/Web/API/SharedWorker](https://developer.mozilla.org/en-US/docs/Web/API/SharedWorker)\n\nWebSocket:\n[https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API)\n\n### Iterators and Generators\n\nBoth Iterators and Generators are well supported in TypeScript.\n\nIterators are objects that implement the iterator protocol, providing a way to access elements of a collection or sequence one by one. It is a structure that contains a pointer to the next element in the iteration. They have a `next()` method that returns the next value in the sequence along with a boolean indicating if the sequence is `done`.\n\n```typescript\nclass NumberIterator implements Iterable<number> {\n    private current: number;\n\n    constructor(\n        private start: number,\n        private end: number\n    ) {\n        this.current = start;\n    }\n\n    public next(): IteratorResult<number> {\n        if (this.current <= this.end) {\n            const value = this.current;\n            this.current++;\n            return { value, done: false };\n        } else {\n            return { value: undefined, done: true };\n        }\n    }\n\n    [Symbol.iterator](): Iterator<number> {\n        return this;\n    }\n}\n\nconst iterator = new NumberIterator(1, 3);\n\nfor (const num of iterator) {\n    console.log(num);\n}\n```\n\nGenerators are special functions defined using the `function*` syntax that simplifies the creation of iterators. They use the `yield` keyword to define the sequence of values and automatically pause and resume execution when values are requested.\n\nGenerators make it easier to create iterators and are especially useful for working with large or infinite sequences.\n\nExample:\n\n```typescript\nfunction* numberGenerator(start: number, end: number): Generator<number> {\n    for (let i = start; i <= end; i++) {\n        yield i;\n    }\n}\n\nconst generator = numberGenerator(1, 5);\n\nfor (const num of generator) {\n    console.log(num);\n}\n```\n\nTypeScript also supports async iterators and async Generators.\n\nTo learn more:\n\n[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Generator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Generator)\n\n[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Iterator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Iterator)\n\n### TsDocs JSDoc Reference\n\nWhen working with a JavaScript code base, it is possible to help TypeScript to infer the right Type by using JSDoc comments with additional annotation to provide type information.\n\nExample:\n\n```typescript\n/**\n * Computes the power of a given number\n * @constructor\n * @param {number} base – The base value of the expression\n * @param {number} exponent – The exponent value of the expression\n */\nfunction power(base: number, exponent: number) {\n    return Math.pow(base, exponent);\n}\npower(10, 2); // function power(base: number, exponent: number): number\n```\n\nFull documentation is provided to this link:\n[https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html](https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html)\n\nFrom version 3.7 it is possible to generate .d.ts type definitions from JavaScript JSDoc syntax.\nMore information can be found here:\n[https://www.typescriptlang.org/docs/handbook/declaration-files/dts-from-js.html](https://www.typescriptlang.org/docs/handbook/declaration-files/dts-from-js.html)\n\n### @types\n\nPackages under the @types organization are special package naming conventions used to provide type definitions for existing JavaScript libraries or modules. For instance using:\n\n```shell\nnpm install --save-dev @types/lodash\n```\n\nWill install the type definitions of `lodash` in your current project.\n\nTo contribute to the type definitions of @types package, please submit a pull request to [https://github.com/DefinitelyTyped/DefinitelyTyped](https://github.com/DefinitelyTyped/DefinitelyTyped).\n\n### JSX\n\nJSX (JavaScript XML) is an extension to the JavaScript language syntax that allows you to write HTML-like code within your JavaScript or TypeScript files. It is commonly used in React to define the HTML structure.\n\nTypeScript extends the capabilities of JSX by providing type checking and static analysis.\n\nTo use JSX you need to set the `jsx` compiler option in your `tsconfig.json` file. Two common configuration options:\n\n* \"preserve\": emit .jsx files with the JSX unchanged. This option tells TypeScript to keep the JSX syntax as-is and not transform it during the compilation process. You can use this option if you have a separate tool, like Babel, that handles the transformation.\n* \"react\": enables TypeScript's built-in JSX transformation. React.createElement will be used.\n\nAll options are available here:\n[https://www.typescriptlang.org/tsconfig#jsx](https://www.typescriptlang.org/tsconfig#jsx)\n\n### ES6 Modules\n\nTypeScript does support ES6 (ECMAScript 2015) and many subsequent versions. This means you can use ES6 syntax, such as arrow functions, template literals, classes, modules, destructuring, and more.\n\nTo enable ES6 features in your project, you can specify the `target` property in the tsconfig.json.\n\nA configuration example:\n\n```json\n{\n  \"compilerOptions\": {\n    \"target\": \"es6\",\n    \"module\": \"es6\",\n    \"moduleResolution\": \"node\",\n    \"sourceMap\": true,\n    \"outDir\": \"dist\"\n  },\n  \"include\": [\"src\"]\n}\n```\n\n### ES7 Exponentiation Operator\n\nThe exponentiation (`**`) operator computes the value obtained by raising the first operand to the power of the second operand. It functions similarly to `Math.pow()`, but with the added capability of accepting BigInts as operands.\nTypeScript fully supports this operator using as `target` in your tsconfig.json file `es2016` or larger version.\n\n```typescript\nconsole.log(2 ** (2 ** 2)); // 16\n```\n\n### The for-await-of Statement\n\nThis is a JavaScript feature fully supported in TypeScript which allows you to iterate over asynchronous iterable objects from target version es2018.\n\n```typescript\nasync function* asyncNumbers(): AsyncIterableIterator<number> {\n    yield Promise.resolve(1);\n    yield Promise.resolve(2);\n    yield Promise.resolve(3);\n}\n\n(async () => {\n    for await (const num of asyncNumbers()) {\n        console.log(num);\n    }\n})();\n```\n\n### New target meta-property\n\nYou can use in TypeScript the `new.target` meta-property which enables you to determine if a function or constructor was invoked using the new operator. It allows you to detect whether an object was created as a result of a constructor call.\n\n```typescript\nclass Parent {\n    constructor() {\n        console.log(new.target); // Logs the constructor function used to create an instance\n    }\n}\n\nclass Child extends Parent {\n    constructor() {\n        super();\n    }\n}\n\nconst parentX = new Parent(); // [Function: Parent]\nconst child = new Child(); // [Function: Child]\n```\n\n### Dynamic Import Expressions\n\nIt is possible to conditionally load modules or lazy load them on-demand using the ECMAScript proposal for dynamic import which is supported in TypeScript.\n\nThe syntax for dynamic import expressions in TypeScript is as follows:\n\n<!-- skip -->\n```typescript\nasync function renderWidget() {\n    const container = document.getElementById('widget');\n    if (container !== null) {\n        const widget = await import('./widget'); // Dynamic import\n        widget.render(container);\n    }\n}\n\nrenderWidget();\n```\n\n### \"tsc –watch\"\n\nThis command starts a TypeScript compiler with `--watch` parameter, with the ability to automatically recompile TypeScript files whenever they are modified.\n\n```shell\ntsc --watch\n```\n\nStarting from TypeScript version 4.9, file monitoring primarily relies on file system events, automatically resorting to polling if an event-based watcher cannot be established.\n\n### Non-null Assertion Operator\n\nThe Non-null Assertion Operator (Postfix !) also called Definite Assignment Assertions is a TypeScript feature that allows you to assert that a variable or property is not null or undefined, even if TypeScript's static type analysis suggests that it might be. With this feature it is possible to remove any explicit checking.\n\n```typescript\ntype Person = {\n    name: string;\n};\n\nconst printName = (person?: Person) => {\n    console.log(`Name is ${person!.name}`);\n};\n```\n\n### Defaulted declarations\n\nDefaulted declarations are used when a variable or parameter is assigned a default value. This means that if no value is provided for that variable or parameter, the default value will be used instead.\n\n```typescript\nfunction greet(name: string = 'Anonymous'): void {\n    console.log(`Hello, ${name}!`);\n}\ngreet(); // Hello, Anonymous!\ngreet('John'); // Hello, John!\n```\n\n### Optional Chaining\n\nThe optional chaining operator `?.` works like the regular dot operator (`.`) for accessing properties or methods. However, it gracefully handles null or undefined values by terminating the expression and returning `undefined`, instead of throwing an error.\n\n```typescript\ntype Person = {\n    name: string;\n    age?: number;\n    address?: {\n        street?: string;\n        city?: string;\n    };\n};\n\nconst person: Person = {\n    name: 'John',\n};\n\nconsole.log(person.address?.city); // undefined\n```\n\n### Nullish coalescing operator\n\nThe nullish coalescing operator `??` returns the right-hand side value if the left-hand side is `null` or `undefined`; otherwise, it returns the left-hand side value.\n\n```typescript\nconst foo = null ?? 'foo';\nconsole.log(foo); // foo\n\nconst baz = 1 ?? 'baz';\nconst baz2 = 0 ?? 'baz';\nconsole.log(baz); // 1\nconsole.log(baz2); // 0\n```\n\n### Template Literal Types\n\nTemplate Literal Types allow to manipulate string value at type level and generate new string types based on existing ones. They are useful to create more expressive and precise types from string-based operations.\n\n```typescript\ntype Department = 'engineering' | 'hr';\ntype Language = 'english' | 'spanish';\ntype Id = `${Department}-${Language}-id`; // \"engineering-english-id\" | \"engineering-spanish-id\" | \"hr-english-id\" | \"hr-spanish-id\"\n```\n\n### Function overloading\n\nFunction overloading allows you to define multiple function signatures for the same function name, each with different parameter types and return type.\nWhen you call an overloaded function, TypeScript uses the provided arguments to determine the correct function signature:\n\n```typescript\nfunction makeGreeting(name: string): string;\nfunction makeGreeting(names: string[]): string[];\n\nfunction makeGreeting(person: unknown): unknown {\n    if (typeof person === 'string') {\n        return `Hi ${person}!`;\n    } else if (Array.isArray(person)) {\n        return person.map(name => `Hi, ${name}!`);\n    }\n    throw new Error('Unable to greet');\n}\n\nmakeGreeting('Simon');\nmakeGreeting(['Simone', 'John']);\n```\n\n### Recursive Types\n\nA Recursive Type is a type that can refer to itself. This is useful for defining data structures that have a hierarchical or recursive structure (potentially infinite nesting), such as linked lists, trees, and graphs.\n\n```typescript\ntype ListNode<T> = {\n    data: T;\n    next: ListNode<T> | undefined;\n};\n```\n\n### Recursive Conditional Types\n\nIt is possible to define complex type relationships using logic and recursion in TypeScript.\nLet’s break it down in simple terms:\n\nConditional Types: allows you to define types based on boolean conditions:\n\n```typescript\ntype CheckNumber<T> = T extends number ? 'Number' : 'Not a number';\ntype A = CheckNumber<123>; // 'Number'\ntype B = CheckNumber<'abc'>; // 'Not a number'\n```\n\nRecursion: means a type definition that refers to itself within its own definition:\n\n```typescript\ntype Json = string | number | boolean | null | Json[] | { [key: string]: Json };\n\nconst data: Json = {\n    prop1: true,\n    prop2: 'prop2',\n    prop3: {\n        prop4: [],\n    },\n};\n```\n\nRecursive Conditional Types combine both conditional logic and recursion. It means that a type definition can depend on itself through conditional logic, creating complex and flexible type relationships.\n\n```typescript\ntype Flatten<T> = T extends Array<infer U> ? Flatten<U> : T;\n\ntype NestedArray = [1, [2, [3, 4], 5], 6];\ntype FlattenedArray = Flatten<NestedArray>; // 2 | 3 | 4 | 5 | 1 | 6\n```\n\n### ECMAScript Module Support in Node\n\nNode.js added support for ECMAScript Modules starting from version 15.3.0, and TypeScript has had ECMAScript Module Support for Node.js since version 4.7. This support can be enabled by using the `module` property with the value `nodenext` in the tsconfig.json file. Here's an example:\n\n```json\n{\n  \"compilerOptions\": {\n    \"module\": \"nodenext\",\n    \"outDir\": \"./lib\",\n    \"declaration\": true\n  }\n}\n```\n\nNode.js supports two file extensions for modules: `.mjs` for ES modules and `.cjs` for CommonJS modules. The equivalent file extensions in TypeScript are `.mts` for ES modules and `.cts` for CommonJS modules. When the TypeScript compiler transpiles these files to JavaScript, it will create `.mjs` and `.cjs` files.\n\nIf you want to use ES modules in your project, you can set the `type` property to \"module\" in your package.json file. This instructs Node.js to treat the project as an ES module project.\n\nAdditionally, TypeScript also supports type declarations in .d.ts files. These declaration files provide type information for libraries or modules written in TypeScript, allowing other developers to utilize them with TypeScript's type checking and auto-completion features.\n\n### Assertion Functions\n\nIn TypeScript, assertion functions are functions that indicate the verification of a specific condition based on their return value. In their simplest form, an assert function examines a provided predicate and raises an error when the predicate evaluates to false.\n\n```typescript\nfunction isNumber(value: unknown): asserts value is number {\n    if (typeof value !== 'number') {\n        throw new Error('Not a number');\n    }\n}\n```\n\nOr can be declared as function expression:\n\n```typescript\ntype AssertIsNumber = (value: unknown) => asserts value is number;\nconst isNumber: AssertIsNumber = value => {\n    if (typeof value !== 'number') {\n        throw new Error('Not a number');\n    }\n};\n```\n\nAssertion functions share similarities with type guards. Type guards were initially introduced to perform runtime checks and ensure the type of a value within a specific scope.\nSpecifically, a type guard is a function that evaluates a type predicate and returns a boolean value indicating whether the predicate is true or false. This differs slightly from assertion functions,where the intention is to throw an error rather than returning false when the predicate is not satisfied.\n\nExample of type guard:\n\n```typescript\nconst isNumber = (value: unknown): value is number => typeof value === 'number';\n```\n\n### Variadic Tuple Types\n\nVariadic Tuple Types are a features introduces in TypeScript version 4.0, let’s start to learn them by revise what is a tuple:\n\nA tuple type is an array which has a defined length, and were the type of each element is known:\n\n```typescript\ntype Student = [string, number];\nconst [name, age]: Student = ['Simone', 20];\n```\n\nThe term \"variadic\" means indefinite arity (accept a variable number of arguments).\n\nA variadic tuple is a tuple type which has all the property as before but the exact shape is not defined yet:\n\n```typescript\ntype Bar<T extends unknown[]> = [boolean, ...T, number];\n\ntype A = Bar<[boolean]>; // [boolean, boolean, number]\ntype B = Bar<['a', 'b']>; // [boolean, 'a', 'b', number]\ntype C = Bar<[]>; // [boolean, number]\n```\n\nIn the previous code we can see that the tuple shape is defined by the `T` generic passed in.\n\nVariadic tuples can accept multiple generics make them very flexible:\n\n```typescript\ntype Bar<T extends unknown[], G extends unknown[]> = [...T, boolean, ...G];\n\ntype A = Bar<[number], [string]>; // [number, boolean, string]\ntype B = Bar<['a', 'b'], [boolean]>; // [\"a\", \"b\", boolean, boolean]\n```\n\nWith the new variadic tuples we can use:\n\n* The spreads in tuple type syntax can now be generic, so we can represent higher-order operation on tuples and arrays even when we do not know the actual types we are operating over.\n* The rest elements can occur anywhere in a tuple.\n\nExample:\n\n```typescript\ntype Items = readonly unknown[];\n\nfunction concat<T extends Items, U extends Items>(\n    arr1: T,\n    arr2: U\n): [...T, ...U] {\n    return [...arr1, ...arr2];\n}\n\nconcat([1, 2, 3], ['4', '5', '6']); // [1, 2, 3, \"4\", \"5\", \"6\"]\n```\n\n### Boxed types\n\nBoxed types refer to the wrapper objects that are used to represent primitive types as objects. These wrapper objects provide additional functionality and methods that are not available directly on the primitive values.\n\nWhen you access a method like `charAt` or `normalize` on a `string` primitive, JavaScript wraps it in a `String` object, calls the method, and then throws the object away.\n\nDemonstration:\n\n```typescript\nconst originalNormalize = String.prototype.normalize;\nString.prototype.normalize = function () {\n    console.log(this, typeof this);\n    return originalNormalize.call(this);\n};\nconsole.log('\\u0041'.normalize());\n```\n\nTypeScript represents this differentiation by providing separate types for the primitives and their corresponding object wrappers:\n\n* string => String\n* number => Number\n* boolean => Boolean\n* symbol => Symbol\n* bigint => BigInt\n\nThe boxed types are usually not needed. Avoid using boxed types and instead use type for the primitives,  for instance `string` instead of `String`.\n\n### Covariance and Contravariance in TypeScript\n\nCovariance and Contravariance are used to describe how relationships work when dealing with inheritance or assignment of types.\n\nCovariance means that a type relationship preserves the direction of inheritance or assignment, so if a type A is a subtype of type B, then an array of type A is also considered a subtype of an array of type B. The important thing to note here is that the subtype relationship is maintained this means that Covariance accept subtype but doesn't accept supertype.\n\nContravariance means that a type relationship reverses the direction of inheritance or assignment, so if a type A is a subtype of type B, then an array of type B is considered a subtype of an array of type A. The subtype relationship is reversed this means that Contravariance accept supertype but doesn't accept subtype.\n\nNotes: Bivariance means accept both supertype & subtype.\n\nExample: Let's say we have a space for all animals and a separate space just for dogs.\n\nIn Covariance, you can put all the dogs in the animals space because dogs are a type of animal. But you cannot put all the animals in the dog space because there might be other animals mixed in.\n\nIn Contravariance, you cannot put all the animals in the dogs space because the animals space might contain other animals as well. However, you can put all the dogs in the animal space because all dogs are also animals.\n\n<!-- skip -->\n```typescript\n// Covariance example\nclass Animal {\n    name: string;\n    constructor(name: string) {\n        this.name = name;\n    }\n}\n\nclass Dog extends Animal {\n    breed: string;\n    constructor(name: string, breed: string) {\n        super(name);\n        this.breed = breed;\n    }\n}\n\nlet animals: Animal[] = [];\nlet dogs: Dog[] = [];\n\n// Covariance allows assigning subtype (Dog) array to supertype (Animal) array\nanimals = dogs;\ndogs = animals; // Invalid: Type 'Animal[]' is not assignable to type 'Dog[]'\n\n// Contravariance example\ntype Feed<in T> = (animal: T) => void;\n\nlet feedAnimal: Feed<Animal> = (animal: Animal) => {\n    console.log(`Animal name: ${animal.name}`);\n};\n\nlet feedDog: Feed<Dog> = (dog: Dog) => {\n    console.log(`Dog name: ${dog.name}, Breed: ${dog.breed}`);\n};\n\n// Contravariance allows assigning supertype (Animal) callback to subtype (Dog) callback\nfeedDog = feedAnimal;\nfeedAnimal = feedDog; // Invalid: Type 'Feed<Dog>' is not assignable to type 'Feed<Animal>'.\n```\n\nIn TypeScript, type relationships for arrays are covariant, while type relationships for function parameters are contravariant. This means that TypeScript exhibits both covariance and contravariance, depending on the context.\n\n#### Optional Variance Annotations for Type Parameters\n\nAs of TypeScript 4.7.0, we can use the `out` and `in` keywords to be specific about Variance annotation.\n\nFor Covariant, use the `out` keyword:\n\n```typescript\ntype AnimalCallback<out T> = () => T; // T is Covariant here\n```\n\nAnd for Contravariant, use the `in` keyword:\n\n```typescript\ntype AnimalCallback<in T> = (value: T) => void; // T is Contravariance here\n```\n\n### Template String Pattern Index Signatures\n\nTemplate string pattern index signatures allow us to define flexible index signatures using template string patterns. This feature enables us to create objects that can be indexed with specific patterns of string keys, providing more control and specificity when accessing and manipulating properties.\n\nTypeScript from version 4.4 allows index signatures for symbols and template string patterns.\n\n```typescript\nconst uniqueSymbol = Symbol('description');\n\ntype MyKeys = `key-${string}`;\n\ntype MyObject = {\n    [uniqueSymbol]: string;\n    [key: MyKeys]: number;\n};\n\nconst obj: MyObject = {\n    [uniqueSymbol]: 'Unique symbol key',\n    'key-a': 123,\n    'key-b': 456,\n};\n\nconsole.log(obj[uniqueSymbol]); // Unique symbol key\nconsole.log(obj['key-a']); // 123\nconsole.log(obj['key-b']); // 456\n```\n\n### The satisfies Operator\n\nThe `satisfies`  allows you to check if a given type satisfies a specific interface or condition. In other words, it ensures that a type has all the required properties and methods of a specific interface. It is a way to ensure a variable fits into a definition of a type.\nHere is an example:\n\n<!-- skip -->\n```typescript\ntype Columns = 'name' | 'nickName' | 'attributes';\n\ntype User = Record<Columns, string | string[] | undefined>;\n\n// Type Annotation using `User`\nconst user: User = {\n    name: 'Simone',\n    nickName: undefined,\n    attributes: ['dev', 'admin'],\n};\n\n// In the following lines, TypeScript won't be able to infer properly\nuser.attributes?.map(console.log); // Property 'map' does not exist on type 'string | string[]'. Property 'map' does not exist on type 'string'.\nuser.nickName; // string | string[] | undefined\n\n// Type assertion using `as`\nconst user2 = {\n    name: 'Simon',\n    nickName: undefined,\n    attributes: ['dev', 'admin'],\n} as User;\n\n// Here too, TypeScript won't be able to infer properly\nuser2.attributes?.map(console.log); // Property 'map' does not exist on type 'string | string[]'. Property 'map' does not exist on type 'string'.\nuser2.nickName; // string | string[] | undefined\n\n// Using `satisfies` operators we can properly infer the types now\nconst user3 = {\n    name: 'Simon',\n    nickName: undefined,\n    attributes: ['dev', 'admin'],\n} satisfies User;\n\nuser3.attributes?.map(console.log); // TypeScript infers correctly: string[]\nuser3.nickName; // TypeScript infers correctly: undefined\n```\n\n### Type-Only Imports and Export\n\nType-Only Imports and Export allows you to import or export types without importing or exporting the values or functions associated with those types. This can be useful for reducing the size of your bundle.\n\nTo use type-only imports, you can use the `import type` keyword.\n\nTypeScript permits using both declaration and implementation file extensions (.ts, .mts, .cts, and .tsx) in type-only imports, regardless of `allowImportingTsExtensions` settings.\n\nFor example:\n\n<!-- skip -->\n```typescript\nimport type { House } from './house.ts';\n```\n\nThe following are supported forms:\n\n<!-- skip -->\n```typescript\nimport type T from './mod';\nimport type { A, B } from './mod';\nimport type * as Types from './mod';\nexport type { T };\nexport type { T } from './mod';\n```\n\n### using declaration and Explicit Resource Management\n\nA `using` declaration is a block-scoped, immutable binding, similar to `const`, used for managing disposable resources. When initialized with a value, the `Symbol.dispose` method of that value is recorded and subsequently executed upon exiting the enclosing block scope.\n\nThis is based on ECMAScript's Resource Management feature, which is useful for performing essential cleanup tasks after object creation, such as closing connections, deleting files, and releasing memory.\n\nNotes:\n\n* Due to its recent introduction in TypeScript version 5.2, most runtimes lack native support. You'll need polyfills for: `Symbol.dispose`, `Symbol.asyncDispose`, `DisposableStack`, `AsyncDisposableStack`, `SuppressedError`.\n* Additionally, you will need to configure your tsconfig.json as follows:\n\n```json\n{\n    \"compilerOptions\": {\n        \"target\": \"es2022\",\n        \"lib\": [\"es2022\", \"esnext.disposable\", \"dom\"]\n    }\n}\n```\n\nExample:\n\n<!-- skip -->\n```typescript\n//@ts-ignore\nSymbol.dispose ??= Symbol('Symbol.dispose'); // Simple polify\n\nconst doWork = (): Disposable => {\n    return {\n        [Symbol.dispose]: () => {\n            console.log('disposed');\n        },\n    };\n};\n\nconsole.log(1);\n\n{\n    using work = doWork(); // Resource is declared\n    console.log(2);\n} // Resource is disposed (e.g., `work[Symbol.dispose]()` is evaluated)\n\nconsole.log(3);\n```\n\nThe code will log:\n\n```shell\n1\n2\ndisposed\n3\n```\n\nA resource eligible for disposal must adhere to the `Disposable` interface:\n\n```typescript\n// lib.esnext.disposable.d.ts\ninterface Disposable {\n    [Symbol.dispose](): void;\n}\n```\n\nThe `using` declarations record resource disposal operations in a stack, ensuring they are disposed in reverse order of declaration:\n\n<!-- skip -->\n```typescript\n{\n    using j = getA(),\n        y = getB();\n    using k = getC();\n} // disposes `C`, then `B`, then `A`.\n```\n\nResources are guaranteed to be disposed, even if subsequent code or exceptions occur. This may lead to disposal potentially throwing an exception, possibly suppressing another. To retain information on suppressed errors, a new native exception, `SuppressedError`, is introduced.\n\n#### await using declaration\n\nAn `await using` declaration handles an asynchronously disposable resource. The value must have a `Symbol.asyncDispose` method, which will be awaited at the block's end.\n\n<!-- skip -->\n```typescript\nasync function doWorkAsync() {\n    await using work = doWorkAsync(); // Resource is declared\n} // Resource is disposed (e.g., `await work[Symbol.asyncDispose]()` is evaluated)\n```\n\nFor an asynchronously disposable resource, it must adhere to either the `Disposable` or `AsyncDisposable` interface:\n\n```typescript\n// lib.esnext.disposable.d.ts\ninterface AsyncDisposable {\n    [Symbol.asyncDispose](): Promise<void>;\n}\n```\n\n<!-- skip -->\n```typescript\n//@ts-ignore\nSymbol.asyncDispose ??= Symbol('Symbol.asyncDispose'); // Simple polify\n\nclass DatabaseConnection implements AsyncDisposable {\n    // A method that is called when the object is disposed asynchronously\n    [Symbol.asyncDispose]() {\n        // Close the connection and return a promise\n        return this.close();\n    }\n\n    async close() {\n        console.log('Closing the connection...');\n        await new Promise(resolve => setTimeout(resolve, 1000));\n        console.log('Connection closed.');\n    }\n}\n\nasync function doWork() {\n    // Create a new connection and dispose it asynchronously when it goes out of scope\n    await using connection = new DatabaseConnection(); //  Resource is declared\n    console.log('Doing some work...');\n} // Resource is disposed (e.g., `await connection[Symbol.asyncDispose]()` is evaluated)\n\ndoWork();\n```\n\nThe code logs:\n\n```shell\nDoing some work...\nClosing the connection...\nConnection closed.\n```\n\nThe `using` and `await using` declarations are allowed in Statements: `for`, `for-in`, `for-of`, `for-await-of`, `switch`.\n\n### Import Attributes\n\nTypeScript 5.3's Import Attributes (labels for imports) tell the runtime how to handle modules (JSON, etc.). This improves security by ensuring clear imports and aligns with Content Security Policy (CSP) for safer resource loading. TypeScript ensures they are valid but lets the runtime handle their interpretation for specific module handling.\n\nExample:\n\n<!-- skip -->\n```typescript\nimport config from './config.json' with { type: 'json' };\n```\n\nwith dynamic import:\n\n<!-- skip -->\n```typescript\nconst config = import('./config.json', { with: { type: 'json' } });\n```\n"
  },
  {
    "path": "tools/.markdownlint.json",
    "content": "{\n    \"code-block-style\": {\n        \"style\": \"fenced\"\n    },\n    \"code-fence-style\": {\n        \"style\": \"backtick\"\n    },\n    \"emphasis-style\": {\n        \"style\": \"asterisk\"\n    },\n    \"fenced-code-language\": {\n        \"allowed_languages\": [\n            \"shell\",\n            \"json\",\n            \"typescript\",\n            \"javascript\",\n            \"text\"\n        ],\n        \"language_only\": true\n    },\n    \"heading-style\": {\n        \"style\": \"atx\"\n    },\n    \"hr-style\": {\n        \"style\": \"---\"\n    },\n    \"line-length\": false,\n    \"no-duplicate-heading\": {\n        \"siblings_only\": true\n    },\n    \"ol-prefix\": {\n        \"style\": \"ordered\"\n    },\n    \"proper-names\": {\n        \"code_blocks\": false,\n        \"names\": [\n            \"TypeScript\",\n            \"Ctrl\",\n            \"JavaScript\",\n            \"Markdown\",\n            \"Node.js\",\n            \"Visual Studio Code\",\n            \"Microsoft\",\n            \"LinkedIn\",\n            \"GitHub\",\n            \"Twitter\",\n            \"Email\",\n            \"IntelliSense\",\n            \"ECMAScript\"\n        ]\n    },\n    \"required-headings\": false,\n    \"strong-style\": {\n        \"style\": \"asterisk\"\n    },\n    \"ul-style\": {\n        \"style\": \"asterisk\"\n    }\n}"
  },
  {
    "path": "tools/.nvmrc",
    "content": "v19.7.0\n"
  },
  {
    "path": "tools/.prettierrc",
    "content": "{\n    \"trailingComma\": \"es5\",\n    \"tabWidth\": 4,\n    \"semi\": true,\n    \"singleQuote\": true,\n    \"printWidth\": 80,\n    \"arrowParens\": \"avoid\"\n}"
  },
  {
    "path": "tools/.vscode/launch.json",
    "content": "{\n    \"version\": \"0.2.0\",\n    \"configurations\": [\n        {\n            \"name\": \"Debug lint\",\n            \"type\": \"node\",\n            \"request\": \"launch\",\n            \"runtimeExecutable\": \"node\",\n            \"runtimeArgs\": [\n                \"--nolazy\",\n                \"-r\",\n                \"${workspaceRoot}/node_modules/ts-node/register/transpile-only\"\n            ],\n            \"args\": [\n                \"lint.ts\",\n                \"--example\",\n                \"hello\"\n            ],\n            \"cwd\": \"${workspaceRoot}\",\n            \"internalConsoleOptions\": \"openOnSessionStart\",\n            \"skipFiles\": [\n                \"<node_internals>/**\",\n                \"node_modules/**\"\n            ]\n        },\n        {\n            \"name\": \"Python: Current File\",\n            \"type\": \"python\",\n            \"request\": \"launch\",\n            \"program\": \"${file}\",\n            \"console\": \"integratedTerminal\",\n            \"justMyCode\": true\n        }\n    ]\n}"
  },
  {
    "path": "tools/.vscode/settings.json",
    "content": "{\n    \"editor.formatOnSave\": true,\n}"
  },
  {
    "path": "tools/Makefile",
    "content": "format:\n\tnpm run format\n\ncheck:\n\tnpm run check\n\nwebsite:\n\tpython3 ./make-website-content.py\n\nwebsite-deploy:\n\tcd ../website && npm run deploy\n\nwebsite-preview:\n\tcd ../website && npm run build && npm run preview\n\nbooks:\n\t./make-books.sh"
  },
  {
    "path": "tools/README.md",
    "content": "# Tools for Working with Markdown Books\n\nIf you're working with Markdown books, here are some essential tools and commands to help you streamline your workflow.\n\n## Installation\n\nBefore you begin, ensure you have Node.js installed. To set up the required dependencies, use the following commands:\n\nIn folder `tools` and `website`:\n\n```shell\nnvm use\nnpm install\n```\n\n```shell\nbrew install pandoc\nbrew install epubcheck\nbrew install --cask calibre\n```\n\n## Commands\n\nUse `make` to run the main commands:\n\n* `make format`: Format Markdown files for books.\n* `make check`: Run several checks to ensure the Markdown files are valid.\n* `make website`: Create different Markdown pages for the website.\n* `make website-preview`: Build and preview website locally.\n* `make website-deploy`: Build and deploy website to GitHub Pages.\n* `make books`: Create .epub books.\n\n### Formatting\n\nConsistent code formatting is crucial. To format all TypeScript snippets, we use Prettier. Execute the following command for formatting:\n\n```shell\nnpm run format\n```\n\n### Compilation\n\nTo compile TypeScript snippets within the Markdown files, utilize the following command:\n\n```shell\nnpm run compile\n```\n\n### Linting\n\nTo ensure that your Markdown files adhere to proper formatting rules, use the linting command:\n\n```shell\nnpm run lint:md\n```\n\n### Linting and Formatting\n\nFor a comprehensive process that includes linting all Markdown files, applying Prettier formatting to all TypeScript snippets, and compiling them using TypeScript, use the following command:\n\n```shell\nnpm run check\n```\n\nThe project uses the [Markdown All in One](https://marketplace.visualstudio.com/items?itemName=yzhang.markdown-all-in-one)Visual Studio Code extension to automatically update the table of contents.\n\nUse the following command to install it:\n\n```shell\ncode --install-extension yzhang.markdown-all-in-one\n```\n\n### Skipping Compilation\n\nIf you have specific snippets in the Markdown files that you don't want to compile, simply add `<!-- skip -->` just before the TypeScript demarcation for those snippets.\n\n### Epub Generation\n\nTo generate Epub files from your Markdown books, navigate to the `tools` folder and run the following command:\n\n```shell\nmake-books.sh\n```\n\nAfter generating the Epub files, thoroughly test them, and once you're satisfied with the results, commit the changes.\n\nThese tools will assist you in efficiently working with Markdown books and ensure a smooth and organized process. Happy writing!\n\n## Debug EPUB Issues\n\nTo debug the EPUB files you create, follow these steps:\n\nFirst, download and install Sigil. You can use the following command to install Sigil:\n\n```shell\nbrew install --cask sigil\n```\n\nNext, run an EPUB check to validate your EPUB file. For example:\n\n```shell\nepubcheck ../downloads/typescript-book.epub\n```\n\nFinally, open the EPUB file using Sigil for detailed inspection.\n\n## How to Contribute to This E-Book\n\nTo contribute to this e-book, follow these steps:\n\n* Update the main Markdown file with your changes.\n* Run `make check` to ensure the linter and other checks pass.\n* Preview the website locally with `make website-preview` to make sure it works as expected.\n* Generate the e-books by running `make books`.\n* Submit your PR and share your awesome contributions!\n"
  },
  {
    "path": "tools/check_toc.py",
    "content": "import re\nimport sys\n\ndef slugify(text):\n    text = text.lower()\n    text = re.sub(r'[^\\w\\s-]', '', text)\n    text = re.sub(r'\\s+', '-', text)\n    return text\n\ndef check_toc(filepath):\n    \"\"\"\n    Checks if all links in the TOC section of a markdown file point to existing headers.\n    \"\"\"\n    with open(filepath, 'r', encoding='utf-8') as f:\n        lines = f.readlines()\n\n    headers = []\n    toc_links = []\n    \n    # Simple state machine to detect TOC section if needed, \n    # but for now we'll just scan all lines for headers and links.\n    # Actually, we should only care about links that look like internal anchors (#...)\n    \n    for line in lines:\n        line = line.strip()\n        \n        # Detect headers\n        header_match = re.match(r'^(#+)\\s+(.+)$', line)\n        if header_match:\n            title = header_match.group(2).strip()\n            # Ignore some specific things if needed, but generally:\n            anchor = slugify(title)\n            headers.append(anchor)\n            \n        # Detect links\n        # simple regex for markdown links [text](#anchor)\n        # We perform findall because there might be multiple links in a line (though rare for TOC)\n        links = re.findall(r'\\[([^\\]]+)\\]\\((#[^)]+)\\)', line)\n        for text, link in links:\n            # clean the link (remove #)\n            anchor_ref = link[1:]\n            toc_links.append({'text': text, 'ref': anchor_ref})\n\n    # Verify\n    broken_links = []\n    for link in toc_links:\n        if link['ref'] not in headers:\n            # Special case: sometimes headers might have duplicate names and some markdown parsers handle it.\n            # But normally GitHub appends -1, -2 etc. We might need to handle that if strict.\n            # For now, let's just check existence.\n            broken_links.append(link)\n\n    return broken_links\n\nif __name__ == \"__main__\":\n    if len(sys.argv) < 2:\n        print(\"Usage: python3 check_toc.py <path_to_markdown>\")\n        sys.exit(1)\n        \n    filepath = sys.argv[1]\n    broken = check_toc(filepath)\n    \n    if broken:\n        print(f\"Found {len(broken)} broken links:\")\n        for b in broken:\n            print(f\"- [{b['text']}](#{b['ref']}) -> Header not found (expected #{b['ref']})\")\n    else:\n        print(\"No broken links found.\")\n"
  },
  {
    "path": "tools/compile.ts",
    "content": "import * as fs from 'fs-extra';\nimport * as path from 'path';\nimport * as ts from \"typescript\";\nimport { marked } from 'marked';\nimport { pipe } from 'fp-ts/function'\nimport { makeFilePath } from './utils';\nimport { languages } from './i18n';\n\nconst TEMP_DIR = 'temp'\nconst SKIP_COMMENT = '<!-- skip -->'\n\ntype ReportsInfo = Readonly<{\n    reports: ts.Diagnostic[],\n    emitSkipped: boolean\n}>\n\ntype TempFilePaths = ReadonlyArray<string>\n\ntype CodeSnippets = ReadonlyArray<string>\n\nconst exitScript = (emitSkipped: boolean) => {\n    const ERROR_CODE = 1\n    const SUCCESS_CODE = 0\n    const exitCode = emitSkipped ? ERROR_CODE : SUCCESS_CODE;\n    console.log(`Process exiting with code '${exitCode}'.`);\n    exitCode === ERROR_CODE && process.exit(exitCode);\n}\n\nconst compileAndReport = (options: ts.CompilerOptions) => (fileNames: TempFilePaths): ReportsInfo => {\n    const program = ts.createProgram(fileNames, options);\n    const emitResult = program.emit();\n\n    const reports = ts\n        .getPreEmitDiagnostics(program)\n        .concat(emitResult.diagnostics);\n\n    return {\n        reports,\n        emitSkipped: emitResult.emitSkipped\n    }\n}\n\nconst logReports = (data: ReportsInfo) => {\n    data.reports.forEach(diagnostic => {\n        if (diagnostic.file) {\n            const { line, character } = ts.getLineAndCharacterOfPosition(diagnostic.file, diagnostic.start!);\n            const message = ts.flattenDiagnosticMessageText(diagnostic.messageText, \"\\n\");\n            console.log(`${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`);\n        } else {\n            console.log(ts.flattenDiagnosticMessageText(diagnostic.messageText, \"\\n\"));\n        }\n    });\n    return data.emitSkipped\n}\n\nconst isTypeScriptCode = (token: marked.Token): token is marked.Tokens.Code => token.type === 'code' && token.lang === 'typescript';\n\nconst isSkipComment = (token: marked.Token): token is marked.Tokens.HTML => token.type === 'html' && token.text === `${SKIP_COMMENT}\\n`;\n\nconst extractCodeSnippets = (markdown: string): CodeSnippets =>\n    pipe(\n        new marked.Lexer(),\n        lexer => lexer.lex(markdown),\n        tokens => {\n            let skipIndex = -1\n            return tokens.reduce<marked.Token[]>((tokens, token, index) => {\n                if (index === skipIndex) {\n                    skipIndex = -1\n                    return [...tokens]\n                }\n                if (isSkipComment(token)) {\n                    skipIndex = index + 1\n                    return [...tokens]\n                }\n                return [...tokens, token]\n            }, [])\n        },\n        tokens => tokens.filter(isTypeScriptCode),\n        codes => codes.map(x => x.text)\n    )\n\nconst makeTempFiles = (snippets: CodeSnippets): TempFilePaths =>\n    snippets.reduce<TempFilePaths>((acc, snippet, index) => {\n        const tempFile = path.join(__dirname, `temp/temp_${index}.ts`);\n        fs.writeFileSync(tempFile, snippet);\n\n        return [\n            ...acc,\n            tempFile\n        ]\n    }, [])\n\nconst processMarkdownFile = (inputPath: string): void =>\n    pipe(\n        () => fs.removeSync(TEMP_DIR),\n        () => fs.ensureDirSync(TEMP_DIR),\n        () => fs.readFileSync(inputPath, 'utf-8'),\n        extractCodeSnippets,\n        makeTempFiles,\n        compileAndReport({\n            noEmitOnError: true,\n            noImplicitAny: true,\n            target: ts.ScriptTarget.ESNext,\n            module: ts.ModuleKind.CommonJS,\n            moduleDetection: ts.ModuleDetectionKind.Force,\n            noUnusedLocals: false,\n            strict: true\n        }),\n        logReports,\n        exitScript,\n    )\n\nfor (const item of languages) {\n    console.log(\"Compiling: \", item)\n    processMarkdownFile(makeFilePath(item));\n}\n"
  },
  {
    "path": "tools/config.ts",
    "content": "export const PRETTIER_CONFIG_FILE_PATH = './.prettierrc'\n\nexport const CODE_BLOCK_TS_REGEX = /```typescript([\\s\\S]*?)```/g;"
  },
  {
    "path": "tools/format.ts",
    "content": "import * as prettier from 'prettier';\nimport * as fs from 'fs';\nimport { Language, languages } from './i18n';\nimport { PrettierOptions, getPrettierOptions, makeFilePath } from './utils';\nimport { CODE_BLOCK_TS_REGEX } from './config';\n\nconst formatCodeBlocksInMarkdownFile = async (filePath: string, options: PrettierOptions, language: Language): Promise<void> => {\n    const markdown = await fs.promises.readFile(filePath, 'utf-8');\n\n    let formattedMarkdown = markdown;\n    let match;\n    while ((match = CODE_BLOCK_TS_REGEX.exec(markdown)) !== null) {\n        const codeBlock = match[0];\n        const code = match[1].trim();\n        const formattedCode = await prettier.format(code, {\n            parser: 'typescript',\n            ...options,\n        });\n        formattedMarkdown = formattedMarkdown.replace(codeBlock, `\\`\\`\\`typescript\\n${formattedCode}\\`\\`\\``);\n    }\n\n    await fs.promises.writeFile(filePath, formattedMarkdown, 'utf-8');\n    console.log(`${language} Formatted code blocks have been updated in the file: ${filePath}`);\n}\n\nconst main = async () => {\n    const options = await getPrettierOptions()\n\n    for (const language of languages) {\n        formatCodeBlocksInMarkdownFile(makeFilePath(language), options, language);\n    }\n}\n\nmain()\n\n\n"
  },
  {
    "path": "tools/i18n.ts",
    "content": "export enum Language {\n    en_EN = 'en_EN',\n    zh_CN = 'zh_CN',\n    it_IT = 'it_IT',\n    pt_BR = 'pt_BR',\n    sv_SE = 'sv_SE',\n}\nexport type Languages = [Language.en_EN, Language.zh_CN, Language.it_IT, Language.pt_BR, Language.sv_SE]\n\nexport const languages: Languages = [Language.en_EN, Language.zh_CN, Language.it_IT, Language.pt_BR, Language.sv_SE]"
  },
  {
    "path": "tools/lint.ts",
    "content": "import * as prettier from 'prettier';\nimport * as fs from 'fs';\nimport { Language, languages } from './i18n';\nimport { PrettierOptions, getPrettierOptions, makeFilePath } from './utils';\nimport { CODE_BLOCK_TS_REGEX } from './config';\n\nconst lintCodeBlocksInMarkdownFile = async (filePath: string, options: PrettierOptions, language: Language): Promise<void> => {\n    const markdown = await fs.promises.readFile(filePath, 'utf-8');\n\n    let reportSnippetsNotLinted = '';\n    let match;\n    while ((match = CODE_BLOCK_TS_REGEX.exec(markdown)) !== null) {\n        const code = match[1].trim() + '\\n'\n        const isCodeLinted = await prettier.check(code, {\n            parser: 'typescript',\n            ...options,\n        });\n        if (isCodeLinted === false) {\n            const lineNumber = markdown.substring(0, match.index).split('\\n').length;\n            reportSnippetsNotLinted += `Line ${lineNumber}:\\n`\n            reportSnippetsNotLinted += code\n            reportSnippetsNotLinted += '\\n'\n        }\n    }\n    if (reportSnippetsNotLinted.length === 0) {\n        console.log(`${language} All snippets are linted!`)\n    } else {\n        console.error(`${language} Not all snippets are linted! Please use this command to automatically format the snippets: npm run format\\n`)\n        console.error(reportSnippetsNotLinted)\n        process.exit(1)\n    }\n}\n\nconst main = async () => {\n    const options = await getPrettierOptions()\n\n    for (const language of languages) {\n        lintCodeBlocksInMarkdownFile(makeFilePath(language), options, language);\n    }\n}\n\nmain()\n\n\n"
  },
  {
    "path": "tools/make-books.sh",
    "content": "#!/bin/bash\n\n# This script creates eBooks from the TypeScript Book.\n\nDIR_DOWNLOADS=\"downloads\"\n\nINPUT_EN=\"README\"\nINPUT_CN=\"README-zh_CN\"\nINPUT_IT=\"README-it_IT\"\nINPUT_BR=\"README-pt_BR\"\nINPUT_SE=\"README-sv_SE\"\n\nOUTPUT_EN=\"typescript-book\"\nOUTPUT_CN=\"typescript-book-zh_CN\"\nOUTPUT_IT=\"typescript-book-it_IT\"\nOUTPUT_BR=\"typescript-book-pt_BR\"\nOUTPUT_SE=\"typescript-book-sv_SE\"\n\nAUTHOR=\"Simone Poggiali\"\nTITLE_EN=\"The Concise TypeScript Book\"\nTITLE_CN=\"# 简洁的TypeScript之书\"\nTITLE_IT=\"The Concise TypeScript Book\"\nTITLE_BR=\"The Concise TypeScript Book\"\nTITLE_SE=\"The Concise TypeScript Book\"\n\ncd ../\n\necho \"Making ebooks ...\"\n\n# Check dependencies\nif command -v pandoc &>/dev/null; then\n    echo \"pandoc is installed\"\nelse\n    echo \"You need to install pandoc. Please visit: https://pandoc.org/installing.html\"\n    exit 1\nfi\nif command -v epubcheck &>/dev/null; then\n    echo \"epubcheck is installed\"\nelse\n    echo \"You need to install epubcheck. Please visit: https://www.w3.org/publishing/epubcheck/docs/installation/\"\n    exit 1\nfi\nif command -v ebook-convert &>/dev/null; then\n    echo \"calibre is installed\"\nelse\n    echo \"You need to install calibre. Please visit: https://calibre-ebook.com/download\"\n    exit 1\nfi\n\n# Generate eBooks\npandoc -o $DIR_DOWNLOADS/$OUTPUT_EN.epub --metadata title=\"$TITLE_EN\" --metadata author=\"$AUTHOR\" -s $INPUT_EN.md\npandoc -o $DIR_DOWNLOADS/$OUTPUT_CN.epub --metadata title=\"$TITLE_CN\" --metadata author=\"$AUTHOR\" -s $INPUT_CN.md\npandoc -o $DIR_DOWNLOADS/$OUTPUT_IT.epub --metadata title=\"$TITLE_IT\" --metadata author=\"$AUTHOR\" -s $INPUT_IT.md\npandoc -o $DIR_DOWNLOADS/$OUTPUT_BR.epub --metadata title=\"$TITLE_BR\" --metadata author=\"$AUTHOR\" -s $INPUT_BR.md\npandoc -o $DIR_DOWNLOADS/$OUTPUT_SE.epub --metadata title=\"$TITLE_SE\" --metadata author=\"$AUTHOR\" -s $INPUT_SE.md\n\n# Validate eBooks\nepubcheck $DIR_DOWNLOADS/$OUTPUT_EN.epub\nepubcheck $DIR_DOWNLOADS/$OUTPUT_CN.epub\nepubcheck $DIR_DOWNLOADS/$OUTPUT_IT.epub\nepubcheck $DIR_DOWNLOADS/$OUTPUT_BR.epub\nepubcheck $DIR_DOWNLOADS/$OUTPUT_SE.epub\n\n# Generate PDFs\nebook-convert $DIR_DOWNLOADS/$OUTPUT_EN.epub $DIR_DOWNLOADS/$OUTPUT_EN.pdf --pdf-page-numbers\nebook-convert $DIR_DOWNLOADS/$OUTPUT_CN.epub $DIR_DOWNLOADS/$OUTPUT_CN.pdf --pdf-page-numbers\nebook-convert $DIR_DOWNLOADS/$OUTPUT_IT.epub $DIR_DOWNLOADS/$OUTPUT_IT.pdf --pdf-page-numbers\nebook-convert $DIR_DOWNLOADS/$OUTPUT_BR.epub $DIR_DOWNLOADS/$OUTPUT_BR.pdf --pdf-page-numbers\nebook-convert $DIR_DOWNLOADS/$OUTPUT_SE.epub $DIR_DOWNLOADS/$OUTPUT_SE.pdf --pdf-page-numbers\n\necho \"Books were created. Please commit!\""
  },
  {
    "path": "tools/make-website-content.py",
    "content": "\"\"\"\nGenerate multiple Markdown documents from a single Markdown file by splitting it based on headings. \nThis script is designed for creating pages on a website and provides results for multiple languages.\nNote: the number of headings per language must be the same.\n\"\"\"\n\nimport os\nimport re\nimport shutil\nfrom typing import List\n\n\n# INPUT_FILE_PATH = \"./test-md/README.md\"\n# OUTPUT_DIR_PATH = \"./test-md/en\"\n# INPUT_FILE_PATH_CN = \"./test-md/README-zh_CN.md\"\n# OUTPUT_DIR_PATH_CN = \"./test-md/zh-cn\"\n\nINPUT_FILE_PATH = \"../README.md\"\nOUTPUT_DIR_PATH = \"../website/src/content/docs/book\"\n\nINPUT_FILE_PATH_CN = \"../README-zh_CN.md\"\nOUTPUT_DIR_PATH_CN = \"../website/src/content/docs/zh-cn/book\"\n\nINPUT_FILE_PATH_IT = \"../README-it_IT.md\"\nOUTPUT_DIR_PATH_IT = \"../website/src/content/docs/it-it/book\"\n\nINPUT_FILE_PATH_PT = \"../README-pt_BR.md\"\nOUTPUT_DIR_PATH_PT = \"../website/src/content/docs/pt-br/book\"\n\nINPUT_FILE_PATH_SV = \"../README-sv_SE.md\"\nOUTPUT_DIR_PATH_SV = \"../website/src/content/docs/sv-se/book\"\n\n\ndef manage_output_dir(path: str) -> None:\n    if os.path.exists(path):\n        shutil.rmtree(path)\n    os.makedirs(path)\n\n\ndef read_content_file(path: str) -> List[str]:\n    with open(path, \"r\") as file:\n        lines = file.readlines()\n    return lines\n\n\ndef make_file_name(name: str) -> str:\n    content_sanitized = re.sub(r\"[^a-zA-Z0-9]+\", \"-\", name.lower()).strip(\"-\")\n    return f\"{content_sanitized}\"\n\n\ndef make_output_path(output_dir: str, file_name: str):\n    return f\"{output_dir}/{file_name}.md\"\n\n\ndef is_line_header_1_to_2(line: str) -> bool:\n    return re.match(r\"^(#{1,2})\\s+(.+)\", line)\n\n\ndef make_file_output_path(output_dir: str, name: str) -> str:\n    file_name = make_file_name(name)\n    output_file_path = make_output_path(output_dir, file_name)\n    return output_file_path\n\n\ndef make_markdown_page_metadata(order: int, header: str) -> List[str]:\n    return [\n        \"---\\n\",\n        f\"title: {header}\\n\",\n        \"sidebar:\\n\",\n        f\"  order: {order}\\n\",\n        f\"  label: {order}. {header}\\n\",\n        \"---\\n\",\n        \"\\n\",\n    ]\n\n\ndef save_content_to_file(path: str, lines: List[str]):\n    with open(path, \"w\") as output_file:\n        output_file.writelines(lines)\n\n\ndef save_pages_to_files(\n    data_pages: List[List[str]], master_headers: List[str], output_dir: str\n) -> None:\n    for index, header in enumerate(master_headers):\n        file = make_file_output_path(output_dir, header)\n        save_content_to_file(file, data_pages[index])\n\n\ndef find_master_headers(lines: List[str]) -> List[str]:\n    headers = [x for x in lines if is_line_header_1_to_2(x)]\n    headers_clean = list(map(lambda x: make_file_name(x), headers))\n    return headers_clean\n\n\ndef remove_markdown_anchors(markdown_text: str):\n    pattern = r\"\\[(.*?)\\]\\(#[^\\)]*\\)\"\n    replacement = r\"\\1\"\n    transformed_text = re.sub(pattern, replacement, markdown_text)\n    return transformed_text\n\n\ndef split_content_by_headings(lines: List[str]):\n    current_content = []\n    in_page = False\n    header_index = -1\n    content_result = []\n\n    for line in lines:\n        is_header_match = is_line_header_1_to_2(line)\n        if is_header_match:\n            header_text = is_header_match.group(2).strip()\n            header_index += 1\n            if not in_page:\n                in_page = True\n                current_content.extend(\n                    make_markdown_page_metadata(header_index + 1, header_text)\n                )\n            else:\n                content_result.extend([current_content])\n                current_content = []\n                in_page = True\n                current_content.extend(\n                    make_markdown_page_metadata(header_index + 1, header_text)\n                )\n        else:\n            line_new = remove_markdown_anchors(line)\n            current_content.append(line_new)\n\n    header_index += 1\n    content_result.extend([current_content])\n\n    return content_result\n\n\ndef process(base_input_path, input_lang_path: str, base_output_path: str) -> None:\n    manage_output_dir(base_output_path)\n\n    content_lines_master = read_content_file(base_input_path)\n    master_headers = find_master_headers(content_lines_master)\n\n    content_lines = read_content_file(input_lang_path)\n    data_pages = split_content_by_headings(\n        content_lines,\n    )\n    save_pages_to_files(data_pages, master_headers, base_output_path)\n    print(f\"A total of: {len(master_headers)} files were at: {base_output_path}\")\n\n\nprocess(INPUT_FILE_PATH, INPUT_FILE_PATH, OUTPUT_DIR_PATH)\n\nprocess(INPUT_FILE_PATH, INPUT_FILE_PATH_CN, OUTPUT_DIR_PATH_CN)\n\nprocess(INPUT_FILE_PATH, INPUT_FILE_PATH_IT, OUTPUT_DIR_PATH_IT)\n\nprocess(INPUT_FILE_PATH, INPUT_FILE_PATH_PT, OUTPUT_DIR_PATH_PT)\n\nprocess(INPUT_FILE_PATH, INPUT_FILE_PATH_SV, OUTPUT_DIR_PATH_SV)\n"
  },
  {
    "path": "tools/package.json",
    "content": "{\n  \"name\": \"typescript-book\",\n  \"version\": \"1.0.0\",\n  \"description\": \"The Concise TypeScript Book provides a comprehensive and succinct overview of TypeScript's capabilities. It offers clear explanations covering all aspects found in the latest version of the language, from its powerful type system to advanced features. Whether you're a beginner or an experienced developer, this book is an invaluable resource to enhance your understanding and proficiency in TypeScript.\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"format\": \"ts-node format\",\n    \"compile\": \"ts-node compile\",\n    \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\",\n    \"lint\": \"ts-node lint\",\n    \"lint:md\": \"markdownlint \\\"./*.md\\\" markdownlint \\\"../*.md\\\"\",\n    \"check\": \"npm run lint:md && npm run format && npm run compile\"\n  },\n  \"author\": \"\",\n  \"license\": \"ISC\",\n  \"devDependencies\": {\n    \"@types/fs-extra\": \"^11.0.1\",\n    \"@types/marked\": \"^5.0.0\",\n    \"@types/node\": \"^20.3.1\",\n    \"@types/prettier\": \"^2.7.3\",\n    \"fp-ts\": \"^2.16.0\",\n    \"fs-extra\": \"^11.1.1\",\n    \"markdownlint-cli\": \"^0.35.0\",\n    \"marked\": \"^5.1.0\",\n    \"prettier\": \"^3.3.0\",\n    \"ts-node\": \"^10.9.1\",\n    \"typescript\": \"^5.4.5\"\n  }\n}\n"
  },
  {
    "path": "tools/remove_skip_empty_lines.sh",
    "content": "#!/bin/bash\n\n# This script removes empty lines after <!-- skip --> comments in a markdown file.\n\n# Remove empty lines after <!-- skip --> comments\nsed -i '' '/<!-- skip -->/{N;s/<!-- skip -->\\n$/<!-- skip -->/;}' README-it_IT.md\n\necho \"Empty lines after <!-- skip --> comments have been removed.\""
  },
  {
    "path": "tools/test-md/README-zh_CN.md",
    "content": "# 简洁 TypeScript 书\nTypeScript 有效开发简明指南。 **免费和开源**。\n## 创建文件和文件夹\n可使用 按钮访问文件资源管理器。\n## 切换到另一个文件\n您的所有文件和文件夹都在文件资源管理器中显示为树。 您可以通过单击树中的文件从一个文件切换到另一个文件。\n### 新标题\n一些家长内容。\n#### 嵌套内容 1\n更多内容在这里。\n##### 嵌套内容 2\n内容甚至更多。"
  },
  {
    "path": "tools/test-md/README.md",
    "content": "# The Concise TypeScript Book\nA Concise Guide to Effective Development in TypeScript. **Free and Open Source**.\n## Create files and folders\nThe file explorer is accessible using the button.\n## Switch to another file\nAll your files and folders are presented as a tree in the file explorer. You can switch from one to another by clicking a file in the tree.\n### New title\nSome parent content.\n#### Nested content 1\nMore content here.\n##### Nested content 2\nEven more content."
  },
  {
    "path": "tools/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"target\": \"es2022\",\n    \"module\": \"commonjs\",\n    \"noImplicitAny\": true,\n    \"esModuleInterop\": true,\n    \"noEmitOnError\": true,\n    \"moduleDetection\": \"force\",\n    \"noUnusedLocals\": false,\n    \"forceConsistentCasingInFileNames\": true,\n    \"strict\": true,\n    \"skipLibCheck\": true,\n    \"lib\": [\n      \"es2022\",\n      \"esnext.disposable\",\n      \"esnext.decorators\",\n      \"dom\"\n    ]\n  }\n}"
  },
  {
    "path": "tools/utilities-add-translation/README.md",
    "content": "# Markdown Split and Translation Tools\n\nThis directory contains Python scripts for splitting, translating, and managing markdown documentation files. This is useful when you want to add a new language to the book.\n\n## Scripts Overview\n\n### 1. `split_markdown.py`\nSplits a large markdown file into smaller parts based on character count.\n\n**Usage:**\n```bash\n# Split root README.md and save parts in current directory (default)\npython3 split_markdown.py\n\n# Split a specific file and save parts in current directory\npython3 split_markdown.py path/to/file.md\n\n# Split and save parts in specific directory\npython3 split_markdown.py ../../README.md ../../target_folder\n```\n\n**Output:** Creates files named `README-part-01.md`, `README-part-02.md`, etc.\n\n---\n\n### 2. `create_language_files.py`\nAutomatically splits README.md into the target language folder and creates empty translation files.\n\n**Usage:**\n```bash\n# Create Italian translation files (splits README.md into ../../ita)\npython3 create_language_files.py ITA\n\n# Create French translation files in specific folder\npython3 create_language_files.py FR ../../fra\n\n# Create Spanish translation files\npython3 create_language_files.py ES ../../spa\n```\n\n**Output:** \n1. Splits README.md and saves parts in the target language folder\n2. Creates empty translation files: `README-part-01-ITA.md`, `README-part-02-ITA.md`, etc.\n\n---\n\n### 3. `concatenate_language_files.py`\nConcatenates all translated part files into a single file.\n\n**Usage:**\n```bash\n# Concatenate Italian files in ../../ita (default)\npython3 concatenate_language_files.py it_IT\n\n# Concatenate Spanish files in specific directory\npython3 concatenate_language_files.py es_ES ../../spa\n\n# Concatenate French files\npython3 concatenate_language_files.py fr_FR ../../fra\n```\n\n**Output:** Creates `README-it_IT.md`, `README-es_ES.md`, etc. containing all parts concatenated.\n\n---\n\n### 4. `verify_concatenation.py`\nVerifies that all part files were included in the concatenated file by comparing character counts.\n\n**Usage:**\n```bash\n# Verify Italian files in ../../ita (default)\npython3 verify_concatenation.py ITA\n\n# Verify Spanish files in specific directory\npython3 verify_concatenation.py ES ../../spa\n```\n\n**Output:** Shows character count comparison and reports any mismatches.\n\n---\n\n### 5. `verify_concatenation_detailed.py`\nEnhanced verification that accounts for newlines added between files.\n\n**Usage:**\n```bash\n# Verify Italian files in ../../ita (default)\npython3 verify_concatenation_detailed.py it_IT\n\n# Verify Spanish files in specific directory\npython3 verify_concatenation_detailed.py es_ES ../../spa\n```\n\n**Output:** Detailed analysis including expected newlines and precise character counts.\n\n---\n\n## Complete Workflow Example\n\n### For Italian Translation:\n\n```bash\ncd tools/split-md\n\n# Step 1: Create Italian folder, split README.md, and create translation files\npython3 create_language_files.py it_IT\n\n# Step 2: Translate each README-part-XX-it_IT.md file manually\n\n# Step 3: Concatenate all translated parts\npython3 concatenate_language_files.py it_IT\n\n# Step 4: Verify the concatenation\npython3 verify_concatenation_detailed.py it_IT\n```\n\n### For Spanish Translation:\n\n```bash\ncd tools/split-md\n\n# Step 1: Create Spanish folder, split README.md, and create translation files\npython3 create_language_files.py es_ES ../../spa\n\n# Step 2: Translate each README-part-XX-es_ES.md file manually\n\n# Step 3: Concatenate all translated parts\npython3 concatenate_language_files.py es_ES ../../spa\n\n# Step 4: Verify the concatenation\npython3 verify_concatenation_detailed.py es_ES ../../spa\n```\n\n---\n\n## File Naming Conventions\n\n- **Source parts:** `README-part-01.md`, `README-part-02.md`, ...\n- **Translation parts:** `README-part-01-{LANG}.md`, `README-part-02-{LANG}.md`, ...\n- **Final concatenated:** `README-{lang}_{COUNTRY}.md` (e.g., `README-it_IT.md`, `README-fr_FR.md`)\n\nLanguage codes follow ISO 639-1 (language) and ISO 3166-1 (country) standards.\n\n---\n\n## AI Assistant Prompt for Translation Workflow\n\n**Copy and paste this prompt to an AI assistant to automate the complete translation workflow:**\n\n```\nI need you to help me create a translation workflow for a TypeScript documentation book. Here's what I need you to do:\n\n1. Navigate to the tools/split-md directory\n2. Follow the complete workflow for creating a new language translation\n3. Use language code [LANGUAGE_CODE] and target directory ../../[LANGUAGE_FOLDER]\n4. Execute all steps including verification\n5. Add sample translated content to the first 2-3 files for testing\n6. Provide a detailed report of the results\n\nThe workflow steps are:\n- Step 1: Run `python3 create_language_files.py [LANGUAGE_CODE] ../../[LANGUAGE_FOLDER]`\n- Step 2: Add sample translated content to first few files\n- Step 3: Run `python3 concatenate_language_files.py [LANGUAGE_CODE] ../../[LANGUAGE_FOLDER]`\n- Step 4: Run `python3 verify_concatenation_detailed.py [LANGUAGE_CODE] ../../[LANGUAGE_FOLDER]`\n\nReplace [LANGUAGE_CODE] with the target language code (e.g., DE, FR, ES, CZ, PT, RU, JA, KO) and [LANGUAGE_FOLDER] with the appropriate folder name (e.g., deu, fra, spa, cze, por, rus, jpn, kor).\n\nExpected results:\n- Multiple part files created in language folder (number depends on README.md size)\n- Equal number of empty translation files created\n- Sample content added to test files\n- Successful concatenation with proper ISO naming\n- Perfect verification match including newlines\n- All files organized in language-specific directory (not root)\n\nPlease execute this workflow and provide a summary report of the results.\n```\n\n**Example usage:**\n- For German: Replace [LANGUAGE_CODE] with `de_DE` and [LANGUAGE_FOLDER] with `deu`\n- For Portuguese: Replace [LANGUAGE_CODE] with `pt_PT` and [LANGUAGE_FOLDER] with `por`\n- For Russian: Replace [LANGUAGE_CODE] with `ru_RU` and [LANGUAGE_FOLDER] with `rus`\n\n---\n\n## Requirements\n\n- Python 3.6+\n- No external dependencies required\n\n---\n\n## Notes\n\n- All scripts are designed to run from the `tools/split-md` directory\n- Default paths assume the project structure: `typescript-book/tools/split-md/`\n- Maximum characters per split: 3,500 (configurable in `split_markdown.py`)\n- Concatenation adds newlines between files for proper formatting\n"
  },
  {
    "path": "tools/utilities-add-translation/concatenate_language_files.py",
    "content": "#!/usr/bin/env python3\nimport os\nimport sys\nfrom pathlib import Path\n\ndef concatenate_language_files(directory, language_ext):\n    \"\"\"\n    Find all files ending with '{language_ext}.md', sort them alphabetically,\n    and concatenate them into README-{iso_code}.md\n    \"\"\"\n    # Convert to Path object for easier handling\n    dir_path = Path(directory)\n    \n    # Check if directory exists\n    if not dir_path.exists():\n        print(f\"Error: Directory '{directory}' does not exist\")\n        return False\n    \n    # Find all files ending with '{language_ext}.md'\n    lang_files = list(dir_path.glob(f'*{language_ext}.md'))\n    \n    if not lang_files:\n        print(f\"No files ending with '{language_ext}.md' found in '{directory}'\")\n        return False\n    \n    # Sort files alphabetically by filename\n    lang_files.sort(key=lambda x: x.name)\n    \n    # Print sorted list of files\n    print(\"Files found and sorted alphabetically:\")\n    for file in lang_files:\n        print(f\"  {file.name}\")\n    \n    # Use the provided language extension as the ISO code\n    iso_code = language_ext\n    output_file = dir_path / f'README-{iso_code}.md'\n    \n    # Concatenate all files\n    try:\n        with open(output_file, 'w', encoding='utf-8') as outfile:\n            for i, file_path in enumerate(lang_files):\n                print(f\"Processing: {file_path.name}\")\n                \n                with open(file_path, 'r', encoding='utf-8') as infile:\n                    content = infile.read()\n                    outfile.write(content)\n                    \n                    # Add newline between files (except for the last one)\n                    if i < len(lang_files) - 1:\n                        outfile.write('\\n')\n        \n        print(f\"\\nSuccess! Created '{output_file.name}' with {len(lang_files)} files concatenated.\")\n        return True\n        \n    except Exception as e:\n        print(f\"Error writing to output file: {e}\")\n        return False\n\ndef main():\n    # Check for ISO code argument\n    if len(sys.argv) < 2:\n        print(\"Usage: python concatenate_language_files.py <iso_code> [directory]\")\n        print(\"Example: python concatenate_language_files.py it_IT\")\n        print(\"Example: python concatenate_language_files.py es_ES ../../spa\")\n        sys.exit(1)\n    \n    iso_code = sys.argv[1]\n    \n    # Default to ita folder if no directory argument provided\n    if len(sys.argv) > 2:\n        directory = sys.argv[2]\n    else:\n        # From tools/split-md, go up two levels and into ita folder\n        directory = \"../../ita\"\n    \n    concatenate_language_files(directory, iso_code)\n\nif __name__ == \"__main__\":\n    main()"
  },
  {
    "path": "tools/utilities-add-translation/create_language_files.py",
    "content": "#!/usr/bin/env python3\nimport os\nimport sys\nimport re\nfrom pathlib import Path\n\ndef split_readme_to_folder(readme_path, target_folder):\n    \"\"\"Split README.md and save parts directly to target folder\"\"\"\n    from split_markdown import split_markdown\n    \n    # Create target folder if it doesn't exist\n    Path(target_folder).mkdir(parents=True, exist_ok=True)\n    \n    # Split README and save parts to target folder\n    split_markdown(readme_path, target_folder)\n\ndef create_language_files(folder_path, language_ext):\n    folder_path = os.path.abspath(folder_path)\n    if not os.path.exists(folder_path):\n        print(f\"Error: Folder '{folder_path}' does not exist\")\n        return\n    \n    print(f\"Scanning folder: {folder_path}\")\n    print(f\"Creating files with extension: {language_ext}\")\n    \n    for filename in os.listdir(folder_path):\n        match = re.match(r'README-part-(\\d+)\\.md$', filename)\n        if match:\n            number = match.group(1)\n            lang_filename = f'README-part-{number}-{language_ext}.md'\n            lang_filepath = os.path.join(folder_path, lang_filename)\n            \n            if not os.path.exists(lang_filepath):\n                with open(lang_filepath, 'w', encoding='utf-8') as f:\n                    pass  # Create empty file\n                print(f'Created: {lang_filename}')\n\nif __name__ == \"__main__\":\n    # Check for language extension argument\n    if len(sys.argv) < 2:\n        print(\"Usage: python create_language_files.py <language_ext> [folder_path]\")\n        print(\"Example: python create_language_files.py ITA\")\n        print(\"Example: python create_language_files.py FR ../../fra\")\n        sys.exit(1)\n    \n    language_ext = sys.argv[1]\n    \n    # Default to ita folder if no folder argument provided\n    if len(sys.argv) > 2:\n        folder_path = sys.argv[2]\n    else:\n        # From tools/split-md, go up two levels and into ita folder\n        folder_path = \"../../ita\"\n    \n    # First, split README.md into the target folder\n    readme_path = \"../../README.md\"\n    if os.path.exists(readme_path):\n        print(f\"Splitting README.md into {folder_path}...\")\n        split_readme_to_folder(readme_path, folder_path)\n    \n    # Then create language files\n    create_language_files(folder_path, language_ext)"
  },
  {
    "path": "tools/utilities-add-translation/split_markdown.py",
    "content": "#!/usr/bin/env python3\nimport sys\nimport os\nfrom pathlib import Path\n\ndef split_markdown(file_path, output_dir=None, max_chars=3500):\n    \"\"\"\n    Splits a markdown file into smaller parts based on a maximum character count.\n    \"\"\"\n    with open(file_path, 'r', encoding='utf-8') as f:\n        content = f.read()\n    \n    if len(content) <= max_chars:\n        print(f\"File is already under {max_chars} characters. No splitting needed.\")\n        return\n    \n    # Determine output directory\n    if output_dir:\n        output_path = Path(output_dir)\n        output_path.mkdir(parents=True, exist_ok=True)\n        base_name = Path(file_path).stem  # Get filename without extension\n        base_path = output_path / base_name\n    else:\n        base_path = Path(file_path).with_suffix('')  # Remove extension\n    \n    parts = []\n    current_part = \"\"\n    \n    lines = content.split('\\n')\n    \n    for line in lines:\n        test_part = current_part + ('\\n' if current_part else '') + line\n        \n        if len(test_part) <= max_chars:\n            current_part = test_part\n        else:\n            if current_part:\n                parts.append(current_part)\n            current_part = line\n    \n    if current_part:\n        parts.append(current_part)\n    \n    for i, part in enumerate(parts, 1):\n        part_filename = f\"{base_path}-part-{i:02d}.md\"\n        with open(part_filename, 'w', encoding='utf-8') as f:\n            f.write(part)\n        print(f\"Created: {part_filename} ({len(part)} characters)\")\n\nif __name__ == \"__main__\":\n    # Parse arguments: file_path [output_directory]\n    if len(sys.argv) > 2:\n        file_path = sys.argv[1]\n        output_dir = sys.argv[2]\n    elif len(sys.argv) > 1:\n        file_path = sys.argv[1]\n        output_dir = None\n    else:\n        # Default: split root README.md and save parts in current directory\n        file_path = \"../../README.md\"\n        output_dir = None\n    \n    if not os.path.exists(file_path):\n        print(f\"Error: File '{file_path}' not found.\")\n        sys.exit(1)\n    \n    split_markdown(file_path, output_dir)"
  },
  {
    "path": "tools/utilities-add-translation/verify_concatenation.py",
    "content": "#!/usr/bin/env python3\nimport os\nimport sys\nfrom pathlib import Path\n\ndef verify_concatenation(directory, language_ext):\n    \"\"\"\n    Verify that all language files were properly included in the concatenated file\n    by comparing total character counts\n    \"\"\"\n    dir_path = Path(directory)\n    \n    if not dir_path.exists():\n        print(f\"Error: Directory '{directory}' does not exist\")\n        return False\n    \n    # Map language extensions to ISO codes\n    lang_map = {\n        'ITA': 'it_IT',\n        'ES': 'es_ES', \n        'FR': 'fr_FR',\n        'DE': 'de_DE',\n        'PT': 'pt_PT',\n        'RU': 'ru_RU',\n        'JA': 'ja_JP',\n        'KO': 'ko_KR',\n        'ZH': 'zh_CN'\n    }\n    \n    iso_code = lang_map.get(language_ext, language_ext.lower())\n    concatenated_filename = f'README-{iso_code}.md'\n    \n    # Find all files ending with '{language_ext}.md' except the concatenated file\n    lang_files = [f for f in dir_path.glob(f'*{language_ext}.md') if f.name != concatenated_filename]\n    concatenated_file = dir_path / concatenated_filename\n    \n    if not concatenated_file.exists():\n        print(f\"Error: Concatenated file '{concatenated_filename}' not found in '{directory}'\")\n        return False\n    \n    if not lang_files:\n        print(f\"No {language_ext}.md files found in '{directory}'\")\n        return False\n    \n    # Sort files alphabetically\n    lang_files.sort(key=lambda x: x.name)\n    \n    # Count characters in individual files\n    total_chars = 0\n    file_details = []\n    \n    print(f\"Counting characters in {len(lang_files)} {language_ext}.md files:\")\n    \n    for file_path in lang_files:\n        try:\n            with open(file_path, 'r', encoding='utf-8') as f:\n                content = f.read()\n                char_count = len(content)\n                total_chars += char_count\n                file_details.append((file_path.name, char_count))\n                print(f\"  {file_path.name}: {char_count:,} characters\")\n        except Exception as e:\n            print(f\"Error reading {file_path.name}: {e}\")\n            return False\n    \n    # Count characters in concatenated file\n    try:\n        with open(concatenated_file, 'r', encoding='utf-8') as f:\n            concatenated_content = f.read()\n            concatenated_chars = len(concatenated_content)\n    except Exception as e:\n        print(f\"Error reading concatenated file: {e}\")\n        return False\n    \n    # Compare counts\n    print(f\"\\n--- VERIFICATION RESULTS ---\")\n    print(f\"Total characters in {len(lang_files)} individual files: {total_chars:,}\")\n    print(f\"Characters in concatenated file: {concatenated_chars:,}\")\n    print(f\"Difference: {concatenated_chars - total_chars:,}\")\n    \n    if total_chars == concatenated_chars:\n        print(\"✅ SUCCESS: Character counts match exactly!\")\n        print(\"All files were properly included in the concatenation.\")\n        return True\n    else:\n        print(\"❌ MISMATCH: Character counts do not match!\")\n        if concatenated_chars > total_chars:\n            print(f\"Concatenated file has {concatenated_chars - total_chars:,} extra characters\")\n        else:\n            print(f\"Concatenated file is missing {total_chars - concatenated_chars:,} characters\")\n        return False\n\ndef main():\n    # Check for language extension argument\n    if len(sys.argv) < 2:\n        print(\"Usage: python verify_concatenation.py <language_ext> [directory]\")\n        print(\"Example: python verify_concatenation.py ITA\")\n        print(\"Example: python verify_concatenation.py ES ../../spa\")\n        sys.exit(1)\n    \n    language_ext = sys.argv[1]\n    \n    # Default to ita folder if no directory argument provided\n    if len(sys.argv) > 2:\n        directory = sys.argv[2]\n    else:\n        # From tools/split-md, go up two levels and into ita folder\n        directory = \"../../ita\"\n    \n    verify_concatenation(directory, language_ext)\n\nif __name__ == \"__main__\":\n    main()"
  },
  {
    "path": "tools/utilities-add-translation/verify_concatenation_detailed.py",
    "content": "#!/usr/bin/env python3\nimport os\nimport sys\nfrom pathlib import Path\n\ndef verify_concatenation_detailed(directory, language_ext):\n    \"\"\"\n    Verify concatenation with detailed analysis including newlines between files\n    \"\"\"\n    dir_path = Path(directory)\n    \n    if not dir_path.exists():\n        print(f\"Error: Directory '{directory}' does not exist\")\n        return False\n    \n    # Map language extensions to ISO codes\n    lang_map = {\n        'ITA': 'it_IT',\n        'ES': 'es_ES', \n        'FR': 'fr_FR',\n        'DE': 'de_DE',\n        'PT': 'pt_PT',\n        'RU': 'ru_RU',\n        'JA': 'ja_JP',\n        'KO': 'ko_KR',\n        'ZH': 'zh_CN'\n    }\n    \n    iso_code = lang_map.get(language_ext, language_ext.lower())\n    concatenated_filename = f'README-{iso_code}.md'\n    \n    # Find all files ending with '{language_ext}.md' except the concatenated file\n    lang_files = [f for f in dir_path.glob(f'*{language_ext}.md') if f.name != concatenated_filename]\n    concatenated_file = dir_path / concatenated_filename\n    \n    if not concatenated_file.exists():\n        print(f\"Error: Concatenated file '{concatenated_filename}' not found in '{directory}'\")\n        return False\n    \n    if not lang_files:\n        print(f\"No {language_ext}.md files found in '{directory}'\")\n        return False\n    \n    # Sort files alphabetically\n    lang_files.sort(key=lambda x: x.name)\n    \n    # Count characters in individual files\n    total_chars = 0\n    print(f\"Analyzing {len(lang_files)} {language_ext}.md files:\")\n    \n    for file_path in lang_files:\n        try:\n            with open(file_path, 'r', encoding='utf-8') as f:\n                content = f.read()\n                char_count = len(content)\n                total_chars += char_count\n                print(f\"  {file_path.name}: {char_count:,} characters\")\n        except Exception as e:\n            print(f\"Error reading {file_path.name}: {e}\")\n            return False\n    \n    # Count characters in concatenated file\n    try:\n        with open(concatenated_file, 'r', encoding='utf-8') as f:\n            concatenated_content = f.read()\n            concatenated_chars = len(concatenated_content)\n    except Exception as e:\n        print(f\"Error reading concatenated file: {e}\")\n        return False\n    \n    # Calculate expected characters with newlines between files\n    # The concatenation script adds newlines between files (n-1 newlines for n files)\n    expected_newlines = len(lang_files) - 1\n    expected_total = total_chars + expected_newlines\n    \n    # Results\n    print(f\"\\n--- DETAILED VERIFICATION RESULTS ---\")\n    print(f\"Individual files: {len(lang_files)} files\")\n    print(f\"Total characters in individual files: {total_chars:,}\")\n    print(f\"Expected newlines between files: {expected_newlines}\")\n    print(f\"Expected total with newlines: {expected_total:,}\")\n    print(f\"Actual concatenated file characters: {concatenated_chars:,}\")\n    print(f\"Difference: {concatenated_chars - expected_total:,}\")\n    \n    if concatenated_chars == expected_total:\n        print(\"✅ SUCCESS: Character counts match perfectly!\")\n        print(\"All files were properly concatenated with correct newlines.\")\n        return True\n    elif concatenated_chars == total_chars:\n        print(\"✅ SUCCESS: Character counts match exactly!\")\n        print(\"All files were concatenated without additional newlines.\")\n        return True\n    else:\n        print(\"❌ MISMATCH: Character counts do not match expected values!\")\n        if concatenated_chars > expected_total:\n            print(f\"Concatenated file has {concatenated_chars - expected_total:,} unexpected extra characters\")\n        else:\n            print(f\"Concatenated file is missing {expected_total - concatenated_chars:,} characters\")\n        \n        # Additional analysis\n        if abs(concatenated_chars - total_chars) < 100:\n            print(\"Note: Small difference likely due to newline handling between files.\")\n        \n        return False\n\ndef main():\n    # Check for language extension argument\n    if len(sys.argv) < 2:\n        print(\"Usage: python verify_concatenation_detailed.py <language_ext> [directory]\")\n        print(\"Example: python verify_concatenation_detailed.py ITA\")\n        print(\"Example: python verify_concatenation_detailed.py ES ../../spa\")\n        sys.exit(1)\n    \n    language_ext = sys.argv[1]\n    \n    # Default to ita folder if no directory argument provided\n    if len(sys.argv) > 2:\n        directory = sys.argv[2]\n    else:\n        # From tools/split-md, go up two levels and into ita folder\n        directory = \"../../ita\"\n    \n    verify_concatenation_detailed(directory, language_ext)\n\nif __name__ == \"__main__\":\n    main()"
  },
  {
    "path": "tools/utils.ts",
    "content": "import { PRETTIER_CONFIG_FILE_PATH } from \"./config\";\nimport { Language } from \"./i18n\";\nimport * as prettier from 'prettier';\n\nexport const makeFilePath = (item: Language) =>\n    item === Language.en_EN ? '../README.md' : `../README-${item}.md`\n\nexport type PrettierOptions = Exclude<prettier.Options, null>\n\nexport const getPrettierOptions = async (): Promise<PrettierOptions> => {\n    const options = await prettier.resolveConfig(PRETTIER_CONFIG_FILE_PATH)\n    if (options === null) {\n        throw `No Prettier options are found! Check your Prettier configuration file.`\n    }\n    return options\n}"
  },
  {
    "path": "tools/verify_codeblocks.py",
    "content": "import re\nimport sys\n\ndef verify_codeblocks(filename):\n    \"\"\"\n    Verifies that all code blocks in a markdown file have matching opening and closing fences.\n    \"\"\"\n    print(f\"Verifying {filename}...\")\n    try:\n        with open(filename, 'r', encoding='utf-8') as f:\n            lines = f.readlines()\n    except FileNotFoundError:\n        print(f\"Error: File {filename} not found.\")\n        sys.exit(1)\n\n    # State\n    in_block = False\n    block_start_line = -1\n    fence_char = ''\n    fence_length = 0\n    \n    errors = []\n    \n    # Regex for fence\n    # Group 1: Leading whitespace\n    # Group 2: Fence characters (```... or ~~~...)\n    # Group 3: Info string / Rest of line\n    fence_pattern = re.compile(r'^(\\s*)(`{3,}|~{3,})(.*)$')\n\n    for i, line in enumerate(lines):\n        lineno = i + 1\n        # Removing only trailing newline to properly check indentation if needed, \n        # though standard markdown parsers effectively ignore indentation <= 3 spaces for fence?\n        # We will just strip start for the regex match to be simple, but keep strictly to start of line logic if we want to be precise.\n        # Actually proper fence must be at start of line (possibly indented up to 3 spaces).\n        \n        match = fence_pattern.match(line)\n        \n        if match:\n            matched_indent = match.group(1)\n            matched_fence = match.group(2)\n            matched_rest = match.group(3).strip()\n            \n            # If we support indented blocks, we should check len(matched_indent) < 4\n            # For this repo, assuming standard formatting.\n            \n            current_fence_char = matched_fence[0]\n            current_fence_length = len(matched_fence)\n            \n            if not in_block:\n                # Opening a block\n                in_block = True\n                block_start_line = lineno\n                fence_char = current_fence_char\n                fence_length = current_fence_length\n                # We don't check matched_rest (info string) for opening\n            else:\n                # We are in a block. Check if this is a valid closing fence.\n                # Must be same char\n                # Must be at least as long\n                # Must not have info string (except spaces)\n                \n                if current_fence_char == fence_char and current_fence_length >= fence_length:\n                    # It qualifies as a closing fence if rest is empty\n                    if matched_rest == \"\":\n                        in_block = False\n                        block_start_line = -1\n                    else:\n                        # Technically it could be a closing fence with garbage, or just code?\n                        # CommonMark: \"The closing code fence ... may be followed only by spaces\"\n                        if matched_rest == \"\":\n                            in_block = False\n                            block_start_line = -1\n                        else:\n                            # If it has content, it is NOT a closing fence, it's part of the code block.\n                            # BUT, if the user intended it to be a close and messed up, we might miss it.\n                            # However, strict parser says it's code.\n                            pass\n                else:\n                    # Different fence inside code block -> treated as content\n                    pass\n\n    if in_block:\n        errors.append(f\"Error: Unclosed code block starting at line {block_start_line}\")\n        # To help debugging, print the last few lines or context?\n        # User just wants the report.\n        \n    with open(\"verification_report.md\", \"w\") as report:\n        report.write(\"# Code Block Verification Report\\n\\n\")\n        report.write(f\"File verified: {filename}\\n\\n\")\n        if errors:\n            print(\"Found issues:\")\n            report.write(\"## Issues Found\\n\\n\")\n            for e in errors:\n                print(e)\n                report.write(f\"- {e}\\n\")\n            sys.exit(1)\n        else:\n            print(\"Verification passed! No mismatched code blocks found.\")\n            report.write(\"## Status\\n\\nPASSED: No mismatched code blocks found.\\n\")\n            sys.exit(0)\n\nif __name__ == \"__main__\":\n    target_file = \"README-it_IT.md\"\n    if len(sys.argv) > 1:\n        target_file = sys.argv[1]\n    verify_codeblocks(target_file)\n"
  },
  {
    "path": "website/.gitignore",
    "content": "# build output\ndist/\n# generated types\n.astro/\n\n# dependencies\nnode_modules/\n\n# logs\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\npnpm-debug.log*\n\n\n# environment variables\n.env\n.env.production\n\n# macOS-specific files\n.DS_Store\n"
  },
  {
    "path": "website/.nvmrc",
    "content": "v19.7.0\n"
  },
  {
    "path": "website/.prettierrc",
    "content": "{\n    \"trailingComma\": \"es5\",\n    \"tabWidth\": 4,\n    \"semi\": true,\n    \"singleQuote\": true,\n    \"printWidth\": 80,\n    \"arrowParens\": \"avoid\"\n}"
  },
  {
    "path": "website/.vscode/extensions.json",
    "content": "{\n  \"recommendations\": [\"astro-build.astro-vscode\"],\n  \"unwantedRecommendations\": []\n}\n"
  },
  {
    "path": "website/.vscode/launch.json",
    "content": "{\n  \"version\": \"0.2.0\",\n  \"configurations\": [\n    {\n      \"command\": \"./node_modules/.bin/astro dev\",\n      \"name\": \"Development server\",\n      \"request\": \"launch\",\n      \"type\": \"node-terminal\"\n    }\n  ]\n}\n"
  },
  {
    "path": "website/README.md",
    "content": "# Starlight Starter Kit: Basics\n\n[![Built with Starlight](https://astro.badg.es/v2/built-with-starlight/tiny.svg)](https://starlight.astro.build)\n\n```\nnpm create astro@latest -- --template starlight\n```\n\n[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/withastro/starlight/tree/main/examples/basics)\n[![Open with CodeSandbox](https://assets.codesandbox.io/github/button-edit-lime.svg)](https://codesandbox.io/p/sandbox/github/withastro/starlight/tree/main/examples/basics)\n[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fwithastro%2Fstarlight%2Ftree%2Fmain%2Fexamples%2Fbasics&project-name=my-starlight-docs&repository-name=my-starlight-docs)\n\n> 🧑‍🚀 **Seasoned astronaut?** Delete this file. Have fun!\n\n## 🚀 Project Structure\n\nInside of your Astro + Starlight project, you'll see the following folders and files:\n\n```\n.\n├── public/\n├── src/\n│   ├── assets/\n│   ├── content/\n│   │   ├── docs/\n│   │   └── config.ts\n│   └── env.d.ts\n├── astro.config.mjs\n├── package.json\n└── tsconfig.json\n```\n\nStarlight looks for `.md` or `.mdx` files in the `src/content/docs/` directory. Each file is exposed as a route based on its file name.\n\nImages can be added to `src/assets/` and embedded in Markdown with a relative link.\n\nStatic assets, like favicons, can be placed in the `public/` directory.\n\n## 🧞 Commands\n\nAll commands are run from the root of the project, from a terminal:\n\n| Command                   | Action                                           |\n| :------------------------ | :----------------------------------------------- |\n| `npm install`             | Installs dependencies                            |\n| `npm run dev`             | Starts local dev server at `localhost:4321`      |\n| `npm run build`           | Build your production site to `./dist/`          |\n| `npm run preview`         | Preview your build locally, before deploying     |\n| `npm run astro ...`       | Run CLI commands like `astro add`, `astro check` |\n| `npm run astro -- --help` | Get help using the Astro CLI                     |\n\n## 👀 Want to learn more?\n\nCheck out [Starlight’s docs](https://starlight.astro.build/), read [the Astro documentation](https://docs.astro.build), or jump into the [Astro Discord server](https://astro.build/chat).\n"
  },
  {
    "path": "website/astro.config.mjs",
    "content": "import { defineConfig } from 'astro/config';\nimport starlight from '@astrojs/starlight';\n\n// https://astro.build/config\nexport default defineConfig({\n  site: 'https://gibbok.github.io',\n  base: '/typescript-book',\n  build: {\n    assets: 'app_assets',\n  },\n  integrations: [\n    starlight({\n      head: [\n        {\n          tag: 'link',\n          attrs: {\n            rel: 'stylesheet',\n            id: 'silktide-consent-manager-css',\n            href: '/typescript-book/cookie-banner/silktide-consent-manager.css',\n          },\n        },\n        {\n          tag: 'script',\n          attrs: {\n            src: '/typescript-book/cookie-banner/silktide-consent-manager.js',\n          },\n        },\n        {\n          tag: 'script',\n          content: `\nsilktideCookieBannerManager.updateCookieBannerConfig({\n  background: {\n    showBackground: false \n  },\n  cookieIcon: {\n    position: \"bottomRight\"\n  },\n  cookieTypes: [\n    {\n      id: \"analytics\",\n      name: \"Analytics\",\n      description: \"<p>These cookies are necessary for the website to function properly and cannot be switched off. They help with things like logging in and setting your privacy preferences.</p>\",\n      required: false,\n      onAccept: function() {\n        gtag('consent', 'update', {\n          analytics_storage: 'granted',\n        });\n        dataLayer.push({\n          'event': 'consent_accepted_analytics',\n        });\n      },\n      onReject: function() {\n        gtag('consent', 'update', {\n          analytics_storage: 'denied',\n        });\n      }\n    },\n    {\n      id: \"advertising\",\n      name: \"Advertising\",\n      description: \"<p>These cookies help us improve the site by tracking which pages are most popular and how visitors move around the site.</p>\",\n      required: false,\n      onAccept: function() {\n        gtag('consent', 'update', {\n          ad_storage: 'granted',\n          ad_user_data: 'granted',\n          ad_personalization: 'granted',\n        });\n        dataLayer.push({\n          'event': 'consent_accepted_advertising',\n        });\n      },\n      onReject: function() {\n        gtag('consent', 'update', {\n          ad_storage: 'denied',\n          ad_user_data: 'denied',\n          ad_personalization: 'denied',\n        });\n      }\n    }\n  ],\n  text: {\n    banner: {\n      description: \"<p>We use cookies on our site to enhance your user experience, provide personalized content, and analyze our traffic. <a href=\\\\\"/typescript-book/cookie_policy.html\\\\\" target=\\\\\"_blank\\\\\">Cookie Policy.</a></p>\",\n      acceptAllButtonText: \"Accept all\",\n      acceptAllButtonAccessibleLabel: \"Accept all cookies\",\n      rejectNonEssentialButtonText: \"Reject non-essential\",\n      rejectNonEssentialButtonAccessibleLabel: \"Reject non-essential\",\n      preferencesButtonText: \"Preferences\",\n      preferencesButtonAccessibleLabel: \"Toggle preferences\"\n    },\n    preferences: {\n      title: \"Customize your cookie preferences\",\n      description: \"<p>We respect your right to privacy. You can choose not to allow some types of cookies. Your cookie preferences will apply across our website.</p>\",\n      creditLinkText: \"Get this banner for free\",\n      creditLinkAccessibleLabel: \"Get this banner for free\"\n    }\n  }\n});\n`\n        },\n        {\n          tag: 'script',\n          attrs: {\n            src: 'https://www.googletagmanager.com/gtag/js?id=G-SR2LV8LB90',\n          },\n        },\n        {\n          tag: 'script',\n          content: `\nwindow.dataLayer = window.dataLayer || [];\nfunction gtag(){dataLayer.push(arguments);}\ngtag('js', new Date());\ngtag('config', 'G-SR2LV8LB90');\n`\n        },\n        {\n          tag: 'script',\n          attrs: {\n            async: true,\n            src: 'https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-8180626414651391',\n            crossorigin: 'anonymous',\n          },\n        }\n      ],\n      title: 'TypeScript Book',\n      customCss: ['./src/styles/custom.css'],\n      components: {\n        PageSidebar: './src/components/RightSidebarBanner.astro',\n        Hero: './src/components/Hero.astro',\n      },\n      social: {\n        github: 'https://github.com/gibbok/typescript-book',\n        'x.com': 'https://twitter.com/gibbok_coding',\n      },\n      defaultLocale: 'root',\n      locales: {\n        root: {\n          label: 'English',\n          lang: 'en',\n        },\n        'zh-cn': {\n          label: '简体中文',\n          lang: 'zh-CN',\n        },\n        'it-it': {\n          label: 'Italiano',\n          lang: 'it-IT',\n        },\n        'pt-br': {\n          label: 'Português (Brasil)',\n          lang: 'pt-BR',\n        },\n        'sv-se': {\n          label: 'Svenska',\n          lang: 'sv-SE',\n        },\n      },\n      sidebar: [\n        {\n          label: 'TypeScript Book',\n          autogenerate: { directory: 'book' },\n        },\n      ],\n    }),\n  ],\n});\n"
  },
  {
    "path": "website/package.json",
    "content": "{\n  \"name\": \"website\",\n  \"type\": \"module\",\n  \"version\": \"0.0.1\",\n  \"scripts\": {\n    \"dev\": \"astro dev\",\n    \"start\": \"astro dev\",\n    \"build\": \"astro check && astro build\",\n    \"preview\": \"astro preview\",\n    \"astro\": \"astro\",\n    \"deploy\": \"npm run build && npx gh-pages -d dist\"\n  },\n  \"dependencies\": {\n    \"@astrojs/check\": \"^0.4.1\",\n    \"@astrojs/starlight\": \"^0.15.3\",\n    \"astro\": \"^4.0.1\",\n    \"sharp\": \"^0.32.5\",\n    \"typescript\": \"^5.9.3\"\n  },\n  \"devDependencies\": {\n    \"gh-pages\": \"^6.1.1\"\n  }\n}\n"
  },
  {
    "path": "website/public/cookie-banner/silktide-consent-manager.css",
    "content": "/* \n  Silktide Consent Manager - https://silktide.com/consent-manager/  \n\n  Styles are at risked of being overridden by styles coming from the site the consent manager is used on.\n  To help prevent this, global wrapper elements are prefixed with \"#silktide-\"\n*/\n\n/* --------------------------------\n  Global Styles - These elements exist in the main DOM and styling is limited to positioning and animation\n-------------------------------- */\n/* Wrapper (Global) */\n#silktide-wrapper {\n              --focus: 0 0 0 2px #ffffff, 0 0 0 4px #000000, 0 0 0 6px #ffffff;\n              --boxShadow: -5px 5px 10px 0px #00000012, 0px 0px 50px 0px #0000001a;\n              --fontFamily: Helvetica Neue, Segoe UI, Arial, sans-serif;\n              --primaryColor: #533BE2;\n              --backgroundColor: #FFFFFF;\n              --textColor: #4B494B;\n              --backdropBackgroundColor: #00000033;\n              --backdropBackgroundBlur: 0px;\n              --cookieIconColor: #533BE2;\n              --cookieIconBackgroundColor: #FFFFFF;\n              position: fixed;\n  bottom: 0;\n  right: 0;\n  width: 100%;\n  height: 100%;\n  z-index: 99999;\n  pointer-events: none;\n  border: 0px;\n  display: flex;\n  justify-content: center;\n  align-items: center\n            }\n\n/* Backdrop (Global) */\n#silktide-backdrop-global {\n  position: fixed;\n  top: 0;\n  left: 0;\n  width: 100%;\n  height: 100%;\n  pointer-events: auto;\n  border: 0px;\n  display: none;\n}\n\n/* --------------------------------\n  Links\n-------------------------------- */\n#silktide-wrapper a {\n  all: unset;\n  display: inline-block;\n  color: var(--primaryColor);\n  text-decoration: underline;\n}\n\n#silktide-wrapper a:hover {\n  cursor: pointer;\n  color: var(--textColor);\n}\n\n/* --------------------------------\n  Focus Styles\n-------------------------------- */\n#silktide-wrapper a:focus,\n#silktide-wrapper #silktide-banner button:focus,\n#silktide-wrapper #silktide-modal button:focus,\n#silktide-wrapper #silktide-cookie-icon:focus {\n  outline: none;\n  box-shadow: var(--focus);\n  border-radius: 5px;\n}\n\n#silktide-wrapper #silktide-cookie-icon:focus {\n  border-radius: 50%;\n}\n\n/* --------------------------------\n  General Styles\n-------------------------------- */\n\n#silktide-wrapper .st-button {\n  color: var(--backgroundColor);\n  background-color: var(--primaryColor);\n  border: 2px solid var(--primaryColor);\n  padding: 10px 20px;\n  text-decoration: none;\n  text-align: center;\n  display: inline-block;\n  font-size: 16px;\n  line-height: 24px;\n  cursor: pointer;\n  border-radius: 5px;\n}\n\n#silktide-wrapper .st-button--primary {\n}\n\n#silktide-wrapper .st-button--primary:hover {\n  background-color: var(--backgroundColor);\n  color: var(--primaryColor);\n}\n\n#silktide-wrapper .st-button--secondary {\n  background-color: var(--backgroundColor);\n  color: var(--primaryColor);\n}\n\n#silktide-wrapper .st-button--secondary:hover {\n  background-color: var(--primaryColor);\n  color: var(--backgroundColor);\n}\n\n/* --------------------------------\n  Banner\n-------------------------------- */\n#silktide-banner {\n  font-family: var(--fontFamily);\n  color: var(--textColor);\n  background-color: var(--backgroundColor);\n  box-sizing: border-box;\n  padding: 32px;\n  border-radius: 5px;\n  pointer-events: auto;\n  border: 0px;\n  position: fixed;\n  bottom: 16px;\n  right: 16px;\n  width: 600px;\n  overflow: auto;\n  max-width: calc(100% - 32px);\n  max-height: calc(100vh - 32px);\n  transform: translate(0, -20px);\n  opacity: 0;\n  animation: silktide-slideInDown 350ms ease-out forwards;\n  animation-delay: 0.3s;\n  box-shadow: -5px 5px 10px 0px #00000012, 0px 0px 50px 0px #0000001a;\n}\n\n#silktide-banner:focus {\n  border-radius: 50%;\n}\n\n#silktide-banner.center {\n  top: 50%;\n  left: 50%;\n  bottom: auto;\n  right: auto;\n  position: fixed;\n  transform: translate(-50%, calc(-50% - 20px));\n  animation: silktide-slideInDown-center 350ms ease-out forwards;\n}\n\n#silktide-banner.bottomLeft {\n  bottom: 16px;\n  left: 16px;\n  position: fixed;\n}\n\n#silktide-banner.bottomCenter {\n  bottom: 16px;\n  left: 50%;\n  position: fixed;\n  transform: translate(-50%, -20px);\n  animation: silktide-slideInDown-bottomCenter 350ms ease-out forwards;\n}\n\n#silktide-banner .preferences {\n  display: flex;\n  gap: 5px;\n  border: none;\n  padding: 15px 0px;\n  background-color: transparent;\n  color: var(--primaryColor);\n  cursor: pointer;\n  font-size: 16px;\n}\n\n#silktide-banner .preferences span {\n  display: block;\n  white-space: nowrap;\n  text-decoration: underline;\n}\n\n#silktide-banner .preferences span:hover {\n  color: var(--textColor);\n}\n\n#silktide-banner .preferences:after {\n  display: block;\n  content: '>';\n  text-decoration: none;\n}\n\n#silktide-banner p {\n  font-size: 16px;\n  line-height: 24px;\n  margin: 0px 0px 15px;\n}\n\n#silktide-banner a {\n  display: inline-block;\n  color: var(--primaryColor);\n  text-decoration: underline;\n  background-color: var(--backgroundColor);\n}\n\n#silktide-banner a:hover {\n  color: var(--textColor);\n}\n\n#silktide-banner a.silktide-logo {\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  fill: var(--primaryColor); /* passed down to svg > path */\n  margin-left: auto;\n  width: 48px;\n  height: 48px;\n}\n\n\n#silktide-banner .actions {\n  display: flex;\n  gap: 16px;\n  flex-direction: column;\n  margin-top: 24px;\n}\n\n@media (min-width: 600px) {\n  #silktide-banner .actions {\n    flex-direction: row;\n    align-items: center;\n  }\n}\n\n#silktide-banner .actions-row {\n  display: flex;\n  gap: 16px;\n  flex-direction: row;\n  align-items: center;\n  justify-content: space-between;\n  flex-grow: 1;\n}\n\n/* --------------------------------\n  Modal\n-------------------------------- */\n#silktide-modal {\n  display: none;\n  pointer-events: auto;\n  overflow: auto;\n  width: 800px;\n  max-width: 100%;\n  max-height: 100%;\n  border: 0px;\n  transform: translate(0px, -20px);\n  opacity: 0;\n  animation: silktide-slideInUp-center 350ms ease-out forwards;\n  box-shadow: -5px 5px 10px 0px #00000012, 0px 0px 50px 0px #0000001a;\n  font-family: var(--fontFamily);\n  color: var(--textColor);\n  flex-direction: column;\n  padding: 30px;\n  background-color: var(--backgroundColor);\n  border-radius: 5px;\n  box-sizing: border-box;\n}\n\n/* --------------------------------\n  Modal - Header\n-------------------------------- */\n#silktide-modal header {\n  display: flex;\n  justify-content: space-between;\n  align-items: center;\n  margin-bottom: 20px;\n  gap: 16px;\n}\n\n#silktide-modal h1 {\n  font-family: var(--fontFamily);\n  color: var(--textColor);\n  font-size: 24px;\n  font-weight: 500;\n  margin: 0px;\n}\n\n#silktide-modal .modal-close {\n  display: inline-flex;\n  border: none;\n  padding: 13px;\n  border: 0px;\n  cursor: pointer;\n  background: var(--backgroundColor);\n  color: var(--primaryColor);\n}\n\n#silktide-modal .modal-close svg {\n  fill: var(--primaryColor);\n}\n\n/* --------------------------------\n  Modal - Content\n-------------------------------- */\n\n#silktide-modal section {\n  flex: 1;\n  margin-top: 32px;\n}\n\n#silktide-modal section::-webkit-scrollbar {\n  display: block; /* Force scrollbars to show */\n  width: 5px; /* Width of the scrollbar */\n}\n\n#silktide-modal section::-webkit-scrollbar-thumb {\n  background-color: var(--textColor); /* Color of the scrollbar thumb */\n  border-radius: 10px; /* Rounded corners for the thumb */\n}\n\n#silktide-modal p {\n  font-size: 16px;\n  line-height: 24px;\n  color: var(--textColor);\n  margin: 0px 0px 15px;\n}\n\n#silktide-modal p:last-of-type {\n  margin: 0px;\n}\n\n#silktide-modal fieldset {\n  padding: 0px;\n  border: none;\n  margin: 0px 0px 32px;\n}\n\n#silktide-modal fieldset:last-of-type {\n  margin: 0px;\n}\n\n#silktide-modal legend {\n  padding: 0px;\n  margin: 0px 0px 10px;\n  font-weight: 700;\n  color: var(--textColor);\n  font-size: 16px;\n}\n\n#silktide-modal .cookie-type-content {\n  display: flex;\n  justify-content: space-between;\n  align-items: flex-start;\n  gap: 24px;  \n}\n\n/* --------------------------------\n  Modal - Switches\n-------------------------------- */\n#silktide-modal .switch {\n  flex-shrink: 0;\n  position: relative;\n  display: inline-block;\n  height: 34px;\n  width: 74px;\n  cursor: pointer;\n}\n\n#silktide-modal .switch:focus-within {\n  outline: none;\n  box-shadow: var(--focus);\n  border-radius: 25px;\n}\n\n#silktide-modal .switch input {\n  opacity: 0;\n  position: absolute;\n}\n\n/* Unchecked Switch Styles */\n#silktide-modal .switch__pill {\n  position: relative;\n  display: block;\n  height: 34px;\n  width: 74px;\n  background: var(--textColor);\n  border-radius: 25px;\n}\n\n#silktide-modal .switch__dot {\n  position: absolute;\n  top: 2px;\n  left: 2px;\n  display: block;\n  height: 30px;\n  width: 30px;\n  background: var(--backgroundColor);\n  border-radius: 50%;\n  transition: left 150ms ease-out;\n}\n\n#silktide-modal .switch__off,\n#silktide-modal .switch__on {\n  text-transform: uppercase;\n  font-size: 15px;\n  font-weight: 500;\n  color: var(--backgroundColor);\n  position: absolute;\n  top: 7px;\n  right: 8px;\n  transition: right 150ms ease-out, opacity 150ms ease-out;\n}\n\n#silktide-modal .switch__off {\n  opacity: 1;\n}\n\n#silktide-modal .switch__on {\n  opacity: 0;\n}\n\n/* Checked Switch Styles */\n#silktide-modal .switch input:checked + .switch__pill {\n  background: var(--primaryColor);\n}\n\n#silktide-modal .switch input:checked ~ .switch__dot {\n  left: calc(100% - 32px);\n}\n\n#silktide-modal .switch input:checked ~ .switch__off {\n  right: calc(100% - 32px);\n  opacity: 0;\n}\n\n#silktide-modal .switch input:checked ~ .switch__on {\n  right: calc(100% - 34px);\n  opacity: 1;\n}\n\n/* Disabled Switch Styles */\n#silktide-modal .switch input:disabled + .switch__pill {\n  opacity: 0.65;\n  cursor: not-allowed;\n}\n\n/* --------------------------------\n  Modal - Footer\n-------------------------------- */\n#silktide-modal footer {\n  display: flex;\n  flex-direction: column;\n  gap: 16px;\n  margin-top: 24px;\n}\n\n@media (min-width: 600px) {\n  #silktide-modal footer {\n    flex-direction: row;\n    align-items: center;\n  }\n}\n\n#silktide-modal footer a {\n  margin-left: auto;\n  padding: 14px 0px;\n}\n\n/* Cookie Icon */\n#silktide-cookie-icon {\n  display: none;\n  position: fixed;\n  bottom: 10px;\n  left: 10px;\n  justify-content: center;\n  align-items: center;\n  width: 60px;\n  height: 60px;\n  border-radius: 50%;\n  padding: 0px;\n  border: none;\n  background-color: var(--cookieIconColor);\n  cursor: pointer;\n  box-shadow: 0px 0px 6px 0px #0000001a;\n  pointer-events: auto;\n  animation: silktide-fadeIn 0.3s ease-in-out forwards;\n  transform: scale(0.7);\n}\n\n#silktide-cookie-icon.bottomRight {\n  left: auto;\n  right: 10px;\n}\n\n#silktide-cookie-icon svg {\n  fill: var(--cookieIconBackgroundColor);\n}\n\n/* --------------------------------\n  Backdrop\n-------------------------------- */\n#silktide-backdrop {\n  display: none;\n  position: absolute;\n  top: 0;\n  left: 0;\n  width: 100%;\n  height: 100%;\n  background-color: var(--backdropBackgroundColor);\n  backdrop-filter: blur(var(--backdropBackgroundBlur));\n  pointer-events: all;\n}\n\n/* --------------------------------\n  Animations\n-------------------------------- */\n@keyframes silktide-fadeIn {\n  from {\n    opacity: 0;\n  }\n  to {\n    opacity: 1;\n  }\n}\n\n@keyframes silktide-slideInDown {\n  from {\n    opacity: 0;\n    transform: translateY(-20px);\n  }\n  to {\n    opacity: 1;\n    transform: translateY(0);\n  }\n}\n\n@keyframes silktide-slideInDown-center {\n  from {\n    opacity: 0;\n    transform: translate(-50%, calc(-50% - 20px));\n  }\n  to {\n    opacity: 1;\n    transform: translate(-50%, -50%);\n  }\n}\n\n@keyframes silktide-slideInDown-bottomCenter {\n  from {\n    opacity: 0;\n    transform: translate(-50%, -20px);\n  }\n  to {\n    opacity: 1;\n    transform: translate(-50%, 0);\n  }\n}\n\n@keyframes silktide-slideInUp-center {\n  from {\n    opacity: 0;\n    transform: translate(0px, 20px);\n  }\n  to {\n    opacity: 1;\n    transform: translate(0px, 0px);\n  }\n}\n"
  },
  {
    "path": "website/public/cookie-banner/silktide-consent-manager.js",
    "content": "// Silktide Consent Manager - https://silktide.com/consent-manager/  \n\nclass SilktideCookieBanner {\n  constructor(config) {\n    this.config = config; // Save config to the instance\n\n    this.wrapper = null;\n    this.banner = null;\n    this.modal = null;\n    this.cookieIcon = null;\n    this.backdrop = null;\n\n    this.createWrapper();\n\n    if (this.shouldShowBackdrop()) {\n      this.createBackdrop();\n    }\n\n    this.createCookieIcon();\n    this.createModal();\n\n    if (this.shouldShowBanner()) {\n      this.createBanner();\n      this.showBackdrop();\n    } else {\n      this.showCookieIcon();\n    }\n\n    this.setupEventListeners();\n\n    if (this.hasSetInitialCookieChoices()) {\n      this.loadRequiredCookies();\n      this.runAcceptedCookieCallbacks();\n    }\n  }\n\n  destroyCookieBanner() {\n    // Remove all cookie banner elements from the DOM\n    if (this.wrapper && this.wrapper.parentNode) {\n      this.wrapper.parentNode.removeChild(this.wrapper);\n    }\n\n    // Restore scrolling\n    this.allowBodyScroll();\n\n    // Clear all references\n    this.wrapper = null;\n    this.banner = null;\n    this.modal = null;\n    this.cookieIcon = null;\n    this.backdrop = null;\n  }\n\n  // ----------------------------------------------------------------\n  // Wrapper\n  // ----------------------------------------------------------------\n  createWrapper() {\n    this.wrapper = document.createElement('div');\n    this.wrapper.id = 'silktide-wrapper';\n    document.body.insertBefore(this.wrapper, document.body.firstChild);\n  }\n\n  // ----------------------------------------------------------------\n  // Wrapper Child Generator\n  // ----------------------------------------------------------------\n  createWrapperChild(htmlContent, id) {\n    // Create child element\n    const child = document.createElement('div');\n    child.id = id;\n    child.innerHTML = htmlContent;\n\n    // Ensure wrapper exists\n    if (!this.wrapper || !document.body.contains(this.wrapper)) {\n      this.createWrapper();\n    }\n\n    // Append child to wrapper\n    this.wrapper.appendChild(child);\n    return child;\n  }\n\n  // ----------------------------------------------------------------\n  // Backdrop\n  // ----------------------------------------------------------------\n  createBackdrop() {\n    this.backdrop = this.createWrapperChild(null, 'silktide-backdrop');\n  }\n\n  showBackdrop() {\n    if (this.backdrop) {\n      this.backdrop.style.display = 'block';\n    }\n    // Trigger optional onBackdropOpen callback\n    if (typeof this.config.onBackdropOpen === 'function') {\n      this.config.onBackdropOpen();\n    }\n  }\n\n  hideBackdrop() {\n    if (this.backdrop) {\n      this.backdrop.style.display = 'none';\n    }\n\n    // Trigger optional onBackdropClose callback\n    if (typeof this.config.onBackdropClose === 'function') {\n      this.config.onBackdropClose();\n    }\n  }\n\n  shouldShowBackdrop() {\n    return this.config?.background?.showBackground || false;\n  }\n\n  // update the checkboxes in the modal with the values from localStorage\n  updateCheckboxState(saveToStorage = false) {\n    const preferencesSection = this.modal.querySelector('#cookie-preferences');\n    const checkboxes = preferencesSection.querySelectorAll('input[type=\"checkbox\"]');\n\n    checkboxes.forEach((checkbox) => {\n      const [, cookieId] = checkbox.id.split('cookies-');\n      const cookieType = this.config.cookieTypes.find(type => type.id === cookieId);\n      \n      if (!cookieType) return;\n\n      if (saveToStorage) {\n        // Save the current state to localStorage and run callbacks\n        const currentState = checkbox.checked;\n        \n        if (cookieType.required) {\n          localStorage.setItem(\n            `silktideCookieChoice_${cookieId}${this.getBannerSuffix()}`,\n            'true'\n          );\n        } else {\n          localStorage.setItem(\n            `silktideCookieChoice_${cookieId}${this.getBannerSuffix()}`,\n            currentState.toString()\n          );\n          \n          // Run appropriate callback\n          if (currentState && typeof cookieType.onAccept === 'function') {\n            cookieType.onAccept();\n          } else if (!currentState && typeof cookieType.onReject === 'function') {\n            cookieType.onReject();\n          }\n        }\n      } else {\n        // When reading values (opening modal)\n        if (cookieType.required) {\n          checkbox.checked = true;\n          checkbox.disabled = true;\n        } else {\n          const storedValue = localStorage.getItem(\n            `silktideCookieChoice_${cookieId}${this.getBannerSuffix()}`\n          );\n          \n          if (storedValue !== null) {\n            checkbox.checked = storedValue === 'true';\n          } else {\n            checkbox.checked = !!cookieType.defaultValue;\n          }\n        }\n      }\n    });\n  }\n\n  setInitialCookieChoiceMade() {\n    window.localStorage.setItem(`silktideCookieBanner_InitialChoice${this.getBannerSuffix()}`, 1);\n  }\n\n  // ----------------------------------------------------------------\n  // Consent Handling\n  // ----------------------------------------------------------------\n  handleCookieChoice(accepted) {\n    // We set that an initial choice was made regardless of what it was so we don't show the banner again\n    this.setInitialCookieChoiceMade();\n\n    this.removeBanner();\n    this.hideBackdrop();\n    this.toggleModal(false);\n    this.showCookieIcon();\n\n    this.config.cookieTypes.forEach((type) => {\n      // Set localStorage and run accept/reject callbacks\n      if (type.required == true) {\n        localStorage.setItem(`silktideCookieChoice_${type.id}${this.getBannerSuffix()}`, 'true');\n        if (typeof type.onAccept === 'function') { type.onAccept() }\n      } else {\n        localStorage.setItem(\n          `silktideCookieChoice_${type.id}${this.getBannerSuffix()}`,\n          accepted.toString(),\n        );\n\n        if (accepted) {\n          if (typeof type.onAccept === 'function') { type.onAccept(); }\n        } else {\n          if (typeof type.onReject === 'function') { type.onReject(); }\n        }\n      }\n    });\n\n    // Trigger optional onAcceptAll/onRejectAll callbacks\n    if (accepted && typeof this.config.onAcceptAll === 'function') {\n      if (typeof this.config.onAcceptAll === 'function') { this.config.onAcceptAll(); }\n    } else if (typeof this.config.onRejectAll === 'function') {\n      if (typeof this.config.onRejectAll === 'function') { this.config.onRejectAll(); }\n    }\n\n    // finally update the checkboxes in the modal with the values from localStorage\n    this.updateCheckboxState();\n  }\n\n  getAcceptedCookies() {\n    return (this.config.cookieTypes || []).reduce((acc, cookieType) => {\n      acc[cookieType.id] =\n        localStorage.getItem(`silktideCookieChoice_${cookieType.id}${this.getBannerSuffix()}`) ===\n        'true';\n      return acc;\n    }, {});\n  }\n\n  runAcceptedCookieCallbacks() {\n    if (!this.config.cookieTypes) return;\n\n    const acceptedCookies = this.getAcceptedCookies();\n    this.config.cookieTypes.forEach((type) => {\n      if (type.required) return; // we run required cookies separately in loadRequiredCookies\n      if (acceptedCookies[type.id] && typeof type.onAccept === 'function') {\n        if (typeof type.onAccept === 'function') { type.onAccept(); }\n      }\n    });\n  }\n\n  runRejectedCookieCallbacks() {\n    if (!this.config.cookieTypes) return;\n\n    const rejectedCookies = this.getRejectedCookies();\n    this.config.cookieTypes.forEach((type) => {\n      if (rejectedCookies[type.id] && typeof type.onReject === 'function') {\n        if (typeof type.onReject === 'function') { type.onReject(); }\n      }\n    });\n  }\n\n  /**\n   * Run through all of the cookie callbacks based on the current localStorage values\n   */\n  runStoredCookiePreferenceCallbacks() {\n    this.config.cookieTypes.forEach((type) => {\n      const accepted =\n        localStorage.getItem(`silktideCookieChoice_${type.id}${this.getBannerSuffix()}`) === 'true';\n      // Set localStorage and run accept/reject callbacks\n      if (accepted) {\n        if (typeof type.onAccept === 'function') { type.onAccept(); }\n      } else {\n        if (typeof type.onReject === 'function') { type.onReject(); }\n      }\n    });\n  }\n\n  loadRequiredCookies() {\n    if (!this.config.cookieTypes) return;\n    this.config.cookieTypes.forEach((cookie) => {\n      if (cookie.required && typeof cookie.onAccept === 'function') {\n        if (typeof cookie.onAccept === 'function') { cookie.onAccept(); }\n      }\n    });\n  }\n\n  // ----------------------------------------------------------------\n  // Banner\n  // ----------------------------------------------------------------\n  getBannerContent() {\n    const bannerDescription =\n      this.config.text?.banner?.description ||\n      \"<p>We use cookies on our site to enhance your user experience, provide personalized content, and analyze our traffic.</p>\";\n\n    // Accept button\n    const acceptAllButtonText = this.config.text?.banner?.acceptAllButtonText || 'Accept all';\n    const acceptAllButtonLabel = this.config.text?.banner?.acceptAllButtonAccessibleLabel;\n    const acceptAllButton = `<button class=\"accept-all st-button st-button--primary\"${\n      acceptAllButtonLabel && acceptAllButtonLabel !== acceptAllButtonText \n        ? ` aria-label=\"${acceptAllButtonLabel}\"` \n        : ''\n    }>${acceptAllButtonText}</button>`;\n    \n    // Reject button\n    const rejectNonEssentialButtonText = this.config.text?.banner?.rejectNonEssentialButtonText || 'Reject non-essential';\n    const rejectNonEssentialButtonLabel = this.config.text?.banner?.rejectNonEssentialButtonAccessibleLabel;\n    const rejectNonEssentialButton = `<button class=\"reject-all st-button st-button--primary\"${\n      rejectNonEssentialButtonLabel && rejectNonEssentialButtonLabel !== rejectNonEssentialButtonText \n        ? ` aria-label=\"${rejectNonEssentialButtonLabel}\"` \n        : ''\n    }>${rejectNonEssentialButtonText}</button>`;\n\n    // Preferences button\n    const preferencesButtonText = this.config.text?.banner?.preferencesButtonText || 'Preferences';\n    const preferencesButtonLabel = this.config.text?.banner?.preferencesButtonAccessibleLabel;\n    const preferencesButton = `<button class=\"preferences\"${\n      preferencesButtonLabel && preferencesButtonLabel !== preferencesButtonText \n        ? ` aria-label=\"${preferencesButtonLabel}\"` \n        : ''\n    }><span>${preferencesButtonText}</span></button>`;\n    \n\n    // Silktide logo link\n    const silktideLogo = `\n      <a class=\"silktide-logo\" href=\"https://silktide.com/consent-manager\" target=\"_blank\" rel=\"noreferrer\" aria-label=\"Visit the Silktide Consent Manager page\">\n        <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"25\" viewBox=\"0 0 24 25\" fill=\"inherit\">\n          <path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M14.1096 16.7745C13.8895 17.2055 13.3537 17.3805 12.9129 17.1653L8.28443 14.9055L2.73192 17.7651L11.1025 21.9814C11.909 22.3876 12.8725 22.3591 13.6524 21.9058L20.4345 17.9645C21.2845 17.4704 21.7797 16.5522 21.7164 15.5872L21.7088 15.4704C21.6487 14.5561 21.0962 13.7419 20.2579 13.3326L15.6793 11.0972L10.2283 13.9045L13.71 15.6043C14.1507 15.8195 14.3297 16.3434 14.1096 16.7745ZM8.2627 12.9448L13.7136 10.1375L10.2889 8.46543C9.84803 8.25021 9.66911 7.72629 9.88916 7.29524C10.1093 6.86417 10.6451 6.68921 11.0859 6.90442L15.6575 9.13647L21.2171 6.27325L12.8808 2.03496C12.0675 1.62147 11.0928 1.65154 10.3078 2.11432L3.54908 6.09869C2.70732 6.59492 2.21846 7.50845 2.28139 8.46761L2.29003 8.59923C2.35002 9.51362 2.9026 10.3278 3.7409 10.7371L8.2627 12.9448ZM6.31884 13.9458L2.94386 12.2981C1.53727 11.6113 0.610092 10.2451 0.509431 8.71094L0.500795 8.57933C0.3952 6.96993 1.21547 5.4371 2.62787 4.60447L9.38662 0.620092C10.7038 -0.156419 12.3392 -0.206861 13.7039 0.486938L23.3799 5.40639C23.4551 5.44459 23.5224 5.4918 23.5811 5.54596C23.7105 5.62499 23.8209 5.73754 23.897 5.87906C24.1266 6.30534 23.9594 6.83293 23.5234 7.05744L17.6231 10.0961L21.0549 11.7716C22.4615 12.4583 23.3887 13.8245 23.4893 15.3587L23.497 15.4755C23.6033 17.0947 22.7724 18.6354 21.346 19.4644L14.5639 23.4057C13.2554 24.1661 11.6386 24.214 10.2854 23.5324L0.621855 18.6649C0.477299 18.592 0.361696 18.4859 0.279794 18.361C0.210188 18.2968 0.150054 18.2204 0.10296 18.133C-0.126635 17.7067 0.0406445 17.1792 0.47659 16.9546L6.31884 13.9458Z\" fill=\"inherit\"/>\n        </svg>\n      </a>\n    `;\n\n    const bannerContent = `\n      ${bannerDescription}\n      <div class=\"actions\">                               \n        ${acceptAllButton}\n        ${rejectNonEssentialButton}\n        <div class=\"actions-row\">\n          ${preferencesButton}\n          ${silktideLogo}\n        </div>\n      </div>\n    `;\n\n    return bannerContent;\n  }\n\n  hasSetInitialCookieChoices() {\n    return !!localStorage.getItem(`silktideCookieBanner_InitialChoice${this.getBannerSuffix()}`);\n  }\n\n  createBanner() {\n    // Create banner element\n    this.banner = this.createWrapperChild(this.getBannerContent(), 'silktide-banner');\n\n    // Add positioning class from config\n    if (this.banner && this.config.position?.banner) {\n      this.banner.classList.add(this.config.position.banner);\n    }\n\n    // Trigger optional onBannerOpen callback\n    if (this.banner && typeof this.config.onBannerOpen === 'function') {\n      this.config.onBannerOpen();\n    }\n  }\n\n  removeBanner() {\n    if (this.banner && this.banner.parentNode) {\n      this.banner.parentNode.removeChild(this.banner);\n      this.banner = null;\n\n      // Trigger optional onBannerClose callback\n      if (typeof this.config.onBannerClose === 'function') {\n        this.config.onBannerClose();\n      }\n    }\n  }\n\n  shouldShowBanner() {\n    if (this.config.showBanner === false) {\n      return false;\n    }\n    return (\n      localStorage.getItem(`silktideCookieBanner_InitialChoice${this.getBannerSuffix()}`) === null\n    );\n  }\n\n  // ----------------------------------------------------------------\n  // Modal\n  // ----------------------------------------------------------------\n  getModalContent() {\n    const preferencesTitle =\n      this.config.text?.preferences?.title || 'Customize your cookie preferences';\n    \n    const preferencesDescription =\n      this.config.text?.preferences?.description ||\n      \"<p>We respect your right to privacy. You can choose not to allow some types of cookies. Your cookie preferences will apply across our website.</p>\";\n    \n    // Preferences button\n    const preferencesButtonLabel = this.config.text?.banner?.preferencesButtonAccessibleLabel;\n\n    const closeModalButton = `<button class=\"modal-close\"${preferencesButtonLabel ? ` aria-label=\"${preferencesButtonLabel}\"` : ''}>\n      <svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n          <path d=\"M19.4081 3.41559C20.189 2.6347 20.189 1.36655 19.4081 0.585663C18.6272 -0.195221 17.3591 -0.195221 16.5782 0.585663L10 7.17008L3.41559 0.59191C2.6347 -0.188974 1.36655 -0.188974 0.585663 0.59191C-0.195221 1.37279 -0.195221 2.64095 0.585663 3.42183L7.17008 10L0.59191 16.5844C-0.188974 17.3653 -0.188974 18.6335 0.59191 19.4143C1.37279 20.1952 2.64095 20.1952 3.42183 19.4143L10 12.8299L16.5844 19.4081C17.3653 20.189 18.6335 20.189 19.4143 19.4081C20.1952 18.6272 20.1952 17.3591 19.4143 16.5782L12.8299 10L19.4081 3.41559Z\"/>\n      </svg>\n    </button>`;\n    \n\n    const cookieTypes = this.config.cookieTypes || [];\n    const acceptedCookieMap = this.getAcceptedCookies();\n\n    // Accept button\n    const acceptAllButtonText = this.config.text?.banner?.acceptAllButtonText || 'Accept all';\n    const acceptAllButtonLabel = this.config.text?.banner?.acceptAllButtonAccessibleLabel;\n    const acceptAllButton = `<button class=\"preferences-accept-all st-button st-button--primary\"${\n      acceptAllButtonLabel && acceptAllButtonLabel !== acceptAllButtonText \n        ? ` aria-label=\"${acceptAllButtonLabel}\"` \n        : ''\n    }>${acceptAllButtonText}</button>`;\n    \n    // Reject button\n    const rejectNonEssentialButtonText = this.config.text?.banner?.rejectNonEssentialButtonText || 'Reject non-essential';\n    const rejectNonEssentialButtonLabel = this.config.text?.banner?.rejectNonEssentialButtonAccessibleLabel;\n    const rejectNonEssentialButton = `<button class=\"preferences-reject-all st-button st-button--primary\"${\n      rejectNonEssentialButtonLabel && rejectNonEssentialButtonLabel !== rejectNonEssentialButtonText \n        ? ` aria-label=\"${rejectNonEssentialButtonLabel}\"` \n        : ''\n    }>${rejectNonEssentialButtonText}</button>`;\n    \n    // Credit link\n    const creditLinkText = this.config.text?.preferences?.creditLinkText || 'Get this banner for free';\n    const creditLinkAccessibleLabel = this.config.text?.preferences?.creditLinkAccessibleLabel;\n    const creditLink = `<a href=\"https://silktide.com/consent-manager\" target=\"_blank\" rel=\"noreferrer\"${\n      creditLinkAccessibleLabel && creditLinkAccessibleLabel !== creditLinkText\n        ? ` aria-label=\"${creditLinkAccessibleLabel}\"`\n        : ''\n    }>${creditLinkText}</a>`;\n    \n    \n\n    const modalContent = `\n      <header>\n        <h1>${preferencesTitle}</h1>                    \n        ${closeModalButton}\n      </header>\n      ${preferencesDescription}\n      <section id=\"cookie-preferences\">\n        ${cookieTypes\n          .map((type) => {\n            const accepted = acceptedCookieMap[type.id];\n            let isChecked = false;\n\n            // if it's accepted then show as checked\n            if (accepted) {\n              isChecked = true;\n            }\n\n            // if nothing has been accepted / rejected yet, then show as checked if the default value is true\n            if (!accepted && !this.hasSetInitialCookieChoices()) {\n              isChecked = type.defaultValue;\n            }\n\n            return `\n            <fieldset>\n                <legend>${type.name}</legend>\n                <div class=\"cookie-type-content\">\n                    <div class=\"cookie-type-description\">${type.description}</div>\n                    <label class=\"switch\" for=\"cookies-${type.id}\">\n                        <input type=\"checkbox\" id=\"cookies-${type.id}\" ${\n              type.required ? 'checked disabled' : isChecked ? 'checked' : ''\n            } />\n                        <span class=\"switch__pill\" aria-hidden=\"true\"></span>\n                        <span class=\"switch__dot\" aria-hidden=\"true\"></span>\n                        <span class=\"switch__off\" aria-hidden=\"true\">Off</span>\n                        <span class=\"switch__on\" aria-hidden=\"true\">On</span>\n                    </label>\n                </div>\n            </fieldset>\n        `;\n          })\n          .join('')}\n      </section>\n      <footer>\n        ${acceptAllButton}\n        ${rejectNonEssentialButton}\n        ${creditLink}\n      </footer>\n    `;\n\n    return modalContent;\n  }\n\n  createModal() {\n    // Create banner element\n    this.modal = this.createWrapperChild(this.getModalContent(), 'silktide-modal');\n  }\n\n  toggleModal(show) {\n    if (!this.modal) return;\n\n    this.modal.style.display = show ? 'flex' : 'none';\n\n    if (show) {\n      this.showBackdrop();\n      this.hideCookieIcon();\n      this.removeBanner();\n      this.preventBodyScroll();\n\n      // Focus the close button\n      const modalCloseButton = this.modal.querySelector('.modal-close');\n      modalCloseButton.focus();\n\n      // Trigger optional onPreferencesOpen callback\n      if (typeof this.config.onPreferencesOpen === 'function') {\n        this.config.onPreferencesOpen();\n      }\n\n      this.updateCheckboxState(false); // read from storage when opening\n    } else {\n      // Set that an initial choice was made when closing the modal\n      this.setInitialCookieChoiceMade();\n      \n      // Save current checkbox states to storage\n      this.updateCheckboxState(true);\n\n      this.hideBackdrop();\n      this.showCookieIcon();\n      this.allowBodyScroll();\n\n      // Trigger optional onPreferencesClose callback\n      if (typeof this.config.onPreferencesClose === 'function') {\n        this.config.onPreferencesClose();\n      }\n    }\n  }\n\n  // ----------------------------------------------------------------\n  // Cookie Icon\n  // ----------------------------------------------------------------\n  getCookieIconContent() {\n    return `\n      <svg width=\"38\" height=\"38\" viewBox=\"0 0 38 38\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n          <path d=\"M19.1172 1.15625C19.0547 0.734374 18.7344 0.390624 18.3125 0.328124C16.5859 0.0859365 14.8281 0.398437 13.2813 1.21875L7.5 4.30469C5.96094 5.125 4.71875 6.41406 3.95313 7.98437L1.08594 13.8906C0.320314 15.4609 0.0703136 17.2422 0.375001 18.9609L1.50781 25.4297C1.8125 27.1562 2.64844 28.7344 3.90625 29.9531L8.61719 34.5156C9.875 35.7344 11.4766 36.5156 13.2031 36.7578L19.6875 37.6719C21.4141 37.9141 23.1719 37.6016 24.7188 36.7812L30.5 33.6953C32.0391 32.875 33.2813 31.5859 34.0469 30.0078L36.9141 24.1094C37.6797 22.5391 37.9297 20.7578 37.625 19.0391C37.5547 18.625 37.2109 18.3125 36.7969 18.25C32.7734 17.6094 29.5469 14.5703 28.6328 10.6406C28.4922 10.0469 28.0078 9.59375 27.4063 9.5C23.1406 8.82031 19.7734 5.4375 19.1094 1.15625H19.1172ZM15.25 10.25C15.913 10.25 16.5489 10.5134 17.0178 10.9822C17.4866 11.4511 17.75 12.087 17.75 12.75C17.75 13.413 17.4866 14.0489 17.0178 14.5178C16.5489 14.9866 15.913 15.25 15.25 15.25C14.587 15.25 13.9511 14.9866 13.4822 14.5178C13.0134 14.0489 12.75 13.413 12.75 12.75C12.75 12.087 13.0134 11.4511 13.4822 10.9822C13.9511 10.5134 14.587 10.25 15.25 10.25ZM10.25 25.25C10.25 24.587 10.5134 23.9511 10.9822 23.4822C11.4511 23.0134 12.087 22.75 12.75 22.75C13.413 22.75 14.0489 23.0134 14.5178 23.4822C14.9866 23.9511 15.25 24.587 15.25 25.25C15.25 25.913 14.9866 26.5489 14.5178 27.0178C14.0489 27.4866 13.413 27.75 12.75 27.75C12.087 27.75 11.4511 27.4866 10.9822 27.0178C10.5134 26.5489 10.25 25.913 10.25 25.25ZM27.75 20.25C28.413 20.25 29.0489 20.5134 29.5178 20.9822C29.9866 21.4511 30.25 22.087 30.25 22.75C30.25 23.413 29.9866 24.0489 29.5178 24.5178C29.0489 24.9866 28.413 25.25 27.75 25.25C27.087 25.25 26.4511 24.9866 25.9822 24.5178C25.5134 24.0489 25.25 23.413 25.25 22.75C25.25 22.087 25.5134 21.4511 25.9822 20.9822C26.4511 20.5134 27.087 20.25 27.75 20.25Z\" />\n      </svg>\n    `;\n  }\n\n  createCookieIcon() {\n    this.cookieIcon = document.createElement('button');\n    this.cookieIcon.id = 'silktide-cookie-icon';\n    this.cookieIcon.title = 'Manage your cookie preferences for this site';\n    this.cookieIcon.innerHTML = this.getCookieIconContent();\n\n    if (this.config.text?.banner?.preferencesButtonAccessibleLabel) {\n      this.cookieIcon.ariaLabel = this.config.text?.banner?.preferencesButtonAccessibleLabel;\n    }\n\n    // Ensure wrapper exists\n    if (!this.wrapper || !document.body.contains(this.wrapper)) {\n      this.createWrapper();\n    }\n\n    // Append child to wrapper\n    this.wrapper.appendChild(this.cookieIcon);\n\n    // Add positioning class from config\n    if (this.cookieIcon && this.config.cookieIcon?.position) {\n      this.cookieIcon.classList.add(this.config.cookieIcon.position);\n    }\n\n    // Add color scheme class from config\n    if (this.cookieIcon && this.config.cookieIcon?.colorScheme) {\n      this.cookieIcon.classList.add(this.config.cookieIcon.colorScheme);\n    }\n  }\n\n  showCookieIcon() {\n    if (this.cookieIcon) {\n      this.cookieIcon.style.display = 'flex';\n    }\n  }\n\n  hideCookieIcon() {\n    if (this.cookieIcon) {\n      this.cookieIcon.style.display = 'none';\n    }\n  }\n\n  /**\n   * This runs if the user closes the modal without making a choice for the first time\n   * We apply the default values and the necessary values as default\n   */\n  handleClosedWithNoChoice() {\n    this.config.cookieTypes.forEach((type) => {\n      let accepted = true;\n      // Set localStorage and run accept/reject callbacks\n      if (type.required == true || type.defaultValue) {\n        localStorage.setItem(\n          `silktideCookieChoice_${type.id}${this.getBannerSuffix()}`,\n          accepted.toString(),\n        );\n      } else {\n        accepted = false;\n        localStorage.setItem(\n          `silktideCookieChoice_${type.id}${this.getBannerSuffix()}`,\n          accepted.toString(),\n        );\n      }\n\n      if (accepted) {\n        if (typeof type.onAccept === 'function') { type.onAccept(); }\n      } else {\n        if (typeof type.onReject === 'function') { type.onReject(); }\n      }\n      // set the flag to say that the cookie choice has been made\n      this.setInitialCookieChoiceMade();\n      this.updateCheckboxState();\n    });\n  }\n\n  // ----------------------------------------------------------------\n  // Focusable Elements\n  // ----------------------------------------------------------------\n  getFocusableElements(element) {\n    return element.querySelectorAll(\n      'button, a[href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])',\n    );\n  }\n\n  // ----------------------------------------------------------------\n  // Event Listeners\n  // ----------------------------------------------------------------\n  setupEventListeners() {\n    // Check Banner exists before trying to add event listeners\n    if (this.banner) {\n      // Get the buttons\n      const acceptButton = this.banner.querySelector('.accept-all');\n      const rejectButton = this.banner.querySelector('.reject-all');\n      const preferencesButton = this.banner.querySelector('.preferences');\n\n      // Add event listeners to the buttons\n      acceptButton?.addEventListener('click', () => this.handleCookieChoice(true));\n      rejectButton?.addEventListener('click', () => this.handleCookieChoice(false));\n      preferencesButton?.addEventListener('click', () => {\n        this.showBackdrop();\n        this.toggleModal(true);\n      });\n\n      // Focus Trap\n      const focusableElements = this.getFocusableElements(this.banner);\n      const firstFocusableEl = focusableElements[0];\n      const lastFocusableEl = focusableElements[focusableElements.length - 1];\n\n      // Add keydown event listener to handle tab navigation\n      this.banner.addEventListener('keydown', (e) => {\n        if (e.key === 'Tab') {\n          if (e.shiftKey) {\n            if (document.activeElement === firstFocusableEl) {\n              lastFocusableEl.focus();\n              e.preventDefault();\n            }\n          } else {\n            if (document.activeElement === lastFocusableEl) {\n              firstFocusableEl.focus();\n              e.preventDefault();\n            }\n          }\n        }\n      });\n\n      // Set initial focus\n      if (this.config.mode !== 'wizard') {\n        acceptButton?.focus();\n      }\n    }\n\n    // Check Modal exists before trying to add event listeners\n    if (this.modal) {\n      const closeButton = this.modal.querySelector('.modal-close');\n      const acceptAllButton = this.modal.querySelector('.preferences-accept-all');\n      const rejectAllButton = this.modal.querySelector('.preferences-reject-all');\n\n      closeButton?.addEventListener('click', () => {\n        this.toggleModal(false);\n\n        const hasMadeFirstChoice = this.hasSetInitialCookieChoices();\n\n        if (hasMadeFirstChoice) {\n          // run through the callbacks based on the current localStorage state\n          this.runStoredCookiePreferenceCallbacks();\n        } else {\n          // handle the case where the user closes without making a choice for the first time\n          this.handleClosedWithNoChoice();\n        }\n      });\n      acceptAllButton?.addEventListener('click', () => this.handleCookieChoice(true));\n      rejectAllButton?.addEventListener('click', () => this.handleCookieChoice(false));\n\n      // Banner Focus Trap\n      const focusableElements = this.getFocusableElements(this.modal);\n      const firstFocusableEl = focusableElements[0];\n      const lastFocusableEl = focusableElements[focusableElements.length - 1];\n\n      this.modal.addEventListener('keydown', (e) => {\n        if (e.key === 'Tab') {\n          if (e.shiftKey) {\n            if (document.activeElement === firstFocusableEl) {\n              lastFocusableEl.focus();\n              e.preventDefault();\n            }\n          } else {\n            if (document.activeElement === lastFocusableEl) {\n              firstFocusableEl.focus();\n              e.preventDefault();\n            }\n          }\n        }\n        if (e.key === 'Escape') {\n          this.toggleModal(false);\n        }\n      });\n\n      closeButton?.focus();\n\n      // Update the checkbox event listeners\n      const preferencesSection = this.modal.querySelector('#cookie-preferences');\n      const checkboxes = preferencesSection.querySelectorAll('input[type=\"checkbox\"]');\n      \n      checkboxes.forEach(checkbox => {\n        checkbox.addEventListener('change', (event) => {\n          const [, cookieId] = event.target.id.split('cookies-');\n          const isAccepted = event.target.checked;\n          const previousValue = localStorage.getItem(\n            `silktideCookieChoice_${cookieId}${this.getBannerSuffix()}`\n          ) === 'true';\n          \n          // Only proceed if the value has actually changed\n          if (isAccepted !== previousValue) {\n            // Find the corresponding cookie type\n            const cookieType = this.config.cookieTypes.find(type => type.id === cookieId);\n            \n            if (cookieType) {\n              // Update localStorage\n              localStorage.setItem(\n                `silktideCookieChoice_${cookieId}${this.getBannerSuffix()}`,\n                isAccepted.toString()\n              );\n              \n              // Run the appropriate callback only if the value changed\n              if (isAccepted && typeof cookieType.onAccept === 'function') {\n                cookieType.onAccept();\n              } else if (!isAccepted && typeof cookieType.onReject === 'function') {\n                cookieType.onReject();\n              }\n            }\n          }\n        });\n      });\n    }\n\n    // Check Cookie Icon exists before trying to add event listeners\n    if (this.cookieIcon) {\n\n      this.cookieIcon.addEventListener('click', () => {\n        // If modal is not found, create it\n        if (!this.modal) {\n          this.createModal();\n          this.toggleModal(true);\n          this.hideCookieIcon();\n        }\n        // If modal is hidden, show it\n        else if (this.modal.style.display === 'none' || this.modal.style.display === '') {\n          this.toggleModal(true);\n          this.hideCookieIcon();\n        }\n        // If modal is visible, hide it\n        else {\n          this.toggleModal(false);\n        }\n      });\n    }\n  }\n\n  getBannerSuffix() {\n    if (this.config.bannerSuffix) {\n      return '_' + this.config.bannerSuffix;\n    }\n    return '';\n  }\n\n  preventBodyScroll() {\n    document.body.style.overflow = 'hidden';\n    // Prevent iOS Safari scrolling\n    document.body.style.position = 'fixed';\n    document.body.style.width = '100%';\n  }\n\n  allowBodyScroll() {\n    document.body.style.overflow = '';\n    document.body.style.position = '';\n    document.body.style.width = '';\n  }\n}\n\n(function () {\n  window.silktideCookieBannerManager = {};\n\n  let config = {};\n  let cookieBanner;\n\n  function updateCookieBannerConfig(userConfig = {}) {\n    config = {...config, ...userConfig};\n\n    // If cookie banner exists, destroy and recreate it with new config\n    if (cookieBanner) {\n      cookieBanner.destroyCookieBanner(); // We'll need to add this method\n      cookieBanner = null;\n    }\n\n    // Only initialize if document.body exists\n    if (document.body) {\n      initCookieBanner();\n    } else {\n      // Wait for DOM to be ready\n      document.addEventListener('DOMContentLoaded', initCookieBanner, {once: true});\n    }\n  }\n\n  function initCookieBanner() {\n    if (!cookieBanner) {\n      cookieBanner = new SilktideCookieBanner(config); // Pass config to the CookieBanner instance\n    }\n  }\n\n  function injectScript(url, loadOption) {\n    // Check if script with this URL already exists\n    const existingScript = document.querySelector(`script[src=\"${url}\"]`);\n    if (existingScript) {\n      return; // Script already exists, don't add it again\n    }\n\n    const script = document.createElement('script');\n    script.src = url;\n\n    // Apply the async or defer attribute based on the loadOption parameter\n    if (loadOption === 'async') {\n      script.async = true;\n    } else if (loadOption === 'defer') {\n      script.defer = true;\n    }\n\n    document.head.appendChild(script);\n  }\n\n  window.silktideCookieBannerManager.initCookieBanner = initCookieBanner;\n  window.silktideCookieBannerManager.updateCookieBannerConfig = updateCookieBannerConfig;\n  window.silktideCookieBannerManager.injectScript = injectScript;\n\n  if (document.readyState === 'loading') {\n    document.addEventListener('DOMContentLoaded', initCookieBanner, {once: true});\n  } else {\n    initCookieBanner();\n  }\n})();"
  },
  {
    "path": "website/public/cookie_policy.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  <title>Cookie Policy</title>\n  <style>\n    body {\n      font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif;\n      line-height: 1.6;\n      color: #333;\n      max-width: 800px;\n      margin: 0 auto;\n      padding: 2rem;\n      background-color: #f9f9f9;\n    }\n    h1 {\n      color: #222;\n      border-bottom: 2px solid #eaeaea;\n      padding-bottom: 0.5rem;\n    }\n    h2 {\n      color: #444;\n      margin-top: 1.5rem;\n    }\n    p {\n      margin-bottom: 1rem;\n    }\n    .container {\n      background-color: #fff;\n      padding: 2rem;\n      border-radius: 8px;\n      box-shadow: 0 4px 6px rgba(0,0,0,0.05);\n    }\n  </style>\n</head>\n<body>\n  <div class=\"container\">\n    <h1>Cookie Policy</h1>\n    <p>This Cookie Policy explains how we use cookies and similar technologies to recognize you when you visit our website. It explains what these technologies are and why we use them, as well as your rights to control our use of them.</p>\n\n    <h2>What are cookies?</h2>\n    <p>Cookies are small data files that are placed on your computer or mobile device when you visit a website. Cookies are widely used by website owners in order to make their websites work, or to work more efficiently, as well as to provide reporting information.</p>\n\n    <h2>Types of Cookies We Use</h2>\n\n    <h3>Necessary cookies</h3>\n    <p>These cookies are strictly necessary to provide you with services available through our website and to use some of its features. Because these cookies are essential for the website to function properly, you cannot refuse them without impacting how our site functions. They help with basic functionalities such as secure login, setting your privacy preferences, and maintaining session state.</p>\n\n    <h3>Analytical Cookies (e.g., Google Analytics)</h3>\n    <p>Analytical cookies collect information that is used either in aggregate form to help us understand how our website is being used or how effective our marketing campaigns are, or to help us customize our website for you. They help us collect reporting information on its usage and continuously optimize the user experience.</p>\n\n    <h3>Marketing/Advertising Cookies (e.g., Google AdSense or Carbon Ads)</h3>\n    <p>We use marketing cookies to make advertising messages more relevant to you. They perform functions like preventing the same ad from continuously reappearing, ensuring that ads are properly displayed for advertisers, and in some cases selecting advertisements that are based on your specific interests. These cookies are typically provided by third-party advertising networks.</p>\n\n    <h2>How can you control cookies?</h2>\n    <p>You have the right to decide whether to accept or reject non-essential cookies. You can exercise your cookie rights by setting your preferences in the Cookie Consent Manager or by amending your web browser controls to accept or refuse cookies. If you choose to reject cookies, you may still use our website though your access to some functionality and areas of our website may be restricted.</p>\n  </div>\n</body>\n</html>\n"
  },
  {
    "path": "website/public/google184c8848cff38265.html",
    "content": "google-site-verification: google184c8848cff38265.html"
  },
  {
    "path": "website/src/components/Hero.astro",
    "content": "---\nimport { Image } from 'astro:assets';\nimport CallToAction from '@astrojs/starlight/components/CallToAction.astro';\nimport type { Props } from '@astrojs/starlight/props';\n\nconst { entry } = Astro.props;\nconst { data } = entry;\nconst { title = data.title, tagline, image, actions = [] } = data.hero || {};\n\nconst imageAttrs = {\n\tloading: 'eager' as const,\n\tdecoding: 'async' as const,\n\twidth: 400,\n\theight: 400,\n\talt: image?.alt || '',\n};\n\nlet darkImage: ImageMetadata | undefined;\nlet lightImage: ImageMetadata | undefined;\nlet rawHtml: string | undefined;\nif (image) {\n\tif ('file' in image) {\n\t\tdarkImage = image.file;\n\t} else if ('dark' in image) {\n\t\tdarkImage = image.dark;\n\t\tlightImage = image.light;\n\t} else {\n\t\trawHtml = image.html;\n\t}\n}\n---\n\n<div class=\"hero\">\n\t{darkImage && (\n\t\t<Image\n\t\t\tsrc={darkImage}\n\t\t\t{...imageAttrs}\n\t\t\tclass:list={{ 'light:sl-hidden': Boolean(lightImage) }}\n\t\t/>\n\t)}\n\t{lightImage && <Image src={lightImage} {...imageAttrs} class=\"dark:sl-hidden\" />}\n\t{rawHtml && <div class=\"hero-html sl-flex\" set:html={rawHtml} />}\n\t<div class=\"sl-flex stack\">\n\t\t<div class=\"sl-flex copy\">\n\t\t\t<h1 id=\"_top\" data-page-title set:html={title} />\n\t\t\t{tagline && <div class=\"tagline\" set:html={tagline} />}\n\t\t</div>\n\t\t{actions.length > 0 && (\n\t\t\t<div class=\"sl-flex actions\">\n\t\t\t\t{actions.map((action) => (\n\t\t\t\t\t<CallToAction {...action}>{action.text}</CallToAction>\n\t\t\t\t))}\n\t\t\t</div>\n\t\t)}\n\t</div>\n\t<div class=\"home-banner\">\n\t\t<script async type=\"text/javascript\" src=\"//cdn.carbonads.com/carbon.js?serve=CWBDPK3L&placement=gibbokgithubio&format=cover\" id=\"_carbonads_js\" is:inline></script>\n\t</div>\n</div>\n\n<style>\n\t@layer starlight.core {\n\t\t.hero {\n\t\t\tdisplay: grid;\n\t\t\talign-items: center;\n\t\t\tgap: 1rem;\n\t\t\tpadding-bottom: 1rem;\n\t\t\tjustify-items: center;\n\t\t}\n\n\t\t.hero > img,\n\t\t.hero > .hero-html {\n\t\t\tobject-fit: contain;\n\t\t\twidth: min(70%, 20rem);\n\t\t\theight: auto;\n\t\t\tmargin-inline: auto;\n\t\t}\n\n\t\t.stack {\n\t\t\tflex-direction: column;\n\t\t\tgap: clamp(1.5rem, calc(1.5rem + 1vw), 2rem);\n\t\t\ttext-align: center;\n\t\t}\n\n\t\t.copy {\n\t\t\tflex-direction: column;\n\t\t\tgap: 1rem;\n\t\t\talign-items: center;\n\t\t}\n\n\t\t.copy > * {\n\t\t\tmax-width: 50ch;\n\t\t}\n\n\t\th1 {\n\t\t\tfont-size: clamp(var(--sl-text-3xl), calc(0.25rem + 5vw), var(--sl-text-6xl));\n\t\t\tline-height: var(--sl-line-height-headings);\n\t\t\tfont-weight: 600;\n\t\t\tcolor: var(--sl-color-white);\n\t\t}\n\n\t\t.tagline {\n\t\t\tfont-size: clamp(var(--sl-text-base), calc(0.0625rem + 2vw), var(--sl-text-xl));\n\t\t\tcolor: var(--sl-color-gray-2);\n\t\t}\n\n\t\t.actions {\n\t\t\tgap: 1rem 2rem;\n\t\t\tflex-wrap: wrap;\n\t\t\tjustify-content: center;\n\t\t}\n\n\t\t.home-banner {\n\t\t\tmargin-top: 1rem !important;\n\t\t}\n\n\t\t@media (min-width: 50rem) {\n\t\t\t.hero {\n\t\t\t\tgrid-template-columns: 7fr 4fr;\n\t\t\t\tgap: 3%;\n\t\t\t\tpadding-block: clamp(2.5rem, calc(1rem + 10vmin), 10rem);\n\t\t\t}\n\n\t\t\t.hero > img,\n\t\t\t.hero > .hero-html {\n\t\t\t\torder: 2;\n\t\t\t\twidth: min(100%, 25rem);\n\t\t\t}\n\n\t\t\t.stack {\n\t\t\t\ttext-align: start;\n\t\t\t}\n\n\t\t\t.copy {\n\t\t\t\talign-items: flex-start;\n\t\t\t}\n\n\t\t\t.actions {\n\t\t\t\tjustify-content: flex-start;\n\t\t\t}\n\t\t}\n\t}\n</style>\n"
  },
  {
    "path": "website/src/components/RightSidebarBanner.astro",
    "content": "---\nimport type { Props } from '@astrojs/starlight/props';\nimport Default from '@astrojs/starlight/components/PageSidebar.astro';\n\nconst props = Astro.props as Props;\n---\n\n<style>\n    .right-sidebar-banner {\n        padding: 1rem 1rem 0 1rem;\n    }\n</style>\n\n<div class=\"right-sidebar-banner\">\n    <script async type=\"text/javascript\" src=\"//cdn.carbonads.com/carbon.js?serve=CWBDPK3L&placement=gibbokgithubio&format=cover\" id=\"_carbonads_js\" is:inline></script>\n</div>\n\n<Default {...props} />\n\n"
  },
  {
    "path": "website/src/content/config.ts",
    "content": "import { defineCollection } from 'astro:content';\nimport { docsSchema, i18nSchema } from '@astrojs/starlight/schema';\n\nexport const collections = {\n\tdocs: defineCollection({ schema: docsSchema() }),\n\ti18n: defineCollection({ type: 'data', schema: i18nSchema() }),\n};\n"
  },
  {
    "path": "website/src/content/docs/book/about-the-author.md",
    "content": "---\ntitle: About the Author\nsidebar:\n  order: 6\n  label: 6. About the Author\n---\n\n\nSimone Poggiali is an experienced Staff Engineer with a passion for writing professional-grade code since the 90s. Throughout his international career, he has contributed to numerous projects for a wide range of clients, from startups to large organizations. Notable companies such as HelloFresh, Siemens, O2, Leroy Merlin and Snowplow have benefited from his expertise and dedication.\n\nYou can reach Simone Poggiali on the following platforms:\n\n* LinkedIn: [https://www.linkedin.com/in/simone-poggiali](https://www.linkedin.com/in/simone-poggiali)\n* GitHub: [https://github.com/gibbok](https://github.com/gibbok)\n* X.com: [https://x.com/gibbok_coding](https://x.com/gibbok_coding)\n* Email: gibbok.coding📧gmail.com\n\nFull list of contributors: [https://github.com/gibbok/typescript-book/graphs/contributors](https://github.com/gibbok/typescript-book/graphs/contributors)\n\n"
  },
  {
    "path": "website/src/content/docs/book/any-type.md",
    "content": "---\ntitle: Any type\nsidebar:\n  order: 44\n  label: 44. Any type\n---\n\n\nThe `any` type is a special type (universal supertype) that can be used to represent any type of value (primitives, objects, arrays, functions, errors, symbols). It is often used in situations where the type of a value is not known at compile time, or when working with values from external APIs or libraries that do not have TypeScript typings.\n\nBy utilizing `any` type, you are indicating to the TypeScript compiler that values should be represented without any limitations. To maximize type safety in your code, consider the following:\n\n* Limit the usage of `any` to specific cases where the type is truly unknown.\n* Do not return `any` types from a function, as this weakens type safety in code that uses it.\n* Instead of `any` use `@ts-ignore` if you need to silence the compiler.\n\n```typescript\nlet value: any;\nvalue = true; // Valid\nvalue = 7; // Valid\n```\n\n"
  },
  {
    "path": "website/src/content/docs/book/assignments.md",
    "content": "---\ntitle: Assignments\nsidebar:\n  order: 21\n  label: 21. Assignments\n---\n\n\nTypeScript narrowing using assignments is a way to narrow the type of a variable based on the value assigned to it. When a variable is assigned a value, TypeScript infers its type based on the assigned value, and it narrows the type of the variable to match the inferred type.\n\n```typescript\nlet value: string | number;\nvalue = 'hello';\nif (typeof value === 'string') {\n    console.log(value.toUpperCase());\n}\nvalue = 42;\nif (typeof value === 'number') {\n    console.log(value.toFixed(2));\n}\n```\n\n"
  },
  {
    "path": "website/src/content/docs/book/built-in-type-primitives.md",
    "content": "---\ntitle: Built-in Type Primitives\nsidebar:\n  order: 49\n  label: 49. Built-in Type Primitives\n---\n\n\nTypeScript has several built-in type primitives that can be used to define variables, function parameters, and return types:\n\n* `number`: Represents numeric values, including integers and floating-point numbers.\n* `string`: Represents textual data\n* `boolean`: Represents logical values, which can be either true or false.\n* `null`: Represents the absence of a value.\n* `undefined`: Represents a value that has not been assigned or has not been defined.\n* `symbol`: Represents a unique identifier. Symbols are typically used as keys for object properties.\n* `bigint`: Represents arbitrary-precision integers.\n* `any`: Represents a dynamic or unknown type. Variables of type any can hold values of any type, and they bypass type checking.\n* `void`: Represents the absence of any type. It is commonly used as the return type of functions that do not return a value.\n* `never`: Represents a type for values that never occur. It is typically used as the return type of functions that throw an error or enter an infinite loop.\n\n"
  },
  {
    "path": "website/src/content/docs/book/class.md",
    "content": "---\ntitle: Class\nsidebar:\n  order: 54\n  label: 54. Class\n---\n\n\n### Class Common Syntax\n\nThe `class` keyword is used in TypeScript to define a class. Below, you can see an example:\n\n```typescript\nclass Person {\n    private name: string;\n    private age: number;\n    constructor(name: string, age: number) {\n        this.name = name;\n        this.age = age;\n    }\n    public sayHi(): void {\n        console.log(\n            `Hello, my name is ${this.name} and I am ${this.age} years old.`\n        );\n    }\n}\n```\n\nThe `class` keyword is used to define a class named \"Person\".\n\nThe class has two private properties: name of type `string` and age of type `number`.\n\nThe constructor is defined using the `constructor` keyword. It takes name and age as parameters and assigns them to the corresponding properties.\n\nThe class has a `public` method named sayHi that logs a greeting message.\n\nTo create an instance of a class in TypeScript, you can use the `new` keyword followed by the class name, followed by parentheses `()`. For instance:\n\n<!-- skip -->\n```typescript\nconst myObject = new Person('John Doe', 25);\nmyObject.sayHi(); // Output: Hello, my name is John Doe and I am 25 years old.\n```\n\n### Constructor\n\nConstructors are special methods within a class that are used to initialize the object's properties when an instance of the class is created.\n\n```typescript\nclass Person {\n    public name: string;\n    public age: number;\n\n    constructor(name: string, age: number) {\n        this.name = name;\n        this.age = age;\n    }\n\n    sayHello() {\n        console.log(\n            `Hello, my name is ${this.name} and I'm ${this.age} years old.`\n        );\n    }\n}\n\nconst john = new Person('Simon', 17);\njohn.sayHello();\n```\n\nIt is possible to overload a constructor using the following syntax:\n\n```typescript\ntype Sex = 'm' | 'f';\n\nclass Person {\n    name: string;\n    age: number;\n    sex: Sex;\n\n    constructor(name: string, age: number, sex?: Sex);\n    constructor(name: string, age: number, sex: Sex) {\n        this.name = name;\n        this.age = age;\n        this.sex = sex ?? 'm';\n    }\n}\n\nconst p1 = new Person('Simon', 17);\nconst p2 = new Person('Alice', 22, 'f');\n```\n\nIn TypeScript, it is possible to define multiple constructor overloads, but you can have only one implementation that must be compatible with all the overloads, this can be achieved  by using an optional parameter.\n\n```typescript\nclass Person {\n    name: string;\n    age: number;\n\n    constructor();\n    constructor(name: string);\n    constructor(name: string, age: number);\n    constructor(name?: string, age?: number) {\n        this.name = name ?? 'Unknown';\n        this.age = age ?? 0;\n    }\n\n    displayInfo() {\n        console.log(`Name: ${this.name}, Age: ${this.age}`);\n    }\n}\n\nconst person1 = new Person();\nperson1.displayInfo(); // Name: Unknown, Age: 0\n\nconst person2 = new Person('John');\nperson2.displayInfo(); // Name: John, Age: 0\n\nconst person3 = new Person('Jane', 25);\nperson3.displayInfo(); // Name: Jane, Age: 25\n```\n\n### Private and Protected Constructors\n\nIn TypeScript, constructors can be marked as private or protected, which restricts their accessibility and usage.\n\nPrivate Constructors:\nCan be called only within the class itself. Private constructors are often used in scenarios where you want to enforce a singleton pattern or restrict the creation of instances to a factory method within the class\n\nProtected Constructors:\nProtected constructors are useful when you want to create a base class that should not be instantiated directly but can be extended by subclasses.\n\n```typescript\nclass BaseClass {\n    protected constructor() {}\n}\n\nclass DerivedClass extends BaseClass {\n    private value: number;\n\n    constructor(value: number) {\n        super();\n        this.value = value;\n    }\n}\n\n// Attempting to instantiate the base class directly will result in an error\n// const baseObj = new BaseClass(); // Error: Constructor of class 'BaseClass' is protected.\n\n// Create an instance of the derived class\nconst derivedObj = new DerivedClass(10);\n```\n\n### Access Modifiers\n\nAccess Modifiers `private`, `protected`, and `public` are used to control the visibility and accessibility of class members, such as properties and methods, in TypeScript classes. These modifiers are essential for enforcing encapsulation and establishing boundaries for accessing and modifying the internal state of a class.\n\nThe `private` modifier restricts access to the class member only within the containing class.\n\nThe `protected` modifier allows access to the class member within the containing class and its derived classes.\n\nThe `public` modifier provides unrestricted access to the class member, allowing it to be accessed from anywhere.\"\n\n### Get and Set\n\nGetters and setters are special methods that allow you to define custom access and modification behavior for class properties. They enable you to encapsulate the internal state of an object and provide additional logic when getting or setting the values of properties.\nIn TypeScript, getters and setters are defined using the `get` and `set` keywords respectively. Here's an example:\n\n```typescript\nclass MyClass {\n    private _myProperty: string;\n\n    constructor(value: string) {\n        this._myProperty = value;\n    }\n    get myProperty(): string {\n        return this._myProperty;\n    }\n    set myProperty(value: string) {\n        this._myProperty = value;\n    }\n}\n```\n\n### Auto-Accessors in Classes\n\nTypeScript version 4.9 adds support for auto-accessors, a forthcoming ECMAScript feature. They resemble class properties but are declared with the \"accessor\" keyword.\n\n```typescript\nclass Animal {\n    accessor name: string;\n\n    constructor(name: string) {\n        this.name = name;\n    }\n}\n```\n\nAuto-accessors are \"de-sugared\" into private `get` and `set` accessors, operating on an inaccessible property.\n\n<!-- skip -->\n```typescript\nclass Animal {\n    #__name: string;\n\n    get name() {\n        return this.#__name;\n    }\n    set name(value: string) {\n        this.#__name = name;\n    }\n\n    constructor(name: string) {\n        this.name = name;\n    }\n}\n```\n\n### this\n\nIn TypeScript, the `this` keyword refers to the current instance of a class within its methods or constructors. It allows you to access and modify the properties and methods of the class from within its own scope.\nIt provides a way to access and manipulate the internal state of an object within its own methods.\n\n```typescript\nclass Person {\n    private name: string;\n    constructor(name: string) {\n        this.name = name;\n    }\n    public introduce(): void {\n        console.log(`Hello, my name is ${this.name}.`);\n    }\n}\n\nconst person1 = new Person('Alice');\nperson1.introduce(); // Hello, my name is Alice.\n```\n\n### Parameter Properties\n\nParameter properties allow you to declare and initialize class properties directly within the constructor parameters avoiding boilerplate code, example:\n\n```typescript\nclass Person {\n    constructor(\n        private name: string,\n        public age: number\n    ) {\n        // The \"private\" and \"public\" keywords in the constructor\n        // automatically declare and initialize the corresponding class properties.\n    }\n    public introduce(): void {\n        console.log(\n            `Hello, my name is ${this.name} and I am ${this.age} years old.`\n        );\n    }\n}\nconst person = new Person('Alice', 25);\nperson.introduce();\n```\n\n### Abstract Classes\n\nAbstract Classes are used in TypeScript mainly for inheritance, they provide a way to define common properties and methods that can be inherited by subclasses.\nThis is useful when you want to define common behavior and enforce that subclasses implement certain methods. They provide a way to create a hierarchy of classes where the abstract base class provides a shared interface and common functionality for the subclasses.\n\n```typescript\nabstract class Animal {\n    protected name: string;\n\n    constructor(name: string) {\n        this.name = name;\n    }\n\n    abstract makeSound(): void;\n}\n\nclass Cat extends Animal {\n    makeSound(): void {\n        console.log(`${this.name} meows.`);\n    }\n}\n\nconst cat = new Cat('Whiskers');\ncat.makeSound(); // Output: Whiskers meows.\n```\n\n### With Generics\n\nClasses with generics allow you to define reusable classes which can work with different types.\n\n```typescript\nclass Container<T> {\n    private item: T;\n\n    constructor(item: T) {\n        this.item = item;\n    }\n\n    getItem(): T {\n        return this.item;\n    }\n\n    setItem(item: T): void {\n        this.item = item;\n    }\n}\n\nconst container1 = new Container<number>(42);\nconsole.log(container1.getItem()); //  42\n\nconst container2 = new Container<string>('Hello');\ncontainer2.setItem('World');\nconsole.log(container2.getItem()); // World\n```\n\n### Decorators\n\nDecorators provide a mechanism to add metadata, modify behavior, validate, or extend the functionality of the target element. They are functions that execute at runtime. Multiple decorators can be applied to a declaration.\n\nDecorators are experimental features, and the following examples are only compatible with TypeScript version 5 or above using ES6.\n\nFor TypeScript versions prior to 5, they should be enabled using the `experimentalDecorators` property in your `tsconfig.json` or by using `--experimentalDecorators` in your command line (but the following example won't work).\n\nSome of the common use cases for decorators include:\n\n* Watching property changes.\n* Watching method calls.\n* Adding extra properties or methods.\n* Runtime validation.\n* Automatic serialization and deserialization.\n* Logging.\n* Authorization and authentication.\n* Error guarding.\n\nNote: Decorators for version 5 do not allow decorating parameters.\n\nTypes of decorators:\n\n#### Class Decorators\n\nClass Decorators are useful for extending an existing class, such as adding properties or methods, or collecting instances of a class. In the following example, we add a `toString` method that converts the class into a string representation.\n\n```typescript\ntype Constructor<T = {}> = new (...args: any[]) => T;\n\nfunction toString<Class extends Constructor>(\n    Value: Class,\n    context: ClassDecoratorContext<Class>\n) {\n    return class extends Value {\n        constructor(...args: any[]) {\n            super(...args);\n            console.log(JSON.stringify(this));\n            console.log(JSON.stringify(context));\n        }\n    };\n}\n\n@toString\nclass Person {\n    name: string;\n\n    constructor(name: string) {\n        this.name = name;\n    }\n\n    greet() {\n        return 'Hello, ' + this.name;\n    }\n}\nconst person = new Person('Simon');\n/* Logs:\n{\"name\":\"Simon\"}\n{\"kind\":\"class\",\"name\":\"Person\"}\n*/\n```\n\n#### Property Decorator\n\nProperty decorators are useful for modifying the behavior of a property, such as changing the initialization values. In the following code, we have a script that sets a property to always be in uppercase:\n\n```typescript\nfunction upperCase<T>(\n    target: undefined,\n    context: ClassFieldDecoratorContext<T, string>\n) {\n    return function (this: T, value: string) {\n        return value.toUpperCase();\n    };\n}\n\nclass MyClass {\n    @upperCase\n    prop1 = 'hello!';\n}\n\nconsole.log(new MyClass().prop1); // Logs: HELLO!\n```\n\n#### Method Decorator\n\nMethod decorators allow you to change or enhance the behavior of methods. Below is an example of a simple logger:\n\n```typescript\nfunction log<This, Args extends any[], Return>(\n    target: (this: This, ...args: Args) => Return,\n    context: ClassMethodDecoratorContext<\n        This,\n        (this: This, ...args: Args) => Return\n    >\n) {\n    const methodName = String(context.name);\n\n    function replacementMethod(this: This, ...args: Args): Return {\n        console.log(`LOG: Entering method '${methodName}'.`);\n        const result = target.call(this, ...args);\n        console.log(`LOG: Exiting method '${methodName}'.`);\n        return result;\n    }\n\n    return replacementMethod;\n}\n\nclass MyClass {\n    @log\n    sayHello() {\n        console.log('Hello!');\n    }\n}\n\nnew MyClass().sayHello();\n```\n\nIt logs:\n\n```shell\nLOG: Entering method 'sayHello'.\nHello!\nLOG: Exiting method 'sayHello'.\n```\n\n#### Getter and Setter Decorators\n\nGetter and setter decorators allow you to change or enhance the behavior of class accessors. They are useful, for instance, for validating property assignments. Here's a simple example for a getter decorator:\n\n```typescript\nfunction range<This, Return extends number>(min: number, max: number) {\n    return function (\n        target: (this: This) => Return,\n        context: ClassGetterDecoratorContext<This, Return>\n    ) {\n        return function (this: This): Return {\n            const value = target.call(this);\n            if (value < min || value > max) {\n                throw 'Invalid';\n            }\n            Object.defineProperty(this, context.name, {\n                value,\n                enumerable: true,\n            });\n            return value;\n        };\n    };\n}\n\nclass MyClass {\n    private _value = 0;\n\n    constructor(value: number) {\n        this._value = value;\n    }\n    @range(1, 100)\n    get getValue(): number {\n        return this._value;\n    }\n}\n\nconst obj = new MyClass(10);\nconsole.log(obj.getValue); // Valid: 10\n\nconst obj2 = new MyClass(999);\nconsole.log(obj2.getValue); // Throw: Invalid!\n```\n\n#### Decorator Metadata\n\nDecorator Metadata simplifies the process for decorators to apply and utilize metadata in any class. They can access a new metadata property on the context object, which can serve as a key for both primitives and objects.\nMetadata information can be accessed on the class via `Symbol.metadata`.\n\nMetadata can be used for various purposes, such as debugging, serialization, or dependency injection with decorators.\n\n```typescript\n//@ts-ignore\nSymbol.metadata ??= Symbol('Symbol.metadata'); // Simple polify\n\ntype Context =\n    | ClassFieldDecoratorContext\n    | ClassAccessorDecoratorContext\n    | ClassMethodDecoratorContext; // Context contains property metadata: DecoratorMetadata\n\nfunction setMetadata(_target: any, context: Context) {\n    // Set the metadata object with a primitive value\n    context.metadata[context.name] = true;\n}\n\nclass MyClass {\n    @setMetadata\n    a = 123;\n\n    @setMetadata\n    accessor b = 'b';\n\n    @setMetadata\n    fn() {}\n}\n\nconst metadata = MyClass[Symbol.metadata]; // Get metadata information\n\nconsole.log(JSON.stringify(metadata)); // {\"bar\":true,\"baz\":true,\"foo\":true}\n```\n\n### Inheritance\n\nInheritance refers to the mechanism by which a class can inherit properties and methods from another class, known as the base class or superclass. The derived class, also called the child class or subclass, can extend and specialize the functionality of the base class by adding new properties and methods or overriding existing ones.\n\n```typescript\nclass Animal {\n    name: string;\n\n    constructor(name: string) {\n        this.name = name;\n    }\n\n    speak(): void {\n        console.log('The animal makes a sound');\n    }\n}\n\nclass Dog extends Animal {\n    breed: string;\n\n    constructor(name: string, breed: string) {\n        super(name);\n        this.breed = breed;\n    }\n\n    speak(): void {\n        console.log('Woof! Woof!');\n    }\n}\n\n// Create an instance of the base class\nconst animal = new Animal('Generic Animal');\nanimal.speak(); // The animal makes a sound\n\n// Create an instance of the derived class\nconst dog = new Dog('Max', 'Labrador');\ndog.speak(); // Woof! Woof!\"\n```\n\nTypeScript does not support multiple inheritance in the traditional sense and instead allows inheritance from a single base class.\nTypeScript supports multiple interfaces. An interface can define a contract for the structure of an object, and a class can implement multiple interfaces. This allows a class to inherit behavior and structure from multiple sources.\n\n```typescript\ninterface Flyable {\n    fly(): void;\n}\n\ninterface Swimmable {\n    swim(): void;\n}\n\nclass FlyingFish implements Flyable, Swimmable {\n    fly() {\n        console.log('Flying...');\n    }\n\n    swim() {\n        console.log('Swimming...');\n    }\n}\n\nconst flyingFish = new FlyingFish();\nflyingFish.fly();\nflyingFish.swim();\n```\n\nThe `class` keyword in TypeScript, similar to JavaScript, is often referred to as syntactic sugar. It was introduced in ECMAScript 2015 (ES6) to offer a more familiar syntax for creating and working with objects in a class-based manner. However, it's important to note that TypeScript, being a superset of JavaScript, ultimately compiles down to JavaScript, which remains prototype-based at its core.\n\n### Statics\n\nTypeScript has static members. To access the static members of a class, you can use the class name followed by a dot, without the need to create an object.\n\n```typescript\nclass OfficeWorker {\n    static memberCount: number = 0;\n\n    constructor(private name: string) {\n        OfficeWorker.memberCount++;\n    }\n}\n\nconst w1 = new OfficeWorker('James');\nconst w2 = new OfficeWorker('Simon');\nconst total = OfficeWorker.memberCount;\nconsole.log(total); // 2\n```\n\n### Property initialization\n\nThere are several ways how you can initialize properties for a class in TypeScript:\n\nInline:\n\nIn the following example these initial values will be used when an instance of the class is created.\n\n```typescript\nclass MyClass {\n    property1: string = 'default value';\n    property2: number = 42;\n}\n```\n\nIn the constructor:\n\n```typescript\nclass MyClass {\n    property1: string;\n    property2: number;\n\n    constructor() {\n        this.property1 = 'default value';\n        this.property2 = 42;\n    }\n}\n```\n\nUsing constructor parameters:\n\n```typescript\nclass MyClass {\n    constructor(\n        private property1: string = 'default value',\n        public property2: number = 42\n    ) {\n        // There is no need to assign the values to the properties explicitly.\n    }\n    log() {\n        console.log(this.property2);\n    }\n}\nconst x = new MyClass();\nx.log();\n```\n\n### Method overloading\n\nMethod overloading allows a class to have multiple methods with the same name but different parameter types or a different number of parameters. This allows us to call a method in different ways based on the arguments passed.\n\n```typescript\nclass MyClass {\n    add(a: number, b: number): number; // Overload signature 1\n    add(a: string, b: string): string; // Overload signature 2\n\n    add(a: number | string, b: number | string): number | string {\n        if (typeof a === 'number' && typeof b === 'number') {\n            return a + b;\n        }\n        if (typeof a === 'string' && typeof b === 'string') {\n            return a.concat(b);\n        }\n        throw new Error('Invalid arguments');\n    }\n}\n\nconst r = new MyClass();\nconsole.log(r.add(10, 5)); // Logs 15\n```\n\n"
  },
  {
    "path": "website/src/content/docs/book/common-built-in-js-objects.md",
    "content": "---\ntitle: Common Built-in JS Objects\nsidebar:\n  order: 50\n  label: 50. Common Built-in JS Objects\n---\n\n\nTypeScript is a superset of JavaScript, it includes all the commonly used built-in JavaScript objects. You can find an extensive list of these objects on the Mozilla Developer Network (MDN) documentation website:\n[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects)\n\nHere is a list of some commonly used built-in JavaScript objects:\n\n* Function\n* Object\n* Boolean\n* Error\n* Number\n* BigInt\n* Math\n* Date\n* String\n* RegExp\n* Array\n* Map\n* Set\n* Promise\n* Intl\n\n"
  },
  {
    "path": "website/src/content/docs/book/conditional-types.md",
    "content": "---\ntitle: Conditional Types\nsidebar:\n  order: 39\n  label: 39. Conditional Types\n---\n\n\nConditional Types are a way to create a type that depends on a condition, where the type to be created is determined based on the result of the condition. They are defined using the `extends` keyword and a ternary operator to conditionally choose between two types.\n\n```typescript\ntype IsArray<T> = T extends any[] ? true : false;\n\nconst myArray = [1, 2, 3];\nconst myNumber = 42;\n\ntype IsMyArrayAnArray = IsArray<typeof myArray>; // Type true\ntype IsMyNumberAnArray = IsArray<typeof myNumber>; // Type false\n```\n\n"
  },
  {
    "path": "website/src/content/docs/book/control-flow-analysis.md",
    "content": "---\ntitle: Control Flow Analysis\nsidebar:\n  order: 22\n  label: 22. Control Flow Analysis\n---\n\n\nControl Flow Analysis in TypeScript is a way to statically analyze the code flow to infer the types of variables, allowing the compiler to narrow the types of those variables as needed, based on the results of the analysis.\n\nPrior to TypeScript 4.4, code flow analysis would only be applied to code within an if statement, but from TypeScript 4.4, it can also be applied to conditional expressions and discriminant property accesses indirectly referenced through const variables.\n\nFor example:\n\n```typescript\nconst f1 = (x: unknown) => {\n    const isString = typeof x === 'string';\n    if (isString) {\n        x.length;\n    }\n};\n\nconst f2 = (\n    obj: { kind: 'foo'; foo: string } | { kind: 'bar'; bar: number }\n) => {\n    const isFoo = obj.kind === 'foo';\n    if (isFoo) {\n        obj.foo;\n    } else {\n        obj.bar;\n    }\n};\n```\n\nSome examples where narrowing does not occur:\n\n<!-- skip -->\n```typescript\nconst f1 = (x: unknown) => {\n    let isString = typeof x === 'string';\n    if (isString) {\n        x.length; // Error, no narrowing because isString it is not const\n    }\n};\n\nconst f6 = (\n    obj: { kind: 'foo'; foo: string } | { kind: 'bar'; bar: number }\n) => {\n    const isFoo = obj.kind === 'foo';\n    obj = obj;\n    if (isFoo) {\n        obj.foo; // Error, no narrowing because obj is assigned in function body\n    }\n};\n```\n\nNotes: Up to five levels of indirection are analyzed in conditional expressions.\n\n"
  },
  {
    "path": "website/src/content/docs/book/differences-between-type-and-interface.md",
    "content": "---\ntitle: Differences between Type and Interface\nsidebar:\n  order: 53\n  label: 53. Differences between Type and Interface\n---\n\n\nDeclaration merging (augmentation):\n\nInterfaces support declaration merging, which means that you can define multiple interfaces with the same name, and TypeScript will merge them into a single interface with the combined properties and methods. On the other hand, types do not support declaration merging. This can be helpful when you want to add extra functionality or customize existing types without modifying the original definitions or patching missing or incorrect types.\n\n```typescript\ninterface A {\n    x: string;\n}\ninterface A {\n    y: string;\n}\nconst j: A = {\n    x: 'xx',\n    y: 'yy',\n};\n```\n\nExtending other types/interfaces:\n\nBoth types and interfaces can extend other types/interfaces, but the syntax is different. With interfaces, you use the `extends` keyword to inherit properties and methods from other interfaces. However, an interface cannot extend a complex type like a union type.\n\n```typescript\ninterface A {\n    x: string;\n    y: number;\n}\ninterface B extends A {\n    z: string;\n}\nconst car: B = {\n    x: 'x',\n    y: 123,\n    z: 'z',\n};\n```\n\nFor types, you use the & operator to combine multiple types into a single type (intersection).\n\n```typescript\ninterface A {\n    x: string;\n    y: number;\n}\n\ntype B = A & {\n    j: string;\n};\n\nconst c: B = {\n    x: 'x',\n    y: 123,\n    j: 'j',\n};\n```\n\nUnion and Intersection Types:\n\nTypes are more flexible when it comes to defining Union and Intersection Types. With the `type` keyword, you can easily create union types using the `|` operator and intersection types using the `&` operator. While interfaces can also represent union types indirectly, they don't have built-in support for intersection types.\n\n```typescript\ntype Department = 'dep-x' | 'dep-y'; // Union\n\ntype Person = {\n    name: string;\n    age: number;\n};\n\ntype Employee = {\n    id: number;\n    department: Department;\n};\n\ntype EmployeeInfo = Person & Employee; // Intersection\n```\n\nExample with interfaces:\n\n```typescript\ninterface A {\n    x: 'x';\n}\ninterface B {\n    y: 'y';\n}\n\ntype C = A | B; // Union of interfaces\n```\n\n"
  },
  {
    "path": "website/src/content/docs/book/discriminated-unions.md",
    "content": "---\ntitle: Discriminated Unions\nsidebar:\n  order: 24\n  label: 24. Discriminated Unions\n---\n\n\nDiscriminated Unions in TypeScript are a type of union type that uses a common property, known as the discriminant, to narrow down the set of possible types for the union.\n\n```typescript\ntype Square = {\n    kind: 'square'; // Discriminant\n    size: number;\n};\n\ntype Circle = {\n    kind: 'circle'; // Discriminant\n    radius: number;\n};\n\ntype Shape = Square | Circle;\n\nconst area = (shape: Shape) => {\n    switch (shape.kind) {\n        case 'square':\n            return Math.pow(shape.size, 2);\n        case 'circle':\n            return Math.PI * Math.pow(shape.radius, 2);\n    }\n};\n\nconst square: Square = { kind: 'square', size: 5 };\nconst circle: Circle = { kind: 'circle', radius: 2 };\n\nconsole.log(area(square)); // 25\nconsole.log(area(circle)); // 12.566370614359172\n```\n\n"
  },
  {
    "path": "website/src/content/docs/book/distributive-conditional-types.md",
    "content": "---\ntitle: Distributive Conditional Types\nsidebar:\n  order: 40\n  label: 40. Distributive Conditional Types\n---\n\n\nDistributive Conditional Types are a feature that allow a type to be distributed over a union of types, by applying a transformation to each member of the union individually.\nThis can be especially useful when working with mapped types or higher-order types.\n\n```typescript\ntype Nullable<T> = T extends any ? T | null : never;\ntype NumberOrBool = number | boolean;\ntype NullableNumberOrBool = Nullable<NumberOrBool>; // number | boolean | null\n```\n\n"
  },
  {
    "path": "website/src/content/docs/book/downloads-and-website.md",
    "content": "---\ntitle: Downloads and website\nsidebar:\n  order: 3\n  label: 3. Downloads and website\n---\n\n\nYou can also download the Epub version:\n\n[https://github.com/gibbok/typescript-book/tree/main/downloads](https://github.com/gibbok/typescript-book/tree/main/downloads)\n\nAn online version is available at:\n\n[https://gibbok.github.io/typescript-book](https://gibbok.github.io/typescript-book)\n\n"
  },
  {
    "path": "website/src/content/docs/book/enums.md",
    "content": "---\ntitle: Enums\nsidebar:\n  order: 19\n  label: 19. Enums\n---\n\n\nIn TypeScript, an `enum` is a set of named constant values.\n\n```typescript\nenum Color {\n    Red = '#ff0000',\n    Green = '#00ff00',\n    Blue = '#0000ff',\n}\n```\n\nEnums can be defined in different ways:\n\n### Numeric enums\n\nIn TypeScript, a Numeric Enum is an Enum where each constant is assigned a numeric value, starting from 0 by default.\n\n```typescript\nenum Size {\n    Small, // value starts from 0\n    Medium,\n    Large,\n}\n```\n\nIt is possible to specify custom values by explicitly assigning them:\n\n```typescript\nenum Size {\n    Small = 10,\n    Medium,\n    Large,\n}\nconsole.log(Size.Medium); // 11\n```\n\n### String enums\n\nIn TypeScript, a String enum is an Enum where each constant is assigned a string value.\n\n```typescript\nenum Language {\n    English = 'EN',\n    Spanish = 'ES',\n}\n```\n\nNote: TypeScript allows the usage of heterogeneous Enums where string and numeric members can coexist.\n\n### Constant enums\n\nA constant enum in TypeScript is a special type of Enum where all the values are known at compile time and are inlined wherever the enum is used, resulting in more efficient code.\n\n```typescript\nconst enum Language {\n    English = 'EN',\n    Spanish = 'ES',\n}\nconsole.log(Language.English);\n```\n\nWill be compiled into:\n\n```typescript\nconsole.log('EN' /* Language.English */);\n```\n\nNotes:\nConst Enums have hardcoded values, erasing the Enum, which can be more efficient in self-contained libraries but is generally not desirable. Also, Const enums cannot have computed members.\n\n### Reverse mapping\n\nIn TypeScript, reverse mappings in Enums refer to the ability to retrieve the Enum member name from its value. By default, Enum members have forward mappings from name to value, but reverse mappings can be created by explicitly setting values for each member. Reverse mappings are useful when you need to look up an Enum member by its value, or when you need to iterate over all the Enum members. Note that only numeric enums members will generate reverse mappings, while String Enum members do not get a reverse mapping generated at all.\n\nThe following enum:\n\n```typescript\nenum Grade {\n    A = 90,\n    B = 80,\n    C = 70,\n    F = 'fail',\n}\n```\n\nCompiles to:\n\n<!-- skip -->\n```javascript\n'use strict';\nvar Grade;\n(function (Grade) {\n    Grade[(Grade['A'] = 90)] = 'A';\n    Grade[(Grade['B'] = 80)] = 'B';\n    Grade[(Grade['C'] = 70)] = 'C';\n    Grade['F'] = 'fail';\n})(Grade || (Grade = {}));\n```\n\nTherefore, mapping values to keys works for numeric enum members, but not for string enum members:\n\n<!-- skip -->\n```typescript\nenum Grade {\n    A = 90,\n    B = 80,\n    C = 70,\n    F = 'fail',\n}\nconst myGrade = Grade.A;\nconsole.log(Grade[myGrade]); // A\nconsole.log(Grade[90]); // A\n\nconst failGrade = Grade.F;\nconsole.log(failGrade); // fail\nconsole.log(Grade[failGrade]); // Element implicitly has an 'any' type because index expression is not of type 'number'.\n```\n\n### Ambient enums\n\nAn ambient enum in TypeScript is a type of Enum that is defined in a declaration file (*.d.ts) without an associated implementation. It allows you to define a set of named constants that can be used in a type-safe way across different files without having to import the implementation details in each file.\n\n### Computed and constant members\n\nIn TypeScript, a computed member is a member of an Enum that has a value calculated at runtime, while a constant member is a member whose value is set at compile-time and cannot be changed during runtime. Computed members are allowed in regular Enums, while constant members are allowed in both regular and const enums.\n\n```typescript\n// Constant members\nenum Color {\n    Red = 1,\n    Green = 5,\n    Blue = Red + Green,\n}\nconsole.log(Color.Blue); // 6 generation at compilation time\n```\n\n```typescript\n// Computed members\nenum Color {\n    Red = 1,\n    Green = Math.pow(2, 2),\n    Blue = Math.floor(Math.random() * 3) + 1,\n}\nconsole.log(Color.Blue); // random number generated at run time\n```\n\nEnums are denoted by unions comprising their member types. The values of each member can be determined through constant or non-constant expressions, with members possessing constant values being assigned literal types. To illustrate, consider the declaration of type E and its subtypes E.A, E.B, and E.C. In this case, E represents the union E.A | E.B | E.C.\n\n```typescript\nconst identity = (value: number) => value;\n\nenum E {\n    A = 2 * 5, // Numeric literal\n    B = 'bar', // String literal\n    C = identity(42), // Opaque computed\n}\n\nconsole.log(E.C); //42\n```\n\n"
  },
  {
    "path": "website/src/content/docs/book/erased-structural-types.md",
    "content": "---\ntitle: Erased Structural Types\nsidebar:\n  order: 56\n  label: 56. Erased Structural Types\n---\n\n\nIn TypeScript, objects do not have to match a specific, exact type. For instance, if we create an object that fulfills an interface's requirements, we can utilize that object in places where that interface is required, even if there was no explicit connection between them.\nExample:\n\n```typescript\ntype NameProp1 = {\n    prop1: string;\n};\n\nfunction log(x: NameProp1) {\n    console.log(x.prop1);\n}\n\nconst obj = {\n    prop2: 123,\n    prop1: 'Origin',\n};\n\nlog(obj); // Valid\n```\n\n"
  },
  {
    "path": "website/src/content/docs/book/exhaustiveness-checking.md",
    "content": "---\ntitle: Exhaustiveness checking\nsidebar:\n  order: 26\n  label: 26. Exhaustiveness checking\n---\n\n\nExhaustiveness checking is a feature in TypeScript that ensures all possible cases of a discriminated union are handled in a `switch` statement or an `if` statement.\n\n```typescript\ntype Direction = 'up' | 'down';\n\nconst move = (direction: Direction) => {\n    switch (direction) {\n        case 'up':\n            console.log('Moving up');\n            break;\n        case 'down':\n            console.log('Moving down');\n            break;\n        default:\n            const exhaustiveCheck: never = direction;\n            console.log(exhaustiveCheck); // This line will never be executed\n    }\n};\n```\n\nThe `never` type is used to ensure that the default case is exhaustive and that TypeScript will raise an error if a new value is added to the Direction type without being handled in the switch statement.\n\n"
  },
  {
    "path": "website/src/content/docs/book/exploring-the-type-system.md",
    "content": "---\ntitle: Exploring the Type System\nsidebar:\n  order: 9\n  label: 9. Exploring the Type System\n---\n\n\n### The TypeScript Language Service\n\nThe TypeScript Language Service, also known as tsserver, offers various features such as error reporting, diagnostics, compile-on-save, renaming, go to definition, completion lists, signature help, and more. It is primarily used by integrated development environments (IDEs) to provide IntelliSense support. It seamlessly integrates with Visual Studio Code and is utilized by tools like Conquer of Completion (Coc).\n\nDevelopers can leverage a dedicated API and create their own custom language service plugins to enhance the TypeScript editing experience. This can be particularly useful for implementing special linting features or enabling auto-completion for a custom templating language.\n\n<!-- markdownlint-disable MD044 -->\nAn example of a real-world custom plugin is \"typescript-styled-plugin\", which provides syntax error reporting and IntelliSense support for CSS properties in styled components.\n<!-- markdownlint-enable MD044 -->\n\nFor more information and quick start guides, you can refer to the official TypeScript Wiki on GitHub: [https://github.com/microsoft/TypeScript/wiki/](https://github.com/microsoft/TypeScript/wiki/)\n\n### Structural Typing\n\nTypeScript is based on a structural type system. This means that the compatibility and equivalence of types are determined by the type's actual structure or definition, rather than its name or place of declaration, as in nominative type systems like C# or C.\n\nTypeScript's structural type system was designed based on how JavaScript's dynamic duck typing system works during runtime.\n\nThe following example is valid TypeScript code. As you can observe, \"X\" and \"Y\" have the same member \"a,\" even though they have different declaration names. The types are determined by their structures, and in this case, since the structures are the same, they are compatible and valid.\n\n```typescript\ntype X = {\n    a: string;\n};\ntype Y = {\n    a: string;\n};\nconst x: X = { a: 'a' };\nconst y: Y = x; // Valid\n```\n\n### TypeScript Fundamental Comparison Rules\n\nThe TypeScript comparison process is recursive and executed on types nested at any level.\n\nA type \"X\" is compatible with \"Y\" if \"Y\" has at least the same members as \"X\".\n\n```typescript\ntype X = {\n    a: string;\n};\nconst y = { a: 'A', b: 'B' }; // Valid, as it has at least the same members as X\nconst r: X = y;\n```\n\nFunction parameters are compared by types, not by their names:\n\n```typescript\ntype X = (a: number) => void;\ntype Y = (a: number) => void;\nlet x: X = (j: number) => undefined;\nlet y: Y = (k: number) => undefined;\ny = x; // Valid\nx = y; // Valid\n```\n\nFunction return types must be the same:\n\n<!-- skip -->\n```typescript\ntype X = (a: number) => undefined;\ntype Y = (a: number) => number;\nlet x: X = (a: number) => undefined;\nlet y: Y = (a: number) => 1;\ny = x; // Invalid\nx = y; // Invalid\n```\n\nThe return type of a source function must be a subtype of the return type of a target function:\n\n<!-- skip -->\n```typescript\nlet x = () => ({ a: 'A' });\nlet y = () => ({ a: 'A', b: 'B' });\nx = y; // Valid\ny = x; // Invalid member b is missing\n```\n\nDiscarding function parameters is allowed, as it is a common practice in JavaScript, for instance using \"Array.prototype.map()\":\n\n```typescript\n[1, 2, 3].map((element, _index, _array) => element + 'x');\n```\n\nTherefore, the following type declarations are completely valid:\n\n```typescript\ntype X = (a: number) => undefined;\ntype Y = (a: number, b: number) => undefined;\nlet x: X = (a: number) => undefined;\nlet y: Y = (a: number) => undefined; // Missing b parameter\ny = x; // Valid\n```\n\nAny additional optional parameters of the source type are valid:\n\n```typescript\ntype X = (a: number, b?: number, c?: number) => undefined;\ntype Y = (a: number) => undefined;\nlet x: X = a => undefined;\nlet y: Y = a => undefined;\ny = x; // Valid\nx = y; //Valid\n```\n\nAny optional parameters of the target type without corresponding parameters in the source type are valid and not an error:\n\n```typescript\ntype X = (a: number) => undefined;\ntype Y = (a: number, b?: number) => undefined;\nlet x: X = a => undefined;\nlet y: Y = a => undefined;\ny = x; // Valid\nx = y; // Valid\n```\n\nThe rest parameter is treated as an infinite series of optional parameters:\n\n```typescript\ntype X = (a: number, ...rest: number[]) => undefined;\nlet x: X = a => undefined; //valid\n```\n\nFunctions with overloads are valid if the overload signature is compatible with its implementation signature:\n\n<!-- skip -->\n```typescript\nfunction x(a: string): void;\nfunction x(a: string, b: number): void;\nfunction x(a: string, b?: number): void {\n    console.log(a, b);\n}\nx('a'); // Valid\nx('a', 1); // Valid\n\nfunction y(a: string): void; // Invalid, not compatible with implementation signature\nfunction y(a: string, b: number): void;\nfunction y(a: string, b: number): void {\n    console.log(a, b);\n}\ny('a');\ny('a', 1);\n```\n\nFunction parameter comparison succeeds if the source and target parameters are assignable to supertypes or subtypes (bivariance).\n\n```typescript\n// Supertype\nclass X {\n    a: string;\n    constructor(value: string) {\n        this.a = value;\n    }\n}\n// Subtype\nclass Y extends X {}\n// Subtype\nclass Z extends X {}\n\ntype GetA = (x: X) => string;\nconst getA: GetA = x => x.a;\n\n// Bivariance does accept supertypes\nconsole.log(getA(new X('x'))); // Valid\nconsole.log(getA(new Y('Y'))); // Valid\nconsole.log(getA(new Z('z'))); // Valid\n```\n\nEnums are comparable and valid with numbers and vice versa, but comparing Enum values from different Enum types is invalid.\n\n<!-- skip -->\n```typescript\nenum X {\n    A,\n    B,\n}\nenum Y {\n    A,\n    B,\n    C,\n}\nconst xa: number = X.A; // Valid\nconst ya: Y = 0; // Valid\nX.A === Y.A; // Invalid\n```\n\nInstances of a class are subject to a compatibility check for their private and protected members:\n\n<!-- skip -->\n```typescript\nclass X {\n    public a: string;\n    constructor(value: string) {\n        this.a = value;\n    }\n}\n\nclass Y {\n    private a: string;\n    constructor(value: string) {\n        this.a = value;\n    }\n}\n\nlet x: X = new Y('y'); // Invalid\n```\n\nThe comparison check does not take into consideration the different inheritance hierarchy, for instance:\n\n```typescript\nclass X {\n    public a: string;\n    constructor(value: string) {\n        this.a = value;\n    }\n}\nclass Y extends X {\n    public a: string;\n    constructor(value: string) {\n        super(value);\n        this.a = value;\n    }\n}\nclass Z {\n    public a: string;\n    constructor(value: string) {\n        this.a = value;\n    }\n}\nlet x: X = new X('x');\nlet y: Y = new Y('y');\nlet z: Z = new Z('z');\nx === y; // Valid\nx === z; // Valid even if z is from a different inheritance hierarchy\n```\n\nGenerics are compared using their structures based on the resulting type after applying the generic parameter, only the final result is compared as a non-generic type.\n\n<!-- skip -->\n```typescript\ninterface X<T> {\n    a: T;\n}\nlet x: X<number> = { a: 1 };\nlet y: X<string> = { a: 'a' };\nx === y; // Invalid as the type argument is used in the final structure\n```\n\n```typescript\ninterface X<T> {}\nconst x: X<number> = 1;\nconst y: X<string> = 'a';\nx === y; // Valid as the type argument is not used in the final structure\n```\n\nWhen generics do not have their type argument specified, all the unspecified arguments are treated as types with \"any\":\n\n```typescript\ntype X = <T>(x: T) => T;\ntype Y = <K>(y: K) => K;\nlet x: X = x => x;\nlet y: Y = y => y;\nx = y; // Valid\n```\n\nRemember:\n\n<!-- skip -->\n```typescript\nlet a: number = 1;\nlet b: number = 2;\na = b; // Valid, everything is assignable to itself\n\nlet c: any;\nc = 1; // Valid, all types are assignable to any\n\nlet d: unknown;\nd = 1; // Valid, all types are assignable to unknown\n\nlet e: unknown;\nlet e1: unknown = e; // Valid, unknown is only assignable to itself and any\nlet e2: any = e; // Valid\nlet e3: number = e; // Invalid\n\nlet f: never;\nf = 1; // Invalid, nothing is assignable to never\n\nlet g: void;\nlet g1: any;\ng = 1; // Invalid, void is not assignable to or from anything expect any\ng = g1; // Valid\n```\n\nPlease note that when \"strictNullChecks\" is enabled, \"null\" and \"undefined\" are treated similarly to \"void\"; otherwise, they are similar to \"never\".\n\n### Types as Sets\n\nIn TypeScript, a type is a set of possible values. This set is also referred to as the domain of the type. Each value of a type can be viewed as an element in a set. A type establishes the constraints that every element in the set must satisfy to be considered a member of that set.\nThe primary task of TypeScript is to check and verify whether one set is a subset of another.\n\nTypeScript supports various types of sets:\n\n| Set term           | TypeScript                      | Notes                                                                                                              |\n| ------------------ | ------------------------------- | ------------------------------------------------------------------------------------------------------------------ |\n| Empty set          | never                           | \"never\" contains anything apart itself                                                                             |\n| Single element set | undefined / null / literal type |                                                                                                                    |\n| Finite set         | boolean / union                 |                                                                                                                    |\n| Infinite set       | string / number / object        |                                                                                                                    |\n| Universal set      | any / unknown                   | Every element is a member of \"any\" and every set is a subset of it / \"unknown\" is a type-safe counterpart of \"any\" |\n\nHere few examples:\n\n| TypeScript            | Set term               | Example                                                                         |\n| --------------------- | ---------------------- | ------------------------------------------------------------------------------- |\n| never                 | ∅ (empty set)          | const x: never = 'x'; // Error: Type 'string' is not assignable to type 'never' |\n|                       |                        |\n| Literal type          | Single element set     | type X = 'X';                                                                   |\n|                       |                        | type Y = 7;                                                                     |\n|                       |                        |\n| Value assignable to T | Value ∈ T (member of)  | type XY = 'X' \\| 'Y';                                                           |\n|                       |                        | const x: XY = 'X';                                                              |\n|                       |                        |\n| T1 assignable to T2   | T1 ⊆ T2 (subset of)    | type XY = 'X' \\| 'Y';                                                           |\n|                       |                        | const x: XY = 'X';                                                              |\n|                       |                        | const j: XY = 'J'; // Type '\"J\"' is not assignable to type 'XY'.                |\n|                       |                        |                                                                                 |\n| T1 extends T2         | T1 ⊆ T2 (subset of)    | type X = 'X' extends string ? true : false;                                     |\n|                       |                        |\n| T1 \\| T2              | T1 ∪ T2 (union)        | type XY = 'X' \\| 'Y';                                                           |\n|                       |                        | type JK = 1 \\| 2;                                                               |\n|                       |                        |\n| T1 & T2               | T1 ∩ T2 (intersection) | type X = \\{ a: string \\}                                                          |\n|                       |                        | type Y = \\{ b: string \\}                                                          |\n|                       |                        | type XY = X & Y                                                                 |\n|                       |                        | const x: XY = \\{ a: 'a', b: 'b' \\}                                                |\n|                       |                        |\n| unknown               | Universal set          | const x: unknown = 1                                                            |\n\nAn union, (T1 | T2) creates a wider set (both):\n\n```typescript\ntype X = {\n    a: string;\n};\ntype Y = {\n    b: string;\n};\ntype XY = X | Y;\nconst r: XY = { a: 'a', b: 'x' }; // Valid\n```\n\nAn intersection, (T1 & T2) create a narrower set (only shared):\n\n<!-- skip -->\n```typescript\ntype X = {\n    a: string;\n};\ntype Y = {\n    a: string;\n    b: string;\n};\ntype XY = X & Y;\nconst r: XY = { a: 'a' }; // Invalid\nconst j: XY = { a: 'a', b: 'b' }; // Valid\n```\n\nThe `extends` keyword could be considered as a \"subset of\" in this context. It sets a constraint for a type. The extends used with a generic, take the generic as an infinite set and it will constrain it to a more specific type.\nPlease note that `extends` has nothing to do with hierarchy in a OOP sense (there is no this concept in TypeScript).\nTypeScript works with sets and does not have a strict hierarchy, infact, as in the example below, two types could overlap without either being a subtype of the other type (TypeScript considers the structure, shape of the objects).\n\n```typescript\ninterface X {\n    a: string;\n}\ninterface Y extends X {\n    b: string;\n}\ninterface Z extends Y {\n    c: string;\n}\nconst z: Z = { a: 'a', b: 'b', c: 'c' };\ninterface X1 {\n    a: string;\n}\ninterface Y1 {\n    a: string;\n    b: string;\n}\ninterface Z1 {\n    a: string;\n    b: string;\n    c: string;\n}\nconst z1: Z1 = { a: 'a', b: 'b', c: 'c' };\n\nconst r: Z1 = z; // Valid\n```\n\n### Assign a type: Type Declarations and Type Assertions\n\nA type can be assigned in different ways in TypeScript:\n\n#### Type Declaration\n\nIn the following example, we use x: X (\": Type\") to declare a type for the variable x.\n\n```typescript\ntype X = {\n    a: string;\n};\n\n// Type declaration\nconst x: X = {\n    a: 'a',\n};\n```\n\nIf the variable is not in the specified format, TypeScript will report an error. For instance:\n\n<!-- skip -->\n```typescript\ntype X = {\n    a: string;\n};\n\nconst x: X = {\n    a: 'a',\n    b: 'b', // Error: Object literal may only specify known properties\n};\n```\n\n#### Type Assertion\n\nIt is possible to add an assertion by using the `as` keyword. This tells the compiler that the developer has more information about a type and silences any errors that may occur.\n\nFor example:\n\n```typescript\ntype X = {\n    a: string;\n};\nconst x = {\n    a: 'a',\n    b: 'b',\n} as X;\n```\n\nIn the above example, the object x is asserted to have the type X using the as keyword. This informs the TypeScript compiler that the object conforms to the specified type, even though it has an additional property b not present in the type definition.\n\nType assertions are useful in situations where a more specific type needs to be specified, especially when working with the DOM. For instance:\n\n```typescript\nconst myInput = document.getElementById('my_input') as HTMLInputElement;\n```\n\nHere, the type assertion as HTMLInputElement is used to tell TypeScript that the result of getElementById should be treated as an HTMLInputElement.\nType assertions can also be used to remap keys, as shown in the example below with template literals:\n\n```typescript\ntype J<Type> = {\n    [Property in keyof Type as `prefix_${string &\n        Property}`]: () => Type[Property];\n};\ntype X = {\n    a: string;\n    b: number;\n};\ntype Y = J<X>;\n```\n\nIn this example, the type `J<Type>` uses a mapped type with a template literal to remap the keys of Type. It creates new properties with a \"prefix_\" added to each key, and their corresponding values are functions returning the original property values.\n\nIt is worth noting that when using a type assertion, TypeScript will not execute excess property checking. Therefore, it is generally preferable to use a Type Declaration when the structure of the object is known in advance.\n\n#### Ambient Declarations\n\nAmbient declarations are files that describe types for JavaScript code, they have a file name format as `.d.ts.`. They are usually imported and used to annotate existing JavaScript libraries or to add types to existing JS files in your project.\n\nMany common libraries types can be found at:\n[https://github.com/DefinitelyTyped/DefinitelyTyped/](https://github.com/DefinitelyTyped/DefinitelyTyped/)\n\nand can be installed using:\n\n```shell\nnpm install --save-dev @types/library-name\n```\n\nFor your defined Ambient Declarations, you can import using the \"triple-slash\" reference:\n\n<!-- skip -->\n```typescript\n/// <reference path=\"./library-types.d.ts\" />\n```\n\nYou can use Ambient Declarations even within JavaScript files using `// @ts-check`.\n\nThe `declare` keyword enables type definitions for existing JavaScript code without importing it, serving as a placeholder for types from another file or globally.\n\n### Property Checking and Excess Property Checking\n\nTypeScript is based on a structural type system but excess property checking is a property of TypeScript which allows it to check whether an object has the exact properties specified in the type.\n\nExcess Property Checking is performed when assigning object literals to variables or when passing them as arguments to the function's excess property, for instance.\n\n<!-- skip -->\n```typescript\ntype X = {\n    a: string;\n};\nconst y = { a: 'a', b: 'b' };\nconst x: X = y; // Valid because structural typing\nconst w: X = { a: 'a', b: 'b' }; // Invalid because excess property checking\n```\n\n### Weak Types\n\nA type is considered weak when it contains nothing but a set of all-optional properties:\n\n```typescript\ntype X = {\n    a?: string;\n    b?: string;\n};\n```\n\nTypeScript considers an error to assign anything to a weak type when there is no overlap, for instance, the following throws an error:\n\n<!-- skip -->\n```typescript\ntype Options = {\n    a?: string;\n    b?: string;\n};\n\nconst fn = (options: Options) => undefined;\n\nfn({ c: 'c' }); // Invalid\n```\n\nAlthough not recommended, if needed, it is possible to bypass this check by using type assertion:\n\n```typescript\ntype Options = {\n    a?: string;\n    b?: string;\n};\nconst fn = (options: Options) => undefined;\nfn({ c: 'c' } as Options); // Valid\n```\n\nOr by adding `unknown` to the index signature to the weak type:\n\n```typescript\ntype Options = {\n    [prop: string]: unknown;\n    a?: string;\n    b?: string;\n};\n\nconst fn = (options: Options) => undefined;\nfn({ c: 'c' }); // Valid\n```\n\n### Strict Object Literal Checking (Freshness)\n\nStrict object literal checking, sometimes referred to as \"freshness\", is a feature in TypeScript that helps catch excess or misspelled properties that would otherwise go unnoticed in normal structural type checks.\n\nWhen creating an object literal, the TypeScript compiler considers it \"fresh.\" If the object literal is assigned to a variable or passed as a parameter, TypeScript will throw an error if the object literal specifies properties that do not exist in the target type.\n\nHowever, \"freshness\" disappears when an object literal is widened or a type assertion is used.\n\nHere are some examples to illustrate:\n\n<!-- skip -->\n```typescript\ntype X = { a: string };\ntype Y = { a: string; b: string };\n\nlet x: X;\nx = { a: 'a', b: 'b' }; // Freshness check: Invalid assignment\nvar y: Y;\ny = { a: 'a', bx: 'bx' }; // Freshness check: Invalid assignment\n\nconst fn = (x: X) => console.log(x.a);\n\nfn(x);\nfn(y); // Widening: No errors, structurally type compatible\n\nfn({ a: 'a', bx: 'b' }); // Freshness check: Invalid argument\n\nlet c: X = { a: 'a' };\nlet d: Y = { a: 'a', b: '' };\nc = d; // Widening: No Freshness check\n```\n\n### Type Inference\n\nTypeScript can infer types when no annotation is provided during:\n\n* Variable initialization.\n* Member initialization.\n* Setting defaults for parameters.\n* Function return type.\n\nFor example:\n\n```typescript\nlet x = 'x'; // The type inferred is string\n```\n\nThe TypeScript compiler analyzes the value or expression and determines its type based on the available information.\n\n### More Advanced Inferences\n\nWhen multiple expressions are used in type inference, TypeScript looks for the \"best common types.\" For instance:\n\n```typescript\nlet x = [1, 'x', 1, null]; // The type inferred is: (string | number | null)[]\n```\n\nIf the compiler cannot find the best common types, it returns a union type. For example:\n\n```typescript\nlet x = [new RegExp('x'), new Date()]; // Type inferred is: (RegExp | Date)[]\n```\n\nTypeScript utilizes \"contextual typing\" based on the variable's location to infer types. In the following example, the compiler knows that `e` is of type `MouseEvent` because of the `click` event type defined in the lib.d.ts file, which contains ambient declarations for various common JavaScript constructs and the DOM:\n\n```typescript\nwindow.addEventListener('click', function (e) {}); // The inferred type of e is MouseEvent\n```\n\n### Type Widening\n\nType widening is the process in which TypeScript assigns a type to a variable initialized when no type annotation was provided. It allows narrow to wider types but not vice versa.\nIn the following example:\n\n<!-- skip -->\n```typescript\nlet x = 'x'; // TypeScript infers as string, a wide type\nlet y: 'y' | 'x' = 'y'; // y types is a union of literal types\ny = x; // Invalid Type 'string' is not assignable to type '\"x\" | \"y\"'.\n```\n\nTypeScript assigns `string` to `x` based on the single value provided during initialization (`x`), this is an example of widening.\n\nTypeScript provides ways to have control of the widening process, for instance using \"const\".\n\n### Const\n\nUsing the `const` keyword when declaring a variable results in a narrower type inference in TypeScript.\n\nFor example:\n\n```typescript\nconst x = 'x'; // TypeScript infers the type of x as 'x', a narrower type\nlet y: 'y' | 'x' = 'y';\ny = x; // Valid: The type of x is inferred as 'x'\n```\n\nBy using `const` to declare the variable x, its type is narrowed to the specific literal value 'x'. Since the type of x is narrowed, it can be assigned to the variable y without any error.\nThe reason the type can be inferred is because `const` variables cannot be reassigned, so their type can be narrowed down to a specific literal type, in this case, the literal type 'x'.\n\n#### Const Modifier on Type Parameters\n\nFrom version 5.0 of TypeScript, it is possible to specify the `const` attribute on a generic type parameter. This allows for inferring the most precise type possible. Let's see an example without using `const`:\n\n```typescript\nfunction identity<T>(value: T) {\n    // No const here\n    return value;\n}\nconst values = identity({ a: 'a', b: 'b' }); // Type infered is: { a: string; b: string; }\n```\n\nAs you can see, the properties `a` and `b` are inferred with a type of `string`   .\n\nNow, let's see the difference with the `const` version:\n\n```typescript\nfunction identity<const T>(value: T) {\n    // Using const modifier on type parameters\n    return value;\n}\nconst values = identity({ a: 'a', b: 'b' }); // Type infered is: { a: \"a\"; b: \"b\"; }\n```\n\nNow we can see that the properties `a` and `b` are inferred as `const`, so `a` and `b` are treated as string literals rather than just `string` types.\n\n#### Const assertion\n\nThis feature allows you to declare a variable with a more precise literal type based on its initialization value, signifying to the compiler that the value should be treated as an immutable literal. Here are a few examples:\n\nOn a single property:\n\n```typescript\nconst v = {\n    x: 3 as const,\n};\nv.x = 3;\n```\n\nOn an entire object:\n\n```typescript\nconst v = {\n    x: 1,\n    y: 2,\n} as const;\n```\n\nThis can be particularly useful when defining the type for a tuple:\n\n```typescript\nconst x = [1, 2, 3]; // number[]\nconst y = [1, 2, 3] as const; // Tuple of readonly [1, 2, 3]\n```\n\n### Explicit Type Annotation\n\nWe can be specific and pass a type, in the following example property `x` is of type `number`:\n\n```typescript\nconst v = {\n    x: 1, // Inferred type: number (widening)\n};\nv.x = 3; // Valid\n```\n\nWe can make the type annotation more specific by using a union of literal types:\n\n<!-- skip -->\n```typescript\nconst v: { x: 1 | 2 | 3 } = {\n    x: 1, // x is now a union of literal types: 1 | 2 | 3\n};\nv.x = 3; // Valid\nv.x = 100; // Invalid\n```\n\n### Type Narrowing\n\nType Narrowing is the process in TypeScript where a general type is narrowed down to a more specific type. This occurs when TypeScript analyzes the code and determines that certain conditions or operations can refine the type information.\n\nNarrowing types can occur in different ways, including:\n\n#### Conditions\n\nBy using conditional statements, such as `if` or `switch`, TypeScript can narrow down the type based on the outcome of the condition. For example:\n\n```typescript\nlet x: number | undefined = 10;\n\nif (x !== undefined) {\n    x += 100; // The type is number, which had been narrowed by the condition\n}\n```\n\n#### Throwing or returning\n\nThrowing an error or returning early from a branch can be used to help TypeScript narrow down a type. For example:\n\n```typescript\nlet x: number | undefined = 10;\n\nif (x === undefined) {\n    throw 'error';\n}\nx += 100;\n```\n\nOther ways to narrow down types in TypeScript include:\n\n* `instanceof` operator: Used to check if an object is an instance of a specific class.\n* `in` operator: Used to check if a property exists in an object.\n* `typeof` operator: Used to check the type of a value at runtime.\n* Built-in functions like `Array.isArray()`: Used to check if a value is an array.\n\n#### Discriminated Union\n\nUsing a \"Discriminated Union\" is a pattern in TypeScript where an explicit \"tag\" is added to objects to distinguish between different types within a union. This pattern is also referred to as a \"tagged union.\" In the following example, the \"tag\" is represented by the property \"type\":\n\n```typescript\ntype A = { type: 'type_a'; value: number };\ntype B = { type: 'type_b'; value: string };\n\nconst x = (input: A | B): string | number => {\n    switch (input.type) {\n        case 'type_a':\n            return input.value + 100; // type is A\n        case 'type_b':\n            return input.value + 'extra'; // type is B\n    }\n};\n```\n\n#### User-Defined Type Guards\n\nIn cases where TypeScript is unable to determine a type, it is possible to write a helper function known as a \"user-defined type guard.\" In the following example, we will utilize a Type Predicate to narrow down the type after applying certain filtering:\n\n```typescript\nconst data = ['a', null, 'c', 'd', null, 'f'];\n\nconst r1 = data.filter(x => x != null); // The type is (string | null)[], TypeScript was not able to infer the type properly\n\nconst isValid = (item: string | null): item is string => item !== null; // Custom type guard\n\nconst r2 = data.filter(isValid); // The type is fine now string[], by using the predicate type guard we were able to narrow the type\n```\n\n"
  },
  {
    "path": "website/src/content/docs/book/extending-types.md",
    "content": "---\ntitle: Extending Types\nsidebar:\n  order: 15\n  label: 15. Extending Types\n---\n\n\nIt is possible to extend an `interface` (copy members from another type):\n\n```typescript\ninterface X {\n    a: string;\n}\ninterface Y extends X {\n    b: string;\n}\n```\n\nIt is also possible to extend from multiple types:\n\n```typescript\ninterface A {\n    a: string;\n}\ninterface B {\n    b: string;\n}\ninterface Y extends A, B {\n    y: string;\n}\n```\n\nThe `extends` keyword works only on interfaces and classes, for types use an intersection:\n\n```typescript\ntype A = {\n    a: number;\n};\ntype B = {\n    b: number;\n};\ntype C = A & B;\n```\n\nIt is possible to extend a type using an inference but not vice versa:\n\n```typescript\ntype A = {\n    a: string;\n};\ninterface B extends A {\n    b: string;\n}\n```\n\n"
  },
  {
    "path": "website/src/content/docs/book/fixed-length-tuple.md",
    "content": "---\ntitle: Fixed Length Tuple\nsidebar:\n  order: 30\n  label: 30. Fixed Length Tuple\n---\n\n\nA Fixed Length Tuple is a specific type of tuple that enforces a fixed number of elements of specific types, and disallows any modifications to the length of the tuple once it is defined.\n\nFixed Length Tuples are useful when you need to represent a collection of values with a specific number of elements and specific types, and you want to ensure that the length and types of the tuple cannot be changed inadvertently.\n\n<!-- skip -->\n```typescript\nconst x = [10, 'hello'] as const;\nx.push(2); // Error\n```\n\n"
  },
  {
    "path": "website/src/content/docs/book/generics.md",
    "content": "---\ntitle: Generics\nsidebar:\n  order: 55\n  label: 55. Generics\n---\n\n\nGenerics allow you to create reusable components and functions that can work with multiple types. With generics, you can parameterize types, functions, and interfaces, allowing them to operate on different types without explicitly specifying them beforehand.\n\nGenerics allow you to make code more flexible and reusable.\n\n### Generic Type\n\nTo define a generic type, you use angle brackets (`<>`) to specify the type parameters, for instance:\n\n```typescript\nfunction identity<T>(arg: T): T {\n    return arg;\n}\nconst a = identity('x');\nconst b = identity(123);\n\nconst getLen = <T,>(data: ReadonlyArray<T>) => data.length;\nconst len = getLen([1, 2, 3]);\n```\n\n### Generic Classes\n\nGenerics can be applied also to classes, in this way they can work with multiple types by using type parameters. This is useful to create reusable class definitions that can operate on different data types while maintaining type safety.\n\n```typescript\nclass Container<T> {\n    private item: T;\n\n    constructor(item: T) {\n        this.item = item;\n    }\n\n    getItem(): T {\n        return this.item;\n    }\n}\n\nconst numberContainer = new Container<number>(123);\nconsole.log(numberContainer.getItem()); // 123\n\nconst stringContainer = new Container<string>('hello');\nconsole.log(stringContainer.getItem()); // hello\n```\n\n### Generic Constraints\n\nGeneric parameters can be constrained using the `extends` keyword followed by a type or interface that the type parameter must satisfy.\n\nIn the following example T it is must containing a properly `length` in order to be valid:\n\n<!-- skip -->\n```typescript\nconst printLen = <T extends { length: number }>(value: T): void => {\n    console.log(value.length);\n};\n\nprintLen('Hello'); // 5\nprintLen([1, 2, 3]); // 3\nprintLen({ length: 10 }); // 10\nprintLen(123); // Invalid\n```\n\nAn interesting feature of generic introduced in version 3.4 RC is Higher order function type inference which introduced  propagated generic type arguments:\n\n```typescript\ndeclare function pipe<A extends any[], B, C>(\n    ab: (...args: A) => B,\n    bc: (b: B) => C\n): (...args: A) => C;\n\ndeclare function list<T>(a: T): T[];\ndeclare function box<V>(x: V): { value: V };\n\nconst listBox = pipe(list, box); // <T>(a: T) => { value: T[] }\nconst boxList = pipe(box, list); // <V>(x: V) => { value: V }[]\n```\n\nThis functionality allows more easily typed safe pointfree style programming which is common in functional programming.\n\n### Generic contextual narrowing\n\nContextual narrowing for generics is the mechanism in TypeScript that allows the compiler to narrow down the type of a generic parameter based on the context in which it is used, it is useful when working with generic types in conditional statements:\n\n```typescript\nfunction process<T>(value: T): void {\n    if (typeof value === 'string') {\n        // Value is narrowed down to type 'string'\n        console.log(value.length);\n    } else if (typeof value === 'number') {\n        // Value is narrowed down to type 'number'\n        console.log(value.toFixed(2));\n    }\n}\n\nprocess('hello'); // 5\nprocess(3.14159); // 3.14\n```\n\n"
  },
  {
    "path": "website/src/content/docs/book/getting-started-with-typescript.md",
    "content": "---\ntitle: Getting Started With TypeScript\nsidebar:\n  order: 8\n  label: 8. Getting Started With TypeScript\n---\n\n\n### Installation\n\nVisual Studio Code provides excellent support for the TypeScript language but does not include the TypeScript compiler. To install the TypeScript compiler, you can use a package manager like npm or yarn:\n\n```shell\nnpm install typescript --save-dev\n```\n\nor\n\n```shell\nyarn add typescript --dev\n```\n\nMake sure to commit the generated lockfile to ensure that every team member uses the same version of TypeScript.\n\nTo run the TypeScript compiler, you can use the following commands\n\n```shell\nnpx tsc\n```\n\nor\n\n```shell\nyarn tsc\n```\n\nIt is recommended to install TypeScript project-wise rather than globally, as it provides a more predictable build process. However, for one-off occasions, you can use the following command:\n\n```shell\nnpx tsc\n```\n\nor installing it globally:\n\n```shell\nnpm install -g typescript\n```\n\nIf you are using Microsoft Visual Studio, you can obtain TypeScript as a package in NuGet for your MSBuild projects. In the NuGet Package Manager Console, run the following command:\n\n```shell\nInstall-Package Microsoft.TypeScript.MSBuild\n```\n\nDuring the TypeScript installation, two executables are installed: \"tsc\" as the TypeScript compiler and \"tsserver\" as the TypeScript standalone server. The standalone server contains the compiler and language services that can be utilized by editors and IDEs to provide intelligent code completion.\n\nAdditionally, there are several TypeScript-compatible transpilers available, such as Babel (via a plugin) or swc. These transpilers can be used to convert TypeScript code into other target languages or versions.\n\n### Configuration\n\nTypeScript can be configured using the tsc CLI options or by utilizing a dedicated configuration file called tsconfig.json placed in the root of the project.\n\nTo generate a tsconfig.json file prepopulated with recommended settings, you can use the following command:\n\n```shell\ntsc --init\n```\n\nWhen executing the `tsc` command locally, TypeScript will compile the code using the configuration specified in the nearest tsconfig.json file.\n\nHere are some examples of CLI commands that run with the default settings:\n\n```shell\ntsc main.ts // Compile a specific file (main.ts) to JavaScript\ntsc src/*.ts // Compile any .ts files under the 'src' folder to JavaScript\ntsc app.ts util.ts --outfile index.js // Compile two TypeScript files (app.ts and util.ts) into a single JavaScript file (index.js)\n```\n\n### TypeScript Configuration File\n\nA tsconfig.json file is used to configure the TypeScript Compiler (tsc). Usually, it is added to the root of the project, together with the `package.json` file.\n\nNotes:\n\n* tsconfig.json accepts comments even if it is in json format.\n* It is advisable to use this configuration file instead of the command-line options.\n\nAt the following link you can find the complete documentation and its schema:\n\n[https://www.typescriptlang.org/tsconfig](https://www.typescriptlang.org/tsconfig)\n\n[https://www.typescriptlang.org/tsconfig/](https://www.typescriptlang.org/tsconfig/)\n\nThe following represents a list of the common and useful configurations:\n\n#### target\n\nThe \"target\" property is used to specify which version of JavaScript ECMAScript version your TypeScript should emit/compile into. For modern browsers ES6 is a good option, for older browsers, ES5 is recommended.\n\n#### lib\n\nThe \"lib\" property is used to specify which library files to include at compilation time. TypeScript automatically includes APIs for features specified in the \"target\" property, but it is possible to omit or pick specific libraries for particular needs. For instance, if you are working on a server project, you could exclude the \"DOM\" library, which is useful only in a browser environment.\n\n#### strict\n\nThe \"strict\" property enables stronger guarantees and enhances type safety. It is advisable to always include this property in your project's tsconfig.json file. Enabling the \"strict\" property allows TypeScript to:\n\n* Emit code using \"use strict\" for each source file.\n* Consider \"null\" and \"undefined\" in the type checking process.\n* Disable the usage of the \"any\" type when no type annotations are present.\n* Raise an error on the usage of the \"this\" expression, which would otherwise imply the \"any\" type.\n\n#### module\n\nThe \"module\" property sets the module system supported for the compiled program. During runtime, a module loader is used to locate and execute dependencies based on the specified module system.\n\nThe most common module loaders used in JavaScript are Node.js CommonJS for server-side applications and RequireJS for AMD modules in browser-based web applications. TypeScript can emit code for various module systems, including UMD, System, ESNext, ES2015/ES6, and ES2020.\n\nNote: The module system should be chosen based on the target environment and the module loading mechanism available in that environment.\n\n#### moduleResolution\n\nThe \"moduleResolution\" property specifies the module resolution strategy. Use \"node\" for modern TypeScript code, the \"classic\" strategy is used only for old versions of TypeScript (before 1.6).\n\n#### esModuleInterop\n\nThe \"esModuleInterop\" property allows import default from CommonJS modules that did not export using the \"default\" property, this property provides a shim to ensure compatibility in the emitted JavaScript. After enabling this option we can use `import MyLibrary from \"my-library\"` instead of `import * as MyLibrary from \"my-library\"`.\n\n#### jsx\n\nThe \"jsx\" property applies only to .tsx files used in ReactJS and controls how JSX constructs are compiled into JavaScript. A common option is \"preserve\" which will compile to a .jsx file keeping unchanged the JSX so it can be passed to different tools like Babel for further transformations.\n\n#### skipLibCheck\n\nThe \"skipLibCheck'' property will prevent TypeScript from type-checking the entire imported third-party packages. This property will reduce the compile time of a project. TypeScript will still check your code against the type definitions provided by these packages.\n\n#### files\n\nThe \"files\" property indicates to the compiler a list of files that must always be included in the program.\n\n#### include\n\n<!-- markdownlint-disable MD049 -->\nThe \"include\" property indicates to the compiler a list of files that we would like to include. This property allows glob-like patterns, such as \"\\*_\" for any subdirectory, \"_\" for any file name, and \"?\" for optional characters.\n<!-- markdownlint-enable MD049 -->\n\n#### exclude\n\nThe \"exclude\" property indicates to the compiler a list of files that should not be included in the compilation. This can include files such as \"node_modules\" or test files.\nNote: tsconfig.json allows comments.\n\n### importHelpers\n\nTypeScript uses helper code when generating code for certain advanced or down-leveled JavaScript features. By default, these helpers are duplicated in files using them. The `importHelpers` option imports these helpers from the `tslib` module instead, making the JavaScript output more efficient.\n\n### Migration to TypeScript Advice\n\nFor large projects, it is recommended to adopt a gradual transition where TypeScript and JavaScript code will initially coexist. Only small projects can be migrated to TypeScript in one go.\n\nThe first step of this transition is to introduce TypeScript into the build chain process. This can be done by using the \"allowJs\" compiler option, which permits .ts and .tsx files to coexist with existing JavaScript files. As TypeScript will fall back to a type of \"any\" for a variable when it cannot infer the type from JavaScript files, it is recommended to disable \"noImplicitAny\" in your compiler options at the beginning of the migration.\n\nThe second step is to ensure that your JavaScript tests work alongside TypeScript files so that you can run tests as you convert each module. If you are using Jest, consider using `ts-jest`, which allows you to test TypeScript projects with Jest.\n\nThe third step is to include type declarations for third-party libraries in your project. These declarations can be found either bundled or on DefinitelyTyped. You can search for them using [https://www.typescriptlang.org/dt/search](https://www.typescriptlang.org/dt/search) and install them using:\n\n```shell\nnpm install --save-dev @types/package-name\n```\n\nor\n\n```shell\nyarn add --dev @types/package-name\n```\n\nThe fourth step is to migrate module by module with a bottom-up approach, following your Dependency Graph starting with the leaves. The idea is to start converting Modules that do not depend on other Modules. To visualize the dependency graphs, you can use the \"madge\" tool.\n\nGood candidate modules for these initial conversions are utility functions and code related to external APIs or specifications. It is possible to automatically generate TypeScript type definitions from Swagger contracts, GraphQL or JSON schemas to be included in your project.\n\nWhen there are no specifications or official schemas available, you can generate types from raw data, such as JSON returned by a server. However, it is recommended to generate types from specifications instead of data to avoid missing edge cases.\n\nDuring the migration, refrain from code refactoring and focus only on adding types to your modules.\n\nThe fifth step is to enable \"noImplicitAny,\" which will enforce that all types are known and defined, providing a better TypeScript experience for your project.\n\nDuring the migration, you can use the `@ts-check` directive, which enables TypeScript type checking in a JavaScript file. This directive provides a loose version of type checking and can be initially used to identify issues in JavaScript files. When `@ts-check` is included in a file, TypeScript will try to deduce definitions using JSDoc-style comments. However, consider using JSDoc annotations only at a very early stage of the migration.\n\nConsider keeping the default value of `noEmitOnError` in your tsconfig.json as false. This will allow you to output JavaScript source code even if errors are reported.\n\n"
  },
  {
    "path": "website/src/content/docs/book/index-signatures.md",
    "content": "---\ntitle: Index Signatures\nsidebar:\n  order: 14\n  label: 14. Index Signatures\n---\n\n\nIn TypeScript we can use as index signature `string`, `number`, and `symbol`:\n\n```typescript\ntype K = {\n    [name: string | number]: string;\n};\nconst k: K = { x: 'x', 1: 'b' };\nconsole.log(k['x']);\nconsole.log(k[1]);\nconsole.log(k['1']); // Same result as k[1]\n```\n\nPlease note that JavaScript automatically converts an index with `number` to an index with `string` so `k[1]` or `k[\"1\"]` return the same value.\n\n"
  },
  {
    "path": "website/src/content/docs/book/infer-type-inference-in-conditional-types.md",
    "content": "---\ntitle: infer Type Inference in Conditional Types\nsidebar:\n  order: 41\n  label: 41. infer Type Inference in Conditional Types\n---\n\n\nThe `infer`keyword is used in conditional types to infer (extract) the type of a generic parameter from a type that depends on it. This allows you to write more flexible and reusable type definitions.\n\n```typescript\ntype ElementType<T> = T extends (infer U)[] ? U : never;\ntype Numbers = ElementType<number[]>; // number\ntype Strings = ElementType<string[]>; // string\n```\n\n"
  },
  {
    "path": "website/src/content/docs/book/interface-and-type.md",
    "content": "---\ntitle: Interface and Type\nsidebar:\n  order: 48\n  label: 48. Interface and Type\n---\n\n\n### Common Syntax\n\nIn TypeScript, interfaces define the structure of objects, specifying the names and types of properties or methods that an object must have. The common syntax for defining an interface in TypeScript is as follows:\n\n<!-- skip -->\n```typescript\ninterface InterfaceName {\n    property1: Type1;\n    // ...\n    method1(arg1: ArgType1, arg2: ArgType2): ReturnType;\n    // ...\n}\n```\n\nSimilarly for type definition:\n\n<!-- skip -->\n```typescript\ntype TypeName = {\n    property1: Type1;\n    // ...\n    method1(arg1: ArgType1, arg2: ArgType2): ReturnType;\n    // ...\n};\n```\n\n`interface InterfaceName` or `type TypeName`: Defines the name of the interface.\n`property1`: `Type1`: Specifies the properties of the interface along with their corresponding types. Multiple properties can be defined, each separated by a semicolon.\n`method1(arg1: ArgType1, arg2: ArgType2): ReturnType;`: Specifies the methods of the interface. Methods are defined with their names, followed by a parameter list in parentheses and the return type. Multiple methods can be defined, each separated by a semicolon.\n\nExample interface:\n\n```typescript\ninterface Person {\n    name: string;\n    age: number;\n    greet(): void;\n}\n```\n\nExample of type:\n\n```typescript\ntype TypeName = {\n    property1: string;\n    method1(arg1: string, arg2: string): string;\n};\n```\n\nIn TypeScript, types are used to define the shape of data and enforce type checking. There are several common syntaxes for defining types in TypeScript, depending on the specific use case. Here are some examples:\n\n### Basic Types\n\n```typescript\nlet myNumber: number = 123; // number type\nlet myBoolean: boolean = true; // boolean type\nlet myArray: string[] = ['a', 'b']; // array of strings\nlet myTuple: [string, number] = ['a', 123]; // tuple\n```\n\n### Objects and Interfaces\n\n```typescript\nconst x: { name: string; age: number } = { name: 'Simon', age: 7 };\n```\n\n### Union and Intersection Types\n\n```typescript\ntype MyType = string | number; // Union type\nlet myUnion: MyType = 'hello'; // Can be a string\nmyUnion = 123; // Or a number\n\ntype TypeA = { name: string };\ntype TypeB = { age: number };\ntype CombinedType = TypeA & TypeB; // Intersection type\nlet myCombined: CombinedType = { name: 'John', age: 25 }; // Object with both name and age properties\n```\n\n"
  },
  {
    "path": "website/src/content/docs/book/intersection-types.md",
    "content": "---\ntitle: Intersection Types\nsidebar:\n  order: 32\n  label: 32. Intersection Types\n---\n\n\nAn Intersection Type is a type that represents a value that has all the properties of two or more types. Intersection Types are denoted using the `&` symbol between each type.\n\n```typescript\ntype X = {\n    a: string;\n};\n\ntype Y = {\n    b: string;\n};\n\ntype J = X & Y; // Intersection\n\nconst j: J = {\n    a: 'a',\n    b: 'b',\n};\n```\n\n"
  },
  {
    "path": "website/src/content/docs/book/introduction.md",
    "content": "---\ntitle: Introduction\nsidebar:\n  order: 5\n  label: 5. Introduction\n---\n\n\nWelcome to The Concise TypeScript Book! This guide equips you with essential knowledge and practical skills for effective TypeScript development. Discover key concepts and techniques to write clean, robust code. Whether you're a beginner or an experienced developer, this book serves as both a comprehensive guide and a handy reference for leveraging TypeScript's power in your projects.\n\nThis book covers TypeScript 5.2.\n\n"
  },
  {
    "path": "website/src/content/docs/book/literal-inference.md",
    "content": "---\ntitle: Literal Inference\nsidebar:\n  order: 17\n  label: 17. Literal Inference\n---\n\n\nLiteral Inference is a feature in TypeScript that allows the type of a variable or parameter to be inferred based on its value.\n\nIn the following example we can see that TypeScript considers `x` a literal type as the value cannot be changed any time later, when instead `y` is inferred as string as it can be modified any time later.\n\n```typescript\nconst x = 'x'; // Literal type of 'x', because this value cannot be changed\nlet y = 'y'; // Type string, as we can change this value\n```\n\nIn the following example we can see that `o.x` was inferred as a `string` (and not a literal of `a`) as TypeScript considers that the value can be changed any time later.\n\n<!-- skip -->\n```typescript\ntype X = 'a' | 'b';\n\nlet o = {\n    x: 'a', // This is a wider string\n};\n\nconst fn = (x: X) => `${x}-foo`;\n\nconsole.log(fn(o.x)); // Argument of type 'string' is not assignable to parameter of type 'X'\n```\n\nAs you can see the code throws an error when passing `o.x` to `fn` as X is a narrower type.\n\nWe can solve this issue by using type assertion using `const` or the `X` type:\n\n<!-- skip -->\n```typescript\nlet o = {\n    x: 'a' as const,\n};\n```\n\nor:\n\n<!-- skip -->\n```typescript\nlet o = {\n    x: 'a' as X,\n};\n```\n\n"
  },
  {
    "path": "website/src/content/docs/book/literal-types.md",
    "content": "---\ntitle: Literal Types\nsidebar:\n  order: 16\n  label: 16. Literal Types\n---\n\n\nA Literal Type is a single element set from a collective type, it defines a very exact value that is a JavaScript primitive.\n\nLiteral Types in TypeScript are numbers, strings, and booleans.\n\nExample of literals:\n\n```typescript\nconst a = 'a'; // String literal type\nconst b = 1; // Numeric literal type\nconst c = true; // Boolean literal type\n```\n\nString, Numeric, and Boolean Literal Types are used in unions, type guards, and type aliases.\nIn the following example, you can see a union type alias. `O` consists of only the specified values, no other string is valid:\n\n```typescript\ntype O = 'a' | 'b' | 'c';\n```\n\n"
  },
  {
    "path": "website/src/content/docs/book/mapped-type-modifiers.md",
    "content": "---\ntitle: Mapped Type Modifiers\nsidebar:\n  order: 38\n  label: 38. Mapped Type Modifiers\n---\n\n\nMapped Type Modifiers in TypeScript enable the transformation of properties within an existing type:\n\n* `readonly` or `+readonly`: This renders a property in the mapped type as read-only.\n* `-readonly`: This allows a property in the mapped type to be mutable.\n* `?`: This designates a property in the mapped type as optional.\n\nExamples:\n\n```typescript\ntype ReadOnly<T> = { readonly [P in keyof T]: T[P] }; // All properties marked as read-only\n\ntype Mutable<T> = { -readonly [P in keyof T]: T[P] }; // All properties marked as mutable\n\ntype MyPartial<T> = { [P in keyof T]?: T[P] }; // All properties marked as optional\n```\n\n"
  },
  {
    "path": "website/src/content/docs/book/mapped-types.md",
    "content": "---\ntitle: Mapped Types\nsidebar:\n  order: 37\n  label: 37. Mapped Types\n---\n\n\nMapped Types in TypeScript allow you to create new types based on an existing type by transforming each property using a mapping function. By mapping existing types, you can create new types that represent the same information in a different format. To create a mapped type, you access the properties of an existing type using the `keyof` operator and then alter them to produce a new type.\nIn the following example:\n\n```typescript\ntype MyMappedType<T> = {\n    [P in keyof T]: T[P][];\n};\ntype MyType = {\n    foo: string;\n    bar: number;\n};\ntype MyNewType = MyMappedType<MyType>;\nconst x: MyNewType = {\n    foo: ['hello', 'world'],\n    bar: [1, 2, 3],\n};\n```\n\nwe define MyMappedType to map over T's properties, creating a new type with each property as an array of its original type. Using this, we create MyNewType to represent the same info as MyType, but with each property as an array.\n\n"
  },
  {
    "path": "website/src/content/docs/book/merging-and-extension.md",
    "content": "---\ntitle: Merging and Extension\nsidebar:\n  order: 52\n  label: 52. Merging and Extension\n---\n\n\nMerging and extension refer to two different concepts related to working with types and interfaces.\n\nMerging allows you to combine multiple declarations of the same name into a single definition, for example, when you define an interface with the same name multiple times:\n\n```typescript\ninterface X {\n    a: string;\n}\n\ninterface X {\n    b: number;\n}\n\nconst person: X = {\n    a: 'a',\n    b: 7,\n};\n```\n\nExtension refers to the ability to extend or inherit from existing types or interfaces to create new ones. It is a mechanism to add additional properties or methods to an existing type without modifying its original definition. Example:\n\n```typescript\ninterface Animal {\n    name: string;\n    eat(): void;\n}\n\ninterface Bird extends Animal {\n    sing(): void;\n}\n\nconst dog: Bird = {\n    name: 'Bird 1',\n    eat() {\n        console.log('Eating');\n    },\n    sing() {\n        console.log('Singing');\n    },\n};\n```\n\n"
  },
  {
    "path": "website/src/content/docs/book/named-tuple-type-labeled.md",
    "content": "---\ntitle: Named Tuple Type (Labeled)\nsidebar:\n  order: 29\n  label: 29. Named Tuple Type (Labeled)\n---\n\n\nTuple types can include optional labels or names for each element. These labels are for readability and tooling assistance, and do not affect the operations you can perform with them.\n\n```typescript\ntype T = string;\ntype Tuple1 = [T, T];\ntype Tuple2 = [a: T, b: T];\ntype Tuple3 = [a: T, T]; // Named Tuple plus Anonymous Tuple\n```\n\n"
  },
  {
    "path": "website/src/content/docs/book/namespacing.md",
    "content": "---\ntitle: Namespacing\nsidebar:\n  order: 57\n  label: 57. Namespacing\n---\n\n\nIn TypeScript, namespaces are used to organize code into logical containers, preventing naming collisions and providing a way to group related code together.\nThe usage of the `export` keywords allows access to the namespace in \"outside\" modules.\n\n```typescript\nexport namespace MyNamespace {\n    export interface MyInterface1 {\n        prop1: boolean;\n    }\n    export interface MyInterface2 {\n        prop2: string;\n    }\n}\n\nconst a: MyNamespace.MyInterface1 = {\n    prop1: true,\n};\n```\n\n"
  },
  {
    "path": "website/src/content/docs/book/narrowing.md",
    "content": "---\ntitle: Narrowing\nsidebar:\n  order: 20\n  label: 20. Narrowing\n---\n\n\nTypeScript narrowing is the process of refining the type of a variable within a conditional block. This is useful when working with union types, where a variable can have more than one type.\n\nTypeScript recognizes several ways to narrow the type:\n\n### typeof type guards\n\nThe typeof type guard is one specific type guard in TypeScript that checks the type of a variable based on its built-in JavaScript type.\n\n```typescript\nconst fn = (x: number | string) => {\n    if (typeof x === 'number') {\n        return x + 1; // x is number\n    }\n    return -1;\n};\n```\n\n### Truthiness narrowing\n\nTruthiness narrowing in TypeScript works by checking whether a variable is truthy or falsy to narrow its type accordingly.\n\n```typescript\nconst toUpperCase = (name: string | null) => {\n    if (name) {\n        return name.toUpperCase();\n    } else {\n        return null;\n    }\n};\n```\n\n### Equality narrowing\n\nEquality narrowing in TypeScript works by checking whether a variable is equal to a specific value or not, to narrow its type accordingly.\n\nIt is used in conjunction with `switch` statements and equality operators such as `===`, `!==`, `==`, and `!=` to narrow down types.\n\n```typescript\nconst checkStatus = (status: 'success' | 'error') => {\n    switch (status) {\n        case 'success':\n            return true;\n        case 'error':\n            return null;\n    }\n};\n```\n\n### In Operator narrowing\n\nThe `in` Operator narrowing in TypeScript is a way to narrow the type of a variable based on whether a property exists within the variable's type.\n\n```typescript\ntype Dog = {\n    name: string;\n    breed: string;\n};\n\ntype Cat = {\n    name: string;\n    likesCream: boolean;\n};\n\nconst getAnimalType = (pet: Dog | Cat) => {\n    if ('breed' in pet) {\n        return 'dog';\n    } else {\n        return 'cat';\n    }\n};\n```\n\n### instanceof narrowing\n\nThe `instanceof` operator narrowing in TypeScript is a way to narrow the type of a variable based on its constructor function, by checking if an object is an instance of a certain class or interface.\n\n```typescript\nclass Square {\n    constructor(public width: number) {}\n}\nclass Rectangle {\n    constructor(\n        public width: number,\n        public height: number\n    ) {}\n}\nfunction area(shape: Square | Rectangle) {\n    if (shape instanceof Square) {\n        return shape.width * shape.width;\n    } else {\n        return shape.width * shape.height;\n    }\n}\nconst square = new Square(5);\nconst rectangle = new Rectangle(5, 10);\nconsole.log(area(square)); // 25\nconsole.log(area(rectangle)); // 50\n```\n\n"
  },
  {
    "path": "website/src/content/docs/book/never-type.md",
    "content": "---\ntitle: Never type\nsidebar:\n  order: 47\n  label: 47. Never type\n---\n\n\nThe `never` type represents values that never occur. It is used to denote functions or expressions that never return or throw an error.\n\nFor instance an infinite loop:\n\n```typescript\nconst infiniteLoop = (): never => {\n    while (true) {\n        // do something\n    }\n};\n```\n\nThrowing an error:\n\n```typescript\nconst throwError = (message: string): never => {\n    throw new Error(message);\n};\n```\n\nThe `never` type is useful in ensuring type safety and catching potential errors in your code. It helps TypeScript analyze and infer more precise types when used in combination with other types and control flow statements, for instance:\n\n```typescript\ntype Direction = 'up' | 'down';\nconst move = (direction: Direction): void => {\n    switch (direction) {\n        case 'up':\n            // move up\n            break;\n        case 'down':\n            // move down\n            break;\n        default:\n            const exhaustiveCheck: never = direction;\n            throw new Error(`Unhandled direction: ${exhaustiveCheck}`);\n    }\n};\n```\n\n"
  },
  {
    "path": "website/src/content/docs/book/object-types.md",
    "content": "---\ntitle: Object Types\nsidebar:\n  order: 27\n  label: 27. Object Types\n---\n\n\nIn TypeScript, object types describe the shape of an object. They specify the names and types of the object's properties, as well as whether those properties are required or optional.\n\nIn TypeScript, you can define object types in two primary ways:\n\nInterface which defines the shape of an object by specifying the names, types, and optionality of its properties.\n\n```typescript\ninterface User {\n    name: string;\n    age: number;\n    email?: string;\n}\n```\n\nType alias, similar to an interface, defines the shape of an object. However, it can also create a new custom type that is based on an existing type or a combination of existing types. This includes defining union types, intersection types, and other complex types.\n\n```typescript\ntype Point = {\n    x: number;\n    y: number;\n};\n```\n\nIt also possible to define a type anonymously:\n\n```typescript\nconst sum = (x: { a: number; b: number }) => x.a + x.b;\nconsole.log(sum({ a: 5, b: 1 }));\n```\n\n"
  },
  {
    "path": "website/src/content/docs/book/optional-properties.md",
    "content": "---\ntitle: Optional Properties\nsidebar:\n  order: 12\n  label: 12. Optional Properties\n---\n\n\nAn object can specify Optional Properties by adding a question mark `?` to the end of the property name:\n\n```typescript\ntype X = {\n    a: number;\n    b?: number; // Optional\n};\n```\n\nIt is possible to specify a default value when a property is optional:\n\n```typescript\ntype X = {\n    a: number;\n    b?: number;\n};\nconst x = ({ a, b = 100 }: X) => a + b;\n```\n\n"
  },
  {
    "path": "website/src/content/docs/book/others.md",
    "content": "---\ntitle: Others\nsidebar:\n  order: 61\n  label: 61. Others\n---\n\n\n### Errors and Exception Handling\n\nTypeScript allows you to catch and handle errors using standard JavaScript error handling mechanisms:\n\nTry-Catch-Finally Blocks:\n\n```typescript\ntry {\n    // Code that might throw an error\n} catch (error) {\n    // Handle the error\n} finally {\n    // Code that always executes, finally is optional\n}\n```\n\nYou can also handle different types of error:\n\n```typescript\ntry {\n    // Code that might throw different types of errors\n} catch (error) {\n    if (error instanceof TypeError) {\n        // Handle TypeError\n    } else if (error instanceof RangeError) {\n        // Handle RangeError\n    } else {\n        // Handle other errors\n    }\n}\n```\n\nCustom Error Types:\n\nIt is possible to specify more specific error by extending on the Error `class`:\n\n```typescript\nclass CustomError extends Error {\n    constructor(message: string) {\n        super(message);\n        this.name = 'CustomError';\n    }\n}\n\nthrow new CustomError('This is a custom error.');\n```\n\n### Mixin classes\n\nMixin classes allow you to combine and compose behavior from multiple classes into a single class. They provide a way to reuse and extend functionality without the need for deep inheritance chains.\n\n```typescript\nabstract class Identifiable {\n    name: string = '';\n    logId() {\n        console.log('id:', this.name);\n    }\n}\nabstract class Selectable {\n    selected: boolean = false;\n    select() {\n        this.selected = true;\n        console.log('Select');\n    }\n    deselect() {\n        this.selected = false;\n        console.log('Deselect');\n    }\n}\nclass MyClass {\n    constructor() {}\n}\n\n// Extend MyClass to include the behavior of Identifiable and Selectable\ninterface MyClass extends Identifiable, Selectable {}\n\n// Function to apply mixins to a class\nfunction applyMixins(source: any, baseCtors: any[]) {\n    baseCtors.forEach(baseCtor => {\n        Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => {\n            let descriptor = Object.getOwnPropertyDescriptor(\n                baseCtor.prototype,\n                name\n            );\n            if (descriptor) {\n                Object.defineProperty(source.prototype, name, descriptor);\n            }\n        });\n    });\n}\n\n// Apply the mixins to MyClass\napplyMixins(MyClass, [Identifiable, Selectable]);\nlet o = new MyClass();\no.name = 'abc';\no.logId();\no.select();\n```\n\n### Asynchronous Language Features\n\nAs TypeScript is a superset of JavaScript, it has built-in asynchronous language features of JavaScript as:\n\nPromises:\n\nPromises are a way to handle asynchronous operations and their results using methods like `.then()` and `.catch()` to handle success and error conditions.\n\nTo learn more: [https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)\n\nAsync/await:\n\nAsync/await keywords are a way to provide a more synchronous-looking syntax for working with Promises. The `async` keyword is used to define an asynchronous function, and the `await` keyword is used within an async function to pause execution until a Promise is resolved or rejected.\n\nTo learn more:\n[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function)\n[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await)\n\nThe following API are well supported in TypeScript:\n\nFetch API:\n[https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API)\n\nWeb Workers:\n[https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API)\n\nShared Workers:\n[https://developer.mozilla.org/en-US/docs/Web/API/SharedWorker](https://developer.mozilla.org/en-US/docs/Web/API/SharedWorker)\n\nWebSocket:\n[https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API)\n\n### Iterators and Generators\n\nBoth Iterators and Generators are well supported in TypeScript.\n\nIterators are objects that implement the iterator protocol, providing a way to access elements of a collection or sequence one by one. It is a structure that contains a pointer to the next element in the iteration. They have a `next()` method that returns the next value in the sequence along with a boolean indicating if the sequence is `done`.\n\n```typescript\nclass NumberIterator implements Iterable<number> {\n    private current: number;\n\n    constructor(\n        private start: number,\n        private end: number\n    ) {\n        this.current = start;\n    }\n\n    public next(): IteratorResult<number> {\n        if (this.current <= this.end) {\n            const value = this.current;\n            this.current++;\n            return { value, done: false };\n        } else {\n            return { value: undefined, done: true };\n        }\n    }\n\n    [Symbol.iterator](): Iterator<number> {\n        return this;\n    }\n}\n\nconst iterator = new NumberIterator(1, 3);\n\nfor (const num of iterator) {\n    console.log(num);\n}\n```\n\nGenerators are special functions defined using the `function*` syntax that simplifies the creation of iterators. They use the `yield` keyword to define the sequence of values and automatically pause and resume execution when values are requested.\n\nGenerators make it easier to create iterators and are especially useful for working with large or infinite sequences.\n\nExample:\n\n```typescript\nfunction* numberGenerator(start: number, end: number): Generator<number> {\n    for (let i = start; i <= end; i++) {\n        yield i;\n    }\n}\n\nconst generator = numberGenerator(1, 5);\n\nfor (const num of generator) {\n    console.log(num);\n}\n```\n\nTypeScript also supports async iterators and async Generators.\n\nTo learn more:\n\n[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Generator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Generator)\n\n[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Iterator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Iterator)\n\n### TsDocs JSDoc Reference\n\nWhen working with a JavaScript code base, it is possible to help TypeScript to infer the right Type by using JSDoc comments with additional annotation to provide type information.\n\nExample:\n\n```typescript\n/**\n * Computes the power of a given number\n * @constructor\n * @param {number} base – The base value of the expression\n * @param {number} exponent – The exponent value of the expression\n */\nfunction power(base: number, exponent: number) {\n    return Math.pow(base, exponent);\n}\npower(10, 2); // function power(base: number, exponent: number): number\n```\n\nFull documentation is provided to this link:\n[https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html](https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html)\n\nFrom version 3.7 it is possible to generate .d.ts type definitions from JavaScript JSDoc syntax.\nMore information can be found here:\n[https://www.typescriptlang.org/docs/handbook/declaration-files/dts-from-js.html](https://www.typescriptlang.org/docs/handbook/declaration-files/dts-from-js.html)\n\n### @types\n\nPackages under the @types organization are special package naming conventions used to provide type definitions for existing JavaScript libraries or modules. For instance using:\n\n```shell\nnpm install --save-dev @types/lodash\n```\n\nWill install the type definitions of `lodash` in your current project.\n\nTo contribute to the type definitions of @types package, please submit a pull request to [https://github.com/DefinitelyTyped/DefinitelyTyped](https://github.com/DefinitelyTyped/DefinitelyTyped).\n\n### JSX\n\nJSX (JavaScript XML) is an extension to the JavaScript language syntax that allows you to write HTML-like code within your JavaScript or TypeScript files. It is commonly used in React to define the HTML structure.\n\nTypeScript extends the capabilities of JSX by providing type checking and static analysis.\n\nTo use JSX you need to set the `jsx` compiler option in your `tsconfig.json` file. Two common configuration options:\n\n* \"preserve\": emit .jsx files with the JSX unchanged. This option tells TypeScript to keep the JSX syntax as-is and not transform it during the compilation process. You can use this option if you have a separate tool, like Babel, that handles the transformation.\n* \"react\": enables TypeScript's built-in JSX transformation. React.createElement will be used.\n\nAll options are available here:\n[https://www.typescriptlang.org/tsconfig#jsx](https://www.typescriptlang.org/tsconfig#jsx)\n\n### ES6 Modules\n\nTypeScript does support ES6 (ECMAScript 2015) and many subsequent versions. This means you can use ES6 syntax, such as arrow functions, template literals, classes, modules, destructuring, and more.\n\nTo enable ES6 features in your project, you can specify the `target` property in the tsconfig.json.\n\nA configuration example:\n\n```json\n{\n  \"compilerOptions\": {\n    \"target\": \"es6\",\n    \"module\": \"es6\",\n    \"moduleResolution\": \"node\",\n    \"sourceMap\": true,\n    \"outDir\": \"dist\"\n  },\n  \"include\": [\"src\"]\n}\n```\n\n### ES7 Exponentiation Operator\n\nThe exponentiation (`**`) operator computes the value obtained by raising the first operand to the power of the second operand. It functions similarly to `Math.pow()`, but with the added capability of accepting BigInts as operands.\nTypeScript fully supports this operator using as `target` in your tsconfig.json file `es2016` or larger version.\n\n```typescript\nconsole.log(2 ** (2 ** 2)); // 16\n```\n\n### The for-await-of Statement\n\nThis is a JavaScript feature fully supported in TypeScript which allows you to iterate over asynchronous iterable objects from target version es2018.\n\n```typescript\nasync function* asyncNumbers(): AsyncIterableIterator<number> {\n    yield Promise.resolve(1);\n    yield Promise.resolve(2);\n    yield Promise.resolve(3);\n}\n\n(async () => {\n    for await (const num of asyncNumbers()) {\n        console.log(num);\n    }\n})();\n```\n\n### New target meta-property\n\nYou can use in TypeScript the `new.target` meta-property which enables you to determine if a function or constructor was invoked using the new operator. It allows you to detect whether an object was created as a result of a constructor call.\n\n```typescript\nclass Parent {\n    constructor() {\n        console.log(new.target); // Logs the constructor function used to create an instance\n    }\n}\n\nclass Child extends Parent {\n    constructor() {\n        super();\n    }\n}\n\nconst parentX = new Parent(); // [Function: Parent]\nconst child = new Child(); // [Function: Child]\n```\n\n### Dynamic Import Expressions\n\nIt is possible to conditionally load modules or lazy load them on-demand using the ECMAScript proposal for dynamic import which is supported in TypeScript.\n\nThe syntax for dynamic import expressions in TypeScript is as follows:\n\n<!-- skip -->\n```typescript\nasync function renderWidget() {\n    const container = document.getElementById('widget');\n    if (container !== null) {\n        const widget = await import('./widget'); // Dynamic import\n        widget.render(container);\n    }\n}\n\nrenderWidget();\n```\n\n### \"tsc –watch\"\n\nThis command starts a TypeScript compiler with `--watch` parameter, with the ability to automatically recompile TypeScript files whenever they are modified.\n\n```shell\ntsc --watch\n```\n\nStarting from TypeScript version 4.9, file monitoring primarily relies on file system events, automatically resorting to polling if an event-based watcher cannot be established.\n\n### Non-null Assertion Operator\n\nThe Non-null Assertion Operator (Postfix !) also called Definite Assignment Assertions is a TypeScript feature that allows you to assert that a variable or property is not null or undefined, even if TypeScript's static type analysis suggests that it might be. With this feature it is possible to remove any explicit checking.\n\n```typescript\ntype Person = {\n    name: string;\n};\n\nconst printName = (person?: Person) => {\n    console.log(`Name is ${person!.name}`);\n};\n```\n\n### Defaulted declarations\n\nDefaulted declarations are used when a variable or parameter is assigned a default value. This means that if no value is provided for that variable or parameter, the default value will be used instead.\n\n```typescript\nfunction greet(name: string = 'Anonymous'): void {\n    console.log(`Hello, ${name}!`);\n}\ngreet(); // Hello, Anonymous!\ngreet('John'); // Hello, John!\n```\n\n### Optional Chaining\n\nThe optional chaining operator `?.` works like the regular dot operator (`.`) for accessing properties or methods. However, it gracefully handles null or undefined values by terminating the expression and returning `undefined`, instead of throwing an error.\n\n```typescript\ntype Person = {\n    name: string;\n    age?: number;\n    address?: {\n        street?: string;\n        city?: string;\n    };\n};\n\nconst person: Person = {\n    name: 'John',\n};\n\nconsole.log(person.address?.city); // undefined\n```\n\n### Nullish coalescing operator\n\nThe nullish coalescing operator `??` returns the right-hand side value if the left-hand side is `null` or `undefined`; otherwise, it returns the left-hand side value.\n\n```typescript\nconst foo = null ?? 'foo';\nconsole.log(foo); // foo\n\nconst baz = 1 ?? 'baz';\nconst baz2 = 0 ?? 'baz';\nconsole.log(baz); // 1\nconsole.log(baz2); // 0\n```\n\n### Template Literal Types\n\nTemplate Literal Types allow to manipulate string value at type level and generate new string types based on existing ones. They are useful to create more expressive and precise types from string-based operations.\n\n```typescript\ntype Department = 'engineering' | 'hr';\ntype Language = 'english' | 'spanish';\ntype Id = `${Department}-${Language}-id`; // \"engineering-english-id\" | \"engineering-spanish-id\" | \"hr-english-id\" | \"hr-spanish-id\"\n```\n\n### Function overloading\n\nFunction overloading allows you to define multiple function signatures for the same function name, each with different parameter types and return type.\nWhen you call an overloaded function, TypeScript uses the provided arguments to determine the correct function signature:\n\n```typescript\nfunction makeGreeting(name: string): string;\nfunction makeGreeting(names: string[]): string[];\n\nfunction makeGreeting(person: unknown): unknown {\n    if (typeof person === 'string') {\n        return `Hi ${person}!`;\n    } else if (Array.isArray(person)) {\n        return person.map(name => `Hi, ${name}!`);\n    }\n    throw new Error('Unable to greet');\n}\n\nmakeGreeting('Simon');\nmakeGreeting(['Simone', 'John']);\n```\n\n### Recursive Types\n\nA Recursive Type is a type that can refer to itself. This is useful for defining data structures that have a hierarchical or recursive structure (potentially infinite nesting), such as linked lists, trees, and graphs.\n\n```typescript\ntype ListNode<T> = {\n    data: T;\n    next: ListNode<T> | undefined;\n};\n```\n\n### Recursive Conditional Types\n\nIt is possible to define complex type relationships using logic and recursion in TypeScript.\nLet’s break it down in simple terms:\n\nConditional Types: allows you to define types based on boolean conditions:\n\n```typescript\ntype CheckNumber<T> = T extends number ? 'Number' : 'Not a number';\ntype A = CheckNumber<123>; // 'Number'\ntype B = CheckNumber<'abc'>; // 'Not a number'\n```\n\nRecursion: means a type definition that refers to itself within its own definition:\n\n```typescript\ntype Json = string | number | boolean | null | Json[] | { [key: string]: Json };\n\nconst data: Json = {\n    prop1: true,\n    prop2: 'prop2',\n    prop3: {\n        prop4: [],\n    },\n};\n```\n\nRecursive Conditional Types combine both conditional logic and recursion. It means that a type definition can depend on itself through conditional logic, creating complex and flexible type relationships.\n\n```typescript\ntype Flatten<T> = T extends Array<infer U> ? Flatten<U> : T;\n\ntype NestedArray = [1, [2, [3, 4], 5], 6];\ntype FlattenedArray = Flatten<NestedArray>; // 2 | 3 | 4 | 5 | 1 | 6\n```\n\n### ECMAScript Module Support in Node\n\nNode.js added support for ECMAScript Modules starting from version 15.3.0, and TypeScript has had ECMAScript Module Support for Node.js since version 4.7. This support can be enabled by using the `module` property with the value `nodenext` in the tsconfig.json file. Here's an example:\n\n```json\n{\n  \"compilerOptions\": {\n    \"module\": \"nodenext\",\n    \"outDir\": \"./lib\",\n    \"declaration\": true\n  }\n}\n```\n\nNode.js supports two file extensions for modules: `.mjs` for ES modules and `.cjs` for CommonJS modules. The equivalent file extensions in TypeScript are `.mts` for ES modules and `.cts` for CommonJS modules. When the TypeScript compiler transpiles these files to JavaScript, it will create `.mjs` and `.cjs` files.\n\nIf you want to use ES modules in your project, you can set the `type` property to \"module\" in your package.json file. This instructs Node.js to treat the project as an ES module project.\n\nAdditionally, TypeScript also supports type declarations in .d.ts files. These declaration files provide type information for libraries or modules written in TypeScript, allowing other developers to utilize them with TypeScript's type checking and auto-completion features.\n\n### Assertion Functions\n\nIn TypeScript, assertion functions are functions that indicate the verification of a specific condition based on their return value. In their simplest form, an assert function examines a provided predicate and raises an error when the predicate evaluates to false.\n\n```typescript\nfunction isNumber(value: unknown): asserts value is number {\n    if (typeof value !== 'number') {\n        throw new Error('Not a number');\n    }\n}\n```\n\nOr can be declared as function expression:\n\n```typescript\ntype AssertIsNumber = (value: unknown) => asserts value is number;\nconst isNumber: AssertIsNumber = value => {\n    if (typeof value !== 'number') {\n        throw new Error('Not a number');\n    }\n};\n```\n\nAssertion functions share similarities with type guards. Type guards were initially introduced to perform runtime checks and ensure the type of a value within a specific scope.\nSpecifically, a type guard is a function that evaluates a type predicate and returns a boolean value indicating whether the predicate is true or false. This differs slightly from assertion functions,where the intention is to throw an error rather than returning false when the predicate is not satisfied.\n\nExample of type guard:\n\n```typescript\nconst isNumber = (value: unknown): value is number => typeof value === 'number';\n```\n\n### Variadic Tuple Types\n\nVariadic Tuple Types are a features introduces in TypeScript version 4.0, let’s start to learn them by revise what is a tuple:\n\nA tuple type is an array which has a defined length, and were the type of each element is known:\n\n```typescript\ntype Student = [string, number];\nconst [name, age]: Student = ['Simone', 20];\n```\n\nThe term \"variadic\" means indefinite arity (accept a variable number of arguments).\n\nA variadic tuple is a tuple type which has all the property as before but the exact shape is not defined yet:\n\n```typescript\ntype Bar<T extends unknown[]> = [boolean, ...T, number];\n\ntype A = Bar<[boolean]>; // [boolean, boolean, number]\ntype B = Bar<['a', 'b']>; // [boolean, 'a', 'b', number]\ntype C = Bar<[]>; // [boolean, number]\n```\n\nIn the previous code we can see that the tuple shape is defined by the `T` generic passed in.\n\nVariadic tuples can accept multiple generics make them very flexible:\n\n```typescript\ntype Bar<T extends unknown[], G extends unknown[]> = [...T, boolean, ...G];\n\ntype A = Bar<[number], [string]>; // [number, boolean, string]\ntype B = Bar<['a', 'b'], [boolean]>; // [\"a\", \"b\", boolean, boolean]\n```\n\nWith the new variadic tuples we can use:\n\n* The spreads in tuple type syntax can now be generic, so we can represent higher-order operation on tuples and arrays even when we do not know the actual types we are operating over.\n* The rest elements can occur anywhere in a tuple.\n\nExample:\n\n```typescript\ntype Items = readonly unknown[];\n\nfunction concat<T extends Items, U extends Items>(\n    arr1: T,\n    arr2: U\n): [...T, ...U] {\n    return [...arr1, ...arr2];\n}\n\nconcat([1, 2, 3], ['4', '5', '6']); // [1, 2, 3, \"4\", \"5\", \"6\"]\n```\n\n### Boxed types\n\nBoxed types refer to the wrapper objects that are used to represent primitive types as objects. These wrapper objects provide additional functionality and methods that are not available directly on the primitive values.\n\nWhen you access a method like `charAt` or `normalize` on a `string` primitive, JavaScript wraps it in a `String` object, calls the method, and then throws the object away.\n\nDemonstration:\n\n```typescript\nconst originalNormalize = String.prototype.normalize;\nString.prototype.normalize = function () {\n    console.log(this, typeof this);\n    return originalNormalize.call(this);\n};\nconsole.log('\\u0041'.normalize());\n```\n\nTypeScript represents this differentiation by providing separate types for the primitives and their corresponding object wrappers:\n\n* string => String\n* number => Number\n* boolean => Boolean\n* symbol => Symbol\n* bigint => BigInt\n\nThe boxed types are usually not needed. Avoid using boxed types and instead use type for the primitives,  for instance `string` instead of `String`.\n\n### Covariance and Contravariance in TypeScript\n\nCovariance and Contravariance are used to describe how relationships work when dealing with inheritance or assignment of types.\n\nCovariance means that a type relationship preserves the direction of inheritance or assignment, so if a type A is a subtype of type B, then an array of type A is also considered a subtype of an array of type B. The important thing to note here is that the subtype relationship is maintained this means that Covariance accept subtype but doesn't accept supertype.\n\nContravariance means that a type relationship reverses the direction of inheritance or assignment, so if a type A is a subtype of type B, then an array of type B is considered a subtype of an array of type A. The subtype relationship is reversed this means that Contravariance accept supertype but doesn't accept subtype.\n\nNotes: Bivariance means accept both supertype & subtype.\n\nExample: Let's say we have a space for all animals and a separate space just for dogs.\n\nIn Covariance, you can put all the dogs in the animals space because dogs are a type of animal. But you cannot put all the animals in the dog space because there might be other animals mixed in.\n\nIn Contravariance, you cannot put all the animals in the dogs space because the animals space might contain other animals as well. However, you can put all the dogs in the animal space because all dogs are also animals.\n\n<!-- skip -->\n```typescript\n// Covariance example\nclass Animal {\n    name: string;\n    constructor(name: string) {\n        this.name = name;\n    }\n}\n\nclass Dog extends Animal {\n    breed: string;\n    constructor(name: string, breed: string) {\n        super(name);\n        this.breed = breed;\n    }\n}\n\nlet animals: Animal[] = [];\nlet dogs: Dog[] = [];\n\n// Covariance allows assigning subtype (Dog) array to supertype (Animal) array\nanimals = dogs;\ndogs = animals; // Invalid: Type 'Animal[]' is not assignable to type 'Dog[]'\n\n// Contravariance example\ntype Feed<in T> = (animal: T) => void;\n\nlet feedAnimal: Feed<Animal> = (animal: Animal) => {\n    console.log(`Animal name: ${animal.name}`);\n};\n\nlet feedDog: Feed<Dog> = (dog: Dog) => {\n    console.log(`Dog name: ${dog.name}, Breed: ${dog.breed}`);\n};\n\n// Contravariance allows assigning supertype (Animal) callback to subtype (Dog) callback\nfeedDog = feedAnimal;\nfeedAnimal = feedDog; // Invalid: Type 'Feed<Dog>' is not assignable to type 'Feed<Animal>'.\n```\n\nIn TypeScript, type relationships for arrays are covariant, while type relationships for function parameters are contravariant. This means that TypeScript exhibits both covariance and contravariance, depending on the context.\n\n#### Optional Variance Annotations for Type Parameters\n\nAs of TypeScript 4.7.0, we can use the `out` and `in` keywords to be specific about Variance annotation.\n\nFor Covariant, use the `out` keyword:\n\n```typescript\ntype AnimalCallback<out T> = () => T; // T is Covariant here\n```\n\nAnd for Contravariant, use the `in` keyword:\n\n```typescript\ntype AnimalCallback<in T> = (value: T) => void; // T is Contravariance here\n```\n\n### Template String Pattern Index Signatures\n\nTemplate string pattern index signatures allow us to define flexible index signatures using template string patterns. This feature enables us to create objects that can be indexed with specific patterns of string keys, providing more control and specificity when accessing and manipulating properties.\n\nTypeScript from version 4.4 allows index signatures for symbols and template string patterns.\n\n```typescript\nconst uniqueSymbol = Symbol('description');\n\ntype MyKeys = `key-${string}`;\n\ntype MyObject = {\n    [uniqueSymbol]: string;\n    [key: MyKeys]: number;\n};\n\nconst obj: MyObject = {\n    [uniqueSymbol]: 'Unique symbol key',\n    'key-a': 123,\n    'key-b': 456,\n};\n\nconsole.log(obj[uniqueSymbol]); // Unique symbol key\nconsole.log(obj['key-a']); // 123\nconsole.log(obj['key-b']); // 456\n```\n\n### The satisfies Operator\n\nThe `satisfies`  allows you to check if a given type satisfies a specific interface or condition. In other words, it ensures that a type has all the required properties and methods of a specific interface. It is a way to ensure a variable fits into a definition of a type.\nHere is an example:\n\n<!-- skip -->\n```typescript\ntype Columns = 'name' | 'nickName' | 'attributes';\n\ntype User = Record<Columns, string | string[] | undefined>;\n\n// Type Annotation using `User`\nconst user: User = {\n    name: 'Simone',\n    nickName: undefined,\n    attributes: ['dev', 'admin'],\n};\n\n// In the following lines, TypeScript won't be able to infer properly\nuser.attributes?.map(console.log); // Property 'map' does not exist on type 'string | string[]'. Property 'map' does not exist on type 'string'.\nuser.nickName; // string | string[] | undefined\n\n// Type assertion using `as`\nconst user2 = {\n    name: 'Simon',\n    nickName: undefined,\n    attributes: ['dev', 'admin'],\n} as User;\n\n// Here too, TypeScript won't be able to infer properly\nuser2.attributes?.map(console.log); // Property 'map' does not exist on type 'string | string[]'. Property 'map' does not exist on type 'string'.\nuser2.nickName; // string | string[] | undefined\n\n// Using `satisfies` operators we can properly infer the types now\nconst user3 = {\n    name: 'Simon',\n    nickName: undefined,\n    attributes: ['dev', 'admin'],\n} satisfies User;\n\nuser3.attributes?.map(console.log); // TypeScript infers correctly: string[]\nuser3.nickName; // TypeScript infers correctly: undefined\n```\n\n### Type-Only Imports and Export\n\nType-Only Imports and Export allows you to import or export types without importing or exporting the values or functions associated with those types. This can be useful for reducing the size of your bundle.\n\nTo use type-only imports, you can use the `import type` keyword.\n\nTypeScript permits using both declaration and implementation file extensions (.ts, .mts, .cts, and .tsx) in type-only imports, regardless of `allowImportingTsExtensions` settings.\n\nFor example:\n\n<!-- skip -->\n```typescript\nimport type { House } from './house.ts';\n```\n\nThe following are supported forms:\n\n<!-- skip -->\n```typescript\nimport type T from './mod';\nimport type { A, B } from './mod';\nimport type * as Types from './mod';\nexport type { T };\nexport type { T } from './mod';\n```\n\n### using declaration and Explicit Resource Management\n\nA `using` declaration is a block-scoped, immutable binding, similar to `const`, used for managing disposable resources. When initialized with a value, the `Symbol.dispose` method of that value is recorded and subsequently executed upon exiting the enclosing block scope.\n\nThis is based on ECMAScript's Resource Management feature, which is useful for performing essential cleanup tasks after object creation, such as closing connections, deleting files, and releasing memory.\n\nNotes:\n\n* Due to its recent introduction in TypeScript version 5.2, most runtimes lack native support. You'll need polyfills for: `Symbol.dispose`, `Symbol.asyncDispose`, `DisposableStack`, `AsyncDisposableStack`, `SuppressedError`.\n* Additionally, you will need to configure your tsconfig.json as follows:\n\n```json\n{\n    \"compilerOptions\": {\n        \"target\": \"es2022\",\n        \"lib\": [\"es2022\", \"esnext.disposable\", \"dom\"]\n    }\n}\n```\n\nExample:\n\n<!-- skip -->\n```typescript\n//@ts-ignore\nSymbol.dispose ??= Symbol('Symbol.dispose'); // Simple polify\n\nconst doWork = (): Disposable => {\n    return {\n        [Symbol.dispose]: () => {\n            console.log('disposed');\n        },\n    };\n};\n\nconsole.log(1);\n\n{\n    using work = doWork(); // Resource is declared\n    console.log(2);\n} // Resource is disposed (e.g., `work[Symbol.dispose]()` is evaluated)\n\nconsole.log(3);\n```\n\nThe code will log:\n\n```shell\n1\n2\ndisposed\n3\n```\n\nA resource eligible for disposal must adhere to the `Disposable` interface:\n\n```typescript\n// lib.esnext.disposable.d.ts\ninterface Disposable {\n    [Symbol.dispose](): void;\n}\n```\n\nThe `using` declarations record resource disposal operations in a stack, ensuring they are disposed in reverse order of declaration:\n\n<!-- skip -->\n```typescript\n{\n    using j = getA(),\n        y = getB();\n    using k = getC();\n} // disposes `C`, then `B`, then `A`.\n```\n\nResources are guaranteed to be disposed, even if subsequent code or exceptions occur. This may lead to disposal potentially throwing an exception, possibly suppressing another. To retain information on suppressed errors, a new native exception, `SuppressedError`, is introduced.\n\n#### await using declaration\n\nAn `await using` declaration handles an asynchronously disposable resource. The value must have a `Symbol.asyncDispose` method, which will be awaited at the block's end.\n\n<!-- skip -->\n```typescript\nasync function doWorkAsync() {\n    await using work = doWorkAsync(); // Resource is declared\n} // Resource is disposed (e.g., `await work[Symbol.asyncDispose]()` is evaluated)\n```\n\nFor an asynchronously disposable resource, it must adhere to either the `Disposable` or `AsyncDisposable` interface:\n\n```typescript\n// lib.esnext.disposable.d.ts\ninterface AsyncDisposable {\n    [Symbol.asyncDispose](): Promise<void>;\n}\n```\n\n<!-- skip -->\n```typescript\n//@ts-ignore\nSymbol.asyncDispose ??= Symbol('Symbol.asyncDispose'); // Simple polify\n\nclass DatabaseConnection implements AsyncDisposable {\n    // A method that is called when the object is disposed asynchronously\n    [Symbol.asyncDispose]() {\n        // Close the connection and return a promise\n        return this.close();\n    }\n\n    async close() {\n        console.log('Closing the connection...');\n        await new Promise(resolve => setTimeout(resolve, 1000));\n        console.log('Connection closed.');\n    }\n}\n\nasync function doWork() {\n    // Create a new connection and dispose it asynchronously when it goes out of scope\n    await using connection = new DatabaseConnection(); //  Resource is declared\n    console.log('Doing some work...');\n} // Resource is disposed (e.g., `await connection[Symbol.asyncDispose]()` is evaluated)\n\ndoWork();\n```\n\nThe code logs:\n\n```shell\nDoing some work...\nClosing the connection...\nConnection closed.\n```\n\nThe `using` and `await using` declarations are allowed in Statements: `for`, `for-in`, `for-of`, `for-await-of`, `switch`.\n\n### Import Attributes\n\nTypeScript 5.3's Import Attributes (labels for imports) tell the runtime how to handle modules (JSON, etc.). This improves security by ensuring clear imports and aligns with Content Security Policy (CSP) for safer resource loading. TypeScript ensures they are valid but lets the runtime handle their interpretation for specific module handling.\n\nExample:\n\n<!-- skip -->\n```typescript\nimport config from './config.json' with { type: 'json' };\n```\n\nwith dynamic import:\n\n<!-- skip -->\n```typescript\nconst config = import('./config.json', { with: { type: 'json' } });\n```\n"
  },
  {
    "path": "website/src/content/docs/book/overloads.md",
    "content": "---\ntitle: Overloads\nsidebar:\n  order: 51\n  label: 51. Overloads\n---\n\n\nFunction overloads in TypeScript allow you to define multiple function signatures for a single function name, enabling you to define functions that can be called in multiple ways. Here's an example:\n\n```typescript\n// Overloads\nfunction sayHi(name: string): string;\nfunction sayHi(names: string[]): string[];\n\n// Implementation\nfunction sayHi(name: unknown): unknown {\n    if (typeof name === 'string') {\n        return `Hi, ${name}!`;\n    } else if (Array.isArray(name)) {\n        return name.map(name => `Hi, ${name}!`);\n    }\n    throw new Error('Invalid value');\n}\n\nsayHi('xx'); // Valid\nsayHi(['aa', 'bb']); // Valid\n```\n\nHere's another example of using function overloads within a `class`:\n\n```typescript\nclass Greeter {\n    message: string;\n\n    constructor(message: string) {\n        this.message = message;\n    }\n\n    // overload\n    sayHi(name: string): string;\n    sayHi(names: string[]): ReadonlyArray<string>;\n\n    // implementation\n    sayHi(name: unknown): unknown {\n        if (typeof name === 'string') {\n            return `${this.message}, ${name}!`;\n        } else if (Array.isArray(name)) {\n            return name.map(name => `${this.message}, ${name}!`);\n        }\n        throw new Error('value is invalid');\n    }\n}\nconsole.log(new Greeter('Hello').sayHi('Simon'));\n```\n\n"
  },
  {
    "path": "website/src/content/docs/book/predefined-conditional-types.md",
    "content": "---\ntitle: Predefined Conditional Types\nsidebar:\n  order: 42\n  label: 42. Predefined Conditional Types\n---\n\n\nIn TypeScript, Predefined Conditional Types are built-in conditional types provided by the language. They are designed to perform common type transformations based on the characteristics of a given type.\n\n`Exclude<UnionType, ExcludedType>`: This type removes all the types from Type that are assignable to ExcludedType.\n\n`Extract<Type, Union>`: This type extracts all the types from Union that are assignable to Type.\n\n`NonNullable<Type>`: This type removes null and undefined from Type.\n\n`ReturnType<Type>`: This type extracts the return type of a function Type.\n\n`Parameters<Type>`: This type extracts the parameter types of a function Type.\n\n`Required<Type>`: This type makes all properties in Type required.\n\n`Partial<Type>`: This type makes all properties in Type optional.\n\n`Readonly<Type>`: This type makes all properties in Type readonly.\n\n"
  },
  {
    "path": "website/src/content/docs/book/primitive-types.md",
    "content": "---\ntitle: Primitive Types\nsidebar:\n  order: 10\n  label: 10. Primitive Types\n---\n\n\nTypeScript supports 7 primitive types. A primitive data type refers to a type that is not an object and does not have any methods associated with it. In TypeScript, all primitive types are immutable, meaning their values cannot be changed once they are assigned.\n\n### string\n\nThe `string` primitive type stores textual data, and the value is always double or single-quoted.\n\n```typescript\nconst x: string = 'x';\nconst y: string = 'y';\n```\n\nStrings can span multiple lines if surrounded by the backtick (`) character:\n\n```typescript\nlet sentence: string = `xxx,\n   yyy`;\n```\n\n### boolean\n\nThe `boolean` data type in TypeScript stores a binary value, either `true` or `false`.\n\n```typescript\nconst isReady: boolean = true;\n```\n\n### number\n\nA `number` data type in TypeScript is represented with a 64-bit floating point value. A `number` type can represent integers and fractions.\nTypeScript also supports hexadecimal, binary, and octal, for instance:\n\n```typescript\nconst decimal: number = 10;\nconst hexadecimal: number = 0xa00d; // Hexadecimal starts with 0x\nconst binary: number = 0b1010; // Binary starts with 0b\nconst octal: number = 0o633; // Octal starts with 0o\n```\n\n### bigInt\n\nA `bigInt` represents numeric values that are very large (253 – 1) and cannot be represented with a `number`.\n\nA `bigInt` can be created by calling the built-in function `BigInt()` or by adding `n` to the end of any integer numeric literal:\n\n```typescript\nconst x: bigint = BigInt(9007199254740991);\nconst y: bigint = 9007199254740991n;\n```\n\nNotes:\n\n* `bigInt` values cannot be mixed with `number` and cannot be used with built-in `Math`, they must be coerced to the same type.\n* `bigInt` values are available only if target configuration is ES2020 or higher.\n\n### Symbol\n\nSymbols are unique identifiers that can be used as property keys in objects to prevent naming conflicts.\n\n```typescript\ntype Obj = {\n    [sym: symbol]: number;\n};\n\nconst a = Symbol('a');\nconst b = Symbol('b');\nlet obj: Obj = {};\nobj[a] = 123;\nobj[b] = 456;\n\nconsole.log(obj[a]); // 123\nconsole.log(obj[b]); // 456\n```\n\n### null and undefined\n\n`null` and `undefined` types both represent no value or the absence of any value.\n\nThe `undefined` type means the value is not assigned or initialized or indicates an unintentional absence of value.\n\nThe `null` type means that we know that the field does not have a value, so value is unavailable, it indicates an intentional absence of value.\n\n### Array\n\nAn `array` is a data type that can store multiple values of the same type or not. It can be defined using the following syntax:\n\n```typescript\nconst x: string[] = ['a', 'b'];\nconst y: Array<string> = ['a', 'b'];\nconst j: Array<string | number> = ['a', 1, 'b', 2]; // Union\n```\n\nTypeScript supports readonly arrays using the following syntax:\n\n<!-- skip -->\n```typescript\nconst x: readonly string[] = ['a', 'b']; // Readonly modifier\nconst y: ReadonlyArray<string> = ['a', 'b'];\nconst j: ReadonlyArray<string | number> = ['a', 1, 'b', 2];\nj.push('x'); // Invalid\n```\n\nTypeScript supports tuple and readonly tuple:\n\n```typescript\nconst x: [string, number] = ['a', 1];\nconst y: readonly [string, number] = ['a', 1];\n```\n\n### any\n\nThe `any` data type represents literally \"any\" value, it is the default value when TypeScript cannot infer the type or is not specified.\n\nWhen using `any` TypeScript compiler skips the type checking so there is no type safety when `any` is being used. Generally do not use `any` to silence the compiler when an error occurs, instead focus on fixing the error as with using `any`  it is possible to break contracts and we lose the benefits of TypeScript autocomplete.\n\nThe `any` type could be useful during a gradual migration from JavaScript to TypeScript, as it can silence the compiler.\n\nFor new projects use TypeScript configuration `noImplicitAny` which enables TypeScript to issue errors where `any` is used or inferred.\n\nThe `any`type  is usually a source of errors which can mask real problems with your types. Avoid using it as much as possible.\n\n"
  },
  {
    "path": "website/src/content/docs/book/readonly-properties.md",
    "content": "---\ntitle: Readonly Properties\nsidebar:\n  order: 13\n  label: 13. Readonly Properties\n---\n\n\nIs it possible to prevent writing on a property by using the modifier `readonly`which  makes sure that the property cannot be re-written but does not provide any guarantee of total immutability:\n\n```typescript\ninterface Y {\n    readonly a: number;\n}\n\ntype X = {\n    readonly a: number;\n};\n\ntype J = Readonly<{\n    a: number;\n}>;\n\ntype K = {\n    readonly [index: number]: string;\n};\n```\n\n"
  },
  {
    "path": "website/src/content/docs/book/strictnullchecks.md",
    "content": "---\ntitle: strictNullChecks\nsidebar:\n  order: 18\n  label: 18. strictNullChecks\n---\n\n\n`strictNullChecks` is a TypeScript compiler option that enforces strict null checking. When this option is enabled, variables and parameters can only be assigned `null` or `undefined` if they have been explicitly declared to be of that type using the union type `null` | `undefined`. If a variable or parameter is not explicitly declared as nullable, TypeScript will generate an error to prevent potential runtime errors.\n\n"
  },
  {
    "path": "website/src/content/docs/book/symbols.md",
    "content": "---\ntitle: Symbols\nsidebar:\n  order: 58\n  label: 58. Symbols\n---\n\n\nSymbols are a primitive data type that represents an immutable value which is guaranteed to be globally unique throughout the lifetime of the program.\n\nSymbols can be used as keys for object properties and provide a way to create non-enumerable properties.\n\n```typescript\nconst key1: symbol = Symbol('key1');\nconst key2: symbol = Symbol('key2');\n\nconst obj = {\n    [key1]: 'value 1',\n    [key2]: 'value 2',\n};\n\nconsole.log(obj[key1]); // value 1\nconsole.log(obj[key2]); // value 2\n```\n\nIn WeakMaps and WeakSets, symbols are now permissible as keys.\n\n"
  },
  {
    "path": "website/src/content/docs/book/table-of-contents.md",
    "content": "---\ntitle: Table of Contents\nsidebar:\n  order: 4\n  label: 4. Table of Contents\n---\n\n\n<!-- markdownlint-disable MD004 -->\n- The Concise TypeScript Book\n  - Translations\n  - Downloads and website\n  - Table of Contents\n  - Introduction\n  - About the Author\n  - TypeScript Introduction\n    - What is TypeScript?\n    - Why TypeScript?\n    - TypeScript and JavaScript\n    - TypeScript Code Generation\n    - Modern JavaScript Now (Downleveling)\n  - Getting Started With TypeScript\n    - Installation\n    - Configuration\n    - TypeScript Configuration File\n      - target\n      - lib\n      - strict\n      - module\n      - moduleResolution\n      - esModuleInterop\n      - jsx\n      - skipLibCheck\n      - files\n      - include\n      - exclude\n    - importHelpers\n    - Migration to TypeScript Advice\n  - Exploring the Type System\n    - The TypeScript Language Service\n    - Structural Typing\n    - TypeScript Fundamental Comparison Rules\n    - Types as Sets\n    - Assign a type: Type Declarations and Type Assertions\n      - Type Declaration\n      - Type Assertion\n      - Ambient Declarations\n    - Property Checking and Excess Property Checking\n    - Weak Types\n    - Strict Object Literal Checking (Freshness)\n    - Type Inference\n    - More Advanced Inferences\n    - Type Widening\n    - Const\n      - Const Modifier on Type Parameters\n      - Const assertion\n    - Explicit Type Annotation\n    - Type Narrowing\n      - Conditions\n      - Throwing or returning\n      - Discriminated Union\n      - User-Defined Type Guards\n  - Primitive Types\n    - string\n    - boolean\n    - number\n    - bigInt\n    - Symbol\n    - null and undefined\n    - Array\n    - any\n  - Type Annotations\n  - Optional Properties\n  - Readonly Properties\n  - Index Signatures\n  - Extending Types\n  - Literal Types\n  - Literal Inference\n  - strictNullChecks\n  - Enums\n    - Numeric enums\n    - String enums\n    - Constant enums\n    - Reverse mapping\n    - Ambient enums\n    - Computed and constant members\n  - Narrowing\n    - typeof type guards\n    - Truthiness narrowing\n    - Equality narrowing\n    - In Operator narrowing\n    - instanceof narrowing\n  - Assignments\n  - Control Flow Analysis\n  - Type Predicates\n  - Discriminated Unions\n  - The never Type\n  - Exhaustiveness checking\n  - Object Types\n  - Tuple Type (Anonymous)\n  - Named Tuple Type (Labeled)\n  - Fixed Length Tuple\n  - Union Type\n  - Intersection Types\n  - Type Indexing\n  - Type from Value\n  - Type from Func Return\n  - Type from Module\n  - Mapped Types\n  - Mapped Type Modifiers\n  - Conditional Types\n  - Distributive Conditional Types\n  - infer Type Inference in Conditional Types\n  - Predefined Conditional Types\n  - Template Union Types\n  - Any type\n  - Unknown type\n  - Void type\n  - Never type\n  - Interface and Type\n    - Common Syntax\n    - Basic Types\n    - Objects and Interfaces\n    - Union and Intersection Types\n  - Built-in Type Primitives\n  - Common Built-in JS Objects\n  - Overloads\n  - Merging and Extension\n  - Differences between Type and Interface\n  - Class\n    - Class Common Syntax\n    - Constructor\n    - Private and Protected Constructors\n    - Access Modifiers\n    - Get and Set\n    - Auto-Accessors in Classes\n    - this\n    - Parameter Properties\n    - Abstract Classes\n    - With Generics\n    - Decorators\n      - Class Decorators\n      - Property Decorator\n      - Method Decorator\n      - Getter and Setter Decorators\n      - Decorator Metadata\n    - Inheritance\n    - Statics\n    - Property initialization\n    - Method overloading\n  - Generics\n    - Generic Type\n    - Generic Classes\n    - Generic Constraints\n    - Generic contextual narrowing\n  - Erased Structural Types\n  - Namespacing\n  - Symbols\n  - Triple-Slash Directives\n  - Type Manipulation\n    - Creating Types from Types\n    - Indexed Access Types\n    - Utility Types\n      - Awaited\\<T\\>\n      - Partial\\<T\\>\n      - Required\\<T\\>\n      - Readonly\\<T\\>\n      - Record\\<K, T\\>\n      - Pick\\<T, K\\>\n      - Omit\\<T, K\\>\n      - Exclude\\<T, U\\>\n      - Extract\\<T, U\\>\n      - NonNullable\\<T\\>\n      - Parameters\\<T\\>\n      - ConstructorParameters\\<T\\>\n      - ReturnType\\<T\\>\n      - InstanceType\\<T\\>\n      - ThisParameterType\\<T\\>\n      - OmitThisParameter\\<T\\>\n      - ThisType\\<T\\>\n      - Uppercase\\<T\\>\n      - Lowercase\\<T\\>\n      - Capitalize\\<T\\>\n      - Uncapitalize\\<T\\>\n      - NoInfer\\<T\\>\n  - Others\n    - Errors and Exception Handling\n    - Mixin classes\n    - Asynchronous Language Features\n    - Iterators and Generators\n    - TsDocs JSDoc Reference\n    - @types\n    - JSX\n    - ES6 Modules\n    - ES7 Exponentiation Operator\n    - The for-await-of Statement\n    - New target meta-property\n    - Dynamic Import Expressions\n    - \"tsc –watch\"\n    - Non-null Assertion Operator\n    - Defaulted declarations\n    - Optional Chaining\n    - Nullish coalescing operator\n    - Template Literal Types\n    - Function overloading\n    - Recursive Types\n    - Recursive Conditional Types\n    - ECMAScript Module Support in Node\n    - Assertion Functions\n    - Variadic Tuple Types\n    - Boxed types\n    - Covariance and Contravariance in TypeScript\n      - Optional Variance Annotations for Type Parameters\n    - Template String Pattern Index Signatures\n    - The satisfies Operator\n    - Type-Only Imports and Export\n    - using declaration and Explicit Resource Management\n      - await using declaration\n    - Import Attributes\n<!-- markdownlint-enable MD004 -->\n\n"
  },
  {
    "path": "website/src/content/docs/book/template-union-types.md",
    "content": "---\ntitle: Template Union Types\nsidebar:\n  order: 43\n  label: 43. Template Union Types\n---\n\n\nTemplate union types can be used to merge and manipulate text inside the type system for instance:\n\n```typescript\ntype Status = 'active' | 'inactive';\ntype Products = 'p1' | 'p2';\ntype ProductId = `id-${Products}-${Status}`; // \"id-p1-active\" | \"id-p1-inactive\" | \"id-p2-active\" | \"id-p2-inactive\"\n```\n\n"
  },
  {
    "path": "website/src/content/docs/book/the-concise-typescript-book.md",
    "content": "---\ntitle: The Concise TypeScript Book\nsidebar:\n  order: 1\n  label: 1. The Concise TypeScript Book\n---\n\n\nThe Concise TypeScript Book provides a comprehensive and succinct overview of TypeScript's capabilities. It offers clear explanations covering all aspects found in the latest version of the language, from its powerful type system to advanced features. Whether you're a beginner or an experienced developer, this book is an invaluable resource to enhance your understanding and proficiency in TypeScript.\n\nThis book is completely Free and Open Source.\n\nI believe that high-quality technical education should be accessible to everyone, which is why I keep this book free and open.\n\nIf the book helped you squash a bug, understand a tricky concept, or advance in your career, please consider supporting my work by paying what you want (suggested price: 15 USD) or sponsoring a coffee. Your support helps me keep the content up to date and expand it with new examples and deeper explanations.\n\n[![Buy Me a Coffee](https://img.shields.io/badge/buy_me_a_coffee-FFDD00?style=for-the-badge&logo=buy-me-a-coffee&logoColor=black)](https://www.buymeacoffee.com/simonepoggiali)\n\n[![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.com/donate/?business=QW82ZS956XLFY&no_recurring=0&currency_code=EUR)\n\n"
  },
  {
    "path": "website/src/content/docs/book/the-never-type.md",
    "content": "---\ntitle: The never Type\nsidebar:\n  order: 25\n  label: 25. The never Type\n---\n\n\nWhen a variable is narrowed to a type that cannot contain any values, the TypeScript compiler will infer that the variable must be of the `never` type. This is because The never Type represents a value that can never be produced.\n\n```typescript\nconst printValue = (val: string | number) => {\n    if (typeof val === 'string') {\n        console.log(val.toUpperCase());\n    } else if (typeof val === 'number') {\n        console.log(val.toFixed(2));\n    } else {\n        // val has type never here because it can never be anything other than a string or a number\n        const neverVal: never = val;\n        console.log(`Unexpected value: ${neverVal}`);\n    }\n};\n```\n\n"
  },
  {
    "path": "website/src/content/docs/book/translations.md",
    "content": "---\ntitle: Translations\nsidebar:\n  order: 2\n  label: 2. Translations\n---\n\n\nThis book has been translated into several language versions, including:\n\n[Chinese](https://github.com/gibbok/typescript-book/blob/main/README-zh_CN.md)\n\n[Italian](https://github.com/gibbok/typescript-book/blob/main/README-it_IT.md)\n\n[Portuguese (Brazil)](https://github.com/gibbok/typescript-book/blob/main/README-pt_BR.md)\n\n[Swedish](https://github.com/gibbok/typescript-book/blob/main/README-sv_SE.md)\n\n"
  },
  {
    "path": "website/src/content/docs/book/triple-slash-directives.md",
    "content": "---\ntitle: Triple-Slash Directives\nsidebar:\n  order: 59\n  label: 59. Triple-Slash Directives\n---\n\n\nTriple-slash directives are special comments that provide instructions to the compiler about how to process a file. These directives begin with three consecutive slashes (`///`) and are typically placed at the top of a TypeScript file and have no effects on the runtime behavior.\n\nTriple-slash directives are used to reference external dependencies, specify module loading behavior, enable/disable certain compiler features, and more. Few examples:\n\nReferencing a declaration file:\n\n<!-- skip -->\n```typescript\n/// <reference path=\"path/to/declaration/file.d.ts\" />\n```\n\nIndicate the module format:\n\n<!-- skip -->\n```typescript\n/// <amd|commonjs|system|umd|es6|es2015|none>\n```\n\nEnable compiler options, in the following example strict mode:\n\n<!-- skip -->\n```typescript\n/// <strict|noImplicitAny|noUnusedLocals|noUnusedParameters>\n```\n\n"
  },
  {
    "path": "website/src/content/docs/book/tuple-type-anonymous.md",
    "content": "---\ntitle: Tuple Type (Anonymous)\nsidebar:\n  order: 28\n  label: 28. Tuple Type (Anonymous)\n---\n\n\nA Tuple Type is a type that represents an array with a fixed number of elements and their corresponding types. A tuple type enforces a specific number of elements and their respective types in a fixed order. Tuple types are useful when you want to represent a collection of values with specific types, where the position of each element in the array has a specific meaning.\n\n```typescript\ntype Point = [number, number];\n```\n\n"
  },
  {
    "path": "website/src/content/docs/book/type-annotations.md",
    "content": "---\ntitle: Type Annotations\nsidebar:\n  order: 11\n  label: 11. Type Annotations\n---\n\n\nOn variables declared using `var`, `let` and `const`, it is possible to optionally add a type:\n\n```typescript\nconst x: number = 1;\n```\n\nTypeScript does a good job of inferring types, especially when simple one, so these declarations in most cases are not necessary.\n\nOn functions is possible to add type annotations to parameters:\n\n```typescript\nfunction sum(a: number, b: number) {\n    return a + b;\n}\n```\n\nThe following is an example using a anonymous functions (so called lambda function):\n\n```typescript\nconst sum = (a: number, b: number) => a + b;\n```\n\nThese annotation can be avoided when a default value for a parameter is present:\n\n```typescript\nconst sum = (a = 10, b: number) => a + b;\n```\n\nReturn type annotations can be added to functions:\n\n```typescript\nconst sum = (a = 10, b: number): number => a + b;\n```\n\nThis is useful especially for  more complex functions as writing expliciting the return type before an implementation can help better think about the function.\n\nGenerally consider annotating type signatures but not the body local variables and add types always to object literals.\n\n"
  },
  {
    "path": "website/src/content/docs/book/type-from-func-return.md",
    "content": "---\ntitle: Type from Func Return\nsidebar:\n  order: 35\n  label: 35. Type from Func Return\n---\n\n\nType from Func Return refers to the ability to automatically infer the return type of a function based on its implementation. This allows TypeScript to determine the type of the value returned by the function without explicit type annotations.\n\n```typescript\nconst add = (x: number, y: number) => x + y; // TypeScript can infer that the return type of the function is a number\n```\n\n"
  },
  {
    "path": "website/src/content/docs/book/type-from-module.md",
    "content": "---\ntitle: Type from Module\nsidebar:\n  order: 36\n  label: 36. Type from Module\n---\n\n\nType from Module refers to the ability to use a module's exported values to automatically infer their types. When a module exports a value with a specific type, TypeScript can use that information to automatically infer the type of that value when it is imported into another module.\n\n<!-- skip -->\n```typescript\n// calc.ts\nexport const add = (x: number, y: number) => x + y;\n// index.ts\nimport { add } from 'calc';\nconst r = add(1, 2); // r is number\n```\n\n"
  },
  {
    "path": "website/src/content/docs/book/type-from-value.md",
    "content": "---\ntitle: Type from Value\nsidebar:\n  order: 34\n  label: 34. Type from Value\n---\n\n\nType from Value in TypeScript refers to the automatic inference of a type from a value or expression through type inference.\n\n```typescript\nconst x = 'x'; // TypeScript infers 'x' as a string literal with 'const' (immutable), but widens it to 'string' with 'let' (reassignable).\n```\n\n"
  },
  {
    "path": "website/src/content/docs/book/type-indexing.md",
    "content": "---\ntitle: Type Indexing\nsidebar:\n  order: 33\n  label: 33. Type Indexing\n---\n\n\nType indexing refers to the ability to define types that can be indexed by a key that is not known in advance, using an index signature to specify the type for properties that are not explicitly declared.\n\n```typescript\ntype Dictionary<T> = {\n    [key: string]: T;\n};\nconst myDict: Dictionary<string> = { a: 'a', b: 'b' };\nconsole.log(myDict['a']); // Returns a\n```\n\n"
  },
  {
    "path": "website/src/content/docs/book/type-manipulation.md",
    "content": "---\ntitle: Type Manipulation\nsidebar:\n  order: 60\n  label: 60. Type Manipulation\n---\n\n\n### Creating Types from Types\n\nIs it possible to create new types composing, manipulating or transforming existing types.\n\nIntersection Types (`&`):\n\nAllow you to combine multiple types into a single  type:\n\n```typescript\ntype A = { foo: number };\ntype B = { bar: string };\ntype C = A & B; // Intersection of A and B\nconst obj: C = { foo: 42, bar: 'hello' };\n```\n\nUnion Types (`|`):\n\nAllow you to define a type that can be one of several types:\n\n```typescript\ntype Result = string | number;\nconst value1: Result = 'hello';\nconst value2: Result = 42;\n```\n\nMapped Types:\n\nAllow you to transform the properties of an existing type to create new type:\n\n```typescript\ntype Mutable<T> = {\n    readonly [P in keyof T]: T[P];\n};\ntype Person = {\n    name: string;\n    age: number;\n};\ntype ImmutablePerson = Mutable<Person>; // Properties become read-only\n```\n\nConditional types:\n\nAllow you to create types based on some conditions:\n\n```typescript\ntype ExtractParam<T> = T extends (param: infer P) => any ? P : never;\ntype MyFunction = (name: string) => number;\ntype ParamType = ExtractParam<MyFunction>; // string\n```\n\n### Indexed Access Types\n\nIn TypeScript is it possible to access and manipulate  the types of properties within another type using an index, `Type[Key]`.\n\n```typescript\ntype Person = {\n    name: string;\n    age: number;\n};\n\ntype AgeType = Person['age']; // number\n```\n\n```typescript\ntype MyTuple = [string, number, boolean];\ntype MyType = MyTuple[2]; // boolean\n```\n\n### Utility Types\n\nSeveral built-in utility types can be used to manipulate types, below a list of the most common used:\n\n#### Awaited\\<T\\>\n\nConstructs a type that recursively unwraps Promise types.\n\n```typescript\ntype A = Awaited<Promise<string>>; // string\n```\n\n#### Partial\\<T\\>\n\nConstructs a type with all properties of T set to optional.\n\n```typescript\ntype Person = {\n    name: string;\n    age: number;\n};\n\ntype A = Partial<Person>; // { name?: string | undefined; age?: number | undefined; }\n```\n\n#### Required\\<T\\>\n\nConstructs a type with all properties of T set to required.\n\n```typescript\ntype Person = {\n    name?: string;\n    age?: number;\n};\n\ntype A = Required<Person>; // { name: string; age: number; }\n```\n\n#### Readonly\\<T\\>\n\nConstructs a type with all properties of T set to readonly.\n\n<!-- skip -->\n```typescript\ntype Person = {\n    name: string;\n    age: number;\n};\n\ntype A = Readonly<Person>;\n\nconst a: A = { name: 'Simon', age: 17 };\na.name = 'John'; // Invalid\n```\n\n#### Record\\<K, T\\>\n\nConstructs a type with a set of properties K of type T.\n\n```typescript\ntype Product = {\n    name: string;\n    price: number;\n};\n\nconst products: Record<string, Product> = {\n    apple: { name: 'Apple', price: 0.5 },\n    banana: { name: 'Banana', price: 0.25 },\n};\n\nconsole.log(products.apple); // { name: 'Apple', price: 0.5 }\n```\n\n#### Pick\\<T, K\\>\n\nConstructs a type by picking the specified properties K from T.\n\n```typescript\ntype Product = {\n    name: string;\n    price: number;\n};\n\ntype Price = Pick<Product, 'price'>; // { price: number; }\n```\n\n#### Omit\\<T, K\\>\n\nConstructs a type by omitting the specified properties K from T.\n\n```typescript\ntype Product = {\n    name: string;\n    price: number;\n};\n\ntype Name = Omit<Product, 'price'>; // { name: string; }\n```\n\n#### Exclude\\<T, U\\>\n\nConstructs a type by excluding all values of type U from T.\n\n```typescript\ntype Union = 'a' | 'b' | 'c';\ntype MyType = Exclude<Union, 'a' | 'c'>; // b\n```\n\n#### Extract\\<T, U\\>\n\nConstructs a type by extracting all values of type U from T.\n\n```typescript\ntype Union = 'a' | 'b' | 'c';\ntype MyType = Extract<Union, 'a' | 'c'>; // a | c\n```\n\n#### NonNullable\\<T\\>\n\nConstructs a type by excluding null and undefined from T.\n\n```typescript\ntype Union = 'a' | null | undefined | 'b';\ntype MyType = NonNullable<Union>; // 'a' | 'b'\n```\n\n#### Parameters\\<T\\>\n\nExtracts the parameter types of a function type T.\n\n```typescript\ntype Func = (a: string, b: number) => void;\ntype MyType = Parameters<Func>; // [a: string, b: number]\n```\n\n#### ConstructorParameters\\<T\\>\n\nExtracts the parameter types of a constructor function type T.\n\n```typescript\nclass Person {\n    constructor(\n        public name: string,\n        public age: number\n    ) {}\n}\ntype PersonConstructorParams = ConstructorParameters<typeof Person>; // [name: string, age: number]\nconst params: PersonConstructorParams = ['John', 30];\nconst person = new Person(...params);\nconsole.log(person); // Person { name: 'John', age: 30 }\n```\n\n#### ReturnType\\<T\\>\n\nExtracts the return type of a function type T.\n\n```typescript\ntype Func = (name: string) => number;\ntype MyType = ReturnType<Func>; // number\n```\n\n#### InstanceType\\<T\\>\n\nExtracts the instance type of a class type T.\n\n```typescript\nclass Person {\n    name: string;\n\n    constructor(name: string) {\n        this.name = name;\n    }\n\n    sayHello() {\n        console.log(`Hello, my name is ${this.name}!`);\n    }\n}\n\ntype PersonInstance = InstanceType<typeof Person>;\n\nconst person: PersonInstance = new Person('John');\n\nperson.sayHello(); // Hello, my name is John!\n```\n\n#### ThisParameterType\\<T\\>\n\nExtracts the type of 'this' parameter from a function type T.\n\n```typescript\ninterface Person {\n    name: string;\n    greet(this: Person): void;\n}\ntype PersonThisType = ThisParameterType<Person['greet']>; // Person\n```\n\n#### OmitThisParameter\\<T\\>\n\nRemoves the 'this' parameter from a function type T.\n\n```typescript\nfunction capitalize(this: String) {\n    return this[0].toUpperCase + this.substring(1).toLowerCase();\n}\n\ntype CapitalizeType = OmitThisParameter<typeof capitalize>; // () => string\n```\n\n#### ThisType\\<T\\>\n\nServers as a market for a contextual `this` type.\n\n<!-- skip -->\n```typescript\ntype Logger = {\n    log: (error: string) => void;\n};\n\nlet helperFunctions: { [name: string]: Function } & ThisType<Logger> = {\n    hello: function () {\n        this.log('some error'); // Valid as \"log\" is a part of \"this\".\n        this.update(); // Invalid\n    },\n};\n```\n\n#### Uppercase\\<T\\>\n\nMake uppercase the name of the input type T.\n\n```typescript\ntype MyType = Uppercase<'abc'>; // \"ABC\"\n```\n\n#### Lowercase\\<T\\>\n\nMake lowercase the name of the input type T.\n\n```typescript\ntype MyType = Lowercase<'ABC'>; // \"abc\"\n```\n\n#### Capitalize\\<T\\>\n\nCapitalize the name of the input type T.\n\n```typescript\ntype MyType = Capitalize<'abc'>; // \"Abc\"\n```\n\n#### Uncapitalize\\<T\\>\n\nUncapitalize the name of the input type T.\n\n```typescript\ntype MyType = Uncapitalize<'Abc'>; // \"abc\"\n```\n\n#### NoInfer\\<T\\>\n\nNoInfer is a utility type designed to block the automatic inference of types within the scope of a generic function.\n\nExample:\n\n```typescript\n// Automatic inference of types within the scope of a generic function.\nfunction fn<T extends string>(x: T[], y: T) {\n    return x.concat(y);\n}\nconst r = fn(['a', 'b'], 'c'); // Type here is (\"a\" | \"b\" | \"c\")[]\n```\n\nWith NoInfer:\n\n<!-- skip -->\n```typescript\n// Example function that uses NoInfer to prevent type inference\nfunction fn2<T extends string>(x: T[], y: NoInfer<T>) {\n    return x.concat(y);\n}\n\nconst r2 = fn2(['a', 'b'], 'c'); // Error: Type Argument of type '\"c\"' is not assignable to parameter of type '\"a\" | \"b\"'.\n```\n\n"
  },
  {
    "path": "website/src/content/docs/book/type-predicates.md",
    "content": "---\ntitle: Type Predicates\nsidebar:\n  order: 23\n  label: 23. Type Predicates\n---\n\n\nType Predicates in TypeScript are functions that return a boolean value and are used to narrow the type of a variable to a more specific type.\n\n```typescript\nconst isString = (value: unknown): value is string => typeof value === 'string';\n\nconst foo = (bar: unknown) => {\n    if (isString(bar)) {\n        console.log(bar.toUpperCase());\n    } else {\n        console.log('not a string');\n    }\n};\n```\n\n"
  },
  {
    "path": "website/src/content/docs/book/typescript-introduction.md",
    "content": "---\ntitle: TypeScript Introduction\nsidebar:\n  order: 7\n  label: 7. TypeScript Introduction\n---\n\n\n### What is TypeScript?\n\nTypeScript is a strongly typed programming language that builds on JavaScript. It was originally designed by Anders Hejlsberg in 2012 and is currently developed and maintained by Microsoft as an open source project.\n\nTypeScript compiles to JavaScript and can be executed in any JavaScript runtime (e.g., a browser or Node.js on a server).\n\nIt supports multiple programming paradigms such as functional, generic, imperative, and object-oriented programming, and is a compiled (transpiled) language that is converted into JavaScript before execution.\n\n### Why TypeScript?\n\nTypeScript is a strongly typed language that helps prevent common programming mistakes and avoid certain kinds of run-time errors before the program is executed.\n\nA strongly typed language allows the developer to specify various program constraints and behaviors in the data type definitions, facilitating the ability to verify the correctness of the software and prevent defects. This is especially valuable in large-scale applications.\n\nSome of the benefits of TypeScript:\n\n* Static typing, optionally strongly typed\n* Type Inference\n* Access to ES6 and ES7 features\n* Cross-Platform and Cross-browser Compatibility\n* Tooling support with IntelliSense\n\n### TypeScript and JavaScript\n\nTypeScript is written in `.ts` or `.tsx` files, while JavaScript files are written in `.js` or `.jsx`.\n\nFiles with the extension `.tsx` or `.jsx` can contain JavaScript Syntax Extension JSX, which is used in React for UI development.\n\nTypeScript is a typed superset of JavaScript (ECMAScript 2015) in terms of syntax. All JavaScript code is valid TypeScript code, but the reverse is not always true.\n\nFor instance, consider a function in a JavaScript file with the `.js` extension, such as the following:\n\n<!-- skip -->\n```typescript\nconst sum = (a, b) => a + b;\n```\n\nThe function can be converted and used in TypeScript by changing the file extension to `.ts`. However, if the same function is annotated with TypeScript types, it cannot be executed in any JavaScript runtime without compilation. The following TypeScript code will produce a syntax error if it is not compiled:\n\n<!-- skip -->\n```typescript\nconst sum = (a: number, b: number): number => a + b;\n```\n\nTypeScript was designed to detect possible exceptions that can occur at runtime during compilation time by having the developer define the intent with type annotations. In addition, TypeScript can also catch issues if no type annotation is provided. For instance, the following code snippet does not specify any TypeScript types:\n\n<!-- skip -->\n```typescript\nconst items = [{ x: 1 }, { x: 2 }];\nconst result = items.filter(item => item.y);\n```\n\nIn this case, TypeScript detects an error and reports:\n\n```text\nProperty 'y' does not exist on type '{ x: number; }'.\n```\n\nTypeScript's type system is largely influenced by the runtime behavior of JavaScript. For example, the addition operator (+), which in JavaScript can either perform string concatenation or numeric addition, is modeled in the same way in TypeScript:\n\n```typescript\nconst result = '1' + 1; // Result is of type string\n```\n\nThe team behind TypeScript has made a deliberate decision to flag unusual usage of JavaScript as errors. For instance, consider the following valid JavaScript code:\n\n<!-- skip -->\n```typescript\nconst result = 1 + true; // In JavaScript, the result is equal 2\n```\n\nHowever, TypeScript throws an error:\n\n```text\nOperator '+' cannot be applied to types 'number' and 'boolean'.\n```\n\nThis error occurs because TypeScript strictly enforces type compatibility, and in this case, it identifies an invalid operation between a number and a boolean.\n\n### TypeScript Code Generation\n\nThe TypeScript compiler has two main responsibilities: checking for type errors and compiling to JavaScript. These two processes are independent of each other. Types do not affect the execution of the code in a JavaScript runtime, as they are completely erased during compilation. TypeScript can still output JavaScript even in the presence of type errors.\nHere is an example of TypeScript code with a type error:\n\n<!-- skip -->\n```typescript\nconst add = (a: number, b: number): number => a + b;\nconst result = add('x', 'y'); // Argument of type 'string' is not assignable to parameter of type 'number'.\n```\n\nHowever, it can still produce executable JavaScript output:\n\n<!-- skip -->\n```typescript\n'use strict';\nconst add = (a, b) => a + b;\nconst result = add('x', 'y'); // xy\n```\n\nIt is not possible to check TypeScript types at runtime. For example:\n\n<!-- skip -->\n```typescript\ninterface Animal {\n    name: string;\n}\ninterface Dog extends Animal {\n    bark: () => void;\n}\ninterface Cat extends Animal {\n    meow: () => void;\n}\nconst makeNoise = (animal: Animal) => {\n    if (animal instanceof Dog) {\n        // 'Dog' only refers to a type, but is being used as a value here.\n        // ...\n    }\n};\n```\n\nAs the types are erased after compilation, there is no way to run this code in JavaScript. To recognize types at runtime, we need to use another mechanism. TypeScript provides several options, with a common one being \"tagged union\". For example:\n\n```typescript\ninterface Dog {\n    kind: 'dog'; // Tagged union\n    bark: () => void;\n}\ninterface Cat {\n    kind: 'cat'; // Tagged union\n    meow: () => void;\n}\ntype Animal = Dog | Cat;\n\nconst makeNoise = (animal: Animal) => {\n    if (animal.kind === 'dog') {\n        animal.bark();\n    } else {\n        animal.meow();\n    }\n};\n\nconst dog: Dog = {\n    kind: 'dog',\n    bark: () => console.log('bark'),\n};\nmakeNoise(dog);\n```\n\nThe property \"kind\" is a value that can be used at runtime to distinguish between objects in JavaScript.\n\nIt is also possible for a value at runtime to have a type different from the one declared in the type declaration. For instance, if the developer has misinterpreted an API type and annotated it incorrectly.\n\nTypeScript is a superset of JavaScript, so the \"class\" keyword can be used as a type and value at runtime.\n\n```typescript\nclass Animal {\n    constructor(public name: string) {}\n}\nclass Dog extends Animal {\n    constructor(\n        public name: string,\n        public bark: () => void\n    ) {\n        super(name);\n    }\n}\nclass Cat extends Animal {\n    constructor(\n        public name: string,\n        public meow: () => void\n    ) {\n        super(name);\n    }\n}\ntype Mammal = Dog | Cat;\n\nconst makeNoise = (mammal: Mammal) => {\n    if (mammal instanceof Dog) {\n        mammal.bark();\n    } else {\n        mammal.meow();\n    }\n};\n\nconst dog = new Dog('Fido', () => console.log('bark'));\nmakeNoise(dog);\n```\n\nIn JavaScript, a \"class\" has a \"prototype\" property, and the \"instanceof\" operator can be used to test if the prototype property of a constructor appears anywhere in the prototype chain of an object.\n\nTypeScript has no effect on runtime performance, as all types will be erased. However, TypeScript does introduce some build time overhead.\n\n### Modern JavaScript Now (Downleveling)\n\nTypeScript can compile code to any released version of JavaScript since ECMAScript 3 (1999). This means that TypeScript can transpile code from the latest JavaScript features to older versions, a process known as Downleveling. This allows the usage of modern JavaScript while maintaining maximum compatibility with older runtime environments.\n\nIt's important to note that during transpilation to an older version of JavaScript, TypeScript may generate code that could incur a performance overhead compared to native implementations.\n\nHere are some of the modern JavaScript features that can be used in TypeScript:\n\n* ECMAScript modules instead of AMD-style \"define\" callbacks or CommonJS \"require\" statements.\n* Classes instead of prototypes.\n* Variables declaration using \"let\" or \"const\" instead of \"var\".\n* \"for-of\" loop or \".forEach\" instead of the traditional \"for\" loop.\n* Arrow functions instead of function expressions.\n* Destructuring assignment.\n* Shorthand property/method names and computed property names.\n* Default function parameters.\n\nBy leveraging these modern JavaScript features, developers can write more expressive and concise code in TypeScript.\n\n"
  },
  {
    "path": "website/src/content/docs/book/union-type.md",
    "content": "---\ntitle: Union Type\nsidebar:\n  order: 31\n  label: 31. Union Type\n---\n\n\nA Union Type is a type that represents a value that can be one of several types. Union Types are denoted using the `|` symbol between each possible type.\n\n```typescript\nlet x: string | number;\nx = 'hello'; // Valid\nx = 123; // Valid\n```\n\n"
  },
  {
    "path": "website/src/content/docs/book/unknown-type.md",
    "content": "---\ntitle: Unknown type\nsidebar:\n  order: 45\n  label: 45. Unknown type\n---\n\n\nIn TypeScript, the `unknown` type represents a value that is of an unknown type. Unlike `any` type, which allows for any type of value, `unknown` requires a type check or assertion before it can be used in a specific way so no operations are permitted on an `unknown` without first asserting or narrowing to a more specific type.\n\nThe `unknown` type is only assignable to any type and the `unknown` type itself, it is a type-safe alternative to `any`.\n\n<!-- skip -->\n```typescript\nlet value: unknown;\n\nlet value1: unknown = value; // Valid\nlet value2: any = value; // Valid\nlet value3: boolean = value; // Invalid\nlet value4: number = value; // Invalid\n```\n\n```typescript\nconst add = (a: unknown, b: unknown): number | undefined =>\n    typeof a === 'number' && typeof b === 'number' ? a + b : undefined;\nconsole.log(add(1, 2)); // 3\nconsole.log(add('x', 2)); // undefined\n```\n\n"
  },
  {
    "path": "website/src/content/docs/book/void-type.md",
    "content": "---\ntitle: Void type\nsidebar:\n  order: 46\n  label: 46. Void type\n---\n\n\nThe `void` type is used to indicate that a function does not return a value.\n\n```typescript\nconst sayHello = (): void => {\n    console.log('Hello!');\n};\n```\n\n"
  },
  {
    "path": "website/src/content/docs/index.mdx",
    "content": "---\ntitle: TypeScript Book\ndescription: The Concise TypeScript Book\ntemplate: splash\nhero:\n    tagline: The Concise TypeScript Book provides a comprehensive and succinct overview of TypeScript's capabilities. It offers clear explanations covering all aspects found in the latest version of the language, from its powerful type system to advanced features. Whether you're a beginner or an experienced developer, this book is an invaluable resource to enhance your understanding and proficiency in TypeScript.<br/><br/>This book is completely Free and Open Source.\n    actions:\n        - text: Read now!\n          link: /typescript-book/book/the-concise-typescript-book/\n          icon: right-arrow\n          variant: primary\n        - text: GitHub\n          link: https://github.com/gibbok/typescript-book\n          icon: github\n          variant: secondary\n        - text: X.com\n          link: https://twitter.com/gibbok_coding\n          icon: x.com\n          variant: secondary\n---\n"
  },
  {
    "path": "website/src/content/docs/it-it/book/about-the-author.md",
    "content": "---\ntitle: Informazioni sull'autore\nsidebar:\n  order: 6\n  label: 6. Informazioni sull'autore\n---\n\n\nSimone Poggiali è uno Staff Engineer esperto, con una passione per la scrittura di codice di livello professionale fin dagli anni '90. Nel corso della sua carriera internazionale, ha contribuito a numerosi progetti per un'ampia gamma di clienti, dalle startup alle grandi organizzazioni. Aziende di spicco come HelloFresh, Siemens, O2, Leroy Merlin e Snowplow hanno beneficiato della sua competenza e dedizione.\n\nÈ possibile contattare Simone Poggiali sulle seguenti piattaforme:\n\n* LinkedIn: [https://www.linkedin.com/in/simone-poggiali](https://www.linkedin.com/in/simone-poggiali)\n* GitHub: [https://github.com/gibbok](https://github.com/gibbok)\n* X.com: [https://x.com/gibbok_coding](https://x.com/gibbok_coding)\n* Email: gibbok.coding📧gmail.com\n\nElenco completo dei collaboratori: [https://github.com/gibbok/typescript-book/graphs/contributors](https://github.com/gibbok/typescript-book/graphs/contributors)\n\n"
  },
  {
    "path": "website/src/content/docs/it-it/book/any-type.md",
    "content": "---\ntitle: Tipo Any\nsidebar:\n  order: 44\n  label: 44. Tipo Any\n---\n\n\nIl tipo `any` è un tipo speciale (supertipo universale) che può essere utilizzato per rappresentare qualsiasi tipo di valore (primitive, oggetti, array, funzioni, errori, simboli). Viene spesso utilizzato in situazioni in cui il tipo di un valore non è noto in fase di compilazione, o quando si lavora con valori provenienti da API o librerie esterne che non dispongono di tipi TypeScript.\n\nUtilizzando il tipo `any`, si indica al compilatore TypeScript che i valori devono essere rappresentati senza alcuna limitazione. Per massimizzare la sicurezza dei tipi nel codice, tieni presente quanto segue:\n\n* Limitare l'utilizzo di `any` a casi specifici in cui il tipo è realmente sconosciuto.\n* Non restituire `any` da una funzione, poiché ciò indebolisce la sicurezza del tipo nel codice che lo utilizza.\n* Invece di `any`, utilizzare `@ts-ignore` se è necessario silenziare il compilatore.\n\n```typescript\nlet value: any;\nvalue = true; // Valido\nvalue = 7; // Valido\n```\n\n"
  },
  {
    "path": "website/src/content/docs/it-it/book/assignments.md",
    "content": "---\ntitle: Assegnazioni\nsidebar:\n  order: 21\n  label: 21. Assegnazioni\n---\n\n\nIl restringimento TypeScript tramite assegnazioni è un modo per restringere il tipo di una variabile in base al valore assegnato. Quando a una variabile viene assegnato un valore, TypeScript ne deduce il tipo in base al valore assegnato e restringe il tipo della variabile in modo che corrisponda al tipo dedotto.\n\n```typescript\nlet value: string | number;\nvalue = 'hello';\nif (typeof value === 'string') {\n    console.log(value.toUpperCase());\n}\nvalue = 42;\nif (typeof value === 'number') {\n    console.log(value.toFixed(2));\n}\n```\n\n"
  },
  {
    "path": "website/src/content/docs/it-it/book/built-in-type-primitives.md",
    "content": "---\ntitle: Primitive di tipo predefinite\nsidebar:\n  order: 49\n  label: 49. Primitive di tipo predefinite\n---\n\n\nTypeScript dispone di diverse primitive di tipo predefinite che possono essere utilizzate per definire variabili, parametri di funzione e tipi restituiti:\n\n* `number`: rappresenta valori numerici, inclusi numeri interi e numeri in virgola mobile.\n* `string`: rappresenta dati testuali.\n* `boolean`: rappresenta valori logici, che possono essere true o false.\n* `null`: rappresenta l'assenza di un valore.\n* `undefined`: rappresenta un valore che non è stato assegnato o non è stato definito.\n* `symbol`: rappresenta un identificatore univoco. I simboli vengono in genere utilizzati come chiavi per le proprietà degli oggetti.\n* `bigint`: rappresenta numeri interi con precisione arbitraria.\n* `any`: rappresenta un tipo dinamico o sconosciuto. Le variabili di tipo any possono contenere valori di qualsiasi tipo e ignorano il controllo del tipo. \\* `void`: rappresenta l'assenza di qualsiasi tipo. È comunemente usato come tipo di ritorno di funzioni che non restituiscono alcun valore.\n* `never`: rappresenta un tipo per valori che non si verificano mai. È tipicamente usato come tipo di ritorno di funzioni che generano un errore o entrano in un ciclo infinito.\n\n"
  },
  {
    "path": "website/src/content/docs/it-it/book/class.md",
    "content": "---\ntitle: Classe\nsidebar:\n  order: 54\n  label: 54. Classe\n---\n\n\n### Sintassi comune della classe\n\nLa parola chiave `class` viene utilizzata in TypeScript per definire una classe. Di seguito è riportato un esempio:\n\n```typescript\nclass Person {\n    private name: string;\n    private age: number;\n    constructor(name: string, age: number) {\n        this.name = name;\n        this.age = age;\n    }\n    public sayHi(): void {\n        console.log(`Ciao, mi chiamo ${this.name} e ho ${this.age} anni.`);\n    }\n}\n```\n\nLa parola chiave `class` viene utilizzata per definire una classe denominata \"Person\".\n\nLa classe ha due proprietà private: name di tipo `string` ed age di tipo `number`.\n\nIl costruttore viene definito utilizzando la parola chiave `constructor`. Accetta name ed age come parametri e li assegna alle proprietà corrispondenti.\n\nLa classe ha un metodo `public` denominato sayHi che registra un messaggio di saluto.\n\nPer creare un'istanza di una classe in TypeScript, è possibile utilizzare la parola chiave `new` seguita dal nome della classe, seguito da parentesi `()`. Ad esempio:\n\n<!-- skip -->\n```typescript\nconst myObject = new Person('John Doe', 25);\nmyObject.sayHi(); // Output: Ciao, mi chiamo John Doe e ho 25 anni.\n```\n\n### Costruttore\n\nI costruttori sono metodi speciali all'interno di una classe che vengono utilizzati per inizializzare le proprietà dell'oggetto quando viene creata un'istanza della classe.\n\n```typescript\nclass Person {\n    public name: string;\n    public age: number;\n\n    constructor(name: string, age: number) {\n        this.name = name;\n        this.age = age;\n    }\n\n    sayHello() {\n        console.log(`Ciao, mi chiamo ${this.name} e ho ${this.age} anni.`);\n    }\n}\n\nconst john = new Person('Simon', 17);\njohn.sayHello();\n```\n\nÈ possibile sovraccaricare un costruttore utilizzando la seguente sintassi:\n\n```typescript\ntype Sex = 'm' | 'f';\n\nclass Person {\n    name: string;\n    age: number;\n    sex: Sex;\n\n    constructor(name: string, age: number, sex?: Sex);\n    constructor(name: string, age: number, sex: Sex) {\n        this.name = name;\n        this.age = age;\n        this.sex = sex ?? 'm';\n    }\n}\n\nconst p1 = new Person('Simon', 17);\nconst p2 = new Person('Alice', 22, 'f');\n```\n\nIn TypeScript, è possibile definire più overload del costruttore, ma è possibile avere una sola implementazione che deve essere compatibile con tutti gli overload; questo si può ottenere utilizzando un parametro opzionale.\n\n```typescript\nclass Person {\n    name: string;\n    age: number;\n\n    constructor();\n    constructor(name: string);\n    constructor(name: string, age: number);\n    constructor(name?: string, age?: number) {\n        this.name = name ?? 'Sconosciuto';\n        this.age = age ?? 0;\n    }\n\n    displayInfo() {\n        console.log(`Nome: ${this.name}, Età: ${this.age}`);\n    }\n}\n\nconst person1 = new Person();\nperson1.displayInfo(); // Nome: unknown, Età: 0\n\nconst person2 = new Person('John');\nperson2.displayInfo(); // Nome: John, Età: 0\n\nconst person3 = new Person('Jane', 25);\nperson3.displayInfo(); // Nome: Jane, Età: 25\n```\n\n### Costruttori privati ​​e protetti\n\nIn TypeScript, i costruttori possono essere contrassegnati come privati ​​o protetti, il che ne limita l'accessibilità e l'utilizzo.\n\nCostruttori privati:\npossono essere chiamati solo all'interno della classe stessa. I costruttori privati ​​vengono spesso utilizzati in scenari in cui si desidera applicare un pattern singleton o limitare la creazione di istanze a un metodo factory all'interno della classe.\n\nCostruttori protetti:\nI costruttori protetti sono utili quando si desidera creare una classe base che non deve essere istanziata direttamente, ma può essere estesa tramite sottoclassi.\n\n```typescript\nclass BaseClass {\n    protected constructor() {}\n}\n\nclass DerivedClass extends BaseClass {\n    private value: number;\n\n    constructor(value: number) {\n        super();\n        this.value = value;\n    }\n}\n\n// Il tentativo di istanziare direttamente la classe base genererà un errore.\n// const baseObj = new BaseClass(); // Errore: il costruttore della classe 'BaseClass' è protetto.\n\n// Crea un'istanza della classe derivata\nconst derivedObj = new DerivedClass(10);\n```\n\n### Modificatori di accesso\n\nI modificatori di accesso `private`, `protected` e `public` vengono utilizzati per controllare la visibilità e l'accessibilità dei membri della classe, come proprietà e metodi, nelle classi TypeScript. Questi modificatori sono essenziali per applicare l'incapsulamento e stabilire limiti per l'accesso e la modifica dello stato interno di una classe.\n\nIl modificatore `private` limita l'accesso al membro della classe solo all'interno della classe contenitore.\n\nIl modificatore `protected` consente l'accesso al membro della classe all'interno della classe contenitore e delle sue classi derivate.\n\nIl modificatore `public` fornisce accesso illimitato al membro della classe, consentendone l'accesso da qualsiasi luogo.\n\n### Get e Set\n\nGetter e setter sono metodi speciali che consentono di definire un comportamento personalizzato di accesso e modifica per le proprietà della classe. Consentono di incapsulare lo stato interno di un oggetto e di fornire logica aggiuntiva durante l'ottenimento o l'impostazione dei valori delle proprietà.\nIn TypeScript, getter e setter sono definiti utilizzando rispettivamente le parole chiave `get` e `set`. Ecco un esempio:\n\n```typescript\nclass MyClass {\n    private _myProperty: string;\n\n    constructor(value: string) {\n        this._myProperty = value;\n    }\n    get myProperty(): string {\n        return this._myProperty;\n    }\n    set myProperty(value: string) {\n        this._myProperty = value;\n    }\n}\n```\n\n### Accessori automatici nelle classi\n\nTypeScript versione 4.9 aggiunge il supporto per auto-accessor, una funzionalità ECMAScript di prossima uscita. Assomigliano alle proprietà di classe, ma sono dichiarate con la parola chiave \"accessor\".\n\n```typescript\nclass Animal {\n    accessor name: string;\n\n    constructor(name: string) {\n        this.name = name;\n    }\n}\n```\n\nGli auto-accessor vengono \"de-sugared\" in accessor privati ​​`get` e `set`, che operano su una proprietà inaccessibile.\n\n<!-- skip -->\n```typescript\nclass Animal {\n    #__name: string;\n\n    get name() {\n        return this.#__name;\n    }\n    set name(value: string) {\n        this.#__name = name;\n    }\n\n    constructor(name: string) {\n        this.name = name;\n    }\n}\n```\n\n### this\n\nIn TypeScript, la parola chiave `this` si riferisce all'istanza corrente di una classe all'interno dei suoi metodi o costruttori. Permette di accedere e modificare le proprietà e i metodi della classe. dall'interno del proprio ambito.\nFornisce un modo per accedere e manipolare lo stato interno di un oggetto all'interno dei propri metodi.\n\n```typescript\nclass Person {\n    private name: string;\n    constructor(name: string) {\n        this.name = name;\n    }\n    public introduce(): void {\n        console.log(`Ciao, mi chiamo ${this.name}.`);\n    }\n}\n\nconst person1 = new Person('Alice');\nperson1.introduce(); // Ciao, mi chiamo Alice.\n```\n\n### Proprietà dei parametri\n\nLe proprietà dei parametri consentono di dichiarare e inizializzare le proprietà della classe direttamente all'interno dei parametri del costruttore, evitando codice boilerplate, ad esempio:\n\n```typescript\nclass Person {\n    constructor(\n        private name: string,\n        public age: number\n    ) {\n        // Le parole chiave \"private\" e \"public\" nel costruttore\n        // dichiarano e inizializzano automaticamente le proprietà della classe corrispondenti.\n    }\n    public introduce(): void {\n        console.log(`Ciao, mi chiamo ${this.name} e ho ${this.age} anni.`);\n    }\n}\nconst person = new Person('Alice', 25);\nperson.introduce();\n```\n\n### Classi astratte\n\nLe classi astratte sono utilizzate in TypeScript principalmente per l'ereditarietà, poiché forniscono un modo per definire proprietà e metodi comuni che possono essere ereditati dalle sottoclassi.\nQuesto è utile quando si desidera definire un comportamento comune e imporre alle sottoclassi di implementare determinati metodi. Forniscono un modo per creare una gerarchia di classi in cui la classe base astratta fornisce un'interfaccia condivisa e funzionalità comuni per le sottoclassi.\n\n```typescript\nabstract class Animal {\n    protected name: string;\n\n    constructor(name: string) {\n        this.name = name;\n    }\n\n    abstract makeSound(): void;\n}\n\nclass Cat extends Animal {\n    makeSound(): void {\n        console.log(`${this.name} miagola.`);\n    }\n}\n\nconst cat = new Cat('Whiskers');\ncat.makeSound(); // Output: Whiskers miagola.\n```\n\n### Con i generici\n\nLe classi con i generici consentono di definire classi riutilizzabili che possono funzionare con tipi diversi.\n\n```typescript\nclass Container<T> {\n    private item: T;\n\n    constructor(item: T) {\n        this.item = item;\n    }\n\n    getItem(): T {\n        return this.item;\n    }\n\n    setItem(item: T): void {\n        this.item = item;\n    }\n}\n\nconst container1 = new Container<number>(42);\nconsole.log(container1.getItem()); // 42\n\nconst container2 = new Container<string>('Hello');\ncontainer2.setItem('World');\nconsole.log(container2.getItem()); // Mondo\n```\n\n### Decoratori\n\nI decoratori forniscono un meccanismo per aggiungere metadati, modificare il comportamento, convalidare o estendere la funzionalità dell'elemento di destinazione. Sono funzioni che vengono eseguite in fase di esecuzione. È possibile applicare più decoratori a una dichiarazione.\n\nI decoratori sono funzionalità sperimentali e gli esempi seguenti sono compatibili solo con TypeScript versione 5 o successive che utilizzano ES6.\n\nPer le versioni di TypeScript precedenti alla 5, dovrebbero essere abilitati utilizzando la proprietà `experimentalDecorators` nel file `tsconfig.json` o utilizzando `--experimentalDecorators` nella riga di comando (ma l'esempio seguente non funzionerà).\n\nAlcuni dei casi d'uso comuni per i decoratori includono:\n\n* Monitoraggio delle modifiche delle proprietà.\n* Monitoraggio delle chiamate ai metodi.\n* Aggiunta di proprietà o metodi aggiuntivi.\n* Validazione in fase di esecuzione.\n* Serializzazione e deserializzazione automatica.\n* Registrazione.\n* Autorizzazione e autenticazione.\n* Protezione dagli errori.\n\nNota: i decoratori per la versione 5 non consentono parametri di decorazione.\n\nTipi di decoratori:\n\n#### Decoratori di classe\n\nI decoratori di classe sono utili per estendere una classe esistente, ad esempio aggiungendo proprietà o metodi o raccogliendo istanze di una classe. Nell'esempio seguente, aggiungiamo un metodo `toString` che converte la classe in una rappresentazione in formato stringa.\n\n```typescript\ntype Constructor<T = {}> = new (...args: any[]) => T;\n\nfunction toString<Class extends Constructor>(\n    Value: Class,\n    context: ClassDecoratorContext<Class>\n) {\n    return class extends Value {\n        constructor(...args: any[]) {\n            super(...args);\n            console.log(JSON.stringify(this));\n            console.log(JSON.stringify(context));\n        }\n    };\n}\n\n@toString\nclass Person {\n    name: string;\n\n    constructor(name: string) {\n        this.name = name;\n    }\n\n    greet() {\n        return 'Ciao,' + this.name;\n    }\n}\nconst person = new Person('Simon');\n/* Log:\n{\"name\":\"Simon\"}\n{\"kind\":\"class\",\"name\":\"Person\"}\n*/\n```\n\n#### Decoratore di proprietà\n\nI decoratori di proprietà sono utili per modificare il comportamento di una proprietà, ad esempio cambiando i valori di inizializzazione. Nel codice seguente, abbiamo uno script che imposta una proprietà in modo che sia sempre in maiuscolo:\n\n```typescript\nfunction upperCase<T>(\n    target: undefined,\n    context: ClassFieldDecoratorContext<T, string>\n) {\n    return function (this: T, value: string) {\n        return value.toUpperCase();\n    };\n}\n\nclass MyClass {\n    @upperCase\n    prop1 = 'hello!';\n}\n\nconsole.log(new MyClass().prop1); // Log: HELLO!\n```\n\n#### Decoratore di metodo\n\nI decoratori di metodo consentono di modificare o migliorare il comportamento dei metodi. Di seguito è riportato un esempio di un semplice logger:\n\n```typescript\nfunction log<This, Args extends any[], Return>(\n    target: (this: This, ...args: Args) => Return,\n    context: ClassMethodDecoratorContext<\n        This,\n        (this: This, ...args: Args) => Return\n    >\n) {\n    const methodName = String(context.name);\n\n    function replacementMethod(this: This, ...args: Args): Return {\n        console.log(`LOG: Accesso al metodo '${methodName}'.`);\n        const result = target.call(this, ...args);\n        console.log(`LOG: Uscita dal metodo '${methodName}'.`);\n        return result;\n    }\n\n    return replacementMethod;\n}\n\nclass MyClass {\n    @log\n    sayHello() {\n        console.log('Ciao!');\n    }\n}\n\nnew MyClass().sayHello();\n```\n\nRegistra:\n\n```shell\nLOG: Accesso al metodo 'sayHello'.\nCiao!\nLOG: Uscita dal metodo 'sayHello'.\n```\n\n#### Decoratori Getter e Setter\n\nI decoratori Getter e Setter consentono di modificare o migliorare il comportamento degli accessor di classe. Sono utili, ad esempio, per convalidare le assegnazioni di proprietà. Ecco un semplice esempio di decoratore getter:\n\n```typescript\nfunction range<This, Return extends number>(min: number, max: number) {\n    return function (\n        target: (this: This) => Return,\n        context: ClassGetterDecoratorContext<This, Return>\n    ) {\n        return function (this: This): Return {\n            const value = target.call(this);\n            if (value < min || value > max) {\n                throw 'Invalid';\n            }\n            Object.defineProperty(this, context.name, {\n                value,\n                enumerable: true,\n            });\n            return value;\n        };\n    };\n}\n\nclass MyClass {\n    private _value = 0;\n\n    constructor(value: number) {\n        this._value = value;\n    }\n    @range(1, 100)\n    get getValue(): number {\n        return this._value;\n    }\n}\n\nconst obj = new MyClass(10);\nconsole.log(obj.getValue); // Valido: 10\n\nconst obj2 = new MyClass(999);\nconsole.log(obj2.getValue); // Throw: Invalid!\n```\n\n#### Metadati del decoratore\n\nI metadati del decoratore semplificano il processo per i decoratori di applicare e utilizzare i metadati in qualsiasi classe. Possono accedere a una nuova proprietà metadati sull'oggetto contesto, che può fungere da chiave sia per le primitive che per gli oggetti.\nLe informazioni sui metadati sono accessibili sulla classe tramite `Symbol.metadata`.\n\nI metadati possono essere utilizzati per vari scopi, come il debug, la serializzazione o l'iniezione di dipendenze con i decoratori.\n\n```typescript\n//@ts-ignore\nSymbol.metadata ??= Symbol('Symbol.metadata'); // Simple polyfill\n\ntype Context =\n    | ClassFieldDecoratorContext\n    | ClassAccessorDecoratorContext\n    | ClassMethodDecoratorContext; // Il contesto contiene la proprietà metadati: DecoratorMetadata\n\nfunction setMetadata(_target: any, context: Context) {\n    // Imposta l'oggetto metadati con un valore primitivo\n    context.metadata[context.name] = true;\n}\n\nclass MyClass {\n    @setMetadata\n    a = 123;\n\n    @setMetadata\n    accessor b = 'b';\n\n    @setMetadata\n    fn() {}\n}\n\nconst metadata = MyClass[Symbol.metadata]; // Ottieni informazioni sui metadati\n\nconsole.log(JSON.stringify(metadata)); // {\"bar\":true,\"baz\":true,\"foo\":true}\n```\n\n### Ereditarietà\n\nL'ereditarietà si riferisce al meccanismo mediante il quale una classe può ereditare proprietà e metodi da un'altra classe, nota come classe base o superclasse. La classe derivata, chiamata anche classe figlia o sottoclasse, può estendere e specializzare le funzionalità della classe base aggiungendo nuove proprietà e metodi o sovrascrivendo quelli esistenti.\n\n```typescript\nclass Animal {\n    name: string;\n\n    constructor(name: string) {\n        this.name = name;\n    }\n\n    speak(): void {\n        console.log(\"L'animale emette un suono\");\n    }\n}\n\nclass Dog extends Animal {\n    breed: string;\n\n    constructor(name: string, breed: string) {\n        super(name);\n        this.breed = breed;\n    }\n\n    speak(): void {\n        console.log('Woof! Woof!');\n    }\n}\n\n// Crea un'istanza della classe base\nconst animal = new Animal('Animale generico');\nanimal.speak(); // L'animale emette un suono\n\n// Crea un'istanza della classe derivata\nconst dog = new Dog('Max', 'Labrador');\ndog.speak(); // Woof! Bau!\"\n```\n\nTypeScript non supporta l'ereditarietà multipla nel senso tradizionale, ma consente invece l'ereditarietà da una singola classe base.\nTypeScript supporta più interfacce. Un'interfaccia può definire un contratto per la struttura di un oggetto e una classe può implementare più interfacce. Questo consente a una classe di ereditare comportamento e struttura da più fonti.\n\n```typescript\ninterface Flyable {\n    fly(): void;\n}\n\ninterface Swimmable {\n    swim(): void;\n}\n\nclass FlyingFish implements Flyable, Swimmable {\n    fly() {\n        console.log('Flying...');\n    }\n\n    swim() {\n        console.log('Swimming...');\n    }\n}\n\nconst flyingFish = new FlyingFish();\nflyingFish.fly();\nflyingFish.swim();\n```\n\nLa parola chiave `class` in TypeScript, simile a JavaScript, è spesso definita \"syntactic sugar\". È stata introdotta in ECMAScript 2015 (ES6) offre una sintassi più familiare per la creazione e l'utilizzo di oggetti in modalità basata sulle classi. Tuttavia, è importante notare che TypeScript, essendo un superset di JavaScript, alla fine si compila in JavaScript, che rimane fondamentalmente basato sui prototipi.\n\n### Statiche\n\nTypeScript ha membri statici. Per accedere ai membri statici di una classe, è possibile utilizzare il nome della classe seguito da un punto, senza dover creare un oggetto.\n\n```typescript\nclass OfficeWorker {\n    static memberCount: number = 0;\n\n    constructor(private name: string) {\n        OfficeWorker.memberCount++;\n    }\n}\n\nconst w1 = new OfficeWorker('James');\nconst w2 = new OfficeWorker('Simon');\nconst total = OfficeWorker.memberCount;\nconsole.log(total); // 2\n```\n\n### Inizializzazione delle proprietà\n\nEsistono diversi modi per Inizializza le proprietà per una classe in TypeScript:\n\nInline:\n\nNell'esempio seguente, questi valori iniziali verranno utilizzati quando verrà creata un'istanza della classe.\n\n```typescript\nclass MyClass {\n    property1: string = 'default value';\n    property2: number = 42;\n}\n```\n\nNel costruttore:\n\n```typescript\nclass MyClass {\n    property1: string;\n    property2: number;\n\n    constructor() {\n        this.property1 = 'default value';\n        this.property2 = 42;\n    }\n}\n```\n\nUtilizzo dei parametri del costruttore:\n\n```typescript\nclass MyClass {\n    constructor(\n        private property1: string = 'default value',\n        public property2: number = 42\n    ) {\n        // Non è necessario assegnare esplicitamente i valori alle proprietà.\n    }\n    log() {\n        console.log(this.property2);\n    }\n}\nconst x = new MyClass();\nx.log();\n```\n\n### Sovraccarico dei metodi\n\nIl sovraccarico dei metodi consente a una classe di avere più metodi con lo stesso nome ma tipi di parametri diversi o un numero diverso di parametri. Questo ci permette di chiamare un metodo in modi diversi in base agli argomenti passati.\n\n```typescript\nclass MyClass {\n    add(a: number, b: number): number; // Firma di sovraccarico 1\n    add(a: string, b: string): string; // Firma di sovraccarico 2\n\n    add(a: number | string, b: number | string): number | string {\n        if (typeof a === 'number' && typeof b === 'number') {\n            return a + b;\n        }\n        if (typeof a === 'string' && typeof b === 'string') {\n            return a.concat(b);\n        }\n        throw new Error('Argomenti non validi');\n    }\n}\n\nconst r = new MyClass();\nconsole.log(r.add(10, 5)); // Log 15\n```\n\n"
  },
  {
    "path": "website/src/content/docs/it-it/book/common-built-in-js-objects.md",
    "content": "---\ntitle: Oggetti JavaScript predefiniti comuni\nsidebar:\n  order: 50\n  label: 50. Oggetti JavaScript predefiniti comuni\n---\n\n\nTypeScript è un superset di JavaScript e include tutti gli oggetti JavaScript predefiniti comunemente usati. Un elenco completo di questi oggetti è disponibile sul sito web di documentazione di Mozilla Developer Network (MDN):\n[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects)\n\nEcco un elenco di alcuni oggetti JavaScript predefiniti comunemente utilizzati:\n\n* Function\n* Object\n* Boolean\n* Error\n* Number\n* BigInt\n* Math\n* Date\n* String\n* RegExp\n* Array\n* Map\n* Set\n* Promise\n* Intl\n\n"
  },
  {
    "path": "website/src/content/docs/it-it/book/conditional-types.md",
    "content": "---\ntitle: Tipi condizionali\nsidebar:\n  order: 39\n  label: 39. Tipi condizionali\n---\n\n\nI tipi condizionali sono un modo per creare un tipo che dipende da una condizione, in cui il tipo da creare viene determinato in base al risultato della condizione. Sono definiti utilizzando la parola chiave `extends` e un operatore ternario per scegliere condizionatamente tra due tipi.\n\n```typescript\ntype IsArray<T> = T extends any[] ? true : false;\n\nconst myArray = [1, 2, 3];\nconst myNumber = 42;\n\ntype IsMyArrayAnArray = IsArray<typeof myArray>; // Type true\ntype IsMyNumberAnArray = IsArray<typeof myNumber>; // Type false\n```\n\n"
  },
  {
    "path": "website/src/content/docs/it-it/book/control-flow-analysis.md",
    "content": "---\ntitle: Analisi del flusso di controllo\nsidebar:\n  order: 22\n  label: 22. Analisi del flusso di controllo\n---\n\n\nL'analisi del flusso di controllo in TypeScript è un modo per analizzare staticamente il flusso di codice per dedurre i tipi di variabili, consentendo al compilatore di restringere i tipi di tali variabili secondo necessità, in base ai risultati dell'analisi.\n\nPrima di TypeScript 4.4, l'analisi del flusso di codice veniva applicata solo al codice all'interno di un'istruzione if, ma da TypeScript 4.4 può essere applicata anche alle espressioni condizionali e agli accessi alle proprietà discriminanti referenziati indirettamente tramite variabili const.\n\nAd esempio:\n\n```typescript\nconst f1 = (x: unknown) => {\n    const isString = typeof x === 'string';\n    if (isString) {\n        x.length;\n    }\n};\n\nconst f2 = (\n    obj: { kind: 'foo'; foo: string } | { kind: 'bar'; bar: number }\n) => {\n    const isFoo = obj.kind === 'foo';\n    if (isFoo) {\n        obj.foo;\n    } else {\n        obj.bar;\n    }\n};\n```\n\nAlcuni esempi in cui il restringimento non avviene:\n\n<!-- skip -->\n```typescript\nconst f1 = (x: unknown) => {\n    let isString = typeof x === 'string';\n    if (isString) {\n        x.length; // Errore, nessun restringimento perché isString non è costante\n    }\n};\n\nconst f6 = (\n    obj: { kind: 'foo'; foo: string } | { kind: 'bar'; bar: number }\n) => {\n    const isFoo = obj.kind === 'foo';\n    obj = obj;\n    if (isFoo) {\n        obj.foo; // Errore, nessun restringimento perché obj è assegnato nel corpo della funzione\n    }\n};\n```\n\nNote: Nelle espressioni condizionali vengono analizzati fino a cinque livelli di indirezione.\n\n"
  },
  {
    "path": "website/src/content/docs/it-it/book/differences-between-type-and-interface.md",
    "content": "---\ntitle: Differenze tra tipo e interfaccia\nsidebar:\n  order: 53\n  label: 53. Differenze tra tipo e interfaccia\n---\n\n\nUnione delle dichiarazioni (aumento):\n\nLe interfacce supportano l'unione delle dichiarazioni, il che significa che è possibile definire più interfacce con lo stesso nome e TypeScript le unirà in un'unica interfaccia con le proprietà e i metodi combinati. D'altra parte, i tipi non supportano l'unione delle dichiarazioni. Questo può essere utile quando si desidera aggiungere funzionalità extra o personalizzare i tipi esistenti senza modificare le definizioni originali o correggere tipi mancanti o errati.\n\n```typescript\ninterface A {\n    x: string;\n}\ninterface A {\n    y: string;\n}\nconst j: A = {\n    x: 'xx',\n    y: 'yy',\n};\n```\n\nEstensione di altri tipi/interfacce:\n\nSia i tipi che le interfacce possono estendere altri tipi/interfacce, ma la sintassi è diversa. Con le interfacce, si utilizza la parola chiave `extends` per ereditare proprietà e metodi da altre interfacce. Tuttavia, un'interfaccia non può estendere un tipo complesso come un tipo unione.\n\n```typescript\ninterface A {\n    x: string;\n    y: number;\n}\ninterface B extends A {\n    z: string;\n}\nconst car: B = {\n    x: 'x',\n    y: 123,\n    z: 'z',\n};\n```\n\nPer i tipi, si utilizza l'operatore & per combinare più tipi in un unico tipo (intersezione).\n\n```typescript\ninterface A {\n    x: string;\n    y: number;\n}\n\ntype B = A & {\n    j: string;\n};\n\nconst c: B = {\n    x: 'x',\n    y: 123,\n    j: 'j',\n};\n```\n\nTipi di unione e intersezione:\n\nI tipi sono più flessibili quando si tratta di definire tipi di unione e intersezione. Con la parola chiave `type`, è possibile creare facilmente tipi di unione utilizzando l'operatore `|` e tipi di intersezione utilizzando l'operatore `&`. Sebbene le interfacce possano anche rappresentare tipi di unione indirettamente, non dispongono di supporto integrato per i tipi di intersezione.\n\n```typescript\ntype Department = 'dep-x' | 'dep-y'; // Unione\n\ntype Person = {\n    name: string;\n    age: number;\n};\n\ntype Employee = {\n    id: number;\n    department: Department;\n};\n\ntype EmployeeInfo = Person & Employee; // Intersezione\n```\n\nEsempio con interfacce:\n\n```typescript\ninterface A {\n    x: 'x';\n}\ninterface B {\n    y: 'y';\n}\n\ntype C = A | B; // Unione di interfacce\n```\n\n"
  },
  {
    "path": "website/src/content/docs/it-it/book/discriminated-unions.md",
    "content": "---\ntitle: Unioni Discriminate\nsidebar:\n  order: 24\n  label: 24. Unioni Discriminate\n---\n\n\nLe unioni Discriminate in TypeScript sono un tipo di unione che utilizza una proprietà comune, nota come discriminante, per restringere l'insieme dei tipi possibili per l'unione.\n\n```typescript\ntype Square = {\n    kind: 'square'; // Discriminante\n    size: number;\n};\n\ntype Circle = {\n    kind: 'circle'; // Discriminante\n    radius: number;\n};\n\ntype Shape = Square | Circle;\n\nconst area = (shape: Shape) => {\n    switch (shape.kind) {\n        case 'square':\n            return Math.pow(shape.size, 2);\n        case 'circle':\n            return Math.PI * Math.pow(shape.radius, 2);\n    }\n};\n\nconst square: Square = { kind: 'square', size: 5 };\nconst circle: Circle = { kind: 'circle', radius: 2 };\n\nconsole.log(area(square)); // 25\nconsole.log(area(circle)); // 12.566370614359172\n```\n\n"
  },
  {
    "path": "website/src/content/docs/it-it/book/distributive-conditional-types.md",
    "content": "---\ntitle: Tipi condizionali distributivi\nsidebar:\n  order: 40\n  label: 40. Tipi condizionali distributivi\n---\n\n\nI tipi condizionali distributivi sono una funzionalità che consente di distribuire un tipo su un'unione di tipi, applicando una trasformazione a ciascun membro dell'unione individualmente.\nQuesto può essere particolarmente utile quando si lavora con tipi mappati o tipi di ordine superiore.\n\n```typescript\ntype Nullable<T> = T extends any ? T | null : never;\ntype NumberOrBool = number | boolean;\ntype NullableNumberOrBool = Nullable<NumberOrBool>; // number | boolean | null\n```\n\n"
  },
  {
    "path": "website/src/content/docs/it-it/book/downloads-and-website.md",
    "content": "---\ntitle: Download e sito web\nsidebar:\n  order: 3\n  label: 3. Download e sito web\n---\n\n\nPuoi anche scaricare la versione Epub:\n\n[https://github.com/gibbok/typescript-book/tree/main/downloads](https://github.com/gibbok/typescript-book/tree/main/downloads)\n\nÈ disponibile una versione online su:\n\n[https://gibbok.github.io/typescript-book](https://gibbok.github.io/typescript-book)\n\n"
  },
  {
    "path": "website/src/content/docs/it-it/book/enums.md",
    "content": "---\ntitle: Enumerazioni\nsidebar:\n  order: 19\n  label: 19. Enumerazioni\n---\n\n\nIn TypeScript, un `enum` è un insieme di valori costanti denominati.\n\n```typescript\nenum Colore {\n    Rosso = '#ff0000',\n    Verde = '#00ff00',\n    Blu = '#0000ff',\n}\n```\n\nGli enum possono essere definiti in diversi modi:\n\n### Enumerazioni numeriche\n\nIn TypeScript, un enum numerico è un enum in cui a ogni costante viene assegnato un valore numerico, a partire da 0 per impostazione predefinita.\n\n```typescript\nenum Size {\n    Small, // il valore inizia da 0\n    Medium,\n    Large,\n}\n```\n\nÈ possibile specificare valori personalizzati assegnandoli esplicitamente:\n\n```typescript\nenum Size {\n    Small = 10,\n    Medium,\n    Large,\n}\nconsole.log(Size.Medium); // 11\n```\n\n### Enum String\n\nIn TypeScript, un enum String è un enum in cui a ogni costante viene assegnato un valore stringa.\n\n```typescript\nenum Language {\n    English = 'EN',\n    Spanish = 'ES',\n}\n```\n\nNota: TypeScript consente l'utilizzo di enum eterogenei in cui stringhe e membri numerici possono coesistere.\n\n### Enum Constant\n\nUn enum Constant in TypeScript è un tipo speciale di enum in cui tutti i valori sono noti in fase di compilazione e vengono inlineati ovunque venga utilizzato l'enum, con conseguente maggiore efficienza del codice.\n\n```typescript\nconst enum Language {\n    English = 'EN',\n    Spanish = 'ES',\n}\nconsole.log(Language.English);\n```\n\nVerrà compilato in:\n\n```typescript\nconsole.log('EN' /* Language.English */);\n```\n\nNote:\n\nGli enum costanti hanno valori hardcoded, che cancellano l'enum, il che può essere più efficiente nelle librerie autonome, ma generalmente non è auspicabile. Inoltre, gli enum costanti non possono avere membri calcolati.\n\n### Mapping inverso\n\nIn TypeScript, i mapping inversi negli enum si riferiscono alla possibilità di recuperare il nome del membro dell'enum dal suo valore. Per impostazione predefinita, i membri dell'enum hanno mapping in avanti dal nome al valore, ma i mapping inversi possono essere creati impostando esplicitamente i valori per ciascun membro. I mapping inversi sono utili quando è necessario cercare un membro dell'enum in base al suo valore o quando è necessario iterare su tutti i membri dell'enum. Si noti che solo i membri dell'enum numerico genereranno mapping inversi, mentre i membri dell'enum stringa non generano alcun mapping inverso.\n\nIl seguente enum:\n\n```typescript\nenum Grade {\n    A = 90,\n    B = 80,\n    C = 70,\n    F = 'fail',\n}\n```\n\nCompila in:\n\n<!-- skip -->\n```javascript\n\"use strict\";\nvar Grade;\n(function (Grade) {\n  Grade[(Grade[\"A\"] = 90)] = \"A\";\n  Grade[(Grade[\"B\"] = 80)] = \"B\";\n  Grade[(Grade[\"C\"] = 70)] = \"C\";\n  Grade[\"F\"] = \"fail\";\n})(Grade || (Grade = {}));\n```\n\nPertanto, la mappatura dei valori alle chiavi funziona per i membri enum numerici, ma non per i membri enum stringa:\n\n<!-- skip -->\n```typescript\nenum Grade {\n    A = 90,\n    B = 80,\n    C = 70,\n    F = 'fail',\n}\nconst myGrade = Grade.A;\nconsole.log(Grade[myGrade]); // A\nconsole.log(Grade[90]); // A\n\nconst failGrade = Grade.F;\nconsole.log(failGrade); // fail\nconsole.log(Grade[failGrade]); // Element ha implicitamente un tipo 'any' perché l'espressione indice non è di tipo 'number'.\n```\n\n### Enum ambientali\n\nUn enum ambientale in TypeScript è un tipo di Enum definito in un file di dichiarazione (\\*.d.ts) senza un'implementazione associata. Permette di definire un set di costanti denominate che possono essere utilizzate in modo sicuro tra file diversi senza dover importare i dettagli di implementazione in ogni file.\n\n### Membri calcolati e costanti\n\nIn TypeScript, un membro calcolato è un membro di un Enum il cui valore è calcolato in fase di esecuzione, mentre un membro costante è un membro il cui valore è impostato in fase di compilazione e non può essere modificato in fase di esecuzione. I membri calcolati sono consentiti negli Enum normali, mentre i membri costanti sono consentiti sia negli enum normali che in quelli costanti.\n\n```typescript\n// Membri costanti\nenum Color {\n    Red = 1,\n    Green = 5,\n    Blue = Red + Green,\n}\nconsole.log(Color.Blue); // 6 generazioni in fase di compilazione\n```\n\n```typescript\n// Membri calcolati\nenum Color {\n    Red = 1,\n    Green = Math.pow(2, 2),\n    Blue = Math.floor(Math.random() * 3) + 1,\n}\nconsole.log(Color.Blue); // numero casuale generato in fase di esecuzione\n```\n\nGli enum sono indicati da unioni che comprendono i loro tipi di membri. I valori di ciascun membro possono essere determinati tramite espressioni costanti o non costanti, con i membri che possiedono valori costanti a cui vengono assegnati tipi letterali. Per illustrare, si consideri la dichiarazione del tipo E e dei suoi sottotipi E.A, E.B ed E.C. In questo caso, E rappresenta l'unione E.A | E.B | E.C.\n\n```typescript\nconst identity = (value: number) => value;\n\nenum E {\n    A = 2 * 5, // Letterale numerico\n    B = 'bar', // Letterale stringa\n    C = identity(42), // Calcolato opaco\n}\n\nconsole.log(E.C); //42\n```\n\n"
  },
  {
    "path": "website/src/content/docs/it-it/book/erased-structural-types.md",
    "content": "---\ntitle: Tipi strutturali cancellati\nsidebar:\n  order: 56\n  label: 56. Tipi strutturali cancellati\n---\n\n\nIn TypeScript, gli oggetti non devono necessariamente corrispondere a un tipo specifico ed esatto. Ad esempio, se creiamo un oggetto che soddisfa i requisiti di un'interfaccia, possiamo utilizzare quell'oggetto nei punti in cui l'interfaccia è richiesta, anche se non esiste una connessione esplicita tra i due.\nEsempio:\n\n```typescript\ntype NameProp1 = {\n    prop1: string;\n};\n\nfunction log(x: NameProp1) {\n    console.log(x.prop1);\n}\n\nconst obj = {\n    prop2: 123,\n    prop1: 'Origin',\n};\n\nlog(obj); // Valido\n```\n\n"
  },
  {
    "path": "website/src/content/docs/it-it/book/exhaustiveness-checking.md",
    "content": "---\ntitle: Controllo di esaustività\nsidebar:\n  order: 26\n  label: 26. Controllo di esaustività\n---\n\n\nIl controllo di esaustività è una funzionalità di TypeScript che garantisce che tutti i possibili casi di unione discriminata vengano gestiti in un'istruzione `switch` o in un'istruzione `if`.\n\n```typescript\ntype Direction = 'up' | 'down';\n\nconst move = (direction: Direction) => {\n    switch (direction) {\n        case 'up':\n            console.log(\"Spostamento verso l'alto\");\n            break;\n        case 'down':\n            console.log('Spostamento verso il basso');\n            break;\n        default:\n            const exhaustiveCheck: never = direction;\n            console.log(exhaustiveCheck); // Questa riga non verrà mai eseguita\n    }\n};\n```\n\nIl tipo `never` viene utilizzato per garantire che il caso predefinito sia esaustivo e che TypeScript generi un errore se un nuovo valore viene aggiunto al tipo Direction senza essere gestito nell'istruzione switch.\n\n"
  },
  {
    "path": "website/src/content/docs/it-it/book/exploring-the-type-system.md",
    "content": "---\ntitle: Esplorazione del sistema di tipi\nsidebar:\n  order: 9\n  label: 9. Esplorazione del sistema di tipi\n---\n\n\n### Il servizio di linguaggio TypeScript\n\nIl servizio di linguaggio TypeScript, noto anche come tsserver, offre diverse funzionalità come la segnalazione degli errori, la diagnostica, la compilazione al salvataggio, la ridenominazione, il passaggio alla definizione, gli elenchi di completamento, la guida alle firme e altro ancora. Viene utilizzato principalmente dagli ambienti di sviluppo integrati (IDE) per fornire supporto IntelliSense. Si integra perfettamente con Visual Studio Code ed è utilizzato da strumenti come Conquer of Completion (Coc).\n\nGli sviluppatori possono sfruttare un'API dedicata e creare plugin di servizi linguistici personalizzati per migliorare l'esperienza di modifica di TypeScript. Questo può essere particolarmente utile per implementare funzionalità di linting speciali o abilitare il completamento automatico per un linguaggio di template personalizzato.\n\n<!-- markdownlint-disable MD044 -->\n\nUn esempio di plugin personalizzato reale è \"TypeScript-styled-plugin\", che fornisce la segnalazione degli errori di sintassi e il supporto IntelliSense per le proprietà CSS nei componenti con stile. <!-- markdownlint-enable MD044 -->\n\nPer ulteriori informazioni e guide rapide, è possibile consultare il Wiki ufficiale di TypeScript su GitHub: [https://github.com/microsoft/TypeScript/wiki/](https://github.com/microsoft/TypeScript/wiki/)\n\n### Tipizzazione Strutturale\n\nTypeScript si basa su un sistema di tipi strutturale. Ciò significa che la compatibilità e l'equivalenza dei tipi sono determinate dalla struttura o definizione effettiva del tipo, piuttosto che dal suo nome o dal punto di dichiarazione, come nei sistemi di tipi nominativi come C# o C.\n\nIl sistema di tipi strutturale di TypeScript è stato progettato sulla base del funzionamento del sistema di tipizzazione dinamica di JavaScript durante l'esecuzione.\n\nL'esempio seguente è codice TypeScript valido. Come si può osservare, \"X\" e \"Y\" hanno lo stesso membro \"a\", anche se hanno nomi di dichiarazione diversi. I tipi sono determinati dalle loro strutture e, in questo caso, poiché le strutture sono le stesse, sono compatibili e validi.\n\n```typescript\ntype X = {\n    a: string;\n};\ntype Y = {\n    a: string;\n};\nconst x: X = { a: 'a' };\nconst y: Y = x; // Valido\n```\n\n### Regole fondamentali di confronto di TypeScript\n\nIl processo di confronto di TypeScript è ricorsivo ed è eseguito su tipi annidati a qualsiasi livello.\n\nUn tipo \"X\" è compatibile con \"Y\" se \"Y\" ha almeno gli stessi membri di \"X\".\n\n```typescript\ntype X = {\n    a: string;\n};\nconst y = { a: 'A', b: 'B' }; // Valido, poiché ha almeno gli stessi membri di X\nconst r: X = y;\n```\n\nI parametri delle funzioni vengono confrontati in base al tipo, non al nome:\n\n```typescript\ntype X = (a: number) => void;\ntype Y = (a: number) => void;\nlet x: X = (j: number) => undefined;\nlet y: Y = (k: number) => undefined;\ny = x; // Valido\nx = y; // Valido\n```\n\nI tipi restituiti dalla funzione devono essere gli stessi:\n\n<!-- skip -->\n```typescript\ntype X = (a: number) => undefined;\ntype Y = (a: number) => number;\nlet x: X = (a: number) => undefined;\nlet y: Y = (a: number) => 1;\ny = x; // Non valido\nx = y; // Non valido\n```\n\nIl tipo di ritorno di una funzione sorgente deve essere un sottotipo del tipo di ritorno di una funzione target:\n\n<!-- skip -->\n```typescript\nlet x = () => ({ a: 'A' });\nlet y = () => ({ a: 'A', b: 'B' });\nx = y; // Valido\ny = x; // Il membro non valido b è mancante\n```\n\nÈ consentito ignorare i parametri della funzione, come è prassi comune in JavaScript, ad esempio utilizzando \"Array.prototype.map()\":\n\n```typescript\n[1, 2, 3].map((element, _index, _array) => element + 'x');\n```\n\nPertanto, le seguenti dichiarazioni di tipo sono completamente valide:\n\n```typescript\ntype X = (a: number) => undefined;\ntype Y = (a: number, b: number) => undefined;\nlet x: X = (a: number) => undefined;\n\nlet y: Y = (a: number) => undefined; // Parametro b mancante\ny = x; // Valido\n```\n\nTutti i parametri opzionali aggiuntivi del tipo sorgente sono validi:\n\n```typescript\ntype X = (a: number, b?: number, c?: number) => undefined;\ntype Y = (a: number) => undefined;\nlet x: X = a => undefined;\nlet y: Y = a => undefined;\ny = x; // Valido\nx = y; //Valido\n```\n\nTutti i parametri opzionali del tipo destinazione senza parametri corrispondenti nel tipo sorgente sono validi e non costituiscono un errore:\n\n```typescript\ntype X = (a: number) => undefined;\ntype Y = (a: number, b?: number) => undefined;\nlet x: X = a => undefined;\nlet y: Y = a => undefined;\ny = x; // Valido\nx = y; // Valido\n```\n\nIl parametro rest viene trattato come una serie infinita di parametri opzionali:\n\n```typescript\ntype X = (a: number, ...rest: number[]) => undefined;\nlet x: X = a => undefined; //valido\n```\n\nLe funzioni con overload sono valide se la firma di overload è compatibile con la firma della sua implementazione:\n\n<!-- skip -->\n```typescript\nfunction x(a: string): void;\nfunction x(a: string, b: number): void;\nfunction x(a: string, b?: number): void {\n    console.log(a, b);\n}\nx('a'); // Valido\nx('a', 1); // Valido\n\nfunction y(a: string): void; // Non valido, non compatibile con la firma dell'implementazione\nfunction y(a: string, b: number): void;\nfunction y(a: string, b: number): void {\n    console.log(a, b);\n}\ny('a');\ny('a', 1);\n```\n\nIl confronto dei parametri della funzione ha esito positivo se i parametri sorgente e destinazione sono assegnabili a supertipi o sottotipi (bivarianza).\n\n```typescript\n// Supertipo\nclass X {\n    a: string;\n    constructor(value: string) {\n        this.a = value;\n    }\n}\n// Sottotipo\nclass Y extends X {}\n// Sottotipo\nclass Z extends X {}\n\ntype GetA = (x: X) => string;\nconst getA: GetA = x => x.a;\n\n// La bivarianza accetta supertipi\nconsole.log(getA(new X('x'))); // Valido\nconsole.log(getA(new Y('Y'))); // Valido\nconsole.log(getA(new Z('z'))); // Valido\n```\n\nGli enum sono confrontabili e validi con i numeri e viceversa, ma il confronto di valori Enum di tipi Enum diversi non è valido.\n\n<!-- skip -->\n```typescript\nenum X {\n    A,\n    B,\n}\nenum Y {\n    A,\n    B,\n    C,\n}\nconst xa: number = X.A; // Valido\nconst ya: Y = 0; // Valido\nX.A === Y.A; // Non valido\n```\n\nLe istanze di una classe sono soggette a un controllo di compatibilità per i loro membri privati ​​e protetti:\n\n<!-- skip -->\n```typescript\nclass X {\n    public a: string;\n    constructor(value: string) {\n        this.a = value;\n    }\n}\n\nclass Y {\n    private a: string;\n    constructor(value: string) {\n        this.a = value;\n    }\n}\n\nlet x: X = new Y('y'); // Non valido\n```\n\nIl controllo di confronto non tiene conto della diversa gerarchia di ereditarietà, ad esempio:\n\n```typescript\nclass X {\n    public a: string;\n    constructor(value: string) {\n        this.a = value;\n    }\n}\nclass Y extends X {\n    public a: string;\n    constructor(value: string) {\n        super(value);\n        this.a = value;\n    }\n}\nclass Z {\n    public a: string;\n    constructor(value: string) {\n        this.a = value;\n    }\n}\nlet x: X = new X('x');\nlet y: Y = new Y('y');\nlet z: Z = new Z('z');\nx === y; // Valido\nx === z; // Valido anche se z proviene da una gerarchia di ereditarietà diversa\n```\n\nI generici vengono confrontati utilizzando le loro strutture in base al tipo risultante dopo l'applicazione del parametro generico; solo il risultato finale viene confrontato come tipo non generico.\n\n<!-- skip -->\n```typescript\ninterface X<T> {\n    a: T;\n}\nlet x: X<number> = { a: 1 };\nlet y: X<string> = { a: 'a' };\nx === y; // Non valido poiché l'argomento tipo è utilizzato nella struttura finale\n```\n\n```typescript\ninterface X<T> {}\nconst x: X<number> = 1;\nconst y: X<string> = 'a';\nx === y; // Valido poiché l'argomento tipo non è utilizzato nella struttura finale\n```\n\nQuando i generici non hanno il loro argomento tipo specificato, tutti gli argomenti non specificati vengono trattati come tipi con \"any\":\n\n```typescript\ntype X = <T>(x: T) => T;\ntype Y = <K>(y: K) => K;\nlet x: X = x => x;\nlet y: Y = y => y;\nx = y; // Valido\n```\n\nRicorda:\n\n<!-- skip -->\n```typescript\nlet a: number = 1;\nlet b: number = 2;\na = b; // Valido, tutto è assegnabile a se stesso\n\nlet c: any;\nc = 1; // Valido, tutti i tipi sono assegnabili a qualsiasi\n\nlet d: unknown;\nd = 1; // Valido, tutti i tipi sono assegnabili a sconosciuto\n\nlet e: unknown;\nlet e1: unknown = e; // Valido, sconosciuto è assegnabile solo a se stesso e a qualsiasi\nlet e2: any = e; // Valido\nlet e3: number = e; // Non valido\n\nlet f: never;\nf = 1; // Non valido, nulla è assegnabile a never\n\nlet g: void;\nlet g1: any;\ng = 1; // Non valido, void non è assegnabile a o da nulla, tranne qualsiasi\ng = g1; // Valido\n```\n\nSi noti che quando \"strictNullChecks\" è abilitato, \"null\" e \"undefined\" vengono trattati in modo simile a \"void\"; in caso contrario, sono simili a \"never\".\n\n### Tipi come insiemi\n\nIn TypeScript, un tipo è un insieme di possibili valori. Questo insieme è anche definito dominio del tipo. Ogni valore di un tipo può essere visto come un elemento di un insieme. Un tipo stabilisce i vincoli che ogni elemento dell'insieme deve soddisfare per essere considerato membro di quell'insieme.\nIl compito principale di TypeScript è controllare e verificare se un insieme è un sottoinsieme di un altro.\n\nTypeScript supporta vari tipi di insiemi:\n\n| Termine di insieme             | TypeScript                        | Note                                                                                                                                          |\n| ------------------------------ | --------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |\n| Insieme vuoto                  | never                             | \"never\" non contiene nulla                                                                                                   |\n| Insieme di un singolo elemento | undefined / null / tipo letterale |                                                                                                                                               |\n| Insieme finito                 | boolean / union                   |                                                                                                                                               |\n| Insieme infinito               | string / number / object          |                                                                                                                                               |\n| Insieme universale             | any / unknown           | Ogni elemento è un membro di \"any\" e ogni insieme è un suo sottoinsieme / \"unknown\" è una controparte di tipo sicuro di \"any\" |\n\nEcco alcuni esempi:\n\n| TypeScript     | Termine di insieme          | Esempio                                                                           |\n| -------------- | --------------------------- | --------------------------------------------------------------------------------- |\n| never          | ∅ (insieme vuoto)           | const x: never = 'x'; // Errore: il tipo 'string' non è assegnabile al tipo 'never' |\n|                |                             |\n| Tipo letterale | Insieme di elementi singoli | type X = 'X';                                                                     |\n\n| | | type Y = 7; |\n| | |\n| Valore assegnabile a T | Valore ∈ T (membro di) | type XY = 'X' \\| 'Y'; |\n| | | const x: XY = 'X'; |\n| | |\n| T1 assegnabile a T2 | T1 ⊆ T2 (sottoinsieme di) | type XY = 'X' \\| 'Y'; |\n| | | const x: XY = 'X'; |\n| | | const j: XY = 'J'; // Il tipo '\"J\"' non è assegnabile al tipo 'XY'. |\n| | | |\n| T1 extends T2 | T1 ⊆ T2 (sottoinsieme di) | type X = 'X' extends string ? true : false; |\n| | |\n| T1 \\| T2 | T1 ∪ T2 (unione) | type XY = 'X' \\| 'Y'; |\n| | | type JK = 1 \\| 2; |\n| | |\n| T1 & T2 | T1 ∩ T2 (intersezione) | type X = \\{ a: string \\} |\n| | | type Y = \\{ b: string \\} |\n| | | type XY = X & Y |\n| | | const x: XY = \\{ a: 'a', b: 'b' \\} |\n| | |\n| unknown | Insieme universale | const x: unknown = 1 |\n\nUn'unione (T1 | T2) crea un insieme più ampio (entrambi):\n\n```typescript\ntype X = {\n    a: string;\n};\ntype Y = {\n    b: string;\n};\ntype XY = X | Y;\nconst r: XY = { a: 'a', b: 'x' }; // Valido\n```\n\nUn'intersezione (T1 e T2) crea un insieme più ristretto (solo condiviso):\n\n<!-- skip -->\n```typescript\ntype X = {\n    a: string;\n};\ntype Y = {\n    a: string;\n    b: string;\n};\ntype XY = X & Y;\nconst r: XY = { a: 'a' }; // Non valido\nconst j: XY = { a: 'a', b: 'b' }; // Valido\n```\n\nLa parola chiave `extends` potrebbe essere considerata un \"sottoinsieme di\" in questo contesto. Imposta un vincolo per un tipo. L'extends utilizzato con un generico, considera il generico come un insieme infinito e lo vincola a un tipo più specifico. Si noti che ``extends` non ha nulla a che fare con la gerarchia in senso OOP (questo concetto non esiste in TypeScript).\nTypeScript funziona con insiemi e non ha una gerarchia rigida; infatti, come nell'esempio seguente, due tipi potrebbero sovrapporsi senza che uno dei due sia un sottotipo dell'altro (TypeScript considera la struttura e la forma degli oggetti).\n\n```typescript\ninterface X {\n    a: string;\n}\ninterface Y extends X {\n    b: string;\n}\ninterface Z extends Y {\n    c: string;\n}\nconst z: Z = { a: 'a', b: 'b', c: 'c' };\ninterface X1 {\n    a: string;\n}\n\ninterface Y1 {\n    a: string;\n    b: string;\n}\ninterface Z1 {\n    a: string;\n    b: string;\n    c: string;\n}\nconst z1: Z1 = { a: 'a', b: 'b', c: 'c' };\n\nconst r: Z1 = z; // Valido\n```\n\n### Assegnare un tipo: Dichiarazioni di tipo e asserzioni di tipo\n\nUn tipo può essere assegnato in diversi modi in TypeScript:\n\n#### Dichiarazione di tipo\n\nNell'esempio seguente, utilizziamo x: X (\": Type\") per dichiarare un tipo per la variabile x.\n\n```typescript\ntype X = {\n    a: string;\n};\n\n// Dichiarazione di tipo\nconst x: X = {\n    a: 'a',\n};\n```\n\nSe la variabile non è nel formato specificato, TypeScript segnalerà un errore. Ad esempio:\n\n<!-- skip -->\n```typescript\ntype X = {\n    a: string;\n};\n\nconst x: X = {\n    a: 'a',\n    b: 'b', // Errore: il letterale dell'oggetto può specificare solo proprietà note\n};\n```\n\n#### Asserzione di tipo\n\nÈ possibile aggiungere un'asserzione utilizzando la parola chiave `as`. Questo indica al compilatore che lo sviluppatore ha maggiori informazioni su un tipo e silenzia eventuali errori.\n\nAd esempio:\n\n```typescript\ntype X = {\n    a: string;\n};\nconst x = {\n    a: 'a',\n    b: 'b',\n} as X;\n```\n\nNell'esempio precedente, si asserisce che l'oggetto x abbia il tipo X utilizzando la parola chiave as. Questo informa il compilatore TypeScript che l'oggetto è conforme al tipo specificato, anche se ha una proprietà aggiuntiva b non presente nella definizione del tipo.\n\nLe asserzioni di tipo sono utili in situazioni in cui è necessario specificare un tipo più specifico, soprattutto quando si lavora con il DOM. Ad esempio:\n\n```typescript\nconst myInput = document.getElementById('my_input') as HTMLInputElement;\n```\n\nQui, l'asserzione di tipo come HTMLInputElement viene utilizzata per indicare a TypeScript che il risultato di getElementById deve essere trattato come un HTMLInputElement.\nLe asserzioni di tipo possono anche essere utilizzate per rimappare le chiavi, come mostrato nell'esempio seguente con letterali di template:\n\n```typescript\ntype J<Type> = {\n    [Property in keyof Type as `prefix_${string &\n        Property}`]: () => Type[Property];\n};\ntype X = {\n    a: string;\n    b: number;\n};\ntype Y = J<X>;\n```\n\nIn questo esempio, il tipo `J<Tipo>` utilizza un tipo mappato con un letterale template per rimappare le chiavi di Tipo. Crea nuove proprietà con un \"prefisso\\_\" aggiunto a ciascuna chiave e i valori corrispondenti sono funzioni che restituiscono i valori delle proprietà originali.\n\nÈ importante notare che quando si utilizza un'asserzione di tipo, TypeScript non eseguirà controlli di proprietà eccessivi. Pertanto, è generalmente preferibile utilizzare una Dichiarazione di Tipo quando la struttura dell'oggetto è nota in anticipo.\n\n#### Dichiarazioni Ambientali\n\nLe dichiarazioni Ambientali sono file che descrivono i tipi per il codice JavaScript e hanno un formato di nome file come `.d.ts.`. Di solito vengono importate e utilizzate per annotare librerie JavaScript esistenti o per aggiungere tipi a file JS esistenti nel progetto.\n\nMolti tipi di librerie comuni sono disponibili all'indirizzo:\n[https://github.com/DefinitelyTyped/DefinitelyTyped/](https://github.com/DefinitelyTyped/DefinitelyTyped/)\n\ne possono essere installate tramite:\n\n```shell\nnpm install --save-dev @types/library-name\n```\n\nPer le dichiarazioni di ambiente definite, è possibile importarle utilizzando il riferimento \"tripla barra\":\n\n<!-- skip -->\n```typescript\n/// <reference path=\"./library-types.d.ts\" />\n```\n\nÈ possibile utilizzare le dichiarazioni di ambiente anche all'interno di file JavaScript utilizzando `// @ts-check`.\n\nLa parola chiave `declare` abilita le definizioni di tipo per il codice JavaScript esistente senza importarlo, fungendo da segnaposto per i tipi da un altro file o a livello globale.\n\n### Controllo delle proprietà e controllo delle proprietà in eccesso\n\nTypeScript si basa su un sistema di tipi strutturale, ma il controllo delle proprietà in eccesso è una proprietà di TypeScript che gli consente di verificare se un oggetto possiede esattamente le proprietà specificate nel tipo.\n\nIl controllo delle proprietà in eccesso viene eseguito, ad esempio, quando si assegnano letterali di oggetto a variabili o quando li si passa come argomenti alla proprietà in eccesso di una funzione.\n\n<!-- skip -->\n```typescript\ntype X = {\n    a: string;\n};\nconst y = { a: 'a', b: 'b' };\nconst x: X = y; // Valido perché tipizzazione strutturale\nconst w: X = { a: 'a', b: 'b' }; // Non valido perché controllo delle proprietà in eccesso\n```\n\n### Tipi deboli\n\nUn tipo è considerato debole quando contiene solo un insieme di proprietà completamente opzionali:\n\n```typescript\ntype X = {\n    a?: string;\n    b?: string;\n};\n```\n\nTypeScript considera un errore assegnare qualsiasi cosa a un tipo debole quando non c'è sovrapposizione, ad esempio, il seguente codice genera un errore:\n\n<!-- skip -->\n```typescript\ntype Options = {\n    a?: string;\n    b?: string;\n};\n\nconst fn = (options: Options) => undefined;\n\nfn({ c: 'c' }); // Non valido\n```\n\nSebbene non sia consigliato, se necessario, è possibile bypassare questo controllo utilizzando l'asserzione di tipo:\n\n```typescript\ntype Options = {\n    a?: string;\n    b?: string;\n};\nconst fn = (options: Options) => undefined;\nfn({ c: 'c' } as Options); // Valido\n```\n\nOppure aggiungendo `unknown` alla firma dell'indice del tipo debole:\n\n```typescript\ntype Options = {\n    [prop: string]: unknown;\n    a?: string;\n    b?: string;\n};\n\nconst fn = (options: Options) => undefined;\nfn({ c: 'c' }); // Valido\n```\n\n### Controllo rigoroso dei letterali di oggetto (freschezza)\n\nIl controllo rigoroso dei letterali di oggetto, a volte chiamato \"freschezza\", è una funzionalità di TypeScript che aiuta a individuare proprietà in eccesso o con errori di ortografia che altrimenti passerebbero inosservate nei normali controlli di tipo strutturale.\n\nQuando si crea un letterale di oggetto, il compilatore TypeScript lo considera \"fresco\". Se il letterale di oggetto viene assegnato a una variabile o passato come parametro, TypeScript genererà un errore se il letterale di oggetto specifica proprietà che non esistono nel tipo di destinazione.\n\nTuttavia, la \"freschezza\" scompare quando un letterale di oggetto viene ampliato o viene utilizzata un'asserzione di tipo.\n\nEcco alcuni esempi per illustrare:\n\n<!-- skip -->\n```typescript\ntype X = { a: string };\ntype Y = { a: string; b: string };\n\nlet x: X;\nx = { a: 'a', b: 'b' }; // Controllo di freschezza: Assegnazione non valida\nvar y: Y;\ny = { a: 'a', bx: 'bx' }; // Controllo di freschezza: Assegnazione non valida\n\nconst fn = (x: X) => console.log(x.a);\n\nfn(x);\nfn(y); // Allargamento: Nessun errore, strutturalmente compatibile con il tipo\n\nfn({ a: 'a', bx: 'b' }); // Controllo di aggiornamento: argomento non valido\n\nlet c: X = { a: 'a' };\nlet d: Y = { a: 'a', b: '' };\nc = d; // Allargamento: nessun controllo di aggiornamento\n```\n\n### Inferenza di tipo\n\nTypeScript può inferire i tipi quando non viene fornita alcuna annotazione durante:\n\n* Inizializzazione delle variabili.\n* Inizializzazione dei membri.\n* Impostazione dei valori predefiniti per i parametri.\n* Tipo di ritorno della funzione.\n\nAd esempio:\n\n```typescript\nlet x = 'x'; // Il tipo inferito è una stringa\n```\n\nIl compilatore TypeScript analizza il valore o l'espressione e ne determina il tipo in base alle informazioni disponibili.\n\n### Inferenze più avanzate\n\nQuando si utilizzano più espressioni nell'inferenza di tipo, TypeScript cerca i \"tipi più comuni\". Ad esempio:\n\n```typescript\nlet x = [1, 'x', 1, null]; // Il tipo dedotto è: (string | number | null)[]\n```\n\nSe il compilatore non riesce a trovare i tipi comuni migliori, restituisce un tipo unione. Ad esempio:\n\n```typescript\nlet x = [new RegExp('x'), new Date()]; // Il tipo inferito è: (RegExp | Date)[]\n```\n\nTypeScript utilizza la \"tipizzazione contestuale\" basata sulla posizione della variabile per inferire i tipi. Nell'esempio seguente, il compilatore sa che `e` è di tipo `MouseEvent` grazie al tipo di evento `click` definito nel file lib.d.ts, che contiene dichiarazioni ambientali per vari costrutti JavaScript comuni e il DOM:\n\n```typescript\nwindow.addEventListener('click', function (e) {}); // Il tipo inferito di e è MouseEvent\n```\n\n### Allargamento di tipo\n\nL'allargamento di tipo è il processo in cui TypeScript assegna un tipo a una variabile inizializzata quando non è stata fornita alcuna annotazione di tipo. Consente il passaggio da tipi stretti a più ampi, ma non viceversa. Nell'esempio seguente:\n\n<!-- skip -->\n```typescript\nlet x = 'x'; // TypeScript inferisce come stringa, un tipo ampio\nlet y: 'y' | 'x' = 'y'; // Il tipo y è un'unione di tipi letterali\ny = x; // Il tipo non valido 'string' non è assegnabile al tipo '\"x\" | \"y\"'.\n```\n\nTypeScript assegna `string` a `x` in base al singolo valore fornito durante l'inizializzazione (`x`); questo è un esempio di ampliamento.\n\nTypeScript fornisce modi per controllare il processo di ampliamento, ad esempio utilizzando \"const\".\n\n### Const\n\nL'utilizzo della parola chiave `const` durante la dichiarazione di una variabile produce un'inferenza di tipo più ristretta in TypeScript.\n\nAd esempio:\n\n```typescript\nconst x = 'x'; // TypeScript deduce il tipo di x come 'x', un tipo più ristretto\nlet y: 'y' | 'x' = 'y';\ny = x; // Valido: il tipo di x viene dedotto come 'x'\n```\n\nUtilizzando `const` per dichiarare la variabile x, il suo tipo viene ristretto allo specifico valore letterale 'x'. Poiché il tipo di x viene ristretto, può essere assegnato alla variabile y senza errori.\nIl motivo per cui il tipo può essere dedotto è che le variabili `const` non possono essere riassegnate, quindi il loro tipo può essere ristretto a un tipo letterale specifico, in questo caso, il tipo letterale 'x'.\n\n#### Modificatore Const sui parametri di tipo\n\nDalla versione 5.0 di TypeScript, è possibile specificare l'attributo `const` su un parametro di tipo generico. Questo consente di dedurre il tipo più preciso possibile. Vediamo un esempio senza usare `const`:\n\n```typescript\nfunction identity<T>(value: T) {\n    // Nessuna costante qui\n    return value;\n}\nconst values = identity({ a: 'a', b: 'b' }); // Il tipo inferito è: { a: string; b: string; }\n```\n\nCome puoi vedere, le proprietà `a` e `b` vengono inferite con un tipo `string`.\n\nOra, vediamo la differenza con la versione `const`:\n\n```typescript\nfunction identity<const T>(value: T) {\n    // Utilizzo del modificatore const sui parametri di tipo\n    return value;\n}\nconst values = identity({ a: 'a', b: 'b' }); // Il tipo inferito è: { a: \"a\"; b: \"b\"; }\n```\n\nOra possiamo vedere che le proprietà `a` e `b` vengono dedotte come `const`, quindi `a` e `b` vengono trattate come stringhe letterali anziché come semplici tipi `string`.\n\n#### Asserzione Const\n\nQuesta funzionalità consente di dichiarare una variabile con un tipo letterale più preciso in base al suo valore di inizializzazione, indicando al compilatore che il valore deve essere trattato come un letterale immutabile. Ecco alcuni esempi:\n\nSu una singola proprietà:\n\n```typescript\nconst v = {\n    x: 3 as const,\n};\nv.x = 3;\n```\n\nSu un intero oggetto:\n\n```typescript\nconst v = {\n    x: 1,\n    y: 2,\n} as const;\n```\n\nQuesto può essere particolarmente utile quando si definisce il tipo per una tupla:\n\n```typescript\nconst x = [1, 2, 3]; // number[]\nconst y = [1, 2, 3] as const; // Tupla di readonly [1, 2, 3]\n```\n\n### Annotazione di tipo esplicita\n\nPossiamo essere specifici e passare un tipo, nell'esempio seguente la proprietà `x` è di tipo `number`:\n\n```typescript\nconst v = {\n    x: 1, // Inferred type: number (widening)\n};\nv.x = 3; // Valido\n```\n\nPossiamo rendere l'annotazione di tipo più specifica utilizzando un'unione di tipi letterali:\n\n<!-- skip -->\n```typescript\nconst v: { x: 1 | 2 | 3 } = {\n    x: 1, // x è ora un'unione di tipi letterali: 1 | 2 | 3\n};\nv.x = 3; // Valido\nv.x = 100; // Non valido\n```\n\n### Restringimento dei tipi\n\nIl restringimento dei tipi è il processo in TypeScript in cui un tipo generico viene ridotto a un tipo più specifico. Ciò si verifica quando TypeScript analizza il codice e determina che determinate condizioni o operazioni possono perfezionare le informazioni sul tipo.\n\nIl restringimento dei tipi può avvenire in diversi modi, tra cui:\n\n#### Condizioni\n\nUtilizzando istruzioni condizionali, come `if` o `switch`, TypeScript può restringere il tipo in base al risultato della condizione. Ad esempio:\n\n```typescript\nlet x: number | undefined = 10;\n\nif (x !== undefined) {\n    x += 100; // Il tipo è number, che è stato ristretto dalla condizione\n}\n```\n\n#### Generazione o restituzione\n\nGenerare un errore o restituire un'istruzione in anticipo da un branch può essere utilizzato per aiutare TypeScript a restringere un tipo. Ad esempio:\n\n```typescript\nlet x: number | undefined = 10;\n\nif (x === undefined) {\n    throw 'error';\n}\nx += 100;\n```\n\nAltri modi per restringere i tipi in TypeScript includono:\n\n* Operatore `instanceof`: utilizzato per verificare se un oggetto è un'istanza di una classe specifica.\n* Operatore `in`: utilizzato per verificare se una proprietà esiste in un oggetto.\n* Operatore `typeof`: utilizzato per verificare il tipo di un valore in fase di esecuzione.\n* Funzioni integrate come `Array.isArray()`: utilizzate per verificare se un valore è un array.\n\n#### Unione Discriminata\n\nL'utilizzo di una \"Unione Discriminata\" è un pattern in TypeScript in cui un \"tag\" esplicito viene aggiunto agli oggetti per distinguere i diversi tipi all'interno di un'unione. Questo pattern è anche definito \"unione con tag\". Nell'esempio seguente, il \"tag\" è rappresentato dalla proprietà \"type\":\n\n```typescript\ntype A = { type: 'type_a'; value: number };\ntype B = { type: 'type_b'; value: string };\n\nconst x = (input: A | B): string | number => {\n    switch (input.type) {\n        case 'type_a':\n            return input.value + 100; // il tipo è A\n        case 'type_b':\n            return input.value + 'extra'; // il tipo è B\n    }\n};\n```\n\n#### Protezioni di tipo definite dall'utente\n\nNei casi in cui TypeScript non sia in grado di determinare un tipo, è possibile scrivere una funzione di supporto nota come \"protezione di tipo definita dall'utente\". Nell'esempio seguente, utilizzeremo un predicato di tipo per restringere il tipo dopo aver applicato un determinato filtro:\n\n```typescript\nconst data = ['a', null, 'c', 'd', null, 'f'];\n\nconst r1 = data.filter(x => x != null); // Il tipo è (string | null)[], TypeScript non è riuscito a dedurre correttamente il tipo\n\nconst isValid = (item: string | null): item is string => item !== null; // Protezione personalizzata del tipo\n\nconst r2 = data.filter(isValid); // Il tipo ora è corretto string[], utilizzando la protezione del tipo predicato siamo riusciti a restringere il tipo\n```\n\n"
  },
  {
    "path": "website/src/content/docs/it-it/book/extending-types.md",
    "content": "---\ntitle: Estensione dei tipi\nsidebar:\n  order: 15\n  label: 15. Estensione dei tipi\n---\n\n\nÈ possibile estendere un'`interfaccia` (copiare membri da un altro tipo):\n\n```typescript\ninterface X {\n    a: string;\n}\ninterface Y extends X {\n    b: string;\n}\n```\n\nÈ anche possibile estendere da più tipi:\n\n```typescript\ninterface A {\n    a: string;\n}\ninterface B {\n    b: string;\n}\ninterface Y extends A, B {\n    y: string;\n}\n```\n\nLa parola chiave `extends` funziona solo su interfacce e classi; per i tipi utilizzare un'intersezione:\n\n```typescript\ntype A = {\n    a: number;\n};\ntype B = {\n    b: number;\n};\ntype C = A & B;\n```\n\nÈ possibile estendere un tipo utilizzando un'inferenza, ma non viceversa:\n\n```typescript\ntype A = {\n    a: string;\n};\ninterface B extends A {\n    b: string;\n}\n```\n\n"
  },
  {
    "path": "website/src/content/docs/it-it/book/fixed-length-tuple.md",
    "content": "---\ntitle: Tupla a lunghezza fissa\nsidebar:\n  order: 30\n  label: 30. Tupla a lunghezza fissa\n---\n\n\nUna tupla a lunghezza fissa è un tipo specifico di tupla che impone un numero fisso di elementi di tipi specifici e non consente alcuna modifica alla lunghezza della tupla una volta definita.\n\nLe tuple a lunghezza fissa sono utili quando è necessario rappresentare una raccolta di valori con un numero specifico di elementi e tipi specifici e si desidera garantire che la lunghezza e i tipi della tupla non possano essere modificati inavvertitamente.\n\n<!-- skip -->\n```typescript\nconst x = [10, 'hello'] as const;\nx.push(2); // Errore\n```\n\n"
  },
  {
    "path": "website/src/content/docs/it-it/book/generics.md",
    "content": "---\ntitle: Generici\nsidebar:\n  order: 55\n  label: 55. Generici\n---\n\n\nI generici consentono di creare componenti e funzioni riutilizzabili che possono funzionare con più tipi. Con i generici, è possibile parametrizzare tipi, funzioni e interfacce, consentendo loro di operare su tipi diversi senza doverli specificare esplicitamente in anticipo.\n\nI generici consentono di rendere il codice più flessibile e riutilizzabile.\n\n### Tipo generico\n\nPer definire un tipo generico, si utilizzano le parentesi angolari (`<>`) per specificare i parametri di tipo, ad esempio:\n\n```typescript\nfunction identity<T>(arg: T): T {\n    return arg;\n}\nconst a = identity('x');\nconst b = identity(123);\n\nconst getLen = <T,>(data: ReadonlyArray<T>) => data.length;\nconst len = getLen([1, 2, 3]);\n```\n\n### Classi generiche\n\nI generici possono essere applicati anche alle classi, in questo modo possono lavorare con più tipi utilizzando parametri di tipo. Questo è utile per creare definizioni di classe riutilizzabili che possono operare su diversi tipi di dati mantenendo la sicurezza dei tipi.\n\n```typescript\nclass Container<T> {\n    private item: T;\n\n    constructor(item: T) {\n        this.item = item;\n    }\n\n    getItem(): T {\n        return this.item;\n    }\n}\n\nconst numberContainer = new Container<number>(123);\nconsole.log(numberContainer.getItem()); // 123\n\nconst stringContainer = new Container<string>('hello');\nconsole.log(stringContainer.getItem()); // ciao\n```\n\n### Vincoli generici\n\nI parametri generici possono essere vincolati utilizzando la parola chiave `extends` seguita da un tipo o un'interfaccia che il parametro di tipo deve soddisfare.\n\nNell'esempio seguente, T deve contenere una `length` appropriata per essere valido:\n\n<!-- skip -->\n```typescript\nconst printLen = <T extends { length: number }>(value: T): void => {\n    console.log(value.length);\n};\n\nprintLen('Ciao'); // 5\nprintLen([1, 2, 3]); // 3\nprintLen({ length: 10 }); // 10\nprintLen(123); // Non valido\n```\n\nUna caratteristica interessante di generic introdotta nella versione 3.4 RC è l'inferenza di tipo di funzione di ordine superiore, che ha introdotto argomenti di tipo generico propagati:\n\n```typescript\ndeclare function pipe<A extends any[], B, C>(\n    ab: (...args: A) => B,\n    bc: (b: B) => C\n): (...args: A) => C;\n\ndeclare function list<T>(a: T): T[];\ndeclare function box<V>(x: V): { value: V };\n\nconst listBox = pipe(list, box); // <T>(a: T) => { value: T[] }\nconst boxList = pipe(box, list); // <V>(x: V) => { value: V }[]\n```\n\nQuesta funzionalità consente una programmazione più semplice, sicura e senza punti, comune nella programmazione funzionale.\n\n### Restringimento contestuale generico\n\nIl restringimento contestuale per i generici è il meccanismo di TypeScript che consente al compilatore di restringere il tipo di un parametro generico in base al contesto in cui viene utilizzato. È utile quando si lavora con tipi generici in istruzioni condizionali:\n\n```typescript\nfunction process<T>(value: T): void {\n    if (typeof value === 'string') {\n        // Il valore viene ristretto al tipo 'string'\n        console.log(value.length);\n    } else if (typeof value === 'number') {\n        // Il valore viene ristretto al tipo 'number'\n        console.log(value.toFixed(2));\n    }\n}\n\nprocess('hello'); // 5\nprocess(3.14159); // 3.14\n```\n\n"
  },
  {
    "path": "website/src/content/docs/it-it/book/getting-started-with-typescript.md",
    "content": "---\ntitle: Per iniziare con TypeScript\nsidebar:\n  order: 8\n  label: 8. Per iniziare con TypeScript\n---\n\n\n### Installazione\n\nVisual Studio Code offre un eccellente supporto per il linguaggio TypeScript, ma non include il compilatore TypeScript. Per installare il compilatore TypeScript, è possibile utilizzare un gestore di pacchetti come npm o yarn:\n\n```shell\nnpm install typescript --save-dev\n```\n\noppure\n\n```shell\nyarn add typescript --dev\n```\n\nAssicurarsi di eseguire il commit del file di lock generato per garantire che ogni membro del team utilizzi la stessa versione di TypeScript.\n\nPer eseguire il compilatore TypeScript, è possibile utilizzare i seguenti comandi:\n\n```shell\nnpx tsc\n```\n\noppure\n\n```shell\nyarn tsc\n```\n\nSi consiglia di installare TypeScript a livello di progetto anziché globale, poiché garantisce un processo di build più prevedibile. Tuttavia, per occasioni particolari, è possibile utilizzare il seguente comando:\n\n```shell\nnpx tsc\n```\n\noppure installarlo globalmente:\n\n```shell\nnpm install -g typescript\n```\n\nSe si utilizza Microsoft Visual Studio, è possibile ottenere TypeScript come pacchetto in NuGet per i progetti MSBuild. Nella console di Gestione Pacchetti di NuGet, eseguire il seguente comando:\n\n```shell\nInstall-Package Microsoft.TypeScript.MSBuild\n```\n\nDurante l'installazione di TypeScript, vengono installati due eseguibili: \"tsc\" come compilatore TypeScript e \"tsserver\" come server autonomo TypeScript. Il server autonomo contiene il compilatore e i servizi linguistici che possono essere utilizzati da editor e IDE per fornire il completamento intelligente del codice.\n\nInoltre, sono disponibili diversi transpiler compatibili con TypeScript, come Babel (tramite un plugin) o swc. Questi transpiler possono essere utilizzati per convertire il codice TypeScript in altri linguaggi o versioni di destinazione.\n\n### Configurazione\n\nTypeScript può essere configurato utilizzando le opzioni della CLI di tsc o un file di configurazione dedicato chiamato tsconfig.json, posizionato nella radice del progetto.\n\nPer generare un file tsconfig.json precompilato con le impostazioni consigliate, è possibile utilizzare il seguente comando:\n\n```shell\ntsc --init\n```\n\nQuando si esegue il comando `tsc` localmente, TypeScript compilerà il codice utilizzando la configurazione specificata nel file tsconfig.json più vicino.\n\nEcco alcuni esempi di comandi CLI che vengono eseguiti con le impostazioni predefinite:\n\n```shell\ntsc main.ts // Compila un file specifico (main.ts) in JavaScript\ntsc src/*.ts // Compila tutti i file .ts nella cartella 'src' in JavaScript\ntsc app.ts util.ts --outfile index.js // Compila due file TypeScript (app.ts e util.ts) in un singolo file JavaScript (index.js)\n```\n\n### File di configurazione TypeScript\n\nUn file tsconfig.json viene utilizzato per configurare il compilatore TypeScript (tsc). Solitamente, viene aggiunto alla radice del progetto, insieme al file `package.json`.\n\nNote:\n\n* tsconfig.json accetta commenti anche se è in formato json.\n* Si consiglia di utilizzare questo file di configurazione al posto delle opzioni della riga di comando.\n\nAl seguente link potete trovare la documentazione completa e il relativo schema:\n\n[https://www.typescriptlang.org/tsconfig](https://www.typescriptlang.org/tsconfig)\n\n[https://www.typescriptlang.org/tsconfig/](https://www.typescriptlang.org/tsconfig/)\n\nDi seguito è riportato un elenco delle configurazioni più comuni e utili:\n\n#### target\n\nLa proprietà \"target\" viene utilizzata per specificare in quale versione di JavaScript ECMAScript TypeScript deve emettere/compilare. Per i browser moderni, ES6 è una buona opzione, mentre per i browser più vecchi si consiglia ES5.\n\n#### lib\n\nLa proprietà \"lib\" viene utilizzata per specificare quali file di libreria includere in fase di compilazione. TypeScript include automaticamente le API per le funzionalità specificate nella proprietà \"target\", ma è possibile omettere o selezionare librerie specifiche per esigenze particolari. Ad esempio, se si lavora su un progetto server, è possibile escludere la libreria \"DOM\", utile solo in un ambiente browser.\n\n#### strict\n\nLa proprietà \"strict\" offre garanzie più solide e migliora la sicurezza dei tipi. Si consiglia di includere sempre questa proprietà nel file tsconfig.json del progetto. Abilitando la proprietà \"strict\", TypeScript può:\n\n* Emettere codice utilizzando \"use strict\" per ogni file sorgente.\n* Considerare \"null\" e \"undefined\" nel processo di controllo dei tipi.\n* Disabilitare l'utilizzo del tipo \"any\" quando non sono presenti annotazioni di tipo.\n* Generare un errore sull'utilizzo dell'espressione \"this\", che altrimenti implicherebbe il tipo \"any\".\n\n#### module\n\nLa proprietà \"module\" imposta il sistema di moduli supportato dal programma compilato. Durante l'esecuzione, un caricatore di moduli viene utilizzato per individuare ed eseguire le dipendenze in base al sistema di moduli specificato.\n\nI caricatori di moduli più comuni utilizzati in JavaScript sono Node.js CommonJS per le applicazioni lato server e RequireJS per i moduli AMD nelle applicazioni web basate su browser. TypeScript può generare codice per vari sistemi di moduli, tra cui UMD, System, ESNext, ES2015/ES6 ed ES2020.\n\nNota: il sistema di moduli deve essere scelto in base all'ambiente di destinazione e al meccanismo di caricamento dei moduli disponibile in tale ambiente.\n\n#### moduleResolution\n\nLa proprietà \"moduleResolution\" specifica la strategia di risoluzione dei moduli. Utilizzare \"node\" per il codice TypeScript moderno, la strategia \"classic\" viene utilizzata solo per le vecchie versioni di TypeScript (precedenti alla 1.6).\n\n#### esModuleInterop\n\nLa proprietà \"esModuleInterop\" consente l'importazione predefinita dai moduli CommonJS che non sono stati esportati utilizzando la proprietà \"default\". Questa proprietà fornisce uno shim per garantire la compatibilità nel codice JavaScript emesso. Dopo aver abilitato questa opzione, possiamo usare `import MyLibrary from \"my-library\"` invece di `import * as MyLibrary from \"my-library\"`.\n\n#### jsx\n\nLa proprietà \"jsx\" si applica solo ai file .tsx utilizzati in ReactJS e controlla il modo in cui i costrutti JSX vengono compilati in JavaScript. Un'opzione comune è \"preserve\", che compilerà in un file .jsx mantenendo invariato il codice JSX, in modo che possa essere passato a diversi strumenti come Babel per ulteriori trasformazioni.\n\n#### skipLibCheck\n\nLa proprietà \"skipLibCheck\" impedisce a TypeScript di controllare il tipo di tutti i pacchetti di terze parti importati. Questa proprietà riduce il tempo di compilazione di un progetto. TypeScript controllerà comunque il codice rispetto alle definizioni di tipo fornite da questi pacchetti.\n\n#### files\n\nLa proprietà \"files\" indica al compilatore un elenco di file che devono essere sempre inclusi nel programma.\n\n#### include\n\n<!-- markdownlint-disable MD049 -->\n\nLa proprietà \"include\" indica al compilatore un elenco di file che si desidera includere. Questa proprietà consente schemi di tipo glob, come \"\\*_\" per qualsiasi sottodirectory, \"_\" per qualsiasi nome di file e \"?\" per caratteri opzionali.\n\n<!-- markdownlint-enable MD049 -->\n\n#### exclude\n\nLa proprietà \"exclude\" indica al compilatore un elenco di file che non devono essere inclusi nella compilazione. Questo può includere file come \"node_modules\" o file di test.\nNota: tsconfig.json consente commenti.\n\n### importHelpers\n\nTypeScript utilizza codice helper durante la generazione di codice per determinate funzionalità JavaScript avanzate o di livello inferiore. Per impostazione predefinita, questi helper vengono duplicati nei file che li utilizzano. L'opzione `importHelpers` importa invece questi helper dal modulo `tslib`, rendendo l'output JavaScript più efficiente.\n\n### Consigli per la migrazione a TypeScript\n\nPer progetti di grandi dimensioni, si consiglia di adottare una transizione graduale in cui TypeScript e codice JavaScript coesisteranno inizialmente. Solo i progetti di piccole dimensioni possono essere migrati a TypeScript in un'unica soluzione.\n\nIl primo passo di questa transizione è introdurre TypeScript nel processo di build chain. Questo può essere fatto utilizzando l'opzione del compilatore \"allowJs\", che consente ai file .ts e .tsx di coesistere con i file JavaScript esistenti. Poiché TypeScript tornerà al tipo \"any\" per una variabile quando non riesce a dedurre il tipo dai file JavaScript, si consiglia di disabilitare \"noImplicitAny\" nelle opzioni del compilatore all'inizio della migrazione.\n\nIl secondo passaggio consiste nell'assicurarsi che i test JavaScript funzionino insieme ai file TypeScript, in modo da poterli eseguire durante la conversione di ciascun modulo. Se si utilizza Jest, si può valutare l'utilizzo di `ts-jest`, che consente di testare i progetti TypeScript con Jest.\n\nIl terzo passaggio consiste nell'includere le dichiarazioni di tipo per le librerie di terze parti nel progetto. Queste dichiarazioni sono disponibili in bundle o su DefinitelyTyped. È possibile cercarle utilizzando [https://www.typescriptlang.org/dt/search](https://www.typescriptlang.org/dt/search) e installarle tramite:\n\n```shell\nnpm install --save-dev @types/package-name\n```\n\nor\n\n```shell\nyarn add --dev @types/package-name\n```\n\nIl quarto passaggio consiste nel migrare modulo per modulo con un approccio bottom-up, seguendo il grafo delle dipendenze partendo dalle foglie. L'idea è di iniziare a convertire i moduli che non dipendono da altri moduli. Per visualizzare i grafici delle dipendenze, è possibile utilizzare lo strumento \"madge\".\n\nI moduli candidati ideali per queste conversioni iniziali sono funzioni di utilità e codice relativo ad API o specifiche esterne. È possibile generare automaticamente definizioni di tipo TypeScript da contratti Swagger, schemi GraphQL o JSON da includere nel progetto.\n\nQuando non sono disponibili specifiche o schemi ufficiali, è possibile generare tipi da dati grezzi, come JSON restituiti da un server. Tuttavia, si consiglia di generare tipi da specifiche anziché da dati per evitare di perdere casi limite.\n\nDurante la migrazione, evitare il refactoring del codice e concentrarsi solo sull'aggiunta di tipi ai moduli.\n\nIl quinto passaggio consiste nell'abilitare \"noImplicitAny\", che garantirà che tutti i tipi siano noti e definiti, offrendo una migliore esperienza TypeScript per il progetto.\n\nDurante la migrazione, è possibile utilizzare la direttiva `@ts-check`, che abilita il controllo dei tipi TypeScript in un file JavaScript. Questa direttiva fornisce una versione semplificata del controllo dei tipi e può essere utilizzata inizialmente per identificare problemi nei file JavaScript. Quando `@ts-check` è incluso in un file, TypeScript tenterà di dedurre le definizioni utilizzando commenti in stile JSDoc. Tuttavia, si consiglia di utilizzare le annotazioni JSDoc solo in una fase molto precoce della migrazione.\n\nSi consiglia di mantenere il valore predefinito di `noEmitOnError` nel file tsconfig.json su false. Questo consentirà di generare codice sorgente JavaScript anche se vengono segnalati errori.\n\n"
  },
  {
    "path": "website/src/content/docs/it-it/book/index-signatures.md",
    "content": "---\ntitle: Firme di indice\nsidebar:\n  order: 14\n  label: 14. Firme di indice\n---\n\n\nIn TypeScript possiamo usare come firma di indice `string`, `number` e `symbol`:\n\n```typescript\ntype K = {\n    [name: string | number]: string;\n};\nconst k: K = { x: 'x', 1: 'b' };\nconsole.log(k['x']);\nconsole.log(k[1]);\nconsole.log(k['1']); // Stesso risultato di k[1]\n```\n\nSi noti che JavaScript converte automaticamente un indice con `number` in un indice con `string`, quindi `k[1]` o `k[\"1\"]` restituiscono lo stesso valore.\n\n"
  },
  {
    "path": "website/src/content/docs/it-it/book/infer-type-inference-in-conditional-types.md",
    "content": "---\ntitle: infer Inferenza di tipo nei tipi condizionali\nsidebar:\n  order: 41\n  label: 41. infer Inferenza di tipo nei tipi condizionali\n---\n\n\nLa parola chiave `infer` viene utilizzata nei tipi condizionali per inferire (estrarre) il tipo di un parametro generico da un tipo che dipende da esso. Questo consente di scrivere definizioni di tipo più flessibili e riutilizzabili.\n\n```typescript\ntype ElementType<T> = T extends (infer U)[] ? U : never;\ntype Numbers = ElementType<number[]>; // number\ntype Strings = ElementType<string[]>; // string\n```\n\n"
  },
  {
    "path": "website/src/content/docs/it-it/book/interface-and-type.md",
    "content": "---\ntitle: Interfaccia e tipo\nsidebar:\n  order: 48\n  label: 48. Interfaccia e tipo\n---\n\n\n### Sintassi comune\n\nIn TypeScript, le interfacce definiscono la struttura degli oggetti, specificando i nomi e i tipi di proprietà o metodi che un oggetto deve avere. La sintassi comune per definire un'interfaccia in TypeScript è la seguente:\n\n<!-- skip -->\n```typescript\ninterface InterfaceName {\n    property1: Type1;\n    // ...\n    method1(arg1: ArgType1, arg2: ArgType2): ReturnType;\n    // ...\n}\n```\n\nAnalogamente per la definizione del tipo:\n\n<!-- skip -->\n```typescript\ntype TypeName = {\n    property1: Type1;\n    // ...\n    method1(arg1: ArgType1, arg2: ArgType2): ReturnType;\n    // ...\n};\n```\n\n`interface InterfaceName` o `type TypeName`: Definisce il nome dell'interfaccia.\n`property1`: `Type1`: Specifica le proprietà dell'interfaccia insieme ai tipi corrispondenti. È possibile definire più proprietà, ciascuna separata da un punto e virgola.\n`method1(arg1: ArgType1, arg2: ArgType2): ReturnType;`: Specifica i metodi dell'interfaccia. I metodi sono definiti con i loro nomi, seguiti da un elenco di parametri tra parentesi e dal tipo di ritorno. È possibile definire più metodi, ciascuno separato da un punto e virgola.\n\nEsempio di interfaccia:\n\n```typescript\ninterface Person {\n    name: string;\n    age: number;\n    greet(): void;\n}\n```\n\nEsempio di tipo:\n\n```typescript\ntype TypeName = {\n    property1: string;\n    method1(arg1: string, arg2: string): string;\n};\n```\n\nIn TypeScript, i tipi vengono utilizzati per definire la forma dei dati e applicare il controllo dei tipi. Esistono diverse sintassi comuni per la definizione dei tipi in TypeScript, a seconda del caso d'uso specifico. Ecco alcuni esempi:\n\n### Tipi di base\n\n```typescript\nlet myNumber: number = 123; // number type\nlet myBoolean: boolean = true; // boolean type\nlet myArray: string[] = ['a', 'b']; // array di stringhe\nlet myTuple: [string, number] = ['a', 123]; // tupla\n```\n\n### Oggetti e interfacce\n\n```typescript\nconst x: { name: string; age: number } = { name: 'Simon', age: 7 };\n```\n\n### Tipi di unione e intersezione\n\n```typescript\ntype MyType = string | number; // Union type\nlet myUnion: MyType = 'hello'; // Can be a string\nmyUnion = 123; // Or a number\n\ntype TypeA = { name: string };\ntype TypeB = { age: number };\ntype CombinedType = TypeA & TypeB; // Intersection type\nlet myCombined: CombinedType = { name: 'John', age: 25 }; // Object with name and age properties\n```\n\n"
  },
  {
    "path": "website/src/content/docs/it-it/book/intersection-types.md",
    "content": "---\ntitle: Tipi Intersezione\nsidebar:\n  order: 32\n  label: 32. Tipi Intersezione\n---\n\n\nUn Tipo Intersezione è un tipo che rappresenta un valore che ha tutte le proprietà di due o più tipi. I Tipi Intersezione sono indicati con il simbolo `&` tra ogni tipo.\n\n```typescript\ntype X = {\n    a: string;\n};\n\ntype Y = {\n    b: string;\n};\n\ntype J = X & Y; // Intersezione\n\nconst j: J = {\n    a: 'a',\n    b: 'b',\n};\n```\n\n"
  },
  {
    "path": "website/src/content/docs/it-it/book/introduction.md",
    "content": "---\ntitle: Introduzione\nsidebar:\n  order: 5\n  label: 5. Introduzione\n---\n\n\nBenvenuti a The Concise TypeScript Book! Questa guida vi fornirà le conoscenze essenziali e le competenze pratiche per uno sviluppo TypeScript efficace. Scoprite i concetti e le tecniche chiave per scrivere codice pulito e robusto. Che siate principianti o sviluppatori esperti, questo libro rappresenta sia una guida completa che un pratico riferimento per sfruttare la potenza di TypeScript nei vostri progetti.\n\nQuesto libro tratta TypeScript 5.2.\n\n"
  },
  {
    "path": "website/src/content/docs/it-it/book/literal-inference.md",
    "content": "---\ntitle: Inferenza letterale\nsidebar:\n  order: 17\n  label: 17. Inferenza letterale\n---\n\n\nL'inferenza letterale è una funzionalità di TypeScript che consente di dedurre il tipo di una variabile o di un parametro in base al suo valore.\n\nNell'esempio seguente possiamo vedere che TypeScript considera `x` un tipo letterale in quanto il valore non può essere modificato in seguito, mentre `y` viene dedotto come stringa in quanto può essere modificato in seguito.\n\n```typescript\nconst x = 'x'; // Literal type of 'x', because this value cannot be changed\nlet y = 'y'; // Type string, because we can change this value\n```\n\nNell'esempio seguente possiamo vedere che `o.x` è stato dedotto come `string` (e non come un letterale di `a`), poiché TypeScript considera che il valore possa essere modificato in qualsiasi momento successivo.\n\n<!-- skip -->\n```typescript\ntype X = 'a' | 'b';\n\nlet o = {\n    x: 'a', // Questa è una stringa più ampia\n};\n\nconst fn = (x: X) => `${x}-foo`;\n\nconsole.log(fn(o.x)); // L'argomento di tipo 'string' non è assegnabile al parametro di tipo 'X'\n```\n\nCome puoi vedere, il codice genera un errore quando si passa `o.x` a `fn`, poiché X è un tipo più ristretto.\n\nPossiamo risolvere questo problema utilizzando l'asserzione di tipo `const` o il tipo `X`:\n\n<!-- skip -->\n```typescript\nlet o = {\n    x: 'a' as const,\n};\n```\n\noppure:\n\n<!-- skip -->\n```typescript\nlet o = {\n    x: 'a' as X,\n};\n```\n\n"
  },
  {
    "path": "website/src/content/docs/it-it/book/literal-types.md",
    "content": "---\ntitle: Tipi letterali\nsidebar:\n  order: 16\n  label: 16. Tipi letterali\n---\n\n\nUn tipo letterale è un singolo insieme di elementi di un tipo collettivo; definisce un valore molto preciso che è una primitiva JavaScript.\n\nI tipi letterali in TypeScript sono numeri, stringhe e booleani.\n\nEsempio di letterali:\n\n```typescript\nconst a = 'a'; // Stringa tipo letterale\n\nconst b = 1; // Numeric literal type\nconst c = true; // Boolean literal type\n```\n\nI tipi letterali stringa, numerico e booleano vengono utilizzati nell'unione, nella protezione dei tipi e negli alias di tipo.\nNell'esempio seguente, è possibile vedere un alias di tipo unione. `O` è costituito solo dai valori specificati, nessun'altra stringa è valida:\n\n```typescript\ntype O = 'a' | 'b' | 'c';\n```\n\n"
  },
  {
    "path": "website/src/content/docs/it-it/book/mapped-type-modifiers.md",
    "content": "---\ntitle: Modificatori di tipo mappati\nsidebar:\n  order: 38\n  label: 38. Modificatori di tipo mappati\n---\n\n\nI modificatori di tipo mappati in TypeScript consentono la trasformazione delle proprietà all'interno di un tipo esistente:\n\n* `readonly` o `+readonly`: questo rende una proprietà nel tipo mappato di sola lettura.\n* `-readonly`: questo consente a una proprietà nel tipo mappato di essere modificabile.\n* `?`: questo designa una proprietà nel tipo mappato come facoltativa.\n\nEsempi:\n\n```typescript\ntype ReadOnly<T> = { readonly [P in keyof T]: T[P] }; // Tutte le proprietà contrassegnate come di sola lettura\n\ntype Mutable<T> = { -readonly [P in keyof T]: T[P] }; // Tutte le proprietà contrassegnate come modificabili\n\ntype MyPartial<T> = { [P in keyof T]?: T[P] }; // Tutte le proprietà contrassegnate come facoltative\n```\n\n"
  },
  {
    "path": "website/src/content/docs/it-it/book/mapped-types.md",
    "content": "---\ntitle: Tipi mappati\nsidebar:\n  order: 37\n  label: 37. Tipi mappati\n---\n\n\nI tipi mappati in TypeScript consentono di creare nuovi tipi basati su un tipo esistente trasformando ciascuna proprietà tramite una funzione di mappatura. Mappando i tipi esistenti, è possibile creare nuovi tipi che rappresentano le stesse informazioni in un formato diverso. Per creare un tipo mappato, si accede alle proprietà di un tipo esistente utilizzando l'operatore `keyof` e quindi le si modifica per produrre un nuovo tipo.\nNell'esempio seguente:\n\n```typescript\ntype MyMappedType<T> = {\n    [P in keyof T]: T[P][];\n};\ntype MyType = {\n    foo: string;\n    bar: number;\n};\ntype MyNewType = MyMappedType<MyType>;\nconst x: MyNewType = {\n    foo: ['hello', 'world'],\n    bar: [1, 2, 3],\n};\n```\n\nDefiniamo MyMappedType per mappare le proprietà di T, creando un nuovo tipo con ogni proprietà come array del suo tipo originale. In questo modo, creiamo MyNewType per rappresentare le stesse informazioni di MyType, ma con ogni proprietà come array.\n\n"
  },
  {
    "path": "website/src/content/docs/it-it/book/merging-and-extension.md",
    "content": "---\ntitle: Unione ed estensione\nsidebar:\n  order: 52\n  label: 52. Unione ed estensione\n---\n\n\nMerging ed estensione si riferiscono a due concetti diversi relativi all'utilizzo di tipi e interfacce.\n\nMerging consente di combinare più dichiarazioni con lo stesso nome in un'unica definizione, ad esempio quando si definisce un'interfaccia con lo stesso nome più volte:\n\n```typescript\ninterface X {\n    a: string;\n}\n\ninterface X {\n    b: number;\n}\n\nconst person: X = {\n    a: 'a',\n    b: 7,\n};\n```\n\nL'estensione si riferisce alla possibilità di estendere o ereditare da tipi o interfacce esistenti per crearne di nuovi. È un meccanismo per aggiungere proprietà o metodi aggiuntivi a un tipo esistente senza modificarne la definizione originale. Esempio:\n\n```typescript\ninterface Animal {\n    name: string;\n    eat(): void;\n}\n\ninterface Bird extends Animal {\n    sing(): void;\n}\n\nconst dog: Bird = {\n    name: 'Bird 1',\n    eat() {\n        console.log('Eating');\n    },\n    sing() {\n        console.log('Singing');\n    },\n};\n```\n\n"
  },
  {
    "path": "website/src/content/docs/it-it/book/named-tuple-type-labeled.md",
    "content": "---\ntitle: Tipo di tupla denominato (etichettato)\nsidebar:\n  order: 29\n  label: 29. Tipo di tupla denominato (etichettato)\n---\n\n\nI tipi di tupla possono includere etichette o nomi opzionali per ciascun elemento. Queste etichette servono per migliorare la leggibilità e facilitare l'utilizzo degli strumenti e non influiscono sulle operazioni che è possibile eseguire con esse.\n\n```typescript\ntype T = string;\ntype Tuple1 = [T, T];\ntype Tuple2 = [a: T, b: T];\ntype Tuple3 = [a: T, T]; // Tupla con nome più Tupla anonima\n```\n\n"
  },
  {
    "path": "website/src/content/docs/it-it/book/namespacing.md",
    "content": "---\ntitle: Namespace\nsidebar:\n  order: 57\n  label: 57. Namespace\n---\n\n\nIn TypeScript, gli spazi dei nomi vengono utilizzati per organizzare il codice in contenitori logici, prevenendo collisioni di nomi e fornendo un modo per raggruppare il codice correlato.\nL'utilizzo delle parole chiave `export` consente l'accesso allo spazio dei nomi nei moduli \"esterni\".\n\n```typescript\nexport namespace MyNamespace {\n    export interface MyInterface1 {\n        prop1: boolean;\n    }\n    export interface MyInterface2 {\n        prop2: string;\n    }\n}\n\nconst a: MyNamespace.MyInterface1 = {\n    prop1: true,\n};\n```\n\n"
  },
  {
    "path": "website/src/content/docs/it-it/book/narrowing.md",
    "content": "---\ntitle: Restringimento\nsidebar:\n  order: 20\n  label: 20. Restringimento\n---\n\n\nIl restringimento di TypeScript è il processo di perfezionamento del tipo di una variabile all'interno di un blocco condizionale. Questo è utile quando si lavora con tipi union, in cui una variabile può avere più di un tipo.\n\nTypeScript riconosce diversi modi per restringere il tipo:\n\n### protezioni di tipo typeof\n\nIl type guard typeof è uno specifico type guard in TypeScript che controlla il tipo di una variabile in base al suo tipo JavaScript predefinito.\n\n```typescript\nconst fn = (x: number | string) => {\n    if (typeof x === 'number') {\n        return x + 1; // x è un numero\n    }\n    return -1;\n};\n```\n\n### Restringimento di veridicità\n\nIl restringimento di veridicità in TypeScript funziona verificando se una variabile è vera o falsa, per restringerne di conseguenza il tipo.\n\n```typescript\nconst toUpperCase = (name: string | null) => {\n    if (name) {\n        return name.toUpperCase();\n    } else {\n        return null;\n    }\n};\n```\n\n### Restringimento di uguaglianza\n\nIl restringimento di uguaglianza in TypeScript funziona verificando se una variabile è uguale o meno a un valore specifico, per restringerne di conseguenza il tipo.\n\nViene utilizzato insieme alle istruzioni `switch` e agli operatori di uguaglianza come `===`, `!==`, `==` e `!=` per restringere i tipi.\n\n```typescript\nconst checkStatus = (status: 'success' | 'error') => {\n    switch (status) {\n        case 'success':\n            return true;\n        case 'error':\n            return null;\n    }\n};\n```\n\n### Restringimento dell'operatore `in`\n\nIl restringimento dell'operatore `in` in TypeScript è un modo per restringere il tipo di una variabile in base all'esistenza di una proprietà all'interno del tipo della variabile.\n\n```typescript\ntype Dog = {\n    name: string;\n    breed: string;\n};\n\ntype Cat = {\n    name: string;\n    likesCream: boolean;\n};\n\nconst getAnimalType = (pet: Dog | Cat) => {\n    if ('breed' in pet) {\n        return 'dog';\n    } else {\n        return 'cat';\n    }\n};\n```\n\n### Restringimento instanceof\n\nL'operatore di restringimento `instanceof` in TypeScript è un modo per restringere il tipo di una variabile in base alla sua funzione costruttore, verificando se un oggetto è un'istanza di una determinata classe o interfaccia.\n\n```typescript\nclass Square {\n    constructor(public width: number) {}\n}\nclass Rectangle {\n    constructor(\n        public width: number,\n        public height: number\n    ) {}\n}\nfunction area(shape: Square | Rectangle) {\n    if (shape instanceof Square) {\n        return shape.width * shape.width;\n    } else {\n        return shape.width * shape.height;\n    }\n}\nconst square = new Square(5);\nconst rectangle = new Rectangle(5, 10);\nconsole.log(area(square)); // 25\nconsole.log(area(rectangle)); // 50\n```\n\n"
  },
  {
    "path": "website/src/content/docs/it-it/book/never-type.md",
    "content": "---\ntitle: Tipo Never\nsidebar:\n  order: 47\n  label: 47. Tipo Never\n---\n\n\nIl tipo `never` rappresenta valori che non si verificano mai. Viene utilizzato per indicare funzioni o espressioni che non restituiscono mai né generano errori.\n\nAd esempio, un ciclo infinito:\n\n```typescript\nconst infiniteLoop = (): never => {\n    while (true) {\n        // fai qualcosa\n    }\n};\n```\n\nGenerazione di un errore:\n\n```typescript\nconst throwError = (message: string): never => {\n    throw new Error(message);\n};\n```\n\nIl tipo `never` è utile per garantire la sicurezza dei tipi e rilevare potenziali errori nel codice. Aiuta TypeScript ad analizzare e dedurre tipi più precisi se utilizzato in combinazione con altri tipi e istruzioni di controllo del flusso, ad esempio:\n\n```typescript\ntype Direction = 'up' | 'down';\nconst move = (direction: Direction): void => {\n    switch (direction) {\n        case 'up':\n            // sposta verso l'alto\n            break;\n        case 'down':\n            // sposta verso il basso\n            break;\n        default:\n            const exhaustiveCheck: never = direction;\n            throw new Error(`Unhandled direction: ${exhaustiveCheck}`);\n    }\n};\n```\n\n"
  },
  {
    "path": "website/src/content/docs/it-it/book/object-types.md",
    "content": "---\ntitle: Tipi di oggetto\nsidebar:\n  order: 27\n  label: 27. Tipi di oggetto\n---\n\n\nIn TypeScript, i tipi di oggetto descrivono la forma di un oggetto. Specificano i nomi e i tipi delle proprietà dell'oggetto, nonché se tali proprietà sono obbligatorie o facoltative.\n\nIn TypeScript, è possibile definire i tipi di oggetto in due modi principali:\n\ninterface, che definisce la forma di un oggetto specificando i nomi, i tipi e l'opzionalità delle sue proprietà.\n\n```typescript\ninterface User {\n    name: string;\n    age: number;\n    email?: string;\n}\n```\n\nUn alias di tipo, simile a un'interfaccia, definisce la forma di un oggetto. Tuttavia, può anche creare un nuovo tipo personalizzato basato su un tipo esistente o su una combinazione di tipi esistenti. Ciò include la definizione di tipi unione, tipi intersezione e altri tipi complessi.\n\n```typescript\ntype Point = {\n    x: number;\n    y: number;\n};\n```\n\nÈ anche possibile definire un tipo in modo anonimo:\n\n```typescript\nconst sum = (x: { a: number; b: number }) => x.a + x.b;\nconsole.log(sum({ a: 5, b: 1 }));\n```\n\n"
  },
  {
    "path": "website/src/content/docs/it-it/book/optional-properties.md",
    "content": "---\ntitle: Proprietà facoltative\nsidebar:\n  order: 12\n  label: 12. Proprietà facoltative\n---\n\n\nUn oggetto può specificare Proprietà facoltative aggiungendo un punto interrogativo `?` alla fine del nome della proprietà:\n\n```typescript\ntype X = {\n    a: number;\n    b?: number; // Facoltativo\n};\n```\n\nÈ possibile specificare un valore predefinito quando una proprietà è facoltativa\"\n\n```typescript\ntype X = {\n    a: number;\n    b?: number;\n};\nconst x = ({ a, b = 100 }: X) => a + b;\n```\n\n"
  },
  {
    "path": "website/src/content/docs/it-it/book/others.md",
    "content": "---\ntitle: Altri\nsidebar:\n  order: 61\n  label: 61. Altri\n---\n\n\n### Gestione degli errori e delle eccezioni\n\nTypeScript consente di rilevare e gestire gli errori utilizzando i meccanismi standard di gestione degli errori JavaScript:\n\nBlocchi Try-Catch-Finally:\n\n```typescript\ntry {\n    // Codice che potrebbe generare un errore\n} catch (error) {\n    // Gestisci l'errore\n} finally {\n    // Codice che viene sempre eseguito, finally è facoltativo\n}\n```\n\nÈ anche possibile gestire diversi tipi di errore:\n\n```typescript\ntry {\n    // Codice che potrebbe generare diversi tipi di errore\n} catch (error) {\n    if (error instanceof TypeError) {\n        // Gestisci TypeError\n    } else if (error instanceof RangeError) {\n        // Gestisci RangeError\n    } else {\n        // Gestisci altri errori\n    }\n}\n```\n\nTipi di errore personalizzati:\n\nÈ possibile specificare errori più specifici estendendo la classe `Error`:\n\n```typescript\nclass CustomError extends Error {\n    constructor(message: string) {\n        super(message);\n        this.name = 'CustomError';\n    }\n}\n\nthrow new CustomError('Questo è un errore personalizzato.');\n```\n\n### Classi Mixin\n\nLe classi Mixin consentono di combinare e comporre il comportamento di più classi in un'unica classe. Forniscono un modo per riutilizzare ed estendere le funzionalità senza la necessità di catene di ereditarietà profonde.\n\n```typescript\nabstract class Identificabile {\n    name: string = '';\n\n    logId() {\n        console.log('id:', this.name);\n    }\n}\n\nabstract class Selezionabile {\n    selected: boolean = false;\n\n    select() {\n        this.selected = true;\n        console.log('Select');\n    }\n\n    deselect() {\n        this.selected = false;\n        console.log('Deselect');\n    }\n}\n\nclass MyClass {\n    constructor() {}\n}\n\n// Estendi MyClass per includere il comportamento di Identificabile e Selezionabile\ninterface MyClass extends Identificabile, Selezionabile {}\n\n// Funzione per applicare i mixin a una classe\nfunction applyMixins(source: any, baseCtors: any[]) {\n    baseCtors.forEach(baseCtor => {\n        Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => {\n            const descriptor = Object.getOwnPropertyDescriptor(\n                baseCtor.prototype,\n                name\n            );\n            if (descriptor) {\n                Object.defineProperty(source.prototype, name, descriptor);\n            }\n        });\n    });\n}\n\n// Applica i mixin a MyClass\napplyMixins(MyClass, [Identificabile, Selezionabile]);\n\nlet o = new MyClass();\no.name = 'abc';\no.logId();\no.select();\n```\n\n### Funzionalità del linguaggio asincrono\n\nEssendo TypeScript un superset di JavaScript, integra funzionalità del linguaggio asincrono come:\n\nPromise:\n\nLe promise sono un modo per gestire le operazioni asincrone e i loro risultati utilizzando metodi come `.then()` e `.catch()` per gestire le condizioni di successo e di errore.\n\nPer saperne di più: [https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)\n\nAsync/await:\n\nLe parole chiave Async/await sono un modo per fornire una sintassi più sincrona per lavorare con le promise. La parola chiave `async` viene utilizzata per definire una funzione asincrona, mentre la parola chiave `await` viene utilizzata all'interno di una funzione asincrona per mettere in pausa l'esecuzione finché una Promise non viene risolta o rifiutata.\n\nPer saperne di più:\n[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function)\n[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await)\n\nLe seguenti API sono ben supportate in TypeScript:\n\nAPI Fetch:\n\n[https://developer.mozilla.org/it/docs/Web/API/Fetch_API](https://developer.mozilla.org/it/docs/Web/API/Fetch_API)\n\nWeb Worker:\n[https://developer.mozilla.org/it/docs/Web/API/Web_Workers_API](https://developer.mozilla.org/it/docs/Web/API/Web_Workers_API)\n\nCondiviso Worker:\n[https://developer.mozilla.org/en-US/docs/Web/API/SharedWorker](https://developer.mozilla.org/en-US/docs/Web/API/SharedWorker)\n\nWebSocket:\n[https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API)\n\n### Iteratori e Generatori\n\nSia gli Iteratori che i Generatori sono ben supportati in TypeScript.\n\nGli Iteratori sono oggetti che implementano il protocollo Iterator, fornendo un modo per accedere agli elementi di una collezione o sequenza uno alla volta. Si tratta di una struttura che contiene un puntatore all'elemento successivo nell'iterazione. Hanno un metodo `next()` che restituisce il valore successivo nella sequenza insieme a un valore booleano che indica se la sequenza è `completata`.\n\n```typescript\nclass NumberIterator implements Iterable<number> {\n    private current: number;\n\n    constructor(\n        private start: number,\n        private end: number\n    ) {\n        this.current = start;\n    }\n\n    public next(): IteratorResult<number> {\n        if (this.current <= this.end) {\n            const value = this.current;\n            this.current++;\n            return { value, done: false };\n        } else {\n            return { value: undefined, done: true };\n        }\n    }\n\n    [Symbol.iterator](): Iterator<number> {\n        return this;\n    }\n}\n\nconst iterator = new NumberIterator(1, 3);\n\nfor (const num of iterator) {\n    console.log(num);\n}\n```\n\nI generatori sono funzioni speciali definite utilizzando la sintassi `function*` che semplifica la creazione di iteratori. Utilizzano la parola chiave `yield` per definire la sequenza di valori e mettono automaticamente in pausa e riprendono l'esecuzione quando vengono richiesti valori.\n\nI generatori semplificano la creazione di iteratori e sono particolarmente utili per lavorare con sequenze di grandi dimensioni o infinite.\n\nEsempio:\n\n```typescript\nfunction* numberGenerator(start: number, end: number): Generator<number> {\n    for (let i = start; i <= end; i++) {\n        yield i;\n    }\n}\n\nconst generator = numberGenerator(1, 5);\n\nfor (const num of generator) {\n    console.log(num);\n}\n```\n\nTypeScript supporta anche iteratori e generatori asincroni.\n\nPer saperne di più:\n\n[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Generator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Generator)\n\n[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Iterator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Iterator)\n\n### Riferimento JSDoc di TsDocs\n\nQuando si lavora con una base di codice JavaScript, è possibile aiutare TypeScript a dedurre il tipo corretto utilizzando commenti JSDoc con annotazioni aggiuntive per fornire informazioni sul tipo.\n\nEsempio:\n\n```typescript\n/**\n * Calcola la potenza di un numero dato\n * @constructor\n * @param {number} base – Il valore base dell'espressione\n * @param {number} exponent – ​​Il valore esponente dell'espressione\n */\nfunction power(base: number, exponent: number) {\n    return Math.pow(base, exponent);\n}\npower(10, 2); // function power(base: number, exponent: number): number\n```\n\nLa documentazione completa è disponibile a questo link:\n\n[https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html](https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html)\n\nDalla versione 3.7 è possibile generare definizioni di tipo .d.ts dalla sintassi JavaScript JSDoc.\nUlteriori informazioni sono disponibili qui:\n[https://www.typescriptlang.org/docs/handbook/declaration-files/dts-from-js.html](https://www.typescriptlang.org/docs/handbook/declaration-files/dts-from-js.html)\n\n### @types\n\nI pacchetti nell'organizzazione @types sono convenzioni di denominazione speciali utilizzate per fornire definizioni di tipo per librerie o moduli JavaScript esistenti. Ad esempio, usando:\n\n```shell\nnpm install --save-dev @types/lodash\n```\n\nInstallerà le definizioni di tipo di `lodash` nel tuo progetto corrente.\n\nPer contribuire alle definizioni di tipo del pacchetto @types, invia una pull request a [https://github.com/DefinitelyTyped/DefinitelyTyped](https://github.com/DefinitelyTyped/DefinitelyTyped).\n\n### JSX\n\nJSX (JavaScript XML) è un'estensione della sintassi del linguaggio JavaScript che consente di scrivere codice simile a HTML all'interno dei file JavaScript o TypeScript. Viene comunemente utilizzato in React per definire la struttura HTML.\n\nTypeScript extends le funzionalità di JSX fornendo il controllo dei tipi e l'analisi statica.\n\nPer utilizzare JSX è necessario impostare l'opzione del compilatore `jsx` nel file `tsconfig.json`. Due opzioni di configurazione comuni:\n\n* \"preserve\": emette file .jsx con il JSX invariato. Questa opzione indica a TypeScript di mantenere la sintassi JSX così com'è e di non trasformarla durante il processo di compilazione. È possibile utilizzare questa opzione se si dispone di uno strumento separato, come Babel, che gestisce la trasformazione.\n* \"react\": abilita la trasformazione JSX integrata di TypeScript. Verrà utilizzato React.createElement.\n\nTutte le opzioni sono disponibili qui:\n[https://www.typescriptlang.org/tsconfig#jsx](https://www.typescriptlang.org/tsconfig#jsx)\n\n### Moduli ES6\n\nTypeScript supporta ES6 (ECMAScript 2015) e molte versioni successive. Ciò significa che è possibile utilizzare la sintassi ES6, come funzioni freccia, letterali template, classi, moduli, destrutturazione e altro ancora.\n\nPer abilitare le funzionalità ES6 nel progetto, è possibile specificare la proprietà `target` nel file tsconfig.json.\n\nUn esempio di configurazione:\n\n```json\n{\n  \"compilerOptions\": {\n    \"target\": \"es6\",\n    \"module\": \"es6\",\n    \"moduleResolution\": \"node\",\n    \"sourceMap\": true,\n    \"outDir\": \"dist\"\n  },\n  \"include\": [\"src\"]\n}\n```\n\n### Operatore di elevamento a potenza ES7\n\nL'operatore di elevamento a potenza (`**`) calcola il valore ottenuto elevando il primo operando alla potenza del secondo operando. Funziona in modo simile a `Math.pow()`, ma con la possibilità aggiuntiva di accettare BigInt come operandi.\nTypeScript supporta pienamente questo operatore, utilizzandolo come `target` nel file tsconfig.json `es2016` o versione successiva.\n\n```typescript\nconsole.log(2 ** (2 ** 2)); // 16\n```\n\n### L'istruzione for-await-of\n\nQuesta è una funzionalità JavaScript completamente supportata in TypeScript che consente di iterare su oggetti iterabili asincroni dalla versione target es2018.\n\n```typescript\nasync function* asyncNumbers(): AsyncIterableIterator<number> {\n    yield Promise.resolve(1);\n    yield Promise.resolve(2);\n    yield Promise.resolve(3);\n}\n\n(async () => {\n    for await (const num of asyncNumbers()) {\n        console.log(num);\n    }\n})();\n```\n\n### Nuova meta-proprietà target\n\nIn TypeScript è possibile utilizzare la meta-proprietà `new.target`, che consente di determinare se una funzione o un costruttore è stato invocato utilizzando l'operatore new. Permette inoltre di rilevare se un oggetto è stato creato a seguito di una chiamata al costruttore.\n\n```typescript\nclass Parent {\n    constructor() {\n        console.log(new.target); // Registra la funzione costruttore utilizzata per creare un'istanza\n    }\n}\n\nclass Child extends Parent {\n    constructor() {\n        super();\n    }\n}\n\nconst parentX = new Parent(); // [Function: Parent]\nconst child = new Child(); // [Function: Child]\n```\n\n### Espressioni di importazione dinamica\n\nÈ possibile caricare i moduli in modo condizionale o caricarli in modo differito su richiesta utilizzando la proposta ECMAScript per l'importazione dinamica, supportata in TypeScript.\n\nLa sintassi per le espressioni di importazione dinamica in TypeScript è la seguente:\n\n<!-- skip -->\n```typescript\nasync function renderWidget() {\n    const container = document.getElementById('widget');\n    if (container !== null) {\n        const widget = await import('./widget'); // Importazione dinamica\n        widget.render(container);\n    }\n}\n\nrenderWidget();\n```\n\n### \"tsc –watch\"\n\nQuesto comando avvia un compilatore TypeScript con il parametro `--watch`, con la possibilità di ricompilare automaticamente i file TypeScript ogni volta che vengono modificati.\n\n```shell\ntsc --watch\n```\n\nA partire dalla versione 4.9 di TypeScript, il monitoraggio dei file si basa principalmente sugli eventi del file system, ricorrendo automaticamente al polling se non è possibile stabilire un watcher basato sugli eventi.\n\n### Operatore di asserzione non nullo\n\nL'operatore di asserzione non nullo (Postfix !), noto anche come asserzione di assegnazione definita, è una funzionalità di TypeScript che consente di affermare che una variabile o una proprietà non è nulla o indefinita, anche se l'analisi statica dei tipi di TypeScript suggerisce che potrebbe esserlo. Con questa funzionalità è possibile rimuovere qualsiasi controllo esplicito.\n\n```typescript\ntype Person = {\n    name: string;\n};\n\nconst printName = (person?: Person) => {\n    console.log(`Name is ${person!.name}`);\n};\n```\n\n### Dichiarazioni predefinite\n\nLe dichiarazioni predefinite vengono utilizzate quando a una variabile o a un parametro viene assegnato un valore predefinito. Ciò significa che se non viene fornito alcun valore per quella variabile o parametro, verrà utilizzato il valore predefinito.\n\n```typescript\nfunction greet(name: string = 'Anonymous'): void {\n    console.log(`Ciao, ${name}!`);\n}\ngreet(); // Ciao, Anonymous!\ngreet('John'); // Ciao, John!\n```\n\n### Concatenamento opzionale\n\nL'operatore di concatenamento opzionale `?.` funziona come il normale operatore punto (`.`) per accedere a proprietà o metodi. Tuttavia, gestisce in modo elegante i valori nulli o indefiniti terminando l'espressione e restituendo `undefined`, invece di generare un errore.\n\n```typescript\ntype Person = {\n    name: string;\n    age?: number;\n    address?: {\n        street?: string;\n        city?: string;\n    };\n};\n\nconst person: Person = {\n    name: 'John',\n};\n\nconsole.log(person.address?.city); // indefinito\n```\n\n### Operatore di coalescenza nullo\n\nL'operatore di coalescenza nullo `??` restituisce il valore del lato destro se il lato sinistro è `null` o `undefined`; in caso contrario, restituisce il valore del lato sinistro.\n\n```typescript\nconst foo = null ?? 'foo';\nconsole.log(foo); // foo\n\nconst baz = 1 ?? 'baz';\nconst baz2 = 0 ?? 'baz';\nconsole.log(baz); // 1\nconsole.log(baz2); // 0\n```\n\n### Tipi letterali di template\n\nI tipi letterali modello consentono di manipolare i valori stringa a livello di tipo e di generare nuovi tipi stringa basati su quelli esistenti. Sono utili per creare tipi più espressivi e precisi da operazioni basate su stringhe.\n\n```typescript\ntype Department = 'engineering' | 'hr';\ntype Language = 'english' | 'spanish';\ntype Id = `${Department}-${Language}-id`; // \"engineering-english-id\" | \"engineering-spanish-id\" | \"hr-english-id\" | \"hr-spanish-id\"\n```\n\n### Sovraccarico di funzioni\n\nIl sovraccarico di funzioni consente di definire più firme di funzione per lo stesso nome di funzione, ciascuna con tipi di parametro e tipo di ritorno diversi.\nQuando si chiama una funzione sovraccaricata, TypeScript utilizza gli argomenti forniti per determinare la firma di funzione corretta:\n\n```typescript\nfunction makeGreeting(name: string): string;\nfunction makeGreeting(names: string[]): string[];\n\nfunction makeGreeting(person: unknown): unknown {\n    if (typeof person === 'string') {\n        return `Ciao ${person}!`;\n    } else if (Array.isArray(person)) {\n        return person.map(name => `Ciao, ${name}!`);\n    }\n    throw new Error('Impossibile salutare');\n}\n\nmakeGreeting('Simon');\nmakeGreeting(['Simone', 'John']);\n```\n\n### Tipi ricorsivi\n\nUn tipo ricorsivo è un tipo che può fare riferimento a se stesso. Questo è utile per definire strutture dati che hanno una struttura gerarchica o ricorsiva (annidamento potenzialmente infinito), come liste concatenate, alberi e grafi.\n\n```typescript\ntype ListNode<T> = {\n    data: T;\n    next: ListNode<T> | undefined;\n};\n```\n\n### Tipi condizionali ricorsivi\n\nÈ possibile definire relazioni di tipo complesse utilizzando la logica e la ricorsione in TypeScript.\nAnalizziamole in termini semplici:\n\nTipi condizionali: consente di definire tipi in base a condizioni booleane:\n\n```typescript\ntype CheckNumber<T> = T extends number ? 'Number' : 'Not a number';\ntype A = CheckNumber<123>; // 'Number'\ntype B = CheckNumber<'abc'>; // 'Not a number'\n```\n\nRicorsione: indica una definizione di tipo che fa riferimento a se stessa all'interno della propria definizione:\n\n```typescript\ntype Json = string | number | boolean | null | Json[] | { [key: string]: Json };\n\nconst data: Json = {\n    prop1: true,\n    prop2: 'prop2',\n    prop3: {\n        prop4: [],\n    },\n};\n```\n\nI tipi condizionali ricorsivi combinano sia la logica condizionale che la ricorsione. Ciò significa che una definizione di tipo può dipendere da se stessa tramite la logica condizionale, creando relazioni di tipo complesse e flessibili.\n\n```typescript\ntype Flatten<T> = T extends Array<infer U> ? Flatten<U> : T;\n\ntype NestedArray = [1, [2, [3, 4], 5], 6];\ntype FlattenedArray = Flatten<NestedArray>; // 2 | 3 | 4 | 5 | 1 | 6\n```\n\n### Supporto per i moduli ECMAScript in Node\n\nNode.js ha aggiunto il supporto per i moduli ECMAScript a partire dalla versione 15.3.0, mentre TypeScript supporta i moduli ECMAScript per Node.js dalla versione 4.7. Questo supporto può essere abilitato utilizzando la proprietà `module` con il valore `nodenext` nel file tsconfig.json. Ecco un esempio:\n\n```json\n{\n  \"compilerOptions\": {\n    \"module\": \"nodenext\",\n    \"outDir\": \"./lib\",\n    \"declaration\": true\n  }\n}\n```\n\nNode.js supporta due estensioni di file per i moduli: `.mjs` per i moduli ES e `.cjs` per i moduli CommonJS. Le estensioni di file equivalenti in TypeScript sono `.mts` per i moduli ES e `.cts` per i moduli CommonJS. Quando il compilatore TypeScript trascrive questi file in JavaScript, creerà i file `.mjs` e `.cjs`.\n\nSe desideri utilizzare moduli ES nel tuo progetto, puoi impostare la proprietà `type` su \"module\" nel file package.json. Questo indica a Node.js di trattare il progetto come un progetto di modulo ES.\n\nInoltre, TypeScript supporta anche le dichiarazioni di tipo nei file .d.ts. Questi file di dichiarazione forniscono informazioni sul tipo per librerie o moduli scritti in TypeScript, consentendo ad altri sviluppatori di utilizzarli con le funzionalità di controllo del tipo e di completamento automatico di TypeScript.\n\n### Funzioni di asserzione\n\nIn TypeScript, le funzioni di asserzione sono funzioni che indicano la verifica di una condizione specifica in base al loro valore di ritorno. Nella loro forma più semplice, una funzione di asserzione esamina un predicato fornito e genera un errore quando il predicato restituisce false.\n\n```typescript\nfunction isNumber(value: unknown): asserts value is number {\n    if (typeof value !== 'number') {\n        throw new Error('Not a number');\n    }\n}\n```\n\nOppure può essere dichiarato come espressione di funzione:\n\n```typescript\ntype AssertIsNumber = (value: unknown) => asserts value is number;\nconst isNumber: AssertIsNumber = value => {\n    if (typeof value !== 'number') {\n        throw new Error('Not a number');\n    }\n};\n```\n\nLe funzioni di asserzione condividono alcune somiglianze con le type guard. Le type guard sono state inizialmente introdotte per eseguire controlli in fase di esecuzione e garantire il tipo di un valore all'interno di un ambito specifico.\nNello specifico, una type guard è una funzione che valuta un predicato di tipo e restituisce un valore booleano che indica se il predicato è vero o falso. Questo differisce leggermente dalle funzioni di asserzione, in cui l'intenzione è quella di generare un errore anziché restituire false quando il predicato non è soddisfatto.\n\nEsempio di type guard:\n\n```typescript\nconst isNumber = (value: unknown): value is number => typeof value === 'number';\n```\n\n### Tipi di tupla variadici\n\nI tipi di tupla variadici sono una funzionalità introdotta nella versione 4.0 di TypeScript. Iniziamo a conoscerli ripassando cos'è una tupla:\n\nUn tipo di tupla è un array di lunghezza definita, di cui è noto il tipo di ogni elemento:\n\n```typescript\ntype Student = [string, number];\nconst [name, age]: Student = ['Simone', 20];\n```\n\nIl termine \"variadico\" significa indefinito (accetta un numero variabile di argomenti).\n\nUna tupla variadica è un tipo di tupla che ha tutte le proprietà di prima, ma la forma esatta non è ancora definita:\n\n```typescript\ntype Bar<T extends unknown[]> = [boolean, ...T, number];\n\ntype A = Bar<[boolean]>; // [booleano, booleano, numero]\ntype B = Bar<['a', 'b']>; // [boolean, 'a', 'b', number]\ntype C = Bar<[]>; // [boolean, number]\n```\n\nNel codice precedente possiamo vedere che la forma della tupla è definita dal generico `T` passato.\n\nLe tuple variadiche possono accettare più generici, il che le rende molto flessibili:\n\n```typescript\ntype Bar<T extends unknown[], G extends unknown[]> = [...T, boolean, ...G];\n\ntype A = Bar<[number], [string]>; // [number, boolean, string]\ntype B = Bar<['a', 'b'], [boolean]>; // [\"a\", \"b\", boolean, boolean]\n```\n\nCon le nuove tuple variadiche possiamo usare:\n\n* Gli spread nella sintassi dei tipi di tupla ora possono essere generici, quindi possiamo rappresentare operazioni di ordine superiore su tuple e array anche quando non conosciamo i tipi effettivi su cui stiamo operando.\n* Gli elementi rimanenti possono trovarsi ovunque in una tupla.\n\nEsempio:\n\n```typescript\ntype Items = readonly unknown[];\n\nfunction concat<T extends Items, U extends Items>(\n    arr1: T,\n    arr2: U\n): [...T, ...U] {\n    return [...arr1, ...arr2];\n}\n\nconcat([1, 2, 3], ['4', '5', '6']); // [1, 2, 3, \"4\", \"5\", \"6\"]\n```\n\n### Tipi boxed\n\nI tipi boxed si riferiscono agli oggetti wrapper utilizzati per rappresentare i tipi primitivi come oggetti. Questi oggetti wrapper forniscono funzionalità e metodi aggiuntivi che non sono disponibili direttamente sui valori primitivi.\n\nQuando si accede a un metodo come `charAt` o `normalize` su una primitiva `string`, JavaScript lo racchiude in un oggetto `String`, chiama il metodo e quindi elimina l'oggetto.\n\nDimostrazione:\n\n```typescript\nconst originalNormalize = String.prototype.normalize;\nString.prototype.normalize = function () {\n    console.log(this, typeof this);\n    return originalNormalize.call(this);\n};\nconsole.log('\\u0041'.normalize());\n```\n\nTypeScript rappresenta questa differenziazione fornendo tipi separati per le primitive e i corrispondenti wrapper di oggetti:\n\n* string => String\n* number => Number\n* boolean => Boolean\n* symbol => Symbol\n* bigint => BigInt\n\nI tipi boxed di solito non sono necessari. Evitare di utilizzare tipi boxed e utilizzare invece type per le primitive, ad esempio `string` invece di `String`.\n\n### Covarianza e Controvarianza in TypeScript\n\nCovarianza e Controvarianza vengono utilizzate per descrivere il funzionamento delle relazioni quando si ha a che fare con l'ereditarietà o l'assegnazione di tipi.\n\nCovarianza significa che una relazione di tipo preserva la direzione dell'ereditarietà o dell'assegnazione, quindi se un tipo A è un sottotipo del tipo B, anche un array di tipo A è considerato un sottotipo di un array di tipo B. La cosa importante da notare qui è che la relazione di sottotipo viene mantenuta, il che significa che Covarianza accetta il sottotipo ma non il supertipo.\n\nLa controvarianza significa che una relazione di tipo inverte la direzione dell'ereditarietà o dell'assegnazione, quindi se un tipo A è un sottotipo del tipo B, allora un array di tipo B è considerato un sottotipo di un array di tipo A. La relazione di sottotipo è invertita, il che significa che la controvarianza accetta il supertipo ma non il sottotipo.\n\nNote: La bivarianza significa accettare sia il supertipo che il sottotipo.\n\nEsempio: supponiamo di avere uno spazio per tutti gli animali e uno spazio separato solo per i cani.\n\nIn covarianza, puoi inserire tutti i cani nello spazio degli animali perché i cani sono un tipo di animale. Ma non puoi inserire tutti gli animali nello spazio dei cani perché potrebbero esserci altri animali mescolati.\n\nIn controvarianza, non puoi inserire tutti gli animali nello spazio dei cani perché lo spazio degli animali potrebbe contenere anche altri animali. Tuttavia, puoi inserire tutti i cani nello spazio degli animali perché tutti i cani sono anche animali.\n\n<!-- skip -->\n```typescript\n// Esempio di covarianza\nclass Animal {\n    name: string;\n    constructor(name: string) {\n        this.name = name;\n    }\n}\n\nclass Dog extends Animal {\n    breed: string;\n    constructor(name: string, breed: string) {\n        super(name);\n        this.breed = breed;\n    }\n}\n\nlet animals: Animal[] = [];\nlet dogs: Dog[] = [];\n\n// La covarianza consente di assegnare l'array del sottotipo (Dog) all'array del supertipo (Animal)\nanimals = dogs;\ndogs = animals; // Non valido: il tipo 'Animal[]' non è assegnabile al tipo 'Dog[]'\n\n// Esempio di controvarianza\ntype Feed<in T> = (animal: T) => void;\n\nlet feedAnimal: Feed<Animal> = (animal: Animal) => {\n    console.log(`Nome animale: ${animal.name}`);\n};\n\nlet feedDog: Feed<Dog> = (dog: Dog) => {\n    console.log(`Nome del cane: ${dog.name}, Razza: ${dog.breed}`);\n};\n\n// La controvarianza consente di assegnare la callback del supertipo (Animal) alla callback del sottotipo (Dog)\nfeedDog = feedAnimal;\nfeedAnimal = feedDog; // Non valido: il tipo 'Feed<Dog>' non è assegnabile al tipo 'Feed<Animal>'.\n```\n\nIn TypeScript, le relazioni di tipo per gli array sono covarianti, mentre le relazioni di tipo per i parametri di funzione sono controvarianti. Ciò significa che TypeScript presenta sia covarianza che controvarianza, a seconda del contesto.\n\n#### Annotazioni di varianza opzionali per i parametri di tipo\n\nA partire da TypeScript 4.7.0, possiamo usare le parole chiave `out` e `in` per specificare l'annotazione di varianza.\n\nPer la covarianza, usare la parola chiave `out`:\n\n```typescript\ntype AnimalCallback<out T> = () => T; // T è covariante in questo caso\n```\n\nE per la controvarianza, usare la parola chiave `in`:\n\n```typescript\ntype AnimalCallback<in T> = (value: T) => void; // T è controvariante in questo caso\n```\n\n### Firme di indice con pattern di stringhe modello\n\nLe firme di indice con pattern di stringhe modello ci consentono di definire firme di indice flessibili utilizzando pattern di stringhe modello. Questa funzionalità ci consente di creare oggetti che possono essere indicizzati con pattern specifici di chiavi stringa, offrendo maggiore controllo e specificità durante l'accesso e la manipolazione delle proprietà.\n\nTypeScript dalla versione 4.4 consente firme di indice per simboli e pattern di stringhe modello.\n\n```typescript\nconst uniqueSymbol = Symbol('description');\n\ntype MyKeys = `key-${string}`;\n\ntype MyObject = {\n    [uniqueSymbol]: string;\n    [key: MyKeys]: number;\n};\n\nconst obj: MyObject = {\n    [uniqueSymbol]: 'Chiave simbolo univoca',\n    'key-a': 123,\n    'key-b': 456,\n};\n\nconsole.log(obj[uniqueSymbol]); // Chiave simbolo univoca\nconsole.log(obj['key-a']); // 123\nconsole.log(obj['key-b']); // 456\n```\n\n### Operatore `satisfies`\n\nL'operatore `satisfies` consente di verificare se un dato tipo soddisfa una specifica interfaccia o condizione. In altre parole, garantisce che un tipo abbia tutte le proprietà e i metodi richiesti da una specifica interfaccia. È un modo per garantire che una variabile rientri nella definizione di un tipo.\nEcco un esempio:\n\n<!-- skip -->\n```typescript\ntype Columns = 'name' | 'nickName' | 'attributes';\n\ntype User = Record<Columns, string | string[] | undefined>;\n\n// Annotazione del tipo tramite `User`\nconst user: User = {\n    name: 'Simone',\n    nickName: undefined,\n    attributes: ['dev', 'admin'],\n};\n\n// Nelle righe seguenti, TypeScript non sarà in grado di dedurre correttamente\nuser.attributes?.map(console.log); // La proprietà 'map' non esiste sul tipo 'string | string[]'. La proprietà 'map' non esiste sul tipo 'string'.\nuser.nickName; // string | string[] | undefined\n\n// Asserzione di tipo tramite `as`\nconst user2 = {\n    name: 'Simon',\n    nickName: undefined,\n    attributes: ['dev', 'admin'],\n} as User;\n\n// Anche in questo caso, TypeScript non sarà in grado di dedurre correttamente\nuser2.attributes?.map(console.log); // La proprietà 'map' non esiste sul tipo 'string | string[]'. La proprietà 'map' non esiste sul tipo 'string'.\nuser2.nickName; // string | string[] | undefined\n\n// Utilizzando gli operatori `satisfies` ora possiamo dedurre correttamente i tipi\nconst user3 = {\n    name: 'Simon',\n    nickName: undefined,\n    attributes: ['dev', 'admin'],\n} satisfies User;\n\nuser3.attributes?.map(console.log); // TypeScript deduce correttamente: string[]\nuser3.nickName; // TypeScript deduce correttamente: undefined\n```\n\n### Importazioni ed esportazioni solo per tipo\n\nLe importazioni ed esportazioni solo per tipo consentono di importare o esportare tipi senza importare o esportare i valori o le funzioni associati a tali tipi. Questo può essere utile per ridurre le dimensioni del bundle.\n\nPer utilizzare le importazioni solo per tipo, è possibile utilizzare la parola chiave `import type`.\n\nTypeScript consente l'utilizzo di estensioni di file sia di dichiarazione che di implementazione (.ts, .mts, .cts e .tsx) nelle importazioni solo tipo, indipendentemente dalle impostazioni `allowImportingTsExtensions`.\n\nAd esempio:\n\n<!-- skip -->\n```typescript\nimport type { House } from './house.ts';\n```\n\nSono supportati i seguenti formati:\n\n<!-- skip -->\n```typescript\nimport type T from './mod';\nimport type { A, B } from './mod';\nimport type * as Types from './mod';\nexport type { T };\nexport type { T } from './mod';\n```\n\n### Dichiarazione using e Gestione Risorse Esplicita\n\nUna dichiarazione `using` è un binding immutabile con ambito a blocco, simile a `const`, utilizzato per la gestione delle risorse usa e getta. Quando inizializzato con un valore, il metodo `Symbol.dispose` di quel valore viene registrato e successivamente eseguito all'uscita dall'ambito del blocco che lo racchiude.\n\nQuesto si basa sulla funzionalità di Gestione Risorse di ECMAScript, utile per eseguire attività di pulizia essenziali dopo la creazione di oggetti, come la chiusura di connessioni, l'eliminazione di file e il rilascio di memoria.\n\nNote:\n\n* A causa della sua recente introduzione nella versione 5.2 di TypeScript, la maggior parte dei runtime non dispone di supporto nativo. Sono necessari polyfill per: `Symbol.dispose`, `Symbol.asyncDispose`, `DisposableStack`, `AsyncDisposableStack`, `SuppressedError`. \\* Inoltre, dovrai configurare il tuo file tsconfig.json come segue:\n\n```json\n{\n  \"compilerOptions\": {\n    \"target\": \"es2022\",\n    \"lib\": [\"es2022\", \"esnext.disposable\", \"dom\"]\n  }\n}\n```\n\nEsempio:\n\n<!-- skip -->\n```typescript\n//@ts-ignore\nSymbol.dispose ??= Symbol('Symbol.dispose'); // Simple polyfill\n\nconst doWork = (): Disposable => {\n    return {\n        [Symbol.dispose]: () => {\n            console.log('disposed');\n        },\n    };\n};\n\nconsole.log(1);\n\n{\n    using work = doWork(); // La risorsa è dichiarata\n    console.log(2);\n} // La risorsa viene eliminata (ad esempio, viene valutata `work[Symbol.dispose]()`)\n\nconsole.log(3);\n```\n\nIl codice registrerà:\n\n```shell\n1\n2\ndisposed\n3\n```\n\nUna risorsa idonea per l'eliminazione deve rispettare l'interfaccia `Disposable`:\n\n```typescript\n// lib.esnext.disposable.d.ts\ninterface Disposable {\n    [Symbol.dispose](): void;\n}\n```\n\nLe dichiarazioni `using` registrano le operazioni di eliminazione delle risorse in uno stack, assicurandosi che vengano eliminate nell'ordine inverso rispetto alla dichiarazione:\n\n<!-- skip -->\n```typescript\n{\n    using j = getA(),\n        y = getB();\n    using k = getC();\n} // elimina `C`, poi `B`, poi `A`.\n```\n\nÈ garantito che le risorse vengano eliminate, anche se si verificano codice o eccezioni successive. Questo potrebbe portare alla generazione di un'eccezione durante l'eliminazione, con la possibile soppressione di un'altra. Per conservare le informazioni sugli errori soppressi, è stata introdotta una nuova eccezione nativa, `SuppressedError`.\n\n#### dichiarazione await using\n\nUna dichiarazione `await using` gestisce una risorsa eliminabile in modo asincrono. Il valore deve avere un metodo `Symbol.asyncDispose`, che verrà atteso alla fine del blocco.\n\n<!-- skip -->\n```typescript\nasync function doWorkAsync() {\n    await using work = doWorkAsync(); // La risorsa viene dichiarata\n} // La risorsa viene eliminata (ad esempio, viene valutata `await work[Symbol.asyncDispose]()`)\n```\n\nPer una risorsa eliminabile in modo asincrono, deve aderire all'interfaccia `Disposable` o `AsyncDisposable`:\n\n```typescript\n// lib.esnext.disposable.d.ts\ninterface AsyncDisposable {\n    [Symbol.asyncDispose](): Promise<void>;\n}\n```\n\n<!-- skip -->\n```typescript\n//@ts-ignore\nSymbol.asyncDispose ??= Symbol('Symbol.asyncDispose'); // Simple polyfill\n\nclass DatabaseConnection implements AsyncDisposable {\n    // Un metodo che viene chiamato quando l'oggetto viene eliminato in modo asincrono\n    [Symbol.asyncDispose]() {\n        // Chiude la connessione e restituisce una promessa\n        return this.close();\n    }\n\n    async close() {\n        console.log('Chiusura della connessione...');\n        await new Promise(resolve => setTimeout(resolve, 1000));\n        console.log('Connessione chiusa.');\n    }\n}\n\nasync function doWork() {\n    // Crea una nuova connessione e la elimina in modo asincrono quando esce dall'ambito\n    await using connection = new DatabaseConnection(); // La risorsa viene dichiarata\n    console.log('Sto lavorando...');\n} // La risorsa viene eliminata (ad esempio, viene valutato `await connection[Symbol.asyncDispose]()`)\n\ndoWork();\n```\n\nIl codice registra:\n\n```shell\nSto lavorando...\nChiusura della connessione...\nConnessione chiusa.\n```\n\nLe dichiarazioni `using` e `await using` sono consentite nelle istruzioni: `for`, `for-in`, `for-of`, `for-await-of`, `switch`.\n\n### Attributi di importazione\n\nGli attributi di importazione di TypeScript 5.3 (etichette per le importazioni) indicano al runtime come gestire i moduli (JSON, ecc.). Questo migliora la sicurezza garantendo importazioni chiare e si allinea con la Content Security Policy (CSP) per un caricamento più sicuro delle risorse. TypeScript garantisce che siano validi, ma lascia che sia il runtime a gestirne l'interpretazione per la gestione di moduli specifici.\n\nEsempio:\n\n<!-- skip -->\n```typescript\nimport config from './config.json' with { type: 'json' };\n```\n\ncon importazione dinamica:\n\n<!-- skip -->\n```typescript\nconst config = import('./config.json', { with: { type: 'json' } });\n```\n"
  },
  {
    "path": "website/src/content/docs/it-it/book/overloads.md",
    "content": "---\ntitle: Sovraccarichi\nsidebar:\n  order: 51\n  label: 51. Sovraccarichi\n---\n\n\nGli overload di funzione in TypeScript consentono di definire più firme di funzione per un singolo nome di funzione, consentendo di definire funzioni che possono essere chiamate in più modi. Ecco un esempio:\n\n```typescript\n// Sovraccarichi\nfunction sayHi(name: string): string;\nfunction sayHi(names: string[]): string[];\n\n// Implementazione\nfunction sayHi(name: unknown): unknown {\n    if (typeof name === 'string') {\n        return `Ciao, ${name}!`;\n    } else if (Array.isArray(name)) {\n        return name.map(name => `Ciao, ${name}!`);\n    }\n    throw new Error('Valore non valido');\n}\n\nsayHi('xx'); // Valido\nsayHi(['aa', 'bb']); // Valido\n```\n\nEcco un altro esempio di utilizzo di overload di funzione all'interno di una `class`:\n\n```typescript\nclass Greeter {\n    message: string;\n\n    constructor(message: string) {\n        this.message = message;\n    }\n\n    // Sovraccarichi\n    sayHi(name: string): string;\n    sayHi(name: string[]): ReadonlyArray<string>;\n\n    // Implementazione\n    sayHi(name: unknown): unknown {\n        if (typeof name === 'string') {\n            return `${this.message}, ${name}!`;\n        } else if (Array.isArray(name)) {\n            return name.map(name => `${this.message}, ${name}!`);\n        }\n        throw new Error('value is invalid');\n    }\n}\nconsole.log(new Greeter('Hello').sayHi('Simon'));\n```\n\n"
  },
  {
    "path": "website/src/content/docs/it-it/book/predefined-conditional-types.md",
    "content": "---\ntitle: Tipi Condizionali Predefiniti\nsidebar:\n  order: 42\n  label: 42. Tipi Condizionali Predefiniti\n---\n\n\nIn TypeScript, i Tipi Condizionali Predefiniti sono tipi condizionali integrati forniti dal linguaggio. Sono progettati per eseguire trasformazioni di tipo comuni in base alle caratteristiche di un dato tipo.\n\n`Exclude<UnionType, ExcludedType>`: questo tipo rimuove da Type tutti i tipi assegnabili a ExcludedType.\n\n`Extract<Type, Union>`: questo tipo estrae da Union tutti i tipi assegnabili a Type.\n\n`NonNullable<Type>`: questo tipo rimuove null e undefined da Type.\n\n`ReturnType<Type>`: questo tipo estrae il tipo di ritorno di un Type di funzione.\n\n`Parameters<Type>`: questo tipo estrae i tipi di parametro di un Type di funzione.\n\n`Required<Type>`: Questo tipo rende obbligatorie tutte le proprietà in Type.\n\n`Partial<Type>`: Questo tipo rende facoltative tutte le proprietà in Type.\n\n`Readonly<Type>`: Questo tipo rende di sola lettura tutte le proprietà in Type.\n\n"
  },
  {
    "path": "website/src/content/docs/it-it/book/primitive-types.md",
    "content": "---\ntitle: Tipi primitivi\nsidebar:\n  order: 10\n  label: 10. Tipi primitivi\n---\n\n\nTypeScript supporta 7 tipi primitivi. Un tipo di dati primitivo si riferisce a un tipo che non è un oggetto e non ha metodi associati. In TypeScript, tutti i tipi primitivi sono immutabili, il che significa che i loro valori non possono essere modificati una volta assegnati.\n\n### string\n\nIl tipo primitivo `string` memorizza dati testuali e il valore è sempre racchiuso tra virgolette doppie o singole.\n\n```typescript\nconst x: string = 'x';\nconst y: string = 'y';\n```\n\nLe stringhe possono estendersi su più righe se racchiuse dal carattere di apice inverso (`):\n\n```typescript\nlet sentence: string = `xxx,\nyyy`;\n```\n\n### boolean\n\nIl tipo di dati `boolean` in TypeScript memorizza un valore binario, `true` o `false`.\n\n```typescript\nconst isReady: boolean = true;\n```\n\n### number\n\nUn tipo di dati `number` in TypeScript è rappresentato da un valore in virgola mobile a 64 bit. Un tipo di dati `number` può rappresentare numeri interi e frazioni.\nTypeScript supporta anche i sistemi di numerazione esadecimale, binario e ottale, ad esempio:\n\n```typescript\nconst decimal: number = 10;\nconst hexadecimal: number = 0xa00d; // L'esadecimale inizia con 0x\nconst binary: number = 0b1010; // Il binario inizia con 0b\nconst octal: number = 0o633; // L'ottale inizia con 0o\n```\n\n### bigInt\n\nUn `bigInt` rappresenta valori numerici molto grandi (253 – 1) e non possono essere rappresentati con un `number`.\n\nUn `bigInt` può essere creato chiamando la funzione integrata `BigInt()` o aggiungendo `n` alla fine di qualsiasi letterale numerico intero:\n\n```typescript\nconst x: bigint = BigInt(9007199254740991);\nconst y: bigint = 9007199254740991n;\n```\n\nNote:\n\n* I valori `bigInt` non possono essere combinati con `number` e non possono essere utilizzati con `Math` integrato, devono essere forzati allo stesso tipo.\n* I valori `bigInt` sono disponibili solo se la configurazione di destinazione è ES2020 o superiore.\n\n### Simbolo\n\nI simboli sono identificatori univoci che possono essere utilizzati come chiavi di proprietà negli oggetti per evitare conflitti di denominazione.\n\n```typescript\ntype Obj = {\n    [sym: symbol]: number;\n};\n\nconst a = Symbol('a');\nconst b = Symbol('b');\nlet obj: Obj = {};\nobj[a] = 123;\nobj[b] = 456;\n\nconsole.log(obj[a]); // 123\nconsole.log(obj[b]); // 456\n```\n\n### null e undefined\n\nI tipi `null` e `undefined` rappresentano entrambi nessun valore o l'assenza di qualsiasi valore.\n\nIl tipo `undefined` indica che il valore non è assegnato o inizializzato o indica un'assenza involontaria di valore.\n\nIl tipo `null` indica che sappiamo che il campo non ha un valore, quindi il valore non è disponibile, e indica un'assenza intenzionale di valore.\n\n### Array\n\nUn `array` è un tipo di dati che può memorizzare più valori dello stesso tipo o meno. Può essere definito utilizzando la seguente sintassi:\n\n```typescript\nconst x: string[] = ['a', 'b'];\nconst y: Array<string> = ['a', 'b'];\nconst j: Array<string | number> = ['a', 1, 'b', 2]; // Unione\n```\n\nTypeScript supporta array di sola lettura utilizzando la seguente sintassi:\n\n<!-- skip -->\n```typescript\nconst x: readonly string[] = ['a', 'b']; // Modificatore di sola lettura\nconst y: ReadonlyArray<string> = ['a', 'b'];\nconst j: ReadonlyArray<string | number> = ['a', 1, 'b', 2];\nj.push('x'); // Non valido\n```\n\nTypeScript supporta tuple e tuple di sola lettura:\n\n```typescript\nconst x: [string, number] = ['a', 1];\nconst y: readonly [string, number] = ['a', 1];\n```\n\n### any\n\nIl tipo di dati ``any` rappresenta letteralmente un valore \"qualsiasi\", ed è il valore predefinito quando TypeScript non può dedurre il tipo o non è specificato.\n\nQuando si utilizza `any`, il compilatore TypeScript salta il controllo del tipo, quindi non c'è sicurezza di tipo quando si utilizza `any`. In genere, non utilizzare `any` per silenziare il compilatore quando si verifica un errore, ma concentrarsi sulla correzione dell'errore, poiché utilizzando `any` è possibile interrompere i contratti e perdere i vantaggi del completamento automatico di TypeScript.\n\nIl tipo `any` potrebbe essere utile durante una migrazione graduale da JavaScript a TypeScript, in quanto può silenziare il compilatore.\n\nPer i nuovi progetti, utilizzare la configurazione TypeScript `noImplicitAny`, che consente a TypeScript di generare errori quando viene utilizzato o dedotto `any`.\n\nIl tipo `any` è solitamente fonte di errori che possono mascherare problemi reali con i tipi. Evitatelo il più possibile.\n\n"
  },
  {
    "path": "website/src/content/docs/it-it/book/readonly-properties.md",
    "content": "---\ntitle: Proprietà di sola lettura\nsidebar:\n  order: 13\n  label: 13. Proprietà di sola lettura\n---\n\n\nÈ possibile impedire la scrittura su una proprietà utilizzando il modificatore `readonly`, che assicura che la proprietà non possa essere riscritta ma non fornisce alcuna garanzia di immutabilità totale:\n\n```typescript\ninterface Y {\n    readonly a: number;\n}\n\ntype X = {\n    readonly a: number;\n};\n\ntype J = Readonly<{\n    a: number;\n}>;\n\ntype K = {\n    readonly [index: number]: string;\n};\n```\n\n"
  },
  {
    "path": "website/src/content/docs/it-it/book/strictnullchecks.md",
    "content": "---\ntitle: strictNullChecks\nsidebar:\n  order: 18\n  label: 18. strictNullChecks\n---\n\n\n`strictNullChecks` è un'opzione del compilatore TypeScript che impone un controllo null rigoroso. Quando questa opzione è abilitata, variabili e parametri possono essere assegnati a `null` o `undefined` solo se sono stati dichiarati esplicitamente di quel tipo utilizzando l'unione `null` | `undefined`. Se una variabile o un parametro non viene dichiarato esplicitamente come nullable, TypeScript genererà un errore per prevenire potenziali errori di runtime.\n\n"
  },
  {
    "path": "website/src/content/docs/it-it/book/symbols.md",
    "content": "---\ntitle: Simboli\nsidebar:\n  order: 58\n  label: 58. Simboli\n---\n\n\nI simboli sono un tipo di dati primitivo che rappresenta un valore immutabile la cui unicità globale è garantita per tutta la durata del programma.\n\nI simboli possono essere utilizzati come chiavi per le proprietà degli oggetti e forniscono un modo per creare proprietà non enumerabili.\n\n```typescript\nconst key1: symbol = Symbol('key1');\nconst key2: symbol = Symbol('key2');\n\nconst obj = {\n    [key1]: 'value 1',\n    [key2]: 'value 2',\n};\n\nconsole.log(obj[key1]); // valore 1\nconsole.log(obj[key2]); // valore 2\n```\n\nIn WeakMaps e WeakSet, i simboli sono ora consentiti come chiavi.\n\n"
  },
  {
    "path": "website/src/content/docs/it-it/book/table-of-contents.md",
    "content": "---\ntitle: Indice\nsidebar:\n  order: 4\n  label: 4. Indice\n---\n\n\n<!-- markdownlint-disable MD004 -->\n\n- The Concise TypeScript Book\n- Traduzioni\n- Download e sito web\n- Indice\n- Introduzione\n- Informazioni sull'autore\n- Introduzione a TypeScript\n  - Cos'è TypeScript?\n  - Perché TypeScript?\n  - TypeScript e JavaScript\n  - Generazione di codice TypeScript\n  - JavaScript moderno ora (Downleveling)\n- Per iniziare con TypeScript\n  - Installazione\n  - Configurazione\n  - File di configurazione TypeScript\n    - target\n    - lib\n    - strict\n    - module\n    - moduleResolution\n    - esModuleInterop\n    - jsx\n    - skipLibCheck\n    - files\n    - include\n    - exclude\n  - importHelpers\n  - Consigli per la migrazione a TypeScript\n- Esplorazione del sistema di tipi\n  - Il servizio di linguaggio TypeScript\n  - Tipizzazione Strutturale\n  - Regole fondamentali di confronto di TypeScript\n  - Tipi come insiemi\n  - Allargamento di tipo\n  - Const\n    - Modificatore Const sui parametri di tipo\n    - Asserzione Const\n  - Annotazione di tipo esplicita\n  - Restringimento dei tipi\n    - Condizioni\n    - Generazione o restituzione\n    - Unione Discriminata\n    - Protezioni di tipo definite dall'utente\n- Tipi primitivi\n  - string\n- Inferenza letterale\n- strictNullChecks\n- Enumerazioni\n  - Enumerazioni numeriche\n  - Enum String\n  - Enum Constant\n  - Mapping inverso\n  - Enum ambientali\n  - Membri calcolati e costanti\n- Restringimento\n  - protezioni di tipo typeof\n  - Restringimento di veridicità\n  - Restringimento di uguaglianza\n  - Restringimento dell'operatore \"in\"\n  - Restringimento instanceof\n- Assegnazioni\n- Analisi del flusso di controllo\n- Tipo da Valore\n- Tipo da Ritorno Funzione\n- Tipo da modulo\n- Tipi mappati\n- Modificatori di tipo mappati\n- Tipi condizionali\n- Tipi condizionali distributivi\n- infer Inferenza di tipo nei tipi condizionali\n- Tipi Condizionali Predefiniti\n- Tipi di unione di template\n- Tipo Any\n- Tipo Unknown\n- Tipo Void\n- Tipo Never\n- Interfaccia e tipo\n  - Sintassi comune\n  - Tipi di base\n  - Oggetti e interfacce\n  - Modificatori di accesso\n  - Get e Set\n  - Accessori automatici nelle classi\n  - this\n  - Proprietà dei parametri\n  - Classi astratte\n  - Con i generici\n  - Decoratori\n    - Decoratori di classe\n    - Decoratore di proprietà\n  - Ereditarietà\n  - Statiche\n  - Inizializzazione delle proprietà\n  - Sovraccarico dei metodi\n- Generici\n  - Tipo generico\n  - Classi generiche\n  - Vincoli generici\n  - Restringimento contestuale generico\n- Tipi strutturali cancellati\n- Namespace\n- Simboli\n- Direttive con tripla barra\n- Manipolazione dei tipi\n  - Creazione di tipi da tipi\n  - Tipi di accesso indicizzati\n  - Tipi di utilità\n    - Awaited\\<T\\>\n    - Partial\\<T\\>\n    - Required\\<T\\>\n    - Readonly\\<T\\>\n    - Record\\<K, T\\>\n    - Pick\\<T, K\\>\n    - Omit\\<T, K\\>\n    - Exclude\\<T, U\\>\n    - Extract\\<T, U\\>\n    - NonNullable\\<T\\>\n    - Parameters\\<T\\>\n    - ConstructorParameters\\<T\\>\n    - ReturnType\\<T\\>\n    - InstanceType\\<T\\>\n    - ThisParameterType\\<T\\>\n    - OmitThisParameter\\<T\\>\n    - ThisType\\<T\\>\n    - Uppercase\\<T\\>\n    - Lowercase\\<T\\>\n    - Capitalize\\<T\\>\n    - Uncapitalize\\<T\\>\n    - NoInfer\\<T\\>\n- Altri\n  - Gestione degli errori e delle eccezioni\n  - Classi Mixin\n  - Funzionalità del linguaggio asincrono\n  - Iteratori e Generatori\n  - Riferimento JSDoc di TsDocs\n  - @types\n  - JSX\n  - Moduli ES6\n  - Operatore di elevamento a potenza ES7\n  - L'istruzione for-await-of\n  - Nuova meta-proprietà target\n  - Espressioni di importazione dinamica\n  - \"tsc –watch\"\n  - Operatore di asserzione non nullo\n  - Dichiarazioni predefinite\n  - Concatenamento opzionale\n  - Operatore di coalescenza nullo\n  - Tipi letterali di template\n  - Sovraccarico di funzioni\n  - Tipi ricorsivi\n  - Tipi condizionali ricorsivi\n  - Supporto per i moduli ECMAScript in Node\n  - Funzioni di asserzione\n  - Tipi di tupla variadici\n  - Tipi boxed\n  - Covarianza e Controvarianza in TypeScript\n    - Annotazioni di varianza opzionali per i parametri di tipo\n  - Firme di indice con pattern di stringhe modello\n  - Operatore `satisfies`\n  - Importazioni ed esportazioni solo per tipo\n  - Dichiarazione using e Gestione Risorse Esplicita\n    - dichiarazione await using\n  - Attributi di importazione\n<!-- markdownlint-enable MD004 -->\n\n"
  },
  {
    "path": "website/src/content/docs/it-it/book/template-union-types.md",
    "content": "---\ntitle: Tipi di unione di template\nsidebar:\n  order: 43\n  label: 43. Tipi di unione di template\n---\n\n\nI tipi di unione di template possono essere utilizzati per unire e manipolare il testo all'interno del sistema di tipi, ad esempio:\n\n```typescript\ntype Status = 'active' | 'inactive';\ntype Products = 'p1' | 'p2';\ntype ProductId = `id-${Products}-${Status}`; // \"id-p1-active\" | \"id-p1-inactive\" | \"id-p2-active\" | \"id-p2-inactive\"\n```\n\n"
  },
  {
    "path": "website/src/content/docs/it-it/book/the-concise-typescript-book.md",
    "content": "---\ntitle: The Concise TypeScript Book\nsidebar:\n  order: 1\n  label: 1. The Concise TypeScript Book\n---\n\n\nThe Concise TypeScript Book offre una panoramica completa e concisa delle funzionalità di TypeScript. Questo libro offre spiegazioni chiare che coprono tutti gli aspetti dell'ultima versione del linguaggio, dal suo potente sistema di tipi alle funzionalità avanzate. Che siate principianti o sviluppatori esperti, questo libro è una risorsa preziosa per migliorare la vostra comprensione e competenza in TypeScript.\n\nQuesto libro è completamente gratuito e open source.\n\nCredo che un'istruzione tecnica di alta qualità debba essere accessibile a tutti, ed è per questo che mantengo questo libro gratuito e aperto.\n\nSe il libro ti ha aiutato a risolvere un bug, a comprendere un concetto ostico o a progredire nella tua carriera, ti prego di considerare di sostenere il mio lavoro pagando quanto vuoi (prezzo suggerito: 15 euro) o sponsorizzando un caffè. Il tuo supporto mi aiuta a mantenere i contenuti aggiornati e ad ampliarli con nuovi esempi e spiegazioni più approfondite.\n\n[![Buy Me a Coffee](https://img.shields.io/badge/buy_me_a_coffee-FFDD00?style=for-the-badge&logo=buy-me-a-coffee&logoColor=black)](https://www.buymeacoffee.com/simonepoggiali)\n\n[![Dona](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.com/donate/?business=QW82ZS956XLFY&no_recurring=0&currency_code=EUR)\n\n"
  },
  {
    "path": "website/src/content/docs/it-it/book/the-never-type.md",
    "content": "---\ntitle: Il tipo never\nsidebar:\n  order: 25\n  label: 25. Il tipo never\n---\n\n\nQuando una variabile viene ristretta a un tipo che non può contenere alcun valore, il compilatore TypeScript dedurrà che la variabile deve essere del tipo `never`. Questo perché il tipo `never` rappresenta un valore che non può mai essere prodotto.\n\n```typescript\nconst printValue = (val: string | number) => {\n    if (typeof val === 'string') {\n        console.log(val.toUpperCase());\n    } else if (typeof val === 'number') {\n        console.log(val.toFixed(2));\n    } else {\n        // val ha il tipo never qui perché non può essere altro che una stringa o un numero\n        const neverVal: never = val;\n        console.log(`Valore imprevisto: ${neverVal}`);\n    }\n};\n```\n\n"
  },
  {
    "path": "website/src/content/docs/it-it/book/translations.md",
    "content": "---\ntitle: Traduzioni\nsidebar:\n  order: 2\n  label: 2. Traduzioni\n---\n\n\nQuesto libro è stato tradotto in diverse lingue, tra cui:\n\n[Cinese](https://github.com/gibbok/typescript-book/blob/main/README-zh_CN.md)\n\n[Italiano](https://github.com/gibbok/typescript-book/blob/main/README-it_IT.md)\n\n[Portoghese (Brasile)](https://github.com/gibbok/typescript-book/blob/main/README-pt_BR.md)\n\n[Svedese](https://github.com/gibbok/typescript-book/blob/main/README-sv_SE.md)\n\n"
  },
  {
    "path": "website/src/content/docs/it-it/book/triple-slash-directives.md",
    "content": "---\ntitle: Direttive con tripla barra\nsidebar:\n  order: 59\n  label: 59. Direttive con tripla barra\n---\n\n\nLe direttive con tripla barra sono commenti speciali che forniscono istruzioni al compilatore su come elaborare un file. Queste direttive iniziano con tre barre consecutive (`///`) e sono in genere posizionate all'inizio di un file TypeScript e non hanno alcun effetto sul comportamento in fase di esecuzione.\n\nLe direttive con tripla barra vengono utilizzate per fare riferimento a dipendenze esterne, specificare il comportamento di caricamento dei moduli, abilitare/disabilitare determinate funzionalità del compilatore e altro ancora. Alcuni esempi:\n\nRiferimento a un file di dichiarazione:\n\n<!-- skip -->\n```typescript\n/// <reference path=\"path/to/declaration/file.d.ts\" />\n```\n\nIndicare il formato del modulo:\n\n<!-- skip -->\n```typescript\n/// <amd|commonjs|system|umd|es6|es2015|none>\n```\n\nAbilitare le opzioni del compilatore, nell'esempio seguente, in modalità strict:\n\n<!-- skip -->\n```typescript\n/// <strict|noImplicitAny|noUnusedLocals|noUnusedParameters>\n```\n\n"
  },
  {
    "path": "website/src/content/docs/it-it/book/tuple-type-anonymous.md",
    "content": "---\ntitle: Tipo di tupla (anonimo)\nsidebar:\n  order: 28\n  label: 28. Tipo di tupla (anonimo)\n---\n\n\nUn tipo di tupla è un tipo che rappresenta un array con un numero fisso di elementi e i relativi tipi. Un tipo di tupla impone un numero specifico di elementi e i rispettivi tipi in un ordine fisso. I tipi di tupla sono utili quando si desidera rappresentare una raccolta di valori con tipi specifici, dove la posizione di ciascun elemento nell'array ha un significato specifico.\n\n```typescript\ntype Point = [number, number];\n```\n\n"
  },
  {
    "path": "website/src/content/docs/it-it/book/type-annotations.md",
    "content": "---\ntitle: Annotazioni di tipo\nsidebar:\n  order: 11\n  label: 11. Annotazioni di tipo\n---\n\n\nSulle variabili dichiarate usando `var`, `let` e `const`, è possibile aggiungere facoltativamente un tipo:\n\n```typescript\nconst x: number = 1;\n```\n\nTypeScript esegue un buon lavoro nell'inferenza dei tipi, soprattutto quando si tratta di tipi semplici, quindi queste dichiarazioni nella maggior parte dei casi non sono necessarie.\n\nSulle funzioni è possibile aggiungere annotazioni di tipo ai parametri:\n\n```typescript\nfunction sum(a: number, b: number) {\n    return a + b;\n}\n```\n\nIl seguente è un esempio che utilizza una funzione anonima (la cosiddetta funzione lambda):\n\n```typescript\nconst sum = (a: number, b: number) => a + b;\n```\n\nQueste annotazioni possono essere evitate quando è presente un valore predefinito per un parametro:\n\n```typescript\nconst sum = (a = 10, b: number) => a + b;\n```\n\nLe annotazioni del tipo di ritorno possono essere aggiunte alle funzioni:\n\n```typescript\nconst sum = (a = 10, b: number): number => a + b;\n```\n\nQuesto è utile soprattutto per le funzioni più complesse, poiché scrivere esplicitamente il tipo di ritorno prima di un'implementazione può aiutare a pensare meglio alla funzione.\n\nIn genere, si consiglia di annotare le firme dei tipi, ma non le variabili locali del corpo, e di aggiungere i tipi sempre ai letterali degli oggetti.\n\n"
  },
  {
    "path": "website/src/content/docs/it-it/book/type-from-func-return.md",
    "content": "---\ntitle: Tipo da Ritorno Funzione\nsidebar:\n  order: 35\n  label: 35. Tipo da Ritorno Funzione\n---\n\n\nIl tipo da Ritorno Funzione si riferisce alla possibilità di inferire automaticamente il tipo di ritorno di una funzione in base alla sua implementazione. Ciò consente a TypeScript di determinare il tipo del valore restituito dalla funzione senza annotazioni di tipo esplicite.\n\n```typescript\nconst add = (x: number, y: number) => x + y; // TypeScript può dedurre che il tipo restituito dalla funzione sia un numero\n```\n\n"
  },
  {
    "path": "website/src/content/docs/it-it/book/type-from-module.md",
    "content": "---\ntitle: Tipo da modulo\nsidebar:\n  order: 36\n  label: 36. Tipo da modulo\n---\n\n\nIl tipo da modulo si riferisce alla possibilità di utilizzare i valori esportati di un modulo per dedurne automaticamente il tipo. Quando un modulo esporta un valore con un tipo specifico, TypeScript può utilizzare tali informazioni per dedurre automaticamente il tipo di quel valore quando viene importato in un altro modulo.\n\n<!-- skip -->\n```typescript\n// calc.ts\nexport const add = (x: number, y: number) => x + y;\n// index.ts\nimport { add } from 'calc';\nconst r = add(1, 2); // r è un numero\n```\n\n"
  },
  {
    "path": "website/src/content/docs/it-it/book/type-from-value.md",
    "content": "---\ntitle: Tipo da Valore\nsidebar:\n  order: 34\n  label: 34. Tipo da Valore\n---\n\n\nIn TypeScript, il tipo da valore si riferisce all'inferenza automatica di un tipo da un valore o da un'espressione tramite inferenza di tipo.\n\n```typescript\nconst x = 'x'; // TypeScript inferisce 'x' come una stringa letterale con 'const' (immutabile), ma lo amplia a 'string' con 'let' (riassegnabile).\n```\n\n"
  },
  {
    "path": "website/src/content/docs/it-it/book/type-indexing.md",
    "content": "---\ntitle: Indicizzazione dei tipi\nsidebar:\n  order: 33\n  label: 33. Indicizzazione dei tipi\n---\n\n\nL'indicizzazione dei tipi si riferisce alla capacità di definire tipi che possono essere indicizzati da una chiave non nota in anticipo, utilizzando una firma di indice per specificare il tipo per le proprietà che non sono dichiarate esplicitamente.\n\n```typescript\ntype Dictionary<T> = {\n    [key: string]: T;\n};\nconst myDict: Dictionary<string> = { a: 'a', b: 'b' };\n\nconsole.log(myDict['a']); // Restituisce un\n```\n\n"
  },
  {
    "path": "website/src/content/docs/it-it/book/type-manipulation.md",
    "content": "---\ntitle: Manipolazione dei tipi\nsidebar:\n  order: 60\n  label: 60. Manipolazione dei tipi\n---\n\n\n### Creazione di tipi da tipi\n\nÈ possibile creare nuovi tipi componendo, manipolando o trasformando tipi esistenti.\n\nTipi di intersezione (`&`):\n\nConsentono di combinare più tipi in un unico tipo:\n\n```typescript\ntype A = { foo: number };\ntype B = { bar: string };\ntype C = A & B; // Intersezione di A e B\nconst obj: C = { foo: 42, bar: 'hello' };\n```\n\nTipi di unione (`|`):\n\nConsente di definire un tipo che può essere di diversi tipi:\n\n```typescript\ntype Result = string | number;\nconst value1: Result = 'hello';\nconst value2: Result = 42;\n```\n\nTipi mappati:\n\nConsentono di trasformare le proprietà di un tipo esistente per crearne uno nuovo:\n\n```typescript\ntype Mutable<T> = {\n    readonly [P in keyof T]: T[P];\n};\ntype Person = {\n    name: string;\n    age: number;\n};\ntype ImmutablePerson = Mutable<Person>; // Le proprietà diventano di sola lettura\n```\n\nTipi condizionali:\n\nConsentono di creare tipi in base ad alcune condizioni:\n\n```typescript\ntype ExtractParam<T> = T extends (param: infer P) => any ? P : never;\ntype MyFunction = (name: string) => number;\ntype ParamType = ExtractParam<MyFunction>; // string\n```\n\n### Tipi di accesso indicizzati\n\nIn TypeScript è possibile accedere e manipolare i tipi di proprietà all'interno di un altro tipo utilizzando un indice, `Type[Key]`.\n\n```typescript\ntype Person = {\n    name: string;\n    age: number;\n};\n\ntype AgeType = Person['age']; // number\n```\n\n```typescript\ntype MyTuple = [string, number, boolean];\ntype MyType = MyTuple[2]; // boolean\n```\n\n### Tipi di utilità\n\nDiversi tipi di utilità predefiniti possono essere utilizzati per manipolare i tipi; di seguito è riportato un elenco dei più comuni:\n\n#### Awaited\\<T\\>\n\nCostruisce un tipo che esegue ricorsivamente l'unwrapping dei tipi Promise.\n\n```typescript\ntype A = Awaited<Promise<string>>; // string\n```\n\n#### Partial\\<T\\>\n\nCostruisce un tipo con tutte le proprietà di T impostate su optional.\n\n```typescript\ntype Person = {\n    name: string;\n    age: number;\n};\n\ntype A = Partial<Person>; // { name?: string | undefined; age?:number | undefined; }\n```\n\n#### Required\\<T\\>\n\nCostruisce un tipo con tutte le proprietà di T impostate su required.\n\n```typescript\ntype Person = {\n    name?: string;\n    age?: number;\n};\n\ntype A = Required<Person>; // { name: string; age:number; }\n```\n\n#### Readonly\\<T\\>\n\nCostruisce un tipo con tutte le proprietà di T impostate su readonly.\n\n<!-- skip -->\n```typescript\ntype Person = {\n    name: string;\n    age: number;\n};\n\ntype A = Readonly<Person>;\n\nconst a: A = { name: 'Simon', age: 17 };\na.name = 'John'; // Non valido\n```\n\n#### Record\\<K, T\\>\n\nCostruisce un tipo con un insieme di proprietà K di tipo T.\n\n```typescript\ntype Product = {\n    name: string;\n    price: number;\n};\n\nconst products: Record<string, Product> = {\n    apple: { name: 'Apple', price: 0.5 },\n    banana: { name: 'Banana', price: 0.25 },\n};\n\nconsole.log(products.apple); // { name: 'Apple', price: 0.5 }\n```\n\n#### Pick\\<T, K\\>\n\nCostruisce un tipo selezionando le proprietà specificate K da T.\n\n```typescript\ntype Product = {\n    name: string;\n    price: number;\n};\n\ntype Price = Pick<Product, 'price'>; // { price: number; }\n```\n\n#### Omit\\<T, K\\>\n\nCostruisce un tipo omettendo le proprietà specificate K da T.\n\n```typescript\ntype Product = {\n    name: string;\n    price: number;\n};\n\ntype Name = Omit<Product, 'price'>; // { name: string; }\n```\n\n#### Exclude\\<T, U\\>\n\nCostruisce un tipo escludendo tutti i valori di tipo U da T.\n\n```typescript\ntype Union = 'a' | 'b' | 'c';\ntype MyType = Exclude<Union, 'a' | 'c'>; // b\n```\n\n#### Extract\\<T, U\\>\n\nCostruisce un tipo estraendo tutti i valori di tipo U da T.\n\n```typescript\ntype Union = 'a' | 'b' | 'c';\ntype MyType = Extract<Union, 'a' | 'c'>; // a | c\n```\n\n#### NonNullable\\<T\\>\n\nCostruisce un tipo escludendo null e undefined da T.\n\n```typescript\ntype Union = 'a' | null | undefined | 'b';\ntype MyType = NonNullable<Union>; // 'a' | 'b'\n```\n\n#### Parameters\\<T\\>\n\nEstrae i tipi di parametro di una funzione di tipo T.\n\n```typescript\ntype Func = (a: string, b: number) => void;\ntype MyType = Parameters<Func>; // [a: string, b: number]\n```\n\n#### ConstructorParameters\\<T\\>\n\nEstrae i tipi di parametro di una funzione costruttore di tipo T.\n\n```typescript\nclass Person {\n    constructor(\n        public name: string,\n        public age: number\n    ) {}\n}\ntype PersonConstructorParams = ConstructorParameters<typeof Person>; // [name: string, age: number]\nconst params: PersonConstructorParams = ['John', 30];\nconst person = new Person(...params);\nconsole.log(person); // Person { name: 'John', age: 30 }\n```\n\n#### ReturnType\\<T\\>\n\nEstrae il tipo di ritorno di una funzione di tipo T.\n\n```typescript\ntype Func = (name: string) => number;\ntype MyType = ReturnType<Func>; // number\n```\n\n#### InstanceType\\<T\\>\n\nEstrae il tipo di istanza di una classe di tipo T.\n\n```typescript\nclass Person {\n    name: string;\n\n    constructor(name: string) {\n        this.name = name;\n    }\n\n    sayHello() {\n        console.log(`Ciao, mi chiamo ${this.name}!`);\n    }\n}\n\ntype PersonInstance = InstanceType<typeof Person>;\n\nconst person: PersonInstance = new Person('John');\n\nperson.sayHello(); // Ciao, mi chiamo John!\n```\n\n#### ThisParameterType\\<T\\>\n\nEstrae il tipo del parametro 'this' da una funzione di tipo T.\n\n```typescript\ninterface Person {\n    name: string;\n    greet(this: Person): void;\n}\ntype PersonThisType = ThisParameterType<Person['greet']>; // Person\n```\n\n#### OmitThisParameter\\<T\\>\n\nRimuove il parametro 'this' da una funzione di tipo T.\n\n```typescript\nfunction capitalize(this: String) {\n    return this[0].toUpperCase + this.substring(1).toLowerCase();\n}\n\ntype CapitalizeType = OmitThisParameter<typeof capitalize>; // () => string\n```\n\n#### ThisType\\<T\\>\n\nFunge da marcatore per un tipo `this` contestuale.\n\n<!-- skip -->\n```typescript\ntype Logger = {\n    log: (error: string) => void;\n};\n\nlet helperFunctions: { [name: string]: Function } & ThisType<Logger> = {\n    hello: function () {\n        this.log('some error'); // Valido poiché \"log\" è parte di \"this\".\n        this.update(); // Non valido\n    },\n};\n```\n\n#### Uppercase\\<T\\>\n\nRendi maiuscolo il nome del tipo di input T.\n\n```typescript\ntype MyType = Uppercase<'abc'>; // \"ABC\"\n```\n\n#### Lowercase\\<T\\>\n\nRendi minuscolo il nome del tipo di input T.\n\n```typescript\ntype MyType = Lowercase<'ABC'>; // \"abc\"\n```\n\n#### Capitalize\\<T\\>\n\nInserisci in maiuscolo il nome del tipo di input T.\n\n```typescript\ntype MyType = Capitalize<'abc'>; // \"Abc\"\n```\n\n#### Uncapitalize\\<T\\>\n\nInserisci in maiuscolo il nome del tipo di input T.\n\n```typescript\ntype MyType = Uncapitalize<'Abc'>; // \"abc\"\n```\n\n#### NoInfer\\<T\\>\n\nNoInfer è un tipo di utilità progettato per bloccare l'inferenza automatica dei tipi nell'ambito di una funzione generica.\n\nEsempio:\n\n```typescript\n// Inferenza automatica dei tipi nell'ambito di una funzione generica.\nfunction fn<T extends string>(x: T[], y: T) {\n    return x.concat(y);\n}\nconst r = fn(['a', 'b'], 'c'); // Il tipo qui è (\"a\" | \"b\" | \"c\")[]\n```\n\nCon NoInfer:\n\n<!-- skip -->\n```typescript\n// Funzione di esempio che utilizza NoInfer per impedire l'inferenza di tipo\nfunction fn2<T extends string>(x: T[], y: NoInfer<T>) {\n    return x.concat(y);\n}\n\nconst r2 = fn2(['a', 'b'], 'c'); // Errore: l'argomento di tipo '\"c\"' non è assegnabile al parametro di tipo '\"a\" | \"b\"'.\n```\n\n"
  },
  {
    "path": "website/src/content/docs/it-it/book/type-predicates.md",
    "content": "---\ntitle: Predicati di tipo\nsidebar:\n  order: 23\n  label: 23. Predicati di tipo\n---\n\n\nI predicati di tipo in TypeScript sono funzioni che restituiscono un valore booleano e vengono utilizzate per restringere il tipo di una variabile a un tipo più specifico.\n\n```typescript\nconst isString = (value: unknown): value is string => typeof value === 'string';\n\nconst foo = (bar: unknown) => {\n    if (isString(bar)) {\n        console.log(bar.toUpperCase());\n    } else {\n        console.log('not a string');\n    }\n};\n```\n\n"
  },
  {
    "path": "website/src/content/docs/it-it/book/typescript-introduction.md",
    "content": "---\ntitle: Introduzione a TypeScript\nsidebar:\n  order: 7\n  label: 7. Introduzione a TypeScript\n---\n\n\n### Cos'è TypeScript?\n\nTypeScript è un linguaggio di programmazione fortemente tipizzato basato su JavaScript. È stato originariamente progettato da Anders Hejlsberg nel 2012 ed è attualmente sviluppato e gestito da Microsoft come progetto open source.\n\nTypeScript si compila in JavaScript e può essere eseguito in qualsiasi runtime JavaScript (ad esempio, un browser o Node.js su un server).\n\nSupporta diversi paradigmi di programmazione, come la programmazione funzionale, generica, imperativa e orientata agli oggetti, ed è un linguaggio compilato (transpilato) che viene convertito in JavaScript prima dell'esecuzione.\n\n### Perché TypeScript?\n\nTypeScript è un linguaggio fortemente tipizzato che aiuta a prevenire errori di programmazione comuni ed evitare determinati tipi di errori di runtime prima dell'esecuzione del programma.\n\nUn linguaggio fortemente tipizzato consente allo sviluppatore di specificare vari vincoli e comportamenti del programma nelle definizioni dei tipi di dati, facilitando la verifica della correttezza del software e la prevenzione dei difetti. Questo è particolarmente utile nelle applicazioni su larga scala.\n\nAlcuni dei vantaggi di TypeScript:\n\n* Tipizzazione statica, facoltativamente fortemente tipizzata\n* Inferenza di tipo\n* Accesso alle funzionalità di ES6 ed ES7\n* Compatibilità multipiattaforma e multibrowser\n* Supporto degli strumenti con IntelliSense\n\n### TypeScript e JavaScript\n\nTypeScript è scritto in file `.ts` o `.tsx`, mentre i file JavaScript sono scritti in file `.js` o `.jsx`.\n\nI file con estensione `.tsx` o `.jsx` possono contenere l'estensione di sintassi JavaScript JSX, utilizzata in React per lo sviluppo dell'interfaccia utente.\n\nTypeScript è un superset tipizzato di JavaScript (ECMAScript 2015) in termini di sintassi. Tutto il codice JavaScript è codice TypeScript valido, ma il contrario non è sempre vero.\n\nAd esempio, si consideri una funzione in un file JavaScript con estensione `.js`, come la seguente:\n\n<!-- skip -->\n```typescript\nconst sum = (a, b) => a + b;\n```\n\nLa funzione può essere convertita e utilizzata in TypeScript modificando l'estensione del file in `.ts`. Tuttavia, se la stessa funzione è annotata con tipi TypeScript, non può essere eseguita in alcun runtime JavaScript senza compilazione. Il seguente codice TypeScript genererà un errore di sintassi se non compilato:\n\n<!-- skip -->\n```typescript\nconst sum = (a: number, b: number): number => a + b;\n```\n\nTypeScript è stato progettato per rilevare possibili eccezioni che possono verificarsi in fase di runtime durante la compilazione, consentendo allo sviluppatore di definire l'intento con annotazioni di tipo. Inoltre, TypeScript può anche rilevare problemi se non viene fornita alcuna annotazione di tipo. Ad esempio, il seguente frammento di codice non specifica alcun tipo TypeScript:\n\n<!-- skip -->\n```typescript\nconst items = [{ x: 1 }, { x: 2 }];\nconst result = items.filter(item => item.y);\n```\n\nIn questo caso, TypeScript rileva un errore e segnala:\n\n```text\nLa proprietà 'y' non esiste sul tipo '{ x: number; }'.\n```\n\nIl sistema di tipi di TypeScript è ampiamente influenzato dal comportamento runtime di JavaScript. Ad esempio, l'operatore di addizione (+), che in JavaScript può eseguire sia la concatenazione di stringhe che l'addizione numerica, è modellato allo stesso modo in TypeScript:\n\n```typescript\nconst result = '1' + 1; // Il risultato è di tipo stringa\n```\n\nIl team di TypeScript ha deliberatamente deciso di segnalare come errori l'utilizzo insolito di JavaScript. Ad esempio, si consideri il seguente codice JavaScript valido:\n\n<!-- skip -->\n```typescript\nconst result = 1 + true; // In JavaScript, il risultato è uguale a 2\n```\n\nTuttavia, TypeScript genera un errore:\n\n```text\nL'operatore '+' non può essere applicato ai tipi 'number' e 'boolean'.\n```\n\nQuesto errore si verifica perché TypeScript applica rigorosamente la compatibilità di tipo e, in questo caso, identifica un'operazione non valida tra un numero e un valore booleano.\n\n### Generazione di codice TypeScript\n\nIl compilatore TypeScript ha due responsabilità principali: il controllo degli errori di tipo e la compilazione in JavaScript. Questi due processi sono indipendenti l'uno dall'altro. I tipi non influenzano l'esecuzione del codice in un runtime JavaScript, poiché vengono completamente cancellati durante la compilazione. TypeScript può comunque generare codice JavaScript anche in presenza di errori di tipo.\nEcco un esempio di codice TypeScript con un errore di tipo:\n\n<!-- skip -->\n```typescript\nconst add = (a: number, b: number): number => a + b;\nconst result = add('x', 'y'); // L'argomento di tipo 'string' non è assegnabile al parametro di tipo 'number'.\n```\n\nTuttavia, può comunque produrre un output JavaScript eseguibile:\n\n<!-- skip -->\n```typescript\n'use strict';\nconst add = (a, b) => a + b;\nconst result = add('x', 'y'); // xy\n```\n\nNon è possibile controllare i tipi TypeScript in fase di esecuzione. Ad esempio:\n\n<!-- skip -->\n```typescript\ninterface Animal {\n    name: string;\n}\ninterface Dog extends Animal {\n    bark: () => void;\n}\ninterface Cat extends Animal {\n    meow: () => void;\n}\nconst makeNoise = (animal: Animal) => {\n    if (animal instanceof Dog) {\n        // 'Dog' si riferisce solo a un tipo, ma qui viene utilizzato come valore.\n        // ...\n    }\n};\n```\n\nPoiché i tipi vengono cancellati dopo la compilazione, non è possibile eseguire questo codice in JavaScript. Per riconoscere i tipi a runtime, dobbiamo usare un altro meccanismo. TypeScript offre diverse opzioni, una delle quali è la \"tagged union\". Ad esempio:\n\n```typescript\ninterface Dog {\n    kind: 'dog'; // Tagged union\n    bark: () => void;\n}\ninterface Cat {\n    kind: 'cat'; // Tagged union\n    meow: () => void;\n}\ntype Animal = Dog | Cat;\n\nconst makeNoise = (animal: Animal) => {\n    if (animal.kind === 'dog') {\n        animal.bark();\n    } else {\n        animal.meow();\n    }\n};\n\nconst dog: Dog = {\n    kind: 'dog',\n    bark: () => console.log('bark'),\n};\nmakeNoise(dog);\n```\n\nLa proprietà \"kind\" è un valore che può essere utilizzato in fase di esecuzione per distinguere gli oggetti in JavaScript.\n\nÈ anche possibile che un valore in fase di esecuzione abbia un tipo diverso da quello dichiarato nella dichiarazione di tipo. Ad esempio, se lo sviluppatore ha interpretato erroneamente un tipo API e lo ha annotato in modo errato.\n\nTypeScript è un superset di JavaScript, quindi la parola chiave \"class\" può essere utilizzata come tipo e valore in fase di esecuzione.\n\n```typescript\nclass Animal {\n    constructor(public name: string) {}\n}\nclass Dog extends Animal {\n    constructor(\n        public name: string,\n        public bark: () => void\n    ) {\n        super(name);\n    }\n}\nclass Cat extends Animal {\n    constructor(\n        public name: string,\n        public meow: () => void\n    ) {\n        super(name);\n    }\n}\ntype Mammal = Dog | Cat;\n\nconst makeNoise = (mammal: Mammal) => {\n    if (mammal instanceof Dog) {\n        mammal.bark();\n    } else {\n        mammal.meow();\n    }\n};\n\nconst dog = new Dog('Fido', () => console.log('bark'));\nmakeNoise(dog);\n```\n\nIn JavaScript, una \"classe\" ha una proprietà \"prototype\" e l'operatore \"instanceof\" può essere utilizzato per verificare se la proprietà prototype di un costruttore appare in qualsiasi punto della catena di prototipi di un oggetto.\n\nTypeScript non ha alcun effetto sulle prestazioni di runtime, poiché tutti i tipi verranno cancellati. Tuttavia, TypeScript introduce un certo overhead in fase di compilazione.\n\n### JavaScript moderno ora (Downleveling)\n\nTypeScript può compilare codice per qualsiasi versione rilasciata di JavaScript a partire da ECMAScript 3 (1999). Ciò significa che TypeScript può transpilare codice dalle funzionalità JavaScript più recenti a versioni precedenti, un processo noto come Downleveling. Questo consente l'utilizzo di JavaScript moderno mantenendo la massima compatibilità con gli ambienti di runtime più vecchi.\n\nÈ importante notare che durante la transpilazione a una versione precedente di JavaScript, TypeScript potrebbe generare codice che potrebbe comportare un sovraccarico di prestazioni rispetto alle implementazioni native.\n\nEcco alcune delle funzionalità di JavaScript moderno che possono essere utilizzate in TypeScript:\n\n* Moduli ECMAScript al posto delle callback \"define\" in stile AMD o delle istruzioni \"require\" di CommonJS.\n* Classi al posto dei prototipi.\n* Dichiarazione di variabili utilizzando \"let\" o \"const\" al posto di \"var\".\n* Ciclo \"for-of\" o \".forEach\" al posto del tradizionale ciclo \"for\".\n* Funzioni freccia al posto delle espressioni di funzione.\n* Assegnazione destrutturata. \\* Nomi abbreviati di proprietà/metodi e nomi di proprietà calcolate.\n* Parametri di funzione predefiniti.\n\nSfruttando queste moderne funzionalità di JavaScript, gli sviluppatori possono scrivere codice più espressivo e conciso in TypeScript.\n\n"
  },
  {
    "path": "website/src/content/docs/it-it/book/union-type.md",
    "content": "---\ntitle: Tipo Unione\nsidebar:\n  order: 31\n  label: 31. Tipo Unione\n---\n\n\nUn Tipo Unione è un tipo che rappresenta un valore che può essere di diversi tipi. I Tipi Unione sono indicati con il simbolo `|` tra ogni tipo possibile.\n\n```typescript\nlet x: string | number;\nx = 'hello'; // Valido\nx = 123; // Valido\n```\n\n"
  },
  {
    "path": "website/src/content/docs/it-it/book/unknown-type.md",
    "content": "---\ntitle: Tipo Unknown\nsidebar:\n  order: 45\n  label: 45. Tipo Unknown\n---\n\n\nIn TypeScript, il tipo `unknown` rappresenta un valore di tipo sconosciuto. A differenza del tipo `any`, che consente qualsiasi tipo di valore, `unknown` richiede un controllo o un'asserzione di tipo prima di poter essere utilizzato in un modo specifico, quindi non sono consentite operazioni su un `unknown` senza prima aver effettuato un'asserzione o aver limitato il campo a un tipo più specifico.\n\nIl tipo `unknown` è assegnabile solo a qualsiasi tipo e il tipo `unknown` stesso è un'alternativa type-safe ad `any`.\n\n<!-- skip -->\n```typescript\nlet value: unknown;\n\nlet value1: unknown = value; // Valido\nlet value2: any = value; // Valido\nlet value3: boolean = value; // Non valido\nlet value4: number = value; // Non valido\n```\n\n```typescript\nconst add = (a: unknown, b: unknown): number | undefined =>\n    typeof a === 'number' && typeof b === 'number' ? a + b : undefined;\nconsole.log(add(1, 2)); // 3\nconsole.log(add('x', 2)); // non definito\n```\n\n"
  },
  {
    "path": "website/src/content/docs/it-it/book/void-type.md",
    "content": "---\ntitle: Tipo Void\nsidebar:\n  order: 46\n  label: 46. Tipo Void\n---\n\n\nIl tipo `void` viene utilizzato per indicare che una funzione non restituisce un valore.\n\n```typescript\nconst sayHello = (): void => {\n    console.log('Hello!');\n};\n```\n\n"
  },
  {
    "path": "website/src/content/docs/it-it/index.mdx",
    "content": "---\ntitle: TypeScript Book\ndescription: The Concise TypeScript Book\ntemplate: splash\nhero:\n    tagline: Il Concise TypeScript Book offre una panoramica completa e concisa delle funzionalità di TypeScript. Offre spiegazioni chiare che coprono tutti gli aspetti dell'ultima versione del linguaggio, dal suo potente sistema di tipi alle funzionalità avanzate. Che siate principianti o sviluppatori esperti, questo libro è una risorsa preziosa per migliorare la vostra comprensione e competenza in TypeScript.<br/><br/>Questo libro è completamente gratuito e open source. \n    actions:\n        - text: Leggi ora!\n          link: /typescript-book/it-it/book/the-concise-typescript-book/\n          icon: right-arrow\n          variant: primary\n        - text: GitHub\n          link: https://github.com/gibbok/typescript-book\n          icon: github\n          variant: secondary\n        - text: X.com\n          link: https://twitter.com/gibbok_coding\n          icon: x.com\n          variant: secondary\n---\n"
  },
  {
    "path": "website/src/content/docs/pt-br/book/about-the-author.md",
    "content": "---\ntitle: Sobre o Autor\nsidebar:\n  order: 6\n  label: 6. Sobre o Autor\n---\n\n\nSimone Poggiali é um Engenheiro Staff experiente com paixão por escrever código de nível profissional desde os anos 90. Ao longo de sua carreira internacional, contribuiu para inúmeros projetos para uma ampla gama de clientes, de startups a grandes organizações. Empresas notáveis como HelloFresh, Siemens, O2, Leroy Merlin e Snowplow se beneficiaram de sua expertise e dedicação.\n\nVocê pode encontrar Simone Poggiali nas seguintes plataformas:\n\n* LinkedIn: [https://www.linkedin.com/in/simone-poggiali](https://www.linkedin.com/in/simone-poggiali)\n* GitHub: [https://github.com/gibbok](https://github.com/gibbok)\n* X.com: [https://x.com/gibbok_coding](https://x.com/gibbok_coding)\n* Email: gibbok.coding📧gmail.com\n\nLista completa de colaboradores: [https://github.com/gibbok/typescript-book/graphs/contributors](https://github.com/gibbok/typescript-book/graphs/contributors)\n\n"
  },
  {
    "path": "website/src/content/docs/pt-br/book/any-type.md",
    "content": "---\ntitle: Tipo any\nsidebar:\n  order: 44\n  label: 44. Tipo any\n---\n\n\nO tipo `any` é um tipo especial (supertipo universal) que pode ser usado para representar qualquer tipo de valor (primitivos, objetos, arrays, funções, erros, símbolos). É frequentemente usado em situações onde o tipo de um valor não é conhecido em tempo de compilação, ou ao trabalhar com valores de APIs externas ou bibliotecas que não possuem tipagens TypeScript.\n\nAo utilizar o tipo `any`, você está indicando ao compilador TypeScript que os valores devem ser representados sem quaisquer limitações. Para maximizar a segurança de tipo em seu código, considere o seguinte:\n\n* Limite o uso de `any` a casos específicos onde o tipo é verdadeiramente desconhecido.\n* Não retorne tipos `any` de uma função, pois isso enfraquece a segurança de tipo no código que a utiliza.\n* Em vez de `any`, use `@ts-ignore` se precisar silenciar o compilador.\n\n```typescript\nlet value: any;\nvalue = true; // Válido\nvalue = 7; // Válido\n```\n\n"
  },
  {
    "path": "website/src/content/docs/pt-br/book/assignments.md",
    "content": "---\ntitle: Atribuições\nsidebar:\n  order: 21\n  label: 21. Atribuições\n---\n\n\nO estreitamento do TypeScript usando atribuições é uma forma de estreitar o tipo de uma variável com base no valor atribuído a ela. Quando uma variável recebe um valor, o TypeScript infere seu tipo com base no valor atribuído e estreita o tipo da variável para corresponder ao tipo inferido.\n\n```typescript\nlet value: string | number;\nvalue = 'hello';\nif (typeof value === 'string') {\n    console.log(value.toUpperCase());\n}\nvalue = 42;\nif (typeof value === 'number') {\n    console.log(value.toFixed(2));\n}\n```\n\n"
  },
  {
    "path": "website/src/content/docs/pt-br/book/built-in-type-primitives.md",
    "content": "---\ntitle: Tipos Primitivos Integrados\nsidebar:\n  order: 49\n  label: 49. Tipos Primitivos Integrados\n---\n\n\nO TypeScript possui vários tipos primitivos integrados que podem ser usados para definir variáveis, parâmetros de função e tipos de retorno:\n\n* `number`: Representa valores numéricos, incluindo inteiros e números de ponto flutuante.\n* `string`: Representa dados textuais.\n* `boolean`: Representa valores lógicos, que podem ser true ou false.\n* `null`: Representa a ausência de um valor.\n* `undefined`: Representa um valor que não foi atribuído ou não foi definido.\n* `symbol`: Representa um identificador único. Symbols são normalmente usados como chaves para propriedades de objetos.\n* `bigint`: Representa inteiros de precisão arbitrária.\n* `any`: Representa um tipo dinâmico ou desconhecido. Variáveis do tipo any podem conter valores de qualquer tipo e ignoram a verificação de tipos.\n* `void`: Representa a ausência de qualquer tipo. É comumente usado como o tipo de retorno de funções que não retornam um valor.\n* `never`: Representa um tipo para valores que nunca ocorrem. É normalmente usado como o tipo de retorno de funções que lançam um erro ou entram em um loop infinito.\n\n"
  },
  {
    "path": "website/src/content/docs/pt-br/book/class.md",
    "content": "---\ntitle: Classes\nsidebar:\n  order: 54\n  label: 54. Classes\n---\n\n\n### Sintaxe Comum de Classes\n\nA palavra-chave `class` é usada no TypeScript para definir uma classe. Abaixo, você pode ver um exemplo:\n\n```typescript\nclass Person {\n    private name: string;\n    private age: number;\n    constructor(name: string, age: number) {\n        this.name = name;\n        this.age = age;\n    }\n    public sayHi(): void {\n        console.log(\n            `Olá, meu nome é ${this.name} e eu tenho ${this.age} anos.`\n        );\n    }\n}\n```\n\nA palavra-chave `class` é usada para definir uma classe chamada \"Person\".\n\nA classe possui duas propriedades privadas: name do tipo `string` e age do tipo `number`.\n\nO construtor é definido usando a palavra-chave `constructor`. Ele recebe name e age como parâmetros e os atribui às propriedades correspondentes.\n\nA classe possui um método `public` chamado `sayHi` que registra uma mensagem de saudação.\n\nPara criar uma instância de uma classe no TypeScript, você pode usar a palavra-chave `new` seguida pelo nome da classe, seguida de parênteses `()`. Por exemplo:\n\n<!-- skip -->\n```typescript\nconst myObject = new Person('John Doe', 25);\nmyObject.sayHi(); // Saída: Olá, meu nome é John Doe e eu tenho 25 anos.\n```\n\n### Construtor\n\nOs construtores são métodos especiais dentro de uma classe que são usados para inicializar as propriedades do objeto quando uma instância da classe é criada.\n\n```typescript\nclass Person {\n    public name: string;\n    public age: number;\n\n    constructor(name: string, age: number) {\n        this.name = name;\n        this.age = age;\n    }\n\n    sayHello() {\n        console.log(\n            `Olá, meu nome é ${this.name} e eu tenho ${this.age} anos.`\n        );\n    }\n}\n\nconst john = new Person('Simon', 17);\njohn.sayHello();\n```\n\nÉ possível sobrecarregar um construtor usando a seguinte sintaxe:\n\n```typescript\ntype Sex = 'm' | 'f';\n\nclass Person {\n    name: string;\n    age: number;\n    sex: Sex;\n\n    constructor(name: string, age: number, sex?: Sex);\n    constructor(name: string, age: number, sex: Sex) {\n        this.name = name;\n        this.age = age;\n        this.sex = sex ?? 'm';\n    }\n}\n\nconst p1 = new Person('Simon', 17);\nconst p2 = new Person('Alice', 22, 'f');\n```\n\nNo TypeScript, é possível definir múltiplas sobrecargas de construtor, mas você pode ter apenas uma implementação que deve ser compatível com todas as sobrecargas, o que pode ser alcançado usando um parâmetro opcional.\n\n```typescript\nclass Person {\n    name: string;\n    age: number;\n\n    constructor();\n    constructor(name: string);\n    constructor(name: string, age: number);\n    constructor(name?: string, age?: number) {\n        this.name = name ?? 'Desconhecido';\n        this.age = age ?? 0;\n    }\n\n    displayInfo() {\n        console.log(`Nome: ${this.name}, Idade: ${this.age}`);\n    }\n}\n\nconst person1 = new Person();\nperson1.displayInfo(); // Nome: Desconhecido, Idade: 0\n\nconst person2 = new Person('John');\nperson2.displayInfo(); // Nome: John, Idade: 0\n\nconst person3 = new Person('Jane', 25);\nperson3.displayInfo(); // Nome: Jane, Idade: 25\n```\n\n### Construtores Privados e Protegidos\n\nNo TypeScript, os construtores podem ser marcados como privados ou protegidos, o que restringe sua acessibilidade e uso.\n\nConstrutores Privados (Private Constructors):\nPodem ser chamados apenas dentro da própria classe. Construtores privados são frequentemente usados em cenários onde você deseja impor um padrão singleton ou restringir a criação de instâncias a um método factual dentro da classe.\n\nConstrutores Protegidos (Protected Constructors):\nConstrutores protegidos são úteis quando você deseja criar uma classe base que não deve ser instanciada diretamente, mas pode ser estendida por subclasses.\n\n```typescript\nclass BaseClass {\n    protected constructor() {}\n}\n\nclass DerivedClass extends BaseClass {\n    private value: number;\n\n    constructor(value: number) {\n        super();\n        this.value = value;\n    }\n}\n\n// Tentar instanciar a classe base diretamente resultará em erro\n// const baseObj = new BaseClass(); // Erro: O construtor da classe 'BaseClass' é protegido.\n\n// Criar uma instância da classe derivada\nconst derivedObj = new DerivedClass(10);\n```\n\n### Modificadores de Acesso\n\nModificadores de Acesso `private`, `protected` e `public` são usados para controlar a visibilidade e acessibilidade dos membros da classe, como propriedades e métodos, em classes TypeScript. Esses modificadores são essenciais para impor o encapsulamento e estabelecer limites para acessar e modificar o estado interno de uma classe.\n\nO modificador `private` restringe o acesso ao membro da classe apenas dentro da classe que o contém.\n\nO modificador `protected` permite o acesso ao membro da classe dentro da classe que o contém e suas classes derivadas.\n\nO modificador `public` fornece acesso irrestrito ao membro da classe, permitindo que ele seja acessado de qualquer lugar.\n\n### Get e Set\n\nGetters e setters são métodos especiais que permitem definir comportamentos personalizados de acesso e modificação para propriedades de classe. Eles permitem encapsular o estado interno de um objeto e fornecer lógica adicional ao obter ou definir os valores das propriedades.\nNo TypeScript, os getters e setters são definidos usando as palavras-chave `get` e `set`, respectivamente. Aqui está um exemplo:\n\n```typescript\nclass MyClass {\n    private _myProperty: string;\n\n    constructor(value: string) {\n        this._myProperty = value;\n    }\n    get myProperty(): string {\n        return this._myProperty;\n    }\n    set myProperty(value: string) {\n        this._myProperty = value;\n    }\n}\n```\n\n### Auto-acessores em Classes\n\nO TypeScript versão 4.9 adiciona suporte para auto-acessores (auto-accessors), um recurso futuro do ECMAScript. Eles se assemelham a propriedades de classe, mas são declarados com a palavra-chave \"accessor\".\n\n```typescript\nclass Animal {\n    accessor name: string;\n\n    constructor(name: string) {\n        this.name = name;\n    }\n}\n```\n\nOs auto-acessores são transformados em acessores `get` e `set` privados, operando em uma propriedade inacessível.\n\n<!-- skip -->\n```typescript\nclass Animal {\n    #__name: string;\n\n    get name() {\n        return this.#__name;\n    }\n    set name(value: string) {\n        this.#__name = name;\n    }\n\n    constructor(name: string) {\n        this.name = name;\n    }\n}\n```\n\n### this\n\nNo TypeScript, a palavra-chave `this` refere-se à instância atual de uma classe dentro de seus métodos ou construtores. Ela permite acessar e modificar as propriedades e métodos da classe de dentro de seu próprio escopo.\nFornece uma maneira de acessar e manipular o estado interno de um objeto dentro de seus próprios métodos.\n\n```typescript\nclass Person {\n    private name: string;\n    constructor(name: string) {\n        this.name = name;\n    }\n    public introduce(): void {\n        console.log(`Olá, meu nome é ${this.name}.`);\n    }\n}\n\nconst person1 = new Person('Alice');\nperson1.introduce(); // Olá, meu nome é Alice.\n```\n\n### Propriedades de Parâmetro\n\nAs propriedades de parâmetro permitem declarar e inicializar propriedades de classe diretamente dentro dos parâmetros do construtor, evitando o código repetitivo (boilerplate). Exemplo:\n\n```typescript\nclass Person {\n    constructor(\n        private name: string,\n        public age: number\n    ) {\n        // As palavras-chave \"private\" e \"public\" no construtor\n        // declaram e inicializam automaticamente as propriedades de classe correspondentes.\n    }\n    public introduce(): void {\n        console.log(\n            `Olá, meu nome é ${this.name} e eu tenho ${this.age} anos.`\n        );\n    }\n}\nconst person = new Person('Alice', 25);\nperson.introduce();\n```\n\n### Classes Abstratas\n\nClasses Abstratas são usadas no TypeScript principalmente para herança; elas fornecem uma maneira de definir propriedades e métodos comuns que podem ser herdados por subclasses.\nIsso é útil quando você deseja definir um comportamento comum e garantir que as subclasses implementem certos métodos. Elas fornecem uma maneira de criar uma hierarquia de classes onde a classe base abstrata fornece uma interface compartilhada e funcionalidade comum para as subclasses.\n\n```typescript\nabstract class Animal {\n    protected name: string;\n\n    constructor(name: string) {\n        this.name = name;\n    }\n\n    abstract makeSound(): void;\n}\n\nclass Cat extends Animal {\n    makeSound(): void {\n        console.log(`${this.name} mia (meows).`);\n    }\n}\n\nconst cat = new Cat('Whiskers');\ncat.makeSound(); // Saída: Whiskers mia (meows).\n```\n\n### Com Genéricos\n\nClasses com genéricos permitem definir classes reutilizáveis que podem trabalhar com diferentes tipos.\n\n```typescript\nclass Container<T> {\n    private item: T;\n\n    constructor(item: T) {\n        this.item = item;\n    }\n\n    getItem(): T {\n        return this.item;\n    }\n\n    setItem(item: T): void {\n        this.item = item;\n    }\n}\n\nconst container1 = new Container<number>(42);\nconsole.log(container1.getItem()); //  42\n\nconst container2 = new Container<string>('Olá');\ncontainer2.setItem('Mundo');\nconsole.log(container2.getItem()); // Mundo\n```\n\n### Decoradores (Decorators)\n\nOs decoradores fornecem um mecanismo para adicionar metadados, modificar comportamentos, validar ou estender a funcionalidade do elemento alvo. São funções que são executadas em tempo de execução. Múltiplos decoradores podem ser aplicados a uma declaração.\n\nOs decoradores são recursos experimentais, e os exemplos a seguir são compatíveis apenas com a versão 5 do TypeScript ou superior usando ES6.\n\nPara versões do TypeScript anteriores à 5, eles devem ser habilitados usando a propriedade `experimentalDecorators` em seu `tsconfig.json` ou usando `--experimentalDecorators` na sua linha de comando (mas o exemplo a seguir não funcionará).\n\nAlguns dos casos de uso comuns para decoradores incluem:\n\n* Observar mudanças de propriedade.\n* Observar chamadas de métodos.\n* Adicionar propriedades ou métodos extras.\n* Validação em tempo de execução.\n* Serialização e desserialização automática.\n* Registro (Logging).\n* Autorização e autenticação.\n* Proteção contra erros (Error guarding).\n\nNota: Decoradores para a versão 5 não permitem decorar parâmetros.\n\nTipos de decoradores:\n\n#### Decoradores de Classe (Class Decorators)\n\nOs Decoradores de Classe são úteis para estender uma classe existente, como adicionar propriedades ou métodos, ou coletar instâncias de uma classe. No exemplo a seguir, adicionamos um método `toString` que converte a classe em uma representação de string.\n\n```typescript\ntype Constructor<T = {}> = new (...args: any[]) => T;\n\nfunction toString<Class extends Constructor>(\n    Value: Class,\n    context: ClassDecoratorContext<Class>\n) {\n    return class extends Value {\n        constructor(...args: any[]) {\n            super(...args);\n            console.log(JSON.stringify(this));\n            console.log(JSON.stringify(context));\n        }\n    };\n}\n\n@toString\nclass Person {\n    name: string;\n\n    constructor(name: string) {\n        this.name = name;\n    }\n\n    greet() {\n        return 'Hello, ' + this.name;\n    }\n}\nconst person = new Person('Simon');\n/* Registra:\n{\"name\":\"Simon\"}\n{\"kind\":\"class\",\"name\":\"Person\"}\n*/\n```\n\n#### Decorador de Propriedade (Property Decorator)\n\nOs decoradores de propriedade são úteis para modificar o comportamento de uma propriedade, como alterar os valores de inicialização. No código a seguir, temos um script que define uma propriedade para estar sempre em letras maiúsculas:\n\n```typescript\nfunction upperCase<T>(\n    target: undefined,\n    context: ClassFieldDecoratorContext<T, string>\n) {\n    return function (this: T, value: string) {\n        return value.toUpperCase();\n    };\n}\n\nclass MyClass {\n    @upperCase\n    prop1 = 'hello!';\n}\n\nconsole.log(new MyClass().prop1); // Registra: HELLO!\n```\n\n#### Decorador de Método (Method Decorator)\n\nOs decoradores de método permitem alterar ou aprimorar o comportamento dos métodos. Abaixo está um exemplo de um registrador (logger) simples:\n\n```typescript\nfunction log<This, Args extends any[], Return>(\n    target: (this: This, ...args: Args) => Return,\n    context: ClassMethodDecoratorContext<\n        This,\n        (this: This, ...args: Args) => Return\n    >\n) {\n    const methodName = String(context.name);\n\n    function replacementMethod(this: This, ...args: Args): Return {\n        console.log(`LOG: Entrando no método '${methodName}'.`);\n        const result = target.call(this, ...args);\n        console.log(`LOG: Saindo do método '${methodName}'.`);\n        return result;\n    }\n\n    return replacementMethod;\n}\n\nclass MyClass {\n    @log\n    sayHello() {\n        console.log('Hello!');\n    }\n}\n\nnew MyClass().sayHello();\n```\n\nIsso registra:\n\n```shell\nLOG: Entrando no método 'sayHello'.\nHello!\nLOG: Saindo do método 'sayHello'.\n```\n\n#### Decoradores de Getter e Setter\n\nDecoradores de getter e setter permitem alterar ou aprimorar o comportamento dos acessores de classe. Eles são úteis, por exemplo, para validar atribuições de propriedades. Aqui está um exemplo simples de um decorador de getter:\n\n```typescript\nfunction range<This, Return extends number>(min: number, max: number) {\n    return function (\n        target: (this: This) => Return,\n        context: ClassGetterDecoratorContext<This, Return>\n    ) {\n        return function (this: This): Return {\n            const value = target.call(this);\n            if (value < min || value > max) {\n                throw 'Invalid';\n            }\n            Object.defineProperty(this, context.name, {\n                value,\n                enumerable: true,\n            });\n            return value;\n        };\n    };\n}\n\nclass MyClass {\n    private _value = 0;\n\n    constructor(value: number) {\n        this._value = value;\n    }\n    @range(1, 100)\n    get getValue(): number {\n        return this._value;\n    }\n}\n\nconst obj = new MyClass(10);\nconsole.log(obj.getValue); // Válido: 10\n\nconst obj2 = new MyClass(999);\nconsole.log(obj2.getValue); // Lança: Invalid!\n```\n\n#### Metadados de Decorador (Decorator Metadata)\n\nOs Metadados de Decorador simplificam o processo para que os decoradores apliquem e utilizem metadados em qualquer classe. Eles podem acessar uma nova propriedade de metadados no objeto de contexto, que pode servir como uma chave para primitivos e objetos.\nAs informações de metadados podem ser acessadas na classe via `Symbol.metadata`.\n\nOs metadados podem ser usados para vários fins, como depuração, serialização ou injeção de dependência com decoradores.\n\n```typescript\n//@ts-ignore\nSymbol.metadata ??= Symbol('Symbol.metadata'); // Polify simples\n\ntype Context =\n    | ClassFieldDecoratorContext\n    | ClassAccessorDecoratorContext\n    | ClassMethodDecoratorContext; // O contexto contém os metadados da propriedade: DecoratorMetadata\n\nfunction setMetadata(_target: any, context: Context) {\n    // Define o objeto de metadados com um valor primitivo\n    context.metadata[context.name] = true;\n}\n\nclass MyClass {\n    @setMetadata\n    a = 123;\n\n    @setMetadata\n    accessor b = 'b';\n\n    @setMetadata\n    fn() {}\n}\n\nconst metadata = MyClass[Symbol.metadata]; // Obtém as informações de metadados\n\nconsole.log(JSON.stringify(metadata)); // {\"bar\":true,\"baz\":true,\"foo\":true}\n```\n\n### Herança\n\nHerança refere-se ao mecanismo pelo qual uma classe pode herdar propriedades e métodos de outra classe, conhecida como classe base ou superclasse. A classe derivada, também chamada de classe filha ou subclasse, pode estender e especializar a funcionalidade da classe base adicionando novas propriedades e métodos ou substituindo (overriding) os existentes.\n\n```typescript\nclass Animal {\n    name: string;\n\n    constructor(name: string) {\n        this.name = name;\n    }\n\n    speak(): void {\n        console.log('O animal faz um som');\n    }\n}\n\nclass Dog extends Animal {\n    breed: string;\n\n    constructor(name: string, breed: string) {\n        super(name);\n        this.breed = breed;\n    }\n\n    speak(): void {\n        console.log('Woof! Woof!');\n    }\n}\n\n// Cria uma instância da classe base\nconst animal = new Animal('Animal Genérico');\nanimal.speak(); // O animal faz um som\n\n// Cria uma instância da classe derivada\nconst dog = new Dog('Max', 'Labrador');\ndog.speak(); // Woof! Woof!\"\n```\n\nO TypeScript não suporta herança múltipla no sentido tradicional e, em vez disso, permite a herança de uma única classe base.\nO TypeScript suporta múltiplas interfaces. Uma interface pode definir um contrato para a estrutura de um objeto, e uma classe pode implementar múltiplas interfaces. Isso permite que uma classe herde comportamento e estrutura de múltiplas fontes.\n\n```typescript\ninterface Flyable {\n    fly(): void;\n}\n\ninterface Swimmable {\n    swim(): void;\n}\n\nclass FlyingFish implements Flyable, Swimmable {\n    fly() {\n        console.log('Voando...');\n    }\n\n    swim() {\n        console.log('Nadando...');\n    }\n}\n\nconst flyingFish = new FlyingFish();\nflyingFish.fly();\nflyingFish.swim();\n```\n\nA palavra-chave `class` no TypeScript, assim como no JavaScript, é frequentemente chamada de açúcar sintático (syntactic sugar). Ela foi introduzida no ECMAScript 2015 (ES6) para oferecer uma sintaxe mais familiar para criar e trabalhar com objetos de maneira baseada em classes. No entanto, é importante notar que o TypeScript, sendo um superconjunto do JavaScript, acaba sendo compilado para JavaScript, que permanece baseado em protótipos em seu núcleo.\n\n### Estáticos (Statics)\n\nO TypeScript possui membros estáticos. Para acessar os membros estáticos de uma classe, você pode usar o nome da classe seguido por um ponto, sem a necessidade de criar um objeto.\n\n```typescript\nclass OfficeWorker {\n    static memberCount: number = 0;\n\n    constructor(private name: string) {\n        OfficeWorker.memberCount++;\n    }\n}\n\nconst w1 = new OfficeWorker('James');\nconst w2 = new OfficeWorker('Simon');\nconst total = OfficeWorker.memberCount;\nconsole.log(total); // 2\n```\n\n### Inicialização de Propriedade\n\nExistem várias maneiras de inicializar propriedades de uma classe no TypeScript:\n\nEm linha (Inline):\n\nNo exemplo a seguir, esses valores iniciais serão usados quando uma instância da classe for criada.\n\n```typescript\nclass MyClass {\n    property1: string = 'valor padrão';\n    property2: number = 42;\n}\n```\n\nNo construtor:\n\n```typescript\nclass MyClass {\n    property1: string;\n    property2: number;\n\n    constructor() {\n        this.property1 = 'valor padrão';\n        this.property2 = 42;\n    }\n}\n```\n\nUsando parâmetros do construtor:\n\n```typescript\nclass MyClass {\n    constructor(\n        private property1: string = 'valor padrão',\n        public property2: number = 42\n    ) {\n        // Não há necessidade de atribuir os valores às propriedades explicitamente.\n    }\n    log() {\n        console.log(this.property2);\n    }\n}\nconst x = new MyClass();\nx.log();\n```\n\n### Sobrecarga de Método\n\nA sobrecarga de método permite que uma classe tenha múltiplos métodos com o mesmo nome, mas diferentes tipos de parâmetros ou um número diferente de parâmetros. Isso nos permite chamar um método de diferentes maneiras com base nos argumentos passados.\n\n```typescript\nclass MyClass {\n    add(a: number, b: number): number; // Assinatura de sobrecarga 1\n    add(a: string, b: string): string; // Assinatura de sobrecarga 2\n\n    add(a: number | string, b: number | string): number | string {\n        if (typeof a === 'number' && typeof b === 'number') {\n            return a + b;\n        }\n        if (typeof a === 'string' && typeof b === 'string') {\n            return a.concat(b);\n        }\n        throw new Error('Argumentos inválidos');\n    }\n}\n\nconst r = new MyClass();\nconsole.log(r.add(10, 5)); // Registra 15\n```\n\n"
  },
  {
    "path": "website/src/content/docs/pt-br/book/common-built-in-js-objects.md",
    "content": "---\ntitle: Objetos JS Integrados Comuns\nsidebar:\n  order: 50\n  label: 50. Objetos JS Integrados Comuns\n---\n\n\nO TypeScript é um superconjunto do JavaScript e inclui todos os objetos integrados do JavaScript comumente usados. Você pode encontrar uma lista extensa desses objetos no site de documentação da Mozilla Developer Network (MDN):\n[https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects](https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects)\n\nAqui está uma lista de alguns objetos integrados do JavaScript comumente usados:\n\n* Function\n* Object\n* Boolean\n* Error\n* Number\n* BigInt\n* Math\n* Date\n* String\n* RegExp\n* Array\n* Map\n* Set\n* Promise\n* Intl\n\n"
  },
  {
    "path": "website/src/content/docs/pt-br/book/conditional-types.md",
    "content": "---\ntitle: Tipos Condicionais (Conditional Types)\nsidebar:\n  order: 39\n  label: 39. Tipos Condicionais (Conditional Types)\n---\n\n\nTipos Condicionais são uma forma de criar um tipo que depende de uma condição, onde o tipo a ser criado é determinado com base no resultado da condição. Eles são definidos usando a palavra-chave `extends` e um operador ternário para escolher condicionalmente entre dois tipos.\n\n```typescript\ntype IsArray<T> = T extends any[] ? true : false;\n\nconst myArray = [1, 2, 3];\nconst myNumber = 42;\n\ntype IsMyArrayAnArray = IsArray<typeof myArray>; // Tipo true\ntype IsMyNumberAnArray = IsArray<typeof myNumber>; // Tipo false\n```\n\n"
  },
  {
    "path": "website/src/content/docs/pt-br/book/control-flow-analysis.md",
    "content": "---\ntitle: Análise de Fluxo de Controle\nsidebar:\n  order: 22\n  label: 22. Análise de Fluxo de Controle\n---\n\n\nA Análise de Fluxo de Controle (Control Flow Analysis) no TypeScript é uma forma de analisar estaticamente o fluxo do código para inferir os tipos das variáveis, permitindo que o compilador estreite os tipos dessas variáveis conforme necessário, com base nos resultados da análise.\n\nAntes do TypeScript 4.4, a análise de fluxo de código só seria aplicada ao código dentro de uma instrução `if`, mas a partir do TypeScript 4.4, ela também pode ser aplicada a expressões condicionais e acessos a propriedades discriminantes referenciados indiretamente por meio de variáveis `const`.\n\nPor exemplo:\n\n```typescript\nconst f1 = (x: unknown) => {\n    const isString = typeof x === 'string';\n    if (isString) {\n        x.length;\n    }\n};\n\nconst f2 = (\n    obj: { kind: 'foo'; foo: string } | { kind: 'bar'; bar: number }\n) => {\n    const isFoo = obj.kind === 'foo';\n    if (isFoo) {\n        obj.foo;\n    } else {\n        obj.bar;\n    }\n};\n```\n\nAlguns exemplos onde o estreitamento não ocorre:\n\n<!-- skip -->\n```typescript\nconst f1 = (x: unknown) => {\n    let isString = typeof x === 'string';\n    if (isString) {\n        x.length; // Erro, sem estreitamento porque isString não é const\n    }\n};\n\nconst f6 = (\n    obj: { kind: 'foo'; foo: string } | { kind: 'bar'; bar: number }\n) => {\n    const isFoo = obj.kind === 'foo';\n    obj = obj;\n    if (isFoo) {\n        obj.foo; // Erro, sem estreitamento porque obj é atribuído no corpo da função\n    }\n};\n```\n\nNotas: Até cinco níveis de indireção são analisados em expressões condicionais.\n\n"
  },
  {
    "path": "website/src/content/docs/pt-br/book/differences-between-type-and-interface.md",
    "content": "---\ntitle: Diferenças entre Type e Interface\nsidebar:\n  order: 53\n  label: 53. Diferenças entre Type e Interface\n---\n\n\nMesclagem de declarações (aumento):\n\nAs interfaces suportam a mesclagem de declarações, o que significa que você pode definir várias interfaces com o mesmo nome, e o TypeScript as mesclará em uma única interface com as propriedades e métodos combinados. Por outro lado, os tipos (types) não suportam a mesclagem de declarações. Isso pode ser útil quando você deseja adicionar funcionalidades extras ou personalizar tipos existentes sem modificar as definições originais ou corrigir tipos ausentes ou incorretos.\n\n```typescript\ninterface A {\n    x: string;\n}\ninterface A {\n    y: string;\n}\nconst j: A = {\n    x: 'xx',\n    y: 'yy',\n};\n```\n\nEstendendo outros tipos/interfaces:\n\nTanto tipos quanto interfaces podem estender outros tipos/interfaces, mas a sintaxe é diferente. Com as interfaces, você usa a palavra-chave `extends` para herdar propriedades e métodos de outras interfaces. No entanto, uma interface não pode estender um tipo complexo, como um tipo união.\n\n```typescript\ninterface A {\n    x: string;\n    y: number;\n}\ninterface B extends A {\n    z: string;\n}\nconst car: B = {\n    x: 'x',\n    y: 123,\n    z: 'z',\n};\n```\n\nPara tipos, você usa o operador `&` para combinar múltiplos tipos em um único tipo (interseção).\n\n```typescript\ninterface A {\n    x: string;\n    y: number;\n}\n\ntype B = A & {\n    j: string;\n};\n\nconst c: B = {\n    x: 'x',\n    y: 123,\n    j: 'j',\n};\n```\n\nTipos União e Interseção:\n\nOs tipos (types) são mais flexíveis quando se trata de definir Tipos União e Interseção. Com a palavra-chave `type`, você pode criar facilmente tipos união usando o operador `|` e tipos interseção usando o operador `&`. Embora as interfaces também possam representar tipos união indiretamente, elas não possuem suporte integrado para tipos interseção.\n\n```typescript\ntype Department = 'dep-x' | 'dep-y'; // União\n\ntype Person = {\n    name: string;\n    age: number;\n};\n\ntype Employee = {\n    id: number;\n    department: Department;\n};\n\ntype EmployeeInfo = Person & Employee; // Interseção\n```\n\nExemplo com interfaces:\n\n```typescript\ninterface A {\n    x: 'x';\n}\ninterface B {\n    y: 'y';\n}\n\ntype C = A | B; // União de interfaces\n```\n\n"
  },
  {
    "path": "website/src/content/docs/pt-br/book/discriminated-unions.md",
    "content": "---\ntitle: Uniões Discriminadas\nsidebar:\n  order: 24\n  label: 24. Uniões Discriminadas\n---\n\n\nUniões Discriminadas (Discriminated Unions) no TypeScript são um tipo de união que usa uma propriedade comum, conhecida como discriminante, para estreitar o conjunto de tipos possíveis para a união.\n\n```typescript\ntype Square = {\n    kind: 'square'; // Discriminante\n    size: number;\n};\n\ntype Circle = {\n    kind: 'circle'; // Discriminante\n    radius: number;\n};\n\ntype Shape = Square | Circle;\n\nconst area = (shape: Shape) => {\n    switch (shape.kind) {\n        case 'square':\n            return Math.pow(shape.size, 2);\n        case 'circle':\n            return Math.PI * Math.pow(shape.radius, 2);\n    }\n};\n\nconst square: Square = { kind: 'square', size: 5 };\nconst circle: Circle = { kind: 'circle', radius: 2 };\n\nconsole.log(area(square)); // 25\nconsole.log(area(circle)); // 12.566370614359172\n```\n\n"
  },
  {
    "path": "website/src/content/docs/pt-br/book/distributive-conditional-types.md",
    "content": "---\ntitle: Tipos Condicionais Distributivos\nsidebar:\n  order: 40\n  label: 40. Tipos Condicionais Distributivos\n---\n\n\nTipos Condicionais Distributivos são um recurso que permite que um tipo seja distribuído sobre uma união de tipos, aplicando uma transformação a cada membro da união individualmente.\nIsso pode ser especialmente útil ao trabalhar com tipos mapeados ou tipos de ordem superior.\n\n```typescript\ntype Nullable<T> = T extends any ? T | null : never;\ntype NumberOrBool = number | boolean;\ntype NullableNumberOrBool = Nullable<NumberOrBool>; // number | boolean | null\n```\n\n"
  },
  {
    "path": "website/src/content/docs/pt-br/book/downloads-and-website.md",
    "content": "---\ntitle: Downloads e site\nsidebar:\n  order: 3\n  label: 3. Downloads e site\n---\n\n\nVocê também pode baixar a versão Epub:\n\n[https://github.com/gibbok/typescript-book/tree/main/downloads](https://github.com/gibbok/typescript-book/tree/main/downloads)\n\nUma versão online está disponível em:\n\n[https://gibbok.github.io/typescript-book](https://gibbok.github.io/typescript-book)\n\n"
  },
  {
    "path": "website/src/content/docs/pt-br/book/enums.md",
    "content": "---\ntitle: Enums\nsidebar:\n  order: 19\n  label: 19. Enums\n---\n\n\nNo TypeScript, um `enum` é um conjunto de valores constantes nomeados.\n\n```typescript\nenum Color {\n    Red = '#ff0000',\n    Green = '#00ff00',\n    Blue = '#0000ff',\n}\n```\n\nEnums podem ser definidos de diferentes maneiras:\n\n### Enums numéricos\n\nNo TypeScript, um Enum Numérico é um Enum onde cada constante recebe um valor numérico, começando em 0 por padrão.\n\n```typescript\nenum Size {\n    Small, // o valor começa de 0\n    Medium,\n    Large,\n}\n```\n\nÉ possível especificar valores personalizados atribuindo-os explicitamente:\n\n```typescript\nenum Size {\n    Small = 10,\n    Medium,\n    Large,\n}\nconsole.log(Size.Medium); // 11\n```\n\n### Enums de string\n\nNo TypeScript, um Enum de String é um Enum onde cada constante recebe um valor de string.\n\n```typescript\nenum Language {\n    English = 'EN',\n    Spanish = 'ES',\n}\n```\n\nNota: O TypeScript permite o uso de Enums heterogêneos, onde membros de string e numéricos podem coexistir.\n\n### Enums constantes\n\nUm enum constante (const enum) no TypeScript é um tipo especial de Enum onde todos os valores são conhecidos em tempo de compilação e são inseridos diretamente (inlined) onde quer que o enum seja usado, resultando em um código mais eficiente.\n\n```typescript\nconst enum Language {\n    English = 'EN',\n    Spanish = 'ES',\n}\nconsole.log(Language.English);\n```\n\nSerá compilado para:\n\n```typescript\nconsole.log('EN' /* Language.English */);\n```\n\nNotas:\nEnums Constantes têm valores fixos (hardcoded), apagando o Enum, o que pode ser mais eficiente em bibliotecas autocontidas, mas geralmente não é desejável. Além disso, enums constantes não podem ter membros computados.\n\n### Mapeamento reverso\n\nNo TypeScript, os mapeamentos reversos em Enums referem-se à capacidade de recuperar o nome do membro do Enum a partir de seu valor. Por padrão, os membros do Enum têm mapeamentos diretos (forward mappings) do nome para o valor, mas mapeamentos reversos podem ser criados definindo explicitamente os valores para cada membro. Os mapeamentos reversos são úteis quando você precisa procurar um membro do Enum pelo seu valor ou quando precisa iterar sobre todos os membros do Enum. Note que apenas membros de enums numéricos gerarão mapeamentos reversos, enquanto membros de Enums de String não possuem um mapeamento reverso gerado.\n\nO seguinte enum:\n\n```typescript\nenum Grade {\n    A = 90,\n    B = 80,\n    C = 70,\n    F = 'fail',\n}\n```\n\nCompila para:\n\n<!-- skip -->\n```javascript\n'use strict';\nvar Grade;\n(function (Grade) {\n    Grade[(Grade['A'] = 90)] = 'A';\n    Grade[(Grade['B'] = 80)] = 'B';\n    Grade[(Grade['C'] = 70)] = 'C';\n    Grade['F'] = 'fail';\n})(Grade || (Grade = {}));\n```\n\nPortanto, mapear valores para chaves funciona para membros de enums numéricos, mas não para membros de enums de string:\n\n<!-- skip -->\n```typescript\nenum Grade {\n    A = 90,\n    B = 80,\n    C = 70,\n    F = 'fail',\n}\nconst myGrade = Grade.A;\nconsole.log(Grade[myGrade]); // A\nconsole.log(Grade[90]); // A\n\nconst failGrade = Grade.F;\nconsole.log(failGrade); // fail\nconsole.log(Grade[failGrade]); // Element implicitly has an 'any' type because index expression is not of type 'number'.\n```\n\n### Enums de ambiente\n\nUm enum de ambiente no TypeScript é um tipo de Enum que é definido em um arquivo de declaração (*.d.ts) sem uma implementação associada. Ele permite definir um conjunto de constantes nomeadas que podem ser usadas de forma segura em relação aos tipos em diferentes arquivos, sem ter que importar os detalhes da implementação em cada arquivo.\n\n### Membros computados e constantes\n\nNo TypeScript, um membro computado é um membro de um Enum que possui um valor calculado em tempo de execução, enquanto um membro constante é um membro cujo valor é definido em tempo de compilação e não pode ser alterado durante o tempo de execução. Membros computados são permitidos em Enums regulares, enquanto membros constantes são permitidos tanto em enums regulares quanto em enums constantes (const enums).\n\n```typescript\n// Membros constantes\nenum Color {\n    Red = 1,\n    Green = 5,\n    Blue = Red + Green,\n}\nconsole.log(Color.Blue); // geração 6 em tempo de compilação\n```\n\n```typescript\n// Membros computados\nenum Color {\n    Red = 1,\n    Green = Math.pow(2, 2),\n    Blue = Math.floor(Math.random() * 3) + 1,\n}\nconsole.log(Color.Blue); // número aleatório gerado em tempo de execução\n```\n\nEnums são representados por uniões compostas pelos tipos de seus membros. Os valores de cada membro podem ser determinados por meio de expressões constantes ou não constantes, com membros que possuem valores constantes recebendo tipos literais. Para ilustrar, considere a declaração do tipo E e seus subtipos E.A, E.B e E.C. Neste caso, E representa a união E.A | E.B | E.C.\n\n```typescript\nconst identity = (value: number) => value;\n\nenum E {\n    A = 2 * 5, // Literal numérico\n    B = 'bar', // Literal de string\n    C = identity(42), // Computado opaco\n}\n\nconsole.log(E.C); //42\n```\n\n"
  },
  {
    "path": "website/src/content/docs/pt-br/book/erased-structural-types.md",
    "content": "---\ntitle: Tipos Estruturais Apagados\nsidebar:\n  order: 56\n  label: 56. Tipos Estruturais Apagados\n---\n\n\nNo TypeScript, os objetos não precisam corresponder a um tipo exato e específico. Por exemplo, se criarmos um objeto que satisfaça os requisitos de uma interface, podemos utilizar esse objeto em locais onde essa interface é necessária, mesmo que não haja uma conexão explícita entre eles.\nExemplo:\n\n```typescript\ntype NameProp1 = {\n    prop1: string;\n};\n\nfunction log(x: NameProp1) {\n    console.log(x.prop1);\n}\n\nconst obj = {\n    prop2: 123,\n    prop1: 'Origin',\n};\n\nlog(obj); // Válido\n```\n\n"
  },
  {
    "path": "website/src/content/docs/pt-br/book/exhaustiveness-checking.md",
    "content": "---\ntitle: Verificação de exaustividade\nsidebar:\n  order: 26\n  label: 26. Verificação de exaustividade\n---\n\n\nA verificação de exaustividade (exhaustiveness checking) é um recurso no TypeScript que garante que todos os casos possíveis de uma união discriminada sejam tratados em uma instrução `switch` ou `if`.\n\n```typescript\ntype Direction = 'up' | 'down';\n\nconst move = (direction: Direction) => {\n    switch (direction) {\n        case 'up':\n            console.log('Movendo para cima');\n            break;\n        case 'down':\n            console.log('Movendo para baixo');\n            break;\n        default:\n            const exhaustiveCheck: never = direction;\n            console.log(exhaustiveCheck); // Esta linha nunca será executada\n    }\n};\n```\n\nO tipo `never` é usado para garantir que o caso `default` seja exaustivo e que o TypeScript aponte um erro se um novo valor for adicionado ao tipo `Direction` sem ser tratado na instrução switch.\n\n"
  },
  {
    "path": "website/src/content/docs/pt-br/book/exploring-the-type-system.md",
    "content": "---\ntitle: Explorando o Sistema de Tipos\nsidebar:\n  order: 9\n  label: 9. Explorando o Sistema de Tipos\n---\n\n\n### O Serviço de Linguagem do TypeScript\n\nO Serviço de Linguagem do TypeScript, também conhecido como tsserver, oferece vários recursos, como relatório de erros, diagnósticos, compilar ao salvar, renomeação, ir para definição, listas de preenchimento, ajuda de assinatura e muito mais. É usado principalmente por ambientes de desenvolvimento integrados (IDEs) para fornecer suporte ao IntelliSense. Ele se integra perfeitamente ao Visual Studio Code e é utilizado por ferramentas como Conquer of Completion (Coc).\n\nOs desenvolvedores podem aproveitar uma API dedicada e criar seus próprios plugins de serviço de linguagem personalizados para aprimorar a experiência de edição do TypeScript. Isso pode ser particularmente útil para implementar recursos especiais de linting ou habilitar o preenchimento automático para uma linguagem de modelagem personalizada.\n\n<!-- markdownlint-disable MD044 -->\nUm exemplo de plugin personalizado do mundo real é o \"typescript-styled-plugin\", que fornece relatórios de erros de sintaxe e suporte IntelliSense para propriedades CSS em componentes estilizados (styled components).\n<!-- markdownlint-enable MD044 -->\n\nPara mais informações e guias de início rápido, você pode consultar o Wiki oficial do TypeScript no GitHub: [https://github.com/microsoft/TypeScript/wiki/](https://github.com/microsoft/TypeScript/wiki/)\n\n### Tipagem Estrutural\n\nO TypeScript é baseado em um sistema de tipos estrutural. Isso significa que a compatibilidade e a equivalência de tipos são determinadas pela estrutura ou definição real do tipo, em vez de seu nome ou local de declaração, como em sistemas de tipos nominativos como C# ou C++.\n\nO sistema de tipos estrutural do TypeScript foi projetado com base em como o sistema de tipagem dinâmica \"duck typing\" do JavaScript funciona durante o tempo de execução.\n\nO exemplo a seguir é um código TypeScript válido. Como você pode observar, \"X\" e \"Y\" têm o mesmo membro \"a\", embora tenham nomes de declaração diferentes. Os tipos são determinados por suas estruturas e, neste caso, como as estruturas são as mesmas, eles são compatíveis e válidos.\n\n```typescript\ntype X = {\n    a: string;\n};\ntype Y = {\n    a: string;\n};\nconst x: X = { a: 'a' };\nconst y: Y = x; // Válido\n```\n\n### Regras Fundamentais de Comparação do TypeScript\n\nO processo de comparação do TypeScript é recursivo e executado em tipos aninhados em qualquer nível.\n\nUm tipo \"X\" é compatível com \"Y\" se \"Y\" tiver pelo menos os mesmos membros que \"X\".\n\n```typescript\ntype X = {\n    a: string;\n};\nconst y = { a: 'A', b: 'B' }; // Válido, pois tem pelo menos os mesmos membros que X\nconst r: X = y;\n```\n\nOs parâmetros da função são comparados por tipos, não por seus nomes:\n\n```typescript\ntype X = (a: number) => void;\ntype Y = (a: number) => void;\nlet x: X = (j: number) => undefined;\nlet y: Y = (k: number) => undefined;\ny = x; // Válido\nx = y; // Válido\n```\n\nOs tipos de retorno da função devem ser os mesmos:\n\n<!-- skip -->\n```typescript\ntype X = (a: number) => undefined;\ntype Y = (a: number) => number;\nlet x: X = (a: number) => undefined;\nlet y: Y = (a: number) => 1;\ny = x; // Inválido\nx = y; // Inválido\n```\n\nO tipo de retorno de uma função de origem deve ser um subtipo do tipo de retorno de uma função de destino:\n\n<!-- skip -->\n```typescript\nlet x = () => ({ a: 'A' });\nlet y = () => ({ a: 'A', b: 'B' });\nx = y; // Válido\ny = x; // Inválido, o membro b está faltando\n```\n\nDescartar parâmetros de função é permitido, pois é uma prática comum no JavaScript, por exemplo, usando \"Array.prototype.map()\":\n\n```typescript\n[1, 2, 3].map((element, _index, _array) => element + 'x');\n```\n\nPortanto, as seguintes declarações de tipo são completamente válidas:\n\n```typescript\ntype X = (a: number) => undefined;\ntype Y = (a: number, b: number) => undefined;\nlet x: X = (a: number) => undefined;\nlet y: Y = (a: number) => undefined; // Falta o parâmetro b\ny = x; // Válido\n```\n\nQuaisquer parâmetros opcionais adicionais do tipo de origem são válidos:\n\n```typescript\ntype X = (a: number, b?: number, c?: number) => undefined;\ntype Y = (a: number) => undefined;\nlet x: X = a => undefined;\nlet y: Y = a => undefined;\ny = x; // Válido\nx = y; // Válido\n```\n\nQuaisquer parâmetros opcionais do tipo de destino sem parâmetros correspondentes no tipo de origem são válidos e não constituem um erro:\n\n```typescript\ntype X = (a: number) => undefined;\ntype Y = (a: number, b?: number) => undefined;\nlet x: X = a => undefined;\nlet y: Y = a => undefined;\ny = x; // Válido\nx = y; // Válido\n```\n\nO parâmetro rest é tratado como uma série infinita de parâmetros opcionais:\n\n```typescript\ntype X = (a: number, ...rest: number[]) => undefined;\nlet x: X = a => undefined; // Válido\n```\n\nFunções com sobrecargas são válidas se a assinatura da sobrecarga for compatível com sua assinatura de implementação:\n\n<!-- skip -->\n```typescript\nfunction x(a: string): void;\nfunction x(a: string, b: number): void;\nfunction x(a: string, b?: number): void {\n    console.log(a, b);\n}\nx('a'); // Válido\nx('a', 1); // Válido\n\nfunction y(a: string): void; // Inválido, não compatível com a assinatura de implementação\nfunction y(a: string, b: number): void;\nfunction y(a: string, b: number): void {\n    console.log(a, b);\n}\ny('a');\ny('a', 1);\n```\n\nA comparação de parâmetros de função é bem-sucedida se os parâmetros de origem e de destino forem atribuíveis a supertipos ou subtipos (bivariância).\n\n```typescript\n// Supertipo\nclass X {\n    a: string;\n    constructor(value: string) {\n        this.a = value;\n    }\n}\n// Subtipo\nclass Y extends X {}\n// Subtipo\nclass Z extends X {}\n\ntype GetA = (x: X) => string;\nconst getA: GetA = x => x.a;\n\n// A bivariância aceita supertipos\nconsole.log(getA(new X('x'))); // Válido\nconsole.log(getA(new Y('Y'))); // Válido\nconsole.log(getA(new Z('z'))); // Válido\n```\n\nEnums são comparáveis e válidos com números e vice-versa, mas comparar valores de Enum de diferentes tipos de Enum é inválido.\n\n<!-- skip -->\n```typescript\nenum X {\n    A,\n    B,\n}\nenum Y {\n    A,\n    B,\n    C,\n}\nconst xa: number = X.A; // Válido\nconst ya: Y = 0; // Válido\nX.A === Y.A; // Inválido\n```\n\nInstâncias de uma classe estão sujeitas a uma verificação de compatibilidade para seus membros privados e protegidos:\n\n<!-- skip -->\n```typescript\nclass X {\n    public a: string;\n    constructor(value: string) {\n        this.a = value;\n    }\n}\n\nclass Y {\n    private a: string;\n    constructor(value: string) {\n        this.a = value;\n    }\n}\n\nlet x: X = new Y('y'); // Inválido\n```\n\nA verificação de comparação não leva em consideração as diferentes hierarquias de herança, por exemplo:\n\n```typescript\nclass X {\n    public a: string;\n    constructor(value: string) {\n        this.a = value;\n    }\n}\nclass Y extends X {\n    public a: string;\n    constructor(value: string) {\n        super(value);\n        this.a = value;\n    }\n}\nclass Z {\n    public a: string;\n    constructor(value: string) {\n        this.a = value;\n    }\n}\nlet x: X = new X('x');\nlet y: Y = new Y('y');\nlet z: Z = new Z('z');\nx === y; // Válido\nx === z; // Válido mesmo que z seja de uma hierarquia de herança diferente\n```\n\nGenéricos são comparados usando suas estruturas baseadas no tipo resultante após a aplicação do parâmetro genérico; apenas o resultado final é comparado como um tipo não genérico.\n\n<!-- skip -->\n```typescript\ninterface X<T> {\n    a: T;\n}\nlet x: X<number> = { a: 1 };\nlet y: X<string> = { a: 'a' };\nx === y; // Inválido, pois o argumento de tipo é usado na estrutura final\n```\n\n```typescript\ninterface X<T> {}\nconst x: X<number> = 1;\nconst y: X<string> = 'a';\nx === y; // Válido, pois o argumento de tipo não é usado na estrutura final\n```\n\nQuando os genéricos não têm seu argumento de tipo especificado, todos os argumentos não especificados são tratados como tipos com \"any\":\n\n```typescript\ntype X = <T>(x: T) => T;\ntype Y = <K>(y: K) => K;\nlet x: X = x => x;\nlet y: Y = y => y;\nx = y; // Válido\n```\n\nLembre-se:\n\n<!-- skip -->\n```typescript\nlet a: number = 1;\nlet b: number = 2;\na = b; // Válido, tudo é atribuível a si mesmo\n\nlet c: any;\nc = 1; // Válido, todos os tipos são atribuíveis a any\n\nlet d: unknown;\nd = 1; // Válido, todos os tipos são atribuíveis a unknown\n\nlet e: unknown;\nlet e1: unknown = e; // Válido, unknown só é atribuível a si mesmo e a any\nlet e2: any = e; // Válido\nlet e3: number = e; // Inválido\n\nlet f: never;\nf = 1; // Inválido, nada é atribuível a never\n\nlet g: void;\nlet g1: any;\ng = 1; // Inválido, void não é atribuível a nada, exceto any, nem nada é atribuível a ele\ng = g1; // Válido\n```\n\nObserve que quando \"strictNullChecks\" está habilitado, \"null\" e \"undefined\" são tratados de forma semelhante a \"void\"; caso contrário, são semelhantes a \"never\".\n\n### Tipos como Conjuntos\n\nNo TypeScript, um tipo é um conjunto de valores possíveis. Este conjunto também é conhecido como o domínio do tipo. Cada valor de um tipo pode ser visto como um elemento em um conjunto. Um tipo estabelece as restrições que cada elemento no conjunto deve satisfazer para ser considerado um membro desse conjunto.\nA principal tarefa do TypeScript é verificar se um conjunto é um subconjunto de outro.\n\nO TypeScript suporta vários tipos de conjuntos:\n\n| Termo do conjunto      | TypeScript                      | Notas                                                                                                                                  |\n| ---------------------- | ------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |\n| Conjunto vazio         | never                           | \"never\" não contém nada além de si mesmo                                                                                               |\n| Conjunto de elemento único | undefined / null / tipo literal |                                                                                                                                        |\n| Conjunto finito        | boolean / união                 |                                                                                                                                        |\n| Conjunto infinito      | string / number / objeto        |                                                                                                                                        |\n| Conjunto universal     | any / unknown                   | Cada elemento é um membro de \"any\" e cada conjunto é um subconjunto dele / \"unknown\" é uma contraparte segura em termos de tipo do \"any\" |\n\nAqui estão alguns exemplos:\n\n| TypeScript              | Termo do conjunto          | Exemplo                                                                               |\n| ----------------------- | -------------------------- | ------------------------------------------------------------------------------------- |\n| never                   | ∅ (conjunto vazio)         | const x: never = 'x'; // Erro: O tipo 'string' não pode ser atribuído ao tipo 'never' |\n|                         |                            |\n| Tipo literal            | Conjunto de elemento único | type X = 'X';                                                                         |\n|                         |                            | type Y = 7;                                                                           |\n|                         |                            |\n| Valor atribuível a T    | Valor ∈ T (membro de)      | type XY = 'X' \\| 'Y';                                                                 |\n|                         |                            | const x: XY = 'X';                                                                    |\n|                         |                            |\n| T1 atribuível a T2      | T1 ⊆ T2 (subconjunto de)   | type XY = 'X' \\| 'Y';                                                                 |\n|                         |                            | const x: XY = 'X';                                                                    |\n|                         |                            | const j: XY = 'J'; // O tipo '\"J\"' não pode ser atribuído ao tipo 'XY'.               |\n|                         |                            |                                                                                       |\n| T1 extends T2           | T1 ⊆ T2 (subconjunto de)   | type X = 'X' extends string ? true : false;                                           |\n|                         |                            |\n| T1 \\| T2                | T1 ∪ T2 (união)            | type XY = 'X' \\| 'Y';                                                                 |\n|                         |                            | type JK = 1 \\| 2;                                                                     |\n|                         |                            |\n| T1 & T2                 | T1 ∩ T2 (interseção)       | type X = \\{ a: string \\}                                                                |\n|                         |                            | type Y = \\{ b: string \\}                                                                |\n|                         |                            | type XY = X & Y                                                                       |\n|                         |                            | const x: XY = \\{ a: 'a', b: 'b' \\}                                                      |\n|                         |                            |\n| unknown                 | Conjunto universal         | const x: unknown = 1                                                                  |\n\nUma união, (T1 | T2), cria um conjunto mais amplo (ambos):\n\n```typescript\ntype X = {\n    a: string;\n};\ntype Y = {\n    b: string;\n};\ntype XY = X | Y;\nconst r: XY = { a: 'a', b: 'x' }; // Válido\n```\n\nUma interseção, (T1 & T2), cria um conjunto mais estreito (apenas o que é compartilhado):\n\n<!-- skip -->\n```typescript\ntype X = {\n    a: string;\n};\ntype Y = {\n    a: string;\n    b: string;\n};\ntype XY = X & Y;\nconst r: XY = { a: 'a' }; // Inválido\nconst j: XY = { a: 'a', b: 'b' }; // Válido\n```\n\nA palavra-chave `extends` pode ser considerada como \"subconjunto de\" neste contexto. Ela define uma restrição para um tipo. O `extends` usado com um genérico trata o genérico como um conjunto infinito e o restringe a um tipo mais específico.\nObserve que o `extends` nada tem a ver com hierarquia no sentido de Orientação a Objetos (não existe esse conceito no TypeScript).\nO TypeScript trabalha com conjuntos e não possui uma hierarquia estrita; de fato, como no exemplo abaixo, dois tipos podem se sobrepor sem que nenhum seja um subtipo do outro (o TypeScript considera a estrutura, a forma dos objetos).\n\n```typescript\ninterface X {\n    a: string;\n}\ninterface Y extends X {\n    b: string;\n}\ninterface Z extends Y {\n    c: string;\n}\nconst z: Z = { a: 'a', b: 'b', c: 'c' };\ninterface X1 {\n    a: string;\n}\ninterface Y1 {\n    a: string;\n    b: string;\n}\ninterface Z1 {\n    a: string;\n    b: string;\n    c: string;\n}\nconst z1: Z1 = { a: 'a', b: 'b', c: 'c' };\n\nconst r: Z1 = z; // Válido\n```\n\n### Atribuir um tipo: Declarações de Tipo e Asserções de Tipo\n\nUm tipo pode ser atribuído de diferentes maneiras no TypeScript:\n\n#### Declaração de Tipo\n\nNo exemplo a seguir, usamos x: X (\": Tipo\") para declarar um tipo para a variável x.\n\n```typescript\ntype X = {\n    a: string;\n};\n\n// Declaração de tipo\nconst x: X = {\n    a: 'a',\n};\n```\n\nSe a variável não estiver no formato especificado, o TypeScript relatará um erro. Por exemplo:\n\n<!-- skip -->\n```typescript\ntype X = {\n    a: string;\n};\n\nconst x: X = {\n    a: 'a',\n    b: 'b', // Erro: O objeto literal só pode especificar propriedades conhecidas\n};\n```\n\n#### Asserção de Tipo\n\nÉ possível adicionar uma asserção usando a palavra-chave `as`. Isso informa ao compilador que o desenvolvedor tem mais informações sobre um tipo e silencia quaisquer erros que possam ocorrer.\n\nPor exemplo:\n\n```typescript\ntype X = {\n    a: string;\n};\nconst x = {\n    a: 'a',\n    b: 'b',\n} as X;\n```\n\nNo exemplo acima, o objeto x é asseverado como tendo o tipo X usando a palavra-chave `as`. Isso informa ao compilador TypeScript que o objeto está em conformidade com o tipo especificado, embora tenha uma propriedade b adicional não presente na definição do tipo.\n\nAsserções de tipo são úteis em situações onde um tipo mais específico precisa ser especificado, especialmente ao trabalhar com o DOM. Por exemplo:\n\n```typescript\nconst myInput = document.getElementById('my_input') as HTMLInputElement;\n```\n\nAqui, a asserção de tipo `as HTMLInputElement` é usada para dizer ao TypeScript que o resultado de `getElementById` deve ser tratado como um `HTMLInputElement`.\nAsserções de tipo também podem ser usadas para mapear chaves novamente, conforme mostrado no exemplo abaixo com literais de template:\n\n```typescript\ntype J<Type> = {\n    [Property in keyof Type as `prefix_${string &\n        Property}`]: () => Type[Property];\n};\ntype X = {\n    a: string;\n    b: number;\n};\ntype Y = J<X>;\n```\n\nNeste exemplo, o tipo `J<Type>` usa um tipo mapeado com um literal de template para mapear as chaves de `Type`. Ele cria novas propriedades com um \"prefix_\" adicionado a cada chave, e seus valores correspondentes são funções que retornam os valores originais da propriedade.\n\nVale a pena notar que, ao usar uma asserção de tipo, o TypeScript não executará a verificação de excesso de propriedades. Portanto, geralmente é preferível usar uma Declaração de Tipo quando a estrutura do objeto for conhecida antecipadamente.\n\n#### Declarações de Ambiente (Ambient Declarations)\n\nDeclarações de ambiente são arquivos que descrevem tipos para código JavaScript; eles têm o formato de nome de arquivo `.d.ts`. Geralmente são importados e usados para anotar bibliotecas JavaScript existentes ou para adicionar tipos a arquivos JS existentes em seu projeto.\n\nMuitos tipos de bibliotecas comuns podem ser encontrados em:\n[https://github.com/DefinitelyTyped/DefinitelyTyped/](https://github.com/DefinitelyTyped/DefinitelyTyped/)\n\ne podem ser instalados usando:\n\n```shell\nnpm install --save-dev @types/nome-da-biblioteca\n```\n\nPara suas Declarações de Ambiente definidas, você pode importar usando a referência de \"barra tripla\":\n\n<!-- skip -->\n```typescript\n/// <reference path=\"./library-types.d.ts\" />\n```\n\nVocê pode usar Declarações de Ambiente até mesmo em arquivos JavaScript usando `// @ts-check`.\n\nA palavra-chave `declare` habilita definições de tipo para código JavaScript existente sem importá-lo, servindo como um marcador para tipos de outro arquivo ou globalmente.\n\n### Verificação de Propriedades e Verificação de Excesso de Propriedades\n\nO TypeScript é baseado em um sistema de tipos estrutural, mas a verificação de excesso de propriedades é um recurso do TypeScript que permite verificar se um objeto tem exatamente as propriedades especificadas no tipo.\n\nA Verificação de Excesso de Propriedades é executada ao atribuir objetos literais a variáveis ou ao passá-los como argumentos para funções, por exemplo.\n\n<!-- skip -->\n```typescript\ntype X = {\n    a: string;\n};\nconst y = { a: 'a', b: 'b' };\nconst x: X = y; // Válido por causa da tipagem estrutural\nconst w: X = { a: 'a', b: 'b' }; // Inválido por causa da verificação de excesso de propriedades\n```\n\n### Tipos Fracos (Weak Types)\n\nUm tipo é considerado fraco quando não contém nada além de um conjunto de todas as propriedades opcionais:\n\n```typescript\ntype X = {\n    a?: string;\n    b?: string;\n};\n```\n\nO TypeScript considera um erro atribuir qualquer coisa a um tipo fraco quando não há sobreposição; por exemplo, o seguinte lança um erro:\n\n<!-- skip -->\n```typescript\ntype Options = {\n    a?: string;\n    b?: string;\n};\n\nconst fn = (options: Options) => undefined;\n\nfn({ c: 'c' }); // Inválido\n```\n\nEmbora não recomendado, se necessário, é possível ignorar esta verificação usando asserção de tipo:\n\n```typescript\ntype Options = {\n    a?: string;\n    b?: string;\n};\nconst fn = (options: Options) => undefined;\nfn({ c: 'c' } as Options); // Válido\n```\n\nOu adicionando `unknown` à assinatura de índice do tipo fraco:\n\n```typescript\ntype Options = {\n    [prop: string]: unknown;\n    a?: string;\n    b?: string;\n};\n\nconst fn = (options: Options) => undefined;\nfn({ c: 'c' }); // Válido\n```\n\n### Verificação Estrita de Objeto Literal (Freshness)\n\nA verificação estrita de objeto literal, às vezes chamada de \"freshness\", é um recurso do TypeScript que ajuda a capturar propriedades em excesso ou com erro de ortografia que, de outra forma, passariam despercebidas em verificações normais de tipo estrutural.\n\nAo criar um objeto literal, o compilador TypeScript o considera \"fresco\" (fresh). Se o objeto literal for atribuído a uma variável ou passado como um parâmetro, o TypeScript lançará um erro se o objeto literal especificar propriedades que não existem no tipo de destino.\n\nNo entanto, a \"freshness\" desaparece quando um objeto literal é alargado ou quando uma asserção de tipo é usada.\n\nAqui estão alguns exemplos para ilustrar:\n\n<!-- skip -->\n```typescript\ntype X = { a: string };\ntype Y = { a: string; b: string };\n\nlet x: X;\nx = { a: 'a', b: 'b' }; // Verificação de Freshness: Atribuição inválida\nvar y: Y;\ny = { a: 'a', bx: 'bx' }; // Verificação de Freshness: Atribuição inválida\n\nconst fn = (x: X) => console.log(x.a);\n\nfn(x);\nfn(y); // Alargamento (Widening): Sem erros, estruturalmente compatível em termos de tipo\n\nfn({ a: 'a', bx: 'b' }); // Verificação de Freshness: Argumento inválido\n\nlet c: X = { a: 'a' };\nlet d: Y = { a: 'a', b: '' };\nc = d; // Alargamento: Sem verificação de Freshness\n```\n\n### Inferência de Tipo\n\nO TypeScript pode inferir tipos quando nenhuma anotação é fornecida durante a:\n\n* Inicialização da variável.\n* Inicialização de membros.\n* Definição de valores padrão para parâmetros.\n* Tipo de retorno da função.\n\nPor exemplo:\n\n```typescript\nlet x = 'x'; // O tipo inferido é string\n```\n\nO compilador TypeScript analisa o valor ou expressão e determina seu tipo com base nas informações disponíveis.\n\n### Inferências Mais Avançadas\n\nQuando várias expressões são usadas na inferência de tipo, o TypeScript procura pelos \"melhores tipos comuns\" (best common types). Por exemplo:\n\n```typescript\nlet x = [1, 'x', 1, null]; // O tipo inferido é: (string | number | null)[]\n```\n\nSe o compilador não conseguir encontrar os melhores tipos comuns, ele retorna um tipo de união. Por exemplo:\n\n```typescript\nlet x = [new RegExp('x'), new Date()]; // O tipo inferido é: (RegExp | Date)[]\n```\n\nO TypeScript utiliza a \"tipagem contextual\" baseada na localização da variável para inferir tipos. No exemplo a seguir, o compilador sabe que `e` é do tipo `MouseEvent` por causa do tipo de evento `click` definido no arquivo `lib.d.ts`, que contém declarações de ambiente para várias construções JavaScript comuns e o DOM:\n\n```typescript\nwindow.addEventListener('click', function (e) {}); // O tipo inferido de e é MouseEvent\n```\n\n### Alargamento de Tipo (Type Widening)\n\nO alargamento de tipo (type widening) é o processo no qual o TypeScript atribui um tipo a uma variável inicializada quando nenhuma anotação de tipo foi fornecida. Ele permite tipos de mais estreitos para mais amplos, mas não o contrário.\nNo exemplo a seguir:\n\n<!-- skip -->\n```typescript\nlet x = 'x'; // O TypeScript infere como string, um tipo amplo\nlet y: 'y' | 'x' = 'y'; // o tipo de y é uma união de tipos literais\ny = x; // Inválido: O tipo 'string' não pode ser atribuído ao tipo '\"x\" | \"y\"'.\n```\n\nO TypeScript atribui `string` a `x` com base no valor único fornecido durante a inicialização (`x`); este é um exemplo de alargamento.\n\nO TypeScript fornece maneiras de ter controle sobre o processo de alargamento, por exemplo, usando \"const\".\n\n### Const\n\nO uso da palavra-chave `const` ao declarar uma variável resulta em uma inferência de tipo mais estreita no TypeScript.\n\nPor exemplo:\n\n```typescript\nconst x = 'x'; // O TypeScript infere o tipo de x como 'x', um tipo mais estreito\nlet y: 'y' | 'x' = 'y';\ny = x; // Válido: O tipo de x é inferido como 'x'\n```\n\nAo usar `const` para declarar a variável x, seu tipo é estreitado para o valor literal específico 'x'. Como o tipo de x é estreitado, ele pode ser atribuído à variável y sem nenhum erro.\nA razão pela qual o tipo pode ser inferido é porque as variáveis `const` não podem ser reatribuídas, portanto seu tipo pode ser estreitado para um tipo literal específico, neste caso, o tipo literal 'x'.\n\n#### Modificador Const em Parâmetros de Tipo\n\nA partir da versão 5.0 do TypeScript, é possível especificar o atributo `const` em um parâmetro de tipo genérico. Isso permite inferir o tipo mais preciso possível. Vejamos um exemplo sem usar `const`:\n\n```typescript\nfunction identity<T>(value: T) {\n    // Sem const aqui\n    return value;\n}\nconst values = identity({ a: 'a', b: 'b' }); // O tipo inferido é: { a: string; b: string; }\n```\n\nComo você pode ver, as propriedades `a` e `b` são inferidas com o tipo `string`.\n\nAgora, vejamos a diferença com a versão `const`:\n\n```typescript\nfunction identity<const T>(value: T) {\n    // Usando modificador const em parâmetros de tipo\n    return value;\n}\nconst values = identity({ a: 'a', b: 'b' }); // O tipo inferido é: { a: \"a\"; b: \"b\"; }\n```\n\nAgora podemos ver que as propriedades `a` e `b` são inferidas como `const`, portanto `a` e `b` são tratados como literais de string em vez de apenas tipos `string`.\n\n#### Asserção Const (Const assertion)\n\nEste recurso permite declarar uma variável com um tipo literal mais preciso baseado em seu valor de inicialização, sinalizando ao compilador que o valor deve ser tratado como um literal imutável. Aqui estão alguns exemplos:\n\nEm uma única propriedade:\n\n```typescript\nconst v = {\n    x: 3 as const,\n};\nv.x = 3;\n```\n\nEm um objeto inteiro:\n\n```typescript\nconst v = {\n    x: 1,\n    y: 2,\n} as const;\n```\n\nIsso pode ser particularmente útil ao definir o tipo para uma tupla:\n\n```typescript\nconst x = [1, 2, 3]; // number[]\nconst y = [1, 2, 3] as const; // Tupla de readonly [1, 2, 3]\n```\n\n### Anotação de Tipo Explícita\n\nPodemos ser específicos e passar um tipo; no exemplo a seguir, a propriedade `x` é do tipo `number`:\n\n```typescript\nconst v = {\n    x: 1, // Tipo inferido: number (alargamento)\n};\nv.x = 3; // Válido\n```\n\nPodemos tornar a anotação de tipo mais específica usando uma união de tipos literais:\n\n<!-- skip -->\n```typescript\nconst v: { x: 1 | 2 | 3 } = {\n    x: 1, // x agora é uma união de tipos literais: 1 | 2 | 3\n};\nv.x = 3; // Válido\nv.x = 100; // Inválido\n```\n\n### Estreitamento de Tipo (Type Narrowing)\n\nO Estreitamento de Tipo (Type Narrowing) é o processo no TypeScript onde um tipo geral é estreitado para um tipo mais específico. Isso ocorre quando o TypeScript analisa o código e determina que certas condições ou operações podem refinar a informação do tipo.\n\nO estreitamento de tipos pode ocorrer de diferentes maneiras, incluindo:\n\n#### Condições\n\nAo usar instruções condicionais, como `if` ou `switch`, o TypeScript pode estreitar o tipo com base no resultado da condição. Por exemplo:\n\n```typescript\nlet x: number | undefined = 10;\n\nif (x !== undefined) {\n    x += 100; // O tipo é number, que foi estreitado pela condição\n}\n```\n\n#### Lançando ou retornando\n\nLançar um erro ou retornar cedo de uma ramificação pode ser usado para ajudar o TypeScript a estreitar um tipo. Por exemplo:\n\n```typescript\nlet x: number | undefined = 10;\n\nif (x === undefined) {\n    throw 'erro';\n}\nx += 100;\n```\n\nOutras formas de estreitar tipos no TypeScript incluem:\n\n* Operador `instanceof`: Usado para verificar se um objeto é uma instância de uma classe específica.\n* Operador `in`: Usado para verificar se uma propriedade existe em um objeto.\n* Operador `typeof`: Usado para verificar o tipo de um valor em tempo de execução.\n* Funções integradas como `Array.isArray()`: Usadas para verificar se um valor é um array.\n\n#### União Discriminada\n\nO uso de uma \"União Discriminada\" é um padrão no TypeScript onde uma \"tag\" explícita é adicionada aos objetos para distinguir entre diferentes tipos dentro de uma união. Este padrão também é conhecido como \"união tagueada\" (tagged union). No exemplo a seguir, a \"tag\" é representada pela propriedade \"type\":\n\n```typescript\ntype A = { type: 'type_a'; value: number };\ntype B = { type: 'type_b'; value: string };\n\nconst x = (input: A | B): string | number => {\n    switch (input.type) {\n        case 'type_a':\n            return input.value + 100; // o tipo é A\n        case 'type_b':\n            return input.value + 'extra'; // o tipo é B\n    }\n};\n```\n\n#### Proteções de Tipo Definidas pelo Usuário (User-Defined Type Guards)\n\nEm casos onde o TypeScript não é capaz de determinar um tipo, é possível escrever uma função auxiliar conhecida como \"proteção de tipo definida pelo usuário\" (user-defined type guard). No exemplo a seguir, utilizaremos um Predicado de Tipo para estreitar o tipo após aplicar certa filtragem:\n\n```typescript\nconst data = ['a', null, 'c', 'd', null, 'f'];\n\nconst r1 = data.filter(x => x != null); // O tipo é (string | null)[], o TypeScript não foi capaz de inferir o tipo corretamente\n\nconst isValid = (item: string | null): item is string => item !== null; // Protetor de tipo customizado\n\nconst r2 = data.filter(isValid); // O tipo está correto agora string[], ao usar o protetor de tipo predicado conseguimos estreitar o tipo\n```\n\n"
  },
  {
    "path": "website/src/content/docs/pt-br/book/extending-types.md",
    "content": "---\ntitle: Estendendo Tipos\nsidebar:\n  order: 15\n  label: 15. Estendendo Tipos\n---\n\n\nÉ possível estender uma `interface` (copiar membros de outro tipo):\n\n```typescript\ninterface X {\n    a: string;\n}\ninterface Y extends X {\n    b: string;\n}\n```\n\nTambém é possível estender de múltiplos tipos:\n\n```typescript\ninterface A {\n    a: string;\n}\ninterface B {\n    b: string;\n}\ninterface Y extends A, B {\n    y: string;\n}\n```\n\nA palavra-chave `extends` funciona apenas em interfaces e classes; para tipos, use uma interseção:\n\n```typescript\ntype A = {\n    a: number;\n};\ntype B = {\n    b: number;\n};\ntype C = A & B;\n```\n\nÉ possível estender um tipo usando uma inferência, mas não o contrário:\n\n```typescript\ntype A = {\n    a: string;\n};\ninterface B extends A {\n    b: string;\n}\n```\n\n"
  },
  {
    "path": "website/src/content/docs/pt-br/book/fixed-length-tuple.md",
    "content": "---\ntitle: Tupla de Comprimento Fixo\nsidebar:\n  order: 30\n  label: 30. Tupla de Comprimento Fixo\n---\n\n\nUma Tupla de Comprimento Fixo é um tipo específico de tupla que impõe um número fixo de elementos de tipos específicos e proíbe quaisquer modificações no comprimento da tupla uma vez definida.\n\nTuplas de Comprimento Fixo são úteis quando você precisa representar uma coleção de valores com um número específico de elementos e tipos específicos, e deseja garantir que o comprimento e os tipos da tupla não possam ser alterados inadvertidamente.\n\n<!-- skip -->\n```typescript\nconst x = [10, 'hello'] as const;\nx.push(2); // Erro\n```\n\n"
  },
  {
    "path": "website/src/content/docs/pt-br/book/generics.md",
    "content": "---\ntitle: Genéricos (Generics)\nsidebar:\n  order: 55\n  label: 55. Genéricos (Generics)\n---\n\n\nOs genéricos permitem que você crie componentes e funções reutilizáveis que podem trabalhar com múltiplos tipos. Com os genéricos, você pode parametrizar tipos, funções e interfaces, permitindo que operem em diferentes tipos sem especificá-los explicitamente de antemão.\n\nOs genéricos permitem tornar o código mais flexível e reutilizável.\n\n### Tipo Genérico\n\nPara definir um tipo genérico, você usa colchetes angulares (`<>`) para especificar os parâmetros de tipo, por exemplo:\n\n```typescript\nfunction identity<T>(arg: T): T {\n    return arg;\n}\nconst a = identity('x');\nconst b = identity(123);\n\nconst getLen = <T,>(data: ReadonlyArray<T>) => data.length;\nconst len = getLen([1, 2, 3]);\n```\n\n### Classes Genéricas\n\nOs genéricos também podem ser aplicados a classes, permitindo que trabalhem com múltiplos tipos por meio de parâmetros de tipo. Isso é útil para criar definições de classe reutilizáveis que podem operar em diferentes tipos de dados mantendo a segurança de tipo.\n\n```typescript\nclass Container<T> {\n    private item: T;\n\n    constructor(item: T) {\n        this.item = item;\n    }\n\n    getItem(): T {\n        return this.item;\n    }\n}\n\nconst numberContainer = new Container<number>(123);\nconsole.log(numberContainer.getItem()); // 123\n\nconst stringContainer = new Container<string>('hello');\nconsole.log(stringContainer.getItem()); // hello\n```\n\n### Restrições Genéricas (Generic Constraints)\n\nParâmetros genéricos podem ser restringidos usando a palavra-chave `extends` seguida por um tipo ou interface que o parâmetro de tipo deve satisfazer.\n\nNo exemplo a seguir, T deve conter uma propriedade `length` para ser válido:\n\n<!-- skip -->\n```typescript\nconst printLen = <T extends { length: number }>(value: T): void => {\n    console.log(value.length);\n};\n\nprintLen('Hello'); // 5\nprintLen([1, 2, 3]); // 3\nprintLen({ length: 10 }); // 10\nprintLen(123); // Inválido\n```\n\nUm recurso interessante de genéricos introduzido na versão 3.4 RC é a inferência de tipo de função de ordem superior, que introduziu argumentos de tipo genérico propagados:\n\n```typescript\ndeclare function pipe<A extends any[], B, C>(\n    ab: (...args: A) => B,\n    bc: (b: B) => C\n): (...args: A) => C;\n\ndeclare function list<T>(a: T): T[];\ndeclare function box<V>(x: V): { value: V };\n\nconst listBox = pipe(list, box); // <T>(a: T) => { value: T[] }\nconst boxList = pipe(box, list); // <V>(x: V) => { value: V }[]\n```\n\nEssa funcionalidade permite uma programação de estilo sem pontos (pointfree) com segurança de tipo mais fácil, o que é comum na programação funcional.\n\n### Estreitamento Contextual Genérico\n\nO estreitamento contextual (contextual narrowing) para genéricos é o mecanismo no TypeScript que permite ao compilador estreitar o tipo de um parâmetro genérico com base no contexto em que é usado. É útil ao trabalhar com tipos genéricos em declarações condicionais:\n\n```typescript\nfunction process<T>(value: T): void {\n    if (typeof value === 'string') {\n        // O valor é estreitado para o tipo 'string'\n        console.log(value.length);\n    } else if (typeof value === 'number') {\n        // O valor é estreitado para o tipo 'number'\n        console.log(value.toFixed(2));\n    }\n}\n\nprocess('hello'); // 5\nprocess(3.14159); // 3.14\n```\n\n"
  },
  {
    "path": "website/src/content/docs/pt-br/book/getting-started-with-typescript.md",
    "content": "---\ntitle: Começando com TypeScript\nsidebar:\n  order: 8\n  label: 8. Começando com TypeScript\n---\n\n\n### Instalação\n\nO Visual Studio Code oferece excelente suporte para a linguagem TypeScript, mas não inclui o compilador TypeScript. Para instalar o compilador TypeScript, você pode usar um gerenciador de pacotes como npm ou yarn:\n\n```shell\nnpm install typescript --save-dev\n```\n\nou\n\n```shell\nyarn add typescript --dev\n```\n\nCertifique-se de realizar o commit do arquivo de bloqueio (lockfile) gerado para garantir que cada membro da equipe use a mesma versão do TypeScript.\n\nPara executar o compilador TypeScript, você pode usar os seguintes comandos:\n\n```shell\nnpx tsc\n```\n\nou\n\n```shell\nyarn tsc\n```\n\nRecomenda-se instalar o TypeScript por projeto em vez de globalmente, pois fornece um processo de construção mais previsível. No entanto, para ocasiões pontuais, você pode usar o seguinte comando:\n\n```shell\nnpx tsc\n```\n\nou instalá-lo globalmente:\n\n```shell\nnpm install -g typescript\n```\n\nSe você estiver usando o Microsoft Visual Studio, pode obter o TypeScript como um pacote no NuGet para seus projetos MSBuild. No Console do Gerenciador de Pacotes NuGet, execute o seguinte comando:\n\n```shell\nInstall-Package Microsoft.TypeScript.MSBuild\n```\n\nDurante a instalação do TypeScript, dois executáveis são instalados: \"tsc\" como o compilador TypeScript e \"tsserver\" como o servidor autônomo do TypeScript. O servidor autônomo contém o compilador e os serviços de linguagem que podem ser utilizados por editores e IDEs para fornecer completamento inteligente de código.\n\nAlém disso, existem vários transpiladores compatíveis com TypeScript disponíveis, como Babel (via um plugin) ou swc. Esses transpiladores podem ser usados para converter código TypeScript em outras linguagens ou versões de destino.\n\n### Configuração\n\nO TypeScript pode ser configurado usando as opções da CLI do tsc ou utilizando um arquivo de configuração dedicado chamado tsconfig.json localizado na raiz do projeto.\n\nPara gerar um arquivo tsconfig.json pré-preenchido com as configurações recomendadas, você pode usar o seguinte comando:\n\n```shell\ntsc --init\n```\n\nAo executar o comando `tsc` localmente, o TypeScript compilará o código usando a configuração especificada no arquivo tsconfig.json mais próximo.\n\nAqui estão alguns exemplos de comandos da CLI que rodam com as configurações padrão:\n\n```shell\ntsc main.ts // Compila um arquivo específico (main.ts) para JavaScript\ntsc src/*.ts // Compila todos os arquivos .ts na pasta 'src' para JavaScript\ntsc app.ts util.ts --outfile index.js // Compila dois arquivos TypeScript (app.ts e util.ts) em um único arquivo JavaScript (index.js)\n```\n\n### Arquivo de Configuração do TypeScript\n\nUm arquivo tsconfig.json é usado para configurar o Compilador TypeScript (tsc). Geralmente, ele é adicionado à raiz do projeto, junto com o arquivo `package.json`.\n\nNotas:\n\n* tsconfig.json aceita comentários, mesmo estando no formato json.\n* É aconselhável usar este arquivo de configuração em vez das opções de linha de comando.\n\nNo link a seguir você encontra a documentação completa e seu esquema:\n\n[https://www.typescriptlang.org/tsconfig](https://www.typescriptlang.org/tsconfig)\n\n[https://www.typescriptlang.org/tsconfig/](https://www.typescriptlang.org/tsconfig/)\n\nA seguir, apresentamos uma lista das configurações comuns e úteis:\n\n#### target\n\nA propriedade \"target\" é usada para especificar qual versão do JavaScript ECMAScript seu TypeScript deve emitir/compilar. Para navegadores modernos, o ES6 é uma boa opção; para navegadores mais antigos, o ES5 é recomendado.\n\n#### lib\n\nA propriedade \"lib\" é usada para especificar quais arquivos de biblioteca incluir no tempo de compilação. O TypeScript inclui automaticamente APIs para recursos especificados na propriedade \"target\", mas é possível omitir ou escolher bibliotecas específicas para necessidades particulares. Por exemplo, se você estiver trabalhando em um projeto de servidor, pode excluir a biblioteca \"DOM\", que é útil apenas em um ambiente de navegador.\n\n#### strict\n\nA propriedade \"strict\" habilita garantias mais fortes e aumenta a segurança de tipos. É aconselhável incluir sempre esta propriedade no arquivo tsconfig.json do seu projeto. Habilitar a propriedade \"strict\" permite que o TypeScript possa:\n\n* Emitir código usando \"use strict\" para cada arquivo de origem.\n* Considerar \"null\" e \"undefined\" no processo de verificação de tipos.\n* Desabilitar o uso do tipo \"any\" quando não houver anotações de tipo.\n* Levantar um erro sobre o uso da expressão \"this\", que de outra forma implicaria o tipo \"any\".\n\n#### module\n\nA propriedade \"module\" define o sistema de módulo suportado para o programa compilado. Durante o tempo de execução, um carregador de módulo é usado para localizar e executar dependências com base no sistema de módulo especificado.\n\nOs carregadores de módulos mais comuns usados no JavaScript são o CommonJS do Node.js para aplicações do lado do servidor e o RequireJS para módulos AMD em aplicações web baseadas em navegador. O TypeScript pode emitir código para vários sistemas de módulos, incluindo UMD, System, ESNext, ES2015/ES6 e ES2020.\n\nNota: O sistema de módulos deve ser escolhido com base no ambiente de destino e no mecanismo de carregamento de módulos disponível nesse ambiente.\n\n#### moduleResolution\n\nA propriedade \"moduleResolution\" especifica a estratégia de resolução de módulos. Use \"node\" para código TypeScript moderno; a estratégia \"classic\" é usada apenas para versões antigas do TypeScript (antes da 1.6).\n\n#### esModuleInterop\n\nA propriedade \"esModuleInterop\" permite a importação padrão de módulos CommonJS que não exportaram usando a propriedade \"default\"; esta propriedade fornece um shim para garantir a compatibilidade no JavaScript emitido. Após habilitar esta opção, podemos usar `import MyLibrary from \"my-library\"` em vez de `import * as MyLibrary from \"my-library\"`.\n\n#### jsx\n\nA propriedade \"jsx\" aplica-se apenas a arquivos .tsx usados no ReactJS e controla como as construções JSX são compiladas em JavaScript. Uma opção comum é \"preserve\", que compilará para um arquivo .jsx mantendo o JSX inalterado para que ele possa ser passado para diferentes ferramentas, como o Babel, para transformações posteriores.\n\n#### skipLibCheck\n\nA propriedade \"skipLibCheck\" evitará que o TypeScript verifique os tipos de todos os pacotes de terceiros importados. Esta propriedade reduzirá o tempo de compilação de um projeto. O TypeScript ainda verificará seu código em relação às definições de tipo fornecidas por esses pacotes.\n\n#### files\n\nA propriedade \"files\" indica ao compilador uma lista de arquivos que devem sempre ser incluídos no programa.\n\n#### include\n\n<!-- markdownlint-disable MD049 -->\nA propriedade \"include\" indica ao compilador uma lista de arquivos que gostaríamos de incluir. Esta propriedade permite padrões semelhantes a glob, como \"\\**\" para qualquer subdiretório, \"*\" para qualquer nome de arquivo e \"?\" para caracteres opcionais.\n<!-- markdownlint-enable MD049 -->\n\n#### exclude\n\nA propriedade \"exclude\" indica ao compilador uma lista de arquivos que não devem ser incluídos na compilação. Isso pode incluir arquivos como \"node_modules\" ou arquivos de teste.\nNota: tsconfig.json permite comentários.\n\n### importHelpers\n\nO TypeScript usa código auxiliar ao gerar código para certos recursos avançados ou de JavaScript com \"down-leveled\". Por padrão, esses auxiliares são duplicados nos arquivos que os utilizam. A opção `importHelpers` importa esses auxiliares do módulo `tslib`, tornando a saída do JavaScript mais eficiente.\n\n### Conselhos para Migração para TypeScript\n\nPara projetos grandes, recomenda-se adotar uma transição gradual onde o código TypeScript e JavaScript coexistirão inicialmente. Apenas projetos pequenos podem ser migrados para TypeScript de uma só vez.\n\nO primeiro passo desta transição é introduzir o TypeScript no processo da cadeia de construção. Isso pode ser feito usando a opção de compilador \"allowJs\", que permite que arquivos .ts e .tsx coexistam com arquivos JavaScript existentes. Como o TypeScript voltará para um tipo \"any\" para uma variável quando não puder inferir o tipo dos arquivos JavaScript, recomenda-se desabilitar \"noImplicitAny\" em suas opções de compilador no início da migração.\n\nO segundo passo é garantir que seus testes JavaScript funcionem junto com os arquivos TypeScript, para que você possa executar testes conforme converte cada módulo. Se estiver usando Jest, considere usar o `ts-jest`, que permite testar projetos TypeScript com Jest.\n\nO terceiro passo é incluir declarações de tipo para bibliotecas de terceiros em seu projeto. Essas declarações podem ser encontradas empacotadas ou no DefinitelyTyped. Você pode pesquisar por elas usando [https://www.typescriptlang.org/dt/search](https://www.typescriptlang.org/dt/search) e instalá-las usando:\n\n```shell\nnpm install --save-dev @types/package-name\n```\n\nou\n\n```shell\nyarn add --dev @types/package-name\n```\n\nO quarto passo é migrar módulo por módulo com uma abordagem de baixo para cima, seguindo seu Gráfico de Dependências começando pelas folhas. A ideia é começar convertendo Módulos que não dependem de outros Módulos. Para visualizar os gráficos de dependência, você pode usar a ferramenta \"madge\".\n\nBons módulos candidatos para essas conversões iniciais são funções utilitárias e código relacionado a APIs ou especificações externas. É possível gerar automaticamente definições de tipo TypeScript a partir de contratos Swagger, GraphQL ou esquemas JSON para serem incluídos em seu projeto.\n\nQuando não houver especificações ou esquemas oficiais disponíveis, você pode gerar tipos a partir de dados brutos, como JSON retornado por um servidor. No entanto, recomenda-se gerar tipos a partir de especificações em vez de dados para evitar perder casos extremos.\n\nDurante a migração, evite a refatoração de código e concentre-se apenas em adicionar tipos aos seus módulos.\n\nO quinto passo é habilitar o \"noImplicitAny\", que forçará que todos os tipos sejam conhecidos e definidos, proporcionando uma melhor experiência de TypeScript para seu projeto.\n\nDurante a migração, você pode usar a diretiva `@ts-check`, que habilita a verificação de tipos do TypeScript em um arquivo JavaScript. Esta diretiva fornece uma versão flexível de verificação de tipos e pode ser usada inicialmente para identificar problemas em arquivos JavaScript. Quando o `@ts-check` é incluído em um arquivo, o TypeScript tentará deduzir definições usando comentários no estilo JSDoc. No entanto, considere usar anotações JSDoc apenas em um estágio muito inicial da migração.\n\nConsidere manter o valor padrão de `noEmitOnError` no seu tsconfig.json como false. Isso permitirá gerar o código-fonte JavaScript mesmo se erros forem relatados.\n\n"
  },
  {
    "path": "website/src/content/docs/pt-br/book/index-signatures.md",
    "content": "---\ntitle: Assinaturas de Índice (Index Signatures)\nsidebar:\n  order: 14\n  label: 14. Assinaturas de Índice (Index Signatures)\n---\n\n\nNo TypeScript, podemos usar como assinatura de índice `string`, `number` e `symbol`:\n\n```typescript\ntype K = {\n    [name: string | number]: string;\n};\nconst k: K = { x: 'x', 1: 'b' };\nconsole.log(k['x']);\nconsole.log(k[1]);\nconsole.log(k['1']); // Mesmo resultado que k[1]\n```\n\nObserve que o JavaScript converte automaticamente um índice com `number` em um índice com `string`, portanto `k[1]` ou `k[\"1\"]` retornam o mesmo valor.\n\n"
  },
  {
    "path": "website/src/content/docs/pt-br/book/infer-type-inference-in-conditional-types.md",
    "content": "---\ntitle: infer Inferência de Tipo em Tipos Condicionais\nsidebar:\n  order: 41\n  label: 41. infer Inferência de Tipo em Tipos Condicionais\n---\n\n\nA palavra-chave `infer` é usada em tipos condicionais para inferir (extrair) o tipo de um parâmetro genérico de um tipo que depende dele. Isso permite escrever definições de tipo mais flexíveis e reutilizáveis.\n\n```typescript\ntype ElementType<T> = T extends (infer U)[] ? U : never;\ntype Numbers = ElementType<number[]>; // number\ntype Strings = ElementType<string[]>; // string\n```\n\n"
  },
  {
    "path": "website/src/content/docs/pt-br/book/interface-and-type.md",
    "content": "---\ntitle: Interface e Type\nsidebar:\n  order: 48\n  label: 48. Interface e Type\n---\n\n\n### Sintaxe Comum\n\nNo TypeScript, as interfaces definem a estrutura de objetos, especificando os nomes e tipos de propriedades ou métodos que um objeto deve possuir. A sintaxe comum para definir uma interface no TypeScript é a seguinte:\n\n<!-- skip -->\n```typescript\ninterface InterfaceName {\n    property1: Type1;\n    // ...\n    method1(arg1: ArgType1, arg2: ArgType2): ReturnType;\n    // ...\n}\n```\n\nDa mesma forma para a definição de tipo (type):\n\n<!-- skip -->\n```typescript\ntype TypeName = {\n    property1: Type1;\n    // ...\n    method1(arg1: ArgType1, arg2: ArgType2): ReturnType;\n    // ...\n};\n```\n\n`interface InterfaceName` ou `type TypeName`: Define o nome da interface/tipo.\n`property1`: `Type1`: Especifica as propriedades da interface junto com seus tipos correspondentes. Múltiplas propriedades podem ser definidas, cada uma separada por um ponto e vírgula.\n`method1(arg1: ArgType1, arg2: ArgType2): ReturnType;`: Especifica os métodos da interface. Métodos são definidos com seus nomes, seguidos por uma lista de parâmetros entre parênteses e o tipo de retorno. Múltiplos métodos podem ser definidas, cada uma separada por um ponto e vírgula.\n\nExemplo de interface:\n\n```typescript\ninterface Person {\n    name: string;\n    age: number;\n    greet(): void;\n}\n```\n\nExemplo de tipo:\n\n```typescript\ntype TypeName = {\n    property1: string;\n    method1(arg1: string, arg2: string): string;\n};\n```\n\nNo TypeScript, os tipos são usados para definir a forma dos dados e impor a verificação de tipos. Existem várias sintaxes comuns para definir tipos, dependendo do caso de uso específico. Aqui estão alguns exemplos:\n\n### Tipos Básicos\n\n```typescript\nlet myNumber: number = 123; // tipo number\nlet myBoolean: boolean = true; // tipo boolean\nlet myArray: string[] = ['a', 'b']; // array de strings\nlet myTuple: [string, number] = ['a', 123]; // tupla\n```\n\n### Objetos e Interfaces\n\n```typescript\nconst x: { name: string; age: number } = { name: 'Simon', age: 7 };\n```\n\n### Tipos União e Interseção\n\n```typescript\ntype MyType = string | number; // Tipo União (Union type)\nlet myUnion: MyType = 'hello'; // Pode ser uma string\nmyUnion = 123; // Ou um número\n\ntype TypeA = { name: string };\ntype TypeB = { age: number };\ntype CombinedType = TypeA & TypeB; // Tipo Interseção (Intersection type)\nlet myCombined: CombinedType = { name: 'John', age: 25 }; // Objeto com as propriedades name e age\n```\n\n"
  },
  {
    "path": "website/src/content/docs/pt-br/book/intersection-types.md",
    "content": "---\ntitle: Tipos de Interseção\nsidebar:\n  order: 32\n  label: 32. Tipos de Interseção\n---\n\n\nUm Tipo de Interseção (Intersection Type) é um tipo que representa um valor que possui todas as propriedades de dois ou mais tipos. Tipos de Interseção são denotados usando o símbolo `&` entre cada tipo.\n\n```typescript\ntype X = {\n    a: string;\n};\n\ntype Y = {\n    b: string;\n};\n\ntype J = X & Y; // Interseção\n\nconst j: J = {\n    a: 'a',\n    b: 'b',\n};\n```\n\n"
  },
  {
    "path": "website/src/content/docs/pt-br/book/introduction.md",
    "content": "---\ntitle: Introdução\nsidebar:\n  order: 5\n  label: 5. Introdução\n---\n\n\nBem-vindo ao Livro Conciso de TypeScript! Este guia o equipa com conhecimentos essenciais e habilidades práticas para o desenvolvimento eficaz em TypeScript. Descubra conceitos e técnicas fundamentais para escrever código limpo e robusto. Seja você um iniciante ou um desenvolvedor experiente, este livro serve tanto como um guia abrangente quanto como uma referência prática para aproveitar o poder do TypeScript em seus projetos.\n\nEste livro cobre o TypeScript 5.2.\n\n"
  },
  {
    "path": "website/src/content/docs/pt-br/book/literal-inference.md",
    "content": "---\ntitle: Inferência Literal\nsidebar:\n  order: 17\n  label: 17. Inferência Literal\n---\n\n\nA Inferência Literal é um recurso do TypeScript que permite que o tipo de uma variável ou parâmetro seja inferido com base em seu valor.\n\nNo exemplo a seguir, podemos ver que o TypeScript considera `x` um tipo literal, pois o valor não pode ser alterado posteriormente, enquanto `y` é inferido como string, pois pode ser modificado posteriormente.\n\n```typescript\nconst x = 'x'; // Tipo literal de 'x', porque este valor não pode ser alterado\nlet y = 'y'; // Tipo string, pois podemos alterar este valor\n```\n\nNo exemplo a seguir, podemos ver que `o.x` foi inferido como uma `string` (e não um literal de `a`), pois o TypeScript considera que o valor pode ser alterado posteriormente.\n\n<!-- skip -->\n```typescript\ntype X = 'a' | 'b';\n\nlet o = {\n    x: 'a', // Esta é uma string mais ampla (wider string)\n};\n\nconst fn = (x: X) => `${x}-foo`;\n\nconsole.log(fn(o.x)); // Argument of type 'string' is not assignable to parameter of type 'X'\n```\n\nComo você pode observar, o código lança um erro ao passar `o.x` para `fn`, pois X é um tipo mais estreito (narrower).\n\nPodemos resolver este problema usando asserção de tipo com `const` ou o tipo `X`:\n\n<!-- skip -->\n```typescript\nlet o = {\n    x: 'a' as const,\n};\n```\n\nou:\n\n<!-- skip -->\n```typescript\nlet o = {\n    x: 'a' as X,\n};\n```\n\n"
  },
  {
    "path": "website/src/content/docs/pt-br/book/literal-types.md",
    "content": "---\ntitle: Tipos Literais\nsidebar:\n  order: 16\n  label: 16. Tipos Literais\n---\n\n\nUm Tipo Literal é um conjunto de elemento único a partir de um tipo coletivo; ele define um valor exato que é um primitivo do JavaScript.\n\nOs Tipos Literais no TypeScript são números, strings e booleanos.\n\nExemplo de literais:\n\n```typescript\nconst a = 'a'; // Tipo literal de string\nconst b = 1; // Tipo literal numérico\nconst c = true; // Tipo literal booleano\n```\n\nTipos Literais de String, Numéricos e Booleanos são usados em uniões, protetores de tipo (type guards) e apelidos de tipo (type aliases).\nNo exemplo a seguir, você pode ver um apelido de tipo de união. `O` consiste apenas nos valores especificados; nenhuma outra string é válida:\n\n```typescript\ntype O = 'a' | 'b' | 'c';\n```\n\n"
  },
  {
    "path": "website/src/content/docs/pt-br/book/mapped-type-modifiers.md",
    "content": "---\ntitle: Modificadores de Tipos Mapeados\nsidebar:\n  order: 38\n  label: 38. Modificadores de Tipos Mapeados\n---\n\n\nOs Modificadores de Tipos Mapeados no TypeScript permitem a transformação de propriedades dentro de um tipo existente:\n\n* `readonly` ou `+readonly`: Torna uma propriedade no tipo mapeado como somente leitura.\n* `-readonly`: Permite que uma propriedade no tipo mapeado seja mutável.\n* `?`: Designa uma propriedade no tipo mapeado como opcional.\n\nExemplos:\n\n```typescript\ntype ReadOnly<T> = { readonly [P in keyof T]: T[P] }; // Todas as propriedades marcadas como somente leitura\n\ntype Mutable<T> = { -readonly [P in keyof T]: T[P] }; // Todas as propriedades marcadas como mutáveis\n\ntype MyPartial<T> = { [P in keyof T]?: T[P] }; // Todas as propriedades marcadas como opcionais\n```\n\n"
  },
  {
    "path": "website/src/content/docs/pt-br/book/mapped-types.md",
    "content": "---\ntitle: Tipos Mapeados\nsidebar:\n  order: 37\n  label: 37. Tipos Mapeados\n---\n\n\nTipos Mapeados (Mapped Types) no TypeScript permitem criar novos tipos baseados em um tipo existente, transformando cada propriedade por meio de uma função de mapeamento. Ao mapear tipos existentes, você pode criar novos tipos que representam a mesma informação em um formato diferente. Para criar um tipo mapeado, você acessa as propriedades de um tipo existente usando o operador `keyof` e as altera para produzir um novo tipo.\nNo exemplo a seguir:\n\n```typescript\ntype MyMappedType<T> = {\n    [P in keyof T]: T[P][];\n};\ntype MyType = {\n    foo: string;\n    bar: number;\n};\ntype MyNewType = MyMappedType<MyType>;\nconst x: MyNewType = {\n    foo: ['hello', 'world'],\n    bar: [1, 2, 3],\n};\n```\n\ndefinimos `MyMappedType` para mapear sobre as propriedades de `T`, criando um novo tipo com cada propriedade sendo um array de seu tipo original. Usando isso, criamos `MyNewType` para representar a mesma informação que `MyType`, mas com cada propriedade como um array.\n\n"
  },
  {
    "path": "website/src/content/docs/pt-br/book/merging-and-extension.md",
    "content": "---\ntitle: Mesclagem e Extensão\nsidebar:\n  order: 52\n  label: 52. Mesclagem e Extensão\n---\n\n\nMesclagem (merging) e extensão (extension) referem-se a dois conceitos diferentes relacionados ao trabalho com tipos e interfaces.\n\nA mesclagem permite combinar várias declarações do mesmo nome em uma única definição, por exemplo, quando você define uma interface com o mesmo nome várias vezes:\n\n```typescript\ninterface X {\n    a: string;\n}\n\ninterface X {\n    b: number;\n}\n\nconst person: X = {\n    a: 'a',\n    b: 7,\n};\n```\n\nA extensão refere-se à capacidade de estender ou herdar de tipos ou interfaces existentes para criar novos. É um mecanismo para adicionar propriedades ou métodos adicionais a um tipo existente sem modificar sua definição original. Exemplo:\n\n```typescript\ninterface Animal {\n    name: string;\n    eat(): void;\n}\n\ninterface Bird extends Animal {\n    sing(): void;\n}\n\nconst dog: Bird = {\n    name: 'Bird 1',\n    eat() {\n        console.log('Comendo');\n    },\n    sing() {\n        console.log('Cantando');\n    },\n};\n```\n\n"
  },
  {
    "path": "website/src/content/docs/pt-br/book/named-tuple-type-labeled.md",
    "content": "---\ntitle: Tipo Tupla Nomeado (Rotulado)\nsidebar:\n  order: 29\n  label: 29. Tipo Tupla Nomeado (Rotulado)\n---\n\n\nOs tipos tupla podem incluir rótulos (labels) ou nomes opcionais para cada elemento. Esses rótulos são para legibilidade e assistência de ferramentas, e não afetam as operações que você pode realizar com eles.\n\n```typescript\ntype T = string;\ntype Tuple1 = [T, T];\ntype Tuple2 = [a: T, b: T];\ntype Tuple3 = [a: T, T]; // Tupla Nomeada mais Tupla Anônima\n```\n\n"
  },
  {
    "path": "website/src/content/docs/pt-br/book/namespacing.md",
    "content": "---\ntitle: Namespacing\nsidebar:\n  order: 57\n  label: 57. Namespacing\n---\n\n\nNo TypeScript, os namespaces são usados para organizar o código em contêineres lógicos, evitando colisões de nomes e fornecendo uma maneira de agrupar códigos relacionados.\nO uso das palavras-chave `export` permite o acesso ao namespace em módulos externos.\n\n```typescript\nexport namespace MyNamespace {\n    export interface MyInterface1 {\n        prop1: boolean;\n    }\n    export interface MyInterface2 {\n        prop2: string;\n    }\n}\n\nconst a: MyNamespace.MyInterface1 = {\n    prop1: true,\n};\n```\n\n"
  },
  {
    "path": "website/src/content/docs/pt-br/book/narrowing.md",
    "content": "---\ntitle: Estreitamento (Narrowing)\nsidebar:\n  order: 20\n  label: 20. Estreitamento (Narrowing)\n---\n\n\nO estreitamento (narrowing) no TypeScript é o processo de refinar o tipo de uma variável dentro de um bloco condicional. Isso é útil ao trabalhar com tipos de união, onde uma variável pode ter mais de um tipo.\n\nO TypeScript reconhece várias maneiras de estreitar o tipo:\n\n### typeof type guards\n\nO protetor de tipo (type guard) `typeof` é um protetor de tipo específico no TypeScript que verifica o tipo de uma variável com base em seu tipo JavaScript integrado.\n\n```typescript\nconst fn = (x: number | string) => {\n    if (typeof x === 'number') {\n        return x + 1; // x é number\n    }\n    return -1;\n};\n```\n\n### Estreitamento de veracidade (Truthiness narrowing)\n\nO estreitamento de veracidade (truthiness narrowing) no TypeScript funciona verificando se uma variável é verdadeira (truthy) ou falsa (falsy) para estreitar seu tipo adequadamente.\n\n```typescript\nconst toUpperCase = (name: string | null) => {\n    if (name) {\n        return name.toUpperCase();\n    } else {\n        return null;\n    }\n};\n```\n\n### Estreitamento de igualdade (Equality narrowing)\n\nO estreitamento de igualdade (equality narrowing) no TypeScript funciona verificando se uma variável é igual a um valor específico ou não, para estreitar seu tipo adequadamente.\n\nÉ usado em conjunto com instruções `switch` e operadores de igualdade como `===`, `!==`, `==` e `!=` para estreitar os tipos.\n\n```typescript\nconst checkStatus = (status: 'success' | 'error') => {\n    switch (status) {\n        case 'success':\n            return true;\n        case 'error':\n            return null;\n    }\n};\n```\n\n### Estreitamento com operador In\n\nO estreitamento com o operador `in` no TypeScript é uma forma de estreitar o tipo de uma variável com base na existência de uma propriedade dentro do tipo da variável.\n\n```typescript\ntype Dog = {\n    name: string;\n    breed: string;\n};\n\ntype Cat = {\n    name: string;\n    likesCream: boolean;\n};\n\nconst getAnimalType = (pet: Dog | Cat) => {\n    if ('breed' in pet) {\n        return 'dog';\n    } else {\n        return 'cat';\n    }\n};\n```\n\n### Estreitamento com instanceof\n\nO estreitamento com o operador `instanceof` no TypeScript é uma forma de estreitar o tipo de uma variável com base em sua função construtora, verificando se um objeto é uma instância de uma determinada classe ou interface.\n\n```typescript\nclass Square {\n    constructor(public width: number) {}\n}\nclass Rectangle {\n    constructor(\n        public width: number,\n        public height: number\n    ) {}\n}\nfunction area(shape: Square | Rectangle) {\n    if (shape instanceof Square) {\n        return shape.width * shape.width;\n    } else {\n        return shape.width * shape.height;\n    }\n}\nconst square = new Square(5);\nconst rectangle = new Rectangle(5, 10);\nconsole.log(area(square)); // 25\nconsole.log(area(rectangle)); // 50\n```\n\n"
  },
  {
    "path": "website/src/content/docs/pt-br/book/never-type.md",
    "content": "---\ntitle: Tipo never\nsidebar:\n  order: 47\n  label: 47. Tipo never\n---\n\n\nO tipo `never` representa valores que nunca ocorrem. É usado para denotar funções ou expressões que nunca retornam ou que lançam um erro.\n\nPor exemplo, um loop infinito:\n\n```typescript\nconst infiniteLoop = (): never => {\n    while (true) {\n        // faz algo\n    }\n};\n```\n\nLançando um erro:\n\n```typescript\nconst throwError = (message: string): never => {\n    throw new Error(message);\n};\n```\n\nO tipo `never` é útil para garantir a segurança de tipos e capturar possíveis erros em seu código. Ele ajuda o TypeScript a analisar e inferir tipos mais precisos quando usado em combinação com outros tipos e instruções de fluxo de controle, por exemplo:\n\n```typescript\ntype Direction = 'up' | 'down';\nconst move = (direction: Direction): void => {\n    switch (direction) {\n        case 'up':\n            // move para cima\n            break;\n        case 'down':\n            // move para baixo\n            break;\n        default:\n            const exhaustiveCheck: never = direction;\n            throw new Error(`Direção não tratada: ${exhaustiveCheck}`);\n    }\n};\n```\n\n"
  },
  {
    "path": "website/src/content/docs/pt-br/book/object-types.md",
    "content": "---\ntitle: Tipos de Objeto\nsidebar:\n  order: 27\n  label: 27. Tipos de Objeto\n---\n\n\nNo TypeScript, os tipos de objeto descrevem a forma de um objeto. Eles especificam os nomes e tipos das propriedades do objeto, bem como se essas propriedades são obrigatórias ou opcionais.\n\nNo TypeScript, você pode definir tipos de objeto de duas maneiras principais:\n\nInterface, que define a forma de um objeto especificando os nomes, tipos e a opcionalidade de suas propriedades.\n\n```typescript\ninterface User {\n    name: string;\n    age: number;\n    email?: string;\n}\n```\n\nApelido de tipo (type alias), semelhante a uma interface, define a forma de um objeto. No entanto, ele também pode criar um novo tipo personalizado baseado em um tipo existente ou em uma combinação de tipos existentes. Isso inclui definir tipos de união, tipos de interseção e outros tipos complexos.\n\n```typescript\ntype Point = {\n    x: number;\n    y: number;\n};\n```\n\nTambém é possível definir um tipo anonimamente:\n\n```typescript\nconst sum = (x: { a: number; b: number }) => x.a + x.b;\nconsole.log(sum({ a: 5, b: 1 }));\n```\n\n"
  },
  {
    "path": "website/src/content/docs/pt-br/book/optional-properties.md",
    "content": "---\ntitle: Propriedades Opcionais\nsidebar:\n  order: 12\n  label: 12. Propriedades Opcionais\n---\n\n\nUm objeto pode especificar Propriedades Opcionais adicionando um ponto de interrogação `?` ao final do nome da propriedade:\n\n```typescript\ntype X = {\n    a: number;\n    b?: number; // Opcional\n};\n```\n\nÉ possível especificar um valor padrão quando uma propriedade é opcional:\n\n```typescript\ntype X = {\n    a: number;\n    b?: number;\n};\nconst x = ({ a, b = 100 }: X) => a + b;\n```\n\n"
  },
  {
    "path": "website/src/content/docs/pt-br/book/others.md",
    "content": "---\ntitle: Outros\nsidebar:\n  order: 61\n  label: 61. Outros\n---\n\n\n### Erros e Tratamento de Exceções\n\nO TypeScript permite capturar e tratar erros usando os mecanismos padrão de tratamento de erros do JavaScript:\n\nBlocos Try-Catch-Finally:\n\n```typescript\ntry {\n    // Código que pode lançar um erro\n} catch (error) {\n    // Trata o erro\n} finally {\n    // Código que sempre executa, finally é opcional\n}\n```\n\nVocê também pode tratar diferentes tipos de erro:\n\n```typescript\ntry {\n    // Código que pode lançar diferentes tipos de erros\n} catch (error) {\n    if (error instanceof TypeError) {\n        // Trata TypeError\n    } else if (error instanceof RangeError) {\n        // Trata RangeError\n    } else {\n        // Trata outros erros\n    }\n}\n```\n\nTipos de Erro Personalizados:\n\nÉ possível especificar erros mais específicos estendendo a `class` Error:\n\n```typescript\nclass CustomError extends Error {\n    constructor(message: string) {\n        super(message);\n        this.name = 'CustomError';\n    }\n}\n\nthrow new CustomError('Este é um erro personalizado.');\n```\n\n### Classes Mixin (Mixin classes)\n\nAs classes mixin permitem combinar e compor comportamentos de múltiplas classes em uma única classe. Elas fornecem uma maneira de reutilizar e estender funcionalidades sem a necessidade de cadeias de herança profundas.\n\n```typescript\nabstract class Identifiable {\n    name: string = '';\n    logId() {\n        console.log('id:', this.name);\n    }\n}\nabstract class Selectable {\n    selected: boolean = false;\n    select() {\n        this.selected = true;\n        console.log('Select');\n    }\n    deselect() {\n        this.selected = false;\n        console.log('Deselect');\n    }\n}\nclass MyClass {\n    constructor() {}\n}\n\n// Estende MyClass para incluir o comportamento de Identifiable e Selectable\ninterface MyClass extends Identifiable, Selectable {}\n\n// Função para aplicar mixins a uma classe\nfunction applyMixins(source: any, baseCtors: any[]) {\n    baseCtors.forEach(baseCtor => {\n        Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => {\n            let descriptor = Object.getOwnPropertyDescriptor(\n                baseCtor.prototype,\n                name\n            );\n            if (descriptor) {\n                Object.defineProperty(source.prototype, name, descriptor);\n            }\n        });\n    });\n}\n\n// Aplica os mixins a MyClass\napplyMixins(MyClass, [Identifiable, Selectable]);\nlet o = new MyClass();\no.name = 'abc';\no.logId();\no.select();\n```\n\n### Recursos de Linguagem Assíncronos\n\nComo o TypeScript é um superconjunto do JavaScript, ele possui recursos de linguagem assíncronos integrados do JavaScript como:\n\nPromises:\n\nPromises são uma maneira de lidar com operações assíncronas e seus resultados usando métodos como `.then()` e `.catch()` para lidar com condições de sucesso e erro.\n\nPara saber mais: [https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/Promise](https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/Promise)\n\nAsync/await:\n\nAs palavras-chave async/await são uma maneira de fornecer uma sintaxe com aparência mais síncrona para trabalhar com Promises. A palavra-chave `async` é usada para definir uma função assíncrona, e a palavra-chave `await` é usada dentro de uma função async para pausar a execução até que uma Promise seja resolvida ou rejeitada.\n\nPara saber mais:\n[https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Statements/async_function](https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Statements/async_function)\n[https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Operators/await](https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Operators/await)\n\nAs seguintes APIs são bem suportadas no TypeScript:\n\nFetch API:\n[https://developer.mozilla.org/pt-BR/docs/Web/API/Fetch_API](https://developer.mozilla.org/pt-BR/docs/Web/API/Fetch_API)\n\nWeb Workers:\n[https://developer.mozilla.org/pt-BR/docs/Web/API/Web_Workers_API](https://developer.mozilla.org/pt-BR/docs/Web/API/Web_Workers_API)\n\nShared Workers:\n[https://developer.mozilla.org/pt-BR/docs/Web/API/SharedWorker](https://developer.mozilla.org/pt-BR/docs/Web/API/SharedWorker)\n\nWebSocket:\n[https://developer.mozilla.org/pt-BR/docs/Web/API/WebSockets_API](https://developer.mozilla.org/pt-BR/docs/Web/API/WebSockets_API)\n\n### Iteradores e Geradores\n\nTanto Iteradores quanto Geradores são bem suportados no TypeScript.\n\nIteradores são objetos que implementam o protocolo iterador, fornecendo uma maneira de acessar elementos de uma coleção ou sequência um por um. É uma estrutura que contém um ponteiro para o próximo elemento na iteração. Eles possuem um método `next()` que retorna o próximo valor na sequência junto com um booleano indicando se a sequência terminou (`done`).\n\n```typescript\nclass NumberIterator implements Iterable<number> {\n    private current: number;\n\n    constructor(\n        private start: number,\n        private end: number\n    ) {\n        this.current = start;\n    }\n\n    public next(): IteratorResult<number> {\n        if (this.current <= this.end) {\n            const value = this.current;\n            this.current++;\n            return { value, done: false };\n        } else {\n            return { value: undefined, done: true };\n        }\n    }\n\n    [Symbol.iterator](): Iterator<number> {\n        return this;\n    }\n}\n\nconst iterator = new NumberIterator(1, 3);\n\nfor (const num of iterator) {\n    console.log(num);\n}\n```\n\nGeradores são funções especiais definidas usando a sintaxe `function*` que simplifica a criação de iteradores. Eles usam a palavra-chave `yield` para definir a sequência de valores e pausar e retomar automaticamente a execução quando os valores são solicitados.\n\nGeradores facilitam a criação de iteradores e são especialmente úteis para trabalhar com sequências grandes ou infinitas.\n\nExemplo:\n\n```typescript\nfunction* numberGenerator(start: number, end: number): Generator<number> {\n    for (let i = start; i <= end; i++) {\n        yield i;\n    }\n}\n\nconst generator = numberGenerator(1, 5);\n\nfor (const num of generator) {\n    console.log(num);\n}\n```\n\nO TypeScript também suporta iteradores assíncronos e geradores assíncronos.\n\nPara saber mais:\n\n[https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/Generator](https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/Generator)\n\n[https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/Iterator](https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/Iterator)\n\n### Referência JSDoc TsDocs\n\nAo trabalhar com uma base de código JavaScript, é possível ajudar o TypeScript a inferir o tipo correto usando comentários JSDoc com anotações adicionais para fornecer informações de tipo.\n\nExemplo:\n\n```typescript\n/**\n * Computa a potência de um dado número\n * @constructor\n * @param {number} base – O valor da base da expressão\n * @param {number} exponent – O valor do expoente da expressão\n */\nfunction power(base: number, exponent: number) {\n    return Math.pow(base, exponent);\n}\npower(10, 2); // function power(base: number, exponent: number): number\n```\n\nA documentação completa é fornecida neste link:\n[https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html](https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html)\n\nA partir da versão 3.7, é possível gerar definições de tipo .d.ts a partir da sintaxe JSDoc do JavaScript.\nMais informações podem ser encontradas aqui:\n[https://www.typescriptlang.org/docs/handbook/declaration-files/dts-from-js.html](https://www.typescriptlang.org/docs/handbook/declaration-files/dts-from-js.html)\n\n### @types\n\nPacotes sob a organização @types são convenções especiais de nomenclatura de pacotes usadas para fornecer definições de tipo para bibliotecas ou módulos JavaScript existentes. Por exemplo, usando:\n\n```shell\nnpm install --save-dev @types/lodash\n```\n\nInstalará as definições de tipo de `lodash` em seu projeto atual.\n\nPara contribuir com as definições de tipo do pacote @types, envie um pull request para [https://github.com/DefinitelyTyped/DefinitelyTyped](https://github.com/DefinitelyTyped/DefinitelyTyped).\n\n### JSX\n\nJSX (JavaScript XML) é uma extensão da sintaxe da linguagem JavaScript que permite escrever código semelhante a HTML em seus arquivos JavaScript ou TypeScript. É comumente usado no React para definir a estrutura HTML.\n\nO TypeScript estende as capacidades do JSX fornecendo verificação de tipos e análise estática.\n\nPara usar JSX, você precisa definir a opção de compilador `jsx` em seu arquivo `tsconfig.json`. Duas opções de configuração comuns:\n\n* \"preserve\": emite arquivos .jsx com o JSX inalterado. Esta opção diz ao TypeScript para manter a sintaxe JSX como está e não transformá-la durante o processo de compilação. Você pode usar esta opção se tiver uma ferramenta separada, como o Babel, que lida com a transformação.\n* \"react\": habilita a transformação JSX integrada do TypeScript. `React.createElement` será usado.\n\nTodas as opções estão disponíveis aqui:\n[https://www.typescriptlang.org/tsconfig#jsx](https://www.typescriptlang.org/tsconfig#jsx)\n\n### Módulos ES6\n\nO TypeScript suporta ES6 (ECMAScript 2015) e muitas versões subsequentes. Isso significa que você pode usar a sintaxe ES6, como arrow functions, template literals, classes, módulos, desestruturação e muito mais.\n\nPara habilitar recursos do ES6 em seu projeto, você pode especificar a propriedade `target` no tsconfig.json.\n\nUm exemplo de configuração:\n\n```json\n{\n  \"compilerOptions\": {\n    \"target\": \"es6\",\n    \"module\": \"es6\",\n    \"moduleResolution\": \"node\",\n    \"sourceMap\": true,\n    \"outDir\": \"dist\"\n  },\n  \"include\": [\"src\"]\n}\n```\n\n### Operador de Exponenciação ES7\n\nO operador de exponenciação (`**`) calcula o valor obtido elevando o primeiro operando à potência do segundo operando. Ele funciona de forma semelhante a `Math.pow()`, mas com a capacidade adicional de aceitar BigInts como operandos.\nO TypeScript suporta totalmente este operador usando como `target` no seu arquivo tsconfig.json a versão `es2016` ou superior.\n\n```typescript\nconsole.log(2 ** (2 ** 2)); // 16\n```\n\n### A Instrução for-await-of\n\nEste é um recurso do JavaScript totalmente suportado no TypeScript que permite iterar sobre objetos iteráveis assíncronos a partir da versão de destino es2018.\n\n```typescript\nasync function* asyncNumbers(): AsyncIterableIterator<number> {\n    yield Promise.resolve(1);\n    yield Promise.resolve(2);\n    yield Promise.resolve(3);\n}\n\n(async () => {\n    for await (const num of asyncNumbers()) {\n        console.log(num);\n    }\n})();\n```\n\n### Nova meta-propriedade target\n\nVocê pode usar no TypeScript a meta-propriedade `new.target` que permite determinar se uma função ou construtor foi invocado usando o operador `new`. Ela permite detectar se um objeto foi criado como resultado de uma chamada de construtor.\n\n```typescript\nclass Parent {\n    constructor() {\n        console.log(new.target); // Registra a função construtora usada para criar uma instância\n    }\n}\n\nclass Child extends Parent {\n    constructor() {\n        super();\n    }\n}\n\nconst parentX = new Parent(); // [Function: Parent]\nconst child = new Child(); // [Function: Child]\n```\n\n### Expressões de Importação Dinâmica\n\nÉ possível carregar módulos condicionalmente ou carregá-los sob demanda (lazy load) usando a proposta do ECMAScript para importação dinâmica, que é suportada no TypeScript.\n\nA sintaxe para expressões de importação dinâmica no TypeScript é as seguinte:\n\n<!-- skip -->\n```typescript\nasync function renderWidget() {\n    const container = document.getElementById('widget');\n    if (container !== null) {\n        const widget = await import('./widget'); // Importação dinâmica\n        widget.render(container);\n    }\n}\n\nrenderWidget();\n```\n\n### \"tsc –watch\"\n\nEste comando inicia o compilador TypeScript com o parâmetro `--watch`, com a capacidade de recompilar automaticamente os arquivos TypeScript sempre que forem modificados.\n\n```shell\ntsc --watch\n```\n\nA partir da versão 4.9 do TypeScript, o monitoramento de arquivos depende principalmente de eventos do sistema de arquivos, recorrendo automaticamente à sondagem (polling) se um observador baseado em eventos não puder ser estabelecido.\n\n### Operador de Asserção Não-Nulo (Non-null Assertion Operator)\n\nO Operador de Asserção Não-Nulo (Postfix !) também chamado de Asserções de Atribuição Definitiva (Definite Assignment Assertions) é um recurso do TypeScript que permite asseverar que uma variável ou propriedade não é nula ou indefinida, mesmo que a análise de tipo estática do TypeScript sugira que poderia ser. Com este recurso, é possível remover qualquer verificação explícita.\n\n```typescript\ntype Person = {\n    name: string;\n};\n\nconst printName = (person?: Person) => {\n    console.log(`O nome é ${person!.name}`);\n};\n```\n\n### Declarações com Valor Padrão (Defaulted declarations)\n\nDeclarações com valor padrão são usadas quando uma variável ou parâmetro recebe um valor padrão. Isso significa que se nenhum valor for fornecido para essa variável ou parâmetro, o valor padrão será usado no lugar.\n\n```typescript\nfunction greet(name: string = 'Anônimo'): void {\n    console.log(`Olá, ${name}!`);\n}\ngreet(); // Olá, Anônimo!\ngreet('John'); // Olá, John!\n```\n\n### Encadeamento Opcional (Optional Chaining)\n\nO operador de encadeamento opcional `?.` funciona como o operador de ponto regular (`.`) para acessar propriedades ou métodos. No entanto, ele trata graciosamente valores nulos ou indefinidos terminando a expressão e retornando `undefined`, em vez de lançar um erro.\n\n```typescript\ntype Person = {\n    name: string;\n    age?: number;\n    address?: {\n        street?: string;\n        city?: string;\n    };\n};\n\nconst person: Person = {\n    name: 'John',\n};\n\nconsole.log(person.address?.city); // undefined\n```\n\n### Operador de Coalescência Nula (Nullish coalescing operator)\n\nO operador de coalescência nula `??` retorna o valor do lado direito se o lado esquerdo for `null` ou `undefined`; caso contrário, retorna o valor do lado esquerdo.\n\n```typescript\nconst foo = null ?? 'foo';\nconsole.log(foo); // foo\n\nconst baz = 1 ?? 'baz';\nconst baz2 = 0 ?? 'baz';\nconsole.log(baz); // 1\nconsole.log(baz2); // 0\n```\n\n### Tipos de Literal de Template (Template Literal Types)\n\nTipos de Literal de Template permitem manipular valores de string em nível de tipo e gerar novos tipos de string baseados em existentes. Eles são úteis para criar tipos mais expressivos e precisos a partir de operações baseadas em string.\n\n```typescript\ntype Department = 'engineering' | 'hr';\ntype Language = 'english' | 'spanish';\ntype Id = `${Department}-${Language}-id`; // \"engineering-english-id\" | \"engineering-spanish-id\" | \"hr-english-id\" | \"hr-spanish-id\"\n```\n\n### Sobrecarga de Função (Function overloading)\n\nA sobrecarga de função permite definir múltiplas assinaturas de função para o mesmo nome de função, cada uma com diferentes tipos de parâmetros e tipo de retorno.\nQuando você chama uma função sobrecarregada, o TypeScript usa os argumentos fornecidos para determinar a assinatura de função correta:\n\n```typescript\nfunction makeGreeting(name: string): string;\nfunction makeGreeting(names: string[]): string[];\n\nfunction makeGreeting(person: unknown): unknown {\n    if (typeof person === 'string') {\n        return `Hi ${person}!`;\n    } else if (Array.isArray(person)) {\n        return person.map(name => `Hi, ${name}!`);\n    }\n    throw new Error('Não foi possível saudar');\n}\n\nmakeGreeting('Simon');\nmakeGreeting(['Simone', 'John']);\n```\n\n### Tipos Recursivos\n\nUm Tipo Recursivo é um tipo que pode se referir a si mesmo. Isso é útil para definir estruturas de dados que possuem uma estrutura hierárquica ou recursiva (aninhamento potencialmente infinito), como listas ligadas, árvores e grafos.\n\n```typescript\ntype ListNode<T> = {\n    data: T;\n    next: ListNode<T> | undefined;\n};\n```\n\n### Tipos Condicionais Recursivos\n\nÉ possível definir relacionamentos de tipo complexos usando lógica e recursão no TypeScript.\nVamos detalhar em termos simples:\n\nTipos Condicionais: permite definir tipos baseados em condições booleanas:\n\n```typescript\ntype CheckNumber<T> = T extends number ? 'Número' : 'Não é um número';\ntype A = CheckNumber<123>; // 'Número'\ntype B = CheckNumber<'abc'>; // 'Não é um número'\n```\n\nRecursão: significa uma definição de tipo que se refere a si mesma dentro de sua própria definição:\n\n```typescript\ntype Json = string | number | boolean | null | Json[] | { [key: string]: Json };\n\nconst data: Json = {\n    prop1: true,\n    prop2: 'prop2',\n    prop3: {\n        prop4: [],\n    },\n};\n```\n\nTipos Condicionais Recursivos combinam lógica condicional e recursão. Isso significa que uma definição de tipo pode depender de si mesma através de lógica condicional, criando relacionamentos de tipo complexos e flexíveis.\n\n```typescript\ntype Flatten<T> = T extends Array<infer U> ? Flatten<U> : T;\n\ntype NestedArray = [1, [2, [3, 4], 5], 6];\ntype FlattenedArray = Flatten<NestedArray>; // 2 | 3 | 4 | 5 | 1 | 6\n```\n\n### Suporte a Módulos ECMAScript no Node\n\nO Node.js adicionou suporte para Módulos ECMAScript a partir da versão 15.3.0, e o TypeScript tem suporte a Módulos ECMAScript para Node.js desde a versão 4.7. Este suporte pode ser habilitado usando a propriedade `module` com o valor `nodenext` no arquivo tsconfig.json. Aqui está um exemplo:\n\n```json\n{\n  \"compilerOptions\": {\n    \"module\": \"nodenext\",\n    \"outDir\": \"./lib\",\n    \"declaration\": true\n  }\n}\n```\n\nO Node.js suporta duas extensões de arquivo para módulos: `.mjs` para módulos ES e `.cjs` para módulos CommonJS. As extensões de arquivo equivalentes no TypeScript são `.mts` para módulos ES e `.cts` para módulos CommonJS. Quando o compilador TypeScript transpila esses arquivos para JavaScript, ele criará arquivos `.mjs` e `.cjs`.\n\nSe você quiser usar módulos ES em seu projeto, você pode definir a propriedade `type` como \"module\" em seu arquivo package.json. Isso instrui o Node.js a tratar o projeto como um projeto de módulo ES.\n\nAlém disso, o TypeScript também suporta declarações de tipo em arquivos .d.ts. Esses arquivos de declaração fornecem informações de tipo para bibliotecas ou módulos escritos em TypeScript, permitindo que outros desenvolvedores os utilizem com a verificação de tipo e os recursos de preenchimento automático do TypeScript.\n\n### Funções de Asserção (Assertion Functions)\n\nNo TypeScript, funções de asserção são funções que indicam a verificação de uma condição específica com base em seu valor de retorno. Em sua forma mais simples, uma função assert examina um predicado fornecido e lança um erro quando o predicado é avaliado como falso.\n\n```typescript\nfunction isNumber(value: unknown): asserts value is number {\n    if (typeof value !== 'number') {\n        throw new Error('Não é um número');\n    }\n}\n```\n\nOu pode ser declarada como uma expressão de função:\n\n```typescript\ntype AssertIsNumber = (value: unknown) => asserts value is number;\nconst isNumber: AssertIsNumber = value => {\n    if (typeof value !== 'number') {\n        throw new Error('Não é um número');\n    }\n};\n```\n\nFunções de asserção compartilham semelhanças com guardas de tipo (type guards). As guardas de tipo foram inicialmente introduzidas para realizar verificações em tempo de execução e garantir o tipo de um valor dentro de um escopo específico.\nEspecificamente, uma guarda de tipo é uma função que avalia um predicado de tipo e retorna um valor booleano indicando se the predicado é verdadeiro ou falso. Isso difere ligeiramente das funções de asserção, onde a intenção é lançar um erro em vez de retornar falso quando o predicado não for satisfeito.\n\nExemplo de guarda de tipo:\n\n```typescript\nconst isNumber = (value: unknown): value is number => typeof value === 'number';\n```\n\n### Tipos de Tupla Variádicos (Variadic Tuple Types)\n\nTipos de Tupla Variádicos são recursos introduzidos na versão 4.0 do TypeScript. Vamos começar revisando o que é uma tupla:\n\nUm tipo tupla é um array que possui um comprimento definido, e onde o tipo de cada elemento é conhecido:\n\n```typescript\ntype Student = [string, number];\nconst [name, age]: Student = ['Simone', 20];\n```\n\nO termo \"variádico\" significa aridade indefinida (aceita um número variável de argumentos).\n\nUma tupla variádica é um tipo tupla que possui todas as propriedades anteriores, mas o formato exato ainda não está definido:\n\n```typescript\ntype Bar<T extends unknown[]> = [boolean, ...T, number];\n\ntype A = Bar<[boolean]>; // [boolean, boolean, number]\ntype B = Bar<['a', 'b']>; // [boolean, 'a', 'b', number]\ntype C = Bar<[]>; // [boolean, number]\n```\n\nNo código anterior, podemos ver que o formato da tupla é definido pelo genérico `T` passado.\n\nTuplas variádicas podem aceitar múltiplos genéricos, tornando-as muito flexíveis:\n\n```typescript\ntype Bar<T extends unknown[], G extends unknown[]> = [...T, boolean, ...G];\n\ntype A = Bar<[number], [string]>; // [number, boolean, string]\ntype B = Bar<['a', 'b'], [boolean]>; // [\"a\", \"b\", boolean, boolean]\n```\n\nCom as novas tuplas variádicas podemos usar:\n\n* Os espalhamentos (spreads) na sintaxe de tipo tupla agora podem ser genéricos, assim podemos representar operações de ordem superior em tuplas e arrays mesmo quando não conhecemos os tipos reais sobre os quais estamos operando.\n* Os elementos de resto (rest elements) podem ocorrer em qualquer lugar em uma tupla.\n\nExemplo:\n\n```typescript\ntype Items = readonly unknown[];\n\nfunction concat<T extends Items, U extends Items>(\n    arr1: T,\n    arr2: U\n): [...T, ...U] {\n    return [...arr1, ...arr2];\n}\n\nconcat([1, 2, 3], ['4', '5', '6']); // [1, 2, 3, \"4\", \"5\", \"6\"]\n```\n\n### Tipos Boxed (Boxed types)\n\nTipos boxed referem-se aos objetos de empacotamento que são usados para representar tipos primitivos como objetos. Esses objetos de empacotamento fornecem funcionalidades e métodos adicionais que não estão disponíveis diretamente nos valores primitivos.\n\nQuando você acessa um método como `charAt` ou `normalize` em um primitivo `string`, o JavaScript o empacota em um objeto `String`, chama o método e depois descarta o objeto.\n\nDemonstração:\n\n```typescript\nconst originalNormalize = String.prototype.normalize;\nString.prototype.normalize = function () {\n    console.log(this, typeof this);\n    return originalNormalize.call(this);\n};\nconsole.log('\\u0041'.normalize());\n```\n\nO TypeScript representa essa diferenciação fornecendo tipos separados para os primitivos e seus empacotadores de objeto correspondentes:\n\n* string => String\n* number => Number\n* boolean => Boolean\n* symbol => Symbol\n* bigint => BigInt\n\nOs tipos boxed geralmente não são necessários. Evite usar tipos boxed e, em vez disso, use o tipo para os primitivos, por exemplo, `string` em vez de `String`.\n\n### Covariância e Contravariância no TypeScript\n\nCovariância e Contravariância são usadas para descrever como os relacionamentos funcionam ao lidar com herança ou atribuição de tipos.\n\nCovariância significa que um relacionamento de tipo preserva a direção da herança ou atribuição, então se um tipo A é um subtipo do tipo B, então um array do tipo A também é considerado um subtipo de um array do tipo B. O importante a notar aqui é que o relacionamento de subtipo é mantido; isso significa que a Covariância aceita subtipo mas não aceita supertipo.\n\nContravariância significa que um relacionamento de tipo inverte a direção da herança ou atribuição, então se um tipo A é um subtipo do tipo B, então um array do tipo B é considerado um subtipo de um array do tipo A. O relacionamento de subtipo é invertido; isso significa que a Contravariância aceita supertipo mas não aceita subtipo.\n\nNotas: Bivariância significa aceitar tanto supertipo quanto subtipo.\n\nExemplo: Digamos que tenhamos um espaço para todos os animais e um espaço separado apenas para cachorros.\n\nNa Covariância, você pode colocar todos os cachorros no espaço dos animais porque cachorros são um tipo de animal. Mas você não pode colocar todos os animais no espaço dos cachorros porque pode haver outros animais misturados.\n\nNa Contravariância, você não pode colocar todos os animais no espaço dos cachorros porque o espaço dos animais também pode conter outros animais. No entanto, você pode colocar todos os cachorros no espaço dos animais porque todos os cachorros também são animais.\n\n<!-- skip -->\n```typescript\n// Exemplo de Covariância\nclass Animal {\n    name: string;\n    constructor(name: string) {\n        this.name = name;\n    }\n}\n\nclass Dog extends Animal {\n    breed: string;\n    constructor(name: string, breed: string) {\n        super(name);\n        this.breed = breed;\n    }\n}\n\nlet animals: Animal[] = [];\nlet dogs: Dog[] = [];\n\n// Covariância permite atribuir array de subtipo (Dog) a array de supertipo (Animal)\nanimals = dogs;\ndogs = animals; // Inválido: Tipo 'Animal[]' não é atribuível ao tipo 'Dog[]'\n\n// Exemplo de Contravariância\ntype Feed<in T> = (animal: T) => void;\n\nlet feedAnimal: Feed<Animal> = (animal: Animal) => {\n    console.log(`Nome do animal: ${animal.name}`);\n};\n\nlet feedDog: Feed<Dog> = (dog: Dog) => {\n    console.log(`Nome do cachorro: ${dog.name}, Raça: ${dog.breed}`);\n};\n\n// Contravariância permite atribuir callback de supertipo (Animal) a callback de subtipo (Dog)\nfeedDog = feedAnimal;\nfeedAnimal = feedDog; // Inválido: Tipo 'Feed<Dog>' não é atribuível ao tipo 'Feed<Animal>'.\n```\n\nNo TypeScript, relacionamentos de tipo para arrays são covariantes, enquanto relacionamentos de tipo para parâmetros de função são contravariantes. Isso significa que o TypeScript exibe tanto covariância quanto contravariância, dependendo do contexto.\n\n#### Anotações de Variância Opcionais para Parâmetros de Tipo\n\nA partir do TypeScript 4.7.0, podemos usar as palavras-chave `out` e `in` para sermos específicos sobre a anotação de variância.\n\nPara Covariante, use a palavra-chave `out`:\n\n```typescript\ntype AnimalCallback<out T> = () => T; // T é Covariante aqui\n```\n\nE para Contravariante, use a palavra-chave `in`:\n\n```typescript\ntype AnimalCallback<in T> = (value: T) => void; // T é Contravariante aqui\n```\n\n### Assinaturas de Índice de Padrão de String de Template (Template String Pattern Index Signatures)\n\nAssinaturas de índice de padrão de string de template permitem definir assinaturas de índice flexíveis usando padrões de string de template. Este recurso nos permite criar objetos que podem ser indexados com padrões específicos de chaves de string, fornecendo mais controle e especificidade ao acessar e manipular propriedades.\n\nO TypeScript a partir da versão 4.4 permite assinaturas de índice para símbolos e padrões de string de template.\n\n```typescript\nconst uniqueSymbol = Symbol('description');\n\ntype MyKeys = `key-${string}`;\n\ntype MyObject = {\n    [uniqueSymbol]: string;\n    [key: MyKeys]: number;\n};\n\nconst obj: MyObject = {\n    [uniqueSymbol]: 'Chave de símbolo único',\n    'key-a': 123,\n    'key-b': 456,\n};\n\nconsole.log(obj[uniqueSymbol]); // Chave de símbolo único\nconsole.log(obj['key-a']); // 123\nconsole.log(obj['key-b']); // 456\n```\n\n### O Operador satisfies\n\nO `satisfies` permite verificar se um determinado tipo satisfaz uma interface ou condição específica. Em outras palavras, ele garante que um tipo possui todas as propriedades e métodos exigidos de uma interface específica. É uma maneira de garantir que uma variável se encaixe na definição de um tipo.\nAqui está um exemplo:\n\n<!-- skip -->\n```typescript\ntype Columns = 'name' | 'nickName' | 'attributes';\n\ntype User = Record<Columns, string | string[] | undefined>;\n\n// Anotação de Tipo usando `User`\nconst user: User = {\n    name: 'Simone',\n    nickName: undefined,\n    attributes: ['dev', 'admin'],\n};\n\n// Nas linhas seguintes, o TypeScript não conseguirá inferir corretamente\nuser.attributes?.map(console.log); // A propriedade 'map' não existe no tipo 'string | string[]'. A propriedade 'map' não existe no tipo 'string'.\nuser.nickName; // string | string[] | undefined\n\n// Asserção de tipo usando `as`\nconst user2 = {\n    name: 'Simon',\n    nickName: undefined,\n    attributes: ['dev', 'admin'],\n} as User;\n\n// Aqui também, o TypeScript não conseguirá inferir corretamente\nuser2.attributes?.map(console.log); // A propriedade 'map' não existe no tipo 'string | string[]'. A propriedade 'map' não existe no tipo 'string'.\nuser2.nickName; // string | string[] | undefined\n\n// Usando operadores `satisfies` podemos inferir os tipos corretamente agora\nconst user3 = {\n    name: 'Simon',\n    nickName: undefined,\n    attributes: ['dev', 'admin'],\n} satisfies User;\n\nuser3.attributes?.map(console.log); // TypeScript infere corretamente: string[]\nuser3.nickName; // TypeScript infere corretamente: undefined\n```\n\n### Importações e Exportações Apenas de Tipo (Type-Only Imports and Export)\n\nImportações e Exportações Apenas de Tipo permitem importar ou exportar tipos sem importar ou exportar os valores ou funções associados a esses tipos. Isso pode ser útil para reduzir o tamanho do seu bundle.\n\nPara usar importações apenas de tipo, você pode usar a palavra-chave `import type`.\n\nO TypeScript permite usar extensões de arquivo de declaração e implementação (.ts, .mts, .cts e .tsx) em importações apenas de tipo, independentemente das configurações de `allowImportingTsExtensions`.\n\nPor exemplo:\n\n<!-- skip -->\n```typescript\nimport type { House } from './house.ts';\n```\n\nAs seguintes são formas suportadas:\n\n<!-- skip -->\n```typescript\nimport type T from './mod';\nimport type { A, B } from './mod';\nimport type * as Types from './mod';\nexport type { T };\nexport type { T } from './mod';\n```\n\n### declaração using e Gerenciamento Explícito de Recursos (Explicit Resource Management)\n\nUma declaração `using` é um vínculo imutável com escopo de bloco, semelhante ao `const`, usado para gerenciar recursos descartáveis (disposable). Quando inicializado com um valor, o método `Symbol.dispose` desse valor é registrado e subsequentemente executado ao sair do escopo de bloco envolvente.\n\nIsso é baseado no recurso de Gerenciamento de Recursos do ECMAScript, que é útil para realizar tarefas essenciais de limpeza após a criação do objeto, como fechar conexões, excluir arquivos e liberar memória.\n\nNotas:\n\n* Devido à sua introdução recente na versão 5.2 do TypeScript, a maioria dos ambientes de execução carece de suporte nativo. Você precisará de polyfills para: `Symbol.dispose`, `Symbol.asyncDispose`, `DisposableStack`, `AsyncDisposableStack`, `SuppressedError`.\n* Além disso, você precisará configurar seu tsconfig.json da seguinte forma:\n\n```json\n{\n    \"compilerOptions\": {\n        \"target\": \"es2022\",\n        \"lib\": [\"es2022\", \"esnext.disposable\", \"dom\"]\n    }\n}\n```\n\nExemplo:\n\n<!-- skip -->\n```typescript\n//@ts-ignore\nSymbol.dispose ??= Symbol('Symbol.dispose'); // Polyfill simples\n\nconst doWork = (): Disposable => {\n    return {\n        [Symbol.dispose]: () => {\n            console.log('disposto (disposed)');\n        },\n    };\n};\n\nconsole.log(1);\n\n{\n    using work = doWork(); // Recurso é declarado\n    console.log(2);\n} // Recurso é descartado (ex: `work[Symbol.dispose]()` é avaliado)\n\nconsole.log(3);\n```\n\nO código registrará:\n\n```shell\n1\n2\ndisposto (disposed)\n3\n```\n\nUm recurso elegível para descarte deve aderir à interface `Disposable`:\n\n```typescript\n// lib.esnext.disposable.d.ts\ninterface Disposable {\n    [Symbol.dispose](): void;\n}\n```\n\nAs declarações `using` registram as operações de descarte de recursos em uma pilha, garantindo que sejam descartadas na ordem inversa da declaração:\n\n<!-- skip -->\n```typescript\n{\n    using j = getA(),\n        y = getB();\n    using k = getC();\n} // descarta `C`, depois `B`, depois `A`.\n```\n\nOs recursos têm garantia de serem descartados, mesmo que ocorra código subsequente ou exceções. Isso pode levar o descarte a potencialmente lançar uma exceção, possivelmente suprimindo outra. Para manter informações sobre erros suprimidos, uma nova exceção nativa, `SuppressedError`, é introduzida.\n\n#### declaração await using\n\nUma declaração `await using` lida com um recurso descartável de forma assíncrona. O valor deve ter um método `Symbol.asyncDispose`, que será aguardado ao final do bloco.\n\n<!-- skip -->\n```typescript\nasync function doWorkAsync() {\n    await using work = doWorkAsync(); // Recurso é declarado\n} // Recurso é descartado (ex: `await work[Symbol.asyncDispose]()` é avaliado)\n```\n\nPara um recurso descartável de forma assíncrona, ele deve aderir à interface `Disposable` ou `AsyncDisposable`:\n\n```typescript\n// lib.esnext.disposable.d.ts\ninterface AsyncDisposable {\n    [Symbol.asyncDispose](): Promise<void>;\n}\n```\n\n<!-- skip -->\n```typescript\n//@ts-ignore\nSymbol.asyncDispose ??= Symbol('Symbol.asyncDispose'); // Polyfill simples\n\nclass DatabaseConnection implements AsyncDisposable {\n    // Um método que é chamado quando o objeto é descartado assincronamente\n    [Symbol.asyncDispose]() {\n        // Fecha a conexão e retorna uma promise\n        return this.close();\n    }\n\n    async close() {\n        console.log('Fechando a conexão...');\n        await new Promise(resolve => setTimeout(resolve, 1000));\n        console.log('Conexão fechada.');\n    }\n}\n\nasync function doWork() {\n    // Cria uma nova conexão e descarte-a assincronamente quando ela sair do escopo\n    await using connection = new DatabaseConnection(); // Recurso é declarado\n    console.log('Fazendo algum trabalho...');\n} // Recurso é descartado (ex: `await connection[Symbol.asyncDispose]()` é avaliado)\n\ndoWork();\n```\n\nO código registra:\n\n```shell\nFazendo algum trabalho...\nFechando a conexão...\nConexão fechada.\n```\n\nAs declarações `using` e `await using` são permitidas em Instruções: `for`, `for-in`, `for-of`, `for-await-of`, `switch`.\n\n### Atributos de Importação (Import Attributes)\n\nOs Atributos de Importação do TypeScript 5.3 (rótulos para importações) dizem ao ambiente de execução como lidar com módulos (JSON, etc.). Isso melhora a segurança garantindo importações claras e se alinha com a Política de Segurança de Conteúdo (CSP) para carregamento de recursos mais seguro. O TypeScript garante que eles sejam válidos, mas deixa o ambiente de execução lidar com sua interpretação para manipulação específica de módulos.\n\nExemplo:\n\n<!-- skip -->\n```typescript\nimport config from './config.json' with { type: 'json' };\n```\n\ncom importação dinâmica:\n\n<!-- skip -->\n```typescript\nconst config = import('./config.json', { with: { type: 'json' } });\n```\n"
  },
  {
    "path": "website/src/content/docs/pt-br/book/overloads.md",
    "content": "---\ntitle: Sobrecargas (Overloads)\nsidebar:\n  order: 51\n  label: 51. Sobrecargas (Overloads)\n---\n\n\nAs sobrecargas de função (function overloads) no TypeScript permitem definir múltiplas assinaturas para um mesmo nome de função, permitindo que as funções sejam chamadas de diversas maneiras. Aqui está um exemplo:\n\n```typescript\n// Sobrecargas\nfunction sayHi(name: string): string;\nfunction sayHi(names: string[]): string[];\n\n// Implementação\nfunction sayHi(name: unknown): unknown {\n    if (typeof name === 'string') {\n        return `Hi, ${name}!`;\n    } else if (Array.isArray(name)) {\n        return name.map(name => `Hi, ${name}!`);\n    }\n    throw new Error('Valor inválido');\n}\n\nsayHi('xx'); // Válido\nsayHi(['aa', 'bb']); // Válido\n```\n\nAqui está outro exemplo de uso de sobrecargas de função dentro de uma `class`:\n\n```typescript\nclass Greeter {\n    message: string;\n\n    constructor(message: string) {\n        this.message = message;\n    }\n\n    // sobrecarga\n    sayHi(name: string): string;\n    sayHi(names: string[]): ReadonlyArray<string>;\n\n    // implementação\n    sayHi(name: unknown): unknown {\n        if (typeof name === 'string') {\n            return `${this.message}, ${name}!`;\n        } else if (Array.isArray(name)) {\n            return name.map(name => `${this.message}, ${name}!`);\n        }\n        throw new Error('o valor é inválido');\n    }\n}\nconsole.log(new Greeter('Hello').sayHi('Simon'));\n```\n\n"
  },
  {
    "path": "website/src/content/docs/pt-br/book/predefined-conditional-types.md",
    "content": "---\ntitle: Tipos Condicionais Predefinidos\nsidebar:\n  order: 42\n  label: 42. Tipos Condicionais Predefinidos\n---\n\n\nNo TypeScript, os Tipos Condicionais Predefinidos são tipos condicionais integrados fornecidos pela linguagem. Eles são projetados para realizar transformações comuns de tipo com base nas características de um determinado tipo.\n\n`Exclude<UnionType, ExcludedType>`: Este tipo remove todos os tipos de Type que são atribuíveis a ExcludedType.\n\n`Extract<Type, Union>`: Este tipo extrai todos os tipos de Union que são atribuíveis a Type.\n\n`NonNullable<Type>`: Este tipo remove null e undefined de Type.\n\n`ReturnType<Type>`: Este tipo extrai o tipo de retorno de uma função Type.\n\n`Parameters<Type>`: Este tipo extrai os tipos de parâmetros de uma função Type.\n\n`Required<Type>`: Este tipo torna todas as propriedades em Type obrigatórias.\n\n`Partial<Type>`: Este tipo torna todas as propriedades em Type opcionais.\n\n`Readonly<Type>`: Este tipo torna todas as propriedades em Type somente leitura (readonly).\n\n"
  },
  {
    "path": "website/src/content/docs/pt-br/book/primitive-types.md",
    "content": "---\ntitle: Tipos Primitivos\nsidebar:\n  order: 10\n  label: 10. Tipos Primitivos\n---\n\n\nO TypeScript suporta 7 tipos primitivos. Um tipo de dado primitivo refere-se a um tipo que não é um objeto e não possui nenhum método associado a ele. No TypeScript, todos os tipos primitivos são imutáveis, o que significa que seus valores não podem ser alterados uma vez que são atribuídos.\n\n### string\n\nO tipo primitivo `string` armazena dados textuais, e o valor é sempre delimitado por aspas duplas ou simples.\n\n```typescript\nconst x: string = 'x';\nconst y: string = 'y';\n```\n\nAs strings podem abranger várias linhas se estiverem rodeadas pelo caractere de crase (`):\n\n```typescript\nlet sentence: string = `xxx,\n   yyy`;\n```\n\n### boolean\n\nO tipo de dado `boolean` no TypeScript armazena um valor binário, seja `true` ou `false`.\n\n```typescript\nconst isReady: boolean = true;\n```\n\n### number\n\nUm tipo de dado `number` no TypeScript é representado com um valor de ponto flutuante de 64 bits. Um tipo `number` pode representar inteiros e frações.\nO TypeScript também suporta hexadecimal, binário e octal, por exemplo:\n\n```typescript\nconst decimal: number = 10;\nconst hexadecimal: number = 0xa00d; // Hexadecimal começa com 0x\nconst binary: number = 0b1010; // Binário começa com 0b\nconst octal: number = 0o633; // Octal começa com 0o\n```\n\n### bigInt\n\nUm `bigInt` representa valores numéricos muito grandes (253 – 1) e que não podem ser representados com um `number`.\n\nUm `bigInt` pode ser criado chamando a função integrada `BigInt()` ou adicionando `n` ao final de qualquer literal numérico inteiro:\n\n```typescript\nconst x: bigint = BigInt(9007199254740991);\nconst y: bigint = 9007199254740991n;\n```\n\nNotas:\n\n* Valores `bigInt` não podem ser misturados com `number` e não podem ser usados com a função integrada `Math`; eles devem ser coagidos para o mesmo tipo.\n* Valores `bigInt` estão disponíveis apenas se a configuração da meta (target) for ES2020 ou superior.\n\n### Symbol\n\nSymbols são identificadores únicos que podem ser usados como chaves de propriedade em objetos para evitar conflitos de nomenclatura.\n\n```typescript\ntype Obj = {\n    [sym: symbol]: number;\n};\n\nconst a = Symbol('a');\nconst b = Symbol('b');\nlet obj: Obj = {};\nobj[a] = 123;\nobj[b] = 456;\n\nconsole.log(obj[a]); // 123\nconsole.log(obj[b]); // 456\n```\n\n### null e undefined\n\nOs tipos `null` e `undefined` representam a ausência de valor.\n\nO tipo `undefined` significa que o valor não foi atribuído ou inicializado, ou indica uma ausência não intencional de valor.\n\nO tipo `null` significa que sabemos que o campo não possui um valor, portanto o valor está indisponível; indica uma ausência intencional de valor.\n\n### Array\n\nUm `array` é um tipo de dado que pode armazenar múltiplos valores do mesmo tipo ou não. Ele pode ser definido usando a seguinte sintaxe:\n\n```typescript\nconst x: string[] = ['a', 'b'];\nconst y: Array<string> = ['a', 'b'];\nconst j: Array<string | number> = ['a', 1, 'b', 2]; // União\n```\n\nO TypeScript suporta arrays somente leitura (readonly) usando a seguinte sintaxe:\n\n<!-- skip -->\n```typescript\nconst x: readonly string[] = ['a', 'b']; // Modificador readonly\nconst y: ReadonlyArray<string> = ['a', 'b'];\nconst j: ReadonlyArray<string | number> = ['a', 1, 'b', 2];\nj.push('x'); // Inválido\n```\n\nO TypeScript suporta tupla e tupla somente leitura:\n\n```typescript\nconst x: [string, number] = ['a', 1];\nconst y: readonly [string, number] = ['a', 1];\n```\n\n### any\n\nO tipo de dado `any` representa literalmente \"qualquer\" valor; é o valor padrão quando o TypeScript não consegue inferir o tipo ou quando este não é especificado.\n\nAo usar `any`, o compilador TypeScript ignora a verificação de tipo, portanto não há segurança de tipo quando o `any` está sendo usado. Geralmente, não use `any` para silenciar o compilador quando ocorre um erro; em vez disso, concentre-se em corrigir o erro, pois ao usar `any` é possível quebrar contratos e perdemos os benefícios do preenchimento automático do TypeScript.\n\nO tipo `any` pode ser útil durante uma migração gradual de JavaScript para TypeScript, pois pode silenciar o compilador.\n\nPara novos projetos, use a configuração do TypeScript `noImplicitAny`, que permite que o TypeScript emita erros onde `any` é usado ou inferido.\n\nO tipo `any` é geralmente uma fonte de erros que podem mascarar problemas reais com seus tipos. Evite usá-lo o máximo possível.\n\n"
  },
  {
    "path": "website/src/content/docs/pt-br/book/readonly-properties.md",
    "content": "---\ntitle: Propriedades Somente Leitura (Readonly)\nsidebar:\n  order: 13\n  label: 13. Propriedades Somente Leitura (Readonly)\n---\n\n\nÉ possível impedir a escrita em uma propriedade usando o modificador `readonly`, que garante que a propriedade não possa ser reescrita, mas não fornece nenhuma garantia de imutabilidade total:\n\n```typescript\ninterface Y {\n    readonly a: number;\n}\n\ntype X = {\n    readonly a: number;\n};\n\ntype J = Readonly<{\n    a: number;\n}>;\n\ntype K = {\n    readonly [index: number]: string;\n};\n```\n\n"
  },
  {
    "path": "website/src/content/docs/pt-br/book/strictnullchecks.md",
    "content": "---\ntitle: strictNullChecks\nsidebar:\n  order: 18\n  label: 18. strictNullChecks\n---\n\n\n`strictNullChecks` é uma opção do compilador TypeScript que impõe a verificação estrita de nulos. Quando esta opção está habilitada, variáveis e parâmetros só podem receber `null` | `undefined` se tiverem sido explicitamente declarados como sendo desse tipo usando o tipo de união `null` | `undefined`. Se uma variável ou parâmetro não for explicitamente declarado como anulável, o TypeScript gerará um erro para evitar possíveis erros de tempo de execução.\n\n"
  },
  {
    "path": "website/src/content/docs/pt-br/book/symbols.md",
    "content": "---\ntitle: Símbolos (Symbols)\nsidebar:\n  order: 58\n  label: 58. Símbolos (Symbols)\n---\n\n\nSímbolos são um tipo de dado primitivo que representa um valor imutável que é garantido ser globalmente único durante todo o tempo de execução do programa.\n\nSímbolos podem ser usados como chaves para propriedades de objetos e fornecem uma maneira de criar propriedades não enumeráveis.\n\n```typescript\nconst key1: symbol = Symbol('key1');\nconst key2: symbol = Symbol('key2');\n\nconst obj = {\n    [key1]: 'value 1',\n    [key2]: 'value 2',\n};\n\nconsole.log(obj[key1]); // value 1\nconsole.log(obj[key2]); // value 2\n```\n\nEm WeakMaps e WeakSets, símbolos agora são permitidos como chaves.\n\n"
  },
  {
    "path": "website/src/content/docs/pt-br/book/table-of-contents.md",
    "content": "---\ntitle: Sumário\nsidebar:\n  order: 4\n  label: 4. Sumário\n---\n\n\n<!-- markdownlint-disable MD004 -->\n- O Livro Conciso de TypeScript\n  - Traduções\n  - Downloads e site\n  - Sumário\n  - Introdução\n  - Sobre o Autor\n  - Introdução ao TypeScript\n    - O que é TypeScript?\n    - Por que TypeScript?\n    - TypeScript e JavaScript\n    - Geração de Código TypeScript\n    - JavaScript Moderno Agora (Downleveling)\n  - Começando com TypeScript\n    - Instalação\n    - Configuração\n    - Arquivo de Configuração do TypeScript\n      - target\n      - lib\n      - strict\n      - module\n      - moduleResolution\n      - esModuleInterop\n      - jsx\n      - skipLibCheck\n      - files\n      - include\n      - exclude\n    - importHelpers\n    - Conselhos para Migração para TypeScript\n  - Explorando o Sistema de Tipos\n    - O Serviço de Linguagem do TypeScript\n    - Tipagem Estrutural\n    - Regras Fundamentais de Comparação do TypeScript\n    - Tipos como Conjuntos\n    - Atribuir um tipo: Declarações de Tipo e Asserções de Tipo\n      - Declaração de Tipo\n      - Asserção de Tipo\n      - Declarações de Ambiente (Ambient Declarations)\n    - Verificação de Propriedades e Verificação de Excesso de Propriedades\n    - Tipos Fracos (Weak Types)\n    - Verificação Estrita de Objeto Literal (Freshness)\n    - Inferência de Tipo\n    - Inferências Mais Avançadas\n    - Alargamento de Tipo (Type Widening)\n    - Const\n      - Modificador Const em Parâmetros de Tipo\n      - Asserção Const\n    - Anotação de Tipo Explícita\n    - Estreitamento de Tipo (Type Narrowing)\n      - Condições\n      - Lançando ou retornando\n      - União Discriminada\n      - Proteções de Tipo Definidas pelo Usuário (User-Defined Type Guards)\n  - Tipos Primitivos\n    - string\n    - boolean\n    - number\n    - bigInt\n    - Symbol\n    - null e undefined\n    - Array\n    - any\n  - Anotações de Tipo\n  - Propriedades Opcionais\n  - Propriedades Somente Leitura (Readonly)\n  - Assinaturas de Índice (Index Signatures)\n  - Estendendo Tipos\n  - Tipos Literais\n  - Inferência Literal\n  - strictNullChecks\n  - Enums\n    - Enums numéricos\n    - Enums de string\n    - Enums constantes\n    - Mapeamento reverso\n    - Enums de ambiente\n    - Membros computados e constantes\n  - Estreitamento (Narrowing)\n    - typeof type guards\n    - Estreitamento de veracidade (Truthiness narrowing)\n    - Estreitamento de igualdade (Equality narrowing)\n    - Estreitamento com operador In\n    - Estreitamento com instanceof\n  - Atribuições\n  - Análise de Fluxo de Controle\n  - Predicados de Tipo\n  - Uniões Discriminadas\n  - O tipo never\n  - Verificação de exaustividade\n  - Tipos de Objeto\n  - Tipo Tupla (Anônimo)\n  - Tipo Tupla Nomeado (Rotulado)\n  - Tupla de Comprimento Fixo\n  - Tipo União\n  - Tipos de Interseção\n  - Indexação de Tipo\n  - Tipo a partir de Valor\n  - Tipo a partir de Retorno de Função\n  - Tipo a partir de Módulo\n  - Tipos Mapeados\n  - Modificadores de Tipos Mapeados\n  - Tipos Condicionais\n  - Tipos Condicionais Distributivos\n  - Inferência de tipo infer em Tipos Condicionais\n  - Tipos Condicionais Predefinidos\n  - Tipos de União de Template\n  - Tipo Any\n  - Tipo Unknown\n  - Tipo Void\n  - Tipo Never\n  - Interface e Tipo\n    - Sintaxe Comum\n    - Tipos Básicos\n    - Objetos e Interfaces\n    - Tipos União e Interseção\n  - Primitivos de Tipo Integrados\n  - Objetos JS Integrados Comuns\n  - Sobrecargas\n  - Mesclagem e Extensão\n  - Diferenças entre Type e Interface\n    - Classe\n    - Sintaxe Comum de Classe\n    - Construtor\n    - Construtores Privados e Protegidos\n    - Modificadores de Acesso\n    - Get e Set\n    - Auto-Accessors em Classes\n    - this\n    - Propriedades de Parâmetro\n    - Classes Abstratas\n    - Com Genéricos\n    - Decoradores\n      - Decoradores de Classe\n      - Decorador de Propriedade\n      - Decorador de Método\n      - Decoradores de Getter e Setter\n      - Metadados de Decorador\n    - Herança\n    - Estáticos\n    - Inicialização de propriedade\n    - Sobrecarga de método\n  - Genéricos\n    - Tipo Genérico\n    - Classes Genéricas\n    - Restrições Genéricas\n    - Estreitamento contextual genérico\n  - Tipos Estruturais Apagados (Erased Structural Types)\n  - Namespacing\n  - Símbolos\n  - Diretivas de Barra Tripla\n  - Manipulação de Tipos\n    - Criando Tipos a partir de Tipos\n    - Tipos de Acesso Indexado\n    - Tipos Utilitários\n      - Awaited\\<T\\>\n      - Partial\\<T\\>\n      - Required\\<T\\>\n      - Readonly\\<T\\>\n      - Record\\<K, T\\>\n      - Pick\\<T, K\\>\n      - Omit\\<T, K\\>\n      - Exclude\\<T, U\\>\n      - Extract\\<T, U\\>\n      - NonNullable\\<T\\>\n      - Parameters\\<T\\>\n      - ConstructorParameters\\<T\\>\n      - ReturnType\\<T\\>\n      - InstanceType\\<T\\>\n      - ThisParameterType\\<T\\>\n      - OmitThisParameter\\<T\\>\n      - ThisType\\<T\\>\n      - Uppercase\\<T\\>\n      - Lowercase\\<T\\>\n      - Capitalize\\<T\\>\n      - Uncapitalize\\<T\\>\n      - NoInfer\\<T\\>\n  - Outros\n    - Tratamento de Erros e Exceções\n    - Classes Mixin\n    - Recursos de Linguagem Assíncronos\n    - Iteradores e Geradores\n    - Referência JSDoc TsDocs\n    - @types\n    - JSX\n    - Módulos ES6\n    - Operador de Exponenciação ES7\n    - A instrução for-await-of\n    - Nova meta-propriedade target\n    - Expressões de Importação Dinâmica\n    - \"tsc –watch\"\n    - Operador de Asserção Não-nula\n    - Declarações padronizadas\n    - Encadeamento Opcional (Optional Chaining)\n    - Operador de coalescência nula\n    - Tipos de Literais de Template\n    - Sobrecarga de função\n    - Tipos Recursivos\n    - Tipos Condicionais Recursivos\n    - Suporte a Módulo ECMAScript no Node\n    - Funções de Asserção\n    - Tipos de Tupla Variádicos\n    - Tipos Boxed\n    - Covariância e Contravariância no TypeScript\n      - Anotações de Variância Opcionais para Parâmetros de Tipo\n    - Assinaturas de Índice de Padrão de String de Template\n    - O Operador satisfies\n    - Importações e Exportações Apenas de Tipo\n    - Declaração using e Gerenciamento Explícito de Recursos\n      - Declaração await using\n    - Atributos de Importação\n<!-- markdownlint-enable MD004 -->\n\n"
  },
  {
    "path": "website/src/content/docs/pt-br/book/template-union-types.md",
    "content": "---\ntitle: Tipos de União de Template (Template Union Types)\nsidebar:\n  order: 43\n  label: 43. Tipos de União de Template (Template Union Types)\n---\n\n\nTipos de união de template podem ser usados para mesclar e manipular texto dentro do sistema de tipos, por exemplo:\n\n```typescript\ntype Status = 'active' | 'inactive';\ntype Products = 'p1' | 'p2';\ntype ProductId = `id-${Products}-${Status}`; // \"id-p1-active\" | \"id-p1-inactive\" | \"id-p2-active\" | \"id-p2-inactive\"\n```\n\n"
  },
  {
    "path": "website/src/content/docs/pt-br/book/the-concise-typescript-book.md",
    "content": "---\ntitle: O Livro Conciso de TypeScript\nsidebar:\n  order: 1\n  label: 1. O Livro Conciso de TypeScript\n---\n\n\nO Livro Conciso de TypeScript fornece uma visão geral abrangente e sucinta dos recursos do TypeScript. Ele oferece explicações claras que abrangem todos os aspectos encontrados na versão mais recente da linguagem, desde o seu poderoso sistema de tipos até recursos avançados. Seja você um iniciante ou um desenvolvedor experiente, este livro é um recurso inestimável para aprimorar sua compreensão e proficiência em TypeScript.\n\nEste livro é completamente Gratuito e de Código Aberto (Open Source).\n\nAcredito que a educação técnica de alta qualidade deve ser acessível a todos, por isso mantenho este livro gratuito e aberto.\n\nSe o livro te ajudou a resolver um bug, entender um conceito difícil ou avançar em sua carreira, considere apoiar meu trabalho pagando quanto quiser (preço sugerido: 15 USD) ou patrocinando um café. Seu apoio me ajuda a manter o conteúdo atualizado e a expandi-lo com novos exemplos e explicações mais profundas.\n\n[![Buy Me a Coffee](https://img.shields.io/badge/buy_me_a_coffee-FFDD00?style=for-the-badge&logo=buy-me-a-coffee&logoColor=black)](https://www.buymeacoffee.com/simonepoggiali)\n\n[![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.com/donate/?business=QW82ZS956XLFY&no_recurring=0&currency_code=EUR)\n\n"
  },
  {
    "path": "website/src/content/docs/pt-br/book/the-never-type.md",
    "content": "---\ntitle: O tipo never\nsidebar:\n  order: 25\n  label: 25. O tipo never\n---\n\n\nQuando uma variável é estreitada para um tipo que não pode conter nenhum valor, o compilador TypeScript inferirá que a variável deve ser do tipo `never`. Isso ocorre porque o Tipo Never representa um valor que nunca pode ser produzido.\n\n```typescript\nconst printValue = (val: string | number) => {\n    if (typeof val === 'string') {\n        console.log(val.toUpperCase());\n    } else if (typeof val === 'number') {\n        console.log(val.toFixed(2));\n    } else {\n        // val tem o tipo never aqui porque nunca pode ser nada além de uma string ou um número\n        const neverVal: never = val;\n        console.log(`Valor inesperado: ${neverVal}`);\n    }\n};\n```\n\n"
  },
  {
    "path": "website/src/content/docs/pt-br/book/translations.md",
    "content": "---\ntitle: Traduções\nsidebar:\n  order: 2\n  label: 2. Traduções\n---\n\n\nEste livro foi traduzido para várias versões de idiomas, incluindo:\n\n[Chinês](https://github.com/gibbok/typescript-book/blob/main/README-zh_CN.md)\n\n[Italiano](https://github.com/gibbok/typescript-book/blob/main/README-it_IT.md)\n\n[Português (Brasil)](https://github.com/gibbok/typescript-book/blob/main/README-pt_BR.md)\n\n[Sueco](https://github.com/gibbok/typescript-book/blob/main/README-sv_SE.md)\n\n"
  },
  {
    "path": "website/src/content/docs/pt-br/book/triple-slash-directives.md",
    "content": "---\ntitle: Diretivas Triple-Slash\nsidebar:\n  order: 59\n  label: 59. Diretivas Triple-Slash\n---\n\n\nAs diretivas triple-slash são comentários especiais que fornecem instruções ao compilador sobre como processar um arquivo. Essas diretivas começam com três barras consecutivas (`///`) e são normalmente colocadas no topo de um arquivo TypeScript e não têm efeitos no comportamento em tempo de execução.\n\nAs diretivas triple-slash são usadas para referenciar dependências externas, especificar o comportamento de carregamento de módulos, habilitar/desabilitar certos recursos do compilador e muito mais. Alguns exemplos:\n\nReferenciando um arquivo de declaração:\n\n<!-- skip -->\n```typescript\n/// <reference path=\"caminho/para/arquivo/de/declaracao.d.ts\" />\n```\n\nIndicar o formato do módulo:\n\n<!-- skip -->\n```typescript\n/// <amd|commonjs|system|umd|es6|es2015|none>\n```\n\nHabilitar opções do compilador, no exemplo a seguir, o modo estrito:\n\n<!-- skip -->\n```typescript\n/// <strict|noImplicitAny|noUnusedLocals|noUnusedParameters>\n```\n\n"
  },
  {
    "path": "website/src/content/docs/pt-br/book/tuple-type-anonymous.md",
    "content": "---\ntitle: Tipo Tupla (Anônimo)\nsidebar:\n  order: 28\n  label: 28. Tipo Tupla (Anônimo)\n---\n\n\nUm Tipo Tupla (Tuple Type) é um tipo que representa um array com um número fixo de elementos e seus tipos correspondentes. Um tipo tupla impõe um número específico de elementos e seus respectivos tipos em uma ordem fixa. Os tipos tupla são úteis quando você deseja representar uma coleção de valores com tipos específicos, onde a posição de cada elemento no array tem um significado específico.\n\n```typescript\ntype Point = [number, number];\n```\n\n"
  },
  {
    "path": "website/src/content/docs/pt-br/book/type-annotations.md",
    "content": "---\ntitle: Anotações de Tipo\nsidebar:\n  order: 11\n  label: 11. Anotações de Tipo\n---\n\n\nEm variáveis declaradas usando `var`, `let` e `const`, é possível adicionar opcionalmente um tipo:\n\n```typescript\nconst x: number = 1;\n```\n\nO TypeScript faz um bom trabalho ao inferir tipos, especialmente quando são simples, portanto essas declarações, na maioria dos casos, não são necessárias.\n\nEm funções, é possível adicionar anotações de tipo aos parâmetros:\n\n```typescript\nfunction sum(a: number, b: number) {\n    return a + b;\n}\n```\n\nO seguinte é um exemplo usando funções anônimas (as chamadas funções lambda):\n\n```typescript\nconst sum = (a: number, b: number) => a + b;\n```\n\nEssas anotações podem ser evitadas quando um valor padrão para um parâmetro está presente:\n\n```typescript\nconst sum = (a = 10, b: number) => a + b;\n```\n\nAnotações de tipo de retorno podem ser adicionadas às funções:\n\n```typescript\nconst sum = (a = 10, b: number): number => a + b;\n```\n\nIsso é útil especialmente para funções mais complexas, pois escrever explicitamente o tipo de retorno antes de uma implementação pode ajudar a pensar melhor sobre a função.\n\nGeralmente, considere anotar as assinaturas de tipo, mas não as variáveis locais do corpo, e sempre adicione tipos a objetos literais.\n\n"
  },
  {
    "path": "website/src/content/docs/pt-br/book/type-from-func-return.md",
    "content": "---\ntitle: Tipo a partir de Retorno de Função\nsidebar:\n  order: 35\n  label: 35. Tipo a partir de Retorno de Função\n---\n\n\nTipo a partir de Retorno de Função refere-se à capacidade de inferir automaticamente o tipo de retorno de uma função com base em sua implementação. Isso permite que o TypeScript determine o tipo do valor retornado pela função sem anotações de tipo explícitas.\n\n```typescript\nconst add = (x: number, y: number) => x + y; // O TypeScript pode inferir que o tipo de retorno da função é um número\n```\n\n"
  },
  {
    "path": "website/src/content/docs/pt-br/book/type-from-module.md",
    "content": "---\ntitle: Tipo a partir de Módulo\nsidebar:\n  order: 36\n  label: 36. Tipo a partir de Módulo\n---\n\n\nTipo a partir de Módulo refere-se à capacidade de usar os valores exportados de um módulo para inferir automaticamente seus tipos. Quando um módulo exporta um valor com um tipo específico, o TypeScript pode usar essa informação para inferir automaticamente o tipo desse valor quando ele é importado para outro módulo.\n\n<!-- skip -->\n```typescript\n// calc.ts\nexport const add = (x: number, y: number) => x + y;\n// index.ts\nimport { add } from 'calc';\nconst r = add(1, 2); // r é number\n```\n\n"
  },
  {
    "path": "website/src/content/docs/pt-br/book/type-from-value.md",
    "content": "---\ntitle: Tipo a partir de Valor\nsidebar:\n  order: 34\n  label: 34. Tipo a partir de Valor\n---\n\n\nTipo a partir de Valor (Type from Value) no TypeScript refere-se à inferência automática de um tipo a partir de um valor ou expressão através da inferência de tipos.\n\n```typescript\nconst x = 'x'; // O TypeScript infere 'x' como um literal de string com 'const' (imutável), mas alarga para 'string' com 'let' (atribuível novamente).\n```\n\n"
  },
  {
    "path": "website/src/content/docs/pt-br/book/type-indexing.md",
    "content": "---\ntitle: Indexação de Tipo\nsidebar:\n  order: 33\n  label: 33. Indexação de Tipo\n---\n\n\nIndexação de tipo (type indexing) refere-se à capacidade de definir tipos que podem ser indexados por uma chave não conhecida antecipadamente, usando uma assinatura de índice para especificar o tipo para propriedades que não são declaradas explicitamente.\n\n```typescript\ntype Dictionary<T> = {\n    [key: string]: T;\n};\nconst myDict: Dictionary<string> = { a: 'a', b: 'b' };\nconsole.log(myDict['a']); // Retorna a\n```\n\n"
  },
  {
    "path": "website/src/content/docs/pt-br/book/type-manipulation.md",
    "content": "---\ntitle: Manipulação de Tipos\nsidebar:\n  order: 60\n  label: 60. Manipulação de Tipos\n---\n\n\n### Criando Tipos a partir de Tipos\n\nÉ possível criar novos tipos compondo, manipulando ou transformando tipos existentes.\n\nTipos Interseção (`&`):\n\nPermitem combinar múltiplos tipos em um único tipo:\n\n```typescript\ntype A = { foo: number };\ntype B = { bar: string };\ntype C = A & B; // Interseção de A e B\nconst obj: C = { foo: 42, bar: 'hello' };\n```\n\nTipos União (`|`):\n\nPermitem definir um tipo que pode ser um de vários tipos:\n\n```typescript\ntype Result = string | number;\nconst value1: Result = 'hello';\nconst value2: Result = 42;\n```\n\nTipos Mapeados:\n\nPermitem transformar as propriedades de um tipo existente para criar um novo tipo:\n\n```typescript\ntype Mutable<T> = {\n    readonly [P in keyof T]: T[P];\n};\ntype Person = {\n    name: string;\n    age: number;\n};\ntype ImmutablePerson = Mutable<Person>; // As propriedades tornam-se somente leitura\n```\n\nTipos Condicionais:\n\nPermitem criar tipos com base em algumas condições:\n\n```typescript\ntype ExtractParam<T> = T extends (param: infer P) => any ? P : never;\ntype MyFunction = (name: string) => number;\ntype ParamType = ExtractParam<MyFunction>; // string\n```\n\n### Tipos de Acesso Indexado (Indexed Access Types)\n\nNo TypeScript, é possível acessar e manipular os tipos de propriedades dentro de outro tipo usando um índice, `Type[Key]`.\n\n```typescript\ntype Person = {\n    name: string;\n    age: number;\n};\n\ntype AgeType = Person['age']; // number\n```\n\n```typescript\ntype MyTuple = [string, number, boolean];\ntype MyType = MyTuple[2]; // boolean\n```\n\n### Tipos Utilitários (Utility Types)\n\nVários tipos utilitários integrados podem ser usados para manipular tipos, abaixo uma lista dos mais comuns:\n\n#### Awaited\\<T\\>\n\nConstrói um tipo que descompacta recursivamente tipos Promise.\n\n```typescript\ntype A = Awaited<Promise<string>>; // string\n```\n\n#### Partial\\<T\\>\n\nConstrói um tipo com todas as propriedades de T definidas como opcionais.\n\n```typescript\ntype Person = {\n    name: string;\n    age: number;\n};\n\ntype A = Partial<Person>; // { name?: string | undefined; age?: number | undefined; }\n```\n\n#### Required\\<T\\>\n\nConstrói um tipo com todas as propriedades de T definidas como obrigatórias.\n\n```typescript\ntype Person = {\n    name?: string;\n    age?: number;\n};\n\ntype A = Required<Person>; // { name: string; age: number; }\n```\n\n#### Readonly\\<T\\>\n\nConstrói um tipo com todas as propriedades de T definidas como somente leitura.\n\n<!-- skip -->\n```typescript\ntype Person = {\n    name: string;\n    age: number;\n};\n\ntype A = Readonly<Person>;\n\nconst a: A = { name: 'Simon', age: 17 };\na.name = 'John'; // Inválido\n```\n\n#### Record\\<K, T\\>\n\nConstrói um tipo com um conjunto de propriedades K do tipo T.\n\n```typescript\ntype Product = {\n    name: string;\n    price: number;\n};\n\nconst products: Record<string, Product> = {\n    apple: { name: 'Apple', price: 0.5 },\n    banana: { name: 'Banana', price: 0.25 },\n};\n\nconsole.log(products.apple); // { name: 'Apple', price: 0.5 }\n```\n\n#### Pick\\<T, K\\>\n\nConstrói um tipo selecionando as propriedades especificadas K de T.\n\n```typescript\ntype Product = {\n    name: string;\n    price: number;\n};\n\ntype Price = Pick<Product, 'price'>; // { price: number; }\n```\n\n#### Omit\\<T, K\\>\n\nConstrói um tipo omitindo as propriedades especificadas K de T.\n\n```typescript\ntype Product = {\n    name: string;\n    price: number;\n};\n\ntype Name = Omit<Product, 'price'>; // { name: string; }\n```\n\n#### Exclude\\<T, U\\>\n\nConstrói um tipo excluindo todos os valores do tipo U de T.\n\n```typescript\ntype Union = 'a' | 'b' | 'c';\ntype MyType = Exclude<Union, 'a' | 'c'>; // b\n```\n\n#### Extract\\<T, U\\>\n\nConstrói um tipo extraindo todos os valores do tipo U de T.\n\n```typescript\ntype Union = 'a' | 'b' | 'c';\ntype MyType = Extract<Union, 'a' | 'c'>; // a | c\n```\n\n#### NonNullable\\<T\\>\n\nConstrói um tipo excluindo null e undefined de T.\n\n```typescript\ntype Union = 'a' | null | undefined | 'b';\ntype MyType = NonNullable<Union>; // 'a' | 'b'\n```\n\n#### Parameters\\<T\\>\n\nExtrai os tipos de parâmetros de um tipo de função T.\n\n```typescript\ntype Func = (a: string, b: number) => void;\ntype MyType = Parameters<Func>; // [a: string, b: number]\n```\n\n#### ConstructorParameters\\<T\\>\n\nExtrai os tipos de parâmetros de um tipo de função construtora T.\n\n```typescript\nclass Person {\n    constructor(\n        public name: string,\n        public age: number\n    ) {}\n}\ntype PersonConstructorParams = ConstructorParameters<typeof Person>; // [name: string, age: number]\nconst params: PersonConstructorParams = ['John', 30];\nconst person = new Person(...params);\nconsole.log(person); // Person { name: 'John', age: 30 }\n```\n\n#### ReturnType\\<T\\>\n\nExtrai o tipo de retorno de um tipo de função T.\n\n```typescript\ntype Func = (name: string) => number;\ntype MyType = ReturnType<Func>; // number\n```\n\n#### InstanceType\\<T\\>\n\nExtrai o tipo de instância de um tipo de classe T.\n\n```typescript\nclass Person {\n    name: string;\n\n    constructor(name: string) {\n        this.name = name;\n    }\n\n    sayHello() {\n        console.log(`Olá, meu nome é ${this.name}!`);\n    }\n}\n\ntype PersonInstance = InstanceType<typeof Person>;\n\nconst person: PersonInstance = new Person('John');\n\nperson.sayHello(); // Olá, meu nome é John!\n```\n\n#### ThisParameterType\\<T\\>\n\nExtrai o tipo do parâmetro 'this' de um tipo de função T.\n\n```typescript\ninterface Person {\n    name: string;\n    greet(this: Person): void;\n}\ntype PersonThisType = ThisParameterType<Person['greet']>; // Person\n```\n\n#### OmitThisParameter\\<T\\>\n\nRemove o parâmetro 'this' de um tipo de função T.\n\n```typescript\nfunction capitalize(this: String) {\n    return this[0].toUpperCase + this.substring(1).toLowerCase();\n}\n\ntype CapitalizeType = OmitThisParameter<typeof capitalize>; // () => string\n```\n\n#### ThisType\\<T\\>\n\nServe como um marcador para um tipo `this` contextual.\n\n<!-- skip -->\n```typescript\ntype Logger = {\n    log: (error: string) => void;\n};\n\nlet helperFunctions: { [name: string]: Function } & ThisType<Logger> = {\n    hello: function () {\n        this.log('some error'); // Válido, pois \"log\" faz parte de \"this\".\n        this.update(); // Inválido\n    },\n};\n```\n\n#### Uppercase\\<T\\>\n\nConverte para maiúsculas o nome do tipo de entrada T.\n\n```typescript\ntype MyType = Uppercase<'abc'>; // \"ABC\"\n```\n\n#### Lowercase\\<T\\>\n\nConverte para minúsculas o nome do tipo de entrada T.\n\n```typescript\ntype MyType = Lowercase<'ABC'>; // \"abc\"\n```\n\n#### Capitalize\\<T\\>\n\nColoca a primeira letra em maiúscula no nome do tipo de entrada T.\n\n```typescript\ntype MyType = Capitalize<'abc'>; // \"Abc\"\n```\n\n#### Uncapitalize\\<T\\>\n\nColoca a primeira letra em minúscula no nome do tipo de entrada T.\n\n```typescript\ntype MyType = Uncapitalize<'Abc'>; // \"abc\"\n```\n\n#### NoInfer\\<T\\>\n\n`NoInfer` é um tipo utilitário projetado para bloquear a inferência automática de tipos dentro do escopo de uma função genérica.\n\nExemplo:\n\n```typescript\n// Inferência automática de tipos dentro do escopo de uma função genérica.\nfunction fn<T extends string>(x: T[], y: T) {\n    return x.concat(y);\n}\nconst r = fn(['a', 'b'], 'c'); // O tipo aqui é (\"a\" | \"b\" | \"c\")[]\n```\n\nCom NoInfer:\n\n<!-- skip -->\n```typescript\n// Exemplo de função que usa NoInfer para evitar inferência de tipo\nfunction fn2<T extends string>(x: T[], y: NoInfer<T>) {\n    return x.concat(y);\n}\n\nconst r2 = fn2(['a', 'b'], 'c'); // Erro: Argumento de tipo '\"c\"' não é atribuível ao parâmetro do tipo '\"a\" | \"b\"'.\n```\n\n"
  },
  {
    "path": "website/src/content/docs/pt-br/book/type-predicates.md",
    "content": "---\ntitle: Predicados de Tipo\nsidebar:\n  order: 23\n  label: 23. Predicados de Tipo\n---\n\n\nPredicados de Tipo (Type Predicates) no TypeScript são funções que retornam um valor booleano e são usadas para estreitar o tipo de uma variável para um tipo mais específico.\n\n```typescript\nconst isString = (value: unknown): value is string => typeof value === 'string';\n\nconst foo = (bar: unknown) => {\n    if (isString(bar)) {\n        console.log(bar.toUpperCase());\n    } else {\n        console.log('não é uma string');\n    }\n};\n```\n\n"
  },
  {
    "path": "website/src/content/docs/pt-br/book/typescript-introduction.md",
    "content": "---\ntitle: Introdução ao TypeScript\nsidebar:\n  order: 7\n  label: 7. Introdução ao TypeScript\n---\n\n\n### O que é TypeScript?\n\nTypeScript é uma linguagem de programação fortemente tipada que se baseia no JavaScript. Foi originalmente projetada por Anders Hejlsberg em 2012 e é atualmente desenvolvida e mantida pela Microsoft como um projeto de código aberto.\n\nO TypeScript compila para JavaScript e pode ser executado em qualquer ambiente de execução JavaScript (por exemplo, um navegador ou Node.js em um servidor).\n\nEle suporta múltiplos paradigmas de programação, como funcional, genérica, imperativa e orientada a objetos, e é uma linguagem compilada (transpilada) que é convertida em JavaScript antes da execução.\n\n### Por que TypeScript?\n\nTypeScript é uma linguagem fortemente tipada que ajuda a prevenir erros comuns de programação e a evitar certos tipos de erros em tempo de execução antes que o programa seja executado.\n\nUma linguagem fortemente tipada permite ao desenvolvedor especificar várias restrições e comportamentos do programa nas definições de tipos de dados, facilitando a capacidade de verificar a correção do software e prevenir defeitos. Isso é especialmente valioso em aplicações de larga escala.\n\nAlguns dos benefícios do TypeScript:\n\n* Tipagem estática, opcionalmente fortemente tipada\n* Inferência de Tipo\n* Acesso a recursos ES6 e ES7\n* Compatibilidade multiplataforma e entre navegadores\n* Suporte de ferramentas com IntelliSense\n\n### TypeScript e JavaScript\n\nArquivos TypeScript são escritos em arquivos `.ts` ou `.tsx`, enquanto arquivos JavaScript são escritos em `.js` ou `.jsx`.\n\nArquivos com a extensão `.tsx` ou `.jsx` podem conter a Extensão de Sintaxe JavaScript JSX, que é usada no React para desenvolvimento de UI.\n\nO TypeScript é um superconjunto tipado de JavaScript (ECMAScript 2015) em termos de sintaxe. Todo código JavaScript é código TypeScript válido, mas o inverso nem sempre é verdadeiro.\n\nPor exemplo, considere uma função em um arquivo JavaScript com a extensão `.js`, como a seguinte:\n\n<!-- skip -->\n```typescript\nconst sum = (a, b) => a + b;\n```\n\nA função pode ser convertida e usada no TypeScript alterando a extensão do arquivo para `.ts`. No entanto, se a mesma função for anotada com tipos TypeScript, ela não poderá ser executada em nenhum ambiente de execução JavaScript sem compilação. O seguinte código TypeScript produzirá um erro de sintaxe se não for compilado:\n\n<!-- skip -->\n```typescript\nconst sum = (a: number, b: number): number => a + b;\n```\n\nO TypeScript foi projetado para detectar possíveis exceções que podem ocorrer em tempo de execução durante o tempo de compilação, fazendo com que o desenvolvedor defina a intenção com anotações de tipo. Além disso, o TypeScript também pode capturar problemas se nenhuma anotação de tipo for fornecida. Por exemplo, o seguinte trecho de código não especifica nenhum tipo TypeScript:\n\n<!-- skip -->\n```typescript\nconst items = [{ x: 1 }, { x: 2 }];\nconst result = items.filter(item => item.y);\n```\n\nNeste caso, o TypeScript detecta um erro e informa:\n\n```text\nProperty 'y' does not exist on type '{ x: number; }'.\n```\n\nO sistema de tipos do TypeScript é amplamente influenciado pelo comportamento de tempo de execução do JavaScript. Por exemplo, o operador de adição (+), que no JavaScript pode realizar a concatenação de strings ou a adição numérica, é modelado da mesma forma no TypeScript:\n\n```typescript\nconst result = '1' + 1; // Result is of type string\n```\n\nA equipe por trás do TypeScript tomou a decisão deliberada de sinalizar o uso incomum do JavaScript como erros. Por exemplo, considere o seguinte código JavaScript válido:\n\n<!-- skip -->\n```typescript\nconst result = 1 + true; // In JavaScript, the result is equal 2\n```\n\nNo entanto, o TypeScript lança um erro:\n\n```text\nOperator '+' cannot be applied to types 'number' and 'boolean'.\n```\n\nEste erro ocorre porque o TypeScript impõe estritamente a compatibilidade de tipos e, neste caso, identifica uma operação inválida entre um número e um booleano.\n\n### Geração de Código TypeScript\n\nO compilador TypeScript tem duas responsabilidades principais: verificar se há erros de tipo e compilar para JavaScript. Esses dois processos são independentes um do outro. Os tipos não afetam a execução do código em um ambiente de execução JavaScript, pois são completamente apagados durante a compilação. O TypeScript ainda pode gerar JavaScript mesmo na presença de erros de tipo.\nAqui está um exemplo de código TypeScript com um erro de tipo:\n\n<!-- skip -->\n```typescript\nconst add = (a: number, b: number): number => a + b;\nconst result = add('x', 'y'); // Argument of type 'string' is not assignable to parameter of type 'number'.\n```\n\nNo entanto, ele ainda pode produzir uma saída JavaScript executável:\n\n<!-- skip -->\n```typescript\n'use strict';\nconst add = (a, b) => a + b;\nconst result = add('x', 'y'); // xy\n```\n\nNão é possível verificar tipos TypeScript em tempo de execução. Por exemplo:\n\n<!-- skip -->\n```typescript\ninterface Animal {\n    name: string;\n}\ninterface Dog extends Animal {\n    bark: () => void;\n}\ninterface Cat extends Animal {\n    meow: () => void;\n}\nconst makeNoise = (animal: Animal) => {\n    if (animal instanceof Dog) {\n        // 'Dog' only refers to a type, but is being used as a value here.\n        // ...\n    }\n};\n```\n\nComo os tipos são apagados após a compilação, não há como executar este código em JavaScript. Para reconhecer tipos em tempo de execução, precisamos usar outro mecanismo. O TypeScript fornece várias opções, sendo uma comum a \"união tagueada\" (tagged union). Por exemplo:\n\n```typescript\ninterface Dog {\n    kind: 'dog'; // Tagged union\n    bark: () => void;\n}\ninterface Cat {\n    kind: 'cat'; // Tagged union\n    meow: () => void;\n}\ntype Animal = Dog | Cat;\n\nconst makeNoise = (animal: Animal) => {\n    if (animal.kind === 'dog') {\n        animal.bark();\n    } else {\n        animal.meow();\n    }\n};\n\nconst dog: Dog = {\n    kind: 'dog',\n    bark: () => console.log('bark'),\n};\nmakeNoise(dog);\n```\n\nA propriedade \"kind\" é um valor que pode ser usado em tempo de execução para distinguir entre objetos em JavaScript.\n\nTambém é possível que um valor em tempo de execução tenha um tipo diferente daquele declarado na declaração de tipo. Por exemplo, se o desenvolvedor interpretou mal um tipo de API e o anotou incorretamente.\n\nO TypeScript é um superconjunto do JavaScript, portanto a palavra-chave \"class\" pode ser usada como um tipo e valor em tempo de execução.\n\n```typescript\nclass Animal {\n    constructor(public name: string) {}\n}\nclass Dog extends Animal {\n    constructor(\n        public name: string,\n        public bark: () => void\n    ) {\n        super(name);\n    }\n}\nclass Cat extends Animal {\n    constructor(\n        public name: string,\n        public meow: () => void\n    ) {\n        super(name);\n    }\n}\ntype Mammal = Dog | Cat;\n\nconst makeNoise = (mammal: Mammal) => {\n    if (mammal instanceof Dog) {\n        mammal.bark();\n    } else {\n        mammal.meow();\n    }\n};\n\nconst dog = new Dog('Fido', () => console.log('bark'));\nmakeNoise(dog);\n```\n\nNo JavaScript, uma \"classe\" tem uma propriedade \"prototype\", e o operador \"instanceof\" pode ser usado para testar se a propriedade prototype de um construtor aparece em qualquer lugar na cadeia de protótipos de um objeto.\n\nO TypeScript não tem efeito no desempenho em tempo de execução, pois todos os tipos serão apagados. No entanto, o TypeScript introduz alguma sobrecarga no tempo de compilação.\n\n### JavaScript Moderno Agora (Downleveling)\n\nO TypeScript pode compilar código para qualquer versão lançada do JavaScript desde o ECMAScript 3 (1999). Isso significa que o TypeScript pode transpilar o código dos recursos JavaScript mais recentes para versões mais antigas, um processo conhecido como *Downleveling*. Isso permite o uso do JavaScript moderno, mantendo a compatibilidade máxima com ambientes de execução mais antigos.\n\nÉ importante notar que durante a transpilação para uma versão mais antiga do JavaScript, o TypeScript pode gerar código que pode incorrer em uma sobrecarga de desempenho em comparação com as implementações nativas.\n\nAqui estão alguns dos recursos modernos do JavaScript que podem ser usados no TypeScript:\n\n* Módulos ECMAScript em vez de callbacks \"define\" no estilo AMD ou instruções \"require\" do CommonJS.\n* Classes em vez de protótipos.\n* Declaração de variáveis usando \"let\" ou \"const\" em vez de \"var\".\n* Loop \"for-of\" ou \".forEach\" em vez do loop \"for\" tradicional.\n* Funções de seta (Arrow functions) em vez de expressões de função.\n* Atribuição via desestruturação (Destructuring assignment).\n* Nomes de propriedade/método abreviados e nomes de propriedade computados.\n* Parâmetros de função padrão.\n\nAo aproveitar esses recursos modernos do JavaScript, os desenvolvedores podem escrever códigos mais expressivos e concisos no TypeScript.\n\n"
  },
  {
    "path": "website/src/content/docs/pt-br/book/union-type.md",
    "content": "---\ntitle: Tipo União\nsidebar:\n  order: 31\n  label: 31. Tipo União\n---\n\n\nUm Tipo União (Union Type) é um tipo que representa um valor que pode ser um de vários tipos. Tipos União são denotados usando o símbolo `|` entre cada tipo possível.\n\n```typescript\nlet x: string | number;\nx = 'hello'; // Válido\nx = 123; // Válido\n```\n\n"
  },
  {
    "path": "website/src/content/docs/pt-br/book/unknown-type.md",
    "content": "---\ntitle: Tipo unknown\nsidebar:\n  order: 45\n  label: 45. Tipo unknown\n---\n\n\nNo TypeScript, o tipo `unknown` representa um valor que é de um tipo desconhecido. Ao contrário do tipo `any`, que permite qualquer tipo de valor, o `unknown` exige uma verificação de tipo ou asserção antes de poder ser usado de uma maneira específica, portanto nenhuma operação é permitida em um `unknown` sem primeiro asseverar ou estreitar para um tipo mais específico.\n\nO tipo `unknown` só é atribuível a si mesmo e ao tipo `any`; é uma alternativa segura em termos de tipos ao `any`.\n\n<!-- skip -->\n```typescript\nlet value: unknown;\n\nlet value1: unknown = value; // Válido\nlet value2: any = value; // Válido\nlet value3: boolean = value; // Inválido\nlet value4: number = value; // Inválido\n```\n\n```typescript\nconst add = (a: unknown, b: unknown): number | undefined =>\n    typeof a === 'number' && typeof b === 'number' ? a + b : undefined;\nconsole.log(add(1, 2)); // 3\nconsole.log(add('x', 2)); // undefined\n```\n\n"
  },
  {
    "path": "website/src/content/docs/pt-br/book/void-type.md",
    "content": "---\ntitle: Tipo void\nsidebar:\n  order: 46\n  label: 46. Tipo void\n---\n\n\nO tipo `void` é usado para indicar que uma função não retorna um valor.\n\n```typescript\nconst sayHello = (): void => {\n    console.log('Hello!');\n};\n```\n\n"
  },
  {
    "path": "website/src/content/docs/pt-br/index.mdx",
    "content": "---\ntitle: TypeScript Book\ndescription: The Concise TypeScript Book\ntemplate: splash\nhero:\n    tagline: O Concise TypeScript Book fornece uma visão geral abrangente e sucinta das capacidades do TypeScript. Ele oferece explicações claras cobrindo todos os aspectos encontrados na versão mais recente da linguagem, desde seu poderoso sistema de tipos até recursos avançados. Seja você um iniciante ou um desenvolvedor experiente, este livro é um recurso inestimável para aprimorar sua compreensão e proficiência em TypeScript.<br/><br/>Este livro é completamente Gratuito e de Código Aberto.\n    actions:\n        - text: Leia agora!\n          link: /typescript-book/pt-br/book/the-concise-typescript-book/\n          icon: right-arrow\n          variant: primary\n        - text: GitHub\n          link: https://github.com/gibbok/typescript-book\n          icon: github\n          variant: secondary\n        - text: X.com\n          link: https://twitter.com/gibbok_coding\n          icon: x.com\n          variant: secondary\n---\n"
  },
  {
    "path": "website/src/content/docs/sv-se/book/about-the-author.md",
    "content": "---\ntitle: Om författaren\nsidebar:\n  order: 6\n  label: 6. Om författaren\n---\n\n\nSimone Poggiali är en erfaren Staff Engineer med en passion för att skriva professionell kod sedan 90-talet. Under sin internationella karriär har han bidragit till många projekt för ett brett spektrum av kunder, från startups till stora organisationer. Framstående företag som HelloFresh, Siemens, O2, Leroy Merlin och Snowplow har dragit nytta av hans expertis och engagemang.\n\nDu kan nå Simone Poggiali på följande plattformar:\n\n* LinkedIn: [https://www.linkedin.com/in/simone-poggiali](https://www.linkedin.com/in/simone-poggiali)\n* GitHub: [https://github.com/gibbok](https://github.com/gibbok)\n* X.com: [https://x.com/gibbok_coding](https://x.com/gibbok_coding)\n* E-post: gibbok.coding📧gmail.com\n\nFullständig lista över bidragsgivare: [https://github.com/gibbok/typescript-book/graphs/contributors](https://github.com/gibbok/typescript-book/graphs/contributors)\n\n"
  },
  {
    "path": "website/src/content/docs/sv-se/book/any-type.md",
    "content": "---\ntitle: Any-typen\nsidebar:\n  order: 44\n  label: 44. Any-typen\n---\n\n\n`any`-typen är en speciell typ (universell supertyp) som kan användas för att representera vilken typ av värde som helst (primitiver, objekt, arrayer, funktioner, fel, symboler). Den används ofta i situationer där typen av ett värde inte är känd vid kompilering, eller vid arbete med värden från externa API:er eller bibliotek som inte har TypeScript-typningar.\n\nGenom att använda `any`-typen indikerar du för TypeScript-kompilatorn att värden ska representeras utan några begränsningar. För att maximera typsäkerheten i din kod, överväg följande:\n\n* Begränsa användningen av `any` till specifika fall där typen verkligen är okänd.\n* Returnera inte `any`-typer från en funktion, eftersom detta försvagar typsäkerheten i kod som använder den.\n* Istället för `any`, använd `@ts-ignore` om du behöver tysta kompilatorn.\n\n```typescript\nlet value: any;\nvalue = true; // Valid\nvalue = 7; // Valid\n```\n\n"
  },
  {
    "path": "website/src/content/docs/sv-se/book/assignments.md",
    "content": "---\ntitle: Tilldelningar\nsidebar:\n  order: 21\n  label: 21. Tilldelningar\n---\n\n\nTypeScript-avsmalning med hjälp av tilldelningar är ett sätt att avsmalma typen av en variabel baserat på det tilldelade värdet. När en variabel tilldelas ett värde härleder TypeScript dess typ baserat på det tilldelade värdet, och avsmalmar variabelns typ för att matcha den härledda typen.\n\n```typescript\nlet value: string | number;\nvalue = 'hello';\nif (typeof value === 'string') {\n    console.log(value.toUpperCase());\n}\nvalue = 42;\nif (typeof value === 'number') {\n    console.log(value.toFixed(2));\n}\n```\n\n"
  },
  {
    "path": "website/src/content/docs/sv-se/book/built-in-type-primitives.md",
    "content": "---\ntitle: Inbyggda primitiva typer\nsidebar:\n  order: 49\n  label: 49. Inbyggda primitiva typer\n---\n\n\nTypeScript har flera inbyggda primitiva typer som kan användas för att definiera variabler, funktionsparametrar och returtyper:\n\n* `number`: Representerar numeriska värden, inklusive heltal och flyttal.\n* `string`: Representerar textdata.\n* `boolean`: Representerar logiska värden, som kan vara antingen true eller false.\n* `null`: Representerar frånvaron av ett värde.\n* `undefined`: Representerar ett värde som inte har tilldelats eller inte har definierats.\n* `symbol`: Representerar en unik identifierare. Symboler används vanligtvis som nycklar för objektegenskaper.\n* `bigint`: Representerar heltal med godtycklig precision.\n* `any`: Representerar en dynamisk eller okänd typ. Variabler av typen any kan innehålla värden av vilken typ som helst, och de kringgår typkontroll.\n* `void`: Representerar frånvaron av någon typ. Den används vanligtvis som returtyp för funktioner som inte returnerar ett värde.\n* `never`: Representerar en typ för värden som aldrig förekommer. Den används vanligtvis som returtyp för funktioner som kastar ett fel eller går in i en oändlig loop.\n\n"
  },
  {
    "path": "website/src/content/docs/sv-se/book/class.md",
    "content": "---\ntitle: Klass\nsidebar:\n  order: 54\n  label: 54. Klass\n---\n\n\n### Vanlig klasssyntax\n\nNyckelordet `class` används i TypeScript för att definiera en klass. Nedan kan du se ett exempel:\n\n```typescript\nclass Person {\n    private name: string;\n    private age: number;\n    constructor(name: string, age: number) {\n        this.name = name;\n        this.age = age;\n    }\n    public sayHi(): void {\n        console.log(\n            `Hello, my name is ${this.name} and I am ${this.age} years old.`\n        );\n    }\n}\n```\n\nNyckelordet `class` används för att definiera en klass som heter \"Person\".\n\nKlassen har två privata egenskaper: name av typen `string` och age av typen `number`.\n\nKonstruktorn definieras med nyckelordet `constructor`. Den tar name och age som parametrar och tilldelar dem till motsvarande egenskaper.\n\nKlassen har en `public` metod som heter sayHi som loggar ett hälsningsmeddelande.\n\nFör att skapa en instans av en klass i TypeScript kan du använda nyckelordet `new` följt av klassnamnet, följt av parenteser `()`. Till exempel:\n\n<!-- skip -->\n```typescript\nconst myObject = new Person('John Doe', 25);\nmyObject.sayHi(); // Output: Hello, my name is John Doe and I am 25 years old.\n```\n\n### Konstruktor\n\nKonstruktorer är speciella metoder inom en klass som används för att initiera objektets egenskaper när en instans av klassen skapas.\n\n```typescript\nclass Person {\n    public name: string;\n    public age: number;\n\n    constructor(name: string, age: number) {\n        this.name = name;\n        this.age = age;\n    }\n\n    sayHello() {\n        console.log(\n            `Hello, my name is ${this.name} and I'm ${this.age} years old.`\n        );\n    }\n}\n\nconst john = new Person('Simon', 17);\njohn.sayHello();\n```\n\nDet är möjligt att överlagra en konstruktor med följande syntax:\n\n```typescript\ntype Sex = 'm' | 'f';\n\nclass Person {\n    name: string;\n    age: number;\n    sex: Sex;\n\n    constructor(name: string, age: number, sex?: Sex);\n    constructor(name: string, age: number, sex: Sex) {\n        this.name = name;\n        this.age = age;\n        this.sex = sex ?? 'm';\n    }\n}\n\nconst p1 = new Person('Simon', 17);\nconst p2 = new Person('Alice', 22, 'f');\n```\n\nI TypeScript är det möjligt att definiera flera konstruktoröverlagringar, men du kan bara ha en implementering som måste vara kompatibel med alla överlagringar. Detta kan uppnås genom att använda en valfri parameter.\n\n```typescript\nclass Person {\n    name: string;\n    age: number;\n\n    constructor();\n    constructor(name: string);\n    constructor(name: string, age: number);\n    constructor(name?: string, age?: number) {\n        this.name = name ?? 'Unknown';\n        this.age = age ?? 0;\n    }\n\n    displayInfo() {\n        console.log(`Name: ${this.name}, Age: ${this.age}`);\n    }\n}\n\nconst person1 = new Person();\nperson1.displayInfo(); // Name: Unknown, Age: 0\n\nconst person2 = new Person('John');\nperson2.displayInfo(); // Name: John, Age: 0\n\nconst person3 = new Person('Jane', 25);\nperson3.displayInfo(); // Name: Jane, Age: 25\n```\n\n### Privata och skyddade konstruktorer\n\nI TypeScript kan konstruktorer markeras som privata eller skyddade, vilket begränsar deras åtkomlighet och användning.\n\nPrivata konstruktorer:\nKan bara anropas inom själva klassen. Privata konstruktorer används ofta i scenarier där du vill upprätthålla ett singleton-mönster eller begränsa skapandet av instanser till en fabriksmetod inom klassen.\n\nSkyddade konstruktorer:\nSkyddade konstruktorer är användbara när du vill skapa en basklass som inte ska instansieras direkt men kan utökas av underklasser.\n\n```typescript\nclass BaseClass {\n    protected constructor() {}\n}\n\nclass DerivedClass extends BaseClass {\n    private value: number;\n\n    constructor(value: number) {\n        super();\n        this.value = value;\n    }\n}\n\n// Attempting to instantiate the base class directly will result in an error\n// const baseObj = new BaseClass(); // Error: Constructor of class 'BaseClass' is protected.\n\n// Create an instance of the derived class\nconst derivedObj = new DerivedClass(10);\n```\n\n### Åtkomstmodifierare\n\nÅtkomstmodifierarna `private`, `protected` och `public` används för att styra synligheten och åtkomsten till klassmedlemmar, såsom egenskaper och metoder, i TypeScript-klasser. Dessa modifierare är viktiga för att upprätthålla inkapsling och för att etablera gränser för åtkomst och modifiering av en klass interna tillstånd.\n\nModifieraren `private` begränsar åtkomsten till klassmedlemmen enbart inom den innehållande klassen.\n\nModifieraren `protected` tillåter åtkomst till klassmedlemmen inom den innehållande klassen och dess härledda klasser.\n\nModifieraren `public` ger obegränsad åtkomst till klassmedlemmen och tillåter att den nås från var som helst.\n\n### Get och Set\n\nGetters och setters är speciella metoder som låter dig definiera anpassat åtkomst- och ändringsbeteende för klassegenskaper. De gör det möjligt att kapsla in det interna tillståndet hos ett objekt och tillhandahålla ytterligare logik vid hämtning eller inställning av egenskapsvärden.\nI TypeScript definieras getters och setters med nyckelorden `get` respektive `set`. Här är ett exempel:\n\n```typescript\nclass MyClass {\n    private _myProperty: string;\n\n    constructor(value: string) {\n        this._myProperty = value;\n    }\n    get myProperty(): string {\n        return this._myProperty;\n    }\n    set myProperty(value: string) {\n        this._myProperty = value;\n    }\n}\n```\n\n### Auto-accessorer i klasser\n\nTypeScript version 4.9 lägger till stöd för auto-accessorer, en kommande ECMAScript-funktion. De liknar klassegenskaper men deklareras med nyckelordet \"accessor\".\n\n```typescript\nclass Animal {\n    accessor name: string;\n\n    constructor(name: string) {\n        this.name = name;\n    }\n}\n```\n\nAuto-accessorer \"avsockras\" till privata `get`- och `set`-accessorer som opererar på en otillgänglig egenskap.\n\n<!-- skip -->\n```typescript\nclass Animal {\n    #__name: string;\n\n    get name() {\n        return this.#__name;\n    }\n    set name(value: string) {\n        this.#__name = name;\n    }\n\n    constructor(name: string) {\n        this.name = name;\n    }\n}\n```\n\n### this\n\nI TypeScript refererar nyckelordet `this` till den aktuella instansen av en klass inom dess metoder eller konstruktorer. Det ger dig möjlighet att komma åt och modifiera klassens egenskaper och metoder inifrån dess eget scope.\nDet erbjuder ett sätt att komma åt och manipulera det interna tillståndet hos ett objekt inom dess egna metoder.\n\n```typescript\nclass Person {\n    private name: string;\n    constructor(name: string) {\n        this.name = name;\n    }\n    public introduce(): void {\n        console.log(`Hello, my name is ${this.name}.`);\n    }\n}\n\nconst person1 = new Person('Alice');\nperson1.introduce(); // Hello, my name is Alice.\n```\n\n### Parameteregenskaper\n\nParameteregenskaper gör det möjligt att deklarera och initiera klassegenskaper direkt i konstruktorns parametrar, vilket undviker överflödig kod. Exempel:\n\n```typescript\nclass Person {\n    constructor(\n        private name: string,\n        public age: number\n    ) {\n        // The \"private\" and \"public\" keywords in the constructor\n        // automatically declare and initialize the corresponding class properties.\n    }\n    public introduce(): void {\n        console.log(\n            `Hello, my name is ${this.name} and I am ${this.age} years old.`\n        );\n    }\n}\nconst person = new Person('Alice', 25);\nperson.introduce();\n```\n\n### Abstrakta klasser\n\nAbstrakta klasser används i TypeScript främst för arv; de erbjuder ett sätt att definiera gemensamma egenskaper och metoder som kan ärvas av underklasser.\nDetta är användbart när du vill definiera gemensamt beteende och säkerställa att underklasser implementerar vissa metoder. De ger ett sätt att skapa en hierarki av klasser där den abstrakta basklassen tillhandahåller ett delat gränssnitt och gemensam funktionalitet för underklasserna.\n\n```typescript\nabstract class Animal {\n    protected name: string;\n\n    constructor(name: string) {\n        this.name = name;\n    }\n\n    abstract makeSound(): void;\n}\n\nclass Cat extends Animal {\n    makeSound(): void {\n        console.log(`${this.name} meows.`);\n    }\n}\n\nconst cat = new Cat('Whiskers');\ncat.makeSound(); // Output: Whiskers meows.\n```\n\n### Med generics\n\nKlasser med generics gör det möjligt att definiera återanvändbara klasser som kan arbeta med olika typer.\n\n```typescript\nclass Container<T> {\n    private item: T;\n\n    constructor(item: T) {\n        this.item = item;\n    }\n\n    getItem(): T {\n        return this.item;\n    }\n\n    setItem(item: T): void {\n        this.item = item;\n    }\n}\n\nconst container1 = new Container<number>(42);\nconsole.log(container1.getItem()); //  42\n\nconst container2 = new Container<string>('Hello');\ncontainer2.setItem('World');\nconsole.log(container2.getItem()); // World\n```\n\n### Dekoratörer\n\nDekoratörer tillhandahåller en mekanism för att lägga till metadata, ändra beteende, validera eller utöka funktionaliteten hos målelementet. De är funktioner som körs vid körning. Flera dekoratörer kan tillämpas på en deklaration.\n\nDekoratörer är experimentella funktioner, och följande exempel är bara kompatibla med TypeScript version 5 eller senare med ES6.\n\nFör TypeScript-versioner före 5 bör de aktiveras med egenskapen `experimentalDecorators` i din `tsconfig.json` eller genom att använda `--experimentalDecorators` på kommandoraden (men följande exempel kommer inte att fungera).\n\nNågra vanliga användningsfall för dekoratörer inkluderar:\n\n* Övervakning av egenskapsändringar.\n* Övervakning av metodanrop.\n* Tillägg av extra egenskaper eller metoder.\n* Validering vid körning.\n* Automatisk serialisering och deserialisering.\n* Loggning.\n* Auktorisering och autentisering.\n* Felhantering.\n\nObservera: Dekoratörer för version 5 tillåter inte dekorering av parametrar.\n\nTyper av dekoratörer:\n\n#### Klassdekoratörer\n\nKlassdekoratörer är användbara för att utöka en befintlig klass, till exempel genom att lägga till egenskaper eller metoder, eller samla instanser av en klass. I följande exempel lägger vi till en `toString`-metod som konverterar klassen till en strängrepresentation.\n\n```typescript\ntype Constructor<T = {}> = new (...args: any[]) => T;\n\nfunction toString<Class extends Constructor>(\n    Value: Class,\n    context: ClassDecoratorContext<Class>\n) {\n    return class extends Value {\n        constructor(...args: any[]) {\n            super(...args);\n            console.log(JSON.stringify(this));\n            console.log(JSON.stringify(context));\n        }\n    };\n}\n\n@toString\nclass Person {\n    name: string;\n\n    constructor(name: string) {\n        this.name = name;\n    }\n\n    greet() {\n        return 'Hello, ' + this.name;\n    }\n}\nconst person = new Person('Simon');\n/* Logs:\n{\"name\":\"Simon\"}\n{\"kind\":\"class\",\"name\":\"Person\"}\n*/\n```\n\n#### Egenskapsdekoratör\n\nEgenskapsdekoratörer är användbara för att ändra beteendet hos en egenskap, till exempel genom att ändra initieringsvärden. I följande kod har vi ett skript som ställer in en egenskap till att alltid vara i versaler:\n\n```typescript\nfunction upperCase<T>(\n    target: undefined,\n    context: ClassFieldDecoratorContext<T, string>\n) {\n    return function (this: T, value: string) {\n        return value.toUpperCase();\n    };\n}\n\nclass MyClass {\n    @upperCase\n    prop1 = 'hello!';\n}\n\nconsole.log(new MyClass().prop1); // Logs: HELLO!\n```\n\n#### Metoddekoratör\n\nMetoddekoratörer låter dig ändra eller förbättra beteendet hos metoder. Nedan följer ett exempel på en enkel logger:\n\n```typescript\nfunction log<This, Args extends any[], Return>(\n    target: (this: This, ...args: Args) => Return,\n    context: ClassMethodDecoratorContext<\n        This,\n        (this: This, ...args: Args) => Return\n    >\n) {\n    const methodName = String(context.name);\n\n    function replacementMethod(this: This, ...args: Args): Return {\n        console.log(`LOG: Entering method '${methodName}'.`);\n        const result = target.call(this, ...args);\n        console.log(`LOG: Exiting method '${methodName}'.`);\n        return result;\n    }\n\n    return replacementMethod;\n}\n\nclass MyClass {\n    @log\n    sayHello() {\n        console.log('Hello!');\n    }\n}\n\nnew MyClass().sayHello();\n```\n\nDet loggar:\n\n```shell\nLOG: Entering method 'sayHello'.\nHello!\nLOG: Exiting method 'sayHello'.\n```\n\n#### Getter- och setter-dekoratörer\n\nGetter- och setter-dekoratörer låter dig ändra eller förbättra beteendet hos klass-accessorer. De är användbara, till exempel, för validering av egenskapstilldelningar. Här är ett enkelt exempel på en getter-dekoratör:\n\n```typescript\nfunction range<This, Return extends number>(min: number, max: number) {\n    return function (\n        target: (this: This) => Return,\n        context: ClassGetterDecoratorContext<This, Return>\n    ) {\n        return function (this: This): Return {\n            const value = target.call(this);\n            if (value < min || value > max) {\n                throw 'Invalid';\n            }\n            Object.defineProperty(this, context.name, {\n                value,\n                enumerable: true,\n            });\n            return value;\n        };\n    };\n}\n\nclass MyClass {\n    private _value = 0;\n\n    constructor(value: number) {\n        this._value = value;\n    }\n    @range(1, 100)\n    get getValue(): number {\n        return this._value;\n    }\n}\n\nconst obj = new MyClass(10);\nconsole.log(obj.getValue); // Valid: 10\n\nconst obj2 = new MyClass(999);\nconsole.log(obj2.getValue); // Throw: Invalid!\n```\n\n#### Dekoratörmetadata\n\nDekoratörmetadata förenklar processen för dekoratörer att tillämpa och använda metadata i valfri klass. De kan komma åt en ny metadataegenskap på kontextobjektet, som kan fungera som en nyckel för både primitiva värden och objekt.\nMetadatainformation kan nås på klassen via `Symbol.metadata`.\n\nMetadata kan användas för olika ändamål, till exempel felsökning, serialisering eller beroendeinjektion med dekoratörer.\n\n```typescript\n//@ts-ignore\nSymbol.metadata ??= Symbol('Symbol.metadata'); // Simple polify\n\ntype Context =\n    | ClassFieldDecoratorContext\n    | ClassAccessorDecoratorContext\n    | ClassMethodDecoratorContext; // Context contains property metadata: DecoratorMetadata\n\nfunction setMetadata(_target: any, context: Context) {\n    // Set the metadata object with a primitive value\n    context.metadata[context.name] = true;\n}\n\nclass MyClass {\n    @setMetadata\n    a = 123;\n\n    @setMetadata\n    accessor b = 'b';\n\n    @setMetadata\n    fn() {}\n}\n\nconst metadata = MyClass[Symbol.metadata]; // Get metadata information\n\nconsole.log(JSON.stringify(metadata)); // {\"bar\":true,\"baz\":true,\"foo\":true}\n```\n\n### Arv\n\nArv avser mekanismen genom vilken en klass kan ärva egenskaper och metoder från en annan klass, känd som basklassen eller superklassen. Den härledda klassen, även kallad barnklassen eller underklassen, kan utöka och specialisera basklassens funktionalitet genom att lägga till nya egenskaper och metoder eller åsidosätta befintliga.\n\n```typescript\nclass Animal {\n    name: string;\n\n    constructor(name: string) {\n        this.name = name;\n    }\n\n    speak(): void {\n        console.log('The animal makes a sound');\n    }\n}\n\nclass Dog extends Animal {\n    breed: string;\n\n    constructor(name: string, breed: string) {\n        super(name);\n        this.breed = breed;\n    }\n\n    speak(): void {\n        console.log('Woof! Woof!');\n    }\n}\n\n// Create an instance of the base class\nconst animal = new Animal('Generic Animal');\nanimal.speak(); // The animal makes a sound\n\n// Create an instance of the derived class\nconst dog = new Dog('Max', 'Labrador');\ndog.speak(); // Woof! Woof!\"\n```\n\nTypeScript stöder inte multipelt arv i traditionell bemärkelse utan tillåter istället arv från en enda basklass.\nTypeScript stöder flera gränssnitt. Ett gränssnitt kan definiera ett kontrakt för strukturen hos ett objekt, och en klass kan implementera flera gränssnitt. Detta gör det möjligt för en klass att ärva beteende och struktur från flera källor.\n\n```typescript\ninterface Flyable {\n    fly(): void;\n}\n\ninterface Swimmable {\n    swim(): void;\n}\n\nclass FlyingFish implements Flyable, Swimmable {\n    fly() {\n        console.log('Flying...');\n    }\n\n    swim() {\n        console.log('Swimming...');\n    }\n}\n\nconst flyingFish = new FlyingFish();\nflyingFish.fly();\nflyingFish.swim();\n```\n\nNyckelordet `class` i TypeScript, liknande JavaScript, kallas ofta för syntaktiskt socker. Det introducerades i ECMAScript 2015 (ES6) för att erbjuda en mer välbekant syntax för att skapa och arbeta med objekt på ett klassbaserat sätt. Det är dock viktigt att notera att TypeScript, som en utökning av JavaScript, slutligen kompileras ner till JavaScript, som i grunden förblir prototypbaserat.\n\n### Statiska medlemmar\n\nTypeScript har statiska medlemmar. För att komma åt de statiska medlemmarna i en klass kan du använda klassnamnet följt av en punkt, utan att behöva skapa ett objekt.\n\n```typescript\nclass OfficeWorker {\n    static memberCount: number = 0;\n\n    constructor(private name: string) {\n        OfficeWorker.memberCount++;\n    }\n}\n\nconst w1 = new OfficeWorker('James');\nconst w2 = new OfficeWorker('Simon');\nconst total = OfficeWorker.memberCount;\nconsole.log(total); // 2\n```\n\n### Egenskapsinitiering\n\nDet finns flera sätt att initiera egenskaper för en klass i TypeScript:\n\nInline:\n\nI följande exempel kommer dessa initiala värden att användas när en instans av klassen skapas.\n\n```typescript\nclass MyClass {\n    property1: string = 'default value';\n    property2: number = 42;\n}\n```\n\nI konstruktorn:\n\n```typescript\nclass MyClass {\n    property1: string;\n    property2: number;\n\n    constructor() {\n        this.property1 = 'default value';\n        this.property2 = 42;\n    }\n}\n```\n\nAnvända konstruktorparametrar:\n\n```typescript\nclass MyClass {\n    constructor(\n        private property1: string = 'default value',\n        public property2: number = 42\n    ) {\n        // There is no need to assign the values to the properties explicitly.\n    }\n    log() {\n        console.log(this.property2);\n    }\n}\nconst x = new MyClass();\nx.log();\n```\n\n### Metodöverlagring\n\nMetodöverlagring gör det möjligt för en klass att ha flera metoder med samma namn men olika parametertyper eller ett annat antal parametrar. Detta gör att vi kan anropa en metod på olika sätt baserat på de argument som skickas.\n\n```typescript\nclass MyClass {\n    add(a: number, b: number): number; // Overload signature 1\n    add(a: string, b: string): string; // Overload signature 2\n\n    add(a: number | string, b: number | string): number | string {\n        if (typeof a === 'number' && typeof b === 'number') {\n            return a + b;\n        }\n        if (typeof a === 'string' && typeof b === 'string') {\n            return a.concat(b);\n        }\n        throw new Error('Invalid arguments');\n    }\n}\n\nconst r = new MyClass();\nconsole.log(r.add(10, 5)); // Logs 15\n```\n\n"
  },
  {
    "path": "website/src/content/docs/sv-se/book/common-built-in-js-objects.md",
    "content": "---\ntitle: Vanliga inbyggda JS-objekt\nsidebar:\n  order: 50\n  label: 50. Vanliga inbyggda JS-objekt\n---\n\n\nTypeScript är en utökning av JavaScript och inkluderar alla vanligt använda inbyggda JavaScript-objekt. Du kan hitta en utförlig lista över dessa objekt på Mozilla Developer Networks (MDN) dokumentationswebbplats:\n[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects)\n\nHär är en lista över några vanligt använda inbyggda JavaScript-objekt:\n\n* Function\n* Object\n* Boolean\n* Error\n* Number\n* BigInt\n* Math\n* Date\n* String\n* RegExp\n* Array\n* Map\n* Set\n* Promise\n* Intl\n\n"
  },
  {
    "path": "website/src/content/docs/sv-se/book/conditional-types.md",
    "content": "---\ntitle: Villkorliga typer\nsidebar:\n  order: 39\n  label: 39. Villkorliga typer\n---\n\n\nVillkorliga typer är ett sätt att skapa en typ som beror på ett villkor, där typen som ska skapas bestäms baserat på resultatet av villkoret. De definieras med nyckelordet `extends` och en ternär operator för att villkorligt välja mellan två typer.\n\n```typescript\ntype IsArray<T> = T extends any[] ? true : false;\n\nconst myArray = [1, 2, 3];\nconst myNumber = 42;\n\ntype IsMyArrayAnArray = IsArray<typeof myArray>; // Type true\ntype IsMyNumberAnArray = IsArray<typeof myNumber>; // Type false\n```\n\n"
  },
  {
    "path": "website/src/content/docs/sv-se/book/control-flow-analysis.md",
    "content": "---\ntitle: Kontrollflödesanalys\nsidebar:\n  order: 22\n  label: 22. Kontrollflödesanalys\n---\n\n\nKontrollflödesanalys i TypeScript är ett sätt att statiskt analysera kodflödet för att härleda typer av variabler, vilket gör det möjligt för kompilatorn att avsmalma typerna av dessa variabler efter behov, baserat på resultaten av analysen.\n\nFöre TypeScript 4.4 tillämpades kodflödesanalys enbart på kod inom en if-sats, men från och med TypeScript 4.4 kan den även tillämpas på villkorliga uttryck och diskriminantegenskapsåtkomster som indirekt refereras genom const-variabler.\n\nTill exempel:\n\n```typescript\nconst f1 = (x: unknown) => {\n    const isString = typeof x === 'string';\n    if (isString) {\n        x.length;\n    }\n};\n\nconst f2 = (\n    obj: { kind: 'foo'; foo: string } | { kind: 'bar'; bar: number }\n) => {\n    const isFoo = obj.kind === 'foo';\n    if (isFoo) {\n        obj.foo;\n    } else {\n        obj.bar;\n    }\n};\n```\n\nNågra exempel där avsmalning inte sker:\n\n<!-- skip -->\n```typescript\nconst f1 = (x: unknown) => {\n    let isString = typeof x === 'string';\n    if (isString) {\n        x.length; // Error, no narrowing because isString it is not const\n    }\n};\n\nconst f6 = (\n    obj: { kind: 'foo'; foo: string } | { kind: 'bar'; bar: number }\n) => {\n    const isFoo = obj.kind === 'foo';\n    obj = obj;\n    if (isFoo) {\n        obj.foo; // Error, no narrowing because obj is assigned in function body\n    }\n};\n```\n\nObservera: Upp till fem nivåer av indirektion analyseras i villkorliga uttryck.\n\n"
  },
  {
    "path": "website/src/content/docs/sv-se/book/differences-between-type-and-interface.md",
    "content": "---\ntitle: Skillnader mellan Type och Interface\nsidebar:\n  order: 53\n  label: 53. Skillnader mellan Type och Interface\n---\n\n\nDeklarationssammanslagning (augmentering):\n\nInterface stöder deklarationssammanslagning, vilket innebär att du kan definiera flera interface med samma namn, och TypeScript kommer att slå samman dem till ett enda interface med de kombinerade egenskaperna och metoderna. Å andra sidan stöder typer inte deklarationssammanslagning. Detta kan vara användbart när du vill lägga till extra funktionalitet eller anpassa befintliga typer utan att ändra de ursprungliga definitionerna eller korrigera saknade eller felaktiga typer.\n\n```typescript\ninterface A {\n    x: string;\n}\ninterface A {\n    y: string;\n}\nconst j: A = {\n    x: 'xx',\n    y: 'yy',\n};\n```\n\nUtökning av andra typer/interface:\n\nBåde typer och interface kan utöka andra typer/interface, men syntaxen är annorlunda. Med interface använder du nyckelordet `extends` för att ärva egenskaper och metoder från andra interface. Ett interface kan dock inte utöka en komplex typ som en union-typ.\n\n```typescript\ninterface A {\n    x: string;\n    y: number;\n}\ninterface B extends A {\n    z: string;\n}\nconst car: B = {\n    x: 'x',\n    y: 123,\n    z: 'z',\n};\n```\n\nFör typer använder du operatorn & för att kombinera flera typer till en enda typ (intersection).\n\n```typescript\ninterface A {\n    x: string;\n    y: number;\n}\n\ntype B = A & {\n    j: string;\n};\n\nconst c: B = {\n    x: 'x',\n    y: 123,\n    j: 'j',\n};\n```\n\nUnion- och Intersection-typer:\n\nTyper är mer flexibla när det gäller att definiera union- och intersection-typer. Med nyckelordet `type` kan du enkelt skapa union-typer med operatorn `|` och intersection-typer med operatorn `&`. Även om interface också kan representera union-typer indirekt, har de inget inbyggt stöd för intersection-typer.\n\n```typescript\ntype Department = 'dep-x' | 'dep-y'; // Union\n\ntype Person = {\n    name: string;\n    age: number;\n};\n\ntype Employee = {\n    id: number;\n    department: Department;\n};\n\ntype EmployeeInfo = Person & Employee; // Intersection\n```\n\nExempel med interface:\n\n```typescript\ninterface A {\n    x: 'x';\n}\ninterface B {\n    y: 'y';\n}\n\ntype C = A | B; // Union of interfaces\n```\n\n"
  },
  {
    "path": "website/src/content/docs/sv-se/book/discriminated-unions.md",
    "content": "---\ntitle: Diskriminerade unioner\nsidebar:\n  order: 24\n  label: 24. Diskriminerade unioner\n---\n\n\nDiskriminerade unioner i TypeScript är en typ av unionstyp som använder en gemensam egenskap, känd som diskriminanten, för att avsmalma uppsättningen av möjliga typer för unionen.\n\n```typescript\ntype Square = {\n    kind: 'square'; // Discriminant\n    size: number;\n};\n\ntype Circle = {\n    kind: 'circle'; // Discriminant\n    radius: number;\n};\n\ntype Shape = Square | Circle;\n\nconst area = (shape: Shape) => {\n    switch (shape.kind) {\n        case 'square':\n            return Math.pow(shape.size, 2);\n        case 'circle':\n            return Math.PI * Math.pow(shape.radius, 2);\n    }\n};\n\nconst square: Square = { kind: 'square', size: 5 };\nconst circle: Circle = { kind: 'circle', radius: 2 };\n\nconsole.log(area(square)); // 25\nconsole.log(area(circle)); // 12.566370614359172\n```\n\n"
  },
  {
    "path": "website/src/content/docs/sv-se/book/distributive-conditional-types.md",
    "content": "---\ntitle: Distributiva villkorliga typer\nsidebar:\n  order: 40\n  label: 40. Distributiva villkorliga typer\n---\n\n\nDistributiva villkorliga typer är en funktion som gör det möjligt att distribuera en typ över en union av typer, genom att tillämpa en transformation på varje medlem av unionen individuellt.\nDetta kan vara särskilt användbart vid arbete med mappade typer eller typer av högre ordning.\n\n```typescript\ntype Nullable<T> = T extends any ? T | null : never;\ntype NumberOrBool = number | boolean;\ntype NullableNumberOrBool = Nullable<NumberOrBool>; // number | boolean | null\n```\n\n"
  },
  {
    "path": "website/src/content/docs/sv-se/book/downloads-and-website.md",
    "content": "---\ntitle: Nedladdningar och webbplats\nsidebar:\n  order: 3\n  label: 3. Nedladdningar och webbplats\n---\n\n\nDu kan också ladda ner Epub-versionen:\n\n[https://github.com/gibbok/typescript-book/tree/main/downloads](https://github.com/gibbok/typescript-book/tree/main/downloads)\n\nEn onlineversion finns tillgänglig på:\n\n[https://gibbok.github.io/typescript-book](https://gibbok.github.io/typescript-book)\n\n"
  },
  {
    "path": "website/src/content/docs/sv-se/book/enums.md",
    "content": "---\ntitle: Enums\nsidebar:\n  order: 19\n  label: 19. Enums\n---\n\n\nI TypeScript är en `enum` en uppsättning namngivna konstantvärden.\n\n```typescript\nenum Color {\n    Red = '#ff0000',\n    Green = '#00ff00',\n    Blue = '#0000ff',\n}\n```\n\nEnums kan definieras på olika sätt:\n\n### Numeriska enums\n\nI TypeScript är en numerisk Enum en Enum där varje konstant tilldelas ett numeriskt värde, med start från 0 som standard.\n\n```typescript\nenum Size {\n    Small, // value starts from 0\n    Medium,\n    Large,\n}\n```\n\nDet är möjligt att ange anpassade värden genom att explicit tilldela dem:\n\n```typescript\nenum Size {\n    Small = 10,\n    Medium,\n    Large,\n}\nconsole.log(Size.Medium); // 11\n```\n\n### Sträng-enums\n\nI TypeScript är en sträng-Enum en Enum där varje konstant tilldelas ett strängvärde.\n\n```typescript\nenum Language {\n    English = 'EN',\n    Spanish = 'ES',\n}\n```\n\nNotera: TypeScript tillåter användning av heterogena Enums där sträng- och numeriska medlemmar kan samexistera.\n\n### Konstanta enums\n\nEn konstant enum i TypeScript är en speciell typ av Enum där alla värden är kända vid kompileringstid och infogas överallt där enum:en används, vilket resulterar i mer effektiv kod.\n\n```typescript\nconst enum Language {\n    English = 'EN',\n    Spanish = 'ES',\n}\nconsole.log(Language.English);\n```\n\nKommer att kompileras till:\n\n```typescript\nconsole.log('EN' /* Language.English */);\n```\n\nNoteringar:\nKonstanta Enums har hårdkodade värden som raderar Enum:en, vilket kan vara mer effektivt i fristående bibliotek men är i allmänhet inte önskvärt. Dessutom kan konstanta enums inte ha beräknade medlemmar.\n\n### Omvänd mappning\n\nI TypeScript avser omvänd mappning i Enums möjligheten att hämta Enum-medlemmens namn från dess värde. Som standard har Enum-medlemmar framåtmappningar från namn till värde, men omvända mappningar kan skapas genom att explicit ange värden för varje medlem. Omvända mappningar är användbara när du behöver slå upp en Enum-medlem efter dess värde, eller när du behöver iterera över alla Enum-medlemmar. Observera att bara numeriska Enum-medlemmar genererar omvända mappningar, medan sträng-Enum-medlemmar inte genererar någon omvänd mappning alls.\n\nFöljande enum:\n\n```typescript\nenum Grade {\n    A = 90,\n    B = 80,\n    C = 70,\n    F = 'fail',\n}\n```\n\nKompileras till:\n\n<!-- skip -->\n```javascript\n'use strict';\nvar Grade;\n(function (Grade) {\n    Grade[(Grade['A'] = 90)] = 'A';\n    Grade[(Grade['B'] = 80)] = 'B';\n    Grade[(Grade['C'] = 70)] = 'C';\n    Grade['F'] = 'fail';\n})(Grade || (Grade = {}));\n```\n\nDärför fungerar mappning av värden till nycklar för numeriska enum-medlemmar, men inte för sträng-enum-medlemmar:\n\n<!-- skip -->\n```typescript\nenum Grade {\n    A = 90,\n    B = 80,\n    C = 70,\n    F = 'fail',\n}\nconst myGrade = Grade.A;\nconsole.log(Grade[myGrade]); // A\nconsole.log(Grade[90]); // A\n\nconst failGrade = Grade.F;\nconsole.log(failGrade); // fail\nconsole.log(Grade[failGrade]); // Element implicitly has an 'any' type because index expression is not of type 'number'.\n```\n\n### Omgivande enums\n\nEn omgivande enum i TypeScript är en typ av Enum som definieras i en deklarationsfil (*.d.ts) utan en associerad implementation. Den låter dig definiera en uppsättning namngivna konstanter som kan användas på ett typsäkert sätt över olika filer utan att behöva importera implementationsdetaljerna i varje fil.\n\n### Beräknade och konstanta medlemmar\n\nI TypeScript är en beräknad medlem en medlem av en Enum som har ett värde som beräknas vid körning, medan en konstant medlem är en medlem vars värde sätts vid kompileringstid och inte kan ändras under körning. Beräknade medlemmar är tillåtna i vanliga Enums, medan konstanta medlemmar är tillåtna i både vanliga och const enums.\n\n```typescript\n// Constant members\nenum Color {\n    Red = 1,\n    Green = 5,\n    Blue = Red + Green,\n}\nconsole.log(Color.Blue); // 6 generation at compilation time\n```\n\n```typescript\n// Computed members\nenum Color {\n    Red = 1,\n    Green = Math.pow(2, 2),\n    Blue = Math.floor(Math.random() * 3) + 1,\n}\nconsole.log(Color.Blue); // random number generated at run time\n```\n\nEnums betecknas av unioner som består av deras medlemstyper. Värdena för varje medlem kan bestämmas genom konstanta eller icke-konstanta uttryck, där medlemmar med konstanta värden tilldelas literaltyper. För att illustrera, betrakta deklarationen av typ E och dess undertyper E.A, E.B och E.C. I detta fall representerar E unionen E.A | E.B | E.C.\n\n```typescript\nconst identity = (value: number) => value;\n\nenum E {\n    A = 2 * 5, // Numeric literal\n    B = 'bar', // String literal\n    C = identity(42), // Opaque computed\n}\n\nconsole.log(E.C); //42\n```\n\n"
  },
  {
    "path": "website/src/content/docs/sv-se/book/erased-structural-types.md",
    "content": "---\ntitle: Raderade strukturella typer\nsidebar:\n  order: 56\n  label: 56. Raderade strukturella typer\n---\n\n\nI TypeScript behöver objekt inte matcha en specifik, exakt typ. Till exempel, om vi skapar ett objekt som uppfyller ett gränssnitts krav, kan vi använda det objektet på platser där det gränssnittet krävs, även om det inte finns någon explicit koppling mellan dem.\nExempel:\n\n```typescript\ntype NameProp1 = {\n    prop1: string;\n};\n\nfunction log(x: NameProp1) {\n    console.log(x.prop1);\n}\n\nconst obj = {\n    prop2: 123,\n    prop1: 'Origin',\n};\n\nlog(obj); // Valid\n```\n\n"
  },
  {
    "path": "website/src/content/docs/sv-se/book/exhaustiveness-checking.md",
    "content": "---\ntitle: Uttömmande kontroll\nsidebar:\n  order: 26\n  label: 26. Uttömmande kontroll\n---\n\n\nUttömmande kontroll är en funktion i TypeScript som säkerställer att alla möjliga fall av en diskriminerad union hanteras i en `switch`-sats eller en `if`-sats.\n\n```typescript\ntype Direction = 'up' | 'down';\n\nconst move = (direction: Direction) => {\n    switch (direction) {\n        case 'up':\n            console.log('Moving up');\n            break;\n        case 'down':\n            console.log('Moving down');\n            break;\n        default:\n            const exhaustiveCheck: never = direction;\n            console.log(exhaustiveCheck); // This line will never be executed\n    }\n};\n```\n\n`never`-typen används för att säkerställa att default-fallet är uttömmande och att TypeScript kommer att ge ett fel om ett nytt värde läggs till i Direction-typen utan att det hanteras i switch-satsen.\n\n"
  },
  {
    "path": "website/src/content/docs/sv-se/book/exploring-the-type-system.md",
    "content": "---\ntitle: Utforska typsystemet\nsidebar:\n  order: 9\n  label: 9. Utforska typsystemet\n---\n\n\n### TypeScript-språktjänsten\n\nTypeScript-språktjänsten, även känd som tsserver, erbjuder olika funktioner såsom felrapportering, diagnostik, kompilera-vid-sparning, namnbyte, gå till definition, kompletteringslistor, signaturhjälp och mer. Den används främst av integrerade utvecklingsmiljöer (IDE:er) för att ge IntelliSense-stöd. Den integreras sömlöst med Visual Studio Code och används av verktyg som Conquer of Completion (Coc).\n\nUtvecklare kan utnyttja ett dedikerat API och skapa sina egna anpassade språktjänstplugin för att förbättra TypeScript-redigeringsupplevelsen. Detta kan vara särskilt användbart för att implementera speciella linting-funktioner eller möjliggöra automatisk komplettering för ett anpassat mallspråk.\n\n<!-- markdownlint-disable MD044 -->\nEtt exempel på ett verkligt anpassat plugin är \"typescript-styled-plugin\", som tillhandahåller syntaxfelrapportering och IntelliSense-stöd för CSS-egenskaper i styled components.\n<!-- markdownlint-enable MD044 -->\n\nFör mer information och snabbstartsguider kan du hänvisa till den officiella TypeScript-wikin på GitHub: [https://github.com/microsoft/TypeScript/wiki/](https://github.com/microsoft/TypeScript/wiki/)\n\n### Strukturell typning\n\nTypeScript är baserat på ett strukturellt typsystem. Detta innebär att kompatibiliteten och ekvivalensen hos typer bestäms av typens faktiska struktur eller definition, snarare än dess namn eller plats för deklaration, som i nominativa typsystem som C# eller C.\n\nTypeScripts strukturella typsystem designades baserat på hur JavaScripts dynamiska duck typing-system fungerar vid körning.\n\nFöljande exempel är giltig TypeScript-kod. Som du kan observera har \"X\" och \"Y\" samma medlem \"a\", även om de har olika deklarationsnamn. Typerna bestäms av deras strukturer, och i detta fall, eftersom strukturerna är desamma, är de kompatibla och giltiga.\n\n```typescript\ntype X = {\n    a: string;\n};\ntype Y = {\n    a: string;\n};\nconst x: X = { a: 'a' };\nconst y: Y = x; // Valid\n```\n\n### Grundläggande jämförelseregler i TypeScript\n\nTypeScripts jämförelseprocess är rekursiv och utförs på typer som är nästlade på valfri nivå.\n\nEn typ \"X\" är kompatibel med \"Y\" om \"Y\" har åtminstone samma medlemmar som \"X\".\n\n```typescript\ntype X = {\n    a: string;\n};\nconst y = { a: 'A', b: 'B' }; // Valid, as it has at least the same members as X\nconst r: X = y;\n```\n\nFunktionsparametrar jämförs efter typer, inte efter deras namn:\n\n```typescript\ntype X = (a: number) => void;\ntype Y = (a: number) => void;\nlet x: X = (j: number) => undefined;\nlet y: Y = (k: number) => undefined;\ny = x; // Valid\nx = y; // Valid\n```\n\nFunktionens returtyper måste vara desamma:\n\n<!-- skip -->\n```typescript\ntype X = (a: number) => undefined;\ntype Y = (a: number) => number;\nlet x: X = (a: number) => undefined;\nlet y: Y = (a: number) => 1;\ny = x; // Invalid\nx = y; // Invalid\n```\n\nReturtypen för en källfunktion måste vara en undertyp av returtypen för en målfunktion:\n\n<!-- skip -->\n```typescript\nlet x = () => ({ a: 'A' });\nlet y = () => ({ a: 'A', b: 'B' });\nx = y; // Valid\ny = x; // Invalid member b is missing\n```\n\nAtt utelämna funktionsparametrar är tillåtet, eftersom det är vanlig praxis i JavaScript, till exempel vid användning av \"Array.prototype.map()\":\n\n```typescript\n[1, 2, 3].map((element, _index, _array) => element + 'x');\n```\n\nDärför är följande typdeklarationer helt giltiga:\n\n```typescript\ntype X = (a: number) => undefined;\ntype Y = (a: number, b: number) => undefined;\nlet x: X = (a: number) => undefined;\nlet y: Y = (a: number) => undefined; // Missing b parameter\ny = x; // Valid\n```\n\nEventuella ytterligare valfria parametrar i källtypen är giltiga:\n\n```typescript\ntype X = (a: number, b?: number, c?: number) => undefined;\ntype Y = (a: number) => undefined;\nlet x: X = a => undefined;\nlet y: Y = a => undefined;\ny = x; // Valid\nx = y; //Valid\n```\n\nEventuella valfria parametrar i måltypen utan motsvarande parametrar i källtypen är giltiga och utgör inte ett fel:\n\n```typescript\ntype X = (a: number) => undefined;\ntype Y = (a: number, b?: number) => undefined;\nlet x: X = a => undefined;\nlet y: Y = a => undefined;\ny = x; // Valid\nx = y; // Valid\n```\n\nRest-parametern behandlas som en oändlig serie av valfria parametrar:\n\n```typescript\ntype X = (a: number, ...rest: number[]) => undefined;\nlet x: X = a => undefined; //valid\n```\n\nFunktioner med överlagringar är giltiga om överlagringssignaturen är kompatibel med dess implementeringssignatur:\n\n<!-- skip -->\n```typescript\nfunction x(a: string): void;\nfunction x(a: string, b: number): void;\nfunction x(a: string, b?: number): void {\n    console.log(a, b);\n}\nx('a'); // Valid\nx('a', 1); // Valid\n\nfunction y(a: string): void; // Invalid, not compatible with implementation signature\nfunction y(a: string, b: number): void;\nfunction y(a: string, b: number): void {\n    console.log(a, b);\n}\ny('a');\ny('a', 1);\n```\n\nJämförelse av funktionsparametrar lyckas om käll- och målparametrarna kan tilldelas supertyper eller undertyper (bivarians).\n\n```typescript\n// Supertype\nclass X {\n    a: string;\n    constructor(value: string) {\n        this.a = value;\n    }\n}\n// Subtype\nclass Y extends X {}\n// Subtype\nclass Z extends X {}\n\ntype GetA = (x: X) => string;\nconst getA: GetA = x => x.a;\n\n// Bivariance does accept supertypes\nconsole.log(getA(new X('x'))); // Valid\nconsole.log(getA(new Y('Y'))); // Valid\nconsole.log(getA(new Z('z'))); // Valid\n```\n\nEnums är jämförbara och giltiga med tal och vice versa, men att jämföra Enum-värden från olika Enum-typer är ogiltigt.\n\n<!-- skip -->\n```typescript\nenum X {\n    A,\n    B,\n}\nenum Y {\n    A,\n    B,\n    C,\n}\nconst xa: number = X.A; // Valid\nconst ya: Y = 0; // Valid\nX.A === Y.A; // Invalid\n```\n\nInstanser av en klass genomgår en kompatibilitetskontroll för sina privata och skyddade medlemmar:\n\n<!-- skip -->\n```typescript\nclass X {\n    public a: string;\n    constructor(value: string) {\n        this.a = value;\n    }\n}\n\nclass Y {\n    private a: string;\n    constructor(value: string) {\n        this.a = value;\n    }\n}\n\nlet x: X = new Y('y'); // Invalid\n```\n\nJämförelsekontrollen tar inte hänsyn till den olika arvshierarkin, till exempel:\n\n```typescript\nclass X {\n    public a: string;\n    constructor(value: string) {\n        this.a = value;\n    }\n}\nclass Y extends X {\n    public a: string;\n    constructor(value: string) {\n        super(value);\n        this.a = value;\n    }\n}\nclass Z {\n    public a: string;\n    constructor(value: string) {\n        this.a = value;\n    }\n}\nlet x: X = new X('x');\nlet y: Y = new Y('y');\nlet z: Z = new Z('z');\nx === y; // Valid\nx === z; // Valid even if z is from a different inheritance hierarchy\n```\n\nGenerics jämförs med hjälp av deras strukturer baserat på den resulterande typen efter tillämpning av den generiska parametern. Bara slutresultatet jämförs som en icke-generisk typ.\n\n<!-- skip -->\n```typescript\ninterface X<T> {\n    a: T;\n}\nlet x: X<number> = { a: 1 };\nlet y: X<string> = { a: 'a' };\nx === y; // Invalid as the type argument is used in the final structure\n```\n\n```typescript\ninterface X<T> {}\nconst x: X<number> = 1;\nconst y: X<string> = 'a';\nx === y; // Valid as the type argument is not used in the final structure\n```\n\nNär generics inte har sitt typargument specificerat behandlas alla ospecificerade argument som typer med \"any\":\n\n```typescript\ntype X = <T>(x: T) => T;\ntype Y = <K>(y: K) => K;\nlet x: X = x => x;\nlet y: Y = y => y;\nx = y; // Valid\n```\n\nKom ihåg:\n\n<!-- skip -->\n```typescript\nlet a: number = 1;\nlet b: number = 2;\na = b; // Valid, everything is assignable to itself\n\nlet c: any;\nc = 1; // Valid, all types are assignable to any\n\nlet d: unknown;\nd = 1; // Valid, all types are assignable to unknown\n\nlet e: unknown;\nlet e1: unknown = e; // Valid, unknown is only assignable to itself and any\nlet e2: any = e; // Valid\nlet e3: number = e; // Invalid\n\nlet f: never;\nf = 1; // Invalid, nothing is assignable to never\n\nlet g: void;\nlet g1: any;\ng = 1; // Invalid, void is not assignable to or from anything expect any\ng = g1; // Valid\n```\n\nObservera att när \"strictNullChecks\" är aktiverat behandlas \"null\" och \"undefined\" på liknande sätt som \"void\"; annars liknar de \"never\".\n\n### Typer som mängder\n\nI TypeScript är en typ en mängd av möjliga värden. Denna mängd kallas även typens domän. Varje värde av en typ kan ses som ett element i en mängd. En typ fastställer de begränsningar som varje element i mängden måste uppfylla för att betraktas som en medlem av den mängden.\nTypeScripts primära uppgift är att kontrollera och verifiera om en mängd är en delmängd av en annan.\n\nTypeScript stöder olika typer av mängder:\n\n| Mängdterm              | TypeScript                      | Anteckningar                                                                                                       |\n| ---------------------- | ------------------------------- | ------------------------------------------------------------------------------------------------------------------ |\n| Tom mängd              | never                           | \"never\" innehåller ingenting förutom sig själv                                                                     |\n| Enelement-mängd        | undefined / null / literal type |                                                                                                                    |\n| Ändlig mängd           | boolean / union                 |                                                                                                                    |\n| Oändlig mängd          | string / number / object        |                                                                                                                    |\n| Universell mängd       | any / unknown                   | Varje element är medlem i \"any\" och varje mängd är en delmängd av den / \"unknown\" är en typsäker motsvarighet till \"any\" |\n\nHär är några exempel:\n\n| TypeScript            | Mängdterm              | Exempel                                                                         |\n| --------------------- | ---------------------- | ------------------------------------------------------------------------------- |\n| never                 | ∅ (tom mängd)          | const x: never = 'x'; // Error: Type 'string' is not assignable to type 'never' |\n|                       |                        |\n| Literal type          | Enelement-mängd        | type X = 'X';                                                                   |\n|                       |                        | type Y = 7;                                                                     |\n|                       |                        |\n| Värde tilldelbart till T | Värde ∈ T (medlem av)  | type XY = 'X' \\| 'Y';                                                           |\n|                       |                        | const x: XY = 'X';                                                              |\n|                       |                        |\n| T1 tilldelbart till T2   | T1 ⊆ T2 (delmängd av)  | type XY = 'X' \\| 'Y';                                                           |\n|                       |                        | const x: XY = 'X';                                                              |\n|                       |                        | const j: XY = 'J'; // Type '\"J\"' is not assignable to type 'XY'.                |\n|                       |                        |                                                                                 |\n| T1 extends T2         | T1 ⊆ T2 (delmängd av)  | type X = 'X' extends string ? true : false;                                     |\n|                       |                        |\n| T1 \\| T2              | T1 ∪ T2 (union)        | type XY = 'X' \\| 'Y';                                                           |\n|                       |                        | type JK = 1 \\| 2;                                                               |\n|                       |                        |\n| T1 & T2               | T1 ∩ T2 (snitt)        | type X = \\{ a: string \\}                                                          |\n|                       |                        | type Y = \\{ b: string \\}                                                          |\n|                       |                        | type XY = X & Y                                                                 |\n|                       |                        | const x: XY = \\{ a: 'a', b: 'b' \\}                                                |\n|                       |                        |\n| unknown               | Universell mängd       | const x: unknown = 1                                                            |\n\nEn union, (T1 | T2) skapar en bredare mängd (båda):\n\n```typescript\ntype X = {\n    a: string;\n};\ntype Y = {\n    b: string;\n};\ntype XY = X | Y;\nconst r: XY = { a: 'a', b: 'x' }; // Valid\n```\n\nEn intersektion, (T1 & T2) skapar en smalare mängd (endast delade):\n\n<!-- skip -->\n```typescript\ntype X = {\n    a: string;\n};\ntype Y = {\n    a: string;\n    b: string;\n};\ntype XY = X & Y;\nconst r: XY = { a: 'a' }; // Invalid\nconst j: XY = { a: 'a', b: 'b' }; // Valid\n```\n\nNyckelordet `extends` kan betraktas som \"delmängd av\" i detta sammanhang. Det sätter en begränsning för en typ. När extends används med en generisk typ, behandlas den generiska typen som en oändlig mängd och begränsas till en mer specifik typ.\nObservera att `extends` inte har något att göra med hierarki i OOP-bemärkelse (det finns inget sådant koncept i TypeScript).\nTypeScript arbetar med mängder och har ingen strikt hierarki. Faktum är att, som i exemplet nedan, två typer kan överlappa utan att någon av dem är en undertyp av den andra (TypeScript betraktar strukturen, formen på objekten).\n\n```typescript\ninterface X {\n    a: string;\n}\ninterface Y extends X {\n    b: string;\n}\ninterface Z extends Y {\n    c: string;\n}\nconst z: Z = { a: 'a', b: 'b', c: 'c' };\ninterface X1 {\n    a: string;\n}\ninterface Y1 {\n    a: string;\n    b: string;\n}\ninterface Z1 {\n    a: string;\n    b: string;\n    c: string;\n}\nconst z1: Z1 = { a: 'a', b: 'b', c: 'c' };\n\nconst r: Z1 = z; // Valid\n```\n\n### Tilldela en typ: Typdeklarationer och Typpåståenden\n\nEn typ kan tilldelas på olika sätt i TypeScript:\n\n#### Typdeklaration\n\nI följande exempel använder vi x: X (\": Type\") för att deklarera en typ för variabeln x.\n\n```typescript\ntype X = {\n    a: string;\n};\n\n// Type declaration\nconst x: X = {\n    a: 'a',\n};\n```\n\nOm variabeln inte har det angivna formatet kommer TypeScript att rapportera ett fel. Till exempel:\n\n<!-- skip -->\n```typescript\ntype X = {\n    a: string;\n};\n\nconst x: X = {\n    a: 'a',\n    b: 'b', // Error: Object literal may only specify known properties\n};\n```\n\n#### Typpåstående\n\nDet är möjligt att lägga till ett påstående genom att använda nyckelordet `as`. Detta talar om för kompilatorn att utvecklaren har mer information om en typ och tystar eventuella fel som kan uppstå.\n\nTill exempel:\n\n```typescript\ntype X = {\n    a: string;\n};\nconst x = {\n    a: 'a',\n    b: 'b',\n} as X;\n```\n\nI exemplet ovan påstås objektet x ha typen X med hjälp av nyckelordet as. Detta informerar TypeScript-kompilatorn om att objektet överensstämmer med den angivna typen, även om det har en extra egenskap b som inte finns i typdefinitionen.\n\nTyppåståenden är användbara i situationer där en mer specifik typ behöver anges, särskilt vid arbete med DOM:en. Till exempel:\n\n```typescript\nconst myInput = document.getElementById('my_input') as HTMLInputElement;\n```\n\nHär används typpåståendet as HTMLInputElement för att tala om för TypeScript att resultatet av getElementById ska behandlas som ett HTMLInputElement.\nTyppåståenden kan också användas för att mappa om nycklar, som visas i exemplet nedan med malliteraler:\n\n```typescript\ntype J<Type> = {\n    [Property in keyof Type as `prefix_${string &\n        Property}`]: () => Type[Property];\n};\ntype X = {\n    a: string;\n    b: number;\n};\ntype Y = J<X>;\n```\n\nI detta exempel använder typen `J<Type>` en mappad typ med en malliteral för att mappa om nycklarna i Type. Den skapar nya egenskaper med ett \"prefix_\" tillagt till varje nyckel, och deras motsvarande värden är funktioner som returnerar de ursprungliga egenskapsvärdena.\n\nDet är värt att notera att när man använder ett typpåstående kommer TypeScript inte att utföra kontroll av överskottsegenskaper. Därför är det generellt att föredra att använda en typdeklaration när objektets struktur är känd i förväg.\n\n#### Omgivande deklarationer\n\nOmgivande deklarationer är filer som beskriver typer för JavaScript-kod. De har filnamnsformatet `.d.ts`. De importeras vanligtvis och används för att annotera befintliga JavaScript-bibliotek eller för att lägga till typer till befintliga JS-filer i ditt projekt.\n\nMånga vanliga bibliotekstyper finns på:\n[https://github.com/DefinitelyTyped/DefinitelyTyped/](https://github.com/DefinitelyTyped/DefinitelyTyped/)\n\noch kan installeras med:\n\n```shell\nnpm install --save-dev @types/library-name\n```\n\nFör dina egna omgivande deklarationer kan du importera dem med \"triple-slash\"-referensen:\n\n<!-- skip -->\n```typescript\n/// <reference path=\"./library-types.d.ts\" />\n```\n\nDu kan använda omgivande deklarationer även i JavaScript-filer med `// @ts-check`.\n\nNyckelordet `declare` möjliggör typdefinitioner för befintlig JavaScript-kod utan att importera den, och fungerar som en platshållare för typer från en annan fil eller globalt.\n\n### Egenskapskontroll och kontroll av överskottsegenskaper\n\nTypeScript bygger på ett strukturellt typsystem, men kontroll av överskottsegenskaper är en egenskap hos TypeScript som gör det möjligt att kontrollera om ett objekt har exakt de egenskaper som anges i typen.\n\nKontroll av överskottsegenskaper utförs vid tilldelning av objektliteraler till variabler eller när de skickas som argument till funktionens överskottsegenskap, till exempel.\n\n<!-- skip -->\n```typescript\ntype X = {\n    a: string;\n};\nconst y = { a: 'a', b: 'b' };\nconst x: X = y; // Valid because structural typing\nconst w: X = { a: 'a', b: 'b' }; // Invalid because excess property checking\n```\n\n### Svaga typer\n\nEn typ anses vara svag när den inte innehåller annat än en uppsättning helt valfria egenskaper:\n\n```typescript\ntype X = {\n    a?: string;\n    b?: string;\n};\n```\n\nTypeScript betraktar det som ett fel att tilldela något till en svag typ när det inte finns någon överlappning. Till exempel ger följande ett fel:\n\n<!-- skip -->\n```typescript\ntype Options = {\n    a?: string;\n    b?: string;\n};\n\nconst fn = (options: Options) => undefined;\n\nfn({ c: 'c' }); // Invalid\n```\n\nÄven om det inte rekommenderas, är det möjligt att kringgå denna kontroll genom att använda typpåstående om det behövs:\n\n```typescript\ntype Options = {\n    a?: string;\n    b?: string;\n};\nconst fn = (options: Options) => undefined;\nfn({ c: 'c' } as Options); // Valid\n```\n\nEller genom att lägga till `unknown` i indexsignaturen till den svaga typen:\n\n```typescript\ntype Options = {\n    [prop: string]: unknown;\n    a?: string;\n    b?: string;\n};\n\nconst fn = (options: Options) => undefined;\nfn({ c: 'c' }); // Valid\n```\n\n### Strikt kontroll av objektliteraler (Freshness)\n\nStrikt kontroll av objektliteraler, ibland kallad \"freshness\", är en funktion i TypeScript som hjälper till att fånga överskotts- eller felstavade egenskaper som annars skulle gå obemärkta vid normala strukturella typkontroller.\n\nNär man skapar en objektliteral betraktar TypeScript-kompilatorn den som \"fresh\". Om objektliteralen tilldelas till en variabel eller skickas som parameter kommer TypeScript att ge ett fel om objektliteralen anger egenskaper som inte finns i måltypen.\n\nDock försvinner \"freshness\" när en objektliteral breddas eller ett typpåstående används.\n\nHär är några exempel för att illustrera:\n\n<!-- skip -->\n```typescript\ntype X = { a: string };\ntype Y = { a: string; b: string };\n\nlet x: X;\nx = { a: 'a', b: 'b' }; // Freshness check: Invalid assignment\nvar y: Y;\ny = { a: 'a', bx: 'bx' }; // Freshness check: Invalid assignment\n\nconst fn = (x: X) => console.log(x.a);\n\nfn(x);\nfn(y); // Widening: No errors, structurally type compatible\n\nfn({ a: 'a', bx: 'b' }); // Freshness check: Invalid argument\n\nlet c: X = { a: 'a' };\nlet d: Y = { a: 'a', b: '' };\nc = d; // Widening: No Freshness check\n```\n\n### Typinferens\n\nTypeScript kan härleda typer när ingen annotering tillhandahålls vid:\n\n* Variabelinitiering.\n* Medlemsinitiering.\n* Inställning av standardvärden för parametrar.\n* Funktionens returtyp.\n\nTill exempel:\n\n```typescript\nlet x = 'x'; // The type inferred is string\n```\n\nTypeScript-kompilatorn analyserar värdet eller uttrycket och bestämmer dess typ baserat på tillgänglig information.\n\n### Mer avancerade inferenser\n\nNär flera uttryck används vid typinferens letar TypeScript efter de \"bästa gemensamma typerna\". Till exempel:\n\n```typescript\nlet x = [1, 'x', 1, null]; // The type inferred is: (string | number | null)[]\n```\n\nOm kompilatorn inte kan hitta de bästa gemensamma typerna returnerar den en unionstyp. Till exempel:\n\n```typescript\nlet x = [new RegExp('x'), new Date()]; // Type inferred is: (RegExp | Date)[]\n```\n\nTypeScript använder \"kontextuell typning\" baserat på variabelns placering för att härleda typer. I följande exempel vet kompilatorn att `e` är av typen `MouseEvent` på grund av händelsetypen `click` som definieras i filen lib.d.ts, vilken innehåller omgivande deklarationer för olika vanliga JavaScript-konstruktioner och DOM:en:\n\n```typescript\nwindow.addEventListener('click', function (e) {}); // The inferred type of e is MouseEvent\n```\n\n### Typbreddning\n\nTypbreddning är den process där TypeScript tilldelar en typ till en variabel som initierats utan att en typannotering angavs. Den tillåter övergång från smal till bredare typ men inte tvärtom.\nI följande exempel:\n\n<!-- skip -->\n```typescript\nlet x = 'x'; // TypeScript infers as string, a wide type\nlet y: 'y' | 'x' = 'y'; // y types is a union of literal types\ny = x; // Invalid Type 'string' is not assignable to type '\"x\" | \"y\"'.\n```\n\nTypeScript tilldelar `string` till `x` baserat på det enda värde som angavs vid initieringen (`x`), detta är ett exempel på breddning.\n\nTypeScript tillhandahåller sätt att kontrollera breddningsprocessen, till exempel genom att använda \"const\".\n\n### Const\n\nAtt använda nyckelordet `const` vid deklaration av en variabel resulterar i en smalare typinferens i TypeScript.\n\nTill exempel:\n\n```typescript\nconst x = 'x'; // TypeScript infers the type of x as 'x', a narrower type\nlet y: 'y' | 'x' = 'y';\ny = x; // Valid: The type of x is inferred as 'x'\n```\n\nGenom att använda `const` för att deklarera variabeln x, smalnas dess typ av till det specifika literalvärdet 'x'. Eftersom typen av x är avsmalnad kan den tilldelas till variabeln y utan något fel.\nAnledningen till att typen kan härledas är att `const`-variabler inte kan omtilldelas, så deras typ kan smalnas av till en specifik literaltyp, i detta fall literaltypen 'x'.\n\n#### Const-modifierare på typparametrar\n\nFrån version 5.0 av TypeScript är det möjligt att ange attributet `const` på en generisk typparameter. Detta möjliggör härledning av den mest precisa typen möjligt. Låt oss se ett exempel utan att använda `const`:\n\n```typescript\nfunction identity<T>(value: T) {\n    // No const here\n    return value;\n}\nconst values = identity({ a: 'a', b: 'b' }); // Type infered is: { a: string; b: string; }\n```\n\nSom du kan se härleddes egenskaperna `a` och `b` med typen `string`.\n\nLåt oss nu se skillnaden med `const`-versionen:\n\n```typescript\nfunction identity<const T>(value: T) {\n    // Using const modifier on type parameters\n    return value;\n}\nconst values = identity({ a: 'a', b: 'b' }); // Type infered is: { a: \"a\"; b: \"b\"; }\n```\n\nNu kan vi se att egenskaperna `a` och `b` härleddes som `const`, så `a` och `b` behandlas som strängliteraler snarare än bara `string`-typer.\n\n#### Const-påstående\n\nDenna funktion låter dig deklarera en variabel med en mer precis literaltyp baserat på dess initieringsvärde, och signalerar till kompilatorn att värdet ska behandlas som en oföränderlig literal. Här är några exempel:\n\nPå en enskild egenskap:\n\n```typescript\nconst v = {\n    x: 3 as const,\n};\nv.x = 3;\n```\n\nPå ett helt objekt:\n\n```typescript\nconst v = {\n    x: 1,\n    y: 2,\n} as const;\n```\n\nDetta kan vara särskilt användbart vid definition av typen för en tupel:\n\n```typescript\nconst x = [1, 2, 3]; // number[]\nconst y = [1, 2, 3] as const; // Tuple of readonly [1, 2, 3]\n```\n\n### Explicit typannotering\n\nVi kan vara specifika och ange en typ. I följande exempel är egenskapen `x` av typen `number`:\n\n```typescript\nconst v = {\n    x: 1, // Inferred type: number (widening)\n};\nv.x = 3; // Valid\n```\n\nVi kan göra typannoteringen mer specifik genom att använda en union av literaltyper:\n\n<!-- skip -->\n```typescript\nconst v: { x: 1 | 2 | 3 } = {\n    x: 1, // x is now a union of literal types: 1 | 2 | 3\n};\nv.x = 3; // Valid\nv.x = 100; // Invalid\n```\n\n### Typavsmalnande\n\nTypavsmalnande är den process i TypeScript där en generell typ smalnas av till en mer specifik typ. Detta sker när TypeScript analyserar koden och avgör att vissa villkor eller operationer kan förfina typinformationen.\n\nAvsmalnande av typer kan ske på olika sätt, bland annat:\n\n#### Villkor\n\nGenom att använda villkorssatser, som `if` eller `switch`, kan TypeScript smalna av typen baserat på utfallet av villkoret. Till exempel:\n\n```typescript\nlet x: number | undefined = 10;\n\nif (x !== undefined) {\n    x += 100; // The type is number, which had been narrowed by the condition\n}\n```\n\n#### Kasta eller returnera\n\nAtt kasta ett fel eller returnera tidigt från en gren kan användas för att hjälpa TypeScript smalna av en typ. Till exempel:\n\n```typescript\nlet x: number | undefined = 10;\n\nif (x === undefined) {\n    throw 'error';\n}\nx += 100;\n```\n\nAndra sätt att smalna av typer i TypeScript inkluderar:\n\n* `instanceof`-operatorn: Används för att kontrollera om ett objekt är en instans av en specifik klass.\n* `in`-operatorn: Används för att kontrollera om en egenskap finns i ett objekt.\n* `typeof`-operatorn: Används för att kontrollera typen av ett värde vid körning.\n* Inbyggda funktioner som `Array.isArray()`: Används för att kontrollera om ett värde är en array.\n\n#### Diskriminerad union\n\nAtt använda en \"diskriminerad union\" är ett mönster i TypeScript där en explicit \"tagg\" läggs till objekt för att skilja mellan olika typer inom en union. Detta mönster kallas också en \"taggad union\". I följande exempel representeras \"taggen\" av egenskapen \"type\":\n\n```typescript\ntype A = { type: 'type_a'; value: number };\ntype B = { type: 'type_b'; value: string };\n\nconst x = (input: A | B): string | number => {\n    switch (input.type) {\n        case 'type_a':\n            return input.value + 100; // type is A\n        case 'type_b':\n            return input.value + 'extra'; // type is B\n    }\n};\n```\n\n#### Användardefinierade typvakter\n\nI fall där TypeScript inte kan avgöra en typ är det möjligt att skriva en hjälpfunktion känd som en \"användardefinierad typvakt\". I följande exempel kommer vi att använda ett typpredikat för att smalna av typen efter att viss filtrering har tillämpats:\n\n```typescript\nconst data = ['a', null, 'c', 'd', null, 'f'];\n\nconst r1 = data.filter(x => x != null); // The type is (string | null)[], TypeScript was not able to infer the type properly\n\nconst isValid = (item: string | null): item is string => item !== null; // Custom type guard\n\nconst r2 = data.filter(isValid); // The type is fine now string[], by using the predicate type guard we were able to narrow the type\n```\n\n"
  },
  {
    "path": "website/src/content/docs/sv-se/book/extending-types.md",
    "content": "---\ntitle: Utöka typer\nsidebar:\n  order: 15\n  label: 15. Utöka typer\n---\n\n\nDet är möjligt att utöka ett `interface` (kopiera medlemmar från en annan typ):\n\n```typescript\ninterface X {\n    a: string;\n}\ninterface Y extends X {\n    b: string;\n}\n```\n\nDet är också möjligt att utöka från flera typer:\n\n```typescript\ninterface A {\n    a: string;\n}\ninterface B {\n    b: string;\n}\ninterface Y extends A, B {\n    y: string;\n}\n```\n\nNyckelordet `extends` fungerar bara på interface och klasser, för typer använd en intersektion:\n\n```typescript\ntype A = {\n    a: number;\n};\ntype B = {\n    b: number;\n};\ntype C = A & B;\n```\n\nDet är möjligt att utöka en typ med hjälp av en härledning men inte tvärtom:\n\n```typescript\ntype A = {\n    a: string;\n};\ninterface B extends A {\n    b: string;\n}\n```\n\n"
  },
  {
    "path": "website/src/content/docs/sv-se/book/fixed-length-tuple.md",
    "content": "---\ntitle: Tuppel med fast längd\nsidebar:\n  order: 30\n  label: 30. Tuppel med fast längd\n---\n\n\nEn tuppel med fast längd är en specifik typ av tuppel som tvingar fram ett fast antal element av specifika typer, och tillåter inte några ändringar av tuppelns längd efter att den har definierats.\n\nTupplar med fast längd är användbara när du behöver representera en samling värden med ett specifikt antal element och specifika typer, och du vill säkerställa att längden och typerna av tuppeln inte kan ändras oavsiktligt.\n\n<!-- skip -->\n```typescript\nconst x = [10, 'hello'] as const;\nx.push(2); // Error\n```\n\n"
  },
  {
    "path": "website/src/content/docs/sv-se/book/generics.md",
    "content": "---\ntitle: Generics\nsidebar:\n  order: 55\n  label: 55. Generics\n---\n\n\nGenerics gör det möjligt att skapa återanvändbara komponenter och funktioner som kan arbeta med flera typer. Med generics kan du parameterisera typer, funktioner och gränssnitt, vilket gör att de kan arbeta med olika typer utan att explicit specificera dem i förväg.\n\nGenerics gör det möjligt att göra koden mer flexibel och återanvändbar.\n\n### Generisk typ\n\nFör att definiera en generisk typ använder du vinkelparenteser (`<>`) för att specificera typparametrarna, till exempel:\n\n```typescript\nfunction identity<T>(arg: T): T {\n    return arg;\n}\nconst a = identity('x');\nconst b = identity(123);\n\nconst getLen = <T,>(data: ReadonlyArray<T>) => data.length;\nconst len = getLen([1, 2, 3]);\n```\n\n### Generiska klasser\n\nGenerics kan även tillämpas på klasser, på så sätt kan de arbeta med flera typer genom att använda typparametrar. Detta är användbart för att skapa återanvändbara klassdefinitioner som kan arbeta med olika datatyper samtidigt som typsäkerheten bibehålls.\n\n```typescript\nclass Container<T> {\n    private item: T;\n\n    constructor(item: T) {\n        this.item = item;\n    }\n\n    getItem(): T {\n        return this.item;\n    }\n}\n\nconst numberContainer = new Container<number>(123);\nconsole.log(numberContainer.getItem()); // 123\n\nconst stringContainer = new Container<string>('hello');\nconsole.log(stringContainer.getItem()); // hello\n```\n\n### Generiska begränsningar\n\nGeneriska parametrar kan begränsas med nyckelordet `extends` följt av en typ eller ett gränssnitt som typparametern måste uppfylla.\n\nI följande exempel måste T innehålla en egenskap `length` för att vara giltig:\n\n<!-- skip -->\n```typescript\nconst printLen = <T extends { length: number }>(value: T): void => {\n    console.log(value.length);\n};\n\nprintLen('Hello'); // 5\nprintLen([1, 2, 3]); // 3\nprintLen({ length: 10 }); // 10\nprintLen(123); // Invalid\n```\n\nEn intressant funktion hos generics som introducerades i version 3.4 RC är typinferens för högre ordningens funktioner, vilket introducerade propagerade generiska typargument:\n\n```typescript\ndeclare function pipe<A extends any[], B, C>(\n    ab: (...args: A) => B,\n    bc: (b: B) => C\n): (...args: A) => C;\n\ndeclare function list<T>(a: T): T[];\ndeclare function box<V>(x: V): { value: V };\n\nconst listBox = pipe(list, box); // <T>(a: T) => { value: T[] }\nconst boxList = pipe(box, list); // <V>(x: V) => { value: V }[]\n```\n\nDenna funktionalitet möjliggör enklare typsäker punktfri programmering (pointfree style) vilket är vanligt inom funktionell programmering.\n\n### Generisk kontextuell avsmalning\n\nKontextuell avsmalning för generics är mekanismen i TypeScript som gör det möjligt för kompilatorn att smalna av typen för en generisk parameter baserat på det sammanhang där den används. Det är användbart vid arbete med generiska typer i villkorssatser:\n\n```typescript\nfunction process<T>(value: T): void {\n    if (typeof value === 'string') {\n        // Value is narrowed down to type 'string'\n        console.log(value.length);\n    } else if (typeof value === 'number') {\n        // Value is narrowed down to type 'number'\n        console.log(value.toFixed(2));\n    }\n}\n\nprocess('hello'); // 5\nprocess(3.14159); // 3.14\n```\n\n"
  },
  {
    "path": "website/src/content/docs/sv-se/book/getting-started-with-typescript.md",
    "content": "---\ntitle: Komma igång med TypeScript\nsidebar:\n  order: 8\n  label: 8. Komma igång med TypeScript\n---\n\n\n### Installation\n\nVisual Studio Code erbjuder utmärkt stöd för TypeScript-språket men inkluderar inte TypeScript-kompilatorn. För att installera TypeScript-kompilatorn kan du använda en pakethanterare som npm eller yarn:\n\n```shell\nnpm install typescript --save-dev\n```\n\neller\n\n```shell\nyarn add typescript --dev\n```\n\nSe till att committa den genererade lockfilen för att säkerställa att varje teammedlem använder samma version av TypeScript.\n\nFör att köra TypeScript-kompilatorn kan du använda följande kommandon\n\n```shell\nnpx tsc\n```\n\neller\n\n```shell\nyarn tsc\n```\n\nDet rekommenderas att installera TypeScript projektvis snarare än globalt, eftersom det ger en mer förutsägbar byggprocess. För enstaka tillfällen kan du dock använda följande kommando:\n\n```shell\nnpx tsc\n```\n\neller installera det globalt:\n\n```shell\nnpm install -g typescript\n```\n\nOm du använder Microsoft Visual Studio kan du hämta TypeScript som ett paket i NuGet för dina MSBuild-projekt. I NuGet Package Manager Console kör du följande kommando:\n\n```shell\nInstall-Package Microsoft.TypeScript.MSBuild\n```\n\nUnder TypeScript-installationen installeras två körbara filer: \"tsc\" som TypeScript-kompilatorn och \"tsserver\" som den fristående TypeScript-servern. Den fristående servern innehåller kompilatorn och språktjänster som kan användas av redigerare och IDE:er för att tillhandahålla intelligent kodkomplettering.\n\nDessutom finns det flera TypeScript-kompatibla transpilerare tillgängliga, såsom Babel (via ett plugin) eller swc. Dessa transpilerare kan användas för att konvertera TypeScript-kod till andra målspråk eller versioner.\n\n### Konfiguration\n\nTypeScript kan konfigureras med hjälp av tsc CLI-alternativ eller genom att använda en dedikerad konfigurationsfil kallad tsconfig.json som placeras i projektets rot.\n\nFör att generera en tsconfig.json-fil förfylld med rekommenderade inställningar kan du använda följande kommando:\n\n```shell\ntsc --init\n```\n\nNär kommandot `tsc` körs lokalt kommer TypeScript att kompilera koden med den konfiguration som anges i den närmaste tsconfig.json-filen.\n\nHär är några exempel på CLI-kommandon som körs med standardinställningarna:\n\n```shell\ntsc main.ts // Compile a specific file (main.ts) to JavaScript\ntsc src/*.ts // Compile any .ts files under the 'src' folder to JavaScript\ntsc app.ts util.ts --outfile index.js // Compile two TypeScript files (app.ts and util.ts) into a single JavaScript file (index.js)\n```\n\n### TypeScript-konfigurationsfil\n\nEn tsconfig.json-fil används för att konfigurera TypeScript-kompilatorn (tsc). Vanligtvis läggs den till i projektets rot, tillsammans med filen `package.json`.\n\nObservera:\n\n* tsconfig.json accepterar kommentarer även om det är i json-format.\n* Det är tillrådligt att använda denna konfigurationsfil istället för kommandoradsalternativ.\n\nPå följande länk hittar du den fullständiga dokumentationen och dess schema:\n\n[https://www.typescriptlang.org/tsconfig](https://www.typescriptlang.org/tsconfig)\n\n[https://www.typescriptlang.org/tsconfig/](https://www.typescriptlang.org/tsconfig/)\n\nFöljande representerar en lista över de vanligaste och mest användbara konfigurationerna:\n\n#### target\n\nEgenskapen \"target\" används för att ange vilken version av JavaScript ECMAScript-version din TypeScript ska generera/kompilera till. För moderna webbläsare är ES6 ett bra alternativ, för äldre webbläsare rekommenderas ES5.\n\n#### lib\n\nEgenskapen \"lib\" används för att ange vilka biblioteksfiler som ska inkluderas vid kompilering. TypeScript inkluderar automatiskt API:er för funktioner som anges i \"target\"-egenskapen, men det är möjligt att utelämna eller välja specifika bibliotek för särskilda behov. Till exempel, om du arbetar med ett serverprojekt kan du exkludera \"DOM\"-biblioteket, som bara är användbart i en webbläsarmiljö.\n\n#### strict\n\nEgenskapen \"strict\" möjliggör starkare garantier och förbättrar typsäkerheten. Det är tillrådligt att alltid inkludera denna egenskap i ditt projekts tsconfig.json-fil. Att aktivera egenskapen \"strict\" gör att TypeScript:\n\n* Genererar kod med \"use strict\" för varje källfil.\n* Beaktar \"null\" och \"undefined\" i typkontrollprocessen.\n* Inaktiverar användningen av typen \"any\" när inga typannoteringar finns.\n* Ger ett fel vid användning av \"this\"-uttrycket, som annars skulle innebära typen \"any\".\n\n#### module\n\nEgenskapen \"module\" anger det modulsystem som stöds för det kompilerade programmet. Vid körning används en modulladdare för att lokalisera och köra beroenden baserat på det angivna modulsystemet.\n\nDe vanligaste modulladdarna som används i JavaScript är Node.js CommonJS för serversidans applikationer och RequireJS för AMD-moduler i webbläsarbaserade webbapplikationer. TypeScript kan generera kod för olika modulsystem, inklusive UMD, System, ESNext, ES2015/ES6 och ES2020.\n\nObservera: Modulsystemet bör väljas baserat på målmiljön och den modulladdningsmekanism som finns tillgänglig i den miljön.\n\n#### moduleResolution\n\nEgenskapen \"moduleResolution\" anger strategin för modulupplösning. Använd \"node\" för modern TypeScript-kod, strategin \"classic\" används bara för gamla versioner av TypeScript (före 1.6).\n\n#### esModuleInterop\n\nEgenskapen \"esModuleInterop\" gör det möjligt att importera standard från CommonJS-moduler som inte exporterade med \"default\"-egenskapen. Denna egenskap tillhandahåller en shim för att säkerställa kompatibilitet i den genererade JavaScript-koden. Efter att ha aktiverat detta alternativ kan vi använda `import MyLibrary from \"my-library\"` istället för `import * as MyLibrary from \"my-library\"`.\n\n#### jsx\n\nEgenskapen \"jsx\" gäller bara för .tsx-filer som används i ReactJS och styr hur JSX-konstruktioner kompileras till JavaScript. Ett vanligt alternativ är \"preserve\" som kompilerar till en .jsx-fil och behåller JSX oförändrat så att det kan skickas vidare till olika verktyg som Babel för ytterligare transformationer.\n\n#### skipLibCheck\n\nEgenskapen \"skipLibCheck\" hindrar TypeScript från att typkontrollera hela importerade tredjepartspaket. Denna egenskap minskar kompileringstiden för ett projekt. TypeScript kommer fortfarande att kontrollera din kod mot typdefinitionerna som tillhandahålls av dessa paket.\n\n#### files\n\nEgenskapen \"files\" anger för kompilatorn en lista med filer som alltid måste inkluderas i programmet.\n\n#### include\n\n<!-- markdownlint-disable MD049 -->\nEgenskapen \"include\" anger för kompilatorn en lista med filer som vi vill inkludera. Denna egenskap tillåter glob-liknande mönster, såsom \"\\*_\" för valfri underkatalog, \"_\" för valfritt filnamn och \"?\" för valfria tecken.\n<!-- markdownlint-enable MD049 -->\n\n#### exclude\n\nEgenskapen \"exclude\" anger för kompilatorn en lista med filer som inte bör inkluderas i kompileringen. Detta kan inkludera filer som \"node_modules\" eller testfiler.\nObservera: tsconfig.json tillåter kommentarer.\n\n### importHelpers\n\nTypeScript använder hjälpkod när det genererar kod för vissa avancerade eller nedåtkompatibla JavaScript-funktioner. Som standard dupliceras dessa hjälpfunktioner i filer som använder dem. Alternativet `importHelpers` importerar dessa hjälpfunktioner från modulen `tslib` istället, vilket gör JavaScript-utdata mer effektiv.\n\n### Råd vid migrering till TypeScript\n\nFör stora projekt rekommenderas en gradvis övergång där TypeScript- och JavaScript-kod initialt samexisterar. Bara små projekt kan migreras till TypeScript på en gång.\n\nDet första steget i denna övergång är att introducera TypeScript i byggkedjeprocessen. Detta kan göras genom att använda kompilatoralternativet \"allowJs\", som tillåter att .ts- och .tsx-filer samexisterar med befintliga JavaScript-filer. Eftersom TypeScript faller tillbaka till typen \"any\" för en variabel när det inte kan härleda typen från JavaScript-filer, rekommenderas det att inaktivera \"noImplicitAny\" i dina kompilatoralternativ i början av migreringen.\n\nDet andra steget är att säkerställa att dina JavaScript-tester fungerar tillsammans med TypeScript-filer så att du kan köra tester allt eftersom du konverterar varje modul. Om du använder Jest, överväg att använda `ts-jest`, som gör det möjligt att testa TypeScript-projekt med Jest.\n\nDet tredje steget är att inkludera typdeklarationer för tredjepartsbibliotek i ditt projekt. Dessa deklarationer kan hittas antingen medföljande eller på DefinitelyTyped. Du kan söka efter dem med [https://www.typescriptlang.org/dt/search](https://www.typescriptlang.org/dt/search) och installera dem med:\n\n```shell\nnpm install --save-dev @types/package-name\n```\n\neller\n\n```shell\nyarn add --dev @types/package-name\n```\n\nDet fjärde steget är att migrera modul för modul med en nedifrån-och-upp-metod, genom att följa ditt beroendeträd med start från löven. Tanken är att börja konvertera moduler som inte är beroende av andra moduler. För att visualisera beroendegrafer kan du använda verktyget \"madge\".\n\nBra kandidatmoduler för dessa initiala konverteringar är hjälpfunktioner och kod relaterad till externa API:er eller specifikationer. Det är möjligt att automatiskt generera TypeScript-typdefinitioner från Swagger-kontrakt, GraphQL- eller JSON-scheman som kan inkluderas i ditt projekt.\n\nNär det inte finns några specifikationer eller officiella scheman tillgängliga kan du generera typer från rådata, såsom JSON som returneras av en server. Det rekommenderas dock att generera typer från specifikationer istället för data för att undvika att missa specialfall.\n\nUnder migreringen bör du avstå från kodrefaktorisering och fokusera enbart på att lägga till typer i dina moduler.\n\nDet femte steget är att aktivera \"noImplicitAny\", vilket kommer att se till att alla typer är kända och definierade, vilket ger en bättre TypeScript-upplevelse för ditt projekt.\n\nUnder migreringen kan du använda direktivet `@ts-check`, som aktiverar TypeScript-typkontroll i en JavaScript-fil. Detta direktiv tillhandahåller en lös version av typkontroll och kan initialt användas för att identifiera problem i JavaScript-filer. När `@ts-check` inkluderas i en fil kommer TypeScript att försöka härleda definitioner med hjälp av kommentarer i JSDoc-stil. Överväg dock att använda JSDoc-annoteringar bara i ett mycket tidigt skede av migreringen.\n\nÖverväg att behålla standardvärdet för `noEmitOnError` i din tsconfig.json som false. Detta gör att du kan generera JavaScript-källkod även om fel rapporteras.\n\n"
  },
  {
    "path": "website/src/content/docs/sv-se/book/index-signatures.md",
    "content": "---\ntitle: Indexsignaturer\nsidebar:\n  order: 14\n  label: 14. Indexsignaturer\n---\n\n\nI TypeScript kan vi använda `string`, `number` och `symbol` som indexsignatur:\n\n```typescript\ntype K = {\n    [name: string | number]: string;\n};\nconst k: K = { x: 'x', 1: 'b' };\nconsole.log(k['x']);\nconsole.log(k[1]);\nconsole.log(k['1']); // Same result as k[1]\n```\n\nObservera att JavaScript automatiskt konverterar ett index med `number` till ett index med `string`, så `k[1]` eller `k[\"1\"]` returnerar samma värde.\n\n"
  },
  {
    "path": "website/src/content/docs/sv-se/book/infer-type-inference-in-conditional-types.md",
    "content": "---\ntitle: infer-typinferens i villkorliga typer\nsidebar:\n  order: 41\n  label: 41. infer-typinferens i villkorliga typer\n---\n\n\nNyckelordet `infer` används i villkorliga typer för att härleda (extrahera) typen av en generisk parameter från en typ som beror på den. Detta gör att du kan skriva mer flexibla och återanvändbara typdefinitioner.\n\n```typescript\ntype ElementType<T> = T extends (infer U)[] ? U : never;\ntype Numbers = ElementType<number[]>; // number\ntype Strings = ElementType<string[]>; // string\n```\n\n"
  },
  {
    "path": "website/src/content/docs/sv-se/book/interface-and-type.md",
    "content": "---\ntitle: Interface och Type\nsidebar:\n  order: 48\n  label: 48. Interface och Type\n---\n\n\n### Gemensam syntax\n\nI TypeScript definierar interface strukturen hos objekt och specificerar namnen och typerna på egenskaper eller metoder som ett objekt måste ha. Den gemensamma syntaxen för att definiera ett interface i TypeScript är följande:\n\n<!-- skip -->\n```typescript\ninterface InterfaceName {\n    property1: Type1;\n    // ...\n    method1(arg1: ArgType1, arg2: ArgType2): ReturnType;\n    // ...\n}\n```\n\nPå liknande sätt för typdefinition:\n\n<!-- skip -->\n```typescript\ntype TypeName = {\n    property1: Type1;\n    // ...\n    method1(arg1: ArgType1, arg2: ArgType2): ReturnType;\n    // ...\n};\n```\n\n`interface InterfaceName` eller `type TypeName`: Definierar namnet på interfacet.\n`property1`: `Type1`: Specificerar interfacets egenskaper tillsammans med deras motsvarande typer. Flera egenskaper kan definieras, var och en separerad med ett semikolon.\n`method1(arg1: ArgType1, arg2: ArgType2): ReturnType;`: Specificerar interfacets metoder. Metoder definieras med sina namn, följt av en parameterlista inom parenteser och returtypen. Flera metoder kan definieras, var och en separerad med ett semikolon.\n\nExempel på interface:\n\n```typescript\ninterface Person {\n    name: string;\n    age: number;\n    greet(): void;\n}\n```\n\nExempel på type:\n\n```typescript\ntype TypeName = {\n    property1: string;\n    method1(arg1: string, arg2: string): string;\n};\n```\n\nI TypeScript används typer för att definiera formen på data och upprätthålla typkontroll. Det finns flera vanliga syntaxer för att definiera typer i TypeScript, beroende på det specifika användningsfallet. Här är några exempel:\n\n### Grundläggande typer\n\n```typescript\nlet myNumber: number = 123; // number type\nlet myBoolean: boolean = true; // boolean type\nlet myArray: string[] = ['a', 'b']; // array of strings\nlet myTuple: [string, number] = ['a', 123]; // tuple\n```\n\n### Objekt och Interface\n\n```typescript\nconst x: { name: string; age: number } = { name: 'Simon', age: 7 };\n```\n\n### Union- och Intersection-typer\n\n```typescript\ntype MyType = string | number; // Union type\nlet myUnion: MyType = 'hello'; // Can be a string\nmyUnion = 123; // Or a number\n\ntype TypeA = { name: string };\ntype TypeB = { age: number };\ntype CombinedType = TypeA & TypeB; // Intersection type\nlet myCombined: CombinedType = { name: 'John', age: 25 }; // Object with both name and age properties\n```\n\n"
  },
  {
    "path": "website/src/content/docs/sv-se/book/intersection-types.md",
    "content": "---\ntitle: Intersektionstyper\nsidebar:\n  order: 32\n  label: 32. Intersektionstyper\n---\n\n\nEn intersektionstyp är en typ som representerar ett värde som har alla egenskaper hos två eller flera typer. Intersektionstyper betecknas med symbolen `&` mellan varje typ.\n\n```typescript\ntype X = {\n    a: string;\n};\n\ntype Y = {\n    b: string;\n};\n\ntype J = X & Y; // Intersection\n\nconst j: J = {\n    a: 'a',\n    b: 'b',\n};\n```\n\n"
  },
  {
    "path": "website/src/content/docs/sv-se/book/introduction.md",
    "content": "---\ntitle: Introduktion\nsidebar:\n  order: 5\n  label: 5. Introduktion\n---\n\n\nVälkommen till Den koncisa TypeScript-boken! Denna guide utrustar dig med väsentlig kunskap och praktiska färdigheter för effektiv TypeScript-utveckling. Upptäck nyckelkoncept och tekniker för att skriva ren, robust kod. Oavsett om du är nybörjare eller en erfaren utvecklare fungerar denna bok både som en omfattande guide och en praktisk referens för att utnyttja TypeScripts kraft i dina projekt.\n\nDenna bok täcker TypeScript 5.2.\n\n"
  },
  {
    "path": "website/src/content/docs/sv-se/book/literal-inference.md",
    "content": "---\ntitle: Literalhärledning\nsidebar:\n  order: 17\n  label: 17. Literalhärledning\n---\n\n\nLiteralhärledning är en funktion i TypeScript som gör att typen av en variabel eller parameter kan härledas baserat på dess värde.\n\nI följande exempel kan vi se att TypeScript betraktar `x` som en literaltyp eftersom värdet inte kan ändras senare, medan `y` härleds som sträng eftersom det kan ändras när som helst.\n\n```typescript\nconst x = 'x'; // Literal type of 'x', because this value cannot be changed\nlet y = 'y'; // Type string, as we can change this value\n```\n\nI följande exempel kan vi se att `o.x` härleds som en `string` (och inte en literal av `a`) eftersom TypeScript anser att värdet kan ändras när som helst.\n\n<!-- skip -->\n```typescript\ntype X = 'a' | 'b';\n\nlet o = {\n    x: 'a', // This is a wider string\n};\n\nconst fn = (x: X) => `${x}-foo`;\n\nconsole.log(fn(o.x)); // Argument of type 'string' is not assignable to parameter of type 'X'\n```\n\nSom du kan se ger koden ett fel när `o.x` skickas till `fn` eftersom X är en smalare typ.\n\nVi kan lösa detta problem genom att använda typbekräftelse med `const` eller typen `X`:\n\n<!-- skip -->\n```typescript\nlet o = {\n    x: 'a' as const,\n};\n```\n\neller:\n\n<!-- skip -->\n```typescript\nlet o = {\n    x: 'a' as X,\n};\n```\n\n"
  },
  {
    "path": "website/src/content/docs/sv-se/book/literal-types.md",
    "content": "---\ntitle: Literaltyper\nsidebar:\n  order: 16\n  label: 16. Literaltyper\n---\n\n\nEn literaltyp är en enskild elementuppsättning från en kollektiv typ, den definierar ett mycket exakt värde som är en JavaScript-primitiv.\n\nLiteraltyper i TypeScript är tal, strängar och booleaner.\n\nExempel på literaler:\n\n```typescript\nconst a = 'a'; // String literal type\nconst b = 1; // Numeric literal type\nconst c = true; // Boolean literal type\n```\n\nSträng-, numeriska och booleska literaltyper används i unioner, typvakter och typalias.\nI följande exempel kan du se ett unionstypealias. `O` består bara av de angivna värdena, ingen annan sträng är giltig:\n\n```typescript\ntype O = 'a' | 'b' | 'c';\n```\n\n"
  },
  {
    "path": "website/src/content/docs/sv-se/book/mapped-type-modifiers.md",
    "content": "---\ntitle: Modifierare för mappade typer\nsidebar:\n  order: 38\n  label: 38. Modifierare för mappade typer\n---\n\n\nModifierare för mappade typer i TypeScript möjliggör transformation av egenskaper inom en befintlig typ:\n\n* `readonly` eller `+readonly`: Detta gör en egenskap i den mappade typen skrivskyddad.\n* `-readonly`: Detta gör att en egenskap i den mappade typen kan ändras.\n* `?`: Detta gör en egenskap i den mappade typen valfri.\n\nExempel:\n\n```typescript\ntype ReadOnly<T> = { readonly [P in keyof T]: T[P] }; // All properties marked as read-only\n\ntype Mutable<T> = { -readonly [P in keyof T]: T[P] }; // All properties marked as mutable\n\ntype MyPartial<T> = { [P in keyof T]?: T[P] }; // All properties marked as optional\n```\n\n"
  },
  {
    "path": "website/src/content/docs/sv-se/book/mapped-types.md",
    "content": "---\ntitle: Mappade typer\nsidebar:\n  order: 37\n  label: 37. Mappade typer\n---\n\n\nMappade typer i TypeScript låter dig skapa nya typer baserade på en befintlig typ genom att transformera varje egenskap med hjälp av en mappningsfunktion. Genom att mappa befintliga typer kan du skapa nya typer som representerar samma information i ett annat format. För att skapa en mappad typ kommer du åt egenskaperna hos en befintlig typ med `keyof`-operatorn och ändrar dem sedan för att producera en ny typ.\nI följande exempel:\n\n```typescript\ntype MyMappedType<T> = {\n    [P in keyof T]: T[P][];\n};\ntype MyType = {\n    foo: string;\n    bar: number;\n};\ntype MyNewType = MyMappedType<MyType>;\nconst x: MyNewType = {\n    foo: ['hello', 'world'],\n    bar: [1, 2, 3],\n};\n```\n\ndefinierar vi MyMappedType för att mappa över T:s egenskaper och skapa en ny typ där varje egenskap är en array av sin ursprungliga typ. Med hjälp av detta skapar vi MyNewType för att representera samma information som MyType, men med varje egenskap som en array.\n\n"
  },
  {
    "path": "website/src/content/docs/sv-se/book/merging-and-extension.md",
    "content": "---\ntitle: Sammanslagning och utökning\nsidebar:\n  order: 52\n  label: 52. Sammanslagning och utökning\n---\n\n\nSammanslagning och utökning avser två olika koncept relaterade till att arbeta med typer och interface.\n\nSammanslagning låter dig kombinera flera deklarationer med samma namn till en enda definition, till exempel när du definierar ett interface med samma namn flera gånger:\n\n```typescript\ninterface X {\n    a: string;\n}\n\ninterface X {\n    b: number;\n}\n\nconst person: X = {\n    a: 'a',\n    b: 7,\n};\n```\n\nUtökning avser möjligheten att utöka eller ärva från befintliga typer eller interface för att skapa nya. Det är en mekanism för att lägga till ytterligare egenskaper eller metoder till en befintlig typ utan att ändra dess ursprungliga definition. Exempel:\n\n```typescript\ninterface Animal {\n    name: string;\n    eat(): void;\n}\n\ninterface Bird extends Animal {\n    sing(): void;\n}\n\nconst dog: Bird = {\n    name: 'Bird 1',\n    eat() {\n        console.log('Eating');\n    },\n    sing() {\n        console.log('Singing');\n    },\n};\n```\n\n"
  },
  {
    "path": "website/src/content/docs/sv-se/book/named-tuple-type-labeled.md",
    "content": "---\ntitle: Namngiven tuppeltyp (Märkt)\nsidebar:\n  order: 29\n  label: 29. Namngiven tuppeltyp (Märkt)\n---\n\n\nTuppeltyper kan inkludera valfria etiketter eller namn för varje element. Dessa etiketter är till för läsbarhet och verktygsstöd, och påverkar inte de operationer du kan utföra med dem.\n\n```typescript\ntype T = string;\ntype Tuple1 = [T, T];\ntype Tuple2 = [a: T, b: T];\ntype Tuple3 = [a: T, T]; // Named Tuple plus Anonymous Tuple\n```\n\n"
  },
  {
    "path": "website/src/content/docs/sv-se/book/namespacing.md",
    "content": "---\ntitle: Namnrymder\nsidebar:\n  order: 57\n  label: 57. Namnrymder\n---\n\n\nI TypeScript används namnrymder (namespaces) för att organisera kod i logiska behållare, förhindra namnkollisioner och ge ett sätt att gruppera relaterad kod tillsammans.\nAnvändningen av nyckelordet `export` tillåter åtkomst till namnrymden i \"utomstående\" moduler.\n\n```typescript\nexport namespace MyNamespace {\n    export interface MyInterface1 {\n        prop1: boolean;\n    }\n    export interface MyInterface2 {\n        prop2: string;\n    }\n}\n\nconst a: MyNamespace.MyInterface1 = {\n    prop1: true,\n};\n```\n\n"
  },
  {
    "path": "website/src/content/docs/sv-se/book/narrowing.md",
    "content": "---\ntitle: Avsmalning\nsidebar:\n  order: 20\n  label: 20. Avsmalning\n---\n\n\nTypeScript-avsmalning är processen att förfina typen av en variabel inom ett villkorsblock. Detta är användbart när man arbetar med unionstyper, där en variabel kan ha mer än en typ.\n\nTypeScript känner igen flera sätt att avsmalna typen:\n\n### typeof-typvakter\n\ntypeof-typvakten är en specifik typvakt i TypeScript som kontrollerar typen av en variabel baserat på dess inbyggda JavaScript-typ.\n\n```typescript\nconst fn = (x: number | string) => {\n    if (typeof x === 'number') {\n        return x + 1; // x is number\n    }\n    return -1;\n};\n```\n\n### Sanningsvärdesavsmalning\n\nSanningsvärdesavsmalning i TypeScript fungerar genom att kontrollera om en variabel är sann eller falsk för att avsmalna dess typ därefter.\n\n```typescript\nconst toUpperCase = (name: string | null) => {\n    if (name) {\n        return name.toUpperCase();\n    } else {\n        return null;\n    }\n};\n```\n\n### Likhetsavsmalning\n\nLikhetsavsmalning i TypeScript fungerar genom att kontrollera om en variabel är lika med ett specifikt värde eller inte, för att avsmalma dess typ därefter.\n\nDen används tillsammans med `switch`-satser och likhetsoperatorer som `===`, `!==`, `==` och `!=` för att avsmalma typer.\n\n```typescript\nconst checkStatus = (status: 'success' | 'error') => {\n    switch (status) {\n        case 'success':\n            return true;\n        case 'error':\n            return null;\n    }\n};\n```\n\n### In-operatoravsmalning\n\n`in`-operatoravsmalning i TypeScript är ett sätt att avsmalma typen av en variabel baserat på om en egenskap finns inom variabelns typ.\n\n```typescript\ntype Dog = {\n    name: string;\n    breed: string;\n};\n\ntype Cat = {\n    name: string;\n    likesCream: boolean;\n};\n\nconst getAnimalType = (pet: Dog | Cat) => {\n    if ('breed' in pet) {\n        return 'dog';\n    } else {\n        return 'cat';\n    }\n};\n```\n\n### instanceof-avsmalning\n\n`instanceof`-operatoravsmalning i TypeScript är ett sätt att avsmalma typen av en variabel baserat på dess konstruktorfunktion, genom att kontrollera om ett objekt är en instans av en viss klass eller gränssnitt.\n\n```typescript\nclass Square {\n    constructor(public width: number) {}\n}\nclass Rectangle {\n    constructor(\n        public width: number,\n        public height: number\n    ) {}\n}\nfunction area(shape: Square | Rectangle) {\n    if (shape instanceof Square) {\n        return shape.width * shape.width;\n    } else {\n        return shape.width * shape.height;\n    }\n}\nconst square = new Square(5);\nconst rectangle = new Rectangle(5, 10);\nconsole.log(area(square)); // 25\nconsole.log(area(rectangle)); // 50\n```\n\n"
  },
  {
    "path": "website/src/content/docs/sv-se/book/never-type.md",
    "content": "---\ntitle: Användning av Never-typen\nsidebar:\n  order: 47\n  label: 47. Användning av Never-typen\n---\n\n\nTypen `never` representerar värden som aldrig förekommer. Den används för att beteckna funktioner eller uttryck som aldrig returnerar eller kastar ett fel.\n\nTill exempel en oändlig loop:\n\n```typescript\nconst infiniteLoop = (): never => {\n    while (true) {\n        // do something\n    }\n};\n```\n\nKasta ett fel:\n\n```typescript\nconst throwError = (message: string): never => {\n    throw new Error(message);\n};\n```\n\nTypen `never` är användbar för att säkerställa typsäkerhet och fånga potentiella fel i din kod. Den hjälper TypeScript att analysera och härleda mer precisa typer när den används i kombination med andra typer och kontrollflödessatser, till exempel:\n\n```typescript\ntype Direction = 'up' | 'down';\nconst move = (direction: Direction): void => {\n    switch (direction) {\n        case 'up':\n            // move up\n            break;\n        case 'down':\n            // move down\n            break;\n        default:\n            const exhaustiveCheck: never = direction;\n            throw new Error(`Unhandled direction: ${exhaustiveCheck}`);\n    }\n};\n```\n\n"
  },
  {
    "path": "website/src/content/docs/sv-se/book/object-types.md",
    "content": "---\ntitle: Objekttyper\nsidebar:\n  order: 27\n  label: 27. Objekttyper\n---\n\n\nI TypeScript beskriver objekttyper formen på ett objekt. De specificerar namnen och typerna på objektets egenskaper, samt huruvida dessa egenskaper är obligatoriska eller valfria.\n\nI TypeScript kan du definiera objekttyper på två primära sätt:\n\nInterface som definierar formen på ett objekt genom att specificera namnen, typerna och valfrihet hos dess egenskaper.\n\n```typescript\ninterface User {\n    name: string;\n    age: number;\n    email?: string;\n}\n```\n\nTypalias, liknande ett interface, definierar formen på ett objekt. Det kan dock även skapa en ny anpassad typ som baseras på en befintlig typ eller en kombination av befintliga typer. Detta inkluderar att definiera unionstyper, intersektionstyper och andra komplexa typer.\n\n```typescript\ntype Point = {\n    x: number;\n    y: number;\n};\n```\n\nDet är också möjligt att definiera en typ anonymt:\n\n```typescript\nconst sum = (x: { a: number; b: number }) => x.a + x.b;\nconsole.log(sum({ a: 5, b: 1 }));\n```\n\n"
  },
  {
    "path": "website/src/content/docs/sv-se/book/optional-properties.md",
    "content": "---\ntitle: Valfria egenskaper\nsidebar:\n  order: 12\n  label: 12. Valfria egenskaper\n---\n\n\nEtt objekt kan specificera valfria egenskaper genom att lägga till ett frågetecken `?` i slutet av egenskapsnamnet:\n\n```typescript\ntype X = {\n    a: number;\n    b?: number; // Optional\n};\n```\n\nDet är möjligt att ange ett standardvärde när en egenskap är valfri:\n\n```typescript\ntype X = {\n    a: number;\n    b?: number;\n};\nconst x = ({ a, b = 100 }: X) => a + b;\n```\n\n"
  },
  {
    "path": "website/src/content/docs/sv-se/book/others.md",
    "content": "---\ntitle: Övrigt\nsidebar:\n  order: 61\n  label: 61. Övrigt\n---\n\n\n### Fel och undantagshantering\n\nTypeScript låter dig fånga och hantera fel med hjälp av JavaScripts standardmekanismer för felhantering:\n\nTry-Catch-Finally-block:\n\n```typescript\ntry {\n    // Code that might throw an error\n} catch (error) {\n    // Handle the error\n} finally {\n    // Code that always executes, finally is optional\n}\n```\n\nDu kan också hantera olika typer av fel:\n\n```typescript\ntry {\n    // Code that might throw different types of errors\n} catch (error) {\n    if (error instanceof TypeError) {\n        // Handle TypeError\n    } else if (error instanceof RangeError) {\n        // Handle RangeError\n    } else {\n        // Handle other errors\n    }\n}\n```\n\nAnpassade feltyper:\n\nDet är möjligt att specificera mer specifika fel genom att utöka `Error`-klassen:\n\n```typescript\nclass CustomError extends Error {\n    constructor(message: string) {\n        super(message);\n        this.name = 'CustomError';\n    }\n}\n\nthrow new CustomError('This is a custom error.');\n```\n\n### Mixin-klasser\n\nMixin-klasser låter dig kombinera och komponera beteende från flera klasser till en enda klass. De erbjuder ett sätt att återanvända och utöka funktionalitet utan behov av djupa arvskedjor.\n\n```typescript\nabstract class Identifiable {\n    name: string = '';\n    logId() {\n        console.log('id:', this.name);\n    }\n}\nabstract class Selectable {\n    selected: boolean = false;\n    select() {\n        this.selected = true;\n        console.log('Select');\n    }\n    deselect() {\n        this.selected = false;\n        console.log('Deselect');\n    }\n}\nclass MyClass {\n    constructor() {}\n}\n\n// Extend MyClass to include the behavior of Identifiable and Selectable\ninterface MyClass extends Identifiable, Selectable {}\n\n// Function to apply mixins to a class\nfunction applyMixins(source: any, baseCtors: any[]) {\n    baseCtors.forEach(baseCtor => {\n        Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => {\n            let descriptor = Object.getOwnPropertyDescriptor(\n                baseCtor.prototype,\n                name\n            );\n            if (descriptor) {\n                Object.defineProperty(source.prototype, name, descriptor);\n            }\n        });\n    });\n}\n\n// Apply the mixins to MyClass\napplyMixins(MyClass, [Identifiable, Selectable]);\nlet o = new MyClass();\no.name = 'abc';\no.logId();\no.select();\n```\n\n### Asynkrona språkfunktioner\n\nEftersom TypeScript är en superset av JavaScript har det inbyggda asynkrona språkfunktioner från JavaScript som:\n\nPromises:\n\nPromises är ett sätt att hantera asynkrona operationer och deras resultat med hjälp av metoder som `.then()` och `.catch()` för att hantera framgångs- och feltillstånd.\n\nLäs mer: [https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)\n\nAsync/await:\n\nNyckelorden async/await erbjuder en mer synkront utseende syntax för att arbeta med Promises. Nyckelordet `async` används för att definiera en asynkron funktion, och nyckelordet `await` används inom en async-funktion för att pausa körningen tills ett Promise har lösts eller avvisats.\n\nLäs mer:\n[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function)\n[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await)\n\nFöljande API:er stöds väl i TypeScript:\n\nFetch API:\n[https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API)\n\nWeb Workers:\n[https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API)\n\nShared Workers:\n[https://developer.mozilla.org/en-US/docs/Web/API/SharedWorker](https://developer.mozilla.org/en-US/docs/Web/API/SharedWorker)\n\nWebSocket:\n[https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API)\n\n### Iteratorer och generatorer\n\nBåde iteratorer och generatorer stöds väl i TypeScript.\n\nIteratorer är objekt som implementerar iteratorprotokollet och erbjuder ett sätt att komma åt element i en samling eller sekvens ett i taget. Det är en struktur som innehåller en pekare till nästa element i iterationen. De har en `next()`-metod som returnerar nästa värde i sekvensen tillsammans med en boolean som anger om sekvensen är `done` (klar).\n\n```typescript\nclass NumberIterator implements Iterable<number> {\n    private current: number;\n\n    constructor(\n        private start: number,\n        private end: number\n    ) {\n        this.current = start;\n    }\n\n    public next(): IteratorResult<number> {\n        if (this.current <= this.end) {\n            const value = this.current;\n            this.current++;\n            return { value, done: false };\n        } else {\n            return { value: undefined, done: true };\n        }\n    }\n\n    [Symbol.iterator](): Iterator<number> {\n        return this;\n    }\n}\n\nconst iterator = new NumberIterator(1, 3);\n\nfor (const num of iterator) {\n    console.log(num);\n}\n```\n\nGeneratorer är speciella funktioner definierade med syntaxen `function*` som förenklar skapandet av iteratorer. De använder nyckelordet `yield` för att definiera sekvensen av värden och pausar och återupptar automatiskt körningen när värden efterfrågas.\n\nGeneratorer gör det enklare att skapa iteratorer och är särskilt användbara för att arbeta med stora eller oändliga sekvenser.\n\nExempel:\n\n```typescript\nfunction* numberGenerator(start: number, end: number): Generator<number> {\n    for (let i = start; i <= end; i++) {\n        yield i;\n    }\n}\n\nconst generator = numberGenerator(1, 5);\n\nfor (const num of generator) {\n    console.log(num);\n}\n```\n\nTypeScript stöder också asynkrona iteratorer och asynkrona generatorer.\n\nLäs mer:\n\n[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Generator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Generator)\n\n[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Iterator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Iterator)\n\n### TsDocs JSDoc-referens\n\nNär man arbetar med en JavaScript-kodbas är det möjligt att hjälpa TypeScript att härleda rätt typ genom att använda JSDoc-kommentarer med ytterligare annotationer för att ge typinformation.\n\nExempel:\n\n```typescript\n/**\n * Computes the power of a given number\n * @constructor\n * @param {number} base – The base value of the expression\n * @param {number} exponent – The exponent value of the expression\n */\nfunction power(base: number, exponent: number) {\n    return Math.pow(base, exponent);\n}\npower(10, 2); // function power(base: number, exponent: number): number\n```\n\nFullständig dokumentation finns på denna länk:\n[https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html](https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html)\n\nFrån version 3.7 är det möjligt att generera .d.ts-typdefinitioner från JavaScript JSDoc-syntax.\nMer information finns här:\n[https://www.typescriptlang.org/docs/handbook/declaration-files/dts-from-js.html](https://www.typescriptlang.org/docs/handbook/declaration-files/dts-from-js.html)\n\n### @types\n\nPaket under @types-organisationen är speciella paketnamnkonventioner som används för att tillhandahålla typdefinitioner för befintliga JavaScript-bibliotek eller moduler. Till exempel genom att använda:\n\n```shell\nnpm install --save-dev @types/lodash\n```\n\nInstalleras typdefinitionerna för `lodash` i ditt nuvarande projekt.\n\nFör att bidra till typdefinitionerna för @types-paket, skicka in en pull request till [https://github.com/DefinitelyTyped/DefinitelyTyped](https://github.com/DefinitelyTyped/DefinitelyTyped).\n\n### JSX\n\nJSX (JavaScript XML) är en utökning av JavaScript-språksyntaxen som låter dig skriva HTML-liknande kod i dina JavaScript- eller TypeScript-filer. Det används vanligtvis i React för att definiera HTML-strukturen.\n\nTypeScript utökar JSX:s kapacitet genom att tillhandahålla typkontroll och statisk analys.\n\nFör att använda JSX behöver du ställa in kompileringsalternativet `jsx` i din `tsconfig.json`-fil. Två vanliga konfigurationsalternativ:\n\n* \"preserve\": genererar .jsx-filer med JSX oförändrad. Detta alternativ talar om för TypeScript att behålla JSX-syntaxen som den är och inte transformera den under kompileringsprocessen. Du kan använda detta alternativ om du har ett separat verktyg, som Babel, som hanterar transformationen.\n* \"react\": aktiverar TypeScripts inbyggda JSX-transformation. React.createElement kommer att användas.\n\nAlla alternativ finns tillgängliga här:\n[https://www.typescriptlang.org/tsconfig#jsx](https://www.typescriptlang.org/tsconfig#jsx)\n\n### ES6-moduler\n\nTypeScript stöder ES6 (ECMAScript 2015) och många efterföljande versioner. Det innebär att du kan använda ES6-syntax, såsom pilfunktioner, mallsträngar, klasser, moduler, destrukturering och mer.\n\nFör att aktivera ES6-funktioner i ditt projekt kan du ange egenskapen `target` i tsconfig.json.\n\nEtt konfigurationsexempel:\n\n```json\n{\n  \"compilerOptions\": {\n    \"target\": \"es6\",\n    \"module\": \"es6\",\n    \"moduleResolution\": \"node\",\n    \"sourceMap\": true,\n    \"outDir\": \"dist\"\n  },\n  \"include\": [\"src\"]\n}\n```\n\n### ES7 exponentiationsoperator\n\nExponentiationsoperatorn (`**`) beräknar värdet som erhålls genom att upphöja den första operanden till den andra operandens potens. Den fungerar på liknande sätt som `Math.pow()`, men med den ytterligare förmågan att acceptera BigInts som operander.\nTypeScript stöder denna operator fullt ut genom att använda `es2016` eller en senare version som `target` i din tsconfig.json-fil.\n\n```typescript\nconsole.log(2 ** (2 ** 2)); // 16\n```\n\n### for-await-of-satsen\n\nDetta är en JavaScript-funktion som stöds fullt ut i TypeScript och som låter dig iterera över asynkrona iterbara objekt från målversion es2018.\n\n```typescript\nasync function* asyncNumbers(): AsyncIterableIterator<number> {\n    yield Promise.resolve(1);\n    yield Promise.resolve(2);\n    yield Promise.resolve(3);\n}\n\n(async () => {\n    for await (const num of asyncNumbers()) {\n        console.log(num);\n    }\n})();\n```\n\n### Metaegenskapen new.target\n\nDu kan i TypeScript använda metaegenskapen `new.target` som gör det möjligt att avgöra om en funktion eller konstruktor anropades med new-operatorn. Det låter dig upptäcka om ett objekt skapades som ett resultat av ett konstruktoranrop.\n\n```typescript\nclass Parent {\n    constructor() {\n        console.log(new.target); // Logs the constructor function used to create an instance\n    }\n}\n\nclass Child extends Parent {\n    constructor() {\n        super();\n    }\n}\n\nconst parentX = new Parent(); // [Function: Parent]\nconst child = new Child(); // [Function: Child]\n```\n\n### Dynamiska importuttryck\n\nDet är möjligt att villkorligt ladda moduler eller lat-ladda dem vid behov med hjälp av ECMAScript-förslaget för dynamisk import som stöds i TypeScript.\n\nSyntaxen för dynamiska importuttryck i TypeScript är följande:\n\n<!-- skip -->\n```typescript\nasync function renderWidget() {\n    const container = document.getElementById('widget');\n    if (container !== null) {\n        const widget = await import('./widget'); // Dynamic import\n        widget.render(container);\n    }\n}\n\nrenderWidget();\n```\n\n### \"tsc –watch\"\n\nDetta kommando startar TypeScript-kompilatorn med parametern `--watch`, med möjligheten att automatiskt kompilera om TypeScript-filer när de ändras.\n\n```shell\ntsc --watch\n```\n\nFrån och med TypeScript version 4.9 förlitar sig filövervakning främst på filsystemhändelser och faller automatiskt tillbaka till polling om en händelsebaserad övervakare inte kan upprättas.\n\n### Non-null Assertion Operator\n\nNon-null Assertion Operator (Postfix !) även kallad Definite Assignment Assertions är en TypeScript-funktion som låter dig försäkra att en variabel eller egenskap inte är null eller undefined, även om TypeScripts statiska typanalys antyder att den kan vara det. Med denna funktion är det möjligt att ta bort all explicit kontroll.\n\n```typescript\ntype Person = {\n    name: string;\n};\n\nconst printName = (person?: Person) => {\n    console.log(`Name is ${person!.name}`);\n};\n```\n\n### Standarddeklarationer\n\nStandarddeklarationer används när en variabel eller parameter tilldelas ett standardvärde. Det innebär att om inget värde anges för den variabeln eller parametern, kommer standardvärdet att användas istället.\n\n```typescript\nfunction greet(name: string = 'Anonymous'): void {\n    console.log(`Hello, ${name}!`);\n}\ngreet(); // Hello, Anonymous!\ngreet('John'); // Hello, John!\n```\n\n### Valfri kedjning (Optional Chaining)\n\nDen valfria kedjningsoperatorn `?.` fungerar som den vanliga punktoperatorn (`.`) för att komma åt egenskaper eller metoder. Den hanterar dock null- eller undefined-värden smidigt genom att avsluta uttrycket och returnera `undefined`, istället för att kasta ett fel.\n\n```typescript\ntype Person = {\n    name: string;\n    age?: number;\n    address?: {\n        street?: string;\n        city?: string;\n    };\n};\n\nconst person: Person = {\n    name: 'John',\n};\n\nconsole.log(person.address?.city); // undefined\n```\n\n### Nullish coalescing-operatorn\n\nNullish coalescing-operatorn `??` returnerar högerledet om vänsterledet är `null` eller `undefined`; annars returnerar den vänsterledets värde.\n\n```typescript\nconst foo = null ?? 'foo';\nconsole.log(foo); // foo\n\nconst baz = 1 ?? 'baz';\nconst baz2 = 0 ?? 'baz';\nconsole.log(baz); // 1\nconsole.log(baz2); // 0\n```\n\n### Mallsträngslitteraltyper (Template Literal Types)\n\nMallsträngslitteraltyper gör det möjligt att manipulera strängvärden på typnivå och generera nya strängtyper baserade på befintliga. De är användbara för att skapa mer uttrycksfulla och precisa typer från strängbaserade operationer.\n\n```typescript\ntype Department = 'engineering' | 'hr';\ntype Language = 'english' | 'spanish';\ntype Id = `${Department}-${Language}-id`; // \"engineering-english-id\" | \"engineering-spanish-id\" | \"hr-english-id\" | \"hr-spanish-id\"\n```\n\n### Funktionsöverlagring\n\nFunktionsöverlagring låter dig definiera flera funktionssignaturer för samma funktionsnamn, var och en med olika parametertyper och returtyp.\nNär du anropar en överlagrad funktion använder TypeScript de angivna argumenten för att avgöra rätt funktionssignatur:\n\n```typescript\nfunction makeGreeting(name: string): string;\nfunction makeGreeting(names: string[]): string[];\n\nfunction makeGreeting(person: unknown): unknown {\n    if (typeof person === 'string') {\n        return `Hi ${person}!`;\n    } else if (Array.isArray(person)) {\n        return person.map(name => `Hi, ${name}!`);\n    }\n    throw new Error('Unable to greet');\n}\n\nmakeGreeting('Simon');\nmakeGreeting(['Simone', 'John']);\n```\n\n### Rekursiva typer\n\nEn rekursiv typ är en typ som kan referera till sig själv. Detta är användbart för att definiera datastrukturer som har en hierarkisk eller rekursiv struktur (potentiellt oändlig nästning), såsom länkade listor, träd och grafer.\n\n```typescript\ntype ListNode<T> = {\n    data: T;\n    next: ListNode<T> | undefined;\n};\n```\n\n### Rekursiva villkorstyper\n\nDet är möjligt att definiera komplexa typrelationer med hjälp av logik och rekursion i TypeScript.\nLåt oss bryta ner det i enkla termer:\n\nVillkorstyper: låter dig definiera typer baserade på booleska villkor:\n\n```typescript\ntype CheckNumber<T> = T extends number ? 'Number' : 'Not a number';\ntype A = CheckNumber<123>; // 'Number'\ntype B = CheckNumber<'abc'>; // 'Not a number'\n```\n\nRekursion: innebär en typdefinition som refererar till sig själv inom sin egen definition:\n\n```typescript\ntype Json = string | number | boolean | null | Json[] | { [key: string]: Json };\n\nconst data: Json = {\n    prop1: true,\n    prop2: 'prop2',\n    prop3: {\n        prop4: [],\n    },\n};\n```\n\nRekursiva villkorstyper kombinerar både villkorslogik och rekursion. Det innebär att en typdefinition kan bero på sig själv genom villkorslogik, vilket skapar komplexa och flexibla typrelationer.\n\n```typescript\ntype Flatten<T> = T extends Array<infer U> ? Flatten<U> : T;\n\ntype NestedArray = [1, [2, [3, 4], 5], 6];\ntype FlattenedArray = Flatten<NestedArray>; // 2 | 3 | 4 | 5 | 1 | 6\n```\n\n### Stöd för ECMAScript-moduler i Node\n\nNode.js lade till stöd för ECMAScript-moduler från och med version 15.3.0, och TypeScript har haft stöd för ECMAScript-moduler i Node.js sedan version 4.7. Detta stöd kan aktiveras genom att använda egenskapen `module` med värdet `nodenext` i tsconfig.json-filen. Här är ett exempel:\n\n```json\n{\n  \"compilerOptions\": {\n    \"module\": \"nodenext\",\n    \"outDir\": \"./lib\",\n    \"declaration\": true\n  }\n}\n```\n\nNode.js stöder två filändelser för moduler: `.mjs` för ES-moduler och `.cjs` för CommonJS-moduler. Motsvarande filändelser i TypeScript är `.mts` för ES-moduler och `.cts` för CommonJS-moduler. När TypeScript-kompilatorn transpilerar dessa filer till JavaScript skapar den `.mjs`- och `.cjs`-filer.\n\nOm du vill använda ES-moduler i ditt projekt kan du ställa in egenskapen `type` till \"module\" i din package.json-fil. Detta instruerar Node.js att behandla projektet som ett ES-modulprojekt.\n\nDessutom stöder TypeScript även typdeklarationer i .d.ts-filer. Dessa deklarationsfiler tillhandahåller typinformation för bibliotek eller moduler skrivna i TypeScript, vilket låter andra utvecklare använda dem med TypeScripts typkontroll och autokompletteringsfunktioner.\n\n### Assertionsfunktioner\n\nI TypeScript är assertionsfunktioner funktioner som indikerar verifieringen av ett specifikt villkor baserat på sitt returvärde. I sin enklaste form undersöker en assert-funktion ett givet predikat och kastar ett fel när predikatet utvärderas till false.\n\n```typescript\nfunction isNumber(value: unknown): asserts value is number {\n    if (typeof value !== 'number') {\n        throw new Error('Not a number');\n    }\n}\n```\n\nDe kan också deklareras som funktionsuttryck:\n\n```typescript\ntype AssertIsNumber = (value: unknown) => asserts value is number;\nconst isNumber: AssertIsNumber = value => {\n    if (typeof value !== 'number') {\n        throw new Error('Not a number');\n    }\n};\n```\n\nAssertionsfunktioner delar likheter med typskydd (type guards). Typskydd introducerades ursprungligen för att utföra körtidskontroller och säkerställa typen av ett värde inom ett specifikt scope.\nSpecifikt är ett typskydd en funktion som utvärderar ett typpredikat och returnerar ett booleskt värde som anger om predikatet är sant eller falskt. Detta skiljer sig något från assertionsfunktioner, där avsikten är att kasta ett fel snarare än att returnera false när predikatet inte uppfylls.\n\nExempel på typskydd:\n\n```typescript\nconst isNumber = (value: unknown): value is number => typeof value === 'number';\n```\n\n### Variadiska tuppeltyper\n\nVariadiska tuppeltyper är en funktion som introducerades i TypeScript version 4.0. Låt oss börja med att repetera vad en tuppel är:\n\nEn tuppeltyp är en array som har en definierad längd, och där typen av varje element är känd:\n\n```typescript\ntype Student = [string, number];\nconst [name, age]: Student = ['Simone', 20];\n```\n\nTermen \"variadisk\" betyder obestämd aritet (accepterar ett variabelt antal argument).\n\nEn variadisk tuppel är en tuppeltyp som har alla egenskaper som ovan men vars exakta form ännu inte är definierad:\n\n```typescript\ntype Bar<T extends unknown[]> = [boolean, ...T, number];\n\ntype A = Bar<[boolean]>; // [boolean, boolean, number]\ntype B = Bar<['a', 'b']>; // [boolean, 'a', 'b', number]\ntype C = Bar<[]>; // [boolean, number]\n```\n\nI den föregående koden kan vi se att tuppelns form definieras av den generiska typen `T` som skickas in.\n\nVariadiska tuppler kan acceptera flera generiska typer vilket gör dem mycket flexibla:\n\n```typescript\ntype Bar<T extends unknown[], G extends unknown[]> = [...T, boolean, ...G];\n\ntype A = Bar<[number], [string]>; // [number, boolean, string]\ntype B = Bar<['a', 'b'], [boolean]>; // [\"a\", \"b\", boolean, boolean]\n```\n\nMed de nya variadiska tupplerna kan vi använda:\n\n* Spridningar i tuppeltypssyntax kan nu vara generiska, så vi kan representera högre ordningens operationer på tuppler och arrayer även när vi inte känner till de faktiska typerna vi opererar på.\n* Restelement kan förekomma var som helst i en tuppel.\n\nExempel:\n\n```typescript\ntype Items = readonly unknown[];\n\nfunction concat<T extends Items, U extends Items>(\n    arr1: T,\n    arr2: U\n): [...T, ...U] {\n    return [...arr1, ...arr2];\n}\n\nconcat([1, 2, 3], ['4', '5', '6']); // [1, 2, 3, \"4\", \"5\", \"6\"]\n```\n\n### Inkapslingstyper (Boxed types)\n\nInkapslingstyper refererar till omslagsobjekten som används för att representera primitiva typer som objekt. Dessa omslagsobjekt tillhandahåller ytterligare funktionalitet och metoder som inte är direkt tillgängliga på de primitiva värdena.\n\nNär du anropar en metod som `charAt` eller `normalize` på en primitiv `string`, omsluter JavaScript den i ett `String`-objekt, anropar metoden och kastar sedan bort objektet.\n\nDemonstration:\n\n```typescript\nconst originalNormalize = String.prototype.normalize;\nString.prototype.normalize = function () {\n    console.log(this, typeof this);\n    return originalNormalize.call(this);\n};\nconsole.log('\\u0041'.normalize());\n```\n\nTypeScript representerar denna skillnad genom att tillhandahålla separata typer för primitiverna och deras motsvarande objektomslag:\n\n* string => String\n* number => Number\n* boolean => Boolean\n* symbol => Symbol\n* bigint => BigInt\n\nInkapslingstyperna behövs vanligtvis inte. Undvik att använda inkapslingstyper och använd istället typer för primitiverna, till exempel `string` istället för `String`.\n\n### Kovarians och kontravarians i TypeScript\n\nKovarians och kontravarians används för att beskriva hur relationer fungerar vid hantering av arv eller tilldelning av typer.\n\nKovarians innebär att en typrelation bevarar riktningen för arv eller tilldelning, så om en typ A är en subtyp av typ B, anses också en array av typ A vara en subtyp av en array av typ B. Det viktiga att notera här är att subtyprelationen bibehålls, vilket innebär att kovarians accepterar subtyper men inte accepterar supertyper.\n\nKontravarians innebär att en typrelation vänder riktningen för arv eller tilldelning, så om en typ A är en subtyp av typ B, anses en array av typ B vara en subtyp av en array av typ A. Subtyprelationen är omvänd, vilket innebär att kontravarians accepterar supertyper men inte accepterar subtyper.\n\nNotera: Bivarians innebär att både supertyper och subtyper accepteras.\n\nExempel: Låt oss säga att vi har ett utrymme för alla djur och ett separat utrymme bara för hundar.\n\nVid kovarians kan du placera alla hundar i djurutrymmet eftersom hundar är en typ av djur. Men du kan inte placera alla djur i hundutrymmet eftersom det kan finnas andra djur inblandade.\n\nVid kontravarians kan du inte placera alla djur i hundutrymmet eftersom djurutrymmet kan innehålla andra djur också. Däremot kan du placera alla hundar i djurutrymmet eftersom alla hundar också är djur.\n\n<!-- skip -->\n```typescript\n// Covariance example\nclass Animal {\n    name: string;\n    constructor(name: string) {\n        this.name = name;\n    }\n}\n\nclass Dog extends Animal {\n    breed: string;\n    constructor(name: string, breed: string) {\n        super(name);\n        this.breed = breed;\n    }\n}\n\nlet animals: Animal[] = [];\nlet dogs: Dog[] = [];\n\n// Covariance allows assigning subtype (Dog) array to supertype (Animal) array\nanimals = dogs;\ndogs = animals; // Invalid: Type 'Animal[]' is not assignable to type 'Dog[]'\n\n// Contravariance example\ntype Feed<in T> = (animal: T) => void;\n\nlet feedAnimal: Feed<Animal> = (animal: Animal) => {\n    console.log(`Animal name: ${animal.name}`);\n};\n\nlet feedDog: Feed<Dog> = (dog: Dog) => {\n    console.log(`Dog name: ${dog.name}, Breed: ${dog.breed}`);\n};\n\n// Contravariance allows assigning supertype (Animal) callback to subtype (Dog) callback\nfeedDog = feedAnimal;\nfeedAnimal = feedDog; // Invalid: Type 'Feed<Dog>' is not assignable to type 'Feed<Animal>'.\n```\n\nI TypeScript är typrelationer för arrayer kovarianta, medan typrelationer för funktionsparametrar är kontravarianta. Det innebär att TypeScript uppvisar både kovarians och kontravarians beroende på sammanhanget.\n\n#### Valfria variansannotationer för typparametrar\n\nFrån och med TypeScript 4.7.0 kan vi använda nyckelorden `out` och `in` för att vara specifika med variansannotationer.\n\nFör kovarians, använd nyckelordet `out`:\n\n```typescript\ntype AnimalCallback<out T> = () => T; // T is Covariant here\n```\n\nOch för kontravarians, använd nyckelordet `in`:\n\n```typescript\ntype AnimalCallback<in T> = (value: T) => void; // T is Contravariance here\n```\n\n### Mallsträngsmönsterindexsignaturer\n\nMallsträngsmönsterindexsignaturer gör det möjligt att definiera flexibla indexsignaturer med hjälp av mallsträngsmönster. Denna funktion gör det möjligt att skapa objekt som kan indexeras med specifika mönster av strängnycklar, vilket ger mer kontroll och specificitet vid åtkomst och manipulering av egenskaper.\n\nTypeScript tillåter från version 4.4 indexsignaturer för symboler och mallsträngsmönster.\n\n```typescript\nconst uniqueSymbol = Symbol('description');\n\ntype MyKeys = `key-${string}`;\n\ntype MyObject = {\n    [uniqueSymbol]: string;\n    [key: MyKeys]: number;\n};\n\nconst obj: MyObject = {\n    [uniqueSymbol]: 'Unique symbol key',\n    'key-a': 123,\n    'key-b': 456,\n};\n\nconsole.log(obj[uniqueSymbol]); // Unique symbol key\nconsole.log(obj['key-a']); // 123\nconsole.log(obj['key-b']); // 456\n```\n\n### satisfies-operatorn\n\nOperatorn `satisfies` låter dig kontrollera om en given typ uppfyller ett specifikt gränssnitt eller villkor. Med andra ord säkerställer den att en typ har alla nödvändiga egenskaper och metoder för ett specifikt gränssnitt. Det är ett sätt att säkerställa att en variabel passar in i en typdefinition.\nHär är ett exempel:\n\n<!-- skip -->\n```typescript\ntype Columns = 'name' | 'nickName' | 'attributes';\n\ntype User = Record<Columns, string | string[] | undefined>;\n\n// Type Annotation using `User`\nconst user: User = {\n    name: 'Simone',\n    nickName: undefined,\n    attributes: ['dev', 'admin'],\n};\n\n// In the following lines, TypeScript won't be able to infer properly\nuser.attributes?.map(console.log); // Property 'map' does not exist on type 'string | string[]'. Property 'map' does not exist on type 'string'.\nuser.nickName; // string | string[] | undefined\n\n// Type assertion using `as`\nconst user2 = {\n    name: 'Simon',\n    nickName: undefined,\n    attributes: ['dev', 'admin'],\n} as User;\n\n// Here too, TypeScript won't be able to infer properly\nuser2.attributes?.map(console.log); // Property 'map' does not exist on type 'string | string[]'. Property 'map' does not exist on type 'string'.\nuser2.nickName; // string | string[] | undefined\n\n// Using `satisfies` operators we can properly infer the types now\nconst user3 = {\n    name: 'Simon',\n    nickName: undefined,\n    attributes: ['dev', 'admin'],\n} satisfies User;\n\nuser3.attributes?.map(console.log); // TypeScript infers correctly: string[]\nuser3.nickName; // TypeScript infers correctly: undefined\n```\n\n### Importer och exporter av enbart typer\n\nImporter och exporter av enbart typer låter dig importera eller exportera typer utan att importera eller exportera de värden eller funktioner som är associerade med dessa typer. Detta kan vara användbart för att minska storleken på ditt paket.\n\nFör att använda importer av enbart typer kan du använda nyckelordet `import type`.\n\nTypeScript tillåter användning av både deklarations- och implementationsfiländelser (.ts, .mts, .cts och .tsx) i importer av enbart typer, oavsett inställningarna för `allowImportingTsExtensions`.\n\nTill exempel:\n\n<!-- skip -->\n```typescript\nimport type { House } from './house.ts';\n```\n\nFöljande former stöds:\n\n<!-- skip -->\n```typescript\nimport type T from './mod';\nimport type { A, B } from './mod';\nimport type * as Types from './mod';\nexport type { T };\nexport type { T } from './mod';\n```\n\n### using-deklaration och explicit resurshantering\n\nEn `using`-deklaration är en blockomfattande, oföränderlig bindning, liknande `const`, som används för att hantera disponibla resurser. När den initialiseras med ett värde registreras värdets `Symbol.dispose`-metod och körs sedan vid utgång ur det omslutande blockomfånget.\n\nDetta baseras på ECMAScripts resurshanteringsfunktion, som är användbar för att utföra väsentliga uppstädningsuppgifter efter objektskapande, såsom att stänga anslutningar, radera filer och frigöra minne.\n\nNoteringar:\n\n* På grund av dess nyliga introduktion i TypeScript version 5.2 saknar de flesta körmiljöer inbyggt stöd. Du behöver polyfills för: `Symbol.dispose`, `Symbol.asyncDispose`, `DisposableStack`, `AsyncDisposableStack`, `SuppressedError`.\n* Dessutom behöver du konfigurera din tsconfig.json enligt följande:\n\n```json\n{\n    \"compilerOptions\": {\n        \"target\": \"es2022\",\n        \"lib\": [\"es2022\", \"esnext.disposable\", \"dom\"]\n    }\n}\n```\n\nExempel:\n\n<!-- skip -->\n```typescript\n//@ts-ignore\nSymbol.dispose ??= Symbol('Symbol.dispose'); // Simple polify\n\nconst doWork = (): Disposable => {\n    return {\n        [Symbol.dispose]: () => {\n            console.log('disposed');\n        },\n    };\n};\n\nconsole.log(1);\n\n{\n    using work = doWork(); // Resource is declared\n    console.log(2);\n} // Resource is disposed (e.g., `work[Symbol.dispose]()` is evaluated)\n\nconsole.log(3);\n```\n\nKoden loggar:\n\n```shell\n1\n2\ndisposed\n3\n```\n\nEn resurs som kan disponeras måste följa `Disposable`-gränssnittet:\n\n```typescript\n// lib.esnext.disposable.d.ts\ninterface Disposable {\n    [Symbol.dispose](): void;\n}\n```\n\n`using`-deklarationer registrerar resursavyttringsoperationer i en stack, vilket säkerställer att de disponeras i omvänd ordning mot deklarationen:\n\n<!-- skip -->\n```typescript\n{\n    using j = getA(),\n        y = getB();\n    using k = getC();\n} // disposes `C`, then `B`, then `A`.\n```\n\nResurser garanteras att disponeras, även om efterföljande kod eller undantag uppstår. Detta kan leda till att avyttringen potentiellt kastar ett undantag, som eventuellt undertrycker ett annat. För att behålla information om undertryckta fel introduceras ett nytt inbyggt undantag, `SuppressedError`.\n\n#### await using-deklaration\n\nEn `await using`-deklaration hanterar en asynkront disponibel resurs. Värdet måste ha en `Symbol.asyncDispose`-metod, som kommer att inväntas vid blockets slut.\n\n<!-- skip -->\n```typescript\nasync function doWorkAsync() {\n    await using work = doWorkAsync(); // Resource is declared\n} // Resource is disposed (e.g., `await work[Symbol.asyncDispose]()` is evaluated)\n```\n\nFör en asynkront disponibel resurs måste den följa antingen `Disposable`- eller `AsyncDisposable`-gränssnittet:\n\n```typescript\n// lib.esnext.disposable.d.ts\ninterface AsyncDisposable {\n    [Symbol.asyncDispose](): Promise<void>;\n}\n```\n\n<!-- skip -->\n```typescript\n//@ts-ignore\nSymbol.asyncDispose ??= Symbol('Symbol.asyncDispose'); // Simple polify\n\nclass DatabaseConnection implements AsyncDisposable {\n    // A method that is called when the object is disposed asynchronously\n    [Symbol.asyncDispose]() {\n        // Close the connection and return a promise\n        return this.close();\n    }\n\n    async close() {\n        console.log('Closing the connection...');\n        await new Promise(resolve => setTimeout(resolve, 1000));\n        console.log('Connection closed.');\n    }\n}\n\nasync function doWork() {\n    // Create a new connection and dispose it asynchronously when it goes out of scope\n    await using connection = new DatabaseConnection(); //  Resource is declared\n    console.log('Doing some work...');\n} // Resource is disposed (e.g., `await connection[Symbol.asyncDispose]()` is evaluated)\n\ndoWork();\n```\n\nKoden loggar:\n\n```shell\nDoing some work...\nClosing the connection...\nConnection closed.\n```\n\nDeklarationerna `using` och `await using` är tillåtna i följande satser: `for`, `for-in`, `for-of`, `for-await-of`, `switch`.\n\n### Importattribut\n\nTypeScript 5.3:s importattribut (etiketter för importer) talar om för körmiljön hur moduler (JSON, etc.) ska hanteras. Detta förbättrar säkerheten genom att säkerställa tydliga importer och överensstämmer med Content Security Policy (CSP) för säkrare resursladdning. TypeScript säkerställer att de är giltiga men låter körmiljön hantera deras tolkning för specifik modulhantering.\n\nExempel:\n\n<!-- skip -->\n```typescript\nimport config from './config.json' with { type: 'json' };\n```\n\nmed dynamisk import:\n\n<!-- skip -->\n```typescript\nconst config = import('./config.json', { with: { type: 'json' } });\n```\n"
  },
  {
    "path": "website/src/content/docs/sv-se/book/overloads.md",
    "content": "---\ntitle: Överlagringar\nsidebar:\n  order: 51\n  label: 51. Överlagringar\n---\n\n\nFunktionsöverlagringar i TypeScript låter dig definiera flera funktionssignaturer för ett enda funktionsnamn, vilket gör det möjligt att definiera funktioner som kan anropas på flera sätt. Här är ett exempel:\n\n```typescript\n// Overloads\nfunction sayHi(name: string): string;\nfunction sayHi(names: string[]): string[];\n\n// Implementation\nfunction sayHi(name: unknown): unknown {\n    if (typeof name === 'string') {\n        return `Hi, ${name}!`;\n    } else if (Array.isArray(name)) {\n        return name.map(name => `Hi, ${name}!`);\n    }\n    throw new Error('Invalid value');\n}\n\nsayHi('xx'); // Valid\nsayHi(['aa', 'bb']); // Valid\n```\n\nHär är ytterligare ett exempel på användning av funktionsöverlagringar inom en `class`:\n\n```typescript\nclass Greeter {\n    message: string;\n\n    constructor(message: string) {\n        this.message = message;\n    }\n\n    // overload\n    sayHi(name: string): string;\n    sayHi(names: string[]): ReadonlyArray<string>;\n\n    // implementation\n    sayHi(name: unknown): unknown {\n        if (typeof name === 'string') {\n            return `${this.message}, ${name}!`;\n        } else if (Array.isArray(name)) {\n            return name.map(name => `${this.message}, ${name}!`);\n        }\n        throw new Error('value is invalid');\n    }\n}\nconsole.log(new Greeter('Hello').sayHi('Simon'));\n```\n\n"
  },
  {
    "path": "website/src/content/docs/sv-se/book/predefined-conditional-types.md",
    "content": "---\ntitle: Fördefinierade villkorliga typer\nsidebar:\n  order: 42\n  label: 42. Fördefinierade villkorliga typer\n---\n\n\nI TypeScript är fördefinierade villkorliga typer inbyggda villkorliga typer som tillhandahålls av språket. De är utformade för att utföra vanliga typtransformationer baserade på egenskaperna hos en given typ.\n\n`Exclude<UnionType, ExcludedType>`: Denna typ tar bort alla typer från Type som kan tilldelas till ExcludedType.\n\n`Extract<Type, Union>`: Denna typ extraherar alla typer från Union som kan tilldelas till Type.\n\n`NonNullable<Type>`: Denna typ tar bort null och undefined från Type.\n\n`ReturnType<Type>`: Denna typ extraherar returtypen av en funktionstyp Type.\n\n`Parameters<Type>`: Denna typ extraherar parametertyperna av en funktionstyp Type.\n\n`Required<Type>`: Denna typ gör alla egenskaper i Type obligatoriska.\n\n`Partial<Type>`: Denna typ gör alla egenskaper i Type valfria.\n\n`Readonly<Type>`: Denna typ gör alla egenskaper i Type skrivskyddade.\n\n"
  },
  {
    "path": "website/src/content/docs/sv-se/book/primitive-types.md",
    "content": "---\ntitle: Primitiva typer\nsidebar:\n  order: 10\n  label: 10. Primitiva typer\n---\n\n\nTypeScript stöder 7 primitiva typer. En primitiv datatyp avser en typ som inte är ett objekt och som inte har några metoder kopplade till sig. I TypeScript är alla primitiva typer oföränderliga, vilket innebär att deras värden inte kan ändras efter att de har tilldelats.\n\n### string\n\nDen primitiva typen `string` lagrar textdata, och värdet omges alltid av dubbla eller enkla citattecken.\n\n```typescript\nconst x: string = 'x';\nconst y: string = 'y';\n```\n\nSträngar kan sträcka sig över flera rader om de omges av backtick-tecknet (`):\n\n```typescript\nlet sentence: string = `xxx,\n   yyy`;\n```\n\n### boolean\n\nDatatypen `boolean` i TypeScript lagrar ett binärt värde, antingen `true` eller `false`.\n\n```typescript\nconst isReady: boolean = true;\n```\n\n### number\n\nEn `number`-datatyp i TypeScript representeras med ett 64-bitars flyttalsvärde. En `number`-typ kan representera heltal och bråktal.\nTypeScript stöder även hexadecimala, binära och oktala tal, till exempel:\n\n```typescript\nconst decimal: number = 10;\nconst hexadecimal: number = 0xa00d; // Hexadecimal starts with 0x\nconst binary: number = 0b1010; // Binary starts with 0b\nconst octal: number = 0o633; // Octal starts with 0o\n```\n\n### bigInt\n\nEn `bigInt` representerar numeriska värden som är mycket stora (253 – 1) och inte kan representeras med en `number`.\n\nEn `bigInt` kan skapas genom att anropa den inbyggda funktionen `BigInt()` eller genom att lägga till `n` i slutet av ett heltalsliteral:\n\n```typescript\nconst x: bigint = BigInt(9007199254740991);\nconst y: bigint = 9007199254740991n;\n```\n\nNoteringar:\n\n* `bigInt`-värden kan inte blandas med `number` och kan inte användas med inbyggd `Math`, de måste konverteras till samma typ.\n* `bigInt`-värden är bara tillgängliga om målkonfigurationen är ES2020 eller högre.\n\n### Symbol\n\nSymboler är unika identifierare som kan användas som egenskapsnycklar i objekt för att förhindra namnkonflikter.\n\n```typescript\ntype Obj = {\n    [sym: symbol]: number;\n};\n\nconst a = Symbol('a');\nconst b = Symbol('b');\nlet obj: Obj = {};\nobj[a] = 123;\nobj[b] = 456;\n\nconsole.log(obj[a]); // 123\nconsole.log(obj[b]); // 456\n```\n\n### null och undefined\n\n`null` och `undefined`-typerna representerar båda inget värde eller frånvaron av något värde.\n\nTypen `undefined` betyder att värdet inte är tilldelat eller initierat och indikerar en oavsiktlig frånvaro av värde.\n\nTypen `null` betyder att vi vet att fältet inte har något värde, alltså är värdet otillgängligt, och det indikerar en avsiktlig frånvaro av värde.\n\n### Array\n\nEn `array` är en datatyp som kan lagra flera värden av samma typ eller inte. Den kan definieras med följande syntax:\n\n```typescript\nconst x: string[] = ['a', 'b'];\nconst y: Array<string> = ['a', 'b'];\nconst j: Array<string | number> = ['a', 1, 'b', 2]; // Union\n```\n\nTypeScript stöder skrivskyddade arrayer med följande syntax:\n\n<!-- skip -->\n```typescript\nconst x: readonly string[] = ['a', 'b']; // Readonly modifier\nconst y: ReadonlyArray<string> = ['a', 'b'];\nconst j: ReadonlyArray<string | number> = ['a', 1, 'b', 2];\nj.push('x'); // Invalid\n```\n\nTypeScript stöder tupler och skrivskyddade tupler:\n\n```typescript\nconst x: [string, number] = ['a', 1];\nconst y: readonly [string, number] = ['a', 1];\n```\n\n### any\n\nDatatypen `any` representerar bokstavligen \"vilket som helst\" värde, det är standardvärdet när TypeScript inte kan härleda typen eller den inte är specificerad.\n\nNär `any` används hoppar TypeScript-kompilatorn över typkontrollen, så det finns ingen typsäkerhet när `any` används. Använd i allmänhet inte `any` för att tysta kompilatorn när ett fel uppstår, fokusera istället på att åtgärda felet eftersom det med `any` är möjligt att bryta kontrakt och vi förlorar fördelarna med TypeScripts autokomplettering.\n\nTypen `any` kan vara användbar vid en gradvis migrering från JavaScript till TypeScript, eftersom den kan tysta kompilatorn.\n\nFör nya projekt, använd TypeScript-konfigurationen `noImplicitAny` som gör att TypeScript ger fel där `any` används eller härleds.\n\nTypen `any` är vanligtvis en källa till fel som kan dölja verkliga problem med dina typer. Undvik att använda den så mycket som möjligt.\n\n"
  },
  {
    "path": "website/src/content/docs/sv-se/book/readonly-properties.md",
    "content": "---\ntitle: Skrivskyddade egenskaper\nsidebar:\n  order: 13\n  label: 13. Skrivskyddade egenskaper\n---\n\n\nDet är möjligt att förhindra skrivning till en egenskap genom att använda modifieraren `readonly` som ser till att egenskapen inte kan skrivas om, men den ger ingen garanti för total oföränderlighet:\n\n```typescript\ninterface Y {\n    readonly a: number;\n}\n\ntype X = {\n    readonly a: number;\n};\n\ntype J = Readonly<{\n    a: number;\n}>;\n\ntype K = {\n    readonly [index: number]: string;\n};\n```\n\n"
  },
  {
    "path": "website/src/content/docs/sv-se/book/strictnullchecks.md",
    "content": "---\ntitle: strictNullChecks\nsidebar:\n  order: 18\n  label: 18. strictNullChecks\n---\n\n\n`strictNullChecks` är ett TypeScript-kompilatoralternativ som framtvingar strikt null-kontroll. När detta alternativ är aktiverat kan variabler och parametrar bara tilldelas `null` eller `undefined` om de uttryckligen har deklarerats att vara av den typen med hjälp av unionstypen `null` | `undefined`. Om en variabel eller parameter inte uttryckligen deklareras som nullable kommer TypeScript att generera ett fel för att förhindra potentiella körtidsfel.\n\n"
  },
  {
    "path": "website/src/content/docs/sv-se/book/symbols.md",
    "content": "---\ntitle: Symboler\nsidebar:\n  order: 58\n  label: 58. Symboler\n---\n\n\nSymboler är en primitiv datatyp som representerar ett oföränderligt värde som garanterat är globalt unikt under hela programmets livstid.\n\nSymboler kan användas som nycklar för objektegenskaper och ger ett sätt att skapa icke-uppräkningsbara egenskaper.\n\n```typescript\nconst key1: symbol = Symbol('key1');\nconst key2: symbol = Symbol('key2');\n\nconst obj = {\n    [key1]: 'value 1',\n    [key2]: 'value 2',\n};\n\nconsole.log(obj[key1]); // value 1\nconsole.log(obj[key2]); // value 2\n```\n\nI WeakMaps och WeakSets är symboler nu tillåtna som nycklar.\n\n"
  },
  {
    "path": "website/src/content/docs/sv-se/book/table-of-contents.md",
    "content": "---\ntitle: Innehållsförteckning\nsidebar:\n  order: 4\n  label: 4. Innehållsförteckning\n---\n\n\n<!-- markdownlint-disable MD004 -->\n- Den koncisa TypeScript-boken\n  - Översättningar\n  - Nedladdningar och webbplats\n  - Innehållsförteckning\n  - Introduktion\n  - Om författaren\n  - Introduktion till TypeScript\n    - Vad är TypeScript?\n    - Varför TypeScript?\n    - TypeScript och JavaScript\n    - TypeScript-kodgenerering\n    - Modernt JavaScript nu (Downleveling)\n  - Komma igång med TypeScript\n    - Installation\n    - Konfiguration\n    - TypeScript-konfigurationsfil\n      - target\n      - lib\n      - strict\n      - module\n      - moduleResolution\n      - esModuleInterop\n      - jsx\n      - skipLibCheck\n      - files\n      - include\n      - exclude\n    - importHelpers\n    - Råd vid migrering till TypeScript\n  - Utforska typsystemet\n    - TypeScript-språktjänsten\n    - Strukturell typning\n    - Grundläggande jämförelseregler i TypeScript\n    - Typer som mängder\n    - Tilldela en typ: Typdeklarationer och typpåståenden\n      - Typdeklaration\n      - Typpåstående\n      - Omgivande deklarationer\n    - Egenskapskontroll och kontroll av överskottsegenskaper\n    - Svaga typer\n    - Strikt kontroll av objektliteraler (Freshness)\n    - Typinferens\n    - Mer avancerade inferenser\n    - Typbreddning\n    - Const\n      - Const-modifierare på typparametrar\n      - Const-påstående\n    - Explicit typannotering\n    - Typavsmalnande\n      - Villkor\n      - Kasta eller returnera\n      - Diskriminerad union\n      - Användardefinierade typvakter\n  - Primitiva typer\n    - string\n    - boolean\n    - number\n    - bigInt\n    - Symbol\n    - null och undefined\n    - Array\n    - any\n  - Typannoteringar\n  - Valfria egenskaper\n  - Skrivskyddade egenskaper\n  - Indexsignaturer\n  - Utöka typer\n  - Literaltyper\n  - Literalhärledning\n  - strictNullChecks\n  - Enums\n    - Numeriska enums\n    - Sträng-enums\n    - Konstanta enums\n    - Omvänd mappning\n    - Omgivande enums\n    - Beräknade och konstanta medlemmar\n  - Avsmalning\n    - typeof-typvakter\n    - Sanningsvärdesavsmalning\n    - Likhetsavsmalning\n    - In-operatoravsmalning\n    - instanceof-avsmalning\n  - Tilldelningar\n  - Kontrollflödesanalys\n  - Typpredikat\n  - Diskriminerade unioner\n  - Never-typen\n  - Uttömmande kontroll\n  - Objekttyper\n  - Tuppeltyp (Anonym)\n  - Namngiven tuppeltyp (Märkt)\n  - Tuppel med fast längd\n  - Unionstyp\n  - Intersektionstyper\n  - Typindexering\n  - Typ från värde\n  - Typ från funktionsreturvärde\n  - Typ från modul\n  - Mappade typer\n  - Modifierare för mappade typer\n  - Villkorliga typer\n  - Distributiva villkorliga typer\n  - infer-typinferens i villkorliga typer\n  - Fördefinierade villkorliga typer\n  - Mall-unionstyper\n  - Any-typen\n  - Unknown-typen\n  - Void-typen\n  - Never-typen\n  - Användning av Never-typen\n  - Interface och Type\n    - Gemensam syntax\n    - Grundläggande typer\n    - Objekt och Interface\n    - Union- och Intersection-typer\n  - Inbyggda primitiva typer\n  - Vanliga inbyggda JS-objekt\n  - Överlagringar\n  - Sammanslagning och utökning\n  - Skillnader mellan Type och Interface\n  - Klass\n    - Vanlig klasssyntax\n    - Konstruktor\n    - Privata och skyddade konstruktorer\n    - Åtkomstmodifierare\n    - Get och Set\n    - Auto-accessorer i klasser\n    - this\n    - Parameteregenskaper\n    - Abstrakta klasser\n    - Med generics\n    - Dekoratörer\n      - Klassdekoratörer\n      - Egenskapsdekoratör\n      - Metoddekoratör\n      - Getter- och setter-dekoratörer\n      - Dekoratörmetadata\n    - Arv\n    - Statiska medlemmar\n    - Egenskapsinitiering\n    - Metodöverlagring\n  - Generics\n    - Generisk typ\n    - Generiska klasser\n    - Generiska begränsningar\n    - Generisk kontextuell avsmalning\n  - Raderade strukturella typer\n  - Namnrymder\n  - Symboler\n  - Trippelsnedstreck-direktiv\n  - Typmanipulation\n    - Skapa typer från typer\n    - Indexerade åtkomsttyper\n    - Verktygstyper\n      - Awaited\\<T\\>\n      - Partial\\<T\\>\n      - Required\\<T\\>\n      - Readonly\\<T\\>\n      - Record\\<K, T\\>\n      - Pick\\<T, K\\>\n      - Omit\\<T, K\\>\n      - Exclude\\<T, U\\>\n      - Extract\\<T, U\\>\n      - NonNullable\\<T\\>\n      - Parameters\\<T\\>\n      - ConstructorParameters\\<T\\>\n      - ReturnType\\<T\\>\n      - InstanceType\\<T\\>\n      - ThisParameterType\\<T\\>\n      - OmitThisParameter\\<T\\>\n      - ThisType\\<T\\>\n      - Uppercase\\<T\\>\n      - Lowercase\\<T\\>\n      - Capitalize\\<T\\>\n      - Uncapitalize\\<T\\>\n      - NoInfer\\<T\\>\n  - Övrigt\n    - Fel och undantagshantering\n    - Mixin-klasser\n    - Asynkrona språkfunktioner\n    - Iteratorer och generatorer\n    - TsDocs JSDoc-referens\n    - @types\n    - JSX\n    - ES6-moduler\n    - ES7 exponentiationsoperator\n    - for-await-of-satsen\n    - Metaegenskapen new.target\n    - Dynamiska importuttryck\n    - \"tsc –watch\"\n    - Non-null Assertion Operator\n    - Standarddeklarationer\n    - Valfri kedjning (Optional Chaining)\n    - Nullish coalescing-operatorn\n    - Mallsträngslitteraltyper (Template Literal Types)\n    - Funktionsöverlagring\n    - Rekursiva typer\n    - Rekursiva villkorstyper\n    - Stöd för ECMAScript-moduler i Node\n    - Assertionsfunktioner\n    - Variadiska tuppeltyper\n    - Inkapslingstyper (Boxed types)\n    - Kovarians och kontravarians i TypeScript\n      - Valfria variansannotationer för typparametrar\n    - Mallsträngsmönsterindexsignaturer\n    - satisfies-operatorn\n    - Importer och exporter av enbart typer\n    - using-deklaration och explicit resurshantering\n      - await using-deklaration\n    - Importattribut\n<!-- markdownlint-enable MD004 -->\n\n"
  },
  {
    "path": "website/src/content/docs/sv-se/book/template-union-types.md",
    "content": "---\ntitle: Mall-unionstyper\nsidebar:\n  order: 43\n  label: 43. Mall-unionstyper\n---\n\n\nMall-unionstyper kan användas för att slå samman och manipulera text inuti typsystemet, till exempel:\n\n```typescript\ntype Status = 'active' | 'inactive';\ntype Products = 'p1' | 'p2';\ntype ProductId = `id-${Products}-${Status}`; // \"id-p1-active\" | \"id-p1-inactive\" | \"id-p2-active\" | \"id-p2-inactive\"\n```\n\n"
  },
  {
    "path": "website/src/content/docs/sv-se/book/the-concise-typescript-book.md",
    "content": "---\ntitle: Den koncisa TypeScript-boken\nsidebar:\n  order: 1\n  label: 1. Den koncisa TypeScript-boken\n---\n\n\nDen koncisa TypeScript-boken ger en omfattande och kortfattad översikt över TypeScripts kapaciteter. Den erbjuder tydliga förklaringar som täcker alla aspekter i den senaste versionen av språket, från dess kraftfulla typsystem till avancerade funktioner. Oavsett om du är nybörjare eller en erfaren utvecklare är denna bok en ovärderlig resurs för att förbättra din förståelse och skicklighet i TypeScript.\n\nDenna bok är helt gratis och öppen källkod.\n\nJag tror att teknisk utbildning av hög kvalitet bör vara tillgänglig för alla, vilket är anledningen till att jag håller denna bok gratis och öppen.\n\nOm boken hjälpte dig att lösa en bugg, förstå ett knepigt koncept eller avancera i din karriär, vänligen överväg att stödja mitt arbete genom att betala vad du vill (föreslaget pris: 15 USD) eller sponsra en kaffe. Ditt stöd hjälper mig att hålla innehållet uppdaterat och utöka det med nya exempel och djupare förklaringar.\n\n[![Buy Me a Coffee](https://img.shields.io/badge/buy_me_a_coffee-FFDD00?style=for-the-badge&logo=buy-me-a-coffee&logoColor=black)](https://www.buymeacoffee.com/simonepoggiali)\n\n[![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.com/donate/?business=QW82ZS956XLFY&no_recurring=0&currency_code=EUR)\n\n"
  },
  {
    "path": "website/src/content/docs/sv-se/book/the-never-type.md",
    "content": "---\ntitle: Never-typen\nsidebar:\n  order: 25\n  label: 25. Never-typen\n---\n\n\nNär en variabel avsmalnas till en typ som inte kan innehålla några värden, kommer TypeScript-kompilatorn att härleda att variabeln måste vara av typen `never`. Detta beror på att never-typen representerar ett värde som aldrig kan produceras.\n\n```typescript\nconst printValue = (val: string | number) => {\n    if (typeof val === 'string') {\n        console.log(val.toUpperCase());\n    } else if (typeof val === 'number') {\n        console.log(val.toFixed(2));\n    } else {\n        // val has type never here because it can never be anything other than a string or a number\n        const neverVal: never = val;\n        console.log(`Unexpected value: ${neverVal}`);\n    }\n};\n```\n\n"
  },
  {
    "path": "website/src/content/docs/sv-se/book/translations.md",
    "content": "---\ntitle: Översättningar\nsidebar:\n  order: 2\n  label: 2. Översättningar\n---\n\n\nDenna bok har översatts till flera språkversioner, inklusive:\n\n[Kinesiska](https://github.com/gibbok/typescript-book/blob/main/README-zh_CN.md)\n\n[Italienska](https://github.com/gibbok/typescript-book/blob/main/README-it_IT.md)\n\n[Portugisiska (Brasilien)](https://github.com/gibbok/typescript-book/blob/main/README-pt_BR.md)\n\n[Svenska](https://github.com/gibbok/typescript-book/blob/main/README-sv_SE.md)\n\n"
  },
  {
    "path": "website/src/content/docs/sv-se/book/triple-slash-directives.md",
    "content": "---\ntitle: Trippelsnedstreck-direktiv\nsidebar:\n  order: 59\n  label: 59. Trippelsnedstreck-direktiv\n---\n\n\nTrippelsnedstreck-direktiv är speciella kommentarer som ger instruktioner till kompilatorn om hur en fil ska bearbetas. Dessa direktiv börjar med tre på varandra följande snedstreck (`///`) och placeras vanligtvis överst i en TypeScript-fil och har ingen effekt på körbeteendet.\n\nTrippelsnedstreck-direktiv används för att referera till externa beroenden, specificera modulinläsningsbeteende, aktivera/inaktivera vissa kompilatorfunktioner, med mera. Några exempel:\n\nReferera till en deklarationsfil:\n\n<!-- skip -->\n```typescript\n/// <reference path=\"path/to/declaration/file.d.ts\" />\n```\n\nAnge modulformat:\n\n<!-- skip -->\n```typescript\n/// <amd|commonjs|system|umd|es6|es2015|none>\n```\n\nAktivera kompilatoralternativ, i följande exempel strikt läge:\n\n<!-- skip -->\n```typescript\n/// <strict|noImplicitAny|noUnusedLocals|noUnusedParameters>\n```\n\n"
  },
  {
    "path": "website/src/content/docs/sv-se/book/tuple-type-anonymous.md",
    "content": "---\ntitle: Tuppeltyp (Anonym)\nsidebar:\n  order: 28\n  label: 28. Tuppeltyp (Anonym)\n---\n\n\nEn tuppeltyp är en typ som representerar en array med ett fast antal element och deras motsvarande typer. En tuppeltyp tvingar fram ett specifikt antal element och deras respektive typer i en fast ordning. Tuppeltyper är användbara när du vill representera en samling värden med specifika typer, där positionen för varje element i arrayen har en specifik betydelse.\n\n```typescript\ntype Point = [number, number];\n```\n\n"
  },
  {
    "path": "website/src/content/docs/sv-se/book/type-annotations.md",
    "content": "---\ntitle: Typannoteringar\nsidebar:\n  order: 11\n  label: 11. Typannoteringar\n---\n\n\nPå variabler som deklareras med `var`, `let` och `const` är det möjligt att valfritt lägga till en typ:\n\n```typescript\nconst x: number = 1;\n```\n\nTypeScript är bra på att härleda typer, särskilt enkla sådana, så dessa deklarationer är i de flesta fall inte nödvändiga.\n\nPå funktioner är det möjligt att lägga till typannoteringar på parametrar:\n\n```typescript\nfunction sum(a: number, b: number) {\n    return a + b;\n}\n```\n\nFöljande är ett exempel med en anonym funktion (så kallad lambda-funktion):\n\n```typescript\nconst sum = (a: number, b: number) => a + b;\n```\n\nDessa annoteringar kan undvikas när ett standardvärde för en parameter finns:\n\n```typescript\nconst sum = (a = 10, b: number) => a + b;\n```\n\nReturtypannoteringar kan läggas till på funktioner:\n\n```typescript\nconst sum = (a = 10, b: number): number => a + b;\n```\n\nDetta är särskilt användbart för mer komplexa funktioner eftersom det att explicit skriva returtypen före en implementation kan hjälpa till att bättre tänka igenom funktionen.\n\nGenerellt sett, överväg att annotera typsignaturer men inte lokala variabler i funktionskroppen, och lägg alltid till typer på objektliteraler.\n\n"
  },
  {
    "path": "website/src/content/docs/sv-se/book/type-from-func-return.md",
    "content": "---\ntitle: Typ från funktionsreturvärde\nsidebar:\n  order: 35\n  label: 35. Typ från funktionsreturvärde\n---\n\n\nTyp från funktionsreturvärde avser möjligheten att automatiskt härleda returtypen av en funktion baserat på dess implementation. Detta gör att TypeScript kan bestämma typen av det värde som returneras av funktionen utan explicita typannoteringar.\n\n```typescript\nconst add = (x: number, y: number) => x + y; // TypeScript can infer that the return type of the function is a number\n```\n\n"
  },
  {
    "path": "website/src/content/docs/sv-se/book/type-from-module.md",
    "content": "---\ntitle: Typ från modul\nsidebar:\n  order: 36\n  label: 36. Typ från modul\n---\n\n\nTyp från modul avser möjligheten att använda en moduls exporterade värden för att automatiskt härleda deras typer. När en modul exporterar ett värde med en specifik typ kan TypeScript använda den informationen för att automatiskt härleda typen av det värdet när det importeras till en annan modul.\n\n<!-- skip -->\n```typescript\n// calc.ts\nexport const add = (x: number, y: number) => x + y;\n// index.ts\nimport { add } from 'calc';\nconst r = add(1, 2); // r is number\n```\n\n"
  },
  {
    "path": "website/src/content/docs/sv-se/book/type-from-value.md",
    "content": "---\ntitle: Typ från värde\nsidebar:\n  order: 34\n  label: 34. Typ från värde\n---\n\n\nTyp från värde i TypeScript avser den automatiska härledningen av en typ från ett värde eller uttryck genom typinferens.\n\n```typescript\nconst x = 'x'; // TypeScript infers 'x' as a string literal with 'const' (immutable), but widens it to 'string' with 'let' (reassignable).\n```\n\n"
  },
  {
    "path": "website/src/content/docs/sv-se/book/type-indexing.md",
    "content": "---\ntitle: Typindexering\nsidebar:\n  order: 33\n  label: 33. Typindexering\n---\n\n\nTypindexering avser möjligheten att definiera typer som kan indexeras med en nyckel som inte är känd i förväg, genom att använda en indexsignatur för att specificera typen för egenskaper som inte uttryckligen deklarerats.\n\n```typescript\ntype Dictionary<T> = {\n    [key: string]: T;\n};\nconst myDict: Dictionary<string> = { a: 'a', b: 'b' };\nconsole.log(myDict['a']); // Returns a\n```\n\n"
  },
  {
    "path": "website/src/content/docs/sv-se/book/type-manipulation.md",
    "content": "---\ntitle: Typmanipulation\nsidebar:\n  order: 60\n  label: 60. Typmanipulation\n---\n\n\n### Skapa typer från typer\n\nDet är möjligt att skapa nya typer genom att komponera, manipulera eller transformera befintliga typer.\n\nIntersektionstyper (`&`):\n\nGör det möjligt att kombinera flera typer till en enda typ:\n\n```typescript\ntype A = { foo: number };\ntype B = { bar: string };\ntype C = A & B; // Intersection of A and B\nconst obj: C = { foo: 42, bar: 'hello' };\n```\n\nUnionstyper (`|`):\n\nGör det möjligt att definiera en typ som kan vara en av flera typer:\n\n```typescript\ntype Result = string | number;\nconst value1: Result = 'hello';\nconst value2: Result = 42;\n```\n\nMappade typer:\n\nGör det möjligt att transformera egenskaperna hos en befintlig typ för att skapa en ny typ:\n\n```typescript\ntype Mutable<T> = {\n    readonly [P in keyof T]: T[P];\n};\ntype Person = {\n    name: string;\n    age: number;\n};\ntype ImmutablePerson = Mutable<Person>; // Properties become read-only\n```\n\nVillkorliga typer:\n\nGör det möjligt att skapa typer baserat på vissa villkor:\n\n```typescript\ntype ExtractParam<T> = T extends (param: infer P) => any ? P : never;\ntype MyFunction = (name: string) => number;\ntype ParamType = ExtractParam<MyFunction>; // string\n```\n\n### Indexerade åtkomsttyper\n\nI TypeScript är det möjligt att komma åt och manipulera typerna av egenskaper inom en annan typ med hjälp av ett index, `Type[Key]`.\n\n```typescript\ntype Person = {\n    name: string;\n    age: number;\n};\n\ntype AgeType = Person['age']; // number\n```\n\n```typescript\ntype MyTuple = [string, number, boolean];\ntype MyType = MyTuple[2]; // boolean\n```\n\n### Verktygstyper\n\nFlera inbyggda verktygstyper kan användas för att manipulera typer. Nedan följer en lista över de mest använda:\n\n#### Awaited\\<T\\>\n\nKonstruerar en typ som rekursivt packar upp Promise-typer.\n\n```typescript\ntype A = Awaited<Promise<string>>; // string\n```\n\n#### Partial\\<T\\>\n\nKonstruerar en typ där alla egenskaper i T är satta som valfria.\n\n```typescript\ntype Person = {\n    name: string;\n    age: number;\n};\n\ntype A = Partial<Person>; // { name?: string | undefined; age?: number | undefined; }\n```\n\n#### Required\\<T\\>\n\nKonstruerar en typ där alla egenskaper i T är satta som obligatoriska.\n\n```typescript\ntype Person = {\n    name?: string;\n    age?: number;\n};\n\ntype A = Required<Person>; // { name: string; age: number; }\n```\n\n#### Readonly\\<T\\>\n\nKonstruerar en typ där alla egenskaper i T är satta som skrivskyddade.\n\n<!-- skip -->\n```typescript\ntype Person = {\n    name: string;\n    age: number;\n};\n\ntype A = Readonly<Person>;\n\nconst a: A = { name: 'Simon', age: 17 };\na.name = 'John'; // Invalid\n```\n\n#### Record\\<K, T\\>\n\nKonstruerar en typ med en uppsättning egenskaper K av typen T.\n\n```typescript\ntype Product = {\n    name: string;\n    price: number;\n};\n\nconst products: Record<string, Product> = {\n    apple: { name: 'Apple', price: 0.5 },\n    banana: { name: 'Banana', price: 0.25 },\n};\n\nconsole.log(products.apple); // { name: 'Apple', price: 0.5 }\n```\n\n#### Pick\\<T, K\\>\n\nKonstruerar en typ genom att välja ut de angivna egenskaperna K från T.\n\n```typescript\ntype Product = {\n    name: string;\n    price: number;\n};\n\ntype Price = Pick<Product, 'price'>; // { price: number; }\n```\n\n#### Omit\\<T, K\\>\n\nKonstruerar en typ genom att utelämna de angivna egenskaperna K från T.\n\n```typescript\ntype Product = {\n    name: string;\n    price: number;\n};\n\ntype Name = Omit<Product, 'price'>; // { name: string; }\n```\n\n#### Exclude\\<T, U\\>\n\nKonstruerar en typ genom att exkludera alla värden av typen U från T.\n\n```typescript\ntype Union = 'a' | 'b' | 'c';\ntype MyType = Exclude<Union, 'a' | 'c'>; // b\n```\n\n#### Extract\\<T, U\\>\n\nKonstruerar en typ genom att extrahera alla värden av typen U från T.\n\n```typescript\ntype Union = 'a' | 'b' | 'c';\ntype MyType = Extract<Union, 'a' | 'c'>; // a | c\n```\n\n#### NonNullable\\<T\\>\n\nKonstruerar en typ genom att exkludera null och undefined från T.\n\n```typescript\ntype Union = 'a' | null | undefined | 'b';\ntype MyType = NonNullable<Union>; // 'a' | 'b'\n```\n\n#### Parameters\\<T\\>\n\nExtraherar parametertyperna för en funktionstyp T.\n\n```typescript\ntype Func = (a: string, b: number) => void;\ntype MyType = Parameters<Func>; // [a: string, b: number]\n```\n\n#### ConstructorParameters\\<T\\>\n\nExtraherar parametertyperna för en konstruktorfunktionstyp T.\n\n```typescript\nclass Person {\n    constructor(\n        public name: string,\n        public age: number\n    ) {}\n}\ntype PersonConstructorParams = ConstructorParameters<typeof Person>; // [name: string, age: number]\nconst params: PersonConstructorParams = ['John', 30];\nconst person = new Person(...params);\nconsole.log(person); // Person { name: 'John', age: 30 }\n```\n\n#### ReturnType\\<T\\>\n\nExtraherar returtypen för en funktionstyp T.\n\n```typescript\ntype Func = (name: string) => number;\ntype MyType = ReturnType<Func>; // number\n```\n\n#### InstanceType\\<T\\>\n\nExtraherar instanstypen för en klasstyp T.\n\n```typescript\nclass Person {\n    name: string;\n\n    constructor(name: string) {\n        this.name = name;\n    }\n\n    sayHello() {\n        console.log(`Hello, my name is ${this.name}!`);\n    }\n}\n\ntype PersonInstance = InstanceType<typeof Person>;\n\nconst person: PersonInstance = new Person('John');\n\nperson.sayHello(); // Hello, my name is John!\n```\n\n#### ThisParameterType\\<T\\>\n\nExtraherar typen av 'this'-parametern från en funktionstyp T.\n\n```typescript\ninterface Person {\n    name: string;\n    greet(this: Person): void;\n}\ntype PersonThisType = ThisParameterType<Person['greet']>; // Person\n```\n\n#### OmitThisParameter\\<T\\>\n\nTar bort 'this'-parametern från en funktionstyp T.\n\n```typescript\nfunction capitalize(this: String) {\n    return this[0].toUpperCase + this.substring(1).toLowerCase();\n}\n\ntype CapitalizeType = OmitThisParameter<typeof capitalize>; // () => string\n```\n\n#### ThisType\\<T\\>\n\nFungerar som en markör för en kontextuell `this`-typ.\n\n<!-- skip -->\n```typescript\ntype Logger = {\n    log: (error: string) => void;\n};\n\nlet helperFunctions: { [name: string]: Function } & ThisType<Logger> = {\n    hello: function () {\n        this.log('some error'); // Valid as \"log\" is a part of \"this\".\n        this.update(); // Invalid\n    },\n};\n```\n\n#### Uppercase\\<T\\>\n\nGör namnet på indatatypen T till versaler.\n\n```typescript\ntype MyType = Uppercase<'abc'>; // \"ABC\"\n```\n\n#### Lowercase\\<T\\>\n\nGör namnet på indatatypen T till gemener.\n\n```typescript\ntype MyType = Lowercase<'ABC'>; // \"abc\"\n```\n\n#### Capitalize\\<T\\>\n\nGör första bokstaven i namnet på indatatypen T till versal.\n\n```typescript\ntype MyType = Capitalize<'abc'>; // \"Abc\"\n```\n\n#### Uncapitalize\\<T\\>\n\nGör första bokstaven i namnet på indatatypen T till gemen.\n\n```typescript\ntype MyType = Uncapitalize<'Abc'>; // \"abc\"\n```\n\n#### NoInfer\\<T\\>\n\nNoInfer är en verktygstyp utformad för att blockera automatisk typinferens inom ramen för en generisk funktion.\n\nExempel:\n\n```typescript\n// Automatic inference of types within the scope of a generic function.\nfunction fn<T extends string>(x: T[], y: T) {\n    return x.concat(y);\n}\nconst r = fn(['a', 'b'], 'c'); // Type here is (\"a\" | \"b\" | \"c\")[]\n```\n\nMed NoInfer:\n\n<!-- skip -->\n```typescript\n// Example function that uses NoInfer to prevent type inference\nfunction fn2<T extends string>(x: T[], y: NoInfer<T>) {\n    return x.concat(y);\n}\n\nconst r2 = fn2(['a', 'b'], 'c'); // Error: Type Argument of type '\"c\"' is not assignable to parameter of type '\"a\" | \"b\"'.\n```\n\n"
  },
  {
    "path": "website/src/content/docs/sv-se/book/type-predicates.md",
    "content": "---\ntitle: Typpredikat\nsidebar:\n  order: 23\n  label: 23. Typpredikat\n---\n\n\nTyppredikat i TypeScript är funktioner som returnerar ett booleskt värde och används för att avsmalma typen av en variabel till en mer specifik typ.\n\n```typescript\nconst isString = (value: unknown): value is string => typeof value === 'string';\n\nconst foo = (bar: unknown) => {\n    if (isString(bar)) {\n        console.log(bar.toUpperCase());\n    } else {\n        console.log('not a string');\n    }\n};\n```\n\n"
  },
  {
    "path": "website/src/content/docs/sv-se/book/typescript-introduction.md",
    "content": "---\ntitle: Introduktion till TypeScript\nsidebar:\n  order: 7\n  label: 7. Introduktion till TypeScript\n---\n\n\n### Vad är TypeScript?\n\nTypeScript är ett starkt typat programmeringsspråk som bygger på JavaScript. Det designades ursprungligen av Anders Hejlsberg 2012 och utvecklas och underhålls för närvarande av Microsoft som ett öppen källkod-projekt.\n\nTypeScript kompileras till JavaScript och kan köras i vilken JavaScript-runtime som helst (t.ex. en webbläsare eller Node.js på en server).\n\nDet stöder flera programmeringsparadigm såsom funktionell, generisk, imperativ och objektorienterad programmering, och är ett kompilerat (transpilerat) språk som konverteras till JavaScript före exekvering.\n\n### Varför TypeScript?\n\nTypeScript är ett starkt typat språk som hjälper till att förhindra vanliga programmeringsmisstag och undvika vissa typer av körtidsfel innan programmet körs.\n\nEtt starkt typat språk gör det möjligt för utvecklaren att specificera olika programbegränsningar och beteenden i datatypsdefinitionerna, vilket underlättar möjligheten att verifiera programvarans korrekthet och förhindra defekter. Detta är särskilt värdefullt i storskaliga applikationer.\n\nNågra av fördelarna med TypeScript:\n\n* Statisk typning, valfritt starkt typad\n* Typinferens\n* Tillgång till ES6- och ES7-funktioner\n* Plattforms- och webbläsarkompatibilitet\n* Verktygsstöd med IntelliSense\n\n### TypeScript och JavaScript\n\nTypeScript skrivs i `.ts`- eller `.tsx`-filer, medan JavaScript-filer skrivs i `.js`- eller `.jsx`-filer.\n\nFiler med tillägget `.tsx` eller `.jsx` kan innehålla JavaScript Syntax Extension JSX, som används i React för UI-utveckling.\n\nTypeScript är en typad supermängd av JavaScript (ECMAScript 2015) vad gäller syntax. All JavaScript-kod är giltig TypeScript-kod, men det omvända är inte alltid sant.\n\nBetrakta till exempel en funktion i en JavaScript-fil med tillägget `.js`, som följande:\n\n<!-- skip -->\n```typescript\nconst sum = (a, b) => a + b;\n```\n\nFunktionen kan konverteras och användas i TypeScript genom att ändra filtillägget till `.ts`. Men om samma funktion annoteras med TypeScript-typer kan den inte köras i någon JavaScript-runtime utan kompilering. Följande TypeScript-kod kommer att producera ett syntaxfel om den inte kompileras:\n\n<!-- skip -->\n```typescript\nconst sum = (a: number, b: number): number => a + b;\n```\n\nTypeScript designades för att upptäcka möjliga undantag som kan uppstå vid körning under kompileringstiden genom att låta utvecklaren definiera avsikten med typannoteringar. Dessutom kan TypeScript också fånga problem om ingen typannotering tillhandahålls. Till exempel specificerar följande kodavsnitt inga TypeScript-typer:\n\n<!-- skip -->\n```typescript\nconst items = [{ x: 1 }, { x: 2 }];\nconst result = items.filter(item => item.y);\n```\n\nI detta fall upptäcker TypeScript ett fel och rapporterar:\n\n```text\nProperty 'y' does not exist on type '{ x: number; }'.\n```\n\nTypeScripts typsystem är till stor del influerat av körtidsbeteendet hos JavaScript. Till exempel kan additionsoperatorn (+), som i JavaScript kan utföra antingen strängkonkatenering eller numerisk addition, modelleras på samma sätt i TypeScript:\n\n```typescript\nconst result = '1' + 1; // Result is of type string\n```\n\nTeamet bakom TypeScript har fattat ett medvetet beslut att flagga ovanlig användning av JavaScript som fel. Betrakta till exempel följande giltiga JavaScript-kod:\n\n<!-- skip -->\n```typescript\nconst result = 1 + true; // In JavaScript, the result is equal 2\n```\n\nDock kastar TypeScript ett fel:\n\n```text\nOperator '+' cannot be applied to types 'number' and 'boolean'.\n```\n\nDetta fel uppstår eftersom TypeScript strikt upprätthåller typkompatibilitet, och i detta fall identifierar det en ogiltig operation mellan en number och en boolean.\n\n### TypeScript-kodgenerering\n\nTypeScript-kompilatorn har två huvudansvar: kontrollera typfel och kompilera till JavaScript. Dessa två processer är oberoende av varandra. Typer påverkar inte kodens exekvering i en JavaScript-runtime, eftersom de raderas helt under kompileringen. TypeScript kan fortfarande producera JavaScript även vid typfel.\nHär är ett exempel på TypeScript-kod med ett typfel:\n\n<!-- skip -->\n```typescript\nconst add = (a: number, b: number): number => a + b;\nconst result = add('x', 'y'); // Argument of type 'string' is not assignable to parameter of type 'number'.\n```\n\nTrots detta kan den fortfarande producera körbar JavaScript-utdata:\n\n<!-- skip -->\n```typescript\n'use strict';\nconst add = (a, b) => a + b;\nconst result = add('x', 'y'); // xy\n```\n\nDet är inte möjligt att kontrollera TypeScript-typer vid körning. Till exempel:\n\n<!-- skip -->\n```typescript\ninterface Animal {\n    name: string;\n}\ninterface Dog extends Animal {\n    bark: () => void;\n}\ninterface Cat extends Animal {\n    meow: () => void;\n}\nconst makeNoise = (animal: Animal) => {\n    if (animal instanceof Dog) {\n        // 'Dog' only refers to a type, but is being used as a value here.\n        // ...\n    }\n};\n```\n\nEftersom typerna raderas efter kompilering finns det inget sätt att köra denna kod i JavaScript. För att känna igen typer vid körning behöver vi använda en annan mekanism. TypeScript erbjuder flera alternativ, där ett vanligt är \"tagged union\". Till exempel:\n\n```typescript\ninterface Dog {\n    kind: 'dog'; // Tagged union\n    bark: () => void;\n}\ninterface Cat {\n    kind: 'cat'; // Tagged union\n    meow: () => void;\n}\ntype Animal = Dog | Cat;\n\nconst makeNoise = (animal: Animal) => {\n    if (animal.kind === 'dog') {\n        animal.bark();\n    } else {\n        animal.meow();\n    }\n};\n\nconst dog: Dog = {\n    kind: 'dog',\n    bark: () => console.log('bark'),\n};\nmakeNoise(dog);\n```\n\nEgenskapen \"kind\" är ett värde som kan användas vid körning för att särskilja mellan objekt i JavaScript.\n\nDet är också möjligt att ett värde vid körning har en annan typ än den som deklarerades i typdeklarationen. Till exempel om utvecklaren har misstolkat en API-typ och annoterat den felaktigt.\n\nTypeScript är en supermängd av JavaScript, så nyckelordet \"class\" kan användas som en typ och ett värde vid körning.\n\n```typescript\nclass Animal {\n    constructor(public name: string) {}\n}\nclass Dog extends Animal {\n    constructor(\n        public name: string,\n        public bark: () => void\n    ) {\n        super(name);\n    }\n}\nclass Cat extends Animal {\n    constructor(\n        public name: string,\n        public meow: () => void\n    ) {\n        super(name);\n    }\n}\ntype Mammal = Dog | Cat;\n\nconst makeNoise = (mammal: Mammal) => {\n    if (mammal instanceof Dog) {\n        mammal.bark();\n    } else {\n        mammal.meow();\n    }\n};\n\nconst dog = new Dog('Fido', () => console.log('bark'));\nmakeNoise(dog);\n```\n\nI JavaScript har en \"class\" en \"prototype\"-egenskap, och \"instanceof\"-operatorn kan användas för att testa om prototype-egenskapen för en konstruktor förekommer någonstans i prototypkedjan för ett objekt.\n\nTypeScript har ingen effekt på körtidsprestanda, eftersom alla typer raderas. Dock introducerar TypeScript viss overhead vid byggtid.\n\n### Modernt JavaScript nu (Downleveling)\n\nTypeScript kan kompilera kod till vilken utgiven version av JavaScript som helst sedan ECMAScript 3 (1999). Detta innebär att TypeScript kan transpilera kod från de senaste JavaScript-funktionerna till äldre versioner, en process som kallas Downleveling. Detta möjliggör användning av modernt JavaScript samtidigt som maximal kompatibilitet med äldre körtidsmiljöer bibehålls.\n\nDet är viktigt att notera att vid transpilering till en äldre version av JavaScript kan TypeScript generera kod som kan medföra en prestandaoverhead jämfört med nativa implementeringar.\n\nHär är några av de moderna JavaScript-funktioner som kan användas i TypeScript:\n\n* ECMAScript-moduler istället för AMD-style \"define\"-callbacks eller CommonJS \"require\"-satser.\n* Klasser istället för prototyper.\n* Variabeldeklaration med \"let\" eller \"const\" istället för \"var\".\n* \"for-of\"-loop eller \".forEach\" istället för den traditionella \"for\"-loopen.\n* Pilfunktioner istället för funktionsuttryck.\n* Destruktureringstilldelning.\n* Förkortade egenskaps-/metodnamn och beräknade egenskapsnamn.\n* Standardparametrar för funktioner.\n\nGenom att utnyttja dessa moderna JavaScript-funktioner kan utvecklare skriva mer uttrycksfull och koncis kod i TypeScript.\n\n"
  },
  {
    "path": "website/src/content/docs/sv-se/book/union-type.md",
    "content": "---\ntitle: Unionstyp\nsidebar:\n  order: 31\n  label: 31. Unionstyp\n---\n\n\nEn unionstyp är en typ som representerar ett värde som kan vara en av flera typer. Unionstyper betecknas med symbolen `|` mellan varje möjlig typ.\n\n```typescript\nlet x: string | number;\nx = 'hello'; // Valid\nx = 123; // Valid\n```\n\n"
  },
  {
    "path": "website/src/content/docs/sv-se/book/unknown-type.md",
    "content": "---\ntitle: Unknown-typen\nsidebar:\n  order: 45\n  label: 45. Unknown-typen\n---\n\n\nI TypeScript representerar `unknown`-typen ett värde av en okänd typ. Till skillnad från `any`-typen, som tillåter vilken typ av värde som helst, kräver `unknown` en typkontroll eller assertion innan den kan användas på ett specifikt sätt, så inga operationer är tillåtna på en `unknown` utan att först göra en assertion eller avsmalning till en mer specifik typ.\n\n`unknown`-typen kan bara tilldelas till any-typen och `unknown`-typen själv, den är ett typsäkert alternativ till `any`.\n<!-- skip -->\n```typescript\nlet value: unknown;\n\nlet value1: unknown = value; // Valid\nlet value2: any = value; // Valid\nlet value3: boolean = value; // Invalid\nlet value4: number = value; // Invalid\n```\n\n```typescript\nconst add = (a: unknown, b: unknown): number | undefined =>\n    typeof a === 'number' && typeof b === 'number' ? a + b : undefined;\nconsole.log(add(1, 2)); // 3\nconsole.log(add('x', 2)); // undefined\n```\n\n"
  },
  {
    "path": "website/src/content/docs/sv-se/book/void-type.md",
    "content": "---\ntitle: Void-typen\nsidebar:\n  order: 46\n  label: 46. Void-typen\n---\n\n\nTypen `void` används för att indikera att en funktion inte returnerar något värde.\n\n```typescript\nconst sayHello = (): void => {\n    console.log('Hello!');\n};\n```\n\n"
  },
  {
    "path": "website/src/content/docs/sv-se/index.mdx",
    "content": "---\ntitle: TypeScript Book\ndescription: The Concise TypeScript Book\ntemplate: splash\nhero:\n    tagline: Den koncisa TypeScript-boken ger en omfattande och kortfattad översikt över TypeScripts kapaciteter. Den erbjuder tydliga förklaringar som täcker alla aspekter i den senaste versionen av språket, från dess kraftfulla typsystem till avancerade funktioner. Oavsett om du är nybörjare eller en erfaren utvecklare är denna bok en ovärderlig resurs för att förbättra din förståelse och skicklighet i TypeScript.<br/><br/>Denna bok är helt gratis och öppen källkod.\n    actions:\n        - text: Läs nu!\n          link: /typescript-book/sv-se/book/the-concise-typescript-book/\n          icon: right-arrow\n          variant: primary\n        - text: GitHub\n          link: https://github.com/gibbok/typescript-book\n          icon: github\n          variant: secondary\n        - text: X.com\n          link: https://twitter.com/gibbok_coding\n          icon: x.com\n          variant: secondary\n---\n"
  },
  {
    "path": "website/src/content/docs/zh-cn/book/about-the-author.md",
    "content": "---\ntitle: 关于作者\nsidebar:\n  order: 6\n  label: 6. 关于作者\n---\n\n\nSimone Poggiali 是一位经验丰富的资深工程师，自 90 年代以来便对编写专业级代码充满热情。在他的国际职业生涯中，他曾为众多客户（从初创公司到大型企业）参与过各种项目。HelloFresh、西门子、O2、Leroy Merlin 和 Snowplow 等知名公司都曾受益于他的专业知识和敬业精神。\n\n您可以通过以下平台联系 Simone Poggiali：\n\n* 领英: [https://www.linkedin.com/in/simone-poggiali](https://www.linkedin.com/in/simone-poggiali)\n* GitHub: [https://github.com/gibbok](https://github.com/gibbok)\n* X.com: [https://x.com/gibbok_coding](https://x.com/gibbok_coding)\n* 电子邮箱: gibbok.coding📧gmail.com\n\n完整的贡献者名单：[https://github.com/gibbok/typescript-book/graphs/contributors](https://github.com/gibbok/typescript-book/graphs/contributors)\n\n"
  },
  {
    "path": "website/src/content/docs/zh-cn/book/any-type.md",
    "content": "---\ntitle: 任意类型\nsidebar:\n  order: 44\n  label: 44. 任意类型\n---\n\n\n`any` 类型是一种特殊类型（通用超类型），可用于表示任何类型的值（基元、对象、数组、函数、错误、符号）。它通常用于编译时未知值类型的情况，或者使用来自没有 TypeScript 类型的外部 API 或库的值时。\n\n使用 `any` 类型，就等于告诉 TypeScript 编译器，值应该不受任何限制地表示。为了最大限度地提高代码的类型安全性，请考虑以下几点：\n\n* 将 `any` 的使用限制在类型确实未知的特定情况下。\n* 不要从函数返回 `any` 类型，因为这会削弱使用该函数的代码的类型安全性。\n* 如果您需要使编译器保持沉默，请使用 `@ts-ignore` 而不是 `any`。\n\n```typescript\nlet value: any;\nvalue = true; // 有效\nvalue = 7; // 有效\n```\n\n"
  },
  {
    "path": "website/src/content/docs/zh-cn/book/assignments.md",
    "content": "---\ntitle: 赋值\nsidebar:\n  order: 21\n  label: 21. 赋值\n---\n\n\n使用赋值缩小 TypeScript 是一种根据分配给变量的值来缩小变量类型的方法。当为变量分配值时，TypeScript 会根据分配的值推断其类型，并缩小变量的类型以匹配推断的类型。\n\n```typescript\nlet value: string | number;\nvalue = 'hello';\nif (typeof value === 'string') {\n    console.log(value.toUpperCase());\n}\nvalue = 42;\nif (typeof value === 'number') {\n    console.log(value.toFixed(2));\n}\n```\n\n"
  },
  {
    "path": "website/src/content/docs/zh-cn/book/built-in-type-primitives.md",
    "content": "---\ntitle: 内置原始数据类型\nsidebar:\n  order: 49\n  label: 49. 内置原始数据类型\n---\n\n\nTypeScript 有几个内置的原属数据类型，可用于定义变量、函数参数和返回类型：\n\n`number`: 表示数值，包括整数和浮点数。\n`string`: 代表文本数据。\n`boolean`: 代表逻辑值，可以是 true 或 false。\n`null`:  表示没有值。\n`undefined`: 表示尚未赋值或未定义的值。\n`symbol`: 代表唯一标识符。符号通常用作对象属性的键。\n`bigint`: 表示任意精度整数。\n`any`: 代表动态或未知类型。any 类型的变量可以保存任何类型的值，并且它们绕过类型检查。\n`void`: 表示不存在任何类型。它通常用作不返回值的函数的返回类型。\n`never`: 表示从未出现过的值的类型。它通常用作引发错误或进入无限循环的函数的返回类型。\n\n"
  },
  {
    "path": "website/src/content/docs/zh-cn/book/class.md",
    "content": "---\ntitle: Class\nsidebar:\n  order: 54\n  label: 54. Class\n---\n\n\n### 通用语法\n\nTypeScript 中使用关键字 `class` 来定义类。下面，您可以看到一个示例：\n\n```typescript\nclass Person {\n    private name: string;\n    private age: number;\n    constructor(name: string, age: number) {\n        this.name = name;\n        this.age = age;\n    }\n    public sayHi(): void {\n        console.log(\n            `Hello, my name is ${this.name} and I am ${this.age} years old.`\n        );\n    }\n}\n```\n\n`class` 关键字用于定义名为 `Person` 的类。\n\n该类有两个私有属性：类型名称 `string` 和类型年龄 `number`。\n\n构造函数是使用 `constructor` 关键字定义的。它将姓名和年龄作为参数并将它们分配给相应的属性。\n\n该类有一个 `public` 名为 `sayHi` 的方法，用于记录问候消息。\n\n要在 TypeScript 中创建类的实例，可以使用 `new` 关键字，后跟类名，然后使用括号 `()`。例如：\n\n<!-- skip -->\n```typescript\nconst myObject = new Person('John Doe', 25);\nmyObject.sayHi(); // 输出：Hello, my name is John Doe and I am 25 years old.\n```\n\n### 构造函数\n\n构造函数是类中的特殊方法，用于在创建类的实例时初始化对象的属性。\n\n```typescript\nclass Person {\n    public name: string;\n    public age: number;\n\n    constructor(name: string, age: number) {\n        this.name = name;\n        this.age = age;\n    }\n\n    sayHello() {\n        console.log(\n            `Hello, my name is ${this.name} and I'm ${this.age} years old.`\n        );\n    }\n}\n\nconst john = new Person('Simon', 17);\njohn.sayHello();\n```\n\n可以使用以下语法重载构造函数：\n\n```typescript\ntype Sex = 'm' | 'f';\n\nclass Person {\n    name: string;\n    age: number;\n    sex: Sex;\n\n    constructor(name: string, age: number, sex?: Sex);\n    constructor(name: string, age: number, sex: Sex) {\n        this.name = name;\n        this.age = age;\n        this.sex = sex ?? 'm';\n    }\n}\n\nconst p1 = new Person('Simon', 17);\nconst p2 = new Person('Alice', 22, 'f');\n```\n\n在 TypeScript 中，可以定义多个构造函数重载，但只能有一个必须与所有重载兼容的实现，这可以通过使用可选参数来实现。\n\n```typescript\nclass Person {\n    name: string;\n    age: number;\n\n    constructor();\n    constructor(name: string);\n    constructor(name: string, age: number);\n    constructor(name?: string, age?: number) {\n        this.name = name ?? 'Unknown';\n        this.age = age ?? 0;\n    }\n\n    displayInfo() {\n        console.log(`Name: ${this.name}, Age: ${this.age}`);\n    }\n}\n\nconst person1 = new Person();\nperson1.displayInfo(); // Name: Unknown, Age: 0\n\nconst person2 = new Person('John');\nperson2.displayInfo(); // Name: John, Age: 0\n\nconst person3 = new Person('Jane', 25);\nperson3.displayInfo(); // Name: Jane, Age: 25\n```\n\n### 私有和受保护的构造函数\n\n在 TypeScript 中，构造函数可以标记为私有或受保护，这限制了它们的可访问性和使用。\n\n私有构造函数：只能在类本身内调用。私有构造函数通常用于以下场景：您想要强制执行单例模式或将实例的创建限制为类中的工厂方法\n\n受保护的构造函数：当您想要创建一个不应直接实例化但可以由子类扩展的基类时，受保护的构造函数非常有用。\n\n```typescript\nclass BaseClass {\n    protected constructor() {}\n}\n\nclass DerivedClass extends BaseClass {\n    private value: number;\n\n    constructor(value: number) {\n        super();\n        this.value = value;\n    }\n}\n\n// 尝试直接实例化基类将导致错误\n// const baseObj = new BaseClass(); // 错误：类\"BaseClass\"的构造函数受到保护。\n\n// 创建派生类的实例\nconst derivedObj = new DerivedClass(10);\n```\n\n### 访问修饰符\n\n访问修饰符 `private` 、`protected` 和 `public` 用于控制 TypeScript 类中类成员（例如属性和方法）的可见性和可访问性。这些修饰符对于强制封装以及建立访问和修改类内部状态的边界至关重要。\n\n修饰符 `private` 仅限制对包含类中的类成员的访问。\n\n修饰符 `protected` 允许访问包含类及其派生类中的类成员。\n\n修饰符 `public` 提供对类成员的不受限制的访问，允许从任何地方访问它。\n\n### Get 与 Set\n\nGetter 和 Setter 是特殊方法，允许您定义类属性的自定义访问和修改行为。它们使您能够封装对象的内部状态，并在获取或设置属性值时提供附加逻辑。在 TypeScript 中，getter 和 setter 分别使用 `get` 和 `set` 关键字定义。这是一个例子：\n\n```typescript\nclass MyClass {\n    private _myProperty: string;\n\n    constructor(value: string) {\n        this._myProperty = value;\n    }\n    get myProperty(): string {\n        return this._myProperty;\n    }\n    set myProperty(value: string) {\n        this._myProperty = value;\n    }\n}\n```\n\n### 类中的自动访问器\n\nTypeScript 版本 4.9 添加了对自动访问器的支持，这是即将推出的 ECMAScript 功能。它们类似于类属性，但使用\"accessor\"关键字声明。\n\n```typescript\nclass Animal {\n    accessor name: string;\n\n    constructor(name: string) {\n        this.name = name;\n    }\n}\n```\n\n自动访问器被\"脱糖\"为私有get访问set器，在无法访问的属性上运行。\n\n<!-- skip -->\n```typescript\nclass Animal {\n    #__name: string;\n\n    get name() {\n        return this.#__name;\n    }\n    set name(value: string) {\n        this.#__name = name;\n    }\n\n    constructor(name: string) {\n        this.name = name;\n    }\n}\n```\n\n### this\n\n在 TypeScript 中，`this` 关键字指的是类的方法或构造函数中的当前实例。它允许您在类自己的范围内访问和修改类的属性和方法。它提供了一种在对象自己的方法中访问和操作对象内部状态的方法。\n\n```typescript\nclass Person {\n    private name: string;\n    constructor(name: string) {\n        this.name = name;\n    }\n    public introduce(): void {\n        console.log(`Hello, my name is ${this.name}.`);\n    }\n}\n\nconst person1 = new Person('Alice');\nperson1.introduce(); // Hello, my name is Alice.\n```\n\n### 参数属性\n\n参数属性允许您直接在构造函数参数中声明和初始化类属性，从而避免样板代码，例如：\n\n```typescript\nclass Person {\n    constructor(\n        private name: string,\n        public age: number\n    ) {\n        // 构造函数中的\"private\"和\"public\"关键字自动声明并初始化相应的类属性。\n    }\n    public introduce(): void {\n        console.log(\n            `Hello, my name is ${this.name} and I am ${this.age} years old.`\n        );\n    }\n}\nconst person = new Person('Alice', 25);\nperson.introduce();\n```\n\n### 抽象类\n\n抽象类在 TypeScript 中主要用于继承，它们提供了一种定义可由子类继承的公共属性和方法的方法。当您想要定义常见行为并强制子类实现某些方法时，这非常有用。它们提供了一种创建类层次结构的方法，其中抽象基类为子类提供共享接口和通用功能。\n\n```typescript\nabstract class Animal {\n    protected name: string;\n\n    constructor(name: string) {\n        this.name = name;\n    }\n\n    abstract makeSound(): void;\n}\n\nclass Cat extends Animal {\n    makeSound(): void {\n        console.log(`${this.name} meows.`);\n    }\n}\n\nconst cat = new Cat('Whiskers');\ncat.makeSound(); // 输出：Whiskers meows.\n```\n\n### 使用泛型\n\n具有泛型的类允许您定义可以与不同类型一起使用的可重用类。\n\n```typescript\nclass Container<T> {\n    private item: T;\n\n    constructor(item: T) {\n        this.item = item;\n    }\n\n    getItem(): T {\n        return this.item;\n    }\n\n    setItem(item: T): void {\n        this.item = item;\n    }\n}\n\nconst container1 = new Container<number>(42);\nconsole.log(container1.getItem()); //  42\n\nconst container2 = new Container<string>('Hello');\ncontainer2.setItem('World');\nconsole.log(container2.getItem()); // World\n```\n\n### 装饰器\n\n装饰器提供了一种添加元数据、修改行为、验证或扩展目标元素功能的机制。它们是在运行时执行的函数。多个装饰器可以应用于一个声明。\n\n装饰器是实验性功能，以下示例仅与使用 ES6 的 TypeScript 版本 5 或更高版本兼容。\n\n对于 5 之前的 TypeScript 版本，应在您的 `tsconfig.json` 中使用使`experimentalDecorators` 或在命令行中使用 `--experimentalDecorators` 来启用它们（但以下示例不起作用）。\n\n装饰器的一些常见用例包括：\n\n* 观察属性变化。\n* 观察方法调用。\n* 添加额外的属性或方法。\n* 运行时验证。\n* 自动序列化和反序列化。\n* 日志记录。\n* 授权和认证。\n* 错误防护。\n\n注意：版本 5 的装饰器不允许装饰参数。\n\n装饰器的类型：\n\n#### 类装饰器\n\n类装饰器对于扩展现有类非常有用，例如添加属性或方法，或者收集类的实例。在下面的示例中，我们添加一个 `toString` 将类转换为字符串表示形式的方法。\n\n```typescript\ntype Constructor<T = {}> = new (...args: any[]) => T;\n\nfunction toString<Class extends Constructor>(\n    Value: Class,\n    context: ClassDecoratorContext<Class>\n) {\n    return class extends Value {\n        constructor(...args: any[]) {\n            super(...args);\n            console.log(JSON.stringify(this));\n            console.log(JSON.stringify(context));\n        }\n    };\n}\n\n@toString\nclass Person {\n    name: string;\n\n    constructor(name: string) {\n        this.name = name;\n    }\n\n    greet() {\n        return 'Hello, ' + this.name;\n    }\n}\nconst person = new Person('Simon');\n/* Logs:\n{\"name\":\"Simon\"}\n{\"kind\":\"class\",\"name\":\"Person\"}\n*/\n```\n\n#### 属性装饰器\n\n属性装饰器对于修改属性的行为非常有用，例如更改初始化值。在下面的代码中，我们有一个脚本将属性设置为始终大写：\n\n```typescript\nfunction upperCase<T>(\n    target: undefined,\n    context: ClassFieldDecoratorContext<T, string>\n) {\n    return function (this: T, value: string) {\n        return value.toUpperCase();\n    };\n}\n\nclass MyClass {\n    @upperCase\n    prop1 = 'hello!';\n}\n\nconsole.log(new MyClass().prop1); // 日志：HELLO!\n```\n\n#### 方法装饰器\n\n方法装饰器允许您更改或增强方法的行为。下面是一个简单记录器的示例：\n\n```typescript\nfunction log<This, Args extends any[], Return>(\n    target: (this: This, ...args: Args) => Return,\n    context: ClassMethodDecoratorContext<\n        This,\n        (this: This, ...args: Args) => Return\n    >\n) {\n    const methodName = String(context.name);\n\n    function replacementMethod(this: This, ...args: Args): Return {\n        console.log(`LOG: Entering method '${methodName}'.`);\n        const result = target.call(this, ...args);\n        console.log(`LOG: Exiting method '${methodName}'.`);\n        return result;\n    }\n\n    return replacementMethod;\n}\n\nclass MyClass {\n    @log\n    sayHello() {\n        console.log('Hello!');\n    }\n}\n\nnew MyClass().sayHello();\n```\n\n它记录：\n\n```shell\nLOG: Entering method 'sayHello'.\nHello!\nLOG: Exiting method 'sayHello'.\n```\n\n#### Getter 和 Setter 装饰器\n\ngetter 和 setter 装饰器允许您更改或增强类访问器的行为。例如，它们对于验证属性分配很有用。这是 getter 装饰器的一个简单示例：\n\n```typescript\nfunction range<This, Return extends number>(min: number, max: number) {\n    return function (\n        target: (this: This) => Return,\n        context: ClassGetterDecoratorContext<This, Return>\n    ) {\n        return function (this: This): Return {\n            const value = target.call(this);\n            if (value < min || value > max) {\n                throw 'Invalid';\n            }\n            Object.defineProperty(this, context.name, {\n                value,\n                enumerable: true,\n            });\n            return value;\n        };\n    };\n}\n\nclass MyClass {\n    private _value = 0;\n\n    constructor(value: number) {\n        this._value = value;\n    }\n    @range(1, 100)\n    get getValue(): number {\n        return this._value;\n    }\n}\n\nconst obj = new MyClass(10);\nconsole.log(obj.getValue); // 有效: 10\n\nconst obj2 = new MyClass(999);\nconsole.log(obj2.getValue); // 抛出异常: Invalid!\n```\n\n### 装饰器元数据\n\n装饰器元数据简化了装饰器在任何类中应用和利用元数据的过程。 他们可以访问上下文对象上的新元数据属性，该属性可以充当基元和对象的密钥。\n可以通过\"Symbol.metadata\"在类上访问元数据信息。\n\n元数据可用于各种目的，例如调试、序列化或使用装饰器的依赖项注入。\n\n```typescript\n//@ts-ignore\nSymbol.metadata ??= Symbol('Symbol.metadata'); // 简单的兼容性填充\n\ntype Context =\n    | ClassFieldDecoratorContext\n    | ClassAccessorDecoratorContext\n    | ClassMethodDecoratorContext; // 上下文对象包含属性元数据: 装饰器元数据\n\nfunction setMetadata(_target: any, context: Context) {\n    // 使用基本类型值设置元数据对象\n    context.metadata[context.name] = true;\n}\n\nclass MyClass {\n    @setMetadata\n    a = 123;\n\n    @setMetadata\n    accessor b = 'b';\n\n    @setMetadata\n    fn() {}\n}\n\nconst metadata = MyClass[Symbol.metadata]; // 获取元数据对象信息\n\nconsole.log(JSON.stringify(metadata)); // {\"bar\":true,\"baz\":true,\"foo\":true}\n```\n\n### 继承\n\n继承是指一个类可以从另一个类（称为基类或超类）继承属性和方法的机制。派生类也称为子类或子类，可以通过添加新的属性和方法或重写现有的属性和方法来扩展和专门化基类的功能。\n\n```typescript\nclass Animal {\n    name: string;\n\n    constructor(name: string) {\n        this.name = name;\n    }\n\n    speak(): void {\n        console.log('The animal makes a sound');\n    }\n}\n\nclass Dog extends Animal {\n    breed: string;\n\n    constructor(name: string, breed: string) {\n        super(name);\n        this.breed = breed;\n    }\n\n    speak(): void {\n        console.log('Woof! Woof!');\n    }\n}\n\n// 创建基类的一个实例\nconst animal = new Animal('Generic Animal');\nanimal.speak(); // The animal makes a sound\n\n// 创建派生类的一个实例\nconst dog = new Dog('Max', 'Labrador');\ndog.speak(); // Woof! Woof!\"\n```\n\nTypeScript 不支持传统意义上的多重继承，而是允许从单个基类继承。TypeScript 支持多种接口。接口可以定义对象结构的契约，类可以实现多个接口。这允许类从多个源继承行为和结构。\n\n```typescript\ninterface Flyable {\n    fly(): void;\n}\n\ninterface Swimmable {\n    swim(): void;\n}\n\nclass FlyingFish implements Flyable, Swimmable {\n    fly() {\n        console.log('Flying...');\n    }\n\n    swim() {\n        console.log('Swimming...');\n    }\n}\n\nconst flyingFish = new FlyingFish();\nflyingFish.fly();\nflyingFish.swim();\n```\n\nTypeScript 中的关键字 `class` 与 JavaScript 类似，通常被称为语法糖。它是在 ECMAScript 2015 (ES6) 中引入的，旨在提供更熟悉的语法，以基于类的方式创建和使用对象。然而，值得注意的是，TypeScript 作为 JavaScript 的超集，最终会编译为 JavaScript，而 JavaScript 的核心仍然是基于原型的。\n\n### 静态成员\n\nTypeScript 有静态成员。要访问类的静态成员，可以使用类名后跟一个点，而不需要创建对象。\n\n```typescript\nclass OfficeWorker {\n    static memberCount: number = 0;\n\n    constructor(private name: string) {\n        OfficeWorker.memberCount++;\n    }\n}\n\nconst w1 = new OfficeWorker('James');\nconst w2 = new OfficeWorker('Simon');\nconst total = OfficeWorker.memberCount;\nconsole.log(total); // 2\n```\n\n### 属性初始化\n\n在 TypeScript 中初始化类的属性有多种方法：\n\n内嵌：\n\n在下面的示例中，创建类的实例时将使用这些初始值。\n\n```typescript\nclass MyClass {\n    property1: string = 'default value';\n    property2: number = 42;\n}\n```\n\n在构造函数中：\n\n```typescript\nclass MyClass {\n    property1: string;\n    property2: number;\n\n    constructor() {\n        this.property1 = 'default value';\n        this.property2 = 42;\n    }\n}\n```\n\n使用构造函数参数：\n\n```typescript\nclass MyClass {\n    constructor(\n        private property1: string = 'default value',\n        public property2: number = 42\n    ) {\n        // 无需显式地将值分配给属性。\n    }\n    log() {\n        console.log(this.property2);\n    }\n}\nconst x = new MyClass();\nx.log();\n```\n\n### 方法重载\n\n方法重载允许一个类有多个名称相同但参数类型不同或参数数量不同的方法。这允许我们根据传递的参数以不同的方式调用方法。\n\n```typescript\nclass MyClass {\n    add(a: number, b: number): number; // 重载签名 1\n    add(a: string, b: string): string; // 重载签名 2\n\n    add(a: number | string, b: number | string): number | string {\n        if (typeof a === 'number' && typeof b === 'number') {\n            return a + b;\n        }\n        if (typeof a === 'string' && typeof b === 'string') {\n            return a.concat(b);\n        }\n        throw new Error('Invalid arguments');\n    }\n}\n\nconst r = new MyClass();\nconsole.log(r.add(10, 5)); // 日志：15\n```\n\n"
  },
  {
    "path": "website/src/content/docs/zh-cn/book/common-built-in-js-objects.md",
    "content": "---\ntitle: 常见的内置JS对象\nsidebar:\n  order: 50\n  label: 50. 常见的内置JS对象\n---\n\n\nTypeScript 是 JavaScript 的超集，它包含所有常用的内置 JavaScript 对象。您可以在 Mozilla 开发者网络 (MDN) 文档网站上找到这些对象的详细列表：\n[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects)\n\n以下是一些常用的内置 JavaScript 对象的列表：\n\n* Function\n* Object\n* Boolean\n* Error\n* Number\n* BigInt\n* Math\n* Date\n* String\n* RegExp\n* Array\n* Map\n* Set\n* Promise\n* Intl\n\n"
  },
  {
    "path": "website/src/content/docs/zh-cn/book/conditional-types.md",
    "content": "---\ntitle: 条件类型\nsidebar:\n  order: 39\n  label: 39. 条件类型\n---\n\n\n条件类型是一种创建依赖于条件的类型的方法，其中要创建的类型是根据条件的结果确定的。它们是使用 `extends` 关键字和三元运算符来定义的，以便有条件地在两种类型之间进行选择。\n\n```typescript\ntype IsArray<T> = T extends any[] ? true : false;\n\nconst myArray = [1, 2, 3];\nconst myNumber = 42;\n\ntype IsMyArrayAnArray = IsArray<typeof myArray>; // true 类型\ntype IsMyNumberAnArray = IsArray<typeof myNumber>; // false 类型\n```\n\n"
  },
  {
    "path": "website/src/content/docs/zh-cn/book/control-flow-analysis.md",
    "content": "---\ntitle: 控制流分析\nsidebar:\n  order: 22\n  label: 22. 控制流分析\n---\n\n\nTypeScript 中的控制流分析是一种静态分析代码流以推断变量类型的方法，允许编译器根据分析结果根据需要缩小这些变量的类型。\n\n在 TypeScript 4.4 之前，代码流分析仅适用于 if 语句中的代码，但从 TypeScript 4.4 开始，它还可以应用于条件表达式和通过 const 变量间接引用的判别式属性访问。\n\n例如：\n\n```typescript\nconst f1 = (x: unknown) => {\n    const isString = typeof x === 'string';\n    if (isString) {\n        x.length;\n    }\n};\n\nconst f2 = (\n    obj: { kind: 'foo'; foo: string } | { kind: 'bar'; bar: number }\n) => {\n    const isFoo = obj.kind === 'foo';\n    if (isFoo) {\n        obj.foo;\n    } else {\n        obj.bar;\n    }\n};\n```\n\n一些未发生缩小的示例：\n\n<!-- skip -->\n```typescript\nconst f1 = (x: unknown) => {\n    let isString = typeof x === 'string';\n    if (isString) {\n        x.length; // 错误, 没有缩小，因为 isString 不是常量\n    }\n};\n\nconst f6 = (\n    obj: { kind: 'foo'; foo: string } | { kind: 'bar'; bar: number }\n) => {\n    const isFoo = obj.kind === 'foo';\n    obj = obj;\n    if (isFoo) {\n        obj.foo; // 错误, 没有缩小，因为 obj 在函数体中被赋值\n    }\n};\n```\n\n注意： 在条件表达式中最多分析五个间接级别。\n\n"
  },
  {
    "path": "website/src/content/docs/zh-cn/book/differences-between-type-and-interface.md",
    "content": "---\ntitle: 类型和接口之间的差异\nsidebar:\n  order: 53\n  label: 53. 类型和接口之间的差异\n---\n\n\n声明合并（增强）：\n\n接口支持声明合并，这意味着您可以定义多个具有相同名称的接口，TypeScript 会将它们合并为具有组合属性和方法的单个接口。 另一方面，类型不支持声明合并。 当您想要添加额外的功能或自定义现有类型而不修改原始定义或修补丢失或不正确的类型时，这可能会很有帮助。\n\n```typescript\ninterface A {\n    x: string;\n}\ninterface A {\n    y: string;\n}\nconst j: A = {\n    x: 'xx',\n    y: 'yy',\n};\n```\n\n扩展其他类型/接口：\n\n类型和接口都可以扩展其他类型/接口，但语法不同。 对于接口，您可以使用“extends”关键字从其他接口继承属性和方法。 但是，接口无法扩展像联合类型这样的复杂类型。\n\n```typescript\ninterface A {\n    x: string;\n    y: number;\n}\ninterface B extends A {\n    z: string;\n}\nconst car: B = {\n    x: 'x',\n    y: 123,\n    z: 'z',\n};\n```\n\n对于类型，您可以使用 & 运算符将多个类型合并为单个类型（交集）。\n\n```typescript\ninterface A {\n    x: string;\n    y: number;\n}\n\ntype B = A & {\n    j: string;\n};\n\nconst c: B = {\n    x: 'x',\n    y: 123,\n    j: 'j',\n};\n```\n\n并集和交集类型：\n\n在定义并集和交集类型时，类型更加灵活。 通过“type”关键字，您可以使用“|”运算符轻松创建联合类型，并使用“&”运算符创建交集类型。 虽然接口也可以间接表示联合类型，但它们没有对交集类型的内置支持。\n\n```typescript\ntype Department = 'dep-x' | 'dep-y'; // 并集\n\ntype Person = {\n    name: string;\n    age: number;\n};\n\ntype Employee = {\n    id: number;\n    department: Department;\n};\n\ntype EmployeeInfo = Person & Employee; // 交集\n```\n\n接口示例：\n\n```typescript\ninterface A {\n    x: 'x';\n}\ninterface B {\n    y: 'y';\n}\n\ntype C = A | B; // 接口的并集\n```\n\n"
  },
  {
    "path": "website/src/content/docs/zh-cn/book/discriminated-unions.md",
    "content": "---\ntitle: 可区分联合\nsidebar:\n  order: 24\n  label: 24. 可区分联合\n---\n\n\nTypeScript 中的可区分联合是一种联合类型，它使用称为判别式的公共属性来缩小联合的可能类型集。\n\n```typescript\ntype Square = {\n    kind: 'square'; // 判别式\n    size: number;\n};\n\ntype Circle = {\n    kind: 'circle'; // 判别式\n    radius: number;\n};\n\ntype Shape = Square | Circle;\n\nconst area = (shape: Shape) => {\n    switch (shape.kind) {\n        case 'square':\n            return Math.pow(shape.size, 2);\n        case 'circle':\n            return Math.PI * Math.pow(shape.radius, 2);\n    }\n};\n\nconst square: Square = { kind: 'square', size: 5 };\nconst circle: Circle = { kind: 'circle', radius: 2 };\n\nconsole.log(area(square)); // 25\nconsole.log(area(circle)); // 12.566370614359172\n```\n\n"
  },
  {
    "path": "website/src/content/docs/zh-cn/book/distributive-conditional-types.md",
    "content": "---\ntitle: 分配条件类型\nsidebar:\n  order: 40\n  label: 40. 分配条件类型\n---\n\n\n分布式条件类型是一种功能，通过单独对联合的每个成员应用转换，允许类型分布在类型的联合上。当使用映射类型或高阶类型时，这尤其有用。\n\n```typescript\ntype Nullable<T> = T extends any ? T | null : never;\ntype NumberOrBool = number | boolean;\ntype NullableNumberOrBool = Nullable<NumberOrBool>; // number | boolean | null\n```\n\n"
  },
  {
    "path": "website/src/content/docs/zh-cn/book/downloads-and-website.md",
    "content": "---\ntitle: 下载和网站\nsidebar:\n  order: 3\n  label: 3. 下载和网站\n---\n\n\n您还可以下载 Epub 版本：\n\n[https://github.com/gibbok/typescript-book/tree/main/downloads](https://github.com/gibbok/typescript-book/tree/main/downloads)\n\n在线版本可在以下位置获得：\n\n[https://gibbok.github.io/typescript-book](https://gibbok.github.io/typescript-book)\n\n"
  },
  {
    "path": "website/src/content/docs/zh-cn/book/enums.md",
    "content": "---\ntitle: 枚举\nsidebar:\n  order: 19\n  label: 19. 枚举\n---\n\n\n在 TypeScript 中，枚举是一组命名常量值。\n\n```typescript\nenum Color {\n    Red = '#ff0000',\n    Green = '#00ff00',\n    Blue = '#0000ff',\n}\n```\n\n枚举可以用不同的方式定义：\n\n### 数字枚举\n\n在 TypeScript 中，数字枚举是一个枚举，其中每个常量都分配有一个数值，默认从 0 开始。\n\n```typescript\nenum Size {\n    Small, // 值从 0 开始\n    Medium,\n    Large,\n}\n```\n\n可以通过显式分配来指定自定义值：\n\n```typescript\nenum Size {\n    Small = 10,\n    Medium,\n    Large,\n}\nconsole.log(Size.Medium); // 11\n```\n\n### 字符串枚举\n\n在 TypeScript 中，字符串枚举是每个常量都分配有一个字符串值的枚举。\n\n```typescript\nenum Language {\n    English = 'EN',\n    Spanish = 'ES',\n}\n```\n\n注意：TypeScript 允许使用异构枚举，其中字符串和数字成员可以共存。\n\n### 常量枚举\n\nTypeScript 中的常量枚举是一种特殊类型的枚举，其中所有值在编译时都是已知的，并且在使用枚举的任何地方都会内联，从而产生更高效的代码。\n\n```typescript\nconst enum Language {\n    English = 'EN',\n    Spanish = 'ES',\n}\nconsole.log(Language.English);\n```\n\n将被编译成：\n\n```typescript\nconsole.log('EN' /* Language.English */);\n```\n\n注意：常量枚举具有硬编码值，擦除枚举，这在独立库中可能更有效，但通常是不可取的。此外，常量枚举不能有计算成员。\n\n### 反向映射\n\n在 TypeScript 中，枚举中的反向映射是指从值中检索枚举成员名称的能力。默认情况下，枚举成员具有从名称到值的正向映射，但可以通过为每个成员显式设置值来创建反向映射。当您需要按枚举成员的值查找枚举成员，或者需要迭代所有枚举成员时，反向映射非常有用。需要注意的是，只有数字类型的枚举成员会生成反向映射，字符串类型的枚举成员则不会。\n\n以下枚举：\n\n```typescript\nenum Grade {\n    A = 90,\n    B = 80,\n    C = 70,\n    F = 'fail',\n}\n```\n\n编译为：\n\n<!-- skip -->\n```javascript\n'use strict';\nvar Grade;\n(function (Grade) {\n    Grade[(Grade['A'] = 90)] = 'A';\n    Grade[(Grade['B'] = 80)] = 'B';\n    Grade[(Grade['C'] = 70)] = 'C';\n    Grade['F'] = 'fail';\n})(Grade || (Grade = {}));\n```\n\n由此可见，对数字类型的枚举成员，可以从枚举值映射回枚举名称，但对字符串类型的枚举成员无法这样做。\n\n<!-- skip -->\n```typescript\nenum Grade {\n    A = 90,\n    B = 80,\n    C = 70,\n    F = 'fail',\n}\nconst myGrade = Grade.A;\nconsole.log(Grade[myGrade]); // A\nconsole.log(Grade[90]); // A\n\nconst failGrade = Grade.F;\nconsole.log(failGrade); // fail\nconsole.log(Grade[failGrade]); // 因为索引表达式的类型不是 'number'，所以元素是隐式的 'any' 类型。\n```\n\n### 环境枚举\n\nTypeScript 中的环境枚举是一种在声明文件 (*.d.ts) 中定义的枚举类型，没有关联的实现。它允许您定义一组命名常量，这些常量可以在不同文件中以类型安全的方式使用，而无需在每个文件中导入实现细节。\n\n### 计算成员和常量成员\n\n在 TypeScript 中，计算成员是枚举的成员，其值在运行时计算，而常量成员是其值在编译时设置且在运行时无法更改的成员。常规枚举中允许使用计算成员，而常规枚举和常量枚举中都允许使用常量成员。\n\n```typescript\n// 常量成员\nenum Color {\n    Red = 1,\n    Green = 5,\n    Blue = Red + Green,\n}\nconsole.log(Color.Blue); // 6 编译时生成\n```\n\n```typescript\n// 计算成员\nenum Color {\n    Red = 1,\n    Green = Math.pow(2, 2),\n    Blue = Math.floor(Math.random() * 3) + 1,\n}\nconsole.log(Color.Blue); // 运行时生成的随机数\n```\n\n枚举由包含其成员类型的联合表示。每个成员的值可以通过常量或非常量表达式确定，拥有常量值的成员被分配字面量类型。为了说明这一点，请考虑类型 E 及其子类型 E.A、E.B 和 E.C 的声明。在本例中，E 表​​示联合 E.A | E.B | E.C 。\n\n```typescript\nconst identity = (value: number) => value;\n\nenum E {\n    A = 2 * 5, // 数字字面量\n    B = 'bar', // 字符串字面量\n    C = identity(42), // 不透明计算\n}\n\nconsole.log(E.C); //42\n```\n\n"
  },
  {
    "path": "website/src/content/docs/zh-cn/book/erased-structural-types.md",
    "content": "---\ntitle: 擦除的结构类型\nsidebar:\n  order: 56\n  label: 56. 擦除的结构类型\n---\n\n\n在 TypeScript 中，对象不必匹配特定的、精确的类型。例如，如果我们创建一个满足接口要求的对象，我们就可以在需要该接口的地方使用该对象，即使它们之间没有显式连接。例子：\n\n```typescript\ntype NameProp1 = {\n    prop1: string;\n};\n\nfunction log(x: NameProp1) {\n    console.log(x.prop1);\n}\n\nconst obj = {\n    prop2: 123,\n    prop1: 'Origin',\n};\n\nlog(obj); // 有效\n```\n\n"
  },
  {
    "path": "website/src/content/docs/zh-cn/book/exhaustiveness-checking.md",
    "content": "---\ntitle: 详尽性检查\nsidebar:\n  order: 26\n  label: 26. 详尽性检查\n---\n\n\n详尽性检查是 TypeScript 中的一项功能，可确保在 `switch` 语句或 `if` 语句中处理可区分联合的所有可能情况。\n\n```typescript\ntype Direction = 'up' | 'down';\n\nconst move = (direction: Direction) => {\n    switch (direction) {\n        case 'up':\n            console.log('Moving up');\n            break;\n        case 'down':\n            console.log('Moving down');\n            break;\n        default:\n            const exhaustiveCheck: never = direction;\n            console.log(exhaustiveCheck); // 这行永远不会被执行\n    }\n};\n```\n\n该 `never` 类型用于确保默认情况是详尽的，并且如果将新值添加到 Direction 类型而未在 switch 语句中进行处理，则 TypeScript 将引发错误。\n\n"
  },
  {
    "path": "website/src/content/docs/zh-cn/book/exploring-the-type-system.md",
    "content": "---\ntitle: 探索类型系统\nsidebar:\n  order: 9\n  label: 9. 探索类型系统\n---\n\n\n### TypeScript 的语言服务\n\nTypeScript 的语言服务, 也被称为 tsserver，提供了各种功能，例如错误报告、诊断、保存时编译、重命名、跳转到定义、补全列表、签名帮助等。 它主要由集成开发环境 (IDE) 使用来提供 IntelliSense 支持。它与 Visual Studio Code 无缝集成，并由 Conquer of Completion (Coc) 等工具使用。\n\n开发人员可以利用专用 API 并创建自己的自定义语言服务插件来增强 TypeScript 编辑体验。这对于实现特殊的 linting 功能或启用自定义模板语言的自动完成特别有用。\n\n<!-- markdownlint-disable MD044 -->\n现实世界中的自定义插件的一个示例是\"typescript-styled-plugin\"，它为样式组件中的 CSS 属性提供语法错误报告和 IntelliSense 支持。\n<!-- markdownlint-enable MD044 -->\n\n有关更多信息和快速入门指南，您可以参考 GitHub 上的官方 TypeScript Wiki： [https://github.com/microsoft/TypeScript/wiki/](https://github.com/microsoft/TypeScript/wiki/)\n\n### 结构类型\n\nTypeScript 基于结构类型系统。这意味着类型的兼容性和等效性由类型的实际结构或定义决定，而不是由其名称或声明位置决定，如 C# 或 C 等主要类型系统中那样。\n\nTypeScript 的结构类型系统是基于 JavaScript 的动态 duck 类型系统在运行时的工作方式而设计的。\n\n以下示例是有效的 TypeScript 代码。正如您所观察到的，\"X\"和\"Y\"具有相同的成员\"a\"，尽管它们具有不同的声明名称。类型由其结构决定，在这种情况下，由于结构相同，因此它们是兼容且有效的。\n\n```typescript\ntype X = {\n    a: string;\n};\ntype Y = {\n    a: string;\n};\nconst x: X = { a: 'a' };\nconst y: Y = x; // 有效\n```\n\n### TypeScript 的基本比较规则\n\nTypeScript 比较过程是递归的，并在任何级别嵌套的类型上执行。\n\n如果\"Y\"至少具有与\"X\"相同的成员，则类型\"X\"与\"Y\"兼容。\n\n```typescript\ntype X = {\n    a: string;\n};\nconst y = { a: 'A', b: 'B' }; // 有效, 至少它拥有相同的成员 X\nconst r: X = y;\n```\n\n函数参数按类型进行比较，而不是按名称进行比较：\n\n```typescript\ntype X = (a: number) => void;\ntype Y = (a: number) => void;\nlet x: X = (j: number) => undefined;\nlet y: Y = (k: number) => undefined;\ny = x; // 有效\nx = y; // 有效\n```\n\n函数返回类型必须相同：\n\n<!-- skip -->\n```typescript\ntype X = (a: number) => undefined;\ntype Y = (a: number) => number;\nlet x: X = (a: number) => undefined;\nlet y: Y = (a: number) => 1;\ny = x; // 无效\nx = y; // 无效\n```\n\n源函数的返回类型必须是目标函数的返回类型的子类型：\n\n<!-- skip -->\n```typescript\nlet x = () => ({ a: 'A' });\nlet y = () => ({ a: 'A', b: 'B' });\nx = y; // 有效\ny = x; // 无效，缺少 b 成员\n```\n\n允许丢弃函数参数，因为这是 JavaScript 中的常见做法，例如使用 \"Array.prototype.map()\"：\n\n```typescript\n[1, 2, 3].map((element, _index, _array) => element + 'x');\n```\n\n因此，以下类型声明是完全有效的：\n\n```typescript\ntype X = (a: number) => undefined;\ntype Y = (a: number, b: number) => undefined;\nlet x: X = (a: number) => undefined;\nlet y: Y = (a: number) => undefined; // 缺少 b 参数\ny = x; // 有效\n```\n\n源类型的任何附加可选参数都是有效的：\n\n```typescript\ntype X = (a: number, b?: number, c?: number) => undefined;\ntype Y = (a: number) => undefined;\nlet x: X = a => undefined;\nlet y: Y = a => undefined;\ny = x; // 有效\nx = y; // 有效\n```\n\n目标类型的任何可选参数在源类型中没有对应的参数都是有效的并且不是错误：\n\n```typescript\ntype X = (a: number) => undefined;\ntype Y = (a: number, b?: number) => undefined;\nlet x: X = a => undefined;\nlet y: Y = a => undefined;\ny = x; // 有效\nx = y; // 有效\n```\n\n其余参数被视为无限系列的可选参数：\n\n```typescript\ntype X = (a: number, ...rest: number[]) => undefined;\nlet x: X = a => undefined; // 有效\n```\n\n如果重载签名与其实现签名兼容，则具有重载的函数有效：\n\n<!-- skip -->\n```typescript\nfunction x(a: string): void;\nfunction x(a: string, b: number): void;\nfunction x(a: string, b?: number): void {\n    console.log(a, b);\n}\nx('a'); // 有效\nx('a', 1); // 有效\n\nfunction y(a: string): void; // 无效, 不兼容重载的签名\nfunction y(a: string, b: number): void;\nfunction y(a: string, b: number): void {\n    console.log(a, b);\n}\ny('a');\ny('a', 1);\n```\n\n如果源参数和目标参数可赋值给超类型或子类型（Bivariance 双变），则函数参数比较成功。\n\n```typescript\n// 超类\nclass X {\n    a: string;\n    constructor(value: string) {\n        this.a = value;\n    }\n}\n// 子类\nclass Y extends X {}\n// 子类\nclass Z extends X {}\n\ntype GetA = (x: X) => string;\nconst getA: GetA = x => x.a;\n\n// 双变（Bivariance） 确实接收超类\nconsole.log(getA(new X('x'))); // 有效\nconsole.log(getA(new Y('Y'))); // 有效\nconsole.log(getA(new Z('z'))); // 有效\n```\n\n枚举与数字具有可比性和有效性，反之亦然，但比较不同枚举类型的枚举值是无效的。\n\n<!-- skip -->\n```typescript\nenum X {\n    A,\n    B,\n}\nenum Y {\n    A,\n    B,\n    C,\n}\nconst xa: number = X.A; // 有效\nconst ya: Y = 0; // 有效\nX.A === Y.A; // 无效\n```\n\n类的实例需要对其私有成员和受保护成员进行兼容性检查：\n\n<!-- skip -->\n```typescript\nclass X {\n    public a: string;\n    constructor(value: string) {\n        this.a = value;\n    }\n}\n\nclass Y {\n    private a: string;\n    constructor(value: string) {\n        this.a = value;\n    }\n}\n\nlet x: X = new Y('y'); // 无效\n```\n\n比较检查不考虑不同的继承层次结构，例如：\n\n```typescript\nclass X {\n    public a: string;\n    constructor(value: string) {\n        this.a = value;\n    }\n}\nclass Y extends X {\n    public a: string;\n    constructor(value: string) {\n        super(value);\n        this.a = value;\n    }\n}\nclass Z {\n    public a: string;\n    constructor(value: string) {\n        this.a = value;\n    }\n}\nlet x: X = new X('x');\nlet y: Y = new Y('y');\nlet z: Z = new Z('z');\nx === y; // 有效\nx === z; // 有效即使 z 来自不同的继承层次结构\n```\n\n泛型根据应用泛型参数后的结果类型使用其结构进行比较，仅将最终结果作为非泛型类型进行比较。\n\n<!-- skip -->\n```typescript\ninterface X<T> {\n    a: T;\n}\nlet x: X<number> = { a: 1 };\nlet y: X<string> = { a: 'a' };\nx === y; // 无效，因为最终结构中使用了类型参数\n```\n\n```typescript\ninterface X<T> {}\nconst x: X<number> = 1;\nconst y: X<string> = 'a';\nx === y; // 有效，因为最终结构中没有使用类型参数\n```\n\n当泛型未指定其类型参数时，所有未指定的参数都将被视为带有\"any\"的类型：\n\n```typescript\ntype X = <T>(x: T) => T;\ntype Y = <K>(y: K) => K;\nlet x: X = x => x;\nlet y: Y = y => y;\nx = y; // 有效\n```\n\n记住：\n\n<!-- skip -->\n```typescript\nlet a: number = 1;\nlet b: number = 2;\na = b; // 有效，一切都可以赋值给自己\n\nlet c: any;\nc = 1; // 有效，所有类型都可以赋值给any\n\nlet d: unknown;\nd = 1; // 有效，所有类型都可以赋值给unknown\n\nlet e: unknown;\nlet e1: unknown = e; // 有效, unknown只能赋值给自己和any\nlet e2: any = e; // 有效\nlet e3: number = e; // 无效\n\nlet f: never;\nf = 1; // 无效, 所有类型不能赋值给never\n\nlet g: void;\nlet g1: any;\ng = 1; // 无效, void不可赋值给除\"any\"之外的任何内容或从任何内容赋值\ng = g1; // 有效\n```\n\n请注意，当启用\"strictNullChecks\"时，\"null\"和\"undefined\"的处理方式与\"void\"类似；否则，它们类似于\"never\"。\n\n### 类型作为集合\n\n在 TypeScript 中，类型是一组可能的值。该集合也称为类型的域。类型的每个值都可以被视为集合中的一个元素。类型建立了集合中的每个元素必须满足才能被视为该集合的成员的约束。TypeScript 的主要任务是检查并验证一组是否是另一组的子集。\n\nTypeScript 支持各种类型的集合：\n\n| Set term | TypeScript                      | Notes                                                                          |\n| -------- | ------------------------------- | ------------------------------------------------------------------------------ |\n| 空集     | never                           | \"never\" 包含除自身之外的任何类型                                               |\n| 单元素集 | undefined / null / literal type |                                                                                |\n| 有限集   | boolean / union                 |                                                                                |\n| 无限集   | string / number / object        |                                                                                |\n| 通用集   | any / unknown                   | 每个元素都是\"any\"的成员，每个集合都是它的子集/\"unknown\"是\"any\"的类型安全对应项 |\n\n这里有几个例子：\n\n| TypScript             | Set term         | Example                                                          |\n| --------------------- | ---------------- | ---------------------------------------------------------------- |\n| never                 | ∅ (空集)         | const x: never = 'x'; // 错误: 'string'类似不能赋值给'never'类型 |\n|                       |                  |\n| Literal type          | 单元素集         | type X = 'X';                                                    |\n|                       |                  | type Y = 7;                                                      |\n|                       |                  |\n| Value assignable to T | Value ∈ T (属于) | type XY = 'X' \\| 'Y';                                            |\n|                       |                  | const x: XY = 'X';                                               |\n|                       |                  |\n| T1 assignable to T2   | T1 ⊆ T2 (子集)   | type XY = 'X' \\| 'Y';                                            |\n|                       |                  | const x: XY = 'X';                                               |\n|                       |                  | const j: XY = 'J'; // 类型'\"J\"' 不能赋值给 'XY' 类型.            |\n|                       |                  |                                                                  |\n| T1 extends T2         | T1 ⊆ T2 (子集)   | type X = 'X' extends string ? true : false;                      |\n|                       |                  |\n| T1 \\| T2              | T1 ∪ T2 (并集)   | type XY = 'X' \\| 'Y';                                            |\n|                       |                  | type JK = 1 \\| 2;                                                |\n|                       |                  |\n| T1 & T2               | T1 ∩ T2 (交集)   | type X = \\{ a: string \\}                                           |\n|                       |                  | type Y = \\{ b: string \\}                                           |\n|                       |                  | type XY = X & Y                                                  |\n|                       |                  | const x: XY = \\{ a: 'a', b: 'b' \\}                                 |\n|                       |                  |\n| unknown               | 通用集           | const x: unknown = 1                                             |\n\n并集 (T1 | T2) 创建一个更广泛的集合（两者）：\n\n```typescript\ntype X = {\n    a: string;\n};\ntype Y = {\n    b: string;\n};\ntype XY = X | Y;\nconst r: XY = { a: 'a', b: 'x' }; // 有效\n```\n\n交集（T1 & T2）创建一个更窄的集合（仅共享）：\n\n<!-- skip -->\n```typescript\ntype X = {\n    a: string;\n};\ntype Y = {\n    a: string;\n    b: string;\n};\ntype XY = X & Y;\nconst r: XY = { a: 'a' }; // 无效\nconst j: XY = { a: 'a', b: 'b' }; // 有效\n```\n\n在这种情况下，关键字extends可以被视为\"的子集\"。它为类型设置约束。与泛型一起使用的扩展将泛型视为无限集，并将其限制为更具体的类型。请注意，这extends与 OOP 意义上的层次结构无关（TypScript 中没有这个概念）。TypeScript 使用集合并且没有严格的层次结构，事实上，如下面的示例所示，两种类型可以重叠，而不会成为另一种类型的子类型（TypScript 考虑对象的结构和形状）。\n\n```typescript\ninterface X {\n    a: string;\n}\ninterface Y extends X {\n    b: string;\n}\ninterface Z extends Y {\n    c: string;\n}\nconst z: Z = { a: 'a', b: 'b', c: 'c' };\ninterface X1 {\n    a: string;\n}\ninterface Y1 {\n    a: string;\n    b: string;\n}\ninterface Z1 {\n    a: string;\n    b: string;\n    c: string;\n}\nconst z1: Z1 = { a: 'a', b: 'b', c: 'c' };\n\nconst r: Z1 = z; // 有效\n```\n\n### 赋值类型：类型声明和类型断言\n\n在 TypeScript 中可以通过不同的方式赋值类型：\n\n#### 类型声明\n\n在下面的示例中，我们使用 x:X(\":Type\") 来声明变量 x 的类型。\n\n```typescript\ntype X = {\n    a: string;\n};\n\n// 类型声明\nconst x: X = {\n    a: 'a',\n};\n```\n\n如果变量不是指定的格式，TypeScript 将报告错误。例如：\n\n<!-- skip -->\n```typescript\ntype X = {\n    a: string;\n};\n\nconst x: X = {\n    a: 'a',\n    b: 'b', // 错误: 对象字面量只能指定已知属性\n};\n```\n\n#### 类型断言\n\n可以使用as关键字添加断言。这告诉编译器开发人员拥有有关类型的更多信息并消除可能发生的任何错误。\n\n例如：\n\n```typescript\ntype X = {\n    a: string;\n};\nconst x = {\n    a: 'a',\n    b: 'b',\n} as X;\n```\n\n在上面的示例中，使用 as 关键字将对象 x 断言为类型 X。这通知 TypeScript 编译器该对象符合指定的类型，即使它具有类型定义中不存在的附加属性 b。\n\n类型断言在需要指定更具体类型的情况下非常有用，尤其是在使用 DOM 时。例如：\n\n```typescript\nconst myInput = document.getElementById('my_input') as HTMLInputElement;\n```\n\n此处，类型断言 HTMLInputElement 用于告诉 TypeScript getElementById 的结果应被视为 HTMLInputElement。类型断言还可以用于重新映射键，如下面使用模板文字的示例所示：\n\n```typescript\ntype J<Type> = {\n    [Property in keyof Type as `prefix_${string &\n        Property}`]: () => Type[Property];\n};\ntype X = {\n    a: string;\n    b: number;\n};\ntype Y = J<X>;\n```\n\n在此示例中，类型 J 使用带有模板文字的映射类型来重新映射 Type 的键。它创建新属性，并在每个键上添加 prefix_ ，它们对应的值是返回原始属性值的函数。\n\n值得注意的是，当使用类型断言时，TypeScript 不会执行多余的属性检查。因此，当预先知道对象的结构时，通常最好使用类型声明。\n\n#### 非空断言\n\n此断言是使用后缀表达式!运算符应用的，它告诉 TypeScript 值不能为 null 或未定义。\n\n```typescript\nlet x: null | number;\nlet y = x!; // number\n```\n\n#### 环境声明\n\n环境声明是描述 JavaScript 代码类型的文件，它们的文件名格式为.d.ts.. 它们通常被导入并用于注释现有的 JavaScript 库或向项目中的现有 JS 文件添加类型。\n\n许多常见的库类型可以在以下位置找到：\n[https://github.com/DefinitelyTyped/DefinitelyTyped/](https://github.com/DefinitelyTyped/DefinitelyTyped/)\n\n```shell\nnpm install --save-dev @types/library-name\n```\n\n对于您定义的环境声明，您可以使用\"三斜杠\"引用导入：\n\n<!-- skip -->\n```typescript\n/// <reference path=\"./library-types.d.ts\" />\n```\n\n即使在 JavaScript 文件中，您也可以通过 `// @ts-check` 使用环境声明。\n\n`declare` 关键字可以为现有的 JavaScript 代码启用类型定义，而无需导入它，作为来自另一个文件或全局的类型的占位符。\n\n### 属性检测和多余属性检测\n\nTypeScript 基于结构类型系统，但过多的属性检查是 TypeScript 的一个属性，它允许它检查对象是否具有类型中指定的确切属性。\n\n例如，在将对象字面量赋值给变量或将它们作为参数传递给函数的多余属性时，会执行多余属性检查。\n\n<!-- skip -->\n```typescript\ntype X = {\n    a: string;\n};\nconst y = { a: 'a', b: 'b' };\nconst x: X = y; // 有效，因为结构类型\nconst w: X = { a: 'a', b: 'b' }; // 无效，因为多余属性检测\n```\n\n### 弱类型\n\n当一个类型只包含一组全可选属性时，该类型被认为是弱类型：\n\n```typescript\ntype X = {\n    a?: string;\n    b?: string;\n};\n```\n\n当没有重叠时，TypeScript 认为将任何内容赋值给弱类型是错误的，例如，以下会引发错误：\n\n<!-- skip -->\n```typescript\ntype Options = {\n    a?: string;\n    b?: string;\n};\n\nconst fn = (options: Options) => undefined;\n\nfn({ c: 'c' }); // 无效\n```\n\n尽管不推荐，但如果需要，可以使用类型断言绕过此检查：\n\n```typescript\ntype Options = {\n    a?: string;\n    b?: string;\n};\nconst fn = (options: Options) => undefined;\nfn({ c: 'c' } as Options); // 有效\n```\n\n或者通过将unknown索引签名添加到弱类型：\n\n```typescript\ntype Options = {\n    [prop: string]: unknown;\n    a?: string;\n    b?: string;\n};\n\nconst fn = (options: Options) => undefined;\nfn({ c: 'c' }); // 有效\n```\n\n### 严格的对象字面量检测 (Freshness)\n\n严格的对象字面量检查（有时称为“新鲜度”）是 TypeScript 中的一项功能，有助于捕获多余或拼写错误的属性，否则这些属性在正常结构类型检查中会被忽视。\n\n创建对象字面量时，TypeScript 编译器认为它是“新鲜的”。 如果将对象字面量分配给变量或作为参数传递，并且对象字面量指定目标类型中不存在的属性，则 TypeScript 将引发错误。\n\n然而，当扩展对象文字或使用类型断言时，“新鲜感”就会消失。\n\n下面举一些例子来说明：\n\n<!-- skip -->\n```typescript\ntype X = { a: string };\ntype Y = { a: string; b: string };\n\nlet x: X;\nx = { a: 'a', b: 'b' }; // 严格的对象字面量检查：无效的赋值\nvar y: Y;\ny = { a: 'a', bx: 'bx' }; // 严格的对象字面量检查：无效的赋值\n\nconst fn = (x: X) => console.log(x.a);\n\nfn(x);\nfn(y); // 类型加宽：没有错误, 结构类型兼容\n\nfn({ a: 'a', bx: 'b' }); // 严格的对象字面量检查：无效的参数\n\nlet c: X = { a: 'a' };\nlet d: Y = { a: 'a', b: '' };\nc = d; // 类型加宽：没有严格的对象字面量检查\n```\n\n### 类型推断\n\n当在以下期间未提供注释时，TypeScript 可以推断类型：\n\n* 变量初始化\n* 成员初始化。\n* 设置参数的默认值。\n* 函数返回类型。\n\n例如：\n\n```typescript\nlet x = 'x'; // 推断的类型是 string\n```\n\nTypeScript 编译器分析值或表达式并根据可用信息确定其类型。\n\n### 更高级的推断\n\n当在类型推断中使用多个表达式时，TypeScript 会查找\"最佳常见类型\"。例如：\n\n```typescript\nlet x = [1, 'x', 1, null]; // 类型推断为: (string | number | null)[]\n```\n\n如果编译器找不到最佳通用类型，它将返回联合类型。例如：\n\n```typescript\nlet x = [new RegExp('x'), new Date()]; // 类型推断为: (RegExp | Date)[]\n```\n\nTypeScript 利用基于变量位置的\"上下文类型\"来推断类型。在下面的示例中，编译器知道它的e类型是MouseEvent，因为在lib.d.ts 文件中定义了click事件类型，该文件包含各种常见 JavaScript 构造和 DOM 的环境声明：\n\n```typescript\nwindow.addEventListener('click', function (e) {}); // e 的类型被推断为 MouseEvent\n```\n\n### 类型加宽\n\n类型加宽是 TypeScript 将类型分配给未提供类型注释时初始化的变量的过程。它允许从窄到宽的类型，但反之则不然。在以下示例中：\n\n<!-- skip -->\n```typescript\nlet x = 'x'; // TypeScript 推断为字符串，一种宽类型\nlet y: 'y' | 'x' = 'y'; // y 类型是字面量类型的联合\ny = x; // 无效，字符串不可分配给类型 'x' | 'y'。\n```\n\nTypeScript根据初始化期间提供的单个值（`x`），将 `string` 赋予给 `x`，这是一个扩展的示例。\n\nTypeScript 提供了控制加宽过程的方法，例如使用\"const\"。\n\n### 常量\n\n在声明变量时使用 `const` 关键字会导致 TypeScript 中的类型推断范围更窄。\n\nFor example:\n\n```typescript\nconst x = 'x'; // TypeScript 将 'x' 推断为带有 'const'（不可变）的字符串字面量，但将其扩展为带有 'let'（可重新赋值）的 'string'。\nlet y: 'y' | 'x' = 'y';\ny = x; // 有效: x的类型推断为 'x'\n```\n\n通过使用 const 声明变量 x，其类型被缩小为特定的文字值\"x\"。由于 x 的类型被缩小，因此可以将其赋值给变量 y 而不会出现任何错误。可以推断类型的原因是因为 const 变量无法重新分配，因此它们的类型可以缩小到特定的文字类型，在本例中为字面量类型\"x\"。\n\n#### 类型参数的 const 修饰符\n\n从 TypeScript 5.0 版本开始，可以 `const` 在泛型类型参数上指定属性。这可以推断出最精确的类型。让我们看一个不使用 `const` 的示例：\n\n```typescript\nfunction identity<T>(value: T) {\n    // 这里没有const\n    return value;\n}\nconst values = identity({ a: 'a', b: 'b' }); // 类型推断为: { a: string; b: string; }\n```\n\n正如您所看到的，属性a和b是通过 类型推断出来的string 。\n\n现在，让我们看看 `const` 版本的差异：\n\n```typescript\nfunction identity<const T>(value: T) {\n    // 对类型参数使用 const 修饰符\n    return value;\n}\nconst values = identity({ a: 'a', b: 'b' }); // 类型推断为: { a: \"a\"; b: \"b\"; }\n```\n\n现在我们可以看到属性 `a` 和 `b` 被推断为const，因此 `a` 和 `b`被视为字符串文字而不仅仅是 `string` 类型。\n\n### 常量断言\n\n此功能允许您根据变量的初始化值声明具有更精确的文字类型的变量，这向编译器表明该值应被视为不可变文字。 这里有一些例子：\n\n在单个属性上：\n\n```typescript\nconst v = {\n    x: 3 as const,\n};\nv.x = 3;\n```\n\n在整个对象上：\n\n```typescript\nconst v = {\n    x: 1,\n    y: 2,\n} as const;\n```\n\n这在定义元组的类型时特别有用：\n\n```typescript\nconst x = [1, 2, 3]; // number[]\nconst y = [1, 2, 3] as const; // 只读数组 [1, 2, 3]\n```\n\n### 显式类型注释\n\n我们可以具体地传递一个类型，在下面的示例中，属性x的类型是number：\n\n```typescript\nconst v = {\n    x: 1, // 推断类型: number (加宽了)\n};\nv.x = 3; // 有效\n```\n\n我们可以通过使用字面量类型的联合使类型注释更加具体：\n\n<!-- skip -->\n```typescript\nconst v: { x: 1 | 2 | 3 } = {\n    x: 1, // x 现在是字面量的联合类型： 1 | 2 | 3\n};\nv.x = 3; // 有效\nv.x = 100; // 无效的\n```\n\n### 类型缩小\n\n类型缩小是 TypeScript 中的一个过程，其中一般类型缩小为更具体的类型。当 TypeScript 分析代码并确定某些条件或操作可以细化类型信息时，就会发生这种情况。\n\n缩小类型可以通过不同的方式发生，包括：\n\n#### 条件\n\n通过使用条件语句（比如 `if` 或 `switch`），TypeScript 可以根据条件的结果缩小类型范围。例如：\n\n```typescript\nlet x: number | undefined = 10;\n\nif (x !== undefined) {\n    x += 100; // 由于条件判断，类型被缩小为 number\n}\n```\n\n#### 抛错或者返回\n\n抛出错误或从分支提前返回可用于帮助 TypeScript 缩小类型范围。例如：\n\n```typescript\nlet x: number | undefined = 10;\n\nif (x === undefined) {\n    throw 'error';\n}\nx += 100;\n```\n\n在 TypeScript 中缩小类型范围的其他方法包括：\n\n* `instanceof` 操作: 用于检查对象是否是特定类的实例。\n* `in` 操作: 用于检查对象中是否存在属性。\n* `typeof` 操作: 用于在运行时检查值的类型。\n* 内部函数，比如: `Array.isArray()`: 用于检查值是否为数组。\n\n#### 可区分联合\n\n使用\"可区分联合\"是 TypeScript 中的一种模式，其中向对象添加显式\"标签\"以区分联合内的不同类型。该模式也称为\"标记联合\"。在以下示例中，\"tag\"由属性\"type\"表示：\n\n```typescript\ntype A = { type: 'type_a'; value: number };\ntype B = { type: 'type_b'; value: string };\n\nconst x = (input: A | B): string | number => {\n    switch (input.type) {\n        case 'type_a':\n            return input.value + 100; // 类型为 A\n        case 'type_b':\n            return input.value + 'extra'; // 类型为 B\n    }\n};\n```\n\n#### 用户定义的类型保护\n\n在 TypeScript 无法确定类型的情况下，可以编写一个称为\"用户定义类型保护\"的辅助函数。在下面的示例中，我们将在应用某些过滤后利用类型谓词来缩小类型范围：\n\n```typescript\nconst data = ['a', null, 'c', 'd', null, 'f'];\n\nconst r1 = data.filter(x => x != null); // 类型为 (string | null)[], TypeScript 不能准确推断类型\n\nconst isValid = (item: string | null): item is string => item !== null; // 自定义类型保护\n\nconst r2 = data.filter(isValid); // 类型现在为 string[], 通过使用断言类型保护，我们能够缩小类型\n```\n\n"
  },
  {
    "path": "website/src/content/docs/zh-cn/book/extending-types.md",
    "content": "---\ntitle: 扩展类型\nsidebar:\n  order: 15\n  label: 15. 扩展类型\n---\n\n\n可以扩展 `interface`（从另一种类型复制成员）：\n\n```typescript\ninterface X {\n    a: string;\n}\ninterface Y extends X {\n    b: string;\n}\n```\n\n还可以从多种 `interface` 进行扩展：\n\n```typescript\ninterface A {\n    a: string;\n}\ninterface B {\n    b: string;\n}\ninterface Y extends A, B {\n    y: string;\n}\n```\n\n该 `extends` 关键字仅适用于 `interface`，因为 `type` 使用交集：\n\n```typescript\ntype A = {\n    a: number;\n};\ntype B = {\n    b: number;\n};\ntype C = A & B;\n```\n\n可以使用 `interface` 来扩展类 `type`，但反之则不然：\n\n```typescript\ntype A = {\n    a: string;\n};\ninterface B extends A {\n    b: string;\n}\n```\n\n"
  },
  {
    "path": "website/src/content/docs/zh-cn/book/fixed-length-tuple.md",
    "content": "---\ntitle: 固定长度元组\nsidebar:\n  order: 30\n  label: 30. 固定长度元组\n---\n\n\n固定长度元组是一种特定类型的元组，它强制执行特定类型的固定数量的元素，并且一旦定义元组就不允许对其长度进行任何修改。\n\n当您需要表示具有特定数量的元素和特定类型的值的集合，并且您希望确保元组的长度和类型不会无意中更改时，固定长度元组非常有用。\n\n<!-- skip -->\n```typescript\nconst x = [10, 'hello'] as const;\nx.push(2); // 错误\n```\n\n"
  },
  {
    "path": "website/src/content/docs/zh-cn/book/generics.md",
    "content": "---\ntitle: 泛型\nsidebar:\n  order: 55\n  label: 55. 泛型\n---\n\n\n泛型允许您创建可与多种类型一起使用的可重用组件和函数。使用泛型，您可以参数化类型、函数和接口，从而允许它们对不同类型进行操作，而无需事先显式指定它们。\n\n泛型允许您使代码更加灵活和可重用。\n\n### 泛型类型\n\n要定义泛型类型，可以使用尖括号 (`<>`) 来指定类型参数，例如：\n\n```typescript\nfunction identity<T>(arg: T): T {\n    return arg;\n}\nconst a = identity('x');\nconst b = identity(123);\n\nconst getLen = <T,>(data: ReadonlyArray<T>) => data.length;\nconst len = getLen([1, 2, 3]);\n```\n\n### 泛型类\n\n泛型也可以应用于类，这样它们就可以通过使用类型参数来处理多种类型。这对于创建可重用的类定义非常有用，这些定义可以在保持类型安全的同时对不同的数据类型进行操作。\n\n```typescript\nclass Container<T> {\n    private item: T;\n\n    constructor(item: T) {\n        this.item = item;\n    }\n\n    getItem(): T {\n        return this.item;\n    }\n}\n\nconst numberContainer = new Container<number>(123);\nconsole.log(numberContainer.getItem()); // 123\n\nconst stringContainer = new Container<string>('hello');\nconsole.log(stringContainer.getItem()); // hello\n```\n\n### 泛型约束\n\n可以使用关键字 `extends` 后跟类型参数必须满足的类型或接口来约束泛型参数。\n\n在下面的示例中，T 必须正确包含 `length` 才能有效：\n\n<!-- skip -->\n```typescript\nconst printLen = <T extends { length: number }>(value: T): void => {\n    console.log(value.length);\n};\n\nprintLen('Hello'); // 5\nprintLen([1, 2, 3]); // 3\nprintLen({ length: 10 }); // 10\nprintLen(123); // 无效\n```\n\n3.4 RC 版中引入的泛型的一个有趣功能是高阶函数类型推断，它引入了传播泛型类型参数：\n\n```typescript\ndeclare function pipe<A extends any[], B, C>(\n    ab: (...args: A) => B,\n    bc: (b: B) => C\n): (...args: A) => C;\n\ndeclare function list<T>(a: T): T[];\ndeclare function box<V>(x: V): { value: V };\n\nconst listBox = pipe(list, box); // <T>(a: T) => { value: T[] }\nconst boxList = pipe(box, list); // <V>(x: V) => { value: V }[]\n```\n\n此功能允许更轻松地键入安全的无点风格编程，这在函数式编程中很常见。\n\n### 泛型上下文缩小\n\n泛型上下文缩小是 TypeScript 中的机制，允许编译器根据使用泛型参数的上下文来缩小泛型参数的类型，在条件语句中使用泛型类型时非常有用：\n\n```typescript\nfunction process<T>(value: T): void {\n    if (typeof value === 'string') {\n        // Value 的类型被缩小到 'string' 类型\n        console.log(value.length);\n    } else if (typeof value === 'number') {\n        // Value 的类型被缩小到 'number' 类型\n        console.log(value.toFixed(2));\n    }\n}\n\nprocess('hello'); // 5\nprocess(3.14159); // 3.14\n```\n\n"
  },
  {
    "path": "website/src/content/docs/zh-cn/book/getting-started-with-typescript.md",
    "content": "---\ntitle: TypeScript 入门\nsidebar:\n  order: 8\n  label: 8. TypeScript 入门\n---\n\n\n### 安装\n\nVisual Studio Code 为 TypeScript 语言提供了出色的支持，但不包含 TypeScript 编译器。要安装 TypeScript 编译器，您可以使用包管理器，例如 npm 或yarn：\n\n```shell\nnpm install typescript --save-dev\n```\n\n或者\n\n```shell\nyarn add typescript --dev\n```\n\n确保提交生成的锁定文件，以确保每个团队成员使用相同版本的 TypeScript。\n\n要运行TypeScript编译器，可以使用以下命令\n\n```shell\nnpx tsc\n```\n\n或者\n\n```shell\nyarn tsc\n```\n\n建议按项目安装 TypeScript，而不是全局安装，因为它提供了更可预测的构建过程。但是，对于一次性情况，您可以使用以下命令：\n\n```shell\nnpx tsc\n```\n\n或者安装到全局：\n\n```shell\nnpm install -g typescript\n```\n\n如果您使用的是 Microsoft Visual Studio，则可以在 NuGet 中为 MSBuild 项目获取作为包的 TypeScript。在 NuGet 包管理器控制台中，运行以下命令：\n\n```shell\nInstall-Package Microsoft.TypeScript.MSBuild\n```\n\n在 TypeScript 安装过程中，会安装两个可执行文件：\"tsc\"作为 TypeScript 编译器，\"tsserver\"作为 TypeScript 独立服务器。独立服务器包含编译器和语言服务，编辑器和 IDE 可以利用它们来提供智能代码补全。\n\n此外，还有几种兼容 TypeScript 的转译器可用，例如 Babel（通过插件）或 swc。这些转译器可用于将 TypeScript 代码转换为其他目标语言或版本。\n\n### 配置\n\n可以使用 tsc CLI 选项或利用位于项目根目录中名为 tsconfig.json 的专用配置文件来配置 TypeScript。\n\n要生成预填充推荐设置的 tsconfig.json 文件，您可以使用以下命令：\n\n```shell\ntsc --init\n```\n\n在本地执行tsc命令时，TypeScript 将使用最近的 tsconfig.json 文件中指定的配置来编译代码。\n\n以下是使用默认设置运行的 CLI 命令的一些示例：\n\n```shell\ntsc main.ts // 将一个特定的文件 (main.ts) 编译成 JavaScript\ntsc src/*.ts // 将 'src' 文件夹下任意的 .ts 文件编译成 JavaScript\ntsc app.ts util.ts --outfile index.js // 将 2 个 TypeScript 文件 (app.ts 和 util.ts) 编译成 1 个 JavaScript 文件 (index.js)\n```\n\n### TypeScript 的配置文件\n\ntsconfig.json 文件用于配置 TypeScript 编译器 (tsc)。通常，它与文件一起添加到项目的根目录中package.json。\n\n注意：\n\n* tsconfig.json 即使是 json 格式也接受注释。\n* 建议使用此配置文件而不是命令行选项。\n\n在以下链接中，您可以找到完整的文档及其配置示例：\n\n[https://www.typescriptlang.org/tsconfig](https://www.typescriptlang.org/tsconfig)\n\n[https://www.typescriptlang.org/tsconfig/](https://www.typescriptlang.org/tsconfig/)\n\n以下列出了常见且有用的配置：\n\n#### target\n\n\"target\"属性用于指定 TypeScript 应发出/编译到哪个版本的 JavaScript ECMAScript 版本。对于现代浏览器，ES6是一个不错的选择，对于较旧的浏览器，建议使用ES5。\n\n#### lib\n\n\"lib\"属性用于指定编译时要包含哪些库文件。TypeScript 自动包含\"目标\"属性中指定功能的 API，但可以根据特定需求省略或选择特定库。例如，如果您正在开发服务器项目，则可以排除\"DOM\"库，该库仅在浏览器环境中有用。\n\n#### strict\n\n\"strict\"属性可以提供更强有力的保证并增强类型安全性。建议始终将此属性包含在项目的 tsconfig.json 文件中。启用\"strict\"属性允许 TypeScript ：\n\n* 触发每个源文件的代码使用\"use strict\"。\n* 在类型检查过程中考虑\"null\"和\"undefined\"\n* 当不存在类型注释时禁用\"any\"类型的使用。\n* 在使用\"this\"表达式时引发错误，否则\"this\"会被视为任意类型。\n\n#### module\n\n\"module\"属性设置编译程序支持的模块系统。在运行时，模块加载器用于根据指定的模块系统定位并执行依赖项。\nJavaScript 中最常见的模块加载器是用于服务器端应用程序的 Node.js 的CommonJS和用于基于浏览器的 Web 应用程序中的 AMD 模块的 RequireJS。\nTypeScript 可以为各种模块系统生成代码，包括 UMD、System、ESNext、ES2015/ES6 和 ES2020。\n\n注意：应根据目标环境和该环境中可用的模块加载机制来选择模块系统。\n\n#### moduleResolution\n\n\"moduleResolution\"属性指定模块解析策略。对现代TypeScript代码使用\"node\"，\"classic\"仅用于旧版本的 TypeScript（1.6 之前）。\n\n#### esModuleInterop\n\n\"esModuleInterop\"属性允许从未使用\"default\"属性导出的 CommonJS 模块导入默认值，此属性提供了一个兼容以确保生成的 JavaScript 的兼容性。启用此选项后，我们可以使用 `import MyLibrary from \"my-library\"` 而不是 `import * as MyLibrary from \"my-library\"`。\n\n#### jsx\n\n\"jsx\"属性仅适用于 ReactJS 中使用的 .tsx 文件，并控制 JSX 构造如何编译为 JavaScript。一个常见的选项是\"preserve\"，它将编译为 .jsx 文件，保持 JSX 不变，以便可以将其传递给 Babel 等不同工具进行进一步转换。\n\n#### skipLibCheck\n\n\"skipLibCheck\"属性将阻止 TypeScript 对整个导入的第三方包进行类型检查。此属性将减少项目的编译时间。TypeScript 仍会根据这些包提供的类型定义检查您的代码。\n\n#### files\n\n\"files\"属性向编译器指示必须始终包含在程序中的文件列表。\n\n#### include\n\n<!-- markdownlint-disable MD049 -->\n\"include\"属性向编译器指示我们想要包含的文件列表。此属性允许类似 glob 的模式，例如 \"\\*_\" 表示任何子目录，\"_\" 表示任何文件名，\"?\" 表示可选字符。\n<!-- markdownlint-enable MD049 -->\n\n#### exclude\n\n\"exclude\"属性向编译器指示不应包含在编译中的文件列表。这可以包括\"node_modules\"等文件或测试文件\n注意：tsconfig.json 允许注释。\n\n### importHelpers\n\nTypeScript 在为某些高级或低级 JavaScript 功能生成代码时使用帮助程序代码。 默认情况下，这些助手会在使用它们的文件中复制。 `importHelpers` 选项从 `tslib` 模块导入这些帮助器，从而使 JavaScript 输出更加高效。\n\n### 迁移到 TypeScript 的建议\n\n对于大型项目，建议采用逐渐过渡的方式，其中 TypeScript 和 JavaScript 代码最初共存。只有小型项目才能一次性迁移到 TypeScript。\n\n此转变的第一步是将 TypeScript 引入构建链过程。这可以通过使用\"allowJs\"编译器选项来完成，该选项允许 .ts 和 .tsx 文件与现有 JavaScript 文件共存。由于当 TypeScript 无法从 JavaScript 文件推断类型时，它会回退到变量的\"any\"类型，因此建议在迁移开始时在编译器选项中禁用\"noImplicitAny\"。\n\n第二步是确保您的 JavaScript 测试与 TypeScript 文件一起工作，以便您可以在转换每个模块时运行测试。如果您正在使用 Jest，请考虑使用ts-jest，它允许您使用 Jest 测试 TypeScript 项目。\n\n第三步是在项目中包含第三方库的类型声明。 这些声明可以第三方库的类型声明文件或专门的声明包中找到，你能通过 [https://www.typescriptlang.org/dt/search](https://www.typescriptlang.org/dt/search) 搜索并安装它们。:\n\n```shell\nnpm install --save-dev @types/package-name\n```\n\n或者\n\n```shell\nyarn add --dev @types/package-name\n```\n\n第四步是使用自下而上的方法逐个模块地迁移，遵循从叶开始的依赖关系图。这个想法是开始转换不依赖于其他模块的模块。要可视化依赖关系图，您可以使用该madge工具。\n\n有一些对于转换成 TypeScript 比较友好的模块（外部 API 或规范相关的实用函数和代码），比如Swagger、GraphQL 或 JSONSchema 自动生成 TypeScript 类型定义，并使用在您的项目中。\n\n当没有可用的规范或官方架构时，您可以从原始数据生成类型，例如服务器返回的 JSON。但是，建议从规范而不是数据生成类型，以避免丢失边缘情况。\n\n在迁移过程中，不要进行代码重构，而只专注于向模块添加类型。\n\n第五步是启用\"noImplicitAny\"，这将强制所有类型都是已知和定义的，从而为您的项目提供更好的 TypeScript 体验。\n\n在迁移过程中，您可以使用该@ts-check指令，该指令在 JavaScript 文件中启用 TypeScript 类型检查。该指令提供了宽松版本的类型检查，最初可用于识别 JavaScript 文件中的问题。当@ts-check包含在文件中时，TypeScript 将尝试使用 JSDoc 风格的注释来推断定义。但是，仅在迁移的早期阶段考虑使用 JSDoc 注释。\n\n考虑在你的tsconfig.json文件中将 `noEmitOnError` 设置为 false，即使报告错误，这也将允许您输出 JavaScript 源代码。\n\n"
  },
  {
    "path": "website/src/content/docs/zh-cn/book/index-signatures.md",
    "content": "---\ntitle: 索引签名\nsidebar:\n  order: 14\n  label: 14. 索引签名\n---\n\n\n在 TypeScript 中，我们可以使用 `string` 、`number` 和 `symbol` 作为索引签名：\n\n```typescript\ntype K = {\n    [name: string | number]: string;\n};\nconst k: K = { x: 'x', 1: 'b' };\nconsole.log(k['x']);\nconsole.log(k[1]);\nconsole.log(k['1']); // 同 k[1] 的结果相同\n```\n\n请注意，JavaScript 会自动将 `number` 的索引转换相同值的 'string'索引, 比如 `k[1]` 和 `k[\"1\"]` 返回相同值。\n\n"
  },
  {
    "path": "website/src/content/docs/zh-cn/book/infer-type-inference-in-conditional-types.md",
    "content": "---\ntitle: infer 条件类型中的类型推断\nsidebar:\n  order: 41\n  label: 41. infer 条件类型中的类型推断\n---\n\n\n`infer` 关键字在条件类型中使用，用于从依赖于泛型参数的类型中推断（提取）泛型参数的类型。这允许您编写更灵活且可重用的类型定义。\n\n```typescript\ntype ElementType<T> = T extends (infer U)[] ? U : never;\ntype Numbers = ElementType<number[]>; // number\ntype Strings = ElementType<string[]>; // string\n```\n\n"
  },
  {
    "path": "website/src/content/docs/zh-cn/book/interface-and-type.md",
    "content": "---\ntitle: 接口及类型\nsidebar:\n  order: 48\n  label: 48. 接口及类型\n---\n\n\n### 通用语法\n\n在 TypeScript 中，接口定义对象的结构，指定对象必须具有的属性或方法的名称和类型。在 TypeScript 中定义接口的常用语法如下：\n\n<!-- skip -->\n```typescript\ninterface InterfaceName {\n    property1: Type1;\n    // ...\n    method1(arg1: ArgType1, arg2: ArgType2): ReturnType;\n    // ...\n}\n```\n\n类型定义也类似：\n\n<!-- skip -->\n```typescript\ntype TypeName = {\n    property1: Type1;\n    // ...\n    method1(arg1: ArgType1, arg2: ArgType2): ReturnType;\n    // ...\n};\n```\n\n`interface InterfaceName` 或者 `type TypeName`: 定义接口的名称。\n`property1`: `Type1`: 指定接口的属性及其相应的类型。可以定义多个属性，每个属性用分号分隔。\n`method1(arg1: ArgType1, arg2: ArgType2): ReturnType;`: 指定接口的方法。方法用其名称进行定义，后跟括号中的参数列表和返回类型。可以定义多个方法，每个方法用分号分隔。\n\n接口示例:\n\n```typescript\ninterface Person {\n    name: string;\n    age: number;\n    greet(): void;\n}\n```\n\n类型示例:\n\n```typescript\ntype TypeName = {\n    property1: string;\n    method1(arg1: string, arg2: string): string;\n};\n```\n\n在 TypeScript 中，类型用于定义数据的形状并强制执行类型检查。在 TypeScript 中定义类型有几种常见的语法，具体取决于具体的用例。这里有些例子：\n\n### 基本类型\n\n```typescript\nlet myNumber: number = 123; // 数字类型\nlet myBoolean: boolean = true; // 布尔类型\nlet myArray: string[] = ['a', 'b']; // 字符串数组\nlet myTuple: [string, number] = ['a', 123]; // 元组\n```\n\n### 对象和接口\n\n```typescript\nconst x: { name: string; age: number } = { name: 'Simon', age: 7 };\n```\n\n### 并集和交集类型\n\n```typescript\ntype MyType = string | number; // 并集\nlet myUnion: MyType = 'hello'; // 可以是字符串\nmyUnion = 123; // 或者是一个数字\n\ntype TypeA = { name: string };\ntype TypeB = { age: number };\ntype CombinedType = TypeA & TypeB; // 交集\nlet myCombined: CombinedType = { name: 'John', age: 25 }; // 对象同时有name和age属性\n```\n\n"
  },
  {
    "path": "website/src/content/docs/zh-cn/book/intersection-types.md",
    "content": "---\ntitle: 交集类型\nsidebar:\n  order: 32\n  label: 32. 交集类型\n---\n\n\n交集类型是表示具有两种或多种类型的所有属性的值的类型。交叉类型在每种类型之间使用 & 符号表示。\n\n```typescript\ntype X = {\n    a: string;\n};\n\ntype Y = {\n    b: string;\n};\n\ntype J = X & Y; // 交集\n\nconst j: J = {\n    a: 'a',\n    b: 'b',\n};\n```\n\n"
  },
  {
    "path": "website/src/content/docs/zh-cn/book/introduction.md",
    "content": "---\ntitle: 介绍\nsidebar:\n  order: 5\n  label: 5. 介绍\n---\n\n\n欢迎来到简洁的TypeScript之书！本指南为您提供有效 TypeScript 开发的基本知识和实践技能。发现编写干净、健壮的代码的关键概念和技术。无论您是初学者还是经验丰富的开发人员，本书都可以作为在项目中利用 TypeScript 强大功能的综合指南和便捷参考。\n\n本书涵盖了 TypeScript 5.2。\n\n"
  },
  {
    "path": "website/src/content/docs/zh-cn/book/literal-inference.md",
    "content": "---\ntitle: 字面量推断\nsidebar:\n  order: 17\n  label: 17. 字面量推断\n---\n\n\n字面量推断是 TypeScript 中的一项功能，允许根据变量或参数的值推断其类型。\n\n在下面的示例中，我们可以看到 TypeScript 认为x文字类型是因为该值以后不能随时更改，而y被推断为字符串，因为它以后可以随时修改。\n\n```typescript\nconst x = 'x'; // x 为字面量类型, 因为值不能改变\nlet y = 'y'; // string, 我们能改变这个值\n```\n\n在下面的示例中，我们可以看到 `o.x` 被推断为 `string`（而不是字面量的a），因为 TypeScript 认为该值可以在以后随时更改。\n\n<!-- skip -->\n```typescript\ntype X = 'a' | 'b';\n\nlet o = {\n    x: 'a', // 这是一个更宽的 string\n};\n\nconst fn = (x: X) => `${x}-foo`;\n\nconsole.log(fn(o.x)); // 'string' 类型的参数不能赋值给 'X' 类型的参数\n```\n\n正如你所看到的代码在传递 `o.x` 给 `fn` 作为一个狭窄类型时，抛出了一个错误。\n\n我们能通过使用 `const` 或者 `X` 来借助类型推断解决这个问题：\n\n<!-- skip -->\n```typescript\nlet o = {\n    x: 'a' as const,\n};\n```\n\nor:\n\n<!-- skip -->\n```typescript\nlet o = {\n    x: 'a' as X,\n};\n```\n\n"
  },
  {
    "path": "website/src/content/docs/zh-cn/book/literal-types.md",
    "content": "---\ntitle: 字面量类型\nsidebar:\n  order: 16\n  label: 16. 字面量类型\n---\n\n\n文字类型是来自集体类型的单个元素集，它定义了一个非常精确的值，即 JavaScript 原始数据。\n\nTypeScript 中的文字类型是数字、字符串和布尔值。\n\n示例如下:\n\n```typescript\nconst a = 'a'; // 字符串字面量类型\nconst b = 1; // 数字字面量类型\nconst c = true; // 布尔字面量类型\n```\n\n在以下示例中，您可以看到联合类型别名。`O` 仅包含指定的值，其他字符串均无效：\n\n```typescript\ntype O = 'a' | 'b' | 'c';\n```\n\n"
  },
  {
    "path": "website/src/content/docs/zh-cn/book/mapped-type-modifiers.md",
    "content": "---\ntitle: 映射类型修饰符\nsidebar:\n  order: 38\n  label: 38. 映射类型修饰符\n---\n\n\nTypeScript 中的映射类型修饰符支持对现有类型中的属性进行转换：\n\n* `readonly` 或 `+readonly`：这会将映射类型中的属性呈现为只读。\n* `-readonly`：这允许映射类型中的属性是可变的。\n* `?`：这将映射类型中的属性指定为可选。\n\n例子：\n\n```typescript\ntype ReadOnly<T> = { readonly [P in keyof T]: T[P] }; // 所有属性标记为只读\n\ntype Mutable<T> = { -readonly [P in keyof T]: T[P] }; // 所有标记为可变的属性\n\ntype MyPartial<T> = { [P in keyof T]?: T[P] }; // 所有标记为可选的属性\n````\n\n"
  },
  {
    "path": "website/src/content/docs/zh-cn/book/mapped-types.md",
    "content": "---\ntitle: 映射类型\nsidebar:\n  order: 37\n  label: 37. 映射类型\n---\n\n\nTypeScript 中的映射类型允许您通过使用映射函数转换每个属性来基于现有类型创建新类型。通过映射现有类型，您可以创建以不同格式表示相同信息的新类型。要创建映射类型，您可以使用运算符访问现有类型的属性 `keyof` ，然后更改它们以生成新类型。在以下示例中：\n\n```typescript\ntype MyMappedType<T> = {\n    [P in keyof T]: T[P][];\n};\ntype MyType = {\n    foo: string;\n    bar: number;\n};\ntype MyNewType = MyMappedType<MyType>;\nconst x: MyNewType = {\n    foo: ['hello', 'world'],\n    bar: [1, 2, 3],\n};\n```\n\n我们定义 MyMappedType 来映射 T 的属性，创建一个新类型，其中每个属性都是其原始类型的数组。使用它，我们创建 MyNewType 来表示与 MyType 相同的信息，但每个属性都是一个数组。\n\n"
  },
  {
    "path": "website/src/content/docs/zh-cn/book/merging-and-extension.md",
    "content": "---\ntitle: 合并与扩展\nsidebar:\n  order: 52\n  label: 52. 合并与扩展\n---\n\n\n合并和扩展是指与使用类型和接口相关的两个不同概念。\n\n合并允许您将多个同名声明合并到一个定义中，例如，当您多次定义同名接口时：\n\n```typescript\ninterface X {\n    a: string;\n}\n\ninterface X {\n    b: number;\n}\n\nconst person: X = {\n    a: 'a',\n    b: 7,\n};\n```\n\n扩展是指扩展或继承现有类型或接口以创建新类型或接口的能力。它是一种向现有类型添加附加属性或方法而不修改其原始定义的机制。例子：\n\n```typescript\ninterface Animal {\n    name: string;\n    eat(): void;\n}\n\ninterface Bird extends Animal {\n    sing(): void;\n}\n\nconst dog: Bird = {\n    name: 'Bird 1',\n    eat() {\n        console.log('Eating');\n    },\n    sing() {\n        console.log('Singing');\n    },\n};\n```\n\n"
  },
  {
    "path": "website/src/content/docs/zh-cn/book/named-tuple-type-labeled.md",
    "content": "---\ntitle: 命名元组类型（已标记）\nsidebar:\n  order: 29\n  label: 29. 命名元组类型（已标记）\n---\n\n\n元组类型可以包含每个元素的可选标签或名称。 这些标签用于提高可读性和工具帮助，不会影响您可以使用它们执行的操作。\n\n```typescript\ntype T = string;\ntype Tuple1 = [T, T];\ntype Tuple2 = [a: T, b: T];\ntype Tuple3 = [a: T, T]; // 命名元组加匿名元组\n```\n\n"
  },
  {
    "path": "website/src/content/docs/zh-cn/book/namespacing.md",
    "content": "---\ntitle: 命名空间\nsidebar:\n  order: 57\n  label: 57. 命名空间\n---\n\n\n在 TypeScript 中，命名空间用于将代码组织到逻辑容器中，防止命名冲突并提供一种将相关代码分组在一起的方法。使用关键字 `export` 允许在\"外部\"模块中访问名称空间。\n\n```typescript\nexport namespace MyNamespace {\n    export interface MyInterface1 {\n        prop1: boolean;\n    }\n    export interface MyInterface2 {\n        prop2: string;\n    }\n}\n\nconst a: MyNamespace.MyInterface1 = {\n    prop1: true,\n};\n```\n\n"
  },
  {
    "path": "website/src/content/docs/zh-cn/book/narrowing.md",
    "content": "---\ntitle: 缩小范围\nsidebar:\n  order: 20\n  label: 20. 缩小范围\n---\n\n\nTypeScript 缩小范围是细化条件块内变量类型的过程。这在使用联合类型时很有用，其中一个变量可以有多个类型。\n\nTypeScript 可识别多种缩小类型范围的方法：\n\n### typeof 类型保护\n\ntypeof 类型保护是 TypeScript 中的一种特定类型保护，它根据变量的内置 JavaScript 类型检查变量的类型。\n\n```typescript\nconst fn = (x: number | string) => {\n    if (typeof x === 'number') {\n        return x + 1; // x 是数字\n    }\n    return -1;\n};\n```\n\n### 真实性缩小\n\nTypeScript 中的真实性缩小是通过检查变量是真还是假来相应地缩小其类型来实现的。\n\n```typescript\nconst toUpperCase = (name: string | null) => {\n    if (name) {\n        return name.toUpperCase();\n    } else {\n        return null;\n    }\n};\n```\n\n### 相等缩小\n\nTypeScript 中的相等缩小通过检查变量是否等于特定值来相应缩小其类型。\n\n它与`switch`语句和等号运算符（例如`===`、`!==`、`==`和`!=`）结合使用来缩小类型范围。\n\n```typescript\nconst checkStatus = (status: 'success' | 'error') => {\n    switch (status) {\n        case 'success':\n            return true;\n        case 'error':\n            return null;\n    }\n};\n```\n\n### In运算符缩小\n\nTypeScript 中的 `in` 运算符缩小范围是一种根据变量类型中是否存在属性来缩小变量类型的方法。\n\n```typescript\ntype Dog = {\n    name: string;\n    breed: string;\n};\n\ntype Cat = {\n    name: string;\n    likesCream: boolean;\n};\n\nconst getAnimalType = (pet: Dog | Cat) => {\n    if ('breed' in pet) {\n        return 'dog';\n    } else {\n        return 'cat';\n    }\n};\n```\n\n### instanceof 缩小\n\nTypeScript 中的 `instanceof` 运算符缩小是一种根据变量的构造函数缩小变量类型的方法，方法是检查对象是否是某个类或接口的实例。\n\n```typescript\nclass Square {\n    constructor(public width: number) {}\n}\nclass Rectangle {\n    constructor(\n        public width: number,\n        public height: number\n    ) {}\n}\nfunction area(shape: Square | Rectangle) {\n    if (shape instanceof Square) {\n        return shape.width * shape.width;\n    } else {\n        return shape.width * shape.height;\n    }\n}\nconst square = new Square(5);\nconst rectangle = new Rectangle(5, 10);\nconsole.log(area(square)); // 25\nconsole.log(area(rectangle)); // 50\n```\n\n"
  },
  {
    "path": "website/src/content/docs/zh-cn/book/never-type.md",
    "content": "---\ntitle: Never类型\nsidebar:\n  order: 47\n  label: 47. Never类型\n---\n\n\n`never` 类型表示从未出现过的值。它用于表示从不返回或抛出错误的函数或表达式。\n\n例如无限循环：\n\n```typescript\nconst infiniteLoop = (): never => {\n    while (true) {\n        // 做点什么\n    }\n};\n```\n\n抛出错误：\n\n```typescript\nconst throwError = (message: string): never => {\n    throw new Error(message);\n};\n```\n\n`never` 类型对于确保类型安全和捕获代码中的潜在错误很有用。当与其他类型和控制流语句结合使用时，它可以帮助 TypeScript 分析和推断更精确的类型，例如：\n\n```typescript\ntype Direction = 'up' | 'down';\nconst move = (direction: Direction): void => {\n    switch (direction) {\n        case 'up':\n            // 向上移动\n            break;\n        case 'down':\n            // 向下移动\n            break;\n        default:\n            const exhaustiveCheck: never = direction;\n            throw new Error(`Unhandled direction: ${exhaustiveCheck}`);\n    }\n};\n```\n\n"
  },
  {
    "path": "website/src/content/docs/zh-cn/book/object-types.md",
    "content": "---\ntitle: 对象类型\nsidebar:\n  order: 27\n  label: 27. 对象类型\n---\n\n\n在 TypeScript 中，对象类型描述对象的形状。它们指定对象属性的名称和类型，以及这些属性是必需的还是可选的。\n\n在 TypeScript 中，您可以通过两种主要方式定义对象类型：\n\n通过指定对象属性的名称、类型和可选性来定义对象的形状的接口。\n\n```typescript\ninterface User {\n    name: string;\n    age: number;\n    email?: string;\n}\n```\n\n类型别名与接口类似，定义了对象的形状。但是，它还可以基于现有类型或现有类型的组合创建新的自定义类型。这包括定义联合类型、交集类型和其他复杂类型。\n\n```typescript\ntype Point = {\n    x: number;\n    y: number;\n};\n```\n\n也可以匿名定义类型：\n\n```typescript\nconst sum = (x: { a: number; b: number }) => x.a + x.b;\nconsole.log(sum({ a: 5, b: 1 }));\n```\n\n"
  },
  {
    "path": "website/src/content/docs/zh-cn/book/optional-properties.md",
    "content": "---\ntitle: 可选属性\nsidebar:\n  order: 12\n  label: 12. 可选属性\n---\n\n\n对象可以通过在属性名称末尾添加问号 `?` 来指定可选属性：\n\n```typescript\ntype X = {\n    a: number;\n    b?: number; // 可选的\n};\n```\n\n当属性是可选的时，可以指定默认值\n\n```typescript\ntype X = {\n    a: number;\n    b?: number;\n};\nconst x = ({ a, b = 100 }: X) => a + b;\n```\n\n"
  },
  {
    "path": "website/src/content/docs/zh-cn/book/others.md",
    "content": "---\ntitle: 其他\nsidebar:\n  order: 61\n  label: 61. 其他\n---\n\n\n### 错误和异常处理\n\nTypeScript 允许您使用标准 JavaScript 错误处理机制捕获和处理错误：\n\nTry-Catch-Finally 块：\n\n```typescript\ntry {\n    // 可能会抛出异常的代码\n} catch (error) {\n    // 处理错误\n} finally {\n    // 总是会执行的代码, finally 是可选的\n}\n```\n\n您还可以处理不同类型的错误：\n\n```typescript\ntry {\n    // 可能会抛出不同类型错误的代码\n} catch (error) {\n    if (error instanceof TypeError) {\n        // 处理 TypeError\n    } else if (error instanceof RangeError) {\n        // 处理 RangeError\n    } else {\n        // 处理其他的错误\n    }\n}\n```\n\n自定义错误类型：\n\n可以通过扩展 Error 来指定更具体的错误 `class` ：\n\n```typescript\nclass CustomError extends Error {\n    constructor(message: string) {\n        super(message);\n        this.name = 'CustomError';\n    }\n}\n\nthrow new CustomError('This is a custom error.');\n```\n\n### 混合类\n\nMixin 类允许您将多个类的行为组合并组合成一个类。它们提供了一种重用和扩展功能的方法，而不需要深层继承链。\n\n```typescript\nabstract class Identifiable {\n    name: string = '';\n    logId() {\n        console.log('id:', this.name);\n    }\n}\nabstract class Selectable {\n    selected: boolean = false;\n    select() {\n        this.selected = true;\n        console.log('Select');\n    }\n    deselect() {\n        this.selected = false;\n        console.log('Deselect');\n    }\n}\nclass MyClass {\n    constructor() {}\n}\n\n// 扩展 MyClass 以包含可识别和可选择的行为\ninterface MyClass extends Identifiable, Selectable {}\n\n// 将 mixins 应用于类的函数\nfunction applyMixins(source: any, baseCtors: any[]) {\n    baseCtors.forEach(baseCtor => {\n        Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => {\n            let descriptor = Object.getOwnPropertyDescriptor(\n                baseCtor.prototype,\n                name\n            );\n            if (descriptor) {\n                Object.defineProperty(source.prototype, name, descriptor);\n            }\n        });\n    });\n}\n\n// 将 mixins 应用到 MyClass\napplyMixins(MyClass, [Identifiable, Selectable]);\nlet o = new MyClass();\no.name = 'abc';\no.logId();\no.select();\n```\n\n### 异步语言特性\n\n由于 TypeScript 是 JavaScript 的超集，因此它内置了 JavaScript 的异步语言功能，例如：\n\nPromises：\n\nPromise 是一种处理异步操作及其结果的方法，使用 `.then()`和等方法 `.catch()` 来处理成功和错误条件。\n\n要了解更多信息： [https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)\n\nAsync/await:\n\nAsync/await 关键字是一种为处理 Promise 提供看起来更同步的语法的方法。`async` 关键字用于定义异步函数，并且 `await` 关键字在异步函数中使用以暂停执行，直到 Promise 被解决或拒绝。\n\n要了解更多信息：\n[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function)\n[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await)\n\nTypeScript 很好地支持以下 API：\n\nFetch API:\n[https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API)\n\nWeb Workers:\n[https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API)\n\nShared Workers:\n[https://developer.mozilla.org/en-US/docs/Web/API/SharedWorker](https://developer.mozilla.org/en-US/docs/Web/API/SharedWorker)\n\nWebSocket:\n[https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API)\n\n### 迭代器和生成器\n\nTypeScript 对迭代器和生成器都提供了很好的支持。\n\n迭代器是实现迭代器协议的对象，提供了一种逐个访问集合或序列元素的方法。它是一个包含指向迭代中下一个元素的指针的结构。他们有一个 `next()` 方法返回序列中的下一个值以及指示序列是否为 的布尔值 `done` 。\n\n```typescript\nclass NumberIterator implements Iterable<number> {\n    private current: number;\n\n    constructor(\n        private start: number,\n        private end: number\n    ) {\n        this.current = start;\n    }\n\n    public next(): IteratorResult<number> {\n        if (this.current <= this.end) {\n            const value = this.current;\n            this.current++;\n            return { value, done: false };\n        } else {\n            return { value: undefined, done: true };\n        }\n    }\n\n    [Symbol.iterator](): Iterator<number> {\n        return this;\n    }\n}\n\nconst iterator = new NumberIterator(1, 3);\n\nfor (const num of iterator) {\n    console.log(num);\n}\n```\n\n生成器是使用 `function*` 简化迭代器创建的语法定义的特殊函数。它们使用 `yield` 关键字来定义值的序列，并在请求值时自动暂停和恢复执行。\n\n生成器使创建迭代器变得更加容易，并且对于处理大型或无限序列特别有用。\n\n例子：\n\n```typescript\nfunction* numberGenerator(start: number, end: number): Generator<number> {\n    for (let i = start; i <= end; i++) {\n        yield i;\n    }\n}\n\nconst generator = numberGenerator(1, 5);\n\nfor (const num of generator) {\n    console.log(num);\n}\n```\n\nTypeScript 还支持异步迭代器和异步生成器。\n\n要了解更多信息：\n\n[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Generator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Generator)\n\n[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Iterator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Iterator)\n\n### TsDocs JSDoc 参考\n\n使用 JavaScript 代码库时，可以通过使用 JSDoc 注释和附加注释来提供类型信息，帮助 TypeScript 推断正确的类型。\n\n例子：\n\n```typescript\n/**\n * Computes the power of a given number\n * @constructor\n * @param {number} base – The base value of the expression\n * @param {number} exponent – The exponent value of the expression\n */\nfunction power(base: number, exponent: number) {\n    return Math.pow(base, exponent);\n}\npower(10, 2); // function power(base: number, exponent: number): number\n```\n\n此链接提供了完整文档：\n[https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html](https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html)\n\n从版本 3.7 开始，可以从 JavaScript JSDoc 语法生成 .d.ts 类型定义。更多信息可以在这里找到：\n[https://www.typescriptlang.org/docs/handbook/declaration-files/dts-from-js.html](https://www.typescriptlang.org/docs/handbook/declaration-files/dts-from-js.html)\n\n### @types\n\n@types 组织下的包是特殊的包命名约定，用于为现有 JavaScript 库或模块提供类型定义。例如使用：\n\n```shell\nnpm install --save-dev @types/lodash\n```\n\n将在您当前的项目中安装 `lodash` 的类型定义。\n\n要为 @types 包的类型定义做出贡献，请向 [https://github.com/DefinitelyTyped/DefinitelyTyped](https://github.com/DefinitelyTyped/DefinitelyTyped) 提交pr请求。\n\n### JSX\n\nJSX (JavaScript XML) 是 JavaScript 语言语法的扩展，允许您在 JavaScript 或 TypeScript 文件中编写类似 HTML 的代码。它通常在 React 中用来定义 HTML 结构。\n\nTypeScript 通过提供类型检查和静态分析来扩展 JSX 的功能。\n\n要使用 JSX，您需要在文件 `tsconfig.json` 中设置 `jsx` 编译器选项。两个常见的配置选项：\n\n* \"preserve\": 触发 .jsx 文件且 JSX 不变. 此选项告诉 TypeScript 按原样保留 JSX 语法，而不是在编译过程中对其进行转换。 如果您有单独的工具（例如 Babel）来处理转换，则可以使用此选项。\n* \"react\": 启用 TypeScript 的内置 JSX 转换。 将使用 React.createElement 。\n\n所有选项均可在此处使用：\n[https://www.typescriptlang.org/tsconfig#jsx](https://www.typescriptlang.org/tsconfig#jsx)\n\n### ES6 模块\n\nTypeScript 确实支持 ES6 (ECMAScript 2015) 和许多后续版本。这意味着您可以使用 ES6 语法，例如箭头函数、模板文字、类、模块、解构等等。\n\n要在项目中启用 ES6 功能，您可以在 `tsconfig.json` 中指定 `target` 属性。\n\n配置示例：\n\n```json\n{\n  \"compilerOptions\": {\n    \"target\": \"es6\",\n    \"module\": \"es6\",\n    \"moduleResolution\": \"node\",\n    \"sourceMap\": true,\n    \"outDir\": \"dist\"\n  },\n  \"include\": [\"src\"]\n}\n```\n\n### ES7 求幂运算符\n\n求幂 (`**`) 运算符计算通过将第一个操作数进行第二个操作数的幂获得的值。它的功能与 `Math.pow()` 类似，但增加了接受 BigInts 作为操作数的功能。TypeScript 完全支持在 `tsconfig.json` 文件中设置 `target` 为 `es2016`或更大版本来使用此运算符。\n\n```typescript\nconsole.log(2 ** (2 ** 2)); // 16\n```\n\n### for-await-of 语句\n\n这是 TypeScript 完全支持的 JavaScript 功能，它允许您从目标版本 `es2018` 迭代异步可迭代对象。\n\n```typescript\nasync function* asyncNumbers(): AsyncIterableIterator<number> {\n    yield Promise.resolve(1);\n    yield Promise.resolve(2);\n    yield Promise.resolve(3);\n}\n\n(async () => {\n    for await (const num of asyncNumbers()) {\n        console.log(num);\n    }\n})();\n```\n\n### New target 元属性\n\n您可以在 TypeScript 中使用 `new.target` 元属性，该属性使您能够确定是否使用 new 运算符调用函数或构造函数。它允许您检测对象是否是由于构造函数调用而创建的。\n\n```typescript\nclass Parent {\n    constructor() {\n        console.log(new.target); // 记录用于创建实例的构造函数\n    }\n}\n\nclass Child extends Parent {\n    constructor() {\n        super();\n    }\n}\n\nconst parentX = new Parent(); // [Function: Parent]\nconst child = new Child(); // [Function: Child]\n```\n\n### 动态导入表达式\n\n可以使用 TypeScript 支持的动态导入 ECMAScript 建议有条件地加载模块或按需延迟加载模块。\n\nTypeScript 中动态导入表达式的语法如下：\n\n<!-- skip -->\n```typescript\nasync function renderWidget() {\n    const container = document.getElementById('widget');\n    if (container !== null) {\n        const widget = await import('./widget'); // 动态导入\n        widget.render(container);\n    }\n}\n\nrenderWidget();\n```\n\n### \"tsc –watch\"\n\n此命令使用 `--watch` 参数启动 TypeScript 编译器，能够在修改 TypeScript 文件时自动重新编译它们。\n\n```shell\ntsc --watch\n```\n\n从 TypeScript 4.9 版本开始，文件监控主要依赖于文件系统事件，如果无法建立基于事件的观察程序，则会自动诉诸轮询。\n\n### 默认声明\n\n当为变量或参数分配默认值时，将使用默认声明。这意味着如果没有为该变量或参数提供值，则将使用默认值。\n\n```typescript\nfunction greet(name: string = 'Anonymous'): void {\n    console.log(`Hello, ${name}!`);\n}\ngreet(); // Hello, Anonymous!\ngreet('John'); // Hello, John!\n```\n\n### 可选链\n\n可选的链接运算符 `?.` 与常规点运算符 (`.`) 一样用于访问属性或方法。但是，它通过优雅处理 `undefined` 和 `null` 来终止表达式并返回 `undefined`，而不是抛出错误。\n\n```typescript\ntype Person = {\n    name: string;\n    age?: number;\n    address?: {\n        street?: string;\n        city?: string;\n    };\n};\n\nconst person: Person = {\n    name: 'John',\n};\n\nconsole.log(person.address?.city); // undefined\n```\n\n### 空合并运算符\n\n如果 `??` 左侧是 `null` 或者 `undefined` ，则空合并运算符返回右侧值，否则，它返回左侧值。\n\n```typescript\nconst foo = null ?? 'foo';\nconsole.log(foo); // foo\n\nconst baz = 1 ?? 'baz';\nconst baz2 = 0 ?? 'baz';\nconsole.log(baz); // 1\nconsole.log(baz2); // 0\n```\n\n### 模板字符串类型\n\n模板字符串类型允许在类型级别操作字符串值并基于现有字符串生成新的字符串类型。它们对于从基于字符串的操作创建更具表现力和更精确的类型非常有用。\n\n```typescript\ntype Department = 'enginnering' | 'hr';\ntype Language = 'english' | 'spanish';\ntype Id = `${Department}-${Language}-id`; // \"enginnering-english-id\" | \"enginnering-spanish-id\" | \"hr-english-id\" | \"hr-spanish-id\"\n```\n\n### 函数重载\n\n函数重载允许您为同一函数名定义多个函数签名，每个函数签名具有不同的参数类型和返回类型。当您调用重载函数时，TypeScript 使用提供的参数来确定正确的函数签名：\n\n```typescript\nfunction makeGreeting(name: string): string;\nfunction makeGreeting(names: string[]): string[];\n\nfunction makeGreeting(person: unknown): unknown {\n    if (typeof person === 'string') {\n        return `Hi ${person}!`;\n    } else if (Array.isArray(person)) {\n        return person.map(name => `Hi, ${name}!`);\n    }\n    throw new Error('Unable to greet');\n}\n\nmakeGreeting('Simon');\nmakeGreeting(['Simone', 'John']);\n```\n\n### 递归类型\n\n递归类型是可以引用自身的类型。 这对于定义具有分层或递归结构（可能无限嵌套）的数据结构非常有用，例如链表、树和图。\n\n```typescript\ntype ListNode<T> = {\n    data: T;\n    next: ListNode<T> | undefined;\n};\n```\n\n### 递归条件类型\n\n可以使用 TypeScript 中的逻辑和递归来定义复杂的类型关系。让我们简单地分解一下：\n\n条件类型：允许您基于布尔条件定义类型：\n\n```typescript\ntype CheckNumber<T> = T extends number ? 'Number' : 'Not a number';\ntype A = CheckNumber<123>; // 'Number'\ntype B = CheckNumber<'abc'>; // 'Not a number'\n```\n\n递归：是指在自己的定义中引用自身的类型定义：\n\n```typescript\ntype Json = string | number | boolean | null | Json[] | { [key: string]: Json };\n\nconst data: Json = {\n    prop1: true,\n    prop2: 'prop2',\n    prop3: {\n        prop4: [],\n    },\n};\n```\n\n递归条件类型结合了条件逻辑和递归。这意味着类型定义可以通过条件逻辑依赖于自身，从而创建复杂且灵活的类型关系。\n\n```typescript\ntype Flatten<T> = T extends Array<infer U> ? Flatten<U> : T;\n\ntype NestedArray = [1, [2, [3, 4], 5], 6];\ntype FlattenedArray = Flatten<NestedArray>; // 2 | 3 | 4 | 5 | 1 | 6\n```\n\n### Node 中的 ECMAScript 模块支持\n\nNode.js 从 15.3.0 版本开始添加了对 ECMAScript 模块的支持，而 TypeScript 从 4.7 版本开始增加了对 Node.js 的 ECMAScript 模块支持。可以通过将 `tsconfig.json` 文件中的`module`属性的值设置为 `nodenext` 来启用此支持。这是一个例子：\n\n```json\n{\n  \"compilerOptions\": {\n    \"module\": \"nodenext\",\n    \"outDir\": \"./lib\",\n    \"declaration\": true\n  }\n}\n```\n\nNode.js 支持两种模块文件扩展名：`.mjs` 的ES 模块和 `.cjs` 的CommonJS 模块。TypeScript 中的等效文件扩展名适用 `.mts` 于 ES 模块和 `.cts` 于CommonJS 模块。当 TypeScript 编译器将这些文件转译为 JavaScript 时，它将分别创建 `.mjs` 和 `.cjs` 文件。\n\n如果您想在项目中使用 ES 模块，可以type在 package.json 文件中将该属性设置为\"module\"。这指示 Node.js 将项目视为 ES 模块项目。\n\n此外，TypeScript 还支持 .d.ts 文件中的类型声明。这些声明文件为用 TypeScript 编写的库或模块提供类型信息，允许其他开发人员通过 TypeScript 的类型检查和自动完成功能来利用它们。\n\n### 断言函数\n\n在 TypeScript 中，断言函数是根据返回值指示特定条件验证的函数。在最简单的形式中，断言函数检查提供的谓词，并在谓词计算结果为 false 时引发错误。\n\n```typescript\nfunction isNumber(value: unknown): asserts value is number {\n    if (typeof value !== 'number') {\n        throw new Error('Not a number');\n    }\n}\n```\n\n或者可以声明为函数表达式：\n\n```typescript\ntype AssertIsNumber = (value: unknown) => asserts value is number;\nconst isNumber: AssertIsNumber = value => {\n    if (typeof value !== 'number') {\n        throw new Error('Not a number');\n    }\n};\n```\n\n断言函数与类型保护有相似之处。类型保护最初是为了执行运行时检查并确保值的类型在特定范围内而引入的。具体来说，类型保护是一个计算类型谓词并返回指示谓词是真还是假的布尔值的函数。这与断言函数略有不同，断言函数的目的是在不满足谓词时抛出错误而不是返回 false。\n\n类型保护示例：\n\n```typescript\nconst isNumber = (value: unknown): value is number => typeof value === 'number';\n```\n\n### 可变参数元组类型\n\n可变元组类型是 TypeScript 4.0 版本中引入的一个功能，让我们通过回顾什么是元组来开始学习它们：\n\n元组类型是一个具有定义长度的数组，并且每个元素的类型已知：\n\n```typescript\ntype Student = [string, number];\nconst [name, age]: Student = ['Simone', 20];\n```\n\n术语\"可变参数\"意味着不定数量（接受可变数量的参数）。\n\n可变参数元组是一种元组类型，它具有以前的所有属性，但确切的形状尚未定义：\n\n```typescript\ntype Bar<T extends unknown[]> = [boolean, ...T, number];\n\ntype A = Bar<[boolean]>; // [boolean, boolean, number]\ntype B = Bar<['a', 'b']>; // [boolean, 'a', 'b', number]\ntype C = Bar<[]>; // [boolean, number]\n```\n\n在前面的代码中我们可以看到元组形状是由T传入的泛型定义的。\n\n可变参数元组可以接受多个泛型，这使得它们非常灵活：\n\n```typescript\ntype Bar<T extends unknown[], G extends unknown[]> = [...T, boolean, ...G];\n\ntype A = Bar<[number], [string]>; // [number, boolean, string]\ntype B = Bar<['a', 'b'], [boolean]>; // [\"a\", \"b\", boolean, boolean]\n```\n\n使用新的可变参数元组，我们可以使用：\n\n* 元组类型语法中的扩展现在可以是通用的，因此即使我们不知道我们正在操作的实际类型，我们也可以表示元组和数组上的高阶操作\n* 其余元素可以出现在元组中的任何位置。\n\n例子：\n\n```typescript\ntype Items = readonly unknown[];\n\nfunction concat<T extends Items, U extends Items>(\n    arr1: T,\n    arr2: U\n): [...T, ...U] {\n    return [...arr1, ...arr2];\n}\n\nconcat([1, 2, 3], ['4', '5', '6']); // [1, 2, 3, \"4\", \"5\", \"6\"]\n```\n\n### 装箱类型\n\n装箱类型是指用于将基本类型表示为对象的包装对象。这些包装器对象提供了原始值无法直接使用的附加功能和方法。\n\n当你访问原始 `string` 上的 `charAt` 或者 `normalize` 方法时，JavaScript 将其包装在 `String` 类型的对象中，调用该方法，然后丢弃该对象\n\n示范：\n\n```typescript\nconst originalNormalize = String.prototype.normalize;\nString.prototype.normalize = function () {\n    console.log(this, typeof this);\n    return originalNormalize.call(this);\n};\nconsole.log('\\u0041'.normalize());\n```\n\nTypeScript 通过为原语及其相应的对象包装器提供单独的类型来表示这种区别：\n\n* string => String\n* number => Number\n* boolean => Boolean\n* symbol => Symbol\n* bigint => BigInt\n\n通常不需要盒装类型。避免使用装箱类型，而是使用基元类型，例如 `string` 代替 `String`。\n\n### TypeScript 中的协变和逆变\n\n协变和逆变用于描述在处理类型的继承或赋值时关系如何工作。\n\n协变意味着类型关系保留继承或赋值的方向，因此如果类型 A 是类型 B 的子类型，则类型 A 的数组也被视为类型 B 的数组的子类型。这里需要注意的重要事项是维持子类型关系，这意味着协变接受子类型但不接受超类型。\n\n逆变意味着类型关系颠倒了继承或赋值的方向，因此如果类型 A 是类型 B 的子类型，则类型 B 的数组被视为类型 A 数组的子类型。子类型关系颠倒了，这意味着该逆变接受超类型但不接受子类型。\n\n注意：双变量意味着同时接受超类型和子类型。\n\n示例：假设我们有一个适合所有动物的空间和一个专门适合狗的单独空间。\n\n在协方差中，您可以将所有狗放入动物空间中，因为狗是一种动物。但你不能把所有的动物都放在狗的空间里，因为可能还有其他动物混在一起。\n\n在逆变中，您不能将所有动物放入狗空间中，因为动物空间也可能包含其他动物。然而，你可以把所有的狗都放在动物空间里，因为所有的狗也是动物。\n\n<!-- skip -->\n```typescript\n// 协变示例\nclass Animal {\n    name: string;\n    constructor(name: string) {\n        this.name = name;\n    }\n}\n\nclass Dog extends Animal {\n    breed: string;\n    constructor(name: string, breed: string) {\n        super(name);\n        this.breed = breed;\n    }\n}\n\nlet animals: Animal[] = [];\nlet dogs: Dog[] = [];\n\n// 协变允许将子类型（狗）数组分配给超类型（动物）数组\nanimals = dogs;\ndogs = animals; // 无效: 'Animal[]' 不能赋值给 'Dog[]'\n\n// 逆变示例\ntype Feed<in T> = (animal: T) => void;\n\nlet feedAnimal: Feed<Animal> = (animal: Animal) => {\n    console.log(`Animal name: ${animal.name}`);\n};\n\nlet feedDog: Feed<Dog> = (dog: Dog) => {\n    console.log(`Dog name: ${dog.name}, Breed: ${dog.breed}`);\n};\n\n// 逆变允许将超类型（动物）回调赋值给子类型（狗）回调\nfeedDog = feedAnimal;\nfeedAnimal = feedDog; // 无效: Type 'Feed<Dog>' 不能赋值给 'Feed<Animal>'.\n```\n\n在 TypeScript 中，数组的类型关系是协变的，而函数参数的类型关系是逆变的。这意味着 TypeScript 同时表现出协变和逆变，具体取决于上下文。\n\n#### 类型参数的可选方差注释\n\n从 TypeScript 4.7.0 开始，我们可以使用out和in关键字来具体说明方差注释。\n\n对于协变，使用out关键字：\n\n```typescript\ntype AnimalCallback<out T> = () => T; // 此处 T 是协变的\n```\n\n对于逆变，使用in关键字：\n\n```typescript\ntype AnimalCallback<in T> = (value: T) => void; // 此处 T 是逆变的\n```\n\n### 模板字符串模式索引签名\n\n模板字符串模式索引签名允许我们使用模板字符串模式定义灵活的索引签名。 此功能使我们能够创建可以使用特定字符串键模式进行索引的对象，从而在访问和操作属性时提供更多控制和特异性。\n\nTypeScript 4.4 版开始允许符号和模板字符串模式的索引签名。\n\n```typescript\nconst uniqueSymbol = Symbol('description');\n\ntype MyKeys = `key-${string}`;\n\ntype MyObject = {\n    [uniqueSymbol]: string;\n    [key: MyKeys]: number;\n};\n\nconst obj: MyObject = {\n    [uniqueSymbol]: 'Unique symbol key',\n    'key-a': 123,\n    'key-b': 456,\n};\n\nconsole.log(obj[uniqueSymbol]); // Unique symbol key\nconsole.log(obj['key-a']); // 123\nconsole.log(obj['key-b']); // 456\n```\n\n### satisfies操作符\n\n`satisfies` 允许您检查给定类型是否满足特定接口或条件。换句话说，它确保类型具有特定接口所需的所有属性和方法。这是确保变量适合类型定义的一种方法。\n\n下面是一个示例：\n\n<!-- skip -->\n```typescript\ntype Columns = 'name' | 'nickName' | 'attributes';\n\ntype User = Record<Columns, string | string[] | undefined>;\n\n// `User`的类型注释\nconst user: User = {\n    name: 'Simone',\n    nickName: undefined,\n    attributes: ['dev', 'admin'],\n};\n\n// 在以下几行中，TypeScript 将无法正确推断\nuser.attributes?.map(console.log); // 'string | string[]' 中不存在属性 'map'。'string' 中不存在属性 'map'。\nuser.nickName; // string | string[] | undefined\n\n// 类型断言 `as`\nconst user2 = {\n    name: 'Simon',\n    nickName: undefined,\n    attributes: ['dev', 'admin'],\n} as User;\n\n// 这里也一样的， TypeScript 将无法正确推断\nuser2.attributes?.map(console.log); //'string | string[]' 中不存在属性 'map'。'string' 中不存在属性 'map'。\nuser2.nickName; // string | string[] | undefined\n\n// 使用\"satisfies\"运算符我们现在可以正确推断类型\nconst user3 = {\n    name: 'Simon',\n    nickName: undefined,\n    attributes: ['dev', 'admin'],\n} satisfies User;\n\nuser3.attributes?.map(console.log); // TypeScript 推断正确: string[]\nuser3.nickName; // TypeScript 推断正确: undefined\n```\n\n### 仅类型导入和导出\n\n仅类型导入和导出允许您导入或导出类型，而无需导入或导出与这些类型关联的值或函数。 这对于减小捆绑包的大小很有用。\n\n要使用仅类型导入，您可以使用`import type`关键字。\n\nTypeScript 允许在仅类型导入中使用声明和实现文件扩展名（.ts、.mts、.cts 和 .tsx），无论`allowImportingTsExtensions`设置如何。\n\n例如：\n\n<!-- skip -->\n```typescript\nimport type { House } from './house.ts';\n```\n\n以下是支持的形式：\n\n<!-- skip -->\n```typescript\nimport type T from './mod';\nimport type { A, B } from './mod';\nimport type * as Types from './mod';\nexport type { T };\nexport type { T } from './mod';\n```\n\n### 使用声明和显式资源管理\n\n\"using\"声明是块范围的、不可变的绑定，类似于\"const\"，用于管理一次性资源。 当使用值初始化时，该值的\"Symbol.dispose\"方法将被记录，并随后在退出封闭块作用域时执行。\n\n这是基于 ECMAScript 的资源管理功能，该功能对于在对象创建后执行基本的清理任务非常有用，例如关闭连接、删除文件和释放内存。\n\n笔记：\n\n* 由于最近在 TypeScript 5.2 版中引入，大多数运行时缺乏本机支持。 您将需要以下功能的填充：`Symbol.dispose`、`Symbol.asyncDispose`、`DisposableStack`、`AsyncDisposableStack`、`SuppressedError`。\n* 此外，您需要按如下方式配置 tsconfig.json：\n\n```json\n{\n    \"compilerOptions\": {\n        \"target\": \"es2022\",\n        \"lib\": [\"es2022\", \"esnext.disposable\", \"dom\"]\n    }\n}\n````\n\n例子：\n\n<!-- skip -->\n```typescript\n//@ts-ignore\nSymbol.dispose ??= Symbol('Symbol.dispose'); // 简单的兼容性填充\n\nconst doWork = (): Disposable => {\n    return {\n        [Symbol.dispose]: () => {\n            console.log('disposed');\n        },\n    };\n};\n\nconsole.log(1);\n\n{\n    using work = doWork(); // 资源被声明\n    console.log(2);\n} // 资源被释放 (例如, `work[Symbol.dispose]()` 被执行)\n\nconsole.log(3);\n```\n\n该代码将记录：\n\n```shell\n1\n2\ndisposed\n3\n```\n\n符合处置条件的资源必须遵守 `Disposable` 接口：\n\n```typescript\n// lib.esnext.disposable.d.ts\ninterface Disposable {\n    [Symbol.dispose](): void;\n}\n```\n\n\"using\"声明在堆栈中记录资源处置操作，确保它们以与声明相反的顺序处置：\n\n<!-- skip -->\n```typescript\n{\n    using j = getA(),\n        y = getB();\n    using k = getC();\n} // 先释放 `C`, 然后 `B`, 然后 `A`.\n```\n\n即使发生后续代码或异常，也保证会释放资源。 这可能会导致处置可能引发异常，并可能抑制另一个异常。 为了保留有关被抑制错误的信息，引入了一个新的本机异常\"SuppressedError\"。\n\n#### 使用声明等待\n\n\"await using\"声明处理异步一次性资源。 该值必须具有\"Symbol.asyncDispose\"方法，该方法将在块末尾等待。\n\n<!-- skip -->\n```typescript\nasync function doWorkAsync() {\n    await using work = doWorkAsync(); // 资源被声明\n} // // 资源被释放 (例如, `await work[Symbol.asyncDispose]()` 被执行)\n```\n\n对于异步可处置资源，它必须遵守\"Disposable\"或\"AsyncDisposable\"接口：\n\n```typescript\n// lib.esnext.disposable.d.ts\ninterface AsyncDisposable {\n    [Symbol.asyncDispose](): Promise<void>;\n}\n```\n\n<!-- skip -->\n```typescript\n//@ts-ignore\nSymbol.asyncDispose ??= Symbol('Symbol.asyncDispose'); // Simple polify\n\nclass DatabaseConnection implements AsyncDisposable {\n    // 当对象被异步释放时会被调用的方法\n    [Symbol.asyncDispose]() {\n        // Close the connection and return a promise\n        return this.close();\n    }\n\n    async close() {\n        console.log('Closing the connection...');\n        await new Promise(resolve => setTimeout(resolve, 1000));\n        console.log('Connection closed.');\n    }\n}\n\nasync function doWork() {\n    // 创建一个新的连接，并在其超出作用域时进行异步释放\n    await using connection = new DatabaseConnection(); // 资源被声明\n    console.log('Doing some work...');\n} // 资源被释放 (例如, `await connection[Symbol.asyncDispose]()` 被执行)\n\ndoWork();\n```\n\n代码日志：\n\n```shell\nDoing some work...\nClosing the connection...\nConnection closed.\n```\n\n语句中允许使用\"using\"和\"await using\"声明：\"for\"、\"for-in\"、\"for-of\"、\"for-await-of\"、\"switch\"。\n\n### 导入属性\n\nTypeScript 5.3 的导入属性（导入标签）告诉运行时如何处理模块（JSON 等）。这通过确保干净的导入来提高安全性，并与内容安全策略 (CSP) 保持一致，以实现更安全的资源加载。TypeScript 确保它们有效，但让运行时处理它们的解释以进行特定的模块处理。\n\n示例：\n\n<!-- skip -->\n```typescript\nimport config from './config.json' with { type: 'json' };\n```\n\n使用动态导入：\n\n<!-- skip -->\n```typescript\nconst config = import('./config.json', { with: { type: 'json' } });\n```\n"
  },
  {
    "path": "website/src/content/docs/zh-cn/book/overloads.md",
    "content": "---\ntitle: 重载\nsidebar:\n  order: 51\n  label: 51. 重载\n---\n\n\nTypeScript 中的函数重载允许您为单个函数名称定义多个函数签名，从而使您能够定义可以多种方式调用的函数。这是一个例子：\n\n```typescript\n// 重载\nfunction sayHi(name: string): string;\nfunction sayHi(names: string[]): string[];\n\n// 实现\nfunction sayHi(name: unknown): unknown {\n    if (typeof name === 'string') {\n        return `Hi, ${name}!`;\n    } else if (Array.isArray(name)) {\n        return name.map(name => `Hi, ${name}!`);\n    }\n    throw new Error('Invalid value');\n}\n\nsayHi('xx'); // 有效\nsayHi(['aa', 'bb']); // 有效\n```\n\n这是在 `class` 中使用函数重载的另一个示例：\n\n```typescript\nclass Greeter {\n    message: string;\n\n    constructor(message: string) {\n        this.message = message;\n    }\n\n    // 重载\n    sayHi(name: string): string;\n    sayHi(names: string[]): ReadonlyArray<string>;\n\n    // 实现\n    sayHi(name: unknown): unknown {\n        if (typeof name === 'string') {\n            return `${this.message}, ${name}!`;\n        } else if (Array.isArray(name)) {\n            return name.map(name => `${this.message}, ${name}!`);\n        }\n        throw new Error('value is invalid');\n    }\n}\nconsole.log(new Greeter('Hello').sayHi('Simon'));\n```\n\n"
  },
  {
    "path": "website/src/content/docs/zh-cn/book/predefined-conditional-types.md",
    "content": "---\ntitle: 预定义条件类型\nsidebar:\n  order: 42\n  label: 42. 预定义条件类型\n---\n\n\n在 TypeScript 中，预定义的条件类型是语言提供的内置条件类型。它们旨在根据给定类型的特征执行常见的类型转换。\n\n`Exclude<UnionType, ExcludedType>`: 此类型从 Type 中删除可分配给 ExcludedType 的所有类型。\n\n`Extract<Type, Union>`: 此类型从 Union 中提取可分配给 Type 的所有类型。\n\n`NonNullable<Type>`: 此类型从 Type 中删除 null 和 undefined。\n\n`ReturnType<Type>`: 此类型提取函数 Type 的返回类型。\n\n`Parameters<Type>`: 该类型提取函数类型的参数类型。\n\n`Required<Type>`: 此类型使 Type 中的所有属性成为必需。\n\n`Partial<Type>`: 此类型使 Type 中的所有属性都是可选的。\n\n`Readonly<Type>`: 此类型使 Type 中的所有属性变为只读。\n\n"
  },
  {
    "path": "website/src/content/docs/zh-cn/book/primitive-types.md",
    "content": "---\ntitle: 原始类型\nsidebar:\n  order: 10\n  label: 10. 原始类型\n---\n\n\nTypeScript 支持 7 种基本类型。原始数据类型是指不是对象并且没有任何与其关联的方法的类型。在 TypeScript 中，所有原始类型都是不可变的，这意味着它们的值一旦分配就无法更改。\n\n### string\n\n原始 `string` 类型存储文本数据，并且值始终是双引号或单引号的。\n\n```typescript\nconst x: string = 'x';\nconst y: string = 'y';\n```\n\n如果字符串被反引号 (`) 字符包围，则字符串可以跨越多行：\n\n```typescript\nlet sentence: string = `xxx,\n   yyy`;\n```\n\n### boolean\n\nTypeScript 中的数据 `boolean` 类型存储二进制值，或者true或false。\n\n```typescript\nconst isReady: boolean = true;\n```\n\n### number\n\nTypeScript 中的数据类型 `number` 用 64 位浮点值表示。类型 `number` 可以表示整数和分数。TypeScript 还支持十六进制、二进制和八进制，例如：\n\n```typescript\nconst decimal: number = 10;\nconst hexadecimal: number = 0xa00d; // 十六进制数以 0x 开始\nconst binary: number = 0b1010; // 二进制数以 0b 开始\nconst octal: number = 0o633; // 八进制数以 0o 开始\n```\n\n### bigInt\n\n`bigInt` 表示无法用 `number` 表示的非常大的数值 (253 – 1)。\n\n`bigInt` 可以通过调用内置函数 `BigInt()` 或添加 `n` 到任何整数数字字面量的末尾来创建：\n\n```typescript\nconst x: bigint = BigInt(9007199254740991);\nconst y: bigint = 9007199254740991n;\n```\n\n笔记：\n\n* `bigInt` 值不能与 `number` 混合，也不能与内置的 `Math` 一起使用，它们必须强制为相同的类型。\n* 仅当目标配置为 ES2020 或更高版本时，“bigInt”值才可用。\n\n### symbol\n\nJavaScript 有一个原始函数 Symbol()，它创建一个全局唯一的引用。\n\n```typescript\nlet sym = Symbol('x'); // symbol 类型\n```\n\n### null and undefined\n\n`null`和 `undefined` 类型都表示没有值或不存在任何值。\n\n`undefined` 类型意味着该值未分配或初始化，或者指示无意中缺少值。\n\n`null` 类型意味着我们知道该字段没有值，因此值不可用，这表明故意不存在值。\n\n### Array\n\n`array` 是一种可以存储多个相同类型或不同类型的值的数据类型。可以使用以下语法定义它：\n\n```typescript\nconst x: string[] = ['a', 'b'];\nconst y: Array<string> = ['a', 'b'];\nconst j: Array<string | number> = ['a', 1, 'b', 2];\n```\n\nTypeScript 使用以下语法支持只读数组：\n\n<!-- skip -->\n```typescript\nconst x: readonly string[] = ['a', 'b']; // 只读修饰符\nconst y: ReadonlyArray<string> = ['a', 'b'];\nconst j: ReadonlyArray<string | number> = ['a', 1, 'b', 2];\nj.push('x'); // 有效\n```\n\nTypeScript 支持数组和只读数组：\n\n```typescript\nconst x: [string, number] = ['a', 1];\nconst y: readonly [string, number] = ['a', 1];\n```\n\n### any\n\n数据 `any` 类型字面上代表\"任何\"值，当 TypeScript 无法推断类型或未指定时，它是默认值。\n\n使用 `any` 时，TypeScript编译器会跳过类型检查，因此 `any` 使用时不存在类型安全。通常，当发生错误时不要使用 `any` 静默编译器，而是专注于修复错误，因为使用 `any` 它可能会破坏契约，并且我们会失去 TypeScript 自动完成的好处。\n\n在从 JavaScript 逐步迁移到 TypeScript 的过程中，该 `any` 类型可能很有用，因为它可以让编译器保持沉默。\n\n对于新项目，请使用 TypeScript 配置 `noImplicitAny` ，该配置使 TypeScript 能够在any使用或推断时发出错误。\n\n`any` 通常是错误的来源，它可以掩盖类型的实际问题。尽可能避免使用它。\n\n"
  },
  {
    "path": "website/src/content/docs/zh-cn/book/readonly-properties.md",
    "content": "---\ntitle: 只读属性\nsidebar:\n  order: 13\n  label: 13. 只读属性\n---\n\n\n是否可以通过使用修饰符来防止对属性进行写入，`readonly` 以确保该属性不能被重写，但不提供任何完全不变性的保证：\n\n```typescript\ninterface Y {\n    readonly a: number;\n}\n\ntype X = {\n    readonly a: number;\n};\n\ntype J = Readonly<{\n    a: number;\n}>;\n\ntype K = {\n    readonly [index: number]: string;\n};\n```\n\n"
  },
  {
    "path": "website/src/content/docs/zh-cn/book/strictnullchecks.md",
    "content": "---\ntitle: 严格空检查\nsidebar:\n  order: 18\n  label: 18. 严格空检查\n---\n\n\n`strictNullChecks` 是一个 TypeScript 编译器选项，强制执行严格的 null 检查。启用此选项后，只有在变量和参数已使用联合类型 `null` | `undefined` 显式声明为该类型时，才可以对其进行赋值`null` 或者 `undefined`。如果变量或参数未显式声明为可为空，TypeScript 将生成错误以防止潜在的运行时错误。\n\n"
  },
  {
    "path": "website/src/content/docs/zh-cn/book/symbols.md",
    "content": "---\ntitle: Symbols\nsidebar:\n  order: 58\n  label: 58. Symbols\n---\n\n\n符号是一种原始数据类型，表示不可变值，保证在程序的整个生命周期中全局唯一。\n\n符号可以用作对象属性的键，并提供一种创建不可枚举属性的方法。\n\n```typescript\nconst key1: symbol = Symbol('key1');\nconst key2: symbol = Symbol('key2');\n\nconst obj = {\n    [key1]: 'value 1',\n    [key2]: 'value 2',\n};\n\nconsole.log(obj[key1]); // value 1\nconsole.log(obj[key2]); // value 2\n```\n\n在 WeakMap 和 WeakSet 中，现在允许符号作为键。\n\n"
  },
  {
    "path": "website/src/content/docs/zh-cn/book/table-of-contents.md",
    "content": "---\ntitle: 目录表\nsidebar:\n  order: 4\n  label: 4. 目录表\n---\n\n\n<!-- markdownlint-disable MD004 -->\n- 简洁的TypeScript之书\n  - 翻译\n  - 下载和网站\n  - 目录表\n  - 介绍\n  - 关于作者\n  - TypeScript简介\n    - 什么是TypeScript？\n    - 为什么选择 TypeScript？\n    - TypeScript 和 JavaScript\n    - TypeScript 代码生成\n    - 现在的现代 JavaScript（降级）\n  - TypeScript 入门\n    - 安装\n    - 配置\n    - TypeScript 的配置文件\n      - target\n      - lib\n      - strict\n      - module\n      - moduleResolution\n      - esModuleInterop\n      - jsx\n      - skipLibCheck\n      - files\n      - include\n      - exclude\n    - importHelpers\n    - 迁移到 TypeScript 的建议\n  - 探索类型系统\n    - TypeScript 的语言服务\n    - 结构类型\n    - TypeScript 的基本比较规则\n    - 类型作为集合\n    - 赋值类型：类型声明和类型断言\n      - 类型声明\n      - 类型断言\n      - 非空断言\n      - 环境声明\n    - 属性检测和多余属性检测\n    - 弱类型\n    - 严格的对象字面量检测 (Freshness)\n    - 类型推断\n    - 更高级的推断\n    - 类型加宽\n    - 常量\n      - 类型参数的 const 修饰符\n    - 常量断言\n    - 显式类型注释\n    - 类型缩小\n      - 条件\n      - 抛错或者返回\n      - 可区分联合\n      - 用户定义的类型保护\n  - 原始类型\n    - string\n    - boolean\n    - number\n    - bigInt\n    - symbol\n    - null and undefined\n    - Array\n    - any\n  - 类型注释\n  - 可选属性\n  - 只读属性\n  - 索引签名\n  - 扩展类型\n  - 字面量类型\n  - 字面量推断\n  - 严格空检查\n  - 枚举\n    - 数字枚举\n    - 字符串枚举\n    - 常量枚举\n    - 反向映射\n    - 环境枚举\n    - 计算成员和常量成员\n  - 缩小范围\n    - typeof 类型保护\n    - 真实性缩小\n    - 相等缩小\n    - In运算符缩小\n    - instanceof 缩小\n  - 赋值\n  - 控制流分析\n  - 类型谓词\n  - 可区分联合\n  - never 类型\n  - 详尽性检查\n  - 对象类型\n  - 元组类型（匿名）\n  - 命名元组类型（已标记）\n  - 固定长度元组\n  - 联合类型\n  - 交集类型\n  - 类型索引\n  - 值的类型\n  - Func 返回值的类型\n  - 模块的类型\n  - 映射类型\n  - 映射类型修饰符\n  - 条件类型\n  - 分配条件类型\n  - infer 条件类型中的类型推断\n  - 预定义条件类型\n  - 模板联合类型\n  - 任意类型\n  - 未知类型\n  - 空类型\n  - Never类型\n  - 接口及类型\n    - 通用语法\n    - 基本类型\n    - 对象和接口\n    - 并集和交集类型\n  - 内置原始数据类型\n  - 常见的内置JS对象\n  - 重载\n  - 合并与扩展\n  - 类型和接口之间的差异\n  - Class\n    - 通用语法\n    - 构造函数\n    - 私有和受保护的构造函数\n    - 访问修饰符\n    - Get 与 Set\n    - 类中的自动访问器\n    - this\n    - 参数属性\n    - 抽象类\n    - 使用泛型\n    - 装饰器\n      - 类装饰器\n      - 属性装饰器\n      - 方法装饰器\n      - Getter 和 Setter 装饰器\n    - 装饰器元数据\n    - 继承\n    - 静态成员\n    - 属性初始化\n    - 方法重载\n  - 泛型\n    - 泛型类型\n    - 泛型类\n    - 泛型约束\n    - 泛型上下文缩小\n  - 擦除的结构类型\n  - 命名空间\n  - Symbols\n  - 三斜杠指令\n  - 类型操作\n    - 从类型创建类型\n    - 索引访问类型\n    - 工具类型\n      - Awaited\\<T\\>\n      - Partial\\<T\\>\n      - Required\\<T\\>\n      - Readonly\\<T\\>\n      - Record\\<K, T\\>\n      - Pick\\<T, K\\>\n      - Omit\\<T, K\\>\n      - Exclude\\<T, U\\>\n      - Extract\\<T, U\\>\n      - NonNullable\\<T\\>\n      - Parameters\\<T\\>\n      - ConstructorParameters\\<T\\>\n      - ReturnType\\<T\\>\n      - InstanceType\\<T\\>\n      - ThisParameterType\\<T\\>\n      - OmitThisParameter\\<T\\>\n      - ThisType\\<T\\>\n      - Uppercase\\<T\\>\n      - Lowercase\\<T\\>\n      - Capitalize\\<T\\>\n      - Uncapitalize\\<T\\>\n      - NoInfer\\<T\\>\n  - 其他\n    - 错误和异常处理\n    - 混合类\n    - 异步语言特性\n    - 迭代器和生成器\n    - TsDocs JSDoc 参考\n    - @types\n    - JSX\n    - ES6 模块\n    - ES7 求幂运算符\n    - for-await-of 语句\n    - New target 元属性\n    - 动态导入表达式\n    - \"tsc –watch\"\n    - 默认声明\n    - 可选链\n    - 空合并运算符\n    - 模板字符串类型\n    - 函数重载\n    - 递归类型\n    - 递归条件类型\n    - Node 中的 ECMAScript 模块支持\n    - 断言函数\n    - 可变参数元组类型\n    - 装箱类型\n    - TypeScript 中的协变和逆变\n      - 类型参数的可选方差注释\n    - 模板字符串模式索引签名\n    - satisfies操作符\n    - 仅类型导入和导出\n    - 使用声明和显式资源管理\n      - 使用声明等待\n    - 导入属性\n<!-- markdownlint-enable MD004 -->\n\n"
  },
  {
    "path": "website/src/content/docs/zh-cn/book/template-union-types.md",
    "content": "---\ntitle: 模板联合类型\nsidebar:\n  order: 43\n  label: 43. 模板联合类型\n---\n\n\n模板联合类型可用于合并和操作类型系统内的文本，例如：\n\n```typescript\ntype Status = 'active' | 'inactive';\ntype Products = 'p1' | 'p2';\ntype ProductId = `id-${Products}-${Status}`; // \"id-p1-active\" | \"id-p1-inactive\" | \"id-p2-active\" | \"id-p2-inactive\"\n```\n\n"
  },
  {
    "path": "website/src/content/docs/zh-cn/book/the-concise-typescript-book.md",
    "content": "---\ntitle: 简洁的TypeScript之书\nsidebar:\n  order: 1\n  label: 1. 简洁的TypeScript之书\n---\n\n\n《Concise TypeScript Book》全面而简洁地概述了 TypeScript 的功能。它提供了清晰的解释，涵盖了该语言最新版本中的所有方面，从强大的类型系统到高级功能。无论您是初学者还是经验丰富的开发人员，本书都是增强您对 TypeScript 的理解和熟练程度的宝贵资源。\n\n本书完全免费且开源。\n\n我相信高质量的技术教育应该惠及所有人，因此我坚持本书免费开源。\n\n如果本书帮助您解决了 bug、理解了棘手的概念或提升了您的职业发展，请考虑以您认为合适的金额（建议价格：15 美元）或请我喝杯咖啡来支持我的工作。您的支持将帮助我保持内容更新，并添加新的示例和更深入的解释。\n\n[![Buy Me a Coffee](https://img.shields.io/badge/buy_me_a_coffee-FFDD00?style=for-the-badge&logo=buy-me-a-coffee&logoColor=black)](https://www.buymeacoffee.com/simonepoggiali)\n\n[![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.com/donate/?business=QW82ZS956XLFY&no_recurring=0&currency_code=EUR)\n\n"
  },
  {
    "path": "website/src/content/docs/zh-cn/book/the-never-type.md",
    "content": "---\ntitle: never 类型\nsidebar:\n  order: 25\n  label: 25. never 类型\n---\n\n\n当变量缩小为不能包含任何值的类型时，TypeScript 编译器将推断该变量必须属于该never类型。这是因为 never 类型代表永远无法生成的值。\n\n```typescript\nconst printValue = (val: string | number) => {\n    if (typeof val === 'string') {\n        console.log(val.toUpperCase());\n    } else if (typeof val === 'number') {\n        console.log(val.toFixed(2));\n    } else {\n        // val 在这里的类型为 never，因为它只能是字符串或数字\n        const neverVal: never = val;\n        console.log(`Unexpected value: ${neverVal}`);\n    }\n};\n```\n\n"
  },
  {
    "path": "website/src/content/docs/zh-cn/book/translations.md",
    "content": "---\ntitle: 翻译\nsidebar:\n  order: 2\n  label: 2. 翻译\n---\n\n\n本书已被翻译成多种语言版本，包括：\n\n[中文](https://github.com/gibbok/typescript-book/blob/main/README-zh_CN.md)\n\n[意大利](https://github.com/gibbok/typescript-book/blob/main/README-it_IT.md)\n\n[葡萄牙语（巴西）](https://github.com/gibbok/typescript-book/blob/main/README-pt_BR.md)\n\n[瑞典语](https://github.com/gibbok/typescript-book/blob/main/README-sv_SE.md)\n\n"
  },
  {
    "path": "website/src/content/docs/zh-cn/book/triple-slash-directives.md",
    "content": "---\ntitle: 三斜杠指令\nsidebar:\n  order: 59\n  label: 59. 三斜杠指令\n---\n\n\n三斜杠指令是特殊注释，为编译器提供有关如何处理文件的说明。这些指令以三个连续斜杠 (`///`) 开头，通常放置在 TypeScript 文件的顶部，对运行时行为没有影响。\n\n三斜杠指令用于引用外部依赖项、指定模块加载行为、启用/禁用某些编译器功能等等。几个例子：\n\n引用声明文件：\n\n<!-- skip -->\n```typescript\n/// <reference path=\"path/to/declaration/file.d.ts\" />\n```\n\n指明模块格式：\n\n<!-- skip -->\n```typescript\n/// <amd|commonjs|system|umd|es6|es2015|none>\n```\n\n启用编译器选项，在以下示例中严格模式：\n\n<!-- skip -->\n```typescript\n/// <strict|noImplicitAny|noUnusedLocals|noUnusedParameters>\n```\n\n"
  },
  {
    "path": "website/src/content/docs/zh-cn/book/tuple-type-anonymous.md",
    "content": "---\ntitle: 元组类型（匿名）\nsidebar:\n  order: 28\n  label: 28. 元组类型（匿名）\n---\n\n\n元组类型是一种表示具有固定数量的元素及其相应类型的数组的类型。元组类型以固定顺序强制执行特定数量的元素及其各自的类型。当您想要表示具有特定类型的值的集合时，元组类型非常有用，其中数组中每个元素的位置都有特定的含义。\n\n```typescript\ntype Point = [number, number];\n```\n\n"
  },
  {
    "path": "website/src/content/docs/zh-cn/book/type-annotations.md",
    "content": "---\ntitle: 类型注释\nsidebar:\n  order: 11\n  label: 11. 类型注释\n---\n\n\n在使用 `var` 、 `let` 和 `const` 声明变量时，可以选择添加类型：\n\n```typescript\nconst x: number = 1;\n```\n\nTypeScript 在推断类型方面做得很好，尤其是简单类型时，因此在大多数情况下这些声明是不必要的。\n\n在函数上可以向参数添加类型注释：\n\n```typescript\nfunction sum(a: number, b: number) {\n    return a + b;\n}\n```\n\n以下是使用匿名函数（所谓的 lambda 函数）的示例：\n\n```typescript\nconst sum = (a: number, b: number) => a + b;\n```\n\n当参数存在默认值时可以避免这些注释：\n\n```typescript\nconst sum = (a = 10, b: number) => a + b;\n```\n\n可以将返回类型注释添加到函数中：\n\n```typescript\nconst sum = (a = 10, b: number): number => a + b;\n```\n\n这对于更复杂的函数尤其有用，因为在实现之前编写显式返回类型可以帮助更好地思考该函数。\n\n通常考虑注释类型签名，但不注释主体局部变量，并始终将类型添加到对象字面量中。\n\n"
  },
  {
    "path": "website/src/content/docs/zh-cn/book/type-from-func-return.md",
    "content": "---\ntitle: Func 返回值的类型\nsidebar:\n  order: 35\n  label: 35. Func 返回值的类型\n---\n\n\nFunc Return 中的类型是指根据函数的实现自动推断函数的返回类型的能力。这允许 TypeScript 无需显式类型注释即可确定函数返回值的类型。\n\n```typescript\nconst add = (x: number, y: number) => x + y; // TypeScript 可以推断函数的返回类型是数字\n```\n\n"
  },
  {
    "path": "website/src/content/docs/zh-cn/book/type-from-module.md",
    "content": "---\ntitle: 模块的类型\nsidebar:\n  order: 36\n  label: 36. 模块的类型\n---\n\n\n模块的类型是指使用模块的导出值自动推断其类型的能力。当模块导出特定类型的值时，TypeScript 可以使用该信息在将该值导入到另一个模块时自动推断该值的类型。\n\n<!-- skip -->\n```typescript\nexport const add = (x: number, y: number) => x + y;\n// index.ts\nimport { add } from 'calc';\nconst r = add(1, 2); // r 是 number 类型\n```\n\n"
  },
  {
    "path": "website/src/content/docs/zh-cn/book/type-from-value.md",
    "content": "---\ntitle: 值的类型\nsidebar:\n  order: 34\n  label: 34. 值的类型\n---\n\n\nTypeScript 中的\"Type from Value\"是指通过类型推断从值或表达式自动推断出类型。\n\n```typescript\nconst x = 'x'; // TypeScript 可以自动推断变量的类型是 string\n```\n\n"
  },
  {
    "path": "website/src/content/docs/zh-cn/book/type-indexing.md",
    "content": "---\ntitle: 类型索引\nsidebar:\n  order: 33\n  label: 33. 类型索引\n---\n\n\n类型索引是指能够通过预先未知的键来定义可以索引的类型，使用索引签名来指定未显式声明的属性的类型。\n\n```typescript\ntype Dictionary<T> = {\n    [key: string]: T;\n};\nconst myDict: Dictionary<string> = { a: 'a', b: 'b' };\nconsole.log(myDict['a']); // 返回 a\n```\n\n"
  },
  {
    "path": "website/src/content/docs/zh-cn/book/type-manipulation.md",
    "content": "---\ntitle: 类型操作\nsidebar:\n  order: 60\n  label: 60. 类型操作\n---\n\n\n### 从类型创建类型\n\n是否可以通过组合、操作或转换现有类型来创建新类型。\n\n交集类型 ( &):\n\n允许您将多种类型组合成单一类型：\n\n```typescript\ntype A = { foo: number };\ntype B = { bar: string };\ntype C = A & B; // A和B的交集\nconst obj: C = { foo: 42, bar: 'hello' };\n```\n\n联合类型 (`|`):\n\n允许您定义可以是以下几种类型之一的类型\n\n```typescript\ntype Result = string | number;\nconst value1: Result = 'hello';\nconst value2: Result = 42;\n```\n\n映射类型：\n\n允许您转换现有类型的属性以创建新类型：\n\n```typescript\ntype Mutable<T> = {\n    readonly [P in keyof T]: T[P];\n};\ntype Person = {\n    name: string;\n    age: number;\n};\ntype ImmutablePerson = Mutable<Person>; // 属性变为只读\n```\n\n条件类型：\n\n允许您根据某些条件创建类型：\n\n```typescript\ntype ExtractParam<T> = T extends (param: infer P) => any ? P : never;\ntype MyFunction = (name: string) => number;\ntype ParamType = ExtractParam<MyFunction>; // string\n```\n\n### 索引访问类型\n\n在 TypeScript 中，可以使用索引访问和操作另一个类型中的属性类型 `Type[Key]`。\n\n```typescript\ntype Person = {\n    name: string;\n    age: number;\n};\n\ntype AgeType = Person['age']; // number\n```\n\n```typescript\ntype MyTuple = [string, number, boolean];\ntype MyType = MyTuple[2]; // boolean\n```\n\n### 工具类型\n\n可以使用几种内置工具来操作类型，下面列出了最常用的：\n\n#### Awaited\\<T\\>\n\n构造一个递归解包 Promise 类型的类型。\n\n```typescript\ntype A = Awaited<Promise<string>>; // string\n```\n\n#### Partial\\<T\\>\n\n构造一个类型，并将 T 的所有属性设置为可选。\n\n```typescript\ntype Person = {\n    name: string;\n    age: number;\n};\n\ntype A = Partial<Person>; // { name?: string | undefined; age?: number | undefined; }\n```\n\n#### Required\\<T\\>\n\n构造一个类型，并将 T 的所有属性设置为必需。\n\n```typescript\ntype Person = {\n    name?: string;\n    age?: number;\n};\n\ntype A = Required<Person>; // { name: string; age: number; }\n```\n\n#### Readonly\\<T\\>\n\n构造一个类型，并将 T 的所有属性设置为只读。\n\n<!-- skip -->\n```typescript\ntype Person = {\n    name: string;\n    age: number;\n};\n\ntype A = Readonly<Person>;\n\nconst a: A = { name: 'Simon', age: 17 };\na.name = 'John'; // 无效\n```\n\n#### Record\\<K, T\\>\n\n构造一个具有类型 T 的一组属性 K 的类型。\n\n```typescript\ntype Product = {\n    name: string;\n    price: number;\n};\n\nconst products: Record<string, Product> = {\n    apple: { name: 'Apple', price: 0.5 },\n    banana: { name: 'Banana', price: 0.25 },\n};\n\nconsole.log(products.apple); // { name: 'Apple', price: 0.5 }\n```\n\n#### Pick\\<T, K\\>\n\n通过从 T 中选取指定属性 K 来构造类型。\n\n```typescript\ntype Product = {\n    name: string;\n    price: number;\n};\n\ntype Price = Pick<Product, 'price'>; // { price: number; }\n```\n\n#### Omit\\<T, K\\>\n\n通过从 T 中省略指定属性 K 来构造类型。\n\n```typescript\ntype Product = {\n    name: string;\n    price: number;\n};\n\ntype Name = Omit<Product, 'price'>; // { name: string; }\n```\n\n#### Exclude\\<T, U\\>\n\n通过从 T 中排除类型 U 的所有值来构造类型。\n\n```typescript\ntype Union = 'a' | 'b' | 'c';\ntype MyType = Exclude<Union, 'a' | 'c'>; // b\n```\n\n#### Extract\\<T, U\\>\n\n通过从 T 中提取类型 U 的所有值来构造类型。\n\n```typescript\ntype Union = 'a' | 'b' | 'c';\ntype MyType = Extract<Union, 'a' | 'c'>; // a | c\n```\n\n#### NonNullable\\<T\\>\n\n通过从 T 中排除 null 和 undefined 来构造类型。\n\n```typescript\ntype Union = 'a' | null | undefined | 'b';\ntype MyType = NonNullable<Union>; // 'a' | 'b'\n```\n\n#### Parameters\\<T\\>\n\n提取函数类型 T 的参数类型。\n\n```typescript\ntype Func = (a: string, b: number) => void;\ntype MyType = Parameters<Func>; // [a: string, b: number]\n```\n\n#### ConstructorParameters\\<T\\>\n\n提取构造函数类型 T 的参数类型。\n\n```typescript\nclass Person {\n    constructor(\n        public name: string,\n        public age: number\n    ) {}\n}\ntype PersonConstructorParams = ConstructorParameters<typeof Person>; // [name: string, age: number]\nconst params: PersonConstructorParams = ['John', 30];\nconst person = new Person(...params);\nconsole.log(person); // Person { name: 'John', age: 30 }\n```\n\n#### ReturnType\\<T\\>\n\n提取函数类型 T 的返回类型。\n\n```typescript\ntype Func = (name: string) => number;\ntype MyType = ReturnType<Func>; // number\n```\n\n#### InstanceType\\<T\\>\n\n提取类类型 T 的实例类型。\n\n```typescript\nclass Person {\n    name: string;\n\n    constructor(name: string) {\n        this.name = name;\n    }\n\n    sayHello() {\n        console.log(`Hello, my name is ${this.name}!`);\n    }\n}\n\ntype PersonInstance = InstanceType<typeof Person>;\n\nconst person: PersonInstance = new Person('John');\n\nperson.sayHello(); // Hello, my name is John!\n```\n\n#### ThisParameterType\\<T\\>\n\n从函数类型 T 中提取\"this\"参数的类型。\n\n```typescript\ninterface Person {\n    name: string;\n    greet(this: Person): void;\n}\ntype PersonThisType = ThisParameterType<Person['greet']>; // Person\n```\n\n#### OmitThisParameter\\<T\\>\n\n从函数类型 T 中删除\"this\"参数。\n\n```typescript\nfunction capitalize(this: String) {\n    return this[0].toUpperCase + this.substring(1).toLowerCase();\n}\n\ntype CapitalizeType = OmitThisParameter<typeof capitalize>; // () => string\n```\n\n#### ThisType\\<T\\>\n\n作为上下文类型 `this` 的一部分。\n\n<!-- skip -->\n```typescript\ntype Logger = {\n    log: (error: string) => void;\n};\n\nlet helperFunctions: { [name: string]: Function } & ThisType<Logger> = {\n    hello: function () {\n        this.log('some error'); // 有效，因为\"log\"是\"this\"的一部分\n        this.update(); // 无效\n    },\n};\n```\n\n#### Uppercase\\<T\\>\n\n将输入类型 T 的名称设为大写。\n\n```typescript\ntype MyType = Uppercase<'abc'>; // \"ABC\"\n```\n\n#### Lowercase\\<T\\>\n\n将输入类型 T 的名称设为小写。\n\n```typescript\ntype MyType = Lowercase<'ABC'>; // \"abc\"\n```\n\n#### Capitalize\\<T\\>\n\n输入类型 T 的名称大写。\n\n```typescript\ntype MyType = Capitalize<'abc'>; // \"Abc\"\n```\n\n#### Uncapitalize\\<T\\>\n\n将输入类型 T 的名称取消大写。\n\n```typescript\ntype MyType = Uncapitalize<'Abc'>; // \"abc\"\n```\n\n#### NoInfer\\<T\\>\n\nNoInfer 是一种实用类型，旨在阻止泛型函数范围内类型的自动推断。\n\n示例：\n\n```typescript\n// 泛型函数范围内类型的自动推断。\nfunction fn<T extends string>(x: T[], y: T) {\n    return x.concat(y);\n}\nconst r = fn(['a', 'b'], 'c'); // 此处的类型为 (\"a\" | \"b\" | \"c\")[]\n```\n\n使用 NoInfer：\n\n<!-- skip -->\n```typescript\n// 使用 NoInfer 阻止类型推断的示例函数\nfunction fn2<T extends string>(x: T[], y: NoInfer<T>) {\n    return x.concat(y);\n}\n\nconst r2 = fn2(['a', 'b'], 'c'); // 错误：类型为“c”的类型参数不能分配给类型为“a”|“b”的参数。\n```\n\n"
  },
  {
    "path": "website/src/content/docs/zh-cn/book/type-predicates.md",
    "content": "---\ntitle: 类型谓词\nsidebar:\n  order: 23\n  label: 23. 类型谓词\n---\n\n\nTypeScript 中的类型谓词是返回布尔值的函数，用于将变量的类型缩小为更具体的类型。\n\n```typescript\nconst isString = (value: unknown): value is string => typeof value === 'string';\n\nconst foo = (bar: unknown) => {\n    if (isString(bar)) {\n        console.log(bar.toUpperCase());\n    } else {\n        console.log('not a string');\n    }\n};\n```\n\n"
  },
  {
    "path": "website/src/content/docs/zh-cn/book/typescript-introduction.md",
    "content": "---\ntitle: TypeScript简介\nsidebar:\n  order: 7\n  label: 7. TypeScript简介\n---\n\n\n### 什么是TypeScript？\n\nTypeScript 是一种基于 JavaScript 的强类型编程语言。它最初由 Anders Hejlsberg 于 2012 年设计，目前由微软开发和维护，是一个开源项目。\n\nTypeScript 会被编译成 JavaScript，并可在任何 JavaScript 运行时环境（例如浏览器或服务器上的 Node.js）中执行。\n\n它支持多种编程范式，例如函数式编程、泛型编程、命令式编程和面向对象编程。TypeScript 是一种编译型（转译型）语言，在执行前会被转换为 JavaScript。\n\n### 为什么选择 TypeScript？\n\nTypeScript 是一种强类型语言，有助于防止常见的编程错误，并在程序执行之前避免某些类型的运行时错误。\n\n强类型语言允许开发人员在数据类型定义中指定各种程序约束和行为，从而有助于验证软件的正确性并防止缺陷。这在大规模应用中尤其有价值。\n\nTypeScript 的一些好处\n\n* 静态类型，可选强类型\n* 类型推断\n* 能使用ES6和ES7的新功能\n* 跨平台和跨浏览器兼容性 \\* IntelliSense 工具支持\n\n### TypeScript 和 JavaScript\n\nTypeScript是用`.ts`或`.tsx`文件编写的, 而JavaScript是用`.js`或`.jsx`文件编写的。\n\n扩展名为.tsx或.jsx的文件可以包含 JavaScript 语法扩展 JSX，该扩展在 React 中用于 UI 开发。\n\n就语法而言，TypeScript 是 JavaScript (ECMAScript 2015) 的类型化超集。所有 JavaScript 代码都是有效的 TypeScript 代码，但反之则不然。\n\n例如，考虑 JavaScript 文件中具有.js扩展名的函数，如下所示：\n\n<!-- skip -->\n```typescript\nconst sum = (a, b) => a + b;\n```\n\n该函数可以通过将文件扩展名更改为 .TypeScript 来转换和使用.ts。但是，如果同一个函数使用 TypeScript 类型进行注释，则未经编译就无法在任何 JavaScript 运行时中执行。如果未编译以下 TypeScript 代码，将会产生语法错误\n\n<!-- skip -->\n```typescript\nconst sum = (a: number, b: number): number => a + b;\n```\n\nTypeScript 旨在通过让开发人员使用类型注释定义意图来检测编译期间运行时可能发生的异常。此外，如果没有提供类型注释，TypeScript 也可以捕获问题。例如，以下代码片段未指定任何 TypeScript 类型：\n\n<!-- skip -->\n```typescript\nconst items = [{ x: 1 }, { x: 2 }];\nconst result = items.filter(item => item.y);\n```\n\n在这种情况下，TypeScript 检测到错误并报告：\n\n```text\n类型 '{ x: number; }' 上不存在属性 'y' 。\n```\n\nTypeScript 的类型系统很大程度上受到 JavaScript 运行时行为的影响。例如，加法运算符 (+) 在 JavaScript 中可以执行字符串连接或数字加法，在 TypeScript 中以相同的方式建模：\n\n```typescript\nconst result = '1' + 1; // 结果是string类型\n```\n\nTypeScript 背后的团队经过深思熟虑，决定将 JavaScript 的异常使用标记为错误。例如，考虑以下有效的 JavaScript 代码：\n\n<!-- skip -->\n```typescript\nconst result = 1 + true; // 在JavaScript中, 结果等于2\n```\n\n但是，TypeScript 会抛出错误：\n\n```text\n运算符\"+\"不能应用于类型\"number\"和\"boolean\"。\n``````\n\n出现此错误的原因是 TypeScript 严格强制执行类型兼容性，在这种情况下，它标识了数字和布尔值之间的无效操作。\n\n### TypeScript 代码生成\n\nTypeScript 编译器有两个主要职责：检查类型错误和编译为 JavaScript。这两个过程是相互独立的。类型不会影响 JavaScript 运行时中代码的执行，因为它们在编译过程中会被完全擦除。即使存在类型错误，TypeScript 仍然可以输出 JavaScript。以下是存在类型错误的 TypeScript 代码示例：\n\n<!-- skip -->\n```typescript\nconst add = (a: number, b: number): number => a + b;\nconst result = add('x', 'y'); // \"字符串\"类型的参数不可赋值给\"数字\"类型的参数\n```\n\n但是，它仍然可以生成可执行的 JavaScript 输出：\n\n<!-- skip -->\n```typescript\n'use strict';\nconst add = (a, b) => a + b;\nconst result = add('x', 'y'); // xy\n```\n\n无法在运行时检查 TypeScript 类型。例如：\n\n<!-- skip -->\n```typescript\ninterface Animal {\n    name: string;\n}\ninterface Dog extends Animal {\n    bark: () => void;\n}\ninterface Cat extends Animal {\n    meow: () => void;\n}\nconst makeNoise = (animal: Animal) => {\n    if (animal instanceof Dog) {\n        // \"Dog\"仅指一种类型，但在这里用作值。\n        // ...\n    }\n};\n```\n\n由于编译后类型被删除，因此无法在 JavaScript 中运行此代码。为了在运行时识别类型，我们需要使用另一种机制。TypeScript 提供了多种选项，其中常见的一个是 \"标签联合（tagged union）\"。例如：\n\n```typescript\ninterface Dog {\n    kind: 'dog'; // 标签联合\n    bark: () => void;\n}\ninterface Cat {\n    kind: 'cat'; // 标签联合\n    meow: () => void;\n}\ntype Animal = Dog | Cat;\n\nconst makeNoise = (animal: Animal) => {\n    if (animal.kind === 'dog') {\n        animal.bark();\n    } else {\n        animal.meow();\n    }\n};\n\nconst dog: Dog = {\n    kind: 'dog',\n    bark: () => console.log('bark'),\n};\nmakeNoise(dog);\n```\n\n属性\"kind\"是一个可以在运行时用来区分 JavaScript 中的对象的值。\n\n运行时的值也可能具有与类型声明中声明的类型不同的类型。例如，如果开发人员误解了 API 类型并对其进行了错误注释。\n\nTypeScript 是 JavaScript 的超集，因此\"class\"关键字可以在运行时用作类型和值。\n\n```typescript\nclass Animal {\n    constructor(public name: string) {}\n}\nclass Dog extends Animal {\n    constructor(\n        public name: string,\n        public bark: () => void\n    ) {\n        super(name);\n    }\n}\nclass Cat extends Animal {\n    constructor(\n        public name: string,\n        public meow: () => void\n    ) {\n        super(name);\n    }\n}\ntype Mammal = Dog | Cat;\n\nconst makeNoise = (mammal: Mammal) => {\n    if (mammal instanceof Dog) {\n        mammal.bark();\n    } else {\n        mammal.meow();\n    }\n};\n\nconst dog = new Dog('Fido', () => console.log('bark'));\nmakeNoise(dog);\n```\n\n在 JavaScript 中，\"类\"具有\"prototype\"属性，\"instanceof\"运算符可用于测试构造函数的原型属性是否出现在对象原型链中的任何位置。\n\nTypeScript 对运行时性能没有影响，因为所有类型都将被删除。然而，TypeScript 确实引入了一些构建时间开销。\n\n### 现在的现代 JavaScript（降级）\n\nTypeScript 可以将代码编译为自 ECMAScript 3 (1999) 以来任何已发布的 JavaScript 版本。这意味着 TypeScript 可以将代码从最新的 JavaScript 功能转换为旧版本，这一过程称为降级。这允许使用现代 JavaScript，同时保持与旧运行时环境的最大兼容性。\n\n值得注意的是，在转换为旧版本 JavaScript 的过程中，TypeScript 可能会生成与本机实现相比会产生性能开销的代码。\n\n以下是一些可以在 TypeScript 中使用的现代 JavaScript 功能：\n\n* ECMAScript 模块，而不是 AMD 风格的\"define\"回调或 CommonJS 的\"require\"语句。\n* 用类代替原型。\n* 变量声明使用\"let\"或\"const\"而不是\"var\"。\n* \"for-of\"循环或\".forEach\"而不是传统的\"for\"循环。\n* 用箭头函数代替函数表达式。\n* 解构赋值。\n* 简写属性/方法名称和计算属性名称。\n* 默认函数参数。\n\n通过利用这些现代 JavaScript 功能，开发人员可以在 TypeScript 中编写更具表现力和简洁的代码。\n\n"
  },
  {
    "path": "website/src/content/docs/zh-cn/book/union-type.md",
    "content": "---\ntitle: 联合类型\nsidebar:\n  order: 31\n  label: 31. 联合类型\n---\n\n\n联合类型是一种表示值的类型，该值可以是多种类型之一。联合类型使用 `|` 表示 每种可能类型之间的符号。\n\n```typescript\nlet x: string | number;\nx = 'hello'; // 有效\nx = 123; // 有效\n```\n\n"
  },
  {
    "path": "website/src/content/docs/zh-cn/book/unknown-type.md",
    "content": "---\ntitle: 未知类型\nsidebar:\n  order: 45\n  label: 45. 未知类型\n---\n\n\n在 TypeScript 中，未知类型表示未知类型的值。与允许任何类型值的 `any` 类型不同，`unknown` 需要在以特定方式使用它之前进行类型检查或断言，因此在未首先断言或缩小到更具体的类型的情况下，不允许对 `unknown` 进行任何操作 。\n\n`unknown` 类型只能分配给任何类型和未知类型本身，它是any 的类型安全替代方案。\n\n<!-- skip -->\n```typescript\nlet value: unknown;\n\nlet value1: unknown = value; // 有效\nlet value2: any = value; // 有效\nlet value3: boolean = value; // 无效\nlet value4: number = value; // 无效\n```\n\n```typescript\nconst add = (a: unknown, b: unknown): number | undefined =>\n    typeof a === 'number' && typeof b === 'number' ? a + b : undefined;\nconsole.log(add(1, 2)); // 3\nconsole.log(add('x', 2)); // undefined\n```\n\n"
  },
  {
    "path": "website/src/content/docs/zh-cn/book/void-type.md",
    "content": "---\ntitle: 空类型\nsidebar:\n  order: 46\n  label: 46. 空类型\n---\n\n\n`void` 类型用于指示函数不返回值。\n\n```typescript\nconst sayHello = (): void => {\n    console.log('Hello!');\n};\n```\n\n"
  },
  {
    "path": "website/src/content/docs/zh-cn/index.mdx",
    "content": "---\ntitle: TypeScript Book\ndescription: The Concise TypeScript Book\ntemplate: splash\nhero:\n    tagline: 《Concise TypeScript Book》全面而简洁地概述了 TypeScript\n        的功能。它提供了清晰的解释，涵盖了该语言最新版本中的所有方面，从强大的类型系统到高级功能。无论您是初学者还是经验丰富的开发人员，本书都是增强您对\n        TypeScript 的理解和熟练程度的宝贵资源。<br/><br/>本书完全免费且开源。\n    actions:\n        - text: 现在读!\n          link: /typescript-book/zh-cn/book/the-concise-typescript-book/\n          icon: right-arrow\n          variant: primary\n        - text: GitHub\n          link: https://github.com/gibbok/typescript-book\n          icon: github\n          variant: secondary\n        - text: X.com\n          link: https://twitter.com/gibbok_coding\n          icon: x.com\n          variant: secondary\n---\n"
  },
  {
    "path": "website/src/content/i18n/zh-cn.json",
    "content": "{}"
  },
  {
    "path": "website/src/env.d.ts",
    "content": "/// <reference path=\"../.astro/types.d.ts\" />\n/// <reference types=\"astro/client\" />\n"
  },
  {
    "path": "website/src/styles/custom.css",
    "content": "/* Dark mode colors. */\n:root {\n\t--sl-color-accent-low: #36113e;\n\t--sl-color-accent: #a400c0;\n\t--sl-color-accent-high: #e3b6ed;\n\t--sl-color-white: #ffffff;\n\t--sl-color-gray-1: #f2e9fd;\n\t--sl-color-gray-2: #c7bdd5;\n\t--sl-color-gray-3: #9581ae;\n\t--sl-color-gray-4: #614e78;\n\t--sl-color-gray-5: #412e55;\n\t--sl-color-gray-6: #2f1c42;\n\t--sl-color-black: #1c1425;\n}\n/* Light mode colors. */\n:root[data-theme='light'] {\n\t--sl-color-accent-low: #ebc9f3;\n\t--sl-color-accent: #a700c3;\n\t--sl-color-accent-high: #4e0e5b;\n\t--sl-color-white: #1c1425;\n\t--sl-color-gray-1: #2f1c42;\n\t--sl-color-gray-2: #412e55;\n\t--sl-color-gray-3: #614e78;\n\t--sl-color-gray-4: #9581ae;\n\t--sl-color-gray-5: #c7bdd5;\n\t--sl-color-gray-6: #f2e9fd;\n\t--sl-color-gray-7: #f8f4fe;\n\t--sl-color-black: #ffffff;\n}\n\n@media (min-width: 72rem) {\n\t.right-sidebar-container {\n\t\tmin-width: 27.188rem; /* Carbon ads layout adjustments for screens ≤ 1366px width */\n\t}\n}\n\n.right-sidebar-panel {\n\tpadding: 0.5rem var(--sl-sidebar-pad-x);\n}\n"
  },
  {
    "path": "website/tsconfig.json",
    "content": "{\n  \"extends\": \"astro/tsconfigs/strict\"\n}"
  }
]