├── .devcontainer └── devcontainer.json ├── .github ├── CODEOWNERS ├── ISSUE_TEMPLATE.md ├── PULL_REQUEST_TEMPLATE.md └── workflows │ └── main.yml ├── .gitignore ├── .vscode └── settings.json ├── 1-working-with-generics ├── 1-1-generics │ ├── ElementHolder.ts │ ├── KeyValuePair.ts │ ├── Pair.ts │ ├── Printer.ts │ ├── Queue.ts │ ├── Response.ts │ ├── exampleWithGenerics.ts │ ├── exampleWithoutGenerics.ts │ └── useQueue.ts ├── 1-2-advanced-generic-patterns │ ├── AppConfig.ts │ ├── CreateSomeClass.ts │ ├── Dog.ts │ ├── exampleConstraint.ts │ ├── exampleDefaultValue.ts │ ├── examplePipe.ts │ ├── useAppConfig.ts │ └── usingCreateSomeClass.ts ├── 1-3-design-patterns-generics │ ├── document-example │ │ ├── Document.ts │ │ ├── DocumentFactory.ts │ │ ├── ExcelDocument.ts │ │ ├── WordDocument.ts │ │ └── usingDocumentFactory.ts │ └── payment-example │ │ ├── CreditCardStrategy.ts │ │ ├── CryptoStrategy.ts │ │ ├── PayPalStrategy.ts │ │ ├── PaymentProcessor.ts │ │ ├── PaymentStrategy.ts │ │ └── usePaymentStrategies.ts └── challenge │ └── solution.ts ├── 2-advanced-types ├── 2-1-utility-types │ ├── OptionalProps.ts │ ├── Task.ts │ ├── Todo.ts │ ├── User.ts │ ├── exampleOmit.ts │ ├── exampleRecord.ts │ └── otherExamples.ts ├── 2-2-mapped-types │ ├── Person.ts │ ├── filterProperties.ts │ ├── nullablePerson.ts │ ├── optionalPerson.ts │ ├── readOnlyPerson.ts │ └── stringifiedPerson.ts ├── 2-3-conditional-types │ ├── exampleApiResponse.ts │ ├── examplesConditionalTypes.ts │ └── practicalExample.ts ├── 2-4-template-literal-types │ ├── EventConfig.ts │ └── templateLiteralTypes.ts └── challenge │ └── solution.ts ├── 3-mastering-function-overloading ├── 3-1-function-overloading │ ├── formatDate.ts │ └── greet.ts ├── 3-2-practical-use-case │ ├── log.ts │ └── userExample.ts └── challenge │ └── solution.ts ├── 4-sophisticated-type-manipulation ├── 4-1-type-guards │ ├── discriminatedUnions.ts │ └── simpleTypeGuard.ts ├── 4-2-using-type-assertion │ ├── exampleJsonString.ts │ └── usingTypeAssertion.ts ├── 4-3-the-unknown-explained │ ├── unknownExample.ts │ └── unknownUseCase.ts └── challenge │ └── solution.ts ├── 5-advanced-modularization-techniques ├── 5-1-namespaces-vs-modules │ ├── modules │ │ ├── invoice.ts │ │ └── main.ts │ └── namespaces │ │ ├── data.ts │ │ ├── payment.ts │ │ └── validation.ts ├── 5-2-dynamic-import-expressions │ ├── main.ts │ ├── mathUtils.ts │ ├── practicalExample.ts │ └── specialFeatureModule.ts └── challenge │ ├── analytics.ts │ ├── main.ts │ └── userManagement.ts ├── 6-decorators-and-metadata-reflection ├── 6-1-understanding-decorators │ ├── logClassExample.js │ ├── logClassExample.ts │ ├── logMethodExample.js │ ├── logMethodExample.ts │ └── tsconfig.json ├── 6-2-reflection-and-metadata │ ├── .gitkeep │ ├── exampleReflectMetadata.ts │ ├── exampleRoleCheck.ts │ ├── package-lock.json │ ├── package.json │ ├── reflectiveExample.js │ ├── reflectiveExample.ts │ └── tsconfig.json └── challenge │ ├── decorators.js │ ├── decorators.ts │ ├── main.js │ ├── main.ts │ ├── package-lock.json │ ├── package.json │ ├── productManagement.js │ ├── productManagement.ts │ └── tsconfig.json ├── 7-typescript-and-the-build-process ├── 7-1-integrating-with-build-tool-webpack │ ├── .gitkeep │ └── my-ts-project │ │ ├── dist │ │ └── bundle.js │ │ ├── package-lock.json │ │ ├── package.json │ │ ├── src │ │ └── index.ts │ │ ├── tsconfig.json │ │ └── webpack.config.js ├── 7-2-optimizing-typescript-for-production │ ├── .gitkeep │ └── my-ts-project │ │ ├── dist │ │ ├── app.503838203537d857f98d.js │ │ ├── bundle.js │ │ └── vendor.503838203537d857f98d.js │ │ ├── package-lock.json │ │ ├── package.json │ │ ├── src │ │ ├── index.ts │ │ └── vendor.ts │ │ ├── tsconfig.json │ │ └── webpack.config.js └── challenge │ ├── dist │ ├── app.ad85ddc11b9521185c6dbundle.js │ ├── bundle.js │ ├── largeModule.31d6cfe0d16ae931b73cbundle.js │ └── main.bundle.js │ ├── package-lock.json │ ├── package.json │ ├── src │ ├── app.ts │ ├── largeModule.ts │ └── unusedModule.ts │ ├── tsconfig.json │ └── webpack.config.js ├── CONTRIBUTING.md ├── LICENSE ├── NOTICE ├── README.md └── favicon.ico /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | "extensions": [ 3 | "GitHub.github-vscode-theme", 4 | "esbenp.prettier-vscode", 5 | "dbaeumer.vscode-eslint", 6 | "ritwickdey.LiveServer", 7 | "stylelint.vscode-stylelint" 8 | // Additional Extensions Here 9 | ], 10 | "onCreateCommand": "echo PS1='\"$ \"' >> ~/.bashrc", //Set Terminal Prompt to $ 11 | "postAttachCommand": "git pull --all" 12 | } 13 | 14 | // DevContainer Reference: https://code.visualstudio.com/docs/remote/devcontainerjson-reference 15 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # Codeowners for these exercise files: 2 | # * (asterisk) denotes "all files and folders" 3 | # Example: * @producer @instructor 4 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 7 | 8 | ## Issue Overview 9 | 10 | 11 | ## Describe your environment 12 | 13 | 14 | ## Steps to Reproduce 15 | 16 | 1. 17 | 2. 18 | 3. 19 | 4. 20 | 21 | ## Expected Behavior 22 | 23 | 24 | ## Current Behavior 25 | 26 | 27 | ## Possible Solution 28 | 29 | 30 | ## Screenshots / Video 31 | 32 | 33 | ## Related Issues 34 | 35 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: Copy To Branches 2 | on: 3 | workflow_dispatch: 4 | jobs: 5 | copy-to-branches: 6 | runs-on: ubuntu-latest 7 | steps: 8 | - uses: actions/checkout@v2 9 | with: 10 | fetch-depth: 0 11 | - name: Copy To Branches Action 12 | uses: planetoftheweb/copy-to-branches@v1.2 13 | env: 14 | key: main 15 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | .tmp 4 | npm-debug.log 5 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.bracketPairColorization.enabled": true, 3 | "editor.cursorBlinking": "solid", 4 | "editor.fontFamily": "ui-monospace, Menlo, Monaco, 'Cascadia Mono', 'Segoe UI Mono', 'Roboto Mono', 'Oxygen Mono', 'Ubuntu Monospace', 'Source Code Pro', 'Fira Mono', 'Droid Sans Mono', 'Courier New', monospace", 5 | "editor.fontLigatures": false, 6 | "editor.fontSize": 22, 7 | "editor.formatOnPaste": true, 8 | "editor.formatOnSave": true, 9 | "editor.lineNumbers": "on", 10 | "editor.matchBrackets": "always", 11 | "editor.minimap.enabled": false, 12 | "editor.smoothScrolling": true, 13 | "editor.tabSize": 2, 14 | "editor.useTabStops": true, 15 | "emmet.triggerExpansionOnTab": true, 16 | "explorer.openEditors.visible": 0, 17 | "files.autoSave": "afterDelay", 18 | "screencastMode.onlyKeyboardShortcuts": true, 19 | "terminal.integrated.fontSize": 18, 20 | "workbench.colorTheme": "Visual Studio Dark", 21 | "workbench.fontAliasing": "antialiased", 22 | "workbench.statusBar.visible": true, 23 | "liveServer.settings.root": "/docs", 24 | "prettier.enable": true, 25 | "eslint.alwaysShowStatus": false, 26 | "liveServer.settings.donotVerifyTags": true 27 | } 28 | -------------------------------------------------------------------------------- /1-working-with-generics/1-1-generics/ElementHolder.ts: -------------------------------------------------------------------------------- 1 | import { Printer } from './Printer' 2 | 3 | export class ElementHolder implements Printer { 4 | private values: T[] = []; 5 | 6 | constructor(values: T[] = []) { 7 | this.values = values; 8 | } 9 | 10 | print(value: T): void { 11 | console.log(value); 12 | } 13 | 14 | printAll(): void { 15 | for (const value of this.values) { 16 | this.print(value); 17 | } 18 | } 19 | 20 | add(value: T): void { 21 | this.values.push(value); 22 | } 23 | 24 | remove(value: T): void { 25 | this.values = this.values.filter(v => v !== value); 26 | } 27 | } 28 | 29 | 30 | const holder = new ElementHolder(["hello", "world", "typescript"]); 31 | holder.printAll(); // This will print "hello", "world", "typescript" 32 | 33 | holder.add("new element"); 34 | holder.printAll(); // Now prints "hello", "world", "typescript", "new element" 35 | 36 | holder.remove("world"); 37 | holder.printAll(); // Now prints "hello", "typescript", "new element" 38 | -------------------------------------------------------------------------------- /1-working-with-generics/1-1-generics/KeyValuePair.ts: -------------------------------------------------------------------------------- 1 | class KeyValuePair { 2 | private key: K; 3 | private value: V; 4 | 5 | constructor(key: K, value: V) { 6 | this.key = key; 7 | this.value = value; 8 | } 9 | 10 | // accessors 11 | 12 | displayPair(): void { 13 | console.log(`Key: ${this.key} - Value: ${this.value}`); 14 | } 15 | } 16 | 17 | let pair = new KeyValuePair("url", "something.com"); 18 | pair.displayPair(); -------------------------------------------------------------------------------- /1-working-with-generics/1-1-generics/Pair.ts: -------------------------------------------------------------------------------- 1 | export interface Pair { 2 | key: K; 3 | value: V; 4 | } 5 | 6 | let configProp: Pair = { 7 | key: 'url', 8 | value: 'www.someurl.com' 9 | }; 10 | -------------------------------------------------------------------------------- /1-working-with-generics/1-1-generics/Printer.ts: -------------------------------------------------------------------------------- 1 | export interface Printer { 2 | print(value: T): void; 3 | } 4 | -------------------------------------------------------------------------------- /1-working-with-generics/1-1-generics/Queue.ts: -------------------------------------------------------------------------------- 1 | export class Queue { 2 | private storage: T[] = []; 3 | 4 | enqueue(item: T) { 5 | this.storage.push(item); 6 | } 7 | 8 | dequeue(): T | undefined { 9 | return this.storage.shift(); 10 | } 11 | 12 | // Returns the number of elements in the queue 13 | size(): number { 14 | return this.storage.length; 15 | } 16 | 17 | // Returns true if the queue is empty 18 | isEmpty(): boolean { 19 | return this.storage.length === 0; 20 | } 21 | 22 | // Returns the front element without removing it 23 | peek(): T | undefined { 24 | return this.storage[0]; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /1-working-with-generics/1-1-generics/Response.ts: -------------------------------------------------------------------------------- 1 | export interface Response { 2 | status: number; 3 | message: string; 4 | data: T; 5 | } 6 | 7 | function createResponse(status: number, message: string, data: T): Response { 8 | return { status, message, data }; 9 | } 10 | 11 | const stringResponse = createResponse(200, "OK", "This is a successful response"); 12 | console.log(stringResponse); 13 | 14 | const numbersResponse = createResponse(200, "OK", [1, 2, 3, 4]); 15 | console.log(numbersResponse); 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /1-working-with-generics/1-1-generics/exampleWithGenerics.ts: -------------------------------------------------------------------------------- 1 | function printSomething(arg: Type): Type { 2 | console.log(arg); 3 | return arg; 4 | } 5 | 6 | let someValue = printSomething("something"); 7 | // let someValue2 = printSomething(3); 8 | let someValue3 = printSomething("some other thing"); 9 | 10 | function printSomething2(arg1: T, arg2: U): V { 11 | // some body that logically results in a value of type V 12 | // This is a placeholder example. Real implementation depends on the specific logic needed. 13 | let result: any; 14 | 15 | // Logic that assigns a properly typed value to 'result' 16 | // ... 17 | 18 | return result as V; // Type assertion to V, should be avoided if possible without proper guarantees 19 | 20 | } 21 | 22 | 23 | function getFirst(arr: T[]): T { 24 | return arr[0]; 25 | } 26 | 27 | function mergeArrays(arr1: T[], arr2: T[]): T[] { 28 | return arr1.concat(arr2); 29 | } 30 | -------------------------------------------------------------------------------- /1-working-with-generics/1-1-generics/exampleWithoutGenerics.ts: -------------------------------------------------------------------------------- 1 | function printSomething3(arg: string): string { 2 | console.log(arg); 3 | return arg; 4 | } -------------------------------------------------------------------------------- /1-working-with-generics/1-1-generics/useQueue.ts: -------------------------------------------------------------------------------- 1 | import { Queue } from './Queue'; 2 | 3 | const queue = new Queue(); 4 | queue.enqueue("Hello"); 5 | queue.enqueue("World"); 6 | queue.enqueue("TypeScript"); 7 | 8 | console.log(queue.peek()); // Outputs: "Hello" 9 | console.log(queue.size()); // Outputs: 3 10 | console.log(queue.isEmpty()); // Outputs: false 11 | 12 | while (!queue.isEmpty()) { 13 | console.log(queue.dequeue()); 14 | } 15 | // Outputs: 16 | // Hello 17 | // World 18 | // TypeScript 19 | console.log(queue.isEmpty()); // Outputs: true 20 | -------------------------------------------------------------------------------- /1-working-with-generics/1-2-advanced-generic-patterns/AppConfig.ts: -------------------------------------------------------------------------------- 1 | export interface AppConfig { 2 | debug: boolean; 3 | logLevel: 'info' | 'warning' | 'error'; 4 | port: number; 5 | } 6 | -------------------------------------------------------------------------------- /1-working-with-generics/1-2-advanced-generic-patterns/CreateSomeClass.ts: -------------------------------------------------------------------------------- 1 | export class CreateSomeClass { 2 | create(type: { new(): T }): T { 3 | return new type(); 4 | } 5 | } -------------------------------------------------------------------------------- /1-working-with-generics/1-2-advanced-generic-patterns/Dog.ts: -------------------------------------------------------------------------------- 1 | export class Dog { 2 | name: string; 3 | 4 | constructor() { 5 | this.name = "Buddy"; 6 | } 7 | 8 | bark() { 9 | return "Woof!"; 10 | } 11 | } -------------------------------------------------------------------------------- /1-working-with-generics/1-2-advanced-generic-patterns/exampleConstraint.ts: -------------------------------------------------------------------------------- 1 | function logLength(item: T): void { 2 | console.log(item.length); 3 | } 4 | 5 | logLength("Hello TypeScript"); 6 | logLength([2]); 7 | 8 | 9 | 10 | function processSerializable string }>(item: T) { 11 | console.log(item.serialize()); 12 | } 13 | 14 | class User { 15 | constructor(public name: string, public age: number) {} 16 | 17 | serialize(): string { 18 | return JSON.stringify({name: this.name, age: this.age}); 19 | } 20 | } 21 | 22 | const user = new User("Dione", 35); 23 | processSerializable(user); -------------------------------------------------------------------------------- /1-working-with-generics/1-2-advanced-generic-patterns/exampleDefaultValue.ts: -------------------------------------------------------------------------------- 1 | class SomeList { 2 | private readonly list: T[] = [] 3 | 4 | add(t: T) { 5 | this.list.push(t) 6 | } 7 | } 8 | 9 | const stringList = new SomeList(); 10 | stringList.add("TS"); 11 | stringList.add("is cool"); 12 | -------------------------------------------------------------------------------- /1-working-with-generics/1-2-advanced-generic-patterns/examplePipe.ts: -------------------------------------------------------------------------------- 1 | function wrapInArray(item: T, multiple: boolean): T | T[] { 2 | return multiple ? [item] : item; 3 | } 4 | -------------------------------------------------------------------------------- /1-working-with-generics/1-2-advanced-generic-patterns/useAppConfig.ts: -------------------------------------------------------------------------------- 1 | import { AppConfig } from "./AppConfig"; 2 | 3 | function getConfigValue(config: Type, key: Key) { 4 | return config[key]; 5 | } 6 | 7 | // Example usage: 8 | const appConfig: AppConfig = { 9 | debug: true, 10 | logLevel: 'info', 11 | port: 3000 12 | }; 13 | 14 | const debugStatus = getConfigValue(appConfig, 'debug'); 15 | const appPort = getConfigValue(appConfig, 'port'); -------------------------------------------------------------------------------- /1-working-with-generics/1-2-advanced-generic-patterns/usingCreateSomeClass.ts: -------------------------------------------------------------------------------- 1 | import { CreateSomeClass } from "./CreateSomeClass"; 2 | import { Dog } from "./Dog"; 3 | 4 | const creator = new CreateSomeClass(); 5 | const myDog = creator.create(Dog); 6 | console.log(myDog.name); // Outputs: Buddy 7 | console.log(myDog.bark()); // Outputs: Woof! -------------------------------------------------------------------------------- /1-working-with-generics/1-3-design-patterns-generics/document-example/Document.ts: -------------------------------------------------------------------------------- 1 | export interface Document { 2 | name: string; 3 | postfix: string; 4 | content: string; 5 | printContent(): void; 6 | } 7 | -------------------------------------------------------------------------------- /1-working-with-generics/1-3-design-patterns-generics/document-example/DocumentFactory.ts: -------------------------------------------------------------------------------- 1 | import { Document } from "./Document"; 2 | import { WordDocument } from "./WordDocument"; 3 | import { ExcelDocument } from "./ExcelDocument"; 4 | 5 | export class DocumentFactory { 6 | createDocument(type: string): Document { 7 | if (type === "word") { 8 | return new WordDocument(); 9 | } else if (type === "excel") { 10 | return new ExcelDocument(); 11 | } else { 12 | throw new Error("Invalid document type"); 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /1-working-with-generics/1-3-design-patterns-generics/document-example/ExcelDocument.ts: -------------------------------------------------------------------------------- 1 | import { Document } from "./Document"; 2 | 3 | export class ExcelDocument implements Document { 4 | content: string; 5 | name = "Table document"; 6 | postfix = "xlsx"; 7 | printContent(): void { 8 | console.log(`Reading the Excel doc: ${this.content}`); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /1-working-with-generics/1-3-design-patterns-generics/document-example/WordDocument.ts: -------------------------------------------------------------------------------- 1 | import { Document } from "./Document"; 2 | 3 | export class WordDocument implements Document { 4 | content: string; 5 | name = "Text document"; 6 | postfix = "docx"; 7 | printContent(): void { 8 | console.log(`Reading the Word doc: ${this.content}`); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /1-working-with-generics/1-3-design-patterns-generics/document-example/usingDocumentFactory.ts: -------------------------------------------------------------------------------- 1 | import { DocumentFactory } from "./DocumentFactory"; 2 | const factory = new DocumentFactory(); 3 | 4 | const wordDoc = factory.createDocument("word"); 5 | wordDoc.content = "Hello, the bird is the word"; 6 | wordDoc.printContent(); 7 | 8 | const excelDoc = factory.createDocument("excel"); 9 | excelDoc.content = "Data1, Data2, Data3"; 10 | excelDoc.printContent(); 11 | 12 | try { 13 | const pdfDoc = factory.createDocument("pdf"); 14 | } catch(error) { 15 | console.log(error); 16 | } 17 | -------------------------------------------------------------------------------- /1-working-with-generics/1-3-design-patterns-generics/payment-example/CreditCardStrategy.ts: -------------------------------------------------------------------------------- 1 | import { PaymentStrategy } from './PaymentStrategy'; 2 | 3 | export class CreditCardStrategy implements PaymentStrategy { 4 | processPayment(amount: number): string { 5 | // Simulate credit card payment processing 6 | console.log(`Processing credit card payment for amount: $${amount}`); 7 | return `Credit card payment of $${amount} processed.`; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /1-working-with-generics/1-3-design-patterns-generics/payment-example/CryptoStrategy.ts: -------------------------------------------------------------------------------- 1 | import { PaymentStrategy } from './PaymentStrategy'; 2 | 3 | export class CryptoStrategy implements PaymentStrategy { 4 | processPayment(amount: number): string { 5 | // Simulate cryptocurrency payment processing 6 | console.log(`Processing cryptocurrency payment for amount: $${amount}`); 7 | return `Cryptocurrency payment of $${amount} processed.`; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /1-working-with-generics/1-3-design-patterns-generics/payment-example/PayPalStrategy.ts: -------------------------------------------------------------------------------- 1 | import { PaymentStrategy } from './PaymentStrategy'; 2 | 3 | export class PayPalStrategy implements PaymentStrategy { 4 | processPayment(amount: number): string { 5 | // Simulate PayPal payment processing 6 | console.log(`Processing PayPal payment for amount: $${amount}`); 7 | return `PayPal payment of $${amount} processed.`; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /1-working-with-generics/1-3-design-patterns-generics/payment-example/PaymentProcessor.ts: -------------------------------------------------------------------------------- 1 | import { PaymentStrategy } from './PaymentStrategy'; 2 | 3 | export class PaymentProcessor { 4 | private strategy: PaymentStrategy; 5 | 6 | constructor(strategy: PaymentStrategy) { 7 | this.strategy = strategy; 8 | } 9 | 10 | setStrategy(strategy: PaymentStrategy) { 11 | this.strategy = strategy; 12 | } 13 | 14 | processPayment(amount: number): string { 15 | return this.strategy.processPayment(amount); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /1-working-with-generics/1-3-design-patterns-generics/payment-example/PaymentStrategy.ts: -------------------------------------------------------------------------------- 1 | export interface PaymentStrategy { 2 | processPayment(amount: number): string; 3 | } 4 | -------------------------------------------------------------------------------- /1-working-with-generics/1-3-design-patterns-generics/payment-example/usePaymentStrategies.ts: -------------------------------------------------------------------------------- 1 | import { PaymentProcessor } from './PaymentProcessor'; 2 | import { CreditCardStrategy } from './CreditCardStrategy'; 3 | import { PayPalStrategy } from './PayPalStrategy'; 4 | import { CryptoStrategy } from './CryptoStrategy'; 5 | 6 | const amount = 150; 7 | const creditCard = new CreditCardStrategy(); 8 | const payPal = new PayPalStrategy(); 9 | const crypto = new CryptoStrategy(); 10 | 11 | const paymentProcessor = new PaymentProcessor(creditCard); 12 | console.log(paymentProcessor.processPayment(amount)); // Uses Credit Card strategy 13 | 14 | paymentProcessor.setStrategy(payPal); 15 | console.log(paymentProcessor.processPayment(amount)); // Switches to PayPal strategy 16 | 17 | paymentProcessor.setStrategy(crypto); 18 | console.log(paymentProcessor.processPayment(amount)); // Switches to Cryptocurrency strategy 19 | -------------------------------------------------------------------------------- /1-working-with-generics/challenge/solution.ts: -------------------------------------------------------------------------------- 1 | // Create a type-safe, generic sorting function for an array of objects 2 | // based on a property key of the object provided at runtime. 3 | 4 | // The function must maintain type safety for property keys. 5 | 6 | function sortArray(array: T[], key: K): T[] { 7 | return array.sort((a, b) => (a[key] < b[key] ? -1 : 1)); 8 | } 9 | 10 | 11 | // Test your sorting function with the following array 12 | let tasks = [{ id: 2, title: "Write Code" }, { id: 1, title: "Compile" }]; 13 | let sortedTasks = sortArray(tasks, "id"); 14 | console.log(sortedTasks); 15 | -------------------------------------------------------------------------------- /2-advanced-types/2-1-utility-types/OptionalProps.ts: -------------------------------------------------------------------------------- 1 | interface OptionalProps { 2 | name?: string; 3 | age?: number; 4 | } 5 | 6 | function configureSettings(settings: Required) { 7 | console.log(`Name: ${settings.name}, Age: ${settings.age}`); 8 | } 9 | 10 | configureSettings({ name: "Gaia", age: 9 }); -------------------------------------------------------------------------------- /2-advanced-types/2-1-utility-types/Task.ts: -------------------------------------------------------------------------------- 1 | export interface Task { 2 | title: string; 3 | description: string; 4 | completed: boolean; 5 | } 6 | 7 | function updateTask(task: Task, fieldsToUpdate: Partial): Task { 8 | return { ...task, ...fieldsToUpdate }; 9 | } 10 | 11 | const task: Task = { 12 | title: "Learn TypeScript", 13 | description: "Understand utility types", 14 | completed: false, 15 | }; 16 | 17 | const updatedTask = updateTask(task, { completed: true }); 18 | -------------------------------------------------------------------------------- /2-advanced-types/2-1-utility-types/Todo.ts: -------------------------------------------------------------------------------- 1 | interface Todo { 2 | title: string; 3 | description: string; 4 | completed: boolean; 5 | } 6 | 7 | type TodoPreview = Pick; 8 | 9 | const todoPreview: TodoPreview = { 10 | title: "Finish article", 11 | completed: false 12 | }; 13 | 14 | 15 | -------------------------------------------------------------------------------- /2-advanced-types/2-1-utility-types/User.ts: -------------------------------------------------------------------------------- 1 | interface User { 2 | readonly id: number; 3 | name: string; 4 | } 5 | 6 | const user: Readonly = { 7 | id: 1, 8 | name: "Malika Z", 9 | }; 10 | 11 | // Error: Cannot assign to 'name' because it is a read-only property. 12 | // user.name = "Marya A"; 13 | -------------------------------------------------------------------------------- /2-advanced-types/2-1-utility-types/exampleOmit.ts: -------------------------------------------------------------------------------- 1 | type TodoInfo = Omit; 2 | 3 | const todoInfo: TodoInfo = { 4 | title: "Write blog post", 5 | description: "Write about TypeScript utility types", 6 | }; 7 | -------------------------------------------------------------------------------- /2-advanced-types/2-1-utility-types/exampleRecord.ts: -------------------------------------------------------------------------------- 1 | type Status = "active" | "inactive" | "pending"; 2 | 3 | const userStatus: Record = { 4 | 1: "active", 5 | 2: "inactive", 6 | 3: "pending", 7 | }; 8 | 9 | console.log(userStatus[1]); // Output: "active" 10 | -------------------------------------------------------------------------------- /2-advanced-types/2-1-utility-types/otherExamples.ts: -------------------------------------------------------------------------------- 1 | type AvailableDrinks = "Coffee" | "Tea" | "Water" | "Soda"; 2 | type NonCaffeinated = Exclude; 3 | 4 | type SomeDrinks = Extract; 5 | 6 | type MaybeString = string | null | undefined; 7 | type JustString = NonNullable; // string 8 | 9 | function getString() { 10 | return "hello"; 11 | } 12 | 13 | type MyString = ReturnType; // string 14 | 15 | class MyClass { 16 | x: number; 17 | y: number; 18 | 19 | constructor(x: number, y: number) { 20 | this.x = x; 21 | this.y = y; 22 | } 23 | } 24 | 25 | type ConstructorParams = ConstructorParameters; 26 | 27 | type MyInstance = InstanceType; // MyClass 28 | 29 | function greet(name: string, age: number) { 30 | console.log(`Hello ${name}, you are ${age} years old.`); 31 | } 32 | 33 | type Params = Parameters; // [string, number] 34 | 35 | function fn(this: string, age: number) { 36 | console.log(this.toUpperCase()); 37 | } 38 | 39 | type ThisParamsType = ThisParameterType; // string 40 | 41 | const fnWithoutThis: OmitThisParameter = fn.bind("Hello"); -------------------------------------------------------------------------------- /2-advanced-types/2-2-mapped-types/Person.ts: -------------------------------------------------------------------------------- 1 | export type Person = { 2 | name: string; 3 | age: number; 4 | } 5 | -------------------------------------------------------------------------------- /2-advanced-types/2-2-mapped-types/filterProperties.ts: -------------------------------------------------------------------------------- 1 | import { Person } from './Person'; 2 | 3 | type StringProperties = { 4 | [Property in keyof T as T[Property] extends string ? Property : never]: T[Property]; 5 | } 6 | 7 | type PersonStringProperties = StringProperties; 8 | // Result: { name: string } 9 | -------------------------------------------------------------------------------- /2-advanced-types/2-2-mapped-types/nullablePerson.ts: -------------------------------------------------------------------------------- 1 | import { Person } from './Person'; 2 | 3 | type NullablePerson = { 4 | [Property in keyof Person]: Person[Property] | null; 5 | } 6 | 7 | 8 | const nullablePerson: NullablePerson = { 9 | name: "Sean", 10 | age: null // 'age' can now be null 11 | }; 12 | -------------------------------------------------------------------------------- /2-advanced-types/2-2-mapped-types/optionalPerson.ts: -------------------------------------------------------------------------------- 1 | import { Person } from './Person'; 2 | 3 | type OptionalPerson = { 4 | [Property in keyof Person]?: Person[Property]; 5 | } 6 | 7 | const person: OptionalPerson = { 8 | name: "Maryam", // 'age' is now optional thanks to the mapped type 9 | }; 10 | 11 | -------------------------------------------------------------------------------- /2-advanced-types/2-2-mapped-types/readOnlyPerson.ts: -------------------------------------------------------------------------------- 1 | import { Person } from './Person'; 2 | 3 | type ReadonlyPerson = { 4 | readonly [Property in keyof Person]: Person[Property]; 5 | }; 6 | 7 | const readPerson: ReadonlyPerson = { 8 | name: "Adnane", 9 | age: 38 10 | }; 11 | 12 | // readPerson.name = "Another name"; // Read only, so not allowed -------------------------------------------------------------------------------- /2-advanced-types/2-2-mapped-types/stringifiedPerson.ts: -------------------------------------------------------------------------------- 1 | import { Person } from './Person'; 2 | 3 | type StringifiedPerson = { 4 | [Property in keyof Person]: string; 5 | } 6 | 7 | const stringPerson: StringifiedPerson = { 8 | name: "Pradeepa", 9 | age: "30" // Note: 'age' is now a string 10 | }; 11 | -------------------------------------------------------------------------------- /2-advanced-types/2-3-conditional-types/exampleApiResponse.ts: -------------------------------------------------------------------------------- 1 | interface User { 2 | username: string; 3 | email: string; 4 | } 5 | 6 | interface ApiError { 7 | errorCode: number; 8 | errorMessage: string; 9 | } 10 | 11 | 12 | type ApiResponse = 13 | Status extends 'success' ? User : ApiError; 14 | 15 | function fetchUserData(status: Status): ApiResponse { 16 | if (status === 'success') { 17 | // Simulating a successful API response 18 | return { 19 | id: 1, 20 | username: 'johndoe', 21 | email: 'john.doe@example.com' 22 | } as ApiResponse; 23 | } else { 24 | // Simulating an error response from the API 25 | return { 26 | errorCode: 404, 27 | errorMessage: 'User not found' 28 | } as ApiResponse; 29 | } 30 | } 31 | 32 | const successResponse = fetchUserData('success'); // User 33 | console.log(successResponse.email); // Accessible because successResponse is inferred as User 34 | 35 | const errorResponse = fetchUserData('error'); // ApiError 36 | console.log(errorResponse.errorMessage); // Accessible because errorResponse is inferred as ApiError 37 | -------------------------------------------------------------------------------- /2-advanced-types/2-3-conditional-types/examplesConditionalTypes.ts: -------------------------------------------------------------------------------- 1 | // Define a conditional type that checks if a type is assignable to string 2 | type CheckString = T extends string ? "String" : "Not a string"; 3 | 4 | // Usage of CheckString 5 | type TypeA = CheckString; // "String" 6 | type TypeB = CheckString; // "Not a string" 7 | 8 | 9 | type ValidTypes = string | number | boolean; 10 | type StringOrNumber = T extends ValidTypes ? T : never; 11 | 12 | type FilteredType = StringOrNumber; // string | boolean 13 | 14 | 15 | type NestedConditional = T extends number 16 | ? "Number" 17 | : T extends string 18 | ? "String" 19 | : "Other"; 20 | 21 | type Test1 = NestedConditional; // "String" 22 | type Test2 = NestedConditional; // "Other" 23 | -------------------------------------------------------------------------------- /2-advanced-types/2-3-conditional-types/practicalExample.ts: -------------------------------------------------------------------------------- 1 | type InputType = "text" | "number"; 2 | type Reply = Type extends "text" ? string[] : number[]; 3 | 4 | function processInput(type: Type, input: Reply) { 5 | console.log(`Processing ${type} input: `, input); 6 | } 7 | 8 | processInput("text", ["Hello", "World"]); // Correctly typed as string[] 9 | processInput("number", [1, 2, 3]); // Correctly typed as number[] 10 | -------------------------------------------------------------------------------- /2-advanced-types/2-4-template-literal-types/EventConfig.ts: -------------------------------------------------------------------------------- 1 | type EventType = `${T}Changed`; 2 | type SpecificEvent = EventType<"user">; // "userChanged" (slide) 3 | 4 | interface EventConfig { 5 | [key: string]: string; 6 | } 7 | 8 | function handleEvent(event: EventType, handler: (e: EventConfig) => void) { 9 | // Event handling logic... 10 | } 11 | 12 | handleEvent("userChanged", (config) => { 13 | console.log(`Handling user changed event with data: ${config.detail}`); 14 | }); 15 | 16 | 17 | -------------------------------------------------------------------------------- /2-advanced-types/2-4-template-literal-types/templateLiteralTypes.ts: -------------------------------------------------------------------------------- 1 | type World = "world"; 2 | type Greeting = `Hello, ${World}`; // "Hello, world" 3 | 4 | type Result = "success" | "error"; 5 | type Message = `${StatusType}_message`; 6 | 7 | type SuccessMessage = Message<"success">; // "success_message" 8 | type ErrorMessage = Message<"error">; // "error_message" 9 | -------------------------------------------------------------------------------- /2-advanced-types/challenge/solution.ts: -------------------------------------------------------------------------------- 1 | type UserType = 'admin' | 'guest' | 'member'; 2 | 3 | interface GenericUser { 4 | id: number; 5 | username: string; 6 | permissions?: T extends 'admin' ? string[] : never; 7 | expirationDate?: T extends 'guest' ? Date : never; 8 | memberSince?: T extends 'member' ? Date : never; 9 | } 10 | 11 | function updateUser(user: GenericUser) { 12 | console.log(`Updating user ${user.username}`); 13 | if (user.permissions && 'permissions' in user) { 14 | console.log('Permissions:', user.permissions.join(', ')); 15 | } 16 | if (user.expirationDate && 'expirationDate' in user) { 17 | console.log('Expires:', user.expirationDate.toISOString()); 18 | } 19 | if (user.memberSince && 'memberSince' in user) { 20 | console.log('Member Since:', user.memberSince.toISOString()); 21 | } 22 | // Simulate updating user in the database 23 | } 24 | 25 | // Usage of the function with conditional types 26 | const admin: GenericUser<'admin'> = { 27 | id: 1, 28 | username: "adminUser", 29 | permissions: ["manage_system", "modify_users"] 30 | }; 31 | 32 | const guest: GenericUser<'guest'> = { 33 | id: 2, 34 | username: "guestUser", 35 | expirationDate: new Date() 36 | }; 37 | 38 | const member: GenericUser<'member'> = { 39 | id: 3, 40 | username: "memberUser", 41 | memberSince: new Date() 42 | }; 43 | 44 | updateUser(admin); 45 | updateUser(guest); 46 | updateUser(member); 47 | -------------------------------------------------------------------------------- /3-mastering-function-overloading/3-1-function-overloading/formatDate.ts: -------------------------------------------------------------------------------- 1 | function formatDate(date: Date): string; 2 | function formatDate(isoString: string): string; 3 | function formatDate(input: Date | string): string { 4 | if (input instanceof Date) { 5 | return input.toLocaleDateString(); 6 | } else { 7 | const date = new Date(input); 8 | return date.toLocaleDateString(); 9 | } 10 | } 11 | 12 | // Usage 13 | console.log(formatDate(new Date())); // Outputs current date in local format 14 | console.log(formatDate("2024-01-01T14:20:00Z")); // Outputs "1/1/2024" 15 | -------------------------------------------------------------------------------- /3-mastering-function-overloading/3-1-function-overloading/greet.ts: -------------------------------------------------------------------------------- 1 | function greet(name: string): string; 2 | function greet(age: number): string; 3 | function greet(value: string | number): string { 4 | if (typeof value === "string") { 5 | return `Hello, ${value}!`; 6 | } else { 7 | return `You are ${value} years old.`; 8 | } 9 | } 10 | 11 | // Usage 12 | console.log(greet("Kareema")); // Output: "Hello, Kareema!" 13 | console.log(greet(32)); // Output: "You are 22 years old." 14 | -------------------------------------------------------------------------------- /3-mastering-function-overloading/3-2-practical-use-case/log.ts: -------------------------------------------------------------------------------- 1 | function log(message: string): void; 2 | function log(error: Error): void; 3 | function log(message: string, error: Error): void; 4 | function log(param1: string | Error, param2?: Error): void { 5 | if (typeof param1 === 'string' && param2 instanceof Error) { 6 | console.error(`Error: ${param1}`, param2); 7 | } else if (param1 instanceof Error) { 8 | console.error(param1); 9 | } else { 10 | console.log(param1); 11 | } 12 | } 13 | 14 | // Usage 15 | log("User login successful."); 16 | log(new Error("Failed to connect to database.")); 17 | log("User request failed.", new Error("Session timeout")); -------------------------------------------------------------------------------- /3-mastering-function-overloading/3-2-practical-use-case/userExample.ts: -------------------------------------------------------------------------------- 1 | interface User { 2 | id: number; 3 | username: string; 4 | email: string; 5 | } 6 | 7 | function getUser(id: number): User; 8 | function getUser(username: string): User[]; 9 | function getUser(id: number, username: string): User; 10 | function getUser(param1: number | string, param2?: string): User | User[] { 11 | if (typeof param1 === 'number' && param2) { 12 | // Fetch user by ID and username 13 | console.log(`Fetching user by ID: ${param1} and username: ${param2}`); 14 | return { id: param1, username: param2, email: "example@email.com" }; // Simulated data 15 | } else if (typeof param1 === 'number') { 16 | // Fetch user by ID 17 | console.log(`Fetching user by ID: ${param1}`); 18 | return { id: param1, username: "user123", email: "user@example.com" }; // Simulated data 19 | } else { 20 | // Fetch users by username 21 | console.log(`Fetching users by username: ${param1}`); 22 | return [{ id: 1, username: param1, email: "user@example.com" }]; // Simulated data 23 | } 24 | } 25 | 26 | // Usage 27 | console.log(getUser(10)); 28 | console.log(getUser("john_doe")); 29 | console.log(getUser(10, "john_doe")); -------------------------------------------------------------------------------- /3-mastering-function-overloading/challenge/solution.ts: -------------------------------------------------------------------------------- 1 | // Overloaded function signatures 2 | function sendMessage(content: string): void; // Text message 3 | function sendMessage(content: { html: string }): void; // HTML message 4 | 5 | // Unified function implementation 6 | function sendMessage(content: string | { html: string }): void { 7 | if (typeof content === "string") { 8 | console.log("Sending text message:", content); 9 | } else { 10 | console.log("Sending HTML message:", content.html); 11 | } 12 | } 13 | 14 | // Usage examples 15 | sendMessage("Hello, world!"); // Should log: Sending text message: Hello, world! 16 | sendMessage({ html: "

Hello, world!

" }); // Should log: Sending HTML message:

Hello, world!

17 | -------------------------------------------------------------------------------- /4-sophisticated-type-manipulation/4-1-type-guards/discriminatedUnions.ts: -------------------------------------------------------------------------------- 1 | interface Circle { 2 | kind: "circle"; 3 | radius: number; 4 | } 5 | 6 | interface Square { 7 | kind: "square"; 8 | sideLength: number; 9 | } 10 | 11 | type Shape = Circle | Square; 12 | 13 | function getArea(shape: Shape) { 14 | switch (shape.kind) { 15 | case "circle": 16 | return Math.PI * shape.radius ** 2; 17 | case "square": 18 | return shape.sideLength ** 2; 19 | } 20 | } 21 | 22 | // Usage 23 | const circle: Circle = { kind: "circle", radius: 10 }; 24 | const square: Square = { kind: "square", sideLength: 10 }; 25 | 26 | console.log(getArea(circle)); // Outputs: 314.1592653589793 27 | console.log(getArea(square)); // Outputs: 100 28 | -------------------------------------------------------------------------------- /4-sophisticated-type-manipulation/4-1-type-guards/simpleTypeGuard.ts: -------------------------------------------------------------------------------- 1 | function isString(test: any): test is string { 2 | return typeof test === "string"; 3 | } 4 | 5 | function example(input: string | number) { 6 | if (isString(input)) { 7 | console.log("It's a string!", input.toUpperCase()); // Safe to call toUpperCase 8 | } else { 9 | console.log("It's a number!", input.toFixed(2)); // Safe to call toFixed 10 | } 11 | } 12 | 13 | // Usage 14 | example("Hello, TypeScript!"); 15 | example(42); 16 | -------------------------------------------------------------------------------- /4-sophisticated-type-manipulation/4-2-using-type-assertion/exampleJsonString.ts: -------------------------------------------------------------------------------- 1 | let jsonString: string = '{"name": "John", "age": 30}'; 2 | 3 | // We know the structure of JSON, assert the type 4 | let userInfo: { name: string; age: number } = JSON.parse(jsonString) as { name: string; age: number }; 5 | 6 | console.log(userInfo.name); // Outputs: John 7 | console.log(userInfo.age); // Outputs: 30 8 | -------------------------------------------------------------------------------- /4-sophisticated-type-manipulation/4-2-using-type-assertion/usingTypeAssertion.ts: -------------------------------------------------------------------------------- 1 | let someValue: any = "this is a string"; 2 | 3 | let strLength: number = (someValue as string).length; 4 | 5 | console.log(strLength); // Outputs the length of "someValue" 6 | 7 | let someValue2: any = "this is another string"; 8 | 9 | let strLength2: number = (someValue).length; 10 | 11 | console.log(strLength2); // Outputs the length of "someValue" 12 | -------------------------------------------------------------------------------- /4-sophisticated-type-manipulation/4-3-the-unknown-explained/unknownExample.ts: -------------------------------------------------------------------------------- 1 | let notSure: unknown = 4; 2 | notSure = "maybe a string instead"; 3 | notSure = false; // still OK, type is unknown 4 | 5 | // Compile-time error: Object is of type 'unknown' 6 | // console.log(notSure.length); 7 | 8 | // Using a type assertion 9 | if (typeof notSure === "string") { 10 | console.log(notSure.length); // Now it's safe to access 'length' 11 | } 12 | -------------------------------------------------------------------------------- /4-sophisticated-type-manipulation/4-3-the-unknown-explained/unknownUseCase.ts: -------------------------------------------------------------------------------- 1 | async function fetchData(url: string): Promise { 2 | const response = await fetch(url); 3 | const data: unknown = await response.json(); 4 | return data; 5 | } 6 | 7 | async function handleData() { 8 | const data = await fetchData("https://api.example.com/data"); 9 | 10 | // Type checking 11 | if (Array.isArray(data)) { 12 | console.log("Data is an array", data); 13 | } else if (typeof data === "object" && data !== null) { 14 | console.log("Data is an object", data); 15 | } 16 | } 17 | 18 | handleData(); 19 | -------------------------------------------------------------------------------- /4-sophisticated-type-manipulation/challenge/solution.ts: -------------------------------------------------------------------------------- 1 | 2 | function processData(data: unknown): void { 3 | if (typeof data === 'string') { 4 | console.log("String data:", data); 5 | } else if (typeof data === 'number') { 6 | console.log("Number data:", data); 7 | } else if (Array.isArray(data)) { 8 | console.log("Array data with length " + data.length + ":", data); 9 | } else if (typeof data === 'object' && data !== null) { 10 | console.log("Object data:", data); 11 | } else if (data === null) { 12 | console.log("Null data"); 13 | } else { 14 | console.log("Unhandled type of data:", data); 15 | } 16 | } 17 | 18 | // Example usage 19 | processData("Hello, TypeScript!"); 20 | processData(12345); 21 | processData([1, 2, 3, 4, 5]); 22 | processData({ name: "Alice", age: 30 }); 23 | processData(null); 24 | processData(undefined); 25 | -------------------------------------------------------------------------------- /5-advanced-modularization-techniques/5-1-namespaces-vs-modules/modules/invoice.ts: -------------------------------------------------------------------------------- 1 | export class Invoice { 2 | constructor(public amount: number) { } 3 | } 4 | -------------------------------------------------------------------------------- /5-advanced-modularization-techniques/5-1-namespaces-vs-modules/modules/main.ts: -------------------------------------------------------------------------------- 1 | import { Invoice } from './invoice'; 2 | 3 | export function calculateTotal(invoices: Invoice[]) { 4 | return invoices.reduce((total, invoice) => total + invoice.amount, 0); 5 | } 6 | 7 | let invoices = [new Invoice(100), new Invoice(200)]; 8 | console.log(calculateTotal(invoices)); // Outputs: 300 9 | -------------------------------------------------------------------------------- /5-advanced-modularization-techniques/5-1-namespaces-vs-modules/namespaces/data.ts: -------------------------------------------------------------------------------- 1 | namespace Data { 2 | export class User { 3 | constructor(public username: string) { } 4 | } 5 | 6 | // This will cause a compile-time error 7 | // export class User { // Duplicate class name 8 | // constructor(public email: string) { } 9 | // } 10 | } 11 | -------------------------------------------------------------------------------- /5-advanced-modularization-techniques/5-1-namespaces-vs-modules/namespaces/payment.ts: -------------------------------------------------------------------------------- 1 | namespace Payment { 2 | export class Invoice { 3 | constructor(public amount: number) { } 4 | } 5 | 6 | export function calculateTotal(invoices: Invoice[]) { 7 | return invoices.reduce((total, invoice) => total + invoice.amount, 0); 8 | } 9 | } 10 | 11 | // Usage 12 | let invoices = [new Payment.Invoice(100), new Payment.Invoice(200)]; 13 | console.log(Payment.calculateTotal(invoices)); // Outputs: 300 14 | -------------------------------------------------------------------------------- /5-advanced-modularization-techniques/5-1-namespaces-vs-modules/namespaces/validation.ts: -------------------------------------------------------------------------------- 1 | namespace Validation { 2 | export interface StringValidator { 3 | isValid(s: string): boolean; 4 | } 5 | 6 | export interface StringValidator { // This merges with the above interface 7 | isAcceptable(s: string): boolean; 8 | } 9 | 10 | export function parse(value: string): string; 11 | export function parse(value: number): string; 12 | 13 | export function parse(value: string | number): string { // Implementation must unify all overloads 14 | if (typeof value === 'number') { 15 | return value.toString(); 16 | } else { 17 | return value; 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /5-advanced-modularization-techniques/5-2-dynamic-import-expressions/main.ts: -------------------------------------------------------------------------------- 1 | async function loadMathUtils() { 2 | const mathUtils = await import('./mathUtils'); 3 | console.log(mathUtils.add(10, 5)); // Outputs: 15 4 | } 5 | 6 | loadMathUtils(); 7 | -------------------------------------------------------------------------------- /5-advanced-modularization-techniques/5-2-dynamic-import-expressions/mathUtils.ts: -------------------------------------------------------------------------------- 1 | export function add(x: number, y: number): number { 2 | return x + y; 3 | } 4 | -------------------------------------------------------------------------------- /5-advanced-modularization-techniques/5-2-dynamic-import-expressions/practicalExample.ts: -------------------------------------------------------------------------------- 1 | let button = document.getElementById('button'); 2 | let condition = true; 3 | 4 | button?.addEventListener('click', async () => { 5 | if (condition) { 6 | const specialFeature = await import('./specialFeatureModule'); 7 | specialFeature.verySpecialFeature(); 8 | } 9 | }); 10 | 11 | 12 | -------------------------------------------------------------------------------- /5-advanced-modularization-techniques/5-2-dynamic-import-expressions/specialFeatureModule.ts: -------------------------------------------------------------------------------- 1 | export function verySpecialFeature() { 2 | return 'Very special feature'; 3 | } -------------------------------------------------------------------------------- /5-advanced-modularization-techniques/challenge/analytics.ts: -------------------------------------------------------------------------------- 1 | export class Analytics { 2 | static recordEvent(event: string) { 3 | console.log(`Event recorded: ${event}`); 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /5-advanced-modularization-techniques/challenge/main.ts: -------------------------------------------------------------------------------- 1 | // No imports necessary up here now 2 | 3 | type ModuleCache = { 4 | Analytics?: { Analytics: { recordEvent: (event: string) => void } }; 5 | UserManagement?: { UserManagement: { loadUserProfile: (userId: string) => void } }; 6 | }; 7 | 8 | const moduleCache: ModuleCache = {}; 9 | 10 | const recordBtn = document.getElementById('record-btn'); 11 | if (!recordBtn) { 12 | console.error("Element with ID 'record-btn' not found."); 13 | } else { 14 | recordBtn.addEventListener('click', async () => { 15 | try { 16 | if (!moduleCache.Analytics) { 17 | moduleCache.Analytics = await import('./analytics'); 18 | } 19 | moduleCache.Analytics.Analytics.recordEvent('Button Clicked'); 20 | } catch (error) { 21 | console.error("Failed to load the analytics module.", error); 22 | } 23 | }); 24 | } 25 | 26 | const loadProfileBtn = document.getElementById('load-profile-btn'); 27 | if (!loadProfileBtn) { 28 | console.error("Element with ID 'load-profile-btn' not found."); 29 | } else { 30 | loadProfileBtn.addEventListener('click', async () => { 31 | try { 32 | if (!moduleCache.UserManagement) { 33 | moduleCache.UserManagement = await import('./userManagement'); 34 | } 35 | moduleCache.UserManagement.UserManagement.loadUserProfile('user123'); 36 | } catch (error) { 37 | console.error("Failed to load the user management module.", error); 38 | } 39 | }); 40 | } 41 | -------------------------------------------------------------------------------- /5-advanced-modularization-techniques/challenge/userManagement.ts: -------------------------------------------------------------------------------- 1 | export class UserManagement { 2 | static loadUserProfile(userId: string) { 3 | console.log(`User profile loaded: ${userId}`); 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /6-decorators-and-metadata-reflection/6-1-understanding-decorators/logClassExample.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { 3 | var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; 4 | if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); 5 | else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; 6 | return c > 3 && r && Object.defineProperty(target, key, r), r; 7 | }; 8 | var __metadata = (this && this.__metadata) || function (k, v) { 9 | if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); 10 | }; 11 | function logClass(target) { 12 | console.log(`Class in use: ${target.name}`); 13 | } 14 | let User = class User { 15 | constructor(name, age) { 16 | this.name = name; 17 | this.age = age; 18 | } 19 | }; 20 | User = __decorate([ 21 | logClass, 22 | __metadata("design:paramtypes", [String, Number]) 23 | ], User); 24 | -------------------------------------------------------------------------------- /6-decorators-and-metadata-reflection/6-1-understanding-decorators/logClassExample.ts: -------------------------------------------------------------------------------- 1 | function logClass(target: Function) { 2 | console.log(`Class in use: ${target.name}`); 3 | } 4 | 5 | @logClass 6 | class User { 7 | constructor(public name: string, public age: number) { } 8 | } 9 | 10 | -------------------------------------------------------------------------------- /6-decorators-and-metadata-reflection/6-1-understanding-decorators/logMethodExample.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { 3 | var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; 4 | if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); 5 | else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; 6 | return c > 3 && r && Object.defineProperty(target, key, r), r; 7 | }; 8 | var __metadata = (this && this.__metadata) || function (k, v) { 9 | if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); 10 | }; 11 | function logMethod(target, key, descriptor) { 12 | const originalMethod = descriptor.value; 13 | descriptor.value = function (...args) { 14 | const start = performance.now(); 15 | const result = originalMethod.apply(this, args); 16 | const finish = performance.now(); 17 | console.log(`${key} executed in ${finish - start} milliseconds`); 18 | return result; 19 | }; 20 | return descriptor; 21 | } 22 | class MathOperations { 23 | add(x, y) { 24 | return x + y; 25 | } 26 | } 27 | __decorate([ 28 | logMethod, 29 | __metadata("design:type", Function), 30 | __metadata("design:paramtypes", [Number, Number]), 31 | __metadata("design:returntype", Number) 32 | ], MathOperations.prototype, "add", null); 33 | const math = new MathOperations(); 34 | math.add(5, 3); // Output: "add executed in X milliseconds" 35 | -------------------------------------------------------------------------------- /6-decorators-and-metadata-reflection/6-1-understanding-decorators/logMethodExample.ts: -------------------------------------------------------------------------------- 1 | function logMethod(target: any, key: string, descriptor: PropertyDescriptor) { 2 | const originalMethod = descriptor.value; 3 | descriptor.value = function (...args: any[]) { 4 | const start = performance.now(); 5 | const result = originalMethod.apply(this, args); 6 | const finish = performance.now(); 7 | console.log(`${key} executed in ${finish - start} milliseconds`); 8 | return result; 9 | }; 10 | return descriptor; 11 | } 12 | 13 | class MathOperations { 14 | //@logMethod 15 | add(x: number, y: number): number { 16 | return x + y; 17 | } 18 | } 19 | 20 | const math = new MathOperations(); 21 | math.add(5, 3); // Output: "add executed in X milliseconds" 22 | -------------------------------------------------------------------------------- /6-decorators-and-metadata-reflection/6-1-understanding-decorators/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Visit https://aka.ms/tsconfig to read more about this file */ 4 | 5 | /* Projects */ 6 | // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ 7 | // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ 8 | // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ 9 | // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ 10 | // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ 11 | // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ 12 | 13 | /* Language and Environment */ 14 | "target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ 15 | // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ 16 | // "jsx": "preserve", /* Specify what JSX code is generated. */ 17 | "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */ 18 | "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ 19 | // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ 20 | // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ 21 | // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ 22 | // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ 23 | // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ 24 | // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ 25 | // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ 26 | 27 | /* Modules */ 28 | "module": "commonjs", /* Specify what module code is generated. */ 29 | // "rootDir": "./", /* Specify the root folder within your source files. */ 30 | // "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */ 31 | // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ 32 | // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ 33 | // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ 34 | // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ 35 | // "types": [], /* Specify type package names to be included without being referenced in a source file. */ 36 | // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ 37 | // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ 38 | // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ 39 | // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ 40 | // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ 41 | // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ 42 | // "resolveJsonModule": true, /* Enable importing .json files. */ 43 | // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ 44 | // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ 45 | 46 | /* JavaScript Support */ 47 | // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ 48 | // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ 49 | // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ 50 | 51 | /* Emit */ 52 | // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ 53 | // "declarationMap": true, /* Create sourcemaps for d.ts files. */ 54 | // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ 55 | // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ 56 | // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ 57 | // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ 58 | // "outDir": "./", /* Specify an output folder for all emitted files. */ 59 | // "removeComments": true, /* Disable emitting comments. */ 60 | // "noEmit": true, /* Disable emitting files from a compilation. */ 61 | // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ 62 | // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */ 63 | // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ 64 | // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ 65 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ 66 | // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ 67 | // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ 68 | // "newLine": "crlf", /* Set the newline character for emitting files. */ 69 | // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ 70 | // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ 71 | // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ 72 | // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ 73 | // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ 74 | // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ 75 | 76 | /* Interop Constraints */ 77 | // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ 78 | // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */ 79 | // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ 80 | "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ 81 | // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ 82 | "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ 83 | 84 | /* Type Checking */ 85 | "strict": true, /* Enable all strict type-checking options. */ 86 | // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ 87 | // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ 88 | // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ 89 | // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ 90 | // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ 91 | // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ 92 | // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ 93 | // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ 94 | // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ 95 | // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ 96 | // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ 97 | // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ 98 | // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ 99 | // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ 100 | // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ 101 | // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ 102 | // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ 103 | // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ 104 | 105 | /* Completeness */ 106 | // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ 107 | "skipLibCheck": true /* Skip type checking all .d.ts files. */ 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /6-decorators-and-metadata-reflection/6-2-reflection-and-metadata/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinkedInLearning/advanced-typescript-concepts-5914414/761c50563fb48345d7e783124bf2709c88362a84/6-decorators-and-metadata-reflection/6-2-reflection-and-metadata/.gitkeep -------------------------------------------------------------------------------- /6-decorators-and-metadata-reflection/6-2-reflection-and-metadata/exampleReflectMetadata.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinkedInLearning/advanced-typescript-concepts-5914414/761c50563fb48345d7e783124bf2709c88362a84/6-decorators-and-metadata-reflection/6-2-reflection-and-metadata/exampleReflectMetadata.ts -------------------------------------------------------------------------------- /6-decorators-and-metadata-reflection/6-2-reflection-and-metadata/exampleRoleCheck.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinkedInLearning/advanced-typescript-concepts-5914414/761c50563fb48345d7e783124bf2709c88362a84/6-decorators-and-metadata-reflection/6-2-reflection-and-metadata/exampleRoleCheck.ts -------------------------------------------------------------------------------- /6-decorators-and-metadata-reflection/6-2-reflection-and-metadata/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "6-2-reflection-and-metadata", 3 | "lockfileVersion": 3, 4 | "requires": true, 5 | "packages": { 6 | "": { 7 | "dependencies": { 8 | "reflect-metadata": "^0.2.2" 9 | } 10 | }, 11 | "node_modules/reflect-metadata": { 12 | "version": "0.2.2", 13 | "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.2.tgz", 14 | "integrity": "sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==" 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /6-decorators-and-metadata-reflection/6-2-reflection-and-metadata/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "reflect-metadata": "^0.2.2" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /6-decorators-and-metadata-reflection/6-2-reflection-and-metadata/reflectiveExample.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { 3 | var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; 4 | if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); 5 | else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; 6 | return c > 3 && r && Object.defineProperty(target, key, r), r; 7 | }; 8 | var __metadata = (this && this.__metadata) || function (k, v) { 9 | if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); 10 | }; 11 | Object.defineProperty(exports, "__esModule", { value: true }); 12 | require("reflect-metadata"); 13 | function ReflectiveDecorator(target, propertyKey) { 14 | Reflect.defineMetadata("role", "user", target, propertyKey); 15 | } 16 | class User { 17 | constructor(name) { 18 | this.name = name; 19 | } 20 | greet() { 21 | console.log("Hello"); 22 | } 23 | } 24 | __decorate([ 25 | ReflectiveDecorator, 26 | __metadata("design:type", String) 27 | ], User.prototype, "name", void 0); 28 | __decorate([ 29 | ReflectiveDecorator, 30 | __metadata("design:type", Function), 31 | __metadata("design:paramtypes", []), 32 | __metadata("design:returntype", void 0) 33 | ], User.prototype, "greet", null); 34 | console.log(Reflect.getMetadata("role", User.prototype, "greet")); // Outputs: "admin" 35 | function RoleCheck(roleRequired) { 36 | return function (target, propertyKey, descriptor) { 37 | const originalMethod = descriptor.value; 38 | descriptor.value = function (...args) { 39 | if (Reflect.getMetadata("role", target, propertyKey) === roleRequired) { 40 | return originalMethod.apply(this, args); 41 | } 42 | else { 43 | console.error(`Access denied for method ${propertyKey}`); 44 | } 45 | }; 46 | }; 47 | } 48 | class SecureSystem { 49 | deleteUser() { 50 | console.log("User deleted"); 51 | } 52 | } 53 | __decorate([ 54 | ReflectiveDecorator, 55 | RoleCheck("admin"), 56 | __metadata("design:type", Function), 57 | __metadata("design:paramtypes", []), 58 | __metadata("design:returntype", void 0) 59 | ], SecureSystem.prototype, "deleteUser", null); 60 | const system = new SecureSystem(); 61 | system.deleteUser(); // Executes correctly if the role matches "admin" 62 | -------------------------------------------------------------------------------- /6-decorators-and-metadata-reflection/6-2-reflection-and-metadata/reflectiveExample.ts: -------------------------------------------------------------------------------- 1 | import "reflect-metadata"; 2 | 3 | function ReflectiveDecorator(target: any, propertyKey: string) { 4 | Reflect.defineMetadata("role", "user", target, propertyKey); 5 | } 6 | 7 | class User { 8 | @ReflectiveDecorator 9 | name: string; 10 | 11 | constructor(name: string) { 12 | this.name = name; 13 | } 14 | 15 | @ReflectiveDecorator 16 | greet() { 17 | console.log("Hello"); 18 | } 19 | } 20 | 21 | console.log(Reflect.getMetadata("role", User.prototype, "greet")); // Outputs: "admin" 22 | 23 | function RoleCheck(roleRequired: string) { 24 | return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) { 25 | const originalMethod = descriptor.value; 26 | descriptor.value = function (...args: any[]) { 27 | if (Reflect.getMetadata("role", target, propertyKey) === roleRequired) { 28 | return originalMethod.apply(this, args); 29 | } else { 30 | console.error(`Access denied for method ${propertyKey}`); 31 | } 32 | }; 33 | }; 34 | } 35 | 36 | class SecureSystem { 37 | @ReflectiveDecorator 38 | @RoleCheck("admin") 39 | deleteUser() { 40 | console.log("User deleted"); 41 | } 42 | } 43 | 44 | const system = new SecureSystem(); 45 | system.deleteUser(); // Executes correctly if the role matches "admin" 46 | 47 | -------------------------------------------------------------------------------- /6-decorators-and-metadata-reflection/6-2-reflection-and-metadata/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Visit https://aka.ms/tsconfig to read more about this file */ 4 | 5 | /* Projects */ 6 | // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ 7 | // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ 8 | // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ 9 | // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ 10 | // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ 11 | // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ 12 | 13 | /* Language and Environment */ 14 | "target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ 15 | // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ 16 | // "jsx": "preserve", /* Specify what JSX code is generated. */ 17 | "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */ 18 | "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ 19 | // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ 20 | // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ 21 | // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ 22 | // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ 23 | // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ 24 | // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ 25 | // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ 26 | 27 | /* Modules */ 28 | "module": "commonjs", /* Specify what module code is generated. */ 29 | // "rootDir": "./", /* Specify the root folder within your source files. */ 30 | // "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */ 31 | // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ 32 | // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ 33 | // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ 34 | // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ 35 | // "types": [], /* Specify type package names to be included without being referenced in a source file. */ 36 | // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ 37 | // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ 38 | // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ 39 | // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ 40 | // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ 41 | // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ 42 | // "resolveJsonModule": true, /* Enable importing .json files. */ 43 | // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ 44 | // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ 45 | 46 | /* JavaScript Support */ 47 | // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ 48 | // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ 49 | // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ 50 | 51 | /* Emit */ 52 | // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ 53 | // "declarationMap": true, /* Create sourcemaps for d.ts files. */ 54 | // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ 55 | // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ 56 | // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ 57 | // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ 58 | // "outDir": "./", /* Specify an output folder for all emitted files. */ 59 | // "removeComments": true, /* Disable emitting comments. */ 60 | // "noEmit": true, /* Disable emitting files from a compilation. */ 61 | // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ 62 | // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */ 63 | // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ 64 | // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ 65 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ 66 | // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ 67 | // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ 68 | // "newLine": "crlf", /* Set the newline character for emitting files. */ 69 | // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ 70 | // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ 71 | // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ 72 | // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ 73 | // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ 74 | // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ 75 | 76 | /* Interop Constraints */ 77 | // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ 78 | // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */ 79 | // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ 80 | "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ 81 | // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ 82 | "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ 83 | 84 | /* Type Checking */ 85 | "strict": true, /* Enable all strict type-checking options. */ 86 | // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ 87 | // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ 88 | // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ 89 | // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ 90 | // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ 91 | // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ 92 | // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ 93 | // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ 94 | // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ 95 | // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ 96 | // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ 97 | // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ 98 | // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ 99 | // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ 100 | // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ 101 | // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ 102 | // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ 103 | // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ 104 | 105 | /* Completeness */ 106 | // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ 107 | "skipLibCheck": true /* Skip type checking all .d.ts files. */ 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /6-decorators-and-metadata-reflection/challenge/decorators.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | exports.Role = exports.Authorize = exports.Log = void 0; 4 | require("reflect-metadata"); 5 | // LogDecorator 6 | function Log(target, propertyName, descriptor) { 7 | const method = descriptor.value; 8 | descriptor.value = function (...args) { 9 | console.log(`Calling ${propertyName}`); 10 | return method.apply(this, args); 11 | }; 12 | } 13 | exports.Log = Log; 14 | // AuthorizeDecorator 15 | function Authorize(roleRequired) { 16 | return function (target, propertyName, descriptor) { 17 | const method = descriptor.value; 18 | descriptor.value = function (...args) { 19 | const role = Reflect.getMetadata("role", target, propertyName); 20 | if (role !== roleRequired) { 21 | console.log(`Access denied for ${propertyName}`); 22 | return; 23 | } 24 | return method.apply(this, args); 25 | }; 26 | }; 27 | } 28 | exports.Authorize = Authorize; 29 | // RoleDecorator to set metadata 30 | function Role(role) { 31 | return function (target, propertyKey, descriptor) { 32 | Reflect.defineMetadata("role", role, target, propertyKey); 33 | }; 34 | } 35 | exports.Role = Role; 36 | -------------------------------------------------------------------------------- /6-decorators-and-metadata-reflection/challenge/decorators.ts: -------------------------------------------------------------------------------- 1 | import "reflect-metadata"; 2 | 3 | // LogDecorator 4 | export function Log(target: any, propertyName: string, descriptor: PropertyDescriptor) { 5 | const method = descriptor.value; 6 | descriptor.value = function (...args: any[]) { 7 | console.log(`Calling ${propertyName}`); 8 | return method.apply(this, args); 9 | } 10 | } 11 | 12 | // AuthorizeDecorator 13 | export function Authorize(roleRequired: string) { 14 | return function (target: any, propertyName: string, descriptor: PropertyDescriptor) { 15 | const method = descriptor.value; 16 | descriptor.value = function (...args: any[]) { 17 | const role = Reflect.getMetadata("role", target, propertyName); 18 | if (role !== roleRequired) { 19 | console.log(`Access denied for ${propertyName}`); 20 | return; 21 | } 22 | return method.apply(this, args); 23 | } 24 | } 25 | } 26 | 27 | // RoleDecorator to set metadata 28 | export function Role(role: string) { 29 | return function (target: any, propertyKey: string, descriptor?: PropertyDescriptor) { 30 | Reflect.defineMetadata("role", role, target, propertyKey); 31 | }; 32 | } 33 | -------------------------------------------------------------------------------- /6-decorators-and-metadata-reflection/challenge/main.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __importDefault = (this && this.__importDefault) || function (mod) { 3 | return (mod && mod.__esModule) ? mod : { "default": mod }; 4 | }; 5 | Object.defineProperty(exports, "__esModule", { value: true }); 6 | require("reflect-metadata"); 7 | const productManagement_1 = __importDefault(require("./productManagement")); 8 | const pm = new productManagement_1.default(); 9 | pm.createProduct("Laptop", 1200); // Should log and then execute if authorized 10 | pm.deleteProduct("Laptop"); // Should just log the call 11 | -------------------------------------------------------------------------------- /6-decorators-and-metadata-reflection/challenge/main.ts: -------------------------------------------------------------------------------- 1 | import "reflect-metadata"; 2 | import ProductManagement from './productManagement'; 3 | 4 | const pm = new ProductManagement(); 5 | pm.createProduct("Laptop", 1200); // Should log and then execute if authorized 6 | pm.deleteProduct("Laptop"); // Should just log the call 7 | -------------------------------------------------------------------------------- /6-decorators-and-metadata-reflection/challenge/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "challenge", 3 | "lockfileVersion": 3, 4 | "requires": true, 5 | "packages": { 6 | "": { 7 | "dependencies": { 8 | "reflect-metadata": "^0.2.2" 9 | } 10 | }, 11 | "node_modules/reflect-metadata": { 12 | "version": "0.2.2", 13 | "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.2.tgz", 14 | "integrity": "sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==" 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /6-decorators-and-metadata-reflection/challenge/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "reflect-metadata": "^0.2.2" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /6-decorators-and-metadata-reflection/challenge/productManagement.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { 3 | var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; 4 | if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); 5 | else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; 6 | return c > 3 && r && Object.defineProperty(target, key, r), r; 7 | }; 8 | var __metadata = (this && this.__metadata) || function (k, v) { 9 | if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); 10 | }; 11 | Object.defineProperty(exports, "__esModule", { value: true }); 12 | const decorators_1 = require("./decorators"); 13 | class ProductManagement { 14 | createProduct(name, price) { 15 | console.log(`Product created: ${name}, Price: ${price}`); 16 | } 17 | deleteProduct(name) { 18 | console.log(`Product deleted: ${name}`); 19 | } 20 | } 21 | __decorate([ 22 | decorators_1.Log, 23 | (0, decorators_1.Role)("user"), 24 | (0, decorators_1.Authorize)("admin"), 25 | __metadata("design:type", Function), 26 | __metadata("design:paramtypes", [String, Number]), 27 | __metadata("design:returntype", void 0) 28 | ], ProductManagement.prototype, "createProduct", null); 29 | __decorate([ 30 | decorators_1.Log, 31 | __metadata("design:type", Function), 32 | __metadata("design:paramtypes", [String]), 33 | __metadata("design:returntype", void 0) 34 | ], ProductManagement.prototype, "deleteProduct", null); 35 | exports.default = ProductManagement; 36 | -------------------------------------------------------------------------------- /6-decorators-and-metadata-reflection/challenge/productManagement.ts: -------------------------------------------------------------------------------- 1 | import { Log, Authorize, Role } from './decorators'; 2 | 3 | class ProductManagement { 4 | @Log 5 | @Role("user") 6 | @Authorize("admin") 7 | createProduct(name: string, price: number) { 8 | console.log(`Product created: ${name}, Price: ${price}`); 9 | } 10 | 11 | @Log 12 | deleteProduct(name: string) { 13 | console.log(`Product deleted: ${name}`); 14 | } 15 | } 16 | 17 | export default ProductManagement; 18 | -------------------------------------------------------------------------------- /6-decorators-and-metadata-reflection/challenge/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Visit https://aka.ms/tsconfig to read more about this file */ 4 | 5 | /* Projects */ 6 | // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ 7 | // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ 8 | // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ 9 | // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ 10 | // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ 11 | // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ 12 | 13 | /* Language and Environment */ 14 | "target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ 15 | // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ 16 | // "jsx": "preserve", /* Specify what JSX code is generated. */ 17 | "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */ 18 | "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ 19 | // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ 20 | // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ 21 | // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ 22 | // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ 23 | // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ 24 | // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ 25 | // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ 26 | 27 | /* Modules */ 28 | "module": "commonjs", /* Specify what module code is generated. */ 29 | // "rootDir": "./", /* Specify the root folder within your source files. */ 30 | // "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */ 31 | // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ 32 | // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ 33 | // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ 34 | // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ 35 | // "types": [], /* Specify type package names to be included without being referenced in a source file. */ 36 | // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ 37 | // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ 38 | // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ 39 | // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ 40 | // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ 41 | // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ 42 | // "resolveJsonModule": true, /* Enable importing .json files. */ 43 | // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ 44 | // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ 45 | 46 | /* JavaScript Support */ 47 | // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ 48 | // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ 49 | // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ 50 | 51 | /* Emit */ 52 | // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ 53 | // "declarationMap": true, /* Create sourcemaps for d.ts files. */ 54 | // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ 55 | // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ 56 | // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ 57 | // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ 58 | // "outDir": "./", /* Specify an output folder for all emitted files. */ 59 | // "removeComments": true, /* Disable emitting comments. */ 60 | // "noEmit": true, /* Disable emitting files from a compilation. */ 61 | // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ 62 | // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */ 63 | // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ 64 | // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ 65 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ 66 | // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ 67 | // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ 68 | // "newLine": "crlf", /* Set the newline character for emitting files. */ 69 | // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ 70 | // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ 71 | // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ 72 | // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ 73 | // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ 74 | // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ 75 | 76 | /* Interop Constraints */ 77 | // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ 78 | // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */ 79 | // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ 80 | "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ 81 | // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ 82 | "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ 83 | 84 | /* Type Checking */ 85 | "strict": true, /* Enable all strict type-checking options. */ 86 | // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ 87 | // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ 88 | // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ 89 | // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ 90 | // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ 91 | // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ 92 | // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ 93 | // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ 94 | // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ 95 | // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ 96 | // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ 97 | // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ 98 | // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ 99 | // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ 100 | // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ 101 | // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ 102 | // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ 103 | // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ 104 | 105 | /* Completeness */ 106 | // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ 107 | "skipLibCheck": true /* Skip type checking all .d.ts files. */ 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /7-typescript-and-the-build-process/7-1-integrating-with-build-tool-webpack/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinkedInLearning/advanced-typescript-concepts-5914414/761c50563fb48345d7e783124bf2709c88362a84/7-typescript-and-the-build-process/7-1-integrating-with-build-tool-webpack/.gitkeep -------------------------------------------------------------------------------- /7-typescript-and-the-build-process/7-1-integrating-with-build-tool-webpack/my-ts-project/dist/bundle.js: -------------------------------------------------------------------------------- 1 | /* 2 | * ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development"). 3 | * This devtool is neither made for production nor for readable output files. 4 | * It uses "eval()" calls to create a separate source file in the browser devtools. 5 | * If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/) 6 | * or disable the default devtool with "devtool: false". 7 | * If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/). 8 | */ 9 | /******/ (() => { // webpackBootstrap 10 | /******/ var __webpack_modules__ = ({ 11 | 12 | /***/ "./src/index.ts": 13 | /*!**********************!*\ 14 | !*** ./src/index.ts ***! 15 | \**********************/ 16 | /***/ (() => { 17 | 18 | eval("function greet(name) {\n console.log(\"Hello, \".concat(name, \"!\"));\n}\ngreet('World');\n\n\n//# sourceURL=webpack://my-ts-project/./src/index.ts?"); 19 | 20 | /***/ }) 21 | 22 | /******/ }); 23 | /************************************************************************/ 24 | /******/ 25 | /******/ // startup 26 | /******/ // Load entry module and return exports 27 | /******/ // This entry module can't be inlined because the eval devtool is used. 28 | /******/ var __webpack_exports__ = {}; 29 | /******/ __webpack_modules__["./src/index.ts"](); 30 | /******/ 31 | /******/ })() 32 | ; -------------------------------------------------------------------------------- /7-typescript-and-the-build-process/7-1-integrating-with-build-tool-webpack/my-ts-project/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "my-ts-project", 3 | "version": "1.0.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "my-ts-project", 9 | "version": "1.0.0", 10 | "license": "ISC", 11 | "devDependencies": { 12 | "ts-loader": "^9.5.1", 13 | "typescript": "^5.4.5", 14 | "webpack": "^5.91.0", 15 | "webpack-cli": "^5.1.4" 16 | } 17 | }, 18 | "node_modules/@discoveryjs/json-ext": { 19 | "version": "0.5.7", 20 | "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", 21 | "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", 22 | "dev": true, 23 | "engines": { 24 | "node": ">=10.0.0" 25 | } 26 | }, 27 | "node_modules/@jridgewell/gen-mapping": { 28 | "version": "0.3.5", 29 | "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", 30 | "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", 31 | "dev": true, 32 | "dependencies": { 33 | "@jridgewell/set-array": "^1.2.1", 34 | "@jridgewell/sourcemap-codec": "^1.4.10", 35 | "@jridgewell/trace-mapping": "^0.3.24" 36 | }, 37 | "engines": { 38 | "node": ">=6.0.0" 39 | } 40 | }, 41 | "node_modules/@jridgewell/resolve-uri": { 42 | "version": "3.1.2", 43 | "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", 44 | "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", 45 | "dev": true, 46 | "engines": { 47 | "node": ">=6.0.0" 48 | } 49 | }, 50 | "node_modules/@jridgewell/set-array": { 51 | "version": "1.2.1", 52 | "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", 53 | "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", 54 | "dev": true, 55 | "engines": { 56 | "node": ">=6.0.0" 57 | } 58 | }, 59 | "node_modules/@jridgewell/source-map": { 60 | "version": "0.3.6", 61 | "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", 62 | "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", 63 | "dev": true, 64 | "dependencies": { 65 | "@jridgewell/gen-mapping": "^0.3.5", 66 | "@jridgewell/trace-mapping": "^0.3.25" 67 | } 68 | }, 69 | "node_modules/@jridgewell/sourcemap-codec": { 70 | "version": "1.4.15", 71 | "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", 72 | "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", 73 | "dev": true 74 | }, 75 | "node_modules/@jridgewell/trace-mapping": { 76 | "version": "0.3.25", 77 | "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", 78 | "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", 79 | "dev": true, 80 | "dependencies": { 81 | "@jridgewell/resolve-uri": "^3.1.0", 82 | "@jridgewell/sourcemap-codec": "^1.4.14" 83 | } 84 | }, 85 | "node_modules/@types/eslint": { 86 | "version": "8.56.10", 87 | "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.10.tgz", 88 | "integrity": "sha512-Shavhk87gCtY2fhXDctcfS3e6FdxWkCx1iUZ9eEUbh7rTqlZT0/IzOkCOVt0fCjcFuZ9FPYfuezTBImfHCDBGQ==", 89 | "dev": true, 90 | "dependencies": { 91 | "@types/estree": "*", 92 | "@types/json-schema": "*" 93 | } 94 | }, 95 | "node_modules/@types/eslint-scope": { 96 | "version": "3.7.7", 97 | "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", 98 | "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", 99 | "dev": true, 100 | "dependencies": { 101 | "@types/eslint": "*", 102 | "@types/estree": "*" 103 | } 104 | }, 105 | "node_modules/@types/estree": { 106 | "version": "1.0.5", 107 | "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", 108 | "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", 109 | "dev": true 110 | }, 111 | "node_modules/@types/json-schema": { 112 | "version": "7.0.15", 113 | "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", 114 | "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", 115 | "dev": true 116 | }, 117 | "node_modules/@types/node": { 118 | "version": "20.14.2", 119 | "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.2.tgz", 120 | "integrity": "sha512-xyu6WAMVwv6AKFLB+e/7ySZVr/0zLCzOa7rSpq6jNwpqOrUbcACDWC+53d4n2QHOnDou0fbIsg8wZu/sxrnI4Q==", 121 | "dev": true, 122 | "dependencies": { 123 | "undici-types": "~5.26.4" 124 | } 125 | }, 126 | "node_modules/@webassemblyjs/ast": { 127 | "version": "1.12.1", 128 | "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", 129 | "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==", 130 | "dev": true, 131 | "dependencies": { 132 | "@webassemblyjs/helper-numbers": "1.11.6", 133 | "@webassemblyjs/helper-wasm-bytecode": "1.11.6" 134 | } 135 | }, 136 | "node_modules/@webassemblyjs/floating-point-hex-parser": { 137 | "version": "1.11.6", 138 | "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", 139 | "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", 140 | "dev": true 141 | }, 142 | "node_modules/@webassemblyjs/helper-api-error": { 143 | "version": "1.11.6", 144 | "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", 145 | "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", 146 | "dev": true 147 | }, 148 | "node_modules/@webassemblyjs/helper-buffer": { 149 | "version": "1.12.1", 150 | "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz", 151 | "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==", 152 | "dev": true 153 | }, 154 | "node_modules/@webassemblyjs/helper-numbers": { 155 | "version": "1.11.6", 156 | "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", 157 | "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", 158 | "dev": true, 159 | "dependencies": { 160 | "@webassemblyjs/floating-point-hex-parser": "1.11.6", 161 | "@webassemblyjs/helper-api-error": "1.11.6", 162 | "@xtuc/long": "4.2.2" 163 | } 164 | }, 165 | "node_modules/@webassemblyjs/helper-wasm-bytecode": { 166 | "version": "1.11.6", 167 | "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", 168 | "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", 169 | "dev": true 170 | }, 171 | "node_modules/@webassemblyjs/helper-wasm-section": { 172 | "version": "1.12.1", 173 | "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz", 174 | "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==", 175 | "dev": true, 176 | "dependencies": { 177 | "@webassemblyjs/ast": "1.12.1", 178 | "@webassemblyjs/helper-buffer": "1.12.1", 179 | "@webassemblyjs/helper-wasm-bytecode": "1.11.6", 180 | "@webassemblyjs/wasm-gen": "1.12.1" 181 | } 182 | }, 183 | "node_modules/@webassemblyjs/ieee754": { 184 | "version": "1.11.6", 185 | "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", 186 | "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", 187 | "dev": true, 188 | "dependencies": { 189 | "@xtuc/ieee754": "^1.2.0" 190 | } 191 | }, 192 | "node_modules/@webassemblyjs/leb128": { 193 | "version": "1.11.6", 194 | "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", 195 | "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", 196 | "dev": true, 197 | "dependencies": { 198 | "@xtuc/long": "4.2.2" 199 | } 200 | }, 201 | "node_modules/@webassemblyjs/utf8": { 202 | "version": "1.11.6", 203 | "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", 204 | "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", 205 | "dev": true 206 | }, 207 | "node_modules/@webassemblyjs/wasm-edit": { 208 | "version": "1.12.1", 209 | "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz", 210 | "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==", 211 | "dev": true, 212 | "dependencies": { 213 | "@webassemblyjs/ast": "1.12.1", 214 | "@webassemblyjs/helper-buffer": "1.12.1", 215 | "@webassemblyjs/helper-wasm-bytecode": "1.11.6", 216 | "@webassemblyjs/helper-wasm-section": "1.12.1", 217 | "@webassemblyjs/wasm-gen": "1.12.1", 218 | "@webassemblyjs/wasm-opt": "1.12.1", 219 | "@webassemblyjs/wasm-parser": "1.12.1", 220 | "@webassemblyjs/wast-printer": "1.12.1" 221 | } 222 | }, 223 | "node_modules/@webassemblyjs/wasm-gen": { 224 | "version": "1.12.1", 225 | "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz", 226 | "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==", 227 | "dev": true, 228 | "dependencies": { 229 | "@webassemblyjs/ast": "1.12.1", 230 | "@webassemblyjs/helper-wasm-bytecode": "1.11.6", 231 | "@webassemblyjs/ieee754": "1.11.6", 232 | "@webassemblyjs/leb128": "1.11.6", 233 | "@webassemblyjs/utf8": "1.11.6" 234 | } 235 | }, 236 | "node_modules/@webassemblyjs/wasm-opt": { 237 | "version": "1.12.1", 238 | "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz", 239 | "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==", 240 | "dev": true, 241 | "dependencies": { 242 | "@webassemblyjs/ast": "1.12.1", 243 | "@webassemblyjs/helper-buffer": "1.12.1", 244 | "@webassemblyjs/wasm-gen": "1.12.1", 245 | "@webassemblyjs/wasm-parser": "1.12.1" 246 | } 247 | }, 248 | "node_modules/@webassemblyjs/wasm-parser": { 249 | "version": "1.12.1", 250 | "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz", 251 | "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==", 252 | "dev": true, 253 | "dependencies": { 254 | "@webassemblyjs/ast": "1.12.1", 255 | "@webassemblyjs/helper-api-error": "1.11.6", 256 | "@webassemblyjs/helper-wasm-bytecode": "1.11.6", 257 | "@webassemblyjs/ieee754": "1.11.6", 258 | "@webassemblyjs/leb128": "1.11.6", 259 | "@webassemblyjs/utf8": "1.11.6" 260 | } 261 | }, 262 | "node_modules/@webassemblyjs/wast-printer": { 263 | "version": "1.12.1", 264 | "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz", 265 | "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==", 266 | "dev": true, 267 | "dependencies": { 268 | "@webassemblyjs/ast": "1.12.1", 269 | "@xtuc/long": "4.2.2" 270 | } 271 | }, 272 | "node_modules/@webpack-cli/configtest": { 273 | "version": "2.1.1", 274 | "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.1.1.tgz", 275 | "integrity": "sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw==", 276 | "dev": true, 277 | "engines": { 278 | "node": ">=14.15.0" 279 | }, 280 | "peerDependencies": { 281 | "webpack": "5.x.x", 282 | "webpack-cli": "5.x.x" 283 | } 284 | }, 285 | "node_modules/@webpack-cli/info": { 286 | "version": "2.0.2", 287 | "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.2.tgz", 288 | "integrity": "sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A==", 289 | "dev": true, 290 | "engines": { 291 | "node": ">=14.15.0" 292 | }, 293 | "peerDependencies": { 294 | "webpack": "5.x.x", 295 | "webpack-cli": "5.x.x" 296 | } 297 | }, 298 | "node_modules/@webpack-cli/serve": { 299 | "version": "2.0.5", 300 | "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.5.tgz", 301 | "integrity": "sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ==", 302 | "dev": true, 303 | "engines": { 304 | "node": ">=14.15.0" 305 | }, 306 | "peerDependencies": { 307 | "webpack": "5.x.x", 308 | "webpack-cli": "5.x.x" 309 | }, 310 | "peerDependenciesMeta": { 311 | "webpack-dev-server": { 312 | "optional": true 313 | } 314 | } 315 | }, 316 | "node_modules/@xtuc/ieee754": { 317 | "version": "1.2.0", 318 | "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", 319 | "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", 320 | "dev": true 321 | }, 322 | "node_modules/@xtuc/long": { 323 | "version": "4.2.2", 324 | "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", 325 | "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", 326 | "dev": true 327 | }, 328 | "node_modules/acorn": { 329 | "version": "8.11.3", 330 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", 331 | "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", 332 | "dev": true, 333 | "bin": { 334 | "acorn": "bin/acorn" 335 | }, 336 | "engines": { 337 | "node": ">=0.4.0" 338 | } 339 | }, 340 | "node_modules/acorn-import-assertions": { 341 | "version": "1.9.0", 342 | "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", 343 | "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", 344 | "dev": true, 345 | "peerDependencies": { 346 | "acorn": "^8" 347 | } 348 | }, 349 | "node_modules/ajv": { 350 | "version": "6.12.6", 351 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", 352 | "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", 353 | "dev": true, 354 | "dependencies": { 355 | "fast-deep-equal": "^3.1.1", 356 | "fast-json-stable-stringify": "^2.0.0", 357 | "json-schema-traverse": "^0.4.1", 358 | "uri-js": "^4.2.2" 359 | }, 360 | "funding": { 361 | "type": "github", 362 | "url": "https://github.com/sponsors/epoberezkin" 363 | } 364 | }, 365 | "node_modules/ajv-keywords": { 366 | "version": "3.5.2", 367 | "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", 368 | "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", 369 | "dev": true, 370 | "peerDependencies": { 371 | "ajv": "^6.9.1" 372 | } 373 | }, 374 | "node_modules/ansi-styles": { 375 | "version": "4.3.0", 376 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", 377 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", 378 | "dev": true, 379 | "dependencies": { 380 | "color-convert": "^2.0.1" 381 | }, 382 | "engines": { 383 | "node": ">=8" 384 | }, 385 | "funding": { 386 | "url": "https://github.com/chalk/ansi-styles?sponsor=1" 387 | } 388 | }, 389 | "node_modules/braces": { 390 | "version": "3.0.3", 391 | "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", 392 | "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", 393 | "dev": true, 394 | "dependencies": { 395 | "fill-range": "^7.1.1" 396 | }, 397 | "engines": { 398 | "node": ">=8" 399 | } 400 | }, 401 | "node_modules/browserslist": { 402 | "version": "4.23.1", 403 | "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.1.tgz", 404 | "integrity": "sha512-TUfofFo/KsK/bWZ9TWQ5O26tsWW4Uhmt8IYklbnUa70udB6P2wA7w7o4PY4muaEPBQaAX+CEnmmIA41NVHtPVw==", 405 | "dev": true, 406 | "funding": [ 407 | { 408 | "type": "opencollective", 409 | "url": "https://opencollective.com/browserslist" 410 | }, 411 | { 412 | "type": "tidelift", 413 | "url": "https://tidelift.com/funding/github/npm/browserslist" 414 | }, 415 | { 416 | "type": "github", 417 | "url": "https://github.com/sponsors/ai" 418 | } 419 | ], 420 | "dependencies": { 421 | "caniuse-lite": "^1.0.30001629", 422 | "electron-to-chromium": "^1.4.796", 423 | "node-releases": "^2.0.14", 424 | "update-browserslist-db": "^1.0.16" 425 | }, 426 | "bin": { 427 | "browserslist": "cli.js" 428 | }, 429 | "engines": { 430 | "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" 431 | } 432 | }, 433 | "node_modules/buffer-from": { 434 | "version": "1.1.2", 435 | "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", 436 | "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", 437 | "dev": true 438 | }, 439 | "node_modules/caniuse-lite": { 440 | "version": "1.0.30001629", 441 | "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001629.tgz", 442 | "integrity": "sha512-c3dl911slnQhmxUIT4HhYzT7wnBK/XYpGnYLOj4nJBaRiw52Ibe7YxlDaAeRECvA786zCuExhxIUJ2K7nHMrBw==", 443 | "dev": true, 444 | "funding": [ 445 | { 446 | "type": "opencollective", 447 | "url": "https://opencollective.com/browserslist" 448 | }, 449 | { 450 | "type": "tidelift", 451 | "url": "https://tidelift.com/funding/github/npm/caniuse-lite" 452 | }, 453 | { 454 | "type": "github", 455 | "url": "https://github.com/sponsors/ai" 456 | } 457 | ] 458 | }, 459 | "node_modules/chalk": { 460 | "version": "4.1.2", 461 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", 462 | "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", 463 | "dev": true, 464 | "dependencies": { 465 | "ansi-styles": "^4.1.0", 466 | "supports-color": "^7.1.0" 467 | }, 468 | "engines": { 469 | "node": ">=10" 470 | }, 471 | "funding": { 472 | "url": "https://github.com/chalk/chalk?sponsor=1" 473 | } 474 | }, 475 | "node_modules/chrome-trace-event": { 476 | "version": "1.0.4", 477 | "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", 478 | "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", 479 | "dev": true, 480 | "engines": { 481 | "node": ">=6.0" 482 | } 483 | }, 484 | "node_modules/clone-deep": { 485 | "version": "4.0.1", 486 | "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", 487 | "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", 488 | "dev": true, 489 | "dependencies": { 490 | "is-plain-object": "^2.0.4", 491 | "kind-of": "^6.0.2", 492 | "shallow-clone": "^3.0.0" 493 | }, 494 | "engines": { 495 | "node": ">=6" 496 | } 497 | }, 498 | "node_modules/color-convert": { 499 | "version": "2.0.1", 500 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", 501 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", 502 | "dev": true, 503 | "dependencies": { 504 | "color-name": "~1.1.4" 505 | }, 506 | "engines": { 507 | "node": ">=7.0.0" 508 | } 509 | }, 510 | "node_modules/color-name": { 511 | "version": "1.1.4", 512 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", 513 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", 514 | "dev": true 515 | }, 516 | "node_modules/colorette": { 517 | "version": "2.0.20", 518 | "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", 519 | "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", 520 | "dev": true 521 | }, 522 | "node_modules/commander": { 523 | "version": "2.20.3", 524 | "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", 525 | "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", 526 | "dev": true 527 | }, 528 | "node_modules/cross-spawn": { 529 | "version": "7.0.3", 530 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", 531 | "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", 532 | "dev": true, 533 | "dependencies": { 534 | "path-key": "^3.1.0", 535 | "shebang-command": "^2.0.0", 536 | "which": "^2.0.1" 537 | }, 538 | "engines": { 539 | "node": ">= 8" 540 | } 541 | }, 542 | "node_modules/electron-to-chromium": { 543 | "version": "1.4.796", 544 | "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.796.tgz", 545 | "integrity": "sha512-NglN/xprcM+SHD2XCli4oC6bWe6kHoytcyLKCWXmRL854F0qhPhaYgUswUsglnPxYaNQIg2uMY4BvaomIf3kLA==", 546 | "dev": true 547 | }, 548 | "node_modules/enhanced-resolve": { 549 | "version": "5.17.0", 550 | "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.0.tgz", 551 | "integrity": "sha512-dwDPwZL0dmye8Txp2gzFmA6sxALaSvdRDjPH0viLcKrtlOL3tw62nWWweVD1SdILDTJrbrL6tdWVN58Wo6U3eA==", 552 | "dev": true, 553 | "dependencies": { 554 | "graceful-fs": "^4.2.4", 555 | "tapable": "^2.2.0" 556 | }, 557 | "engines": { 558 | "node": ">=10.13.0" 559 | } 560 | }, 561 | "node_modules/envinfo": { 562 | "version": "7.13.0", 563 | "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.13.0.tgz", 564 | "integrity": "sha512-cvcaMr7KqXVh4nyzGTVqTum+gAiL265x5jUWQIDLq//zOGbW+gSW/C+OWLleY/rs9Qole6AZLMXPbtIFQbqu+Q==", 565 | "dev": true, 566 | "bin": { 567 | "envinfo": "dist/cli.js" 568 | }, 569 | "engines": { 570 | "node": ">=4" 571 | } 572 | }, 573 | "node_modules/es-module-lexer": { 574 | "version": "1.5.3", 575 | "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.3.tgz", 576 | "integrity": "sha512-i1gCgmR9dCl6Vil6UKPI/trA69s08g/syhiDK9TG0Nf1RJjjFI+AzoWW7sPufzkgYAn861skuCwJa0pIIHYxvg==", 577 | "dev": true 578 | }, 579 | "node_modules/escalade": { 580 | "version": "3.1.2", 581 | "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", 582 | "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", 583 | "dev": true, 584 | "engines": { 585 | "node": ">=6" 586 | } 587 | }, 588 | "node_modules/eslint-scope": { 589 | "version": "5.1.1", 590 | "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", 591 | "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", 592 | "dev": true, 593 | "dependencies": { 594 | "esrecurse": "^4.3.0", 595 | "estraverse": "^4.1.1" 596 | }, 597 | "engines": { 598 | "node": ">=8.0.0" 599 | } 600 | }, 601 | "node_modules/esrecurse": { 602 | "version": "4.3.0", 603 | "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", 604 | "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", 605 | "dev": true, 606 | "dependencies": { 607 | "estraverse": "^5.2.0" 608 | }, 609 | "engines": { 610 | "node": ">=4.0" 611 | } 612 | }, 613 | "node_modules/esrecurse/node_modules/estraverse": { 614 | "version": "5.3.0", 615 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", 616 | "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", 617 | "dev": true, 618 | "engines": { 619 | "node": ">=4.0" 620 | } 621 | }, 622 | "node_modules/estraverse": { 623 | "version": "4.3.0", 624 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", 625 | "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", 626 | "dev": true, 627 | "engines": { 628 | "node": ">=4.0" 629 | } 630 | }, 631 | "node_modules/events": { 632 | "version": "3.3.0", 633 | "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", 634 | "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", 635 | "dev": true, 636 | "engines": { 637 | "node": ">=0.8.x" 638 | } 639 | }, 640 | "node_modules/fast-deep-equal": { 641 | "version": "3.1.3", 642 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", 643 | "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", 644 | "dev": true 645 | }, 646 | "node_modules/fast-json-stable-stringify": { 647 | "version": "2.1.0", 648 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", 649 | "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", 650 | "dev": true 651 | }, 652 | "node_modules/fastest-levenshtein": { 653 | "version": "1.0.16", 654 | "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", 655 | "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", 656 | "dev": true, 657 | "engines": { 658 | "node": ">= 4.9.1" 659 | } 660 | }, 661 | "node_modules/fill-range": { 662 | "version": "7.1.1", 663 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", 664 | "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", 665 | "dev": true, 666 | "dependencies": { 667 | "to-regex-range": "^5.0.1" 668 | }, 669 | "engines": { 670 | "node": ">=8" 671 | } 672 | }, 673 | "node_modules/find-up": { 674 | "version": "4.1.0", 675 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", 676 | "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", 677 | "dev": true, 678 | "dependencies": { 679 | "locate-path": "^5.0.0", 680 | "path-exists": "^4.0.0" 681 | }, 682 | "engines": { 683 | "node": ">=8" 684 | } 685 | }, 686 | "node_modules/flat": { 687 | "version": "5.0.2", 688 | "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", 689 | "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", 690 | "dev": true, 691 | "bin": { 692 | "flat": "cli.js" 693 | } 694 | }, 695 | "node_modules/function-bind": { 696 | "version": "1.1.2", 697 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", 698 | "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", 699 | "dev": true, 700 | "funding": { 701 | "url": "https://github.com/sponsors/ljharb" 702 | } 703 | }, 704 | "node_modules/glob-to-regexp": { 705 | "version": "0.4.1", 706 | "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", 707 | "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", 708 | "dev": true 709 | }, 710 | "node_modules/graceful-fs": { 711 | "version": "4.2.11", 712 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", 713 | "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", 714 | "dev": true 715 | }, 716 | "node_modules/has-flag": { 717 | "version": "4.0.0", 718 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", 719 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", 720 | "dev": true, 721 | "engines": { 722 | "node": ">=8" 723 | } 724 | }, 725 | "node_modules/hasown": { 726 | "version": "2.0.2", 727 | "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", 728 | "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", 729 | "dev": true, 730 | "dependencies": { 731 | "function-bind": "^1.1.2" 732 | }, 733 | "engines": { 734 | "node": ">= 0.4" 735 | } 736 | }, 737 | "node_modules/import-local": { 738 | "version": "3.1.0", 739 | "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", 740 | "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", 741 | "dev": true, 742 | "dependencies": { 743 | "pkg-dir": "^4.2.0", 744 | "resolve-cwd": "^3.0.0" 745 | }, 746 | "bin": { 747 | "import-local-fixture": "fixtures/cli.js" 748 | }, 749 | "engines": { 750 | "node": ">=8" 751 | }, 752 | "funding": { 753 | "url": "https://github.com/sponsors/sindresorhus" 754 | } 755 | }, 756 | "node_modules/interpret": { 757 | "version": "3.1.1", 758 | "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", 759 | "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", 760 | "dev": true, 761 | "engines": { 762 | "node": ">=10.13.0" 763 | } 764 | }, 765 | "node_modules/is-core-module": { 766 | "version": "2.13.1", 767 | "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", 768 | "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", 769 | "dev": true, 770 | "dependencies": { 771 | "hasown": "^2.0.0" 772 | }, 773 | "funding": { 774 | "url": "https://github.com/sponsors/ljharb" 775 | } 776 | }, 777 | "node_modules/is-number": { 778 | "version": "7.0.0", 779 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", 780 | "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", 781 | "dev": true, 782 | "engines": { 783 | "node": ">=0.12.0" 784 | } 785 | }, 786 | "node_modules/is-plain-object": { 787 | "version": "2.0.4", 788 | "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", 789 | "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", 790 | "dev": true, 791 | "dependencies": { 792 | "isobject": "^3.0.1" 793 | }, 794 | "engines": { 795 | "node": ">=0.10.0" 796 | } 797 | }, 798 | "node_modules/isexe": { 799 | "version": "2.0.0", 800 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 801 | "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", 802 | "dev": true 803 | }, 804 | "node_modules/isobject": { 805 | "version": "3.0.1", 806 | "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", 807 | "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", 808 | "dev": true, 809 | "engines": { 810 | "node": ">=0.10.0" 811 | } 812 | }, 813 | "node_modules/jest-worker": { 814 | "version": "27.5.1", 815 | "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", 816 | "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", 817 | "dev": true, 818 | "dependencies": { 819 | "@types/node": "*", 820 | "merge-stream": "^2.0.0", 821 | "supports-color": "^8.0.0" 822 | }, 823 | "engines": { 824 | "node": ">= 10.13.0" 825 | } 826 | }, 827 | "node_modules/jest-worker/node_modules/supports-color": { 828 | "version": "8.1.1", 829 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", 830 | "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", 831 | "dev": true, 832 | "dependencies": { 833 | "has-flag": "^4.0.0" 834 | }, 835 | "engines": { 836 | "node": ">=10" 837 | }, 838 | "funding": { 839 | "url": "https://github.com/chalk/supports-color?sponsor=1" 840 | } 841 | }, 842 | "node_modules/json-parse-even-better-errors": { 843 | "version": "2.3.1", 844 | "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", 845 | "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", 846 | "dev": true 847 | }, 848 | "node_modules/json-schema-traverse": { 849 | "version": "0.4.1", 850 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", 851 | "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", 852 | "dev": true 853 | }, 854 | "node_modules/kind-of": { 855 | "version": "6.0.3", 856 | "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", 857 | "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", 858 | "dev": true, 859 | "engines": { 860 | "node": ">=0.10.0" 861 | } 862 | }, 863 | "node_modules/loader-runner": { 864 | "version": "4.3.0", 865 | "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", 866 | "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", 867 | "dev": true, 868 | "engines": { 869 | "node": ">=6.11.5" 870 | } 871 | }, 872 | "node_modules/locate-path": { 873 | "version": "5.0.0", 874 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", 875 | "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", 876 | "dev": true, 877 | "dependencies": { 878 | "p-locate": "^4.1.0" 879 | }, 880 | "engines": { 881 | "node": ">=8" 882 | } 883 | }, 884 | "node_modules/merge-stream": { 885 | "version": "2.0.0", 886 | "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", 887 | "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", 888 | "dev": true 889 | }, 890 | "node_modules/micromatch": { 891 | "version": "4.0.7", 892 | "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", 893 | "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", 894 | "dev": true, 895 | "dependencies": { 896 | "braces": "^3.0.3", 897 | "picomatch": "^2.3.1" 898 | }, 899 | "engines": { 900 | "node": ">=8.6" 901 | } 902 | }, 903 | "node_modules/mime-db": { 904 | "version": "1.52.0", 905 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", 906 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", 907 | "dev": true, 908 | "engines": { 909 | "node": ">= 0.6" 910 | } 911 | }, 912 | "node_modules/mime-types": { 913 | "version": "2.1.35", 914 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", 915 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", 916 | "dev": true, 917 | "dependencies": { 918 | "mime-db": "1.52.0" 919 | }, 920 | "engines": { 921 | "node": ">= 0.6" 922 | } 923 | }, 924 | "node_modules/neo-async": { 925 | "version": "2.6.2", 926 | "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", 927 | "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", 928 | "dev": true 929 | }, 930 | "node_modules/node-releases": { 931 | "version": "2.0.14", 932 | "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", 933 | "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", 934 | "dev": true 935 | }, 936 | "node_modules/p-limit": { 937 | "version": "2.3.0", 938 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", 939 | "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", 940 | "dev": true, 941 | "dependencies": { 942 | "p-try": "^2.0.0" 943 | }, 944 | "engines": { 945 | "node": ">=6" 946 | }, 947 | "funding": { 948 | "url": "https://github.com/sponsors/sindresorhus" 949 | } 950 | }, 951 | "node_modules/p-locate": { 952 | "version": "4.1.0", 953 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", 954 | "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", 955 | "dev": true, 956 | "dependencies": { 957 | "p-limit": "^2.2.0" 958 | }, 959 | "engines": { 960 | "node": ">=8" 961 | } 962 | }, 963 | "node_modules/p-try": { 964 | "version": "2.2.0", 965 | "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", 966 | "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", 967 | "dev": true, 968 | "engines": { 969 | "node": ">=6" 970 | } 971 | }, 972 | "node_modules/path-exists": { 973 | "version": "4.0.0", 974 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", 975 | "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", 976 | "dev": true, 977 | "engines": { 978 | "node": ">=8" 979 | } 980 | }, 981 | "node_modules/path-key": { 982 | "version": "3.1.1", 983 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", 984 | "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", 985 | "dev": true, 986 | "engines": { 987 | "node": ">=8" 988 | } 989 | }, 990 | "node_modules/path-parse": { 991 | "version": "1.0.7", 992 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", 993 | "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", 994 | "dev": true 995 | }, 996 | "node_modules/picocolors": { 997 | "version": "1.0.1", 998 | "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", 999 | "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", 1000 | "dev": true 1001 | }, 1002 | "node_modules/picomatch": { 1003 | "version": "2.3.1", 1004 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", 1005 | "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", 1006 | "dev": true, 1007 | "engines": { 1008 | "node": ">=8.6" 1009 | }, 1010 | "funding": { 1011 | "url": "https://github.com/sponsors/jonschlinkert" 1012 | } 1013 | }, 1014 | "node_modules/pkg-dir": { 1015 | "version": "4.2.0", 1016 | "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", 1017 | "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", 1018 | "dev": true, 1019 | "dependencies": { 1020 | "find-up": "^4.0.0" 1021 | }, 1022 | "engines": { 1023 | "node": ">=8" 1024 | } 1025 | }, 1026 | "node_modules/punycode": { 1027 | "version": "2.3.1", 1028 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", 1029 | "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", 1030 | "dev": true, 1031 | "engines": { 1032 | "node": ">=6" 1033 | } 1034 | }, 1035 | "node_modules/randombytes": { 1036 | "version": "2.1.0", 1037 | "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", 1038 | "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", 1039 | "dev": true, 1040 | "dependencies": { 1041 | "safe-buffer": "^5.1.0" 1042 | } 1043 | }, 1044 | "node_modules/rechoir": { 1045 | "version": "0.8.0", 1046 | "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", 1047 | "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", 1048 | "dev": true, 1049 | "dependencies": { 1050 | "resolve": "^1.20.0" 1051 | }, 1052 | "engines": { 1053 | "node": ">= 10.13.0" 1054 | } 1055 | }, 1056 | "node_modules/resolve": { 1057 | "version": "1.22.8", 1058 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", 1059 | "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", 1060 | "dev": true, 1061 | "dependencies": { 1062 | "is-core-module": "^2.13.0", 1063 | "path-parse": "^1.0.7", 1064 | "supports-preserve-symlinks-flag": "^1.0.0" 1065 | }, 1066 | "bin": { 1067 | "resolve": "bin/resolve" 1068 | }, 1069 | "funding": { 1070 | "url": "https://github.com/sponsors/ljharb" 1071 | } 1072 | }, 1073 | "node_modules/resolve-cwd": { 1074 | "version": "3.0.0", 1075 | "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", 1076 | "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", 1077 | "dev": true, 1078 | "dependencies": { 1079 | "resolve-from": "^5.0.0" 1080 | }, 1081 | "engines": { 1082 | "node": ">=8" 1083 | } 1084 | }, 1085 | "node_modules/resolve-from": { 1086 | "version": "5.0.0", 1087 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", 1088 | "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", 1089 | "dev": true, 1090 | "engines": { 1091 | "node": ">=8" 1092 | } 1093 | }, 1094 | "node_modules/safe-buffer": { 1095 | "version": "5.2.1", 1096 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 1097 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", 1098 | "dev": true, 1099 | "funding": [ 1100 | { 1101 | "type": "github", 1102 | "url": "https://github.com/sponsors/feross" 1103 | }, 1104 | { 1105 | "type": "patreon", 1106 | "url": "https://www.patreon.com/feross" 1107 | }, 1108 | { 1109 | "type": "consulting", 1110 | "url": "https://feross.org/support" 1111 | } 1112 | ] 1113 | }, 1114 | "node_modules/schema-utils": { 1115 | "version": "3.3.0", 1116 | "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", 1117 | "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", 1118 | "dev": true, 1119 | "dependencies": { 1120 | "@types/json-schema": "^7.0.8", 1121 | "ajv": "^6.12.5", 1122 | "ajv-keywords": "^3.5.2" 1123 | }, 1124 | "engines": { 1125 | "node": ">= 10.13.0" 1126 | }, 1127 | "funding": { 1128 | "type": "opencollective", 1129 | "url": "https://opencollective.com/webpack" 1130 | } 1131 | }, 1132 | "node_modules/semver": { 1133 | "version": "7.6.2", 1134 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", 1135 | "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", 1136 | "dev": true, 1137 | "bin": { 1138 | "semver": "bin/semver.js" 1139 | }, 1140 | "engines": { 1141 | "node": ">=10" 1142 | } 1143 | }, 1144 | "node_modules/serialize-javascript": { 1145 | "version": "6.0.2", 1146 | "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", 1147 | "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", 1148 | "dev": true, 1149 | "dependencies": { 1150 | "randombytes": "^2.1.0" 1151 | } 1152 | }, 1153 | "node_modules/shallow-clone": { 1154 | "version": "3.0.1", 1155 | "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", 1156 | "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", 1157 | "dev": true, 1158 | "dependencies": { 1159 | "kind-of": "^6.0.2" 1160 | }, 1161 | "engines": { 1162 | "node": ">=8" 1163 | } 1164 | }, 1165 | "node_modules/shebang-command": { 1166 | "version": "2.0.0", 1167 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", 1168 | "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", 1169 | "dev": true, 1170 | "dependencies": { 1171 | "shebang-regex": "^3.0.0" 1172 | }, 1173 | "engines": { 1174 | "node": ">=8" 1175 | } 1176 | }, 1177 | "node_modules/shebang-regex": { 1178 | "version": "3.0.0", 1179 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", 1180 | "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", 1181 | "dev": true, 1182 | "engines": { 1183 | "node": ">=8" 1184 | } 1185 | }, 1186 | "node_modules/source-map": { 1187 | "version": "0.7.4", 1188 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", 1189 | "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", 1190 | "dev": true, 1191 | "engines": { 1192 | "node": ">= 8" 1193 | } 1194 | }, 1195 | "node_modules/source-map-support": { 1196 | "version": "0.5.21", 1197 | "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", 1198 | "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", 1199 | "dev": true, 1200 | "dependencies": { 1201 | "buffer-from": "^1.0.0", 1202 | "source-map": "^0.6.0" 1203 | } 1204 | }, 1205 | "node_modules/source-map-support/node_modules/source-map": { 1206 | "version": "0.6.1", 1207 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", 1208 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", 1209 | "dev": true, 1210 | "engines": { 1211 | "node": ">=0.10.0" 1212 | } 1213 | }, 1214 | "node_modules/supports-color": { 1215 | "version": "7.2.0", 1216 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", 1217 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", 1218 | "dev": true, 1219 | "dependencies": { 1220 | "has-flag": "^4.0.0" 1221 | }, 1222 | "engines": { 1223 | "node": ">=8" 1224 | } 1225 | }, 1226 | "node_modules/supports-preserve-symlinks-flag": { 1227 | "version": "1.0.0", 1228 | "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", 1229 | "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", 1230 | "dev": true, 1231 | "engines": { 1232 | "node": ">= 0.4" 1233 | }, 1234 | "funding": { 1235 | "url": "https://github.com/sponsors/ljharb" 1236 | } 1237 | }, 1238 | "node_modules/tapable": { 1239 | "version": "2.2.1", 1240 | "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", 1241 | "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", 1242 | "dev": true, 1243 | "engines": { 1244 | "node": ">=6" 1245 | } 1246 | }, 1247 | "node_modules/terser": { 1248 | "version": "5.31.1", 1249 | "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.1.tgz", 1250 | "integrity": "sha512-37upzU1+viGvuFtBo9NPufCb9dwM0+l9hMxYyWfBA+fbwrPqNJAhbZ6W47bBFnZHKHTUBnMvi87434qq+qnxOg==", 1251 | "dev": true, 1252 | "dependencies": { 1253 | "@jridgewell/source-map": "^0.3.3", 1254 | "acorn": "^8.8.2", 1255 | "commander": "^2.20.0", 1256 | "source-map-support": "~0.5.20" 1257 | }, 1258 | "bin": { 1259 | "terser": "bin/terser" 1260 | }, 1261 | "engines": { 1262 | "node": ">=10" 1263 | } 1264 | }, 1265 | "node_modules/terser-webpack-plugin": { 1266 | "version": "5.3.10", 1267 | "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", 1268 | "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", 1269 | "dev": true, 1270 | "dependencies": { 1271 | "@jridgewell/trace-mapping": "^0.3.20", 1272 | "jest-worker": "^27.4.5", 1273 | "schema-utils": "^3.1.1", 1274 | "serialize-javascript": "^6.0.1", 1275 | "terser": "^5.26.0" 1276 | }, 1277 | "engines": { 1278 | "node": ">= 10.13.0" 1279 | }, 1280 | "funding": { 1281 | "type": "opencollective", 1282 | "url": "https://opencollective.com/webpack" 1283 | }, 1284 | "peerDependencies": { 1285 | "webpack": "^5.1.0" 1286 | }, 1287 | "peerDependenciesMeta": { 1288 | "@swc/core": { 1289 | "optional": true 1290 | }, 1291 | "esbuild": { 1292 | "optional": true 1293 | }, 1294 | "uglify-js": { 1295 | "optional": true 1296 | } 1297 | } 1298 | }, 1299 | "node_modules/to-regex-range": { 1300 | "version": "5.0.1", 1301 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", 1302 | "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", 1303 | "dev": true, 1304 | "dependencies": { 1305 | "is-number": "^7.0.0" 1306 | }, 1307 | "engines": { 1308 | "node": ">=8.0" 1309 | } 1310 | }, 1311 | "node_modules/ts-loader": { 1312 | "version": "9.5.1", 1313 | "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.5.1.tgz", 1314 | "integrity": "sha512-rNH3sK9kGZcH9dYzC7CewQm4NtxJTjSEVRJ2DyBZR7f8/wcta+iV44UPCXc5+nzDzivKtlzV6c9P4e+oFhDLYg==", 1315 | "dev": true, 1316 | "dependencies": { 1317 | "chalk": "^4.1.0", 1318 | "enhanced-resolve": "^5.0.0", 1319 | "micromatch": "^4.0.0", 1320 | "semver": "^7.3.4", 1321 | "source-map": "^0.7.4" 1322 | }, 1323 | "engines": { 1324 | "node": ">=12.0.0" 1325 | }, 1326 | "peerDependencies": { 1327 | "typescript": "*", 1328 | "webpack": "^5.0.0" 1329 | } 1330 | }, 1331 | "node_modules/typescript": { 1332 | "version": "5.4.5", 1333 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", 1334 | "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", 1335 | "dev": true, 1336 | "bin": { 1337 | "tsc": "bin/tsc", 1338 | "tsserver": "bin/tsserver" 1339 | }, 1340 | "engines": { 1341 | "node": ">=14.17" 1342 | } 1343 | }, 1344 | "node_modules/undici-types": { 1345 | "version": "5.26.5", 1346 | "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", 1347 | "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", 1348 | "dev": true 1349 | }, 1350 | "node_modules/update-browserslist-db": { 1351 | "version": "1.0.16", 1352 | "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.16.tgz", 1353 | "integrity": "sha512-KVbTxlBYlckhF5wgfyZXTWnMn7MMZjMu9XG8bPlliUOP9ThaF4QnhP8qrjrH7DRzHfSk0oQv1wToW+iA5GajEQ==", 1354 | "dev": true, 1355 | "funding": [ 1356 | { 1357 | "type": "opencollective", 1358 | "url": "https://opencollective.com/browserslist" 1359 | }, 1360 | { 1361 | "type": "tidelift", 1362 | "url": "https://tidelift.com/funding/github/npm/browserslist" 1363 | }, 1364 | { 1365 | "type": "github", 1366 | "url": "https://github.com/sponsors/ai" 1367 | } 1368 | ], 1369 | "dependencies": { 1370 | "escalade": "^3.1.2", 1371 | "picocolors": "^1.0.1" 1372 | }, 1373 | "bin": { 1374 | "update-browserslist-db": "cli.js" 1375 | }, 1376 | "peerDependencies": { 1377 | "browserslist": ">= 4.21.0" 1378 | } 1379 | }, 1380 | "node_modules/uri-js": { 1381 | "version": "4.4.1", 1382 | "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", 1383 | "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", 1384 | "dev": true, 1385 | "dependencies": { 1386 | "punycode": "^2.1.0" 1387 | } 1388 | }, 1389 | "node_modules/watchpack": { 1390 | "version": "2.4.1", 1391 | "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.1.tgz", 1392 | "integrity": "sha512-8wrBCMtVhqcXP2Sup1ctSkga6uc2Bx0IIvKyT7yTFier5AXHooSI+QyQQAtTb7+E0IUCCKyTFmXqdqgum2XWGg==", 1393 | "dev": true, 1394 | "dependencies": { 1395 | "glob-to-regexp": "^0.4.1", 1396 | "graceful-fs": "^4.1.2" 1397 | }, 1398 | "engines": { 1399 | "node": ">=10.13.0" 1400 | } 1401 | }, 1402 | "node_modules/webpack": { 1403 | "version": "5.91.0", 1404 | "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.91.0.tgz", 1405 | "integrity": "sha512-rzVwlLeBWHJbmgTC/8TvAcu5vpJNII+MelQpylD4jNERPwpBJOE2lEcko1zJX3QJeLjTTAnQxn/OJ8bjDzVQaw==", 1406 | "dev": true, 1407 | "dependencies": { 1408 | "@types/eslint-scope": "^3.7.3", 1409 | "@types/estree": "^1.0.5", 1410 | "@webassemblyjs/ast": "^1.12.1", 1411 | "@webassemblyjs/wasm-edit": "^1.12.1", 1412 | "@webassemblyjs/wasm-parser": "^1.12.1", 1413 | "acorn": "^8.7.1", 1414 | "acorn-import-assertions": "^1.9.0", 1415 | "browserslist": "^4.21.10", 1416 | "chrome-trace-event": "^1.0.2", 1417 | "enhanced-resolve": "^5.16.0", 1418 | "es-module-lexer": "^1.2.1", 1419 | "eslint-scope": "5.1.1", 1420 | "events": "^3.2.0", 1421 | "glob-to-regexp": "^0.4.1", 1422 | "graceful-fs": "^4.2.11", 1423 | "json-parse-even-better-errors": "^2.3.1", 1424 | "loader-runner": "^4.2.0", 1425 | "mime-types": "^2.1.27", 1426 | "neo-async": "^2.6.2", 1427 | "schema-utils": "^3.2.0", 1428 | "tapable": "^2.1.1", 1429 | "terser-webpack-plugin": "^5.3.10", 1430 | "watchpack": "^2.4.1", 1431 | "webpack-sources": "^3.2.3" 1432 | }, 1433 | "bin": { 1434 | "webpack": "bin/webpack.js" 1435 | }, 1436 | "engines": { 1437 | "node": ">=10.13.0" 1438 | }, 1439 | "funding": { 1440 | "type": "opencollective", 1441 | "url": "https://opencollective.com/webpack" 1442 | }, 1443 | "peerDependenciesMeta": { 1444 | "webpack-cli": { 1445 | "optional": true 1446 | } 1447 | } 1448 | }, 1449 | "node_modules/webpack-cli": { 1450 | "version": "5.1.4", 1451 | "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.1.4.tgz", 1452 | "integrity": "sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==", 1453 | "dev": true, 1454 | "dependencies": { 1455 | "@discoveryjs/json-ext": "^0.5.0", 1456 | "@webpack-cli/configtest": "^2.1.1", 1457 | "@webpack-cli/info": "^2.0.2", 1458 | "@webpack-cli/serve": "^2.0.5", 1459 | "colorette": "^2.0.14", 1460 | "commander": "^10.0.1", 1461 | "cross-spawn": "^7.0.3", 1462 | "envinfo": "^7.7.3", 1463 | "fastest-levenshtein": "^1.0.12", 1464 | "import-local": "^3.0.2", 1465 | "interpret": "^3.1.1", 1466 | "rechoir": "^0.8.0", 1467 | "webpack-merge": "^5.7.3" 1468 | }, 1469 | "bin": { 1470 | "webpack-cli": "bin/cli.js" 1471 | }, 1472 | "engines": { 1473 | "node": ">=14.15.0" 1474 | }, 1475 | "funding": { 1476 | "type": "opencollective", 1477 | "url": "https://opencollective.com/webpack" 1478 | }, 1479 | "peerDependencies": { 1480 | "webpack": "5.x.x" 1481 | }, 1482 | "peerDependenciesMeta": { 1483 | "@webpack-cli/generators": { 1484 | "optional": true 1485 | }, 1486 | "webpack-bundle-analyzer": { 1487 | "optional": true 1488 | }, 1489 | "webpack-dev-server": { 1490 | "optional": true 1491 | } 1492 | } 1493 | }, 1494 | "node_modules/webpack-cli/node_modules/commander": { 1495 | "version": "10.0.1", 1496 | "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", 1497 | "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", 1498 | "dev": true, 1499 | "engines": { 1500 | "node": ">=14" 1501 | } 1502 | }, 1503 | "node_modules/webpack-merge": { 1504 | "version": "5.10.0", 1505 | "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz", 1506 | "integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==", 1507 | "dev": true, 1508 | "dependencies": { 1509 | "clone-deep": "^4.0.1", 1510 | "flat": "^5.0.2", 1511 | "wildcard": "^2.0.0" 1512 | }, 1513 | "engines": { 1514 | "node": ">=10.0.0" 1515 | } 1516 | }, 1517 | "node_modules/webpack-sources": { 1518 | "version": "3.2.3", 1519 | "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", 1520 | "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", 1521 | "dev": true, 1522 | "engines": { 1523 | "node": ">=10.13.0" 1524 | } 1525 | }, 1526 | "node_modules/which": { 1527 | "version": "2.0.2", 1528 | "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", 1529 | "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", 1530 | "dev": true, 1531 | "dependencies": { 1532 | "isexe": "^2.0.0" 1533 | }, 1534 | "bin": { 1535 | "node-which": "bin/node-which" 1536 | }, 1537 | "engines": { 1538 | "node": ">= 8" 1539 | } 1540 | }, 1541 | "node_modules/wildcard": { 1542 | "version": "2.0.1", 1543 | "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", 1544 | "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", 1545 | "dev": true 1546 | } 1547 | } 1548 | } 1549 | -------------------------------------------------------------------------------- /7-typescript-and-the-build-process/7-1-integrating-with-build-tool-webpack/my-ts-project/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "my-ts-project", 3 | "version": "1.0.0", 4 | "main": "index.js", 5 | "scripts": { 6 | "test": "echo \"Error: no test specified\" && exit 1", 7 | "build": "webpack" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "description": "", 13 | "devDependencies": { 14 | "ts-loader": "^9.5.1", 15 | "typescript": "^5.4.5", 16 | "webpack": "^5.91.0", 17 | "webpack-cli": "^5.1.4" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /7-typescript-and-the-build-process/7-1-integrating-with-build-tool-webpack/my-ts-project/src/index.ts: -------------------------------------------------------------------------------- 1 | function greet(name: string): void { 2 | console.log(`Hello, ${name}!`); 3 | } 4 | 5 | greet('World'); 6 | -------------------------------------------------------------------------------- /7-typescript-and-the-build-process/7-1-integrating-with-build-tool-webpack/my-ts-project/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "./dist/", 4 | "sourceMap": true, 5 | "noImplicitAny": true, 6 | "module": "es6", 7 | "target": "es5", 8 | "jsx": "react", 9 | "allowJs": true 10 | }, 11 | "include": [ 12 | "./src/**/*" 13 | ] 14 | } -------------------------------------------------------------------------------- /7-typescript-and-the-build-process/7-1-integrating-with-build-tool-webpack/my-ts-project/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | 3 | module.exports = { 4 | mode: 'development', 5 | entry: './src/index.ts', 6 | module: { 7 | rules: [ 8 | { 9 | test: /\.tsx?$/, 10 | use: 'ts-loader', 11 | exclude: /node_modules/ 12 | } 13 | ] 14 | }, 15 | resolve: { 16 | extensions: ['.tsx', '.ts', '.js'] 17 | }, 18 | output: { 19 | filename: 'bundle.js', 20 | path: path.resolve(__dirname, 'dist') 21 | } 22 | }; 23 | -------------------------------------------------------------------------------- /7-typescript-and-the-build-process/7-2-optimizing-typescript-for-production/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinkedInLearning/advanced-typescript-concepts-5914414/761c50563fb48345d7e783124bf2709c88362a84/7-typescript-and-the-build-process/7-2-optimizing-typescript-for-production/.gitkeep -------------------------------------------------------------------------------- /7-typescript-and-the-build-process/7-2-optimizing-typescript-for-production/my-ts-project/dist/app.503838203537d857f98d.js: -------------------------------------------------------------------------------- 1 | console.log("Hello, ".concat("World","!")); -------------------------------------------------------------------------------- /7-typescript-and-the-build-process/7-2-optimizing-typescript-for-production/my-ts-project/dist/bundle.js: -------------------------------------------------------------------------------- 1 | /* 2 | * ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development"). 3 | * This devtool is neither made for production nor for readable output files. 4 | * It uses "eval()" calls to create a separate source file in the browser devtools. 5 | * If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/) 6 | * or disable the default devtool with "devtool: false". 7 | * If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/). 8 | */ 9 | /******/ (() => { // webpackBootstrap 10 | /******/ var __webpack_modules__ = ({ 11 | 12 | /***/ "./src/index.ts": 13 | /*!**********************!*\ 14 | !*** ./src/index.ts ***! 15 | \**********************/ 16 | /***/ (() => { 17 | 18 | eval("function greet(name) {\n console.log(\"Hello, \".concat(name, \"!\"));\n}\ngreet('World');\n\n\n//# sourceURL=webpack://my-ts-project/./src/index.ts?"); 19 | 20 | /***/ }) 21 | 22 | /******/ }); 23 | /************************************************************************/ 24 | /******/ 25 | /******/ // startup 26 | /******/ // Load entry module and return exports 27 | /******/ // This entry module can't be inlined because the eval devtool is used. 28 | /******/ var __webpack_exports__ = {}; 29 | /******/ __webpack_modules__["./src/index.ts"](); 30 | /******/ 31 | /******/ })() 32 | ; -------------------------------------------------------------------------------- /7-typescript-and-the-build-process/7-2-optimizing-typescript-for-production/my-ts-project/dist/vendor.503838203537d857f98d.js: -------------------------------------------------------------------------------- 1 | console.log("Hello, ".concat("World","!")); -------------------------------------------------------------------------------- /7-typescript-and-the-build-process/7-2-optimizing-typescript-for-production/my-ts-project/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "my-ts-project", 3 | "version": "1.0.0", 4 | "main": "index.js", 5 | "scripts": { 6 | "test": "echo \"Error: no test specified\" && exit 1", 7 | "build": "webpack" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "description": "", 13 | "devDependencies": { 14 | "compression-webpack-plugin": "^11.1.0", 15 | "ts-loader": "^9.5.1", 16 | "typescript": "^5.4.5", 17 | "webpack": "^5.91.0", 18 | "webpack-cli": "^5.1.4" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /7-typescript-and-the-build-process/7-2-optimizing-typescript-for-production/my-ts-project/src/index.ts: -------------------------------------------------------------------------------- 1 | function greet(name: string): void { 2 | console.log(`Hello, ${name}!`); 3 | } 4 | 5 | greet('World'); 6 | -------------------------------------------------------------------------------- /7-typescript-and-the-build-process/7-2-optimizing-typescript-for-production/my-ts-project/src/vendor.ts: -------------------------------------------------------------------------------- 1 | function hello(name: string): void { 2 | console.log(`Hello, ${name}!`); 3 | } 4 | 5 | hello('World'); 6 | -------------------------------------------------------------------------------- /7-typescript-and-the-build-process/7-2-optimizing-typescript-for-production/my-ts-project/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "./dist/", 4 | "sourceMap": true, 5 | "noImplicitAny": true, 6 | "module": "es6", 7 | "target": "es5", 8 | "jsx": "react", 9 | "allowJs": true 10 | }, 11 | "include": [ 12 | "./src/**/*" 13 | ] 14 | } -------------------------------------------------------------------------------- /7-typescript-and-the-build-process/7-2-optimizing-typescript-for-production/my-ts-project/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const CompressionPlugin = require('compression-webpack-plugin'); 3 | 4 | 5 | module.exports = { 6 | mode: 'production', 7 | entry: { 8 | app: './src/index.ts', 9 | vendor: './src/vendor.ts' 10 | }, 11 | module: { 12 | rules: [ 13 | { 14 | test: /\.tsx?$/, 15 | use: 'ts-loader', 16 | exclude: /node_modules/ 17 | } 18 | ] 19 | }, 20 | resolve: { 21 | extensions: ['.tsx', '.ts', '.js'] 22 | }, 23 | output: { 24 | filename: '[name].[contenthash].js', 25 | path: path.resolve(__dirname, 'dist') 26 | }, 27 | optimization: { 28 | splitChunks: { 29 | chunks: 'all' 30 | } 31 | }, 32 | plugins: [ 33 | new CompressionPlugin({ 34 | algorithm: 'gzip' // Specify the Gzip compression algorithm 35 | }) 36 | ] 37 | }; 38 | -------------------------------------------------------------------------------- /7-typescript-and-the-build-process/challenge/dist/app.ad85ddc11b9521185c6dbundle.js: -------------------------------------------------------------------------------- 1 | (()=>{"use strict";var e={859:function(e,t,r){var o=this&&this.__createBinding||(Object.create?function(e,t,r,o){void 0===o&&(o=r);var n=Object.getOwnPropertyDescriptor(t,r);n&&!("get"in n?!t.__esModule:n.writable||n.configurable)||(n={enumerable:!0,get:function(){return t[r]}}),Object.defineProperty(e,o,n)}:function(e,t,r,o){void 0===o&&(o=r),e[o]=t[r]}),n=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),i=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var r in e)"default"!==r&&Object.prototype.hasOwnProperty.call(e,r)&&o(t,e,r);return n(t,e),t};console.log("App started"),Promise.resolve().then((()=>i(r(831)))).then((e=>{e.largeModule.doSomething()}))},831:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.largeModule=void 0,t.largeModule={doSomething:()=>console.log("Doing something")}}},t={};!function r(o){var n=t[o];if(void 0!==n)return n.exports;var i=t[o]={exports:{}};return e[o].call(i.exports,i,i.exports,r),i.exports}(859)})(); -------------------------------------------------------------------------------- /7-typescript-and-the-build-process/challenge/dist/bundle.js: -------------------------------------------------------------------------------- 1 | (()=>{"use strict";var e={831:(e,o)=>{Object.defineProperty(o,"__esModule",{value:!0}),o.largeModule=void 0,o.largeModule={doSomething:()=>console.log("Doing something")}}},o={};function r(t){var l=o[t];if(void 0!==l)return l.exports;var n=o[t]={exports:{}};return e[t](n,n.exports,r),n.exports}(()=>{const e=r(831);console.log("App started"),e.largeModule.doSomething()})()})(); -------------------------------------------------------------------------------- /7-typescript-and-the-build-process/challenge/dist/largeModule.31d6cfe0d16ae931b73cbundle.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinkedInLearning/advanced-typescript-concepts-5914414/761c50563fb48345d7e783124bf2709c88362a84/7-typescript-and-the-build-process/challenge/dist/largeModule.31d6cfe0d16ae931b73cbundle.js -------------------------------------------------------------------------------- /7-typescript-and-the-build-process/challenge/dist/main.bundle.js: -------------------------------------------------------------------------------- 1 | (()=>{"use strict";var e={859:function(e,t,r){var o=this&&this.__createBinding||(Object.create?function(e,t,r,o){void 0===o&&(o=r);var n=Object.getOwnPropertyDescriptor(t,r);n&&!("get"in n?!t.__esModule:n.writable||n.configurable)||(n={enumerable:!0,get:function(){return t[r]}}),Object.defineProperty(e,o,n)}:function(e,t,r,o){void 0===o&&(o=r),e[o]=t[r]}),n=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),i=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var r in e)"default"!==r&&Object.prototype.hasOwnProperty.call(e,r)&&o(t,e,r);return n(t,e),t};console.log("App started"),Promise.resolve().then((()=>i(r(831)))).then((e=>{e.largeModule.doSomething()}))},831:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.largeModule=void 0,t.largeModule={doSomething:()=>console.log("Doing something")}}},t={};!function r(o){var n=t[o];if(void 0!==n)return n.exports;var i=t[o]={exports:{}};return e[o].call(i.exports,i,i.exports,r),i.exports}(859)})(); -------------------------------------------------------------------------------- /7-typescript-and-the-build-process/challenge/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "optimized-ts-app", 3 | "version": "1.0.0", 4 | "description": "An optimized TypeScript application", 5 | "main": "dist/bundle.js", 6 | "scripts": { 7 | "build": "webpack --config webpack.config.js", 8 | "start": "node dist/bundle.js" 9 | }, 10 | "author": "Your Name", 11 | "license": "MIT", 12 | "devDependencies": { 13 | "compression-webpack-plugin": "^10.0.0", 14 | "ts-loader": "^9.2.6", 15 | "typescript": "^5.1.3", 16 | "webpack": "^5.76.0", 17 | "webpack-cli": "^5.0.1" 18 | }, 19 | "dependencies": {} 20 | } -------------------------------------------------------------------------------- /7-typescript-and-the-build-process/challenge/src/app.ts: -------------------------------------------------------------------------------- 1 | import { largeModule } from './largeModule'; 2 | //import { unusedModule } from './unusedModule'; 3 | 4 | console.log('App started'); 5 | largeModule.doSomething(); 6 | -------------------------------------------------------------------------------- /7-typescript-and-the-build-process/challenge/src/largeModule.ts: -------------------------------------------------------------------------------- 1 | export const largeModule = { 2 | doSomething: () => console.log('Doing something') 3 | }; 4 | -------------------------------------------------------------------------------- /7-typescript-and-the-build-process/challenge/src/unusedModule.ts: -------------------------------------------------------------------------------- 1 | export const unusedModule = { 2 | doNothing: () => console.log('Doing nothing') 3 | }; 4 | 5 | -------------------------------------------------------------------------------- /7-typescript-and-the-build-process/challenge/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Visit https://aka.ms/tsconfig to read more about this file */ 4 | 5 | /* Projects */ 6 | // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ 7 | // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ 8 | // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ 9 | // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ 10 | // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ 11 | // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ 12 | 13 | /* Language and Environment */ 14 | "target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ 15 | // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ 16 | // "jsx": "preserve", /* Specify what JSX code is generated. */ 17 | // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */ 18 | // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ 19 | // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ 20 | // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ 21 | // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ 22 | // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ 23 | // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ 24 | // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ 25 | // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ 26 | 27 | /* Modules */ 28 | "module": "commonjs", /* Specify what module code is generated. */ 29 | // "rootDir": "./", /* Specify the root folder within your source files. */ 30 | // "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */ 31 | // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ 32 | // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ 33 | // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ 34 | // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ 35 | // "types": [], /* Specify type package names to be included without being referenced in a source file. */ 36 | // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ 37 | // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ 38 | // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ 39 | // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ 40 | // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ 41 | // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ 42 | // "resolveJsonModule": true, /* Enable importing .json files. */ 43 | // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ 44 | // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ 45 | 46 | /* JavaScript Support */ 47 | // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ 48 | // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ 49 | // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ 50 | 51 | /* Emit */ 52 | // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ 53 | // "declarationMap": true, /* Create sourcemaps for d.ts files. */ 54 | // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ 55 | // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ 56 | // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ 57 | // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ 58 | // "outDir": "./", /* Specify an output folder for all emitted files. */ 59 | // "removeComments": true, /* Disable emitting comments. */ 60 | // "noEmit": true, /* Disable emitting files from a compilation. */ 61 | // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ 62 | // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */ 63 | // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ 64 | // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ 65 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ 66 | // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ 67 | // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ 68 | // "newLine": "crlf", /* Set the newline character for emitting files. */ 69 | // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ 70 | // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ 71 | // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ 72 | // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ 73 | // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ 74 | // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ 75 | 76 | /* Interop Constraints */ 77 | // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ 78 | // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */ 79 | // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ 80 | "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ 81 | // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ 82 | "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ 83 | 84 | /* Type Checking */ 85 | "strict": true, /* Enable all strict type-checking options. */ 86 | // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ 87 | // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ 88 | // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ 89 | // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ 90 | // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ 91 | // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ 92 | // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ 93 | // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ 94 | // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ 95 | // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ 96 | // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ 97 | // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ 98 | // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ 99 | // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ 100 | // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ 101 | // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ 102 | // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ 103 | // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ 104 | 105 | /* Completeness */ 106 | // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ 107 | "skipLibCheck": true /* Skip type checking all .d.ts files. */ 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /7-typescript-and-the-build-process/challenge/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const CompressionPlugin = require('compression-webpack-plugin'); 3 | 4 | module.exports = { 5 | mode: 'production', // Enable production mode 6 | entry: './src/app.ts', 7 | output: { 8 | filename: 'bundle.js', 9 | path: path.resolve(__dirname, 'dist') 10 | }, 11 | module: { 12 | rules: [ 13 | { 14 | test: /\.tsx?$/, 15 | use: 'ts-loader', 16 | exclude: /node_modules/ 17 | } 18 | ] 19 | }, 20 | resolve: { 21 | extensions: ['.tsx', '.ts', '.js'] 22 | }, 23 | optimization: { 24 | splitChunks: { 25 | chunks: 'all', // Enable code splitting 26 | } 27 | }, 28 | plugins: [ 29 | new CompressionPlugin({ 30 | algorithm: 'gzip', 31 | test: /\.js$|\.css$|\.html$/, 32 | threshold: 10240, 33 | minRatio: 0.8 34 | }) 35 | ] 36 | }; 37 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | 2 | Contribution Agreement 3 | ====================== 4 | 5 | This repository does not accept pull requests (PRs). All pull requests will be closed. 6 | 7 | However, if any contributions (through pull requests, issues, feedback or otherwise) are provided, as a contributor, you represent that the code you submit is your original work or that of your employer (in which case you represent you have the right to bind your employer). By submitting code (or otherwise providing feedback), you (and, if applicable, your employer) are licensing the submitted code (and/or feedback) to LinkedIn and the open source community subject to the BSD 2-Clause license. 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | LinkedIn Learning Exercise Files License Agreement 2 | ================================================== 3 | 4 | This License Agreement (the "Agreement") is a binding legal agreement 5 | between you (as an individual or entity, as applicable) and LinkedIn 6 | Corporation (“LinkedIn”). By downloading or using the LinkedIn Learning 7 | exercise files in this repository (“Licensed Materials”), you agree to 8 | be bound by the terms of this Agreement. If you do not agree to these 9 | terms, do not download or use the Licensed Materials. 10 | 11 | 1. License. 12 | - a. Subject to the terms of this Agreement, LinkedIn hereby grants LinkedIn 13 | members during their LinkedIn Learning subscription a non-exclusive, 14 | non-transferable copyright license, for internal use only, to 1) make a 15 | reasonable number of copies of the Licensed Materials, and 2) make 16 | derivative works of the Licensed Materials for the sole purpose of 17 | practicing skills taught in LinkedIn Learning courses. 18 | - b. Distribution. Unless otherwise noted in the Licensed Materials, subject 19 | to the terms of this Agreement, LinkedIn hereby grants LinkedIn members 20 | with a LinkedIn Learning subscription a non-exclusive, non-transferable 21 | copyright license to distribute the Licensed Materials, except the 22 | Licensed Materials may not be included in any product or service (or 23 | otherwise used) to instruct or educate others. 24 | 25 | 2. Restrictions and Intellectual Property. 26 | - a. You may not to use, modify, copy, make derivative works of, publish, 27 | distribute, rent, lease, sell, sublicense, assign or otherwise transfer the 28 | Licensed Materials, except as expressly set forth above in Section 1. 29 | - b. Linkedin (and its licensors) retains its intellectual property rights 30 | in the Licensed Materials. Except as expressly set forth in Section 1, 31 | LinkedIn grants no licenses. 32 | - c. You indemnify LinkedIn and its licensors and affiliates for i) any 33 | alleged infringement or misappropriation of any intellectual property rights 34 | of any third party based on modifications you make to the Licensed Materials, 35 | ii) any claims arising from your use or distribution of all or part of the 36 | Licensed Materials and iii) a breach of this Agreement. You will defend, hold 37 | harmless, and indemnify LinkedIn and its affiliates (and our and their 38 | respective employees, shareholders, and directors) from any claim or action 39 | brought by a third party, including all damages, liabilities, costs and 40 | expenses, including reasonable attorneys’ fees, to the extent resulting from, 41 | alleged to have resulted from, or in connection with: (a) your breach of your 42 | obligations herein; or (b) your use or distribution of any Licensed Materials. 43 | 44 | 3. Open source. This code may include open source software, which may be 45 | subject to other license terms as provided in the files. 46 | 47 | 4. Warranty Disclaimer. LINKEDIN PROVIDES THE LICENSED MATERIALS ON AN “AS IS” 48 | AND “AS AVAILABLE” BASIS. LINKEDIN MAKES NO REPRESENTATION OR WARRANTY, 49 | WHETHER EXPRESS OR IMPLIED, ABOUT THE LICENSED MATERIALS, INCLUDING ANY 50 | REPRESENTATION THAT THE LICENSED MATERIALS WILL BE FREE OF ERRORS, BUGS OR 51 | INTERRUPTIONS, OR THAT THE LICENSED MATERIALS ARE ACCURATE, COMPLETE OR 52 | OTHERWISE VALID. TO THE FULLEST EXTENT PERMITTED BY LAW, LINKEDIN AND ITS 53 | AFFILIATES DISCLAIM ANY IMPLIED OR STATUTORY WARRANTY OR CONDITION, INCLUDING 54 | ANY IMPLIED WARRANTY OR CONDITION OF MERCHANTABILITY OR FITNESS FOR A 55 | PARTICULAR PURPOSE, AVAILABILITY, SECURITY, TITLE AND/OR NON-INFRINGEMENT. 56 | YOUR USE OF THE LICENSED MATERIALS IS AT YOUR OWN DISCRETION AND RISK, AND 57 | YOU WILL BE SOLELY RESPONSIBLE FOR ANY DAMAGE THAT RESULTS FROM USE OF THE 58 | LICENSED MATERIALS TO YOUR COMPUTER SYSTEM OR LOSS OF DATA. NO ADVICE OR 59 | INFORMATION, WHETHER ORAL OR WRITTEN, OBTAINED BY YOU FROM US OR THROUGH OR 60 | FROM THE LICENSED MATERIALS WILL CREATE ANY WARRANTY OR CONDITION NOT 61 | EXPRESSLY STATED IN THESE TERMS. 62 | 63 | 5. Limitation of Liability. LINKEDIN SHALL NOT BE LIABLE FOR ANY INDIRECT, 64 | INCIDENTAL, SPECIAL, PUNITIVE, CONSEQUENTIAL OR EXEMPLARY DAMAGES, INCLUDING 65 | BUT NOT LIMITED TO, DAMAGES FOR LOSS OF PROFITS, GOODWILL, USE, DATA OR OTHER 66 | INTANGIBLE LOSSES . IN NO EVENT WILL LINKEDIN'S AGGREGATE LIABILITY TO YOU 67 | EXCEED $100. THIS LIMITATION OF LIABILITY SHALL: 68 | - i. APPLY REGARDLESS OF WHETHER (A) YOU BASE YOUR CLAIM ON CONTRACT, TORT, 69 | STATUTE, OR ANY OTHER LEGAL THEORY, (B) WE KNEW OR SHOULD HAVE KNOWN ABOUT 70 | THE POSSIBILITY OF SUCH DAMAGES, OR (C) THE LIMITED REMEDIES PROVIDED IN THIS 71 | SECTION FAIL OF THEIR ESSENTIAL PURPOSE; AND 72 | - ii. NOT APPLY TO ANY DAMAGE THAT LINKEDIN MAY CAUSE YOU INTENTIONALLY OR 73 | KNOWINGLY IN VIOLATION OF THESE TERMS OR APPLICABLE LAW, OR AS OTHERWISE 74 | MANDATED BY APPLICABLE LAW THAT CANNOT BE DISCLAIMED IN THESE TERMS. 75 | 76 | 6. Termination. This Agreement automatically terminates upon your breach of 77 | this Agreement or termination of your LinkedIn Learning subscription. On 78 | termination, all licenses granted under this Agreement will terminate 79 | immediately and you will delete the Licensed Materials. Sections 2-7 of this 80 | Agreement survive any termination of this Agreement. LinkedIn may discontinue 81 | the availability of some or all of the Licensed Materials at any time for any 82 | reason. 83 | 84 | 7. Miscellaneous. This Agreement will be governed by and construed in 85 | accordance with the laws of the State of California without regard to conflict 86 | of laws principles. The exclusive forum for any disputes arising out of or 87 | relating to this Agreement shall be an appropriate federal or state court 88 | sitting in the County of Santa Clara, State of California. If LinkedIn does 89 | not act to enforce a breach of this Agreement, that does not mean that 90 | LinkedIn has waived its right to enforce this Agreement. The Agreement does 91 | not create a partnership, agency relationship, or joint venture between the 92 | parties. Neither party has the power or authority to bind the other or to 93 | create any obligation or responsibility on behalf of the other. You may not, 94 | without LinkedIn’s prior written consent, assign or delegate any rights or 95 | obligations under these terms, including in connection with a change of 96 | control. Any purported assignment and delegation shall be ineffective. The 97 | Agreement shall bind and inure to the benefit of the parties, their respective 98 | successors and permitted assigns. If any provision of the Agreement is 99 | unenforceable, that provision will be modified to render it enforceable to the 100 | extent possible to give effect to the parties’ intentions and the remaining 101 | provisions will not be affected. This Agreement is the only agreement between 102 | you and LinkedIn regarding the Licensed Materials, and supersedes all prior 103 | agreements relating to the Licensed Materials. 104 | 105 | Last Updated: March 2019 106 | -------------------------------------------------------------------------------- /NOTICE: -------------------------------------------------------------------------------- 1 | Copyright 2024 LinkedIn Corporation 2 | All Rights Reserved. 3 | 4 | Licensed under the LinkedIn Learning Exercise File License (the "License"). 5 | See LICENSE in the project root for license information. 6 | 7 | ATTRIBUTIONS: 8 | 9 | Typescript 10 | https://github.com/microsoft/TypeScript/ 11 | License: Apache 2.0 12 | http://www.apache.org/licenses/ 13 | 14 | Please note, this project may automatically load third party code from external 15 | repositories (for example, NPM modules, Composer packages, or other dependencies). 16 | If so, such third party code may be subject to other license terms than as set 17 | forth above. In addition, such third party code may also depend on and load 18 | multiple tiers of dependencies. Please review the applicable licenses of the 19 | additional dependencies. 20 | 21 | =-=-=-=-=-=-=-=-=-=-=- 22 | 23 | "Apache License 24 | 25 | Version 2.0, January 2004 26 | 27 | http://www.apache.org/licenses/ 28 | 29 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 30 | 31 | 1. Definitions. 32 | 33 | ""License"" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. 34 | 35 | ""Licensor"" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. 36 | 37 | ""Legal Entity"" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, ""control"" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. 38 | 39 | ""You"" (or ""Your"") shall mean an individual or Legal Entity exercising permissions granted by this License. 40 | 41 | ""Source"" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. 42 | 43 | ""Object"" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. 44 | 45 | ""Work"" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). 46 | 47 | ""Derivative Works"" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. 48 | 49 | ""Contribution"" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, ""submitted"" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as ""Not a Contribution."" 50 | 51 | ""Contributor"" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 52 | 53 | 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 54 | 55 | 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 56 | 57 | 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: 58 | 59 | You must give any other recipients of the Work or Derivative Works a copy of this License; and 60 | 61 | You must cause any modified files to carry prominent notices stating that You changed the files; and 62 | 63 | You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and 64 | 65 | If the Work includes a ""NOTICE"" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 66 | 67 | 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 68 | 69 | 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 70 | 71 | 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an ""AS IS"" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 72 | 73 | 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 74 | 75 | 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. 76 | 77 | END OF TERMS AND CONDITIONS" 78 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Advanced TypeScript Concepts 2 | This is the repository for the LinkedIn Learning course `Advanced TypeScript Concepts`. The full course is available from [LinkedIn Learning][lil-course-url]. 3 | 4 | ![lil-thumbnail-url] 5 | 6 |

As TypeScript becomes increasingly important in both front-end and back-end development, understanding how to use its advanced features is quickly turning into an essential skill. Are you ready to take your skills to the next level to start writing better, faster, cleaner code? Join tech educator and developer Maaike van Putten as she shows you how to leverage the full power of TypeScript, going beyond its basic syntax and common usage. Maaike offers an in-depth exploration of several advanced concepts, including generics, advanced types, function overloading, sophisticated type manipulation, advanced modularization techniques, decorators and metadata, and build tool integration and optimization. By the end of this course, you’ll be equipped with the skills and know-how required to start writing code in TypeScript with an expert-level proficiency.

This course is integrated with GitHub Codespaces, an instant cloud developer environment that offers all the functionality of your favorite IDE without the need for any local machine setup. With GitHub Codespaces, you can get hands-on practice from any machine, at any time-all while using a tool that you'll likely encounter in the workplace. Check out the "How to use Codespaces" video to learn how to get started.

7 | 8 | _See the readme file in the main branch for updated instructions and information._ 9 | ## Instructions 10 | This repository has branches for each of the videos in the course. You can use the branch pop up menu in github to switch to a specific branch and take a look at the course at that stage, or you can add `/tree/BRANCH_NAME` to the URL to go to the branch you want to access. 11 | 12 | ## Branches 13 | The branches are structured to correspond to the videos in the course. The naming convention is `CHAPTER#_MOVIE#`. As an example, the branch named `02_03` corresponds to the second chapter and the third video in that chapter. 14 | Some branches will have a beginning and an end state. These are marked with the letters `b` for "beginning" and `e` for "end". The `b` branch contains the code as it is at the beginning of the movie. The `e` branch contains the code as it is at the end of the movie. The `main` branch holds the final state of the code when in the course. 15 | 16 | When switching from one exercise files branch to the next after making changes to the files, you may get a message like this: 17 | 18 | error: Your local changes to the following files would be overwritten by checkout: [files] 19 | Please commit your changes or stash them before you switch branches. 20 | Aborting 21 | 22 | To resolve this issue: 23 | 24 | Add changes to git using this command: git add . 25 | Commit changes using this command: git commit -m "some message" 26 | 27 | ### Instructor 28 | 29 | Maaike van Putten 30 | 31 | Trainer and Developer for Java, Python, Spring Boot, and More 32 | 33 | 34 | 35 | Check out my other courses on [LinkedIn Learning](https://www.linkedin.com/learning/instructors/maaike-van-putten?u=104). 36 | 37 | 38 | [0]: # (Replace these placeholder URLs with actual course URLs) 39 | 40 | [lil-course-url]: https://www.linkedin.com/learning/advanced-typescript-concepts 41 | [lil-thumbnail-url]: https://media.licdn.com/dms/image/D560DAQFc5eVY1zlhsw/learning-public-crop_675_1200/0/1722623856336?e=2147483647&v=beta&t=ICCTPv87mJ6Yn_HHDXOw1NGc0M63vI_eCEwUf3Bs5Co 42 | 43 | -------------------------------------------------------------------------------- /favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinkedInLearning/advanced-typescript-concepts-5914414/761c50563fb48345d7e783124bf2709c88362a84/favicon.ico --------------------------------------------------------------------------------