├── .github
└── workflows
│ ├── renovate-checks.yml
│ └── section-repos.yml
├── .gitignore
├── .vscode
└── settings.json
├── LICENSE.md
├── README.md
├── book-content
├── chapters
│ ├── 01-setup-typescript.md
│ ├── 02-ide-superpowers.md
│ ├── 03-typescript-in-the-development-pipeline.md
│ ├── 04-essential-types-and-annotations.md
│ ├── 05-unions-literals-and-narrowing.md
│ ├── 06-objects.md
│ ├── 07-mutability.md
│ ├── 08-classes.md
│ ├── 09-typescript-only-features.md
│ ├── 10-deriving-types.md
│ ├── 11-annotations-and-assertions.md
│ ├── 12-the-weird-parts.md
│ ├── 13-modules-scripts-declaration-files.md
│ ├── 14-configuring-typescript.md
│ ├── 15-designing-your-types.md
│ └── 16-the-utils-folder.md
├── formatter
│ ├── format.ts
│ ├── package.json
│ └── tsconfig.json
├── fragments.md
├── preview-01.md
└── readme.md
├── package.json
├── pnpm-lock.yaml
├── renovate.json
├── src
├── 005-kickstart-your-typescript-setup
│ ├── 001-typescript-vs-javascript.explainer.ts
│ ├── 002-how-typescript-works.explainer.png
│ ├── 002-how-typescript-works.explainer.svg
│ ├── 002-how-typescript-works.explainer.ts
│ ├── 003-tools-needed.explainer.png
│ ├── 003-tools-needed.explainer.ts
│ ├── 004-set-up-node-js-and-vscode.explainer.ts
│ ├── 005-set-up-npm-and-pnpm.explainer.png
│ ├── 005-set-up-npm-and-pnpm.explainer.ts
│ ├── 006-vscode-extension.explainer.ts
│ └── workshop.md
├── 010-typescript-in-the-build-process
│ ├── 010-typescript-in-the-browser.problem
│ │ ├── example.ts
│ │ ├── index.html
│ │ └── readme.md
│ ├── 010-typescript-in-the-browser.solution
│ │ ├── example.js
│ │ └── index.html
│ ├── 011-compile-typescript-to-javascript.problem
│ │ ├── example.ts
│ │ ├── index.html
│ │ └── readme.md
│ ├── 011-compile-typescript-to-javascript.solution
│ │ ├── .gitignore
│ │ ├── example.ts
│ │ ├── index.html
│ │ └── tsconfig.json
│ ├── 012-tsc-watch-mode.problem
│ │ ├── .gitignore
│ │ ├── example.ts
│ │ ├── index.html
│ │ ├── readme.md
│ │ └── tsconfig.json
│ ├── 012-tsc-watch-mode.solution
│ │ ├── .gitignore
│ │ ├── example.ts
│ │ ├── index.html
│ │ └── tsconfig.json
│ ├── 013-compiling-to-a-directory.problem
│ │ ├── .gitignore
│ │ ├── example.ts
│ │ ├── index.html
│ │ ├── readme.md
│ │ └── tsconfig.json
│ ├── 013-compiling-to-a-directory.solution
│ │ ├── .gitignore
│ │ ├── example.ts
│ │ ├── index.html
│ │ └── tsconfig.json
│ ├── 014-setting-up-a-frontend-app-with-vite.problem
│ │ ├── .gitignore
│ │ ├── example.ts
│ │ ├── index.html
│ │ ├── readme.md
│ │ └── tsconfig.json
│ ├── 014-setting-up-a-frontend-app-with-vite.solution
│ │ ├── .gitignore
│ │ ├── index.html
│ │ ├── package.json
│ │ ├── pnpm-lock.yaml
│ │ ├── public
│ │ │ └── vite.svg
│ │ ├── src
│ │ │ ├── counter.ts
│ │ │ ├── main.ts
│ │ │ ├── style.css
│ │ │ ├── typescript.svg
│ │ │ └── vite-env.d.ts
│ │ └── tsconfig.json
│ ├── 015-typescript-as-a-linter.problem
│ │ ├── .gitignore
│ │ ├── index.html
│ │ ├── package.json
│ │ ├── pnpm-lock.yaml
│ │ ├── public
│ │ │ └── vite.svg
│ │ ├── readme.md
│ │ ├── src
│ │ │ ├── counter.ts
│ │ │ ├── main.ts
│ │ │ ├── style.css
│ │ │ ├── typescript.svg
│ │ │ └── vite-env.d.ts
│ │ └── tsconfig.json
│ ├── 015-typescript-as-a-linter.solution
│ │ ├── .gitignore
│ │ ├── index.html
│ │ ├── package.json
│ │ ├── pnpm-lock.yaml
│ │ ├── public
│ │ │ └── vite.svg
│ │ ├── src
│ │ │ ├── counter.ts
│ │ │ ├── main.ts
│ │ │ ├── style.css
│ │ │ ├── typescript.svg
│ │ │ └── vite-env.d.ts
│ │ └── tsconfig.json
│ ├── 016-typescript-on-ci.explainer
│ │ ├── .github
│ │ │ └── workflows
│ │ │ │ └── ci.yml
│ │ ├── .gitignore
│ │ ├── index.html
│ │ ├── package.json
│ │ ├── pnpm-lock.yaml
│ │ ├── public
│ │ │ └── vite.svg
│ │ ├── readme.md
│ │ ├── src
│ │ │ ├── counter.ts
│ │ │ ├── main.ts
│ │ │ ├── style.css
│ │ │ ├── typescript.svg
│ │ │ └── vite-env.d.ts
│ │ └── tsconfig.json
│ ├── 017-blocking-your-dev-server-with-typescript.explainer.1
│ │ ├── .gitignore
│ │ ├── index.html
│ │ ├── package.json
│ │ ├── pnpm-lock.yaml
│ │ ├── public
│ │ │ └── vite.svg
│ │ ├── readme.md
│ │ ├── src
│ │ │ ├── counter.ts
│ │ │ ├── main.ts
│ │ │ ├── style.css
│ │ │ ├── typescript.svg
│ │ │ └── vite-env.d.ts
│ │ └── tsconfig.json
│ ├── 017-blocking-your-dev-server-with-typescript.explainer.2
│ │ ├── .gitignore
│ │ ├── index.html
│ │ ├── package.json
│ │ ├── pnpm-lock.yaml
│ │ ├── public
│ │ │ └── vite.svg
│ │ ├── src
│ │ │ ├── counter.ts
│ │ │ ├── main.ts
│ │ │ ├── style.css
│ │ │ ├── typescript.svg
│ │ │ └── vite-env.d.ts
│ │ ├── tsconfig.json
│ │ └── vite.config.js
│ ├── 017-blocking-your-dev-server-with-typescript.explainer.3
│ │ ├── .gitignore
│ │ ├── index.html
│ │ ├── package.json
│ │ ├── pnpm-lock.yaml
│ │ ├── public
│ │ │ └── vite.svg
│ │ ├── src
│ │ │ ├── counter.ts
│ │ │ ├── main.ts
│ │ │ ├── style.css
│ │ │ ├── typescript.svg
│ │ │ └── vite-env.d.ts
│ │ └── tsconfig.json
│ └── 019-using-tsx-to-create-quick-scripts.explainer
│ │ ├── .gitignore
│ │ ├── index.html
│ │ ├── package.json
│ │ ├── pnpm-lock.yaml
│ │ ├── public
│ │ └── vite.svg
│ │ ├── scripts
│ │ └── doSomething.ts
│ │ ├── src
│ │ ├── counter.ts
│ │ ├── main.ts
│ │ ├── style.css
│ │ ├── typescript.svg
│ │ └── vite-env.d.ts
│ │ └── tsconfig.json
├── 015-essential-types-and-annotations
│ ├── 020-basic-types-with-function-parameters.problem.ts
│ ├── 020-basic-types-with-function-parameters.solution.ts
│ ├── 021-annotating-empty-parameters.problem.ts
│ ├── 021-annotating-empty-parameters.solution.ts
│ ├── 022-all-types.problem.ts
│ ├── 022-all-types.solution.1.ts
│ ├── 022-all-types.solution.2.ts
│ ├── 023-optional-function-parameters.problem.ts
│ ├── 023-optional-function-parameters.solution.ts
│ ├── 024-default-parameters.problem.ts
│ ├── 024-default-parameters.solution.ts
│ ├── 025-object-literal-types.problem.ts
│ ├── 025-object-literal-types.solution.ts
│ ├── 026-optional-property-types.problem.ts
│ ├── 026-optional-property-types.solution.ts
│ ├── 027-type-keyword.problem.ts
│ ├── 027-type-keyword.solution.1.ts
│ ├── 027-type-keyword.solution.2.ts
│ ├── 027-type-keyword.solution.3.ts
│ ├── 028-arrays.problem.ts
│ ├── 028-arrays.solution.1.ts
│ ├── 028-arrays.solution.2.ts
│ ├── 029-arrays-of-objects.problem.ts
│ ├── 029-arrays-of-objects.solution.1.ts
│ ├── 029-arrays-of-objects.solution.2.ts
│ ├── 029-arrays-of-objects.solution.3.ts
│ ├── 029-arrays-of-objects.solution.4.ts
│ ├── 030-rest-parameters-of-functions.problem.ts
│ ├── 030-rest-parameters-of-functions.solution.1.ts
│ ├── 030-rest-parameters-of-functions.solution.2.ts
│ ├── 031-tuples.problem.ts
│ ├── 031-tuples.solution.1.ts
│ ├── 031-tuples.solution.2.ts
│ ├── 032-optional-members-of-tuples.problem.ts
│ ├── 032-optional-members-of-tuples.solution.1.ts
│ ├── 032-optional-members-of-tuples.solution.2.ts
│ ├── 032.5-any.problem.ts
│ ├── 032.5-any.solution.ts
│ ├── 033-function-types.problem.ts
│ ├── 033-function-types.solution.ts
│ ├── 034-functions-returning-void.problem.ts
│ ├── 034-functions-returning-void.solution.ts
│ ├── 034.5-void-vs-undefined.problem.ts
│ ├── 034.5-void-vs-undefined.solution.ts
│ ├── 035-pass-types-to-set.problem.ts
│ ├── 035-pass-types-to-set.solution.1.ts
│ ├── 035-pass-types-to-set.solution.2.ts
│ ├── 036-pass-types-to-map.problem.ts
│ ├── 036-pass-types-to-map.solution.1.ts
│ ├── 036-pass-types-to-map.solution.2.ts
│ ├── 036-pass-types-to-map.solution.3.ts
│ ├── 036-pass-types-to-map.solution.4.ts
│ ├── 037-json-parse-cant-receive-type-arguments.problem.ts
│ ├── 037-json-parse-cant-receive-type-arguments.solution.ts
│ ├── 038-type-async-functions.problem.ts
│ ├── 038-type-async-functions.solution.1.ts
│ ├── 038-type-async-functions.solution.2.ts
│ └── workshop.md
├── 016.5-ide-superpowers
│ ├── 039-understand-the-ts-server.explainer.svg
│ ├── 039-understand-the-ts-server.explainer.ts
│ ├── 040-understand-how-to-hover-a-variable-to-see-its-type.explainer.ts
│ ├── 041-hovering-a-function-call.problem.ts
│ ├── 041-hovering-a-function-call.solution.ts
│ ├── 042-adding-tsdoc-comments-for-hovers.problem.ts
│ ├── 042-adding-tsdoc-comments-for-hovers.solution.ts
│ ├── 044-manually-triggering-autocomplete.problem.ts
│ ├── 044-manually-triggering-autocomplete.solution.ts
│ ├── 045-basics-of-errors.explainer.ts
│ ├── 046-go-to-definition.explainer.ts
│ ├── 047-rename-symbol.explainer.ts
│ ├── 048-auto-import.problem.ts
│ ├── 048-auto-import.solution.ts
│ ├── 049-organize-imports.problem.ts
│ ├── 049-organize-imports.solution.ts
│ ├── 050-refactor.problem.ts
│ ├── 050-refactor.solution.ts
│ ├── 051-prettier-format-on-save.explainer.ts
│ ├── 052-resetting-the-typescript-server.explainer.ts
│ ├── dummy-import-2.ts
│ └── dummy-import.ts
├── 018-unions-and-narrowing
│ ├── 053-introduction-to-unions.problem.ts
│ ├── 053-introduction-to-unions.solution.ts
│ ├── 053.5-unions-diagram.explainer.svg
│ ├── 054-literal-types.problem.ts
│ ├── 054-literal-types.solution.1.ts
│ ├── 054-literal-types.solution.2.ts
│ ├── 054.5-literal-type-assignability.explainer.svg
│ ├── 055-combining-unions.problem.ts
│ ├── 055-combining-unions.solution.ts
│ ├── 056-how-big-can-a-union-be.explainer.ts
│ ├── 057-literals-vs-wider-types.explainer.1.svg
│ ├── 057-literals-vs-wider-types.explainer.2.svg
│ ├── 057-literals-vs-wider-types.explainer.ts
│ ├── 058-narrowing-unions-with-typeof.explainer.ts
│ ├── 059-narrowing-with-if-statements.problem.ts
│ ├── 059-narrowing-with-if-statements.solution.1.svg
│ ├── 059-narrowing-with-if-statements.solution.1.ts
│ ├── 059-narrowing-with-if-statements.solution.2.ts
│ ├── 059-narrowing-with-if-statements.solution.3.ts
│ ├── 059-narrowing-with-if-statements.solution.4.ts
│ ├── 059-narrowing-with-if-statements.solution.5.ts
│ ├── 060-narrowing-with-boolean-wont-work.explainer.ts
│ ├── 061-map-has-doesnt-narrow-map-get.problem.ts
│ ├── 061-map-has-doesnt-narrow-map-get.solution.ts
│ ├── 062-throwing-errors-to-narrow.problem.ts
│ ├── 062-throwing-errors-to-narrow.solution.ts
│ ├── 064-narrowing-with-in-statements.problem.ts
│ ├── 064-narrowing-with-in-statements.solution.ts
│ ├── 065-introduction-to-unknown.explainer.svg
│ ├── 065-introduction-to-unknown.explainer.ts
│ ├── 065.5-narrowing-with-instanceof-statements.problem.ts
│ ├── 065.5-narrowing-with-instanceof-statements.solution.ts
│ ├── 066-narrowing-unknown-to-a-value.problem.ts
│ ├── 066-narrowing-unknown-to-a-value.solution.ts
│ ├── 067-introduction-to-never.explainer.svg
│ ├── 067-introduction-to-never.explainer.ts
│ ├── 067.5-never-array.problem.ts
│ ├── 067.5-never-array.solution.ts
│ ├── 068-returning-never-to-narrow.problem.ts
│ ├── 068-returning-never-to-narrow.solution.1.ts
│ ├── 068-returning-never-to-narrow.solution.2.ts
│ ├── 071-narrowing-in-different-scopes.problem.ts
│ ├── 071-narrowing-in-different-scopes.solution.ts
│ ├── 072.5-reusable-type-guards.problem.ts
│ ├── 072.5-reusable-type-guards.solution.ts
│ ├── 074-intro-to-discriminated-unions.problem.ts
│ ├── 074-intro-to-discriminated-unions.solution.ts
│ ├── 075-destructuring-a-discriminated-union.problem.ts
│ ├── 075-destructuring-a-discriminated-union.solution.ts
│ ├── 076-narrowing-a-discriminated-union-with-a-switch-statement.problem.ts
│ ├── 076-narrowing-a-discriminated-union-with-a-switch-statement.solution.ts
│ ├── 077-narrowing-with-switch-true.explainer.ts
│ ├── 078-destructuring-a-discriminated-tuple.problem.ts
│ ├── 078-destructuring-a-discriminated-tuple.solution.ts
│ ├── 079-discriminated-booleans.problem.ts
│ ├── 079-discriminated-booleans.solution.ts
│ ├── 080-adding-defaults-to-discriminated-union.problem.ts
│ ├── 080-adding-defaults-to-discriminated-union.solution.ts
│ ├── 080.5-should-you-provide-function-return-types.explainer.ts
│ └── workshop.md
├── 020-objects
│ ├── 081-extend-object-using-intersections.problem.ts
│ ├── 081-extend-object-using-intersections.solution.ts
│ ├── 082-extend-object-using-interfaces.problem.ts
│ ├── 082-extend-object-using-interfaces.solution.1.ts
│ ├── 082-extend-object-using-interfaces.solution.2.ts
│ ├── 082.5-extending-incompatible-properties.problem.ts
│ ├── 082.5-extending-incompatible-properties.solution.ts
│ ├── 083-compare-between-intersections-and-interfaces.explainer.ts
│ ├── 084-index-signatures.problem.ts
│ ├── 084-index-signatures.solution.1.ts
│ ├── 084-index-signatures.solution.2.ts
│ ├── 084-index-signatures.solution.3.ts
│ ├── 084-index-signatures.solution.4.ts
│ ├── 085-index-signatures-with-defined-keys.problem.ts
│ ├── 085-index-signatures-with-defined-keys.solution.1.ts
│ ├── 085-index-signatures-with-defined-keys.solution.2.ts
│ ├── 086-property-key-type.problem.ts
│ ├── 086-property-key-type.solution.ts
│ ├── 086.5-object-type.explainer.ts
│ ├── 087-record-type-with-union-as-keys.problem.ts
│ ├── 087-record-type-with-union-as-keys.solution.1.ts
│ ├── 087-record-type-with-union-as-keys.solution.2.ts
│ ├── 088-declaration-merging-of-interfaces.problem.ts
│ ├── 088-declaration-merging-of-interfaces.solution.ts
│ ├── 089-pick-type-helper.problem.ts
│ ├── 089-pick-type-helper.solution.1.ts
│ ├── 089-pick-type-helper.solution.2.ts
│ ├── 091-omit-type-helper.problem.ts
│ ├── 091-omit-type-helper.solution.1.ts
│ ├── 091-omit-type-helper.solution.2.ts
│ ├── 092-no-autocomplete-on-omit.explainer.ts
│ ├── 093-omit-cant-distribute.explainer.1.ts
│ ├── 093-omit-cant-distribute.explainer.2.ts
│ ├── 095-partial-type-helper.problem.ts
│ ├── 095-partial-type-helper.solution.ts
│ ├── 096-required-type-helper.explainer.ts
│ ├── 096.5-common-keys-of-unions-of-objects.problem.ts
│ ├── 096.5-common-keys-of-unions-of-objects.solution.ts
│ └── workshop.md
├── 028-mutability
│ ├── 097-let-and-const-inference.problem.ts
│ ├── 097-let-and-const-inference.solution.1.ts
│ ├── 097-let-and-const-inference.solution.2.ts
│ ├── 098-object-property-inference.problem.ts
│ ├── 098-object-property-inference.solution.ts
│ ├── 099-readonly-object-properties.problem.ts
│ ├── 099-readonly-object-properties.solution.ts
│ ├── 100-readonly-type-helper.problem.ts
│ ├── 100-readonly-type-helper.solution.ts
│ ├── 101-intro-to-as-const.problem.ts
│ ├── 101-intro-to-as-const.solution.ts
│ ├── 102-as-const-vs-object-freeze.problem.ts
│ ├── 102-as-const-vs-object-freeze.solution.ts
│ ├── 103-readonly-arrays.problem.ts
│ ├── 103-readonly-arrays.solution.1.ts
│ ├── 103-readonly-arrays.solution.2.ts
│ ├── 104-readonly-arrays-assignability-to-mutable-arrays.explainer.ts
│ ├── 104.5-fixing-unsafe-tuples.problem.ts
│ ├── 104.5-fixing-unsafe-tuples.solution.ts
│ ├── 105-includes-on-readonly-arrays.explainer.ts
│ ├── 106-as-const-to-make-functions-infer-a-tuple.problem.ts
│ ├── 106-as-const-to-make-functions-infer-a-tuple.solution.1.ts
│ ├── 106-as-const-to-make-functions-infer-a-tuple.solution.2.ts
│ ├── 107-as-const-can-make-strings-infer-as-their-literals-in-objects.explainer.ts
│ └── workshop.md
├── 030-classes
│ ├── 108-understand-classes.problem.ts
│ ├── 108-understand-classes.solution.1.ts
│ ├── 108-understand-classes.solution.2.ts
│ ├── 109-class-methods.problem.ts
│ ├── 109-class-methods.solution.1.ts
│ ├── 109-class-methods.solution.2.ts
│ ├── 110-receiving-arguments-to-constructor.problem.ts
│ ├── 110-receiving-arguments-to-constructor.solution.1.ts
│ ├── 110-receiving-arguments-to-constructor.solution.2.ts
│ ├── 111-getters.problem.ts
│ ├── 111-getters.solution.ts
│ ├── 112-public-and-private-properties.problem.ts
│ ├── 112-public-and-private-properties.solution.1.ts
│ ├── 112-public-and-private-properties.solution.2.ts
│ ├── 113-setters.problem.ts
│ ├── 113-setters.solution.ts
│ ├── 114-extending-other-classes.problem.ts
│ ├── 114-extending-other-classes.solution.ts
│ ├── 115-implementing-interfaces-or-types.problem.ts
│ ├── 115-implementing-interfaces-or-types.solution.1.ts
│ ├── 115-implementing-interfaces-or-types.solution.2.ts
│ ├── 116-this-in-functions-and-objects.problem.ts
│ ├── 116-this-in-functions-and-objects.solution.ts
│ └── workshop.md
├── 032-typescript-only-features
│ ├── 116.5-intro.explainer.ts
│ ├── 117-parameter-properties.explainer.ts
│ ├── 118-enums.problem.ts
│ ├── 118-enums.solution.1.ts
│ ├── 118-enums.solution.2.ts
│ ├── 119-string-enums.problem.ts
│ ├── 119-string-enums.solution.ts
│ ├── 120-const-enums.explainer
│ │ ├── index.ts
│ │ ├── package.json
│ │ └── tsconfig.json
│ ├── 121-namespaces.explainer.ts
│ ├── 122-namespaces-can-declaration-merge.explainer.ts
│ ├── 123-interfaces-within-namespaces-can-declaration-merge.explainer.ts
│ ├── 124-prefer-es-features-to-ts-features.explainer
│ │ ├── index.ts
│ │ ├── package.json
│ │ └── tsconfig.json
│ └── workshop.md
├── 040-deriving-types-from-values
│ ├── 124.5-intro.explainer.ts
│ ├── 125-keyof.problem.ts
│ ├── 125-keyof.solution.ts
│ ├── 126-typeof-keyword.problem.ts
│ ├── 126-typeof-keyword.solution.1.ts
│ ├── 126-typeof-keyword.solution.2.ts
│ ├── 128-create-runtime-values-from-types.explainer.ts
│ ├── 129-classes-cross-value-and-type-world.problem.ts
│ ├── 129-classes-cross-value-and-type-world.solution.ts
│ ├── 129.5-enums-cross-value-and-type-world.explainer.ts
│ ├── 130-this-crosses-value-and-type-world.explainer.ts
│ ├── 131-naming-values-and-types-the-same.explainer.1.ts
│ ├── 131-naming-values-and-types-the-same.explainer.2.ts
│ ├── 132-parameters-type-helper.problem.ts
│ ├── 132-parameters-type-helper.solution.ts
│ ├── 133-return-type.problem.ts
│ ├── 133-return-type.solution.ts
│ ├── 134-awaited-type-helper.problem.ts
│ ├── 134-awaited-type-helper.solution.ts
│ ├── 135-indexed-access-types.problem.ts
│ ├── 135-indexed-access-types.solution.ts
│ ├── 136-pass-unions-to-indexed-access-types.problem.ts
│ ├── 136-pass-unions-to-indexed-access-types.solution.ts
│ ├── 137-pass-keyof-into-an-indexed-access-type.problem.ts
│ ├── 137-pass-keyof-into-an-indexed-access-type.solution.1.ts
│ ├── 137-pass-keyof-into-an-indexed-access-type.solution.2.ts
│ ├── 138-create-a-union-from-an-as-const-array.problem.ts
│ ├── 138-create-a-union-from-an-as-const-array.solution.ts
│ └── workshop.md
├── 045-annotations-and-assertions
│ ├── 139-dont-annotate-too-much.problem.ts
│ ├── 139-dont-annotate-too-much.solution.ts
│ ├── 141-as-and-as-any.problem.ts
│ ├── 141-as-and-as-any.solution.1.ts
│ ├── 141-as-and-as-any.solution.2.ts
│ ├── 142-global-typings-use-any.problem.ts
│ ├── 142-global-typings-use-any.solution.1.ts
│ ├── 142-global-typings-use-any.solution.2.ts
│ ├── 143-limits-of-as.explainer.ts
│ ├── 143.5-non-null-assertions.problem.ts
│ ├── 143.5-non-null-assertions.solution.ts
│ ├── 144-ts-ignore.explainer.1.ts
│ ├── 144-ts-ignore.explainer.2.ts
│ ├── 145-ts-expect-error.explainer.ts
│ ├── 145.5-ts-nocheck.explainer.ts
│ ├── 145.8-when-to-assert.explainer.ts
│ ├── 146-satisfies.problem.ts
│ ├── 146-satisfies.solution.svg
│ ├── 146-satisfies.solution.ts
│ ├── 146.5-typeof-keyof-and-satisfies-keyword.problem.ts
│ ├── 146.5-typeof-keyof-and-satisfies-keyword.solution.ts
│ ├── 146.7-satisfies-helps-narrow-literals.explainer.ts
│ ├── 147-satisfies-vs-as-vs-variable-annotations.problem.ts
│ ├── 147-satisfies-vs-as-vs-variable-annotations.solution.svg
│ ├── 147-satisfies-vs-as-vs-variable-annotations.solution.ts
│ ├── 148-satisfies-with-as-const.problem.ts
│ ├── 148-satisfies-with-as-const.solution.ts
│ └── workshop.md
├── 050-the-weird-parts
│ ├── 150-empty-object-type.problem.ts
│ ├── 150-empty-object-type.solution.1.svg
│ ├── 150-empty-object-type.solution.2.svg
│ ├── 150-empty-object-type.solution.ts
│ ├── 151-truly-empty-object.problem.ts
│ ├── 151-truly-empty-object.solution.1.ts
│ ├── 151-truly-empty-object.solution.2.ts
│ ├── 152-excess-properties-warnings.problem.ts
│ ├── 152-excess-properties-warnings.solution.1.ts
│ ├── 152-excess-properties-warnings.solution.2.ts
│ ├── 152-excess-properties-warnings.solution.3.ts
│ ├── 152-excess-properties-warnings.solution.svg
│ ├── 153-excess-properties-warnings-in-functions.problem.ts
│ ├── 153-excess-properties-warnings-in-functions.solution.1.ts
│ ├── 153-excess-properties-warnings-in-functions.solution.2.ts
│ ├── 154-object-keys-and-object-entries.explainer.ts
│ ├── 154.6-iterating-over-objects.problem.ts
│ ├── 154.6-iterating-over-objects.solution.1.ts
│ ├── 154.6-iterating-over-objects.solution.2.ts
│ ├── 154.6-iterating-over-objects.solution.3.ts
│ ├── 154.6-iterating-over-objects.solution.4.ts
│ ├── 154.8-evolving-any.problem.ts
│ ├── 154.8-evolving-any.solution.ts
│ ├── 154.9-evolving-any-arrays.explainer.ts
│ ├── 155-function-parameter-comparisons.problem.ts
│ ├── 155-function-parameter-comparisons.solution.ts
│ ├── 156-unions-of-functions-with-object-params.problem.ts
│ ├── 156-unions-of-functions-with-object-params.solution.ts
│ ├── 157-unions-of-functions.problem.ts
│ ├── 157-unions-of-functions.solution.1.ts
│ ├── 157-unions-of-functions.solution.2.ts
│ ├── 158-unions-of-function-return-types.explainer.ts
│ ├── 158.5-annotating-errors-a-function-throws.problem.ts
│ ├── 158.5-annotating-errors-a-function-throws.solution.ts
│ └── workshop.md
├── 060-modules-scripts-and-declaration-files
│ ├── 159-module-or-script.explainer
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── module-1.ts
│ │ │ ├── module-2.ts
│ │ │ ├── script-1.ts
│ │ │ └── script-2.ts
│ │ └── tsconfig.json
│ ├── 160-module-detection-force.problem
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── script-1.ts
│ │ │ └── script-2.ts
│ │ └── tsconfig.json
│ ├── 160-module-detection-force.solution
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── script-1.ts
│ │ │ └── script-2.ts
│ │ └── tsconfig.json
│ ├── 161-declaration-files.explainer
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── can-export-types.d.ts
│ │ │ ├── cant-use-runtime-code.d.ts
│ │ │ └── index.ts
│ │ └── tsconfig.json
│ ├── 162-declaration-files-can-be-modules-or-scripts.explainer
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── index.ts
│ │ │ ├── treated-as-module.d.ts
│ │ │ └── treated-as-script.d.ts
│ │ └── tsconfig.json
│ ├── 164-declaration-files-can-be-used-to-type-js-files.problem
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── example.js
│ │ │ └── index.ts
│ │ └── tsconfig.json
│ ├── 164-declaration-files-can-be-used-to-type-js-files.solution
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── example.d.ts
│ │ │ ├── example.js
│ │ │ └── index.ts
│ │ └── tsconfig.json
│ ├── 166-ambient-context-and-declare-const.problem
│ │ ├── package.json
│ │ ├── src
│ │ │ └── index.ts
│ │ └── tsconfig.json
│ ├── 166-ambient-context-and-declare-const.solution
│ │ ├── package.json
│ │ ├── src
│ │ │ └── index.ts
│ │ └── tsconfig.json
│ ├── 167-declare-global.problem
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── index.ts
│ │ │ └── other-file.ts
│ │ └── tsconfig.json
│ ├── 167-declare-global.solution.1
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── index.ts
│ │ │ └── other-file.ts
│ │ └── tsconfig.json
│ ├── 167-declare-global.solution.2
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── debug.d.ts
│ │ │ ├── index.ts
│ │ │ └── other-file.ts
│ │ └── tsconfig.json
│ └── plan.md
├── 065-types-you-dont-control
│ ├── 172-lib-d-ts.problem
│ │ ├── package.json
│ │ ├── src
│ │ │ └── index.ts
│ │ └── tsconfig.json
│ ├── 172-lib-d-ts.solution.1
│ │ ├── package.json
│ │ ├── src
│ │ │ └── index.ts
│ │ └── tsconfig.json
│ ├── 172-lib-d-ts.solution.2
│ │ ├── package.json
│ │ ├── src
│ │ │ └── index.ts
│ │ └── tsconfig.json
│ ├── 173-lib-dom.problem
│ │ ├── package.json
│ │ ├── src
│ │ │ └── index.ts
│ │ └── tsconfig.json
│ ├── 173-lib-dom.solution
│ │ ├── package.json
│ │ ├── src
│ │ │ └── index.ts
│ │ └── tsconfig.json
│ ├── 174-lib-dom-iterable.problem
│ │ ├── package.json
│ │ ├── src
│ │ │ └── index.ts
│ │ └── tsconfig.json
│ ├── 174-lib-dom-iterable.solution
│ │ ├── package.json
│ │ ├── src
│ │ │ └── index.ts
│ │ └── tsconfig.json
│ ├── 174.5-modifying-window.problem
│ │ ├── package.json
│ │ ├── src
│ │ │ └── index.ts
│ │ └── tsconfig.json
│ ├── 174.5-modifying-window.solution
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── index.ts
│ │ │ └── window.d.ts
│ │ └── tsconfig.json
│ ├── 175-definitely-typed.problem
│ │ ├── package.json
│ │ ├── pnpm-lock.yaml
│ │ ├── src
│ │ │ └── index.ts
│ │ └── tsconfig.json
│ ├── 175-definitely-typed.solution
│ │ ├── package.json
│ │ ├── pnpm-lock.yaml
│ │ ├── src
│ │ │ └── index.ts
│ │ └── tsconfig.json
│ ├── 175.2-types-node.explainer
│ │ ├── package.json
│ │ ├── src
│ │ │ └── index.ts
│ │ └── tsconfig.json
│ ├── 175.5-modifying-process-env.problem
│ │ ├── package.json
│ │ ├── src
│ │ │ └── index.ts
│ │ └── tsconfig.json
│ ├── 175.5-modifying-process-env.solution
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── index.ts
│ │ │ └── process.d.ts
│ │ └── tsconfig.json
│ ├── 176-types-that-ship-with-libraries.explainer
│ │ ├── package.json
│ │ ├── pnpm-lock.yaml
│ │ ├── src
│ │ │ └── index.ts
│ │ └── tsconfig.json
│ ├── 176.2-declare-module.problem
│ │ ├── package.json
│ │ ├── src
│ │ │ └── index.ts
│ │ └── tsconfig.json
│ ├── 176.2-declare-module.solution
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── index.ts
│ │ │ └── my-module-name-does-not-matter.d.ts
│ │ └── tsconfig.json
│ ├── 176.3-wildcard-in-declare-module.problem
│ │ ├── package.json
│ │ ├── src
│ │ │ └── index.ts
│ │ └── tsconfig.json
│ ├── 176.3-wildcard-in-declare-module.solution
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── index.ts
│ │ │ └── png.d.ts
│ │ └── tsconfig.json
│ ├── 176.5-skip-lib-check-true.problem
│ │ ├── package.json
│ │ ├── src
│ │ │ └── index.d.ts
│ │ └── tsconfig.json
│ ├── 176.5-skip-lib-check-true.solution
│ │ ├── package.json
│ │ ├── src
│ │ │ └── index.d.ts
│ │ └── tsconfig.json
│ ├── 176.7-should-you-use-declaration-files-to-store-your-types.explainer
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── index.ts
│ │ │ └── types.d.ts
│ │ └── tsconfig.json
│ ├── 177-declare-module-for-overriding-third-party-libraries.explainer
│ │ ├── package.json
│ │ ├── pnpm-lock.yaml
│ │ ├── src
│ │ │ ├── index.ts
│ │ │ └── zod.d.ts
│ │ └── tsconfig.json
│ └── plan.md
├── 080-configuring-typescript
│ ├── 178-my-recommended-tsconfig-base.explainer
│ │ ├── notes.ts
│ │ ├── package.json
│ │ └── tsconfig.json
│ ├── 178.5-isolated-modules.explainer
│ │ ├── package.json
│ │ ├── pnpm-lock.yaml
│ │ ├── src
│ │ │ └── index.ts
│ │ └── tsconfig.json
│ ├── 179-no-unchecked-indexed-access.problem
│ │ ├── package.json
│ │ ├── src
│ │ │ └── index.ts
│ │ └── tsconfig.json
│ ├── 179-no-unchecked-indexed-access.solution
│ │ ├── package.json
│ │ ├── src
│ │ │ └── index.ts
│ │ └── tsconfig.json
│ ├── 179.5-no-emit.problem
│ │ ├── package.json
│ │ ├── pnpm-lock.yaml
│ │ ├── src
│ │ │ └── index.ts
│ │ └── tsconfig.json
│ ├── 179.5-no-emit.solution
│ │ ├── package.json
│ │ ├── pnpm-lock.yaml
│ │ ├── src
│ │ │ └── index.ts
│ │ └── tsconfig.json
│ ├── 180-module-resolution-bundler-or-nodenext.explainer
│ │ ├── package.json
│ │ ├── pnpm-lock.yaml
│ │ ├── src
│ │ │ ├── example.ts
│ │ │ └── index.ts
│ │ └── tsconfig.json
│ ├── 181-lib-vs-target.explainer
│ │ ├── package.json
│ │ ├── pnpm-lock.yaml
│ │ ├── src
│ │ │ └── index.ts
│ │ └── tsconfig.json
│ ├── 181.2-creating-declaration-files.problem
│ │ ├── package.json
│ │ ├── pnpm-lock.yaml
│ │ ├── src
│ │ │ └── index.ts
│ │ └── tsconfig.json
│ ├── 181.2-creating-declaration-files.solution
│ │ ├── package.json
│ │ ├── pnpm-lock.yaml
│ │ ├── src
│ │ │ └── index.ts
│ │ └── tsconfig.json
│ ├── 181.4-declaration-maps.problem
│ │ ├── package.json
│ │ ├── pnpm-lock.yaml
│ │ ├── src
│ │ │ └── index.ts
│ │ ├── test.ts
│ │ └── tsconfig.json
│ ├── 181.4-declaration-maps.solution
│ │ ├── package.json
│ │ ├── pnpm-lock.yaml
│ │ ├── src
│ │ │ └── index.ts
│ │ ├── test.ts
│ │ └── tsconfig.json
│ ├── 182-jsx.problem
│ │ ├── package.json
│ │ ├── pnpm-lock.yaml
│ │ ├── src
│ │ │ └── index.tsx
│ │ └── tsconfig.json
│ ├── 182-jsx.solution.1
│ │ ├── package.json
│ │ ├── pnpm-lock.yaml
│ │ ├── src
│ │ │ └── index.tsx
│ │ └── tsconfig.json
│ ├── 182-jsx.solution.2
│ │ ├── package.json
│ │ ├── pnpm-lock.yaml
│ │ ├── src
│ │ │ └── index.tsx
│ │ └── tsconfig.json
│ ├── 183-multiple-tsconfig-json-files.problem
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── client.ts
│ │ │ └── server.ts
│ │ └── tsconfig.json
│ ├── 183-multiple-tsconfig-json-files.solution
│ │ ├── package.json
│ │ └── src
│ │ │ ├── client
│ │ │ ├── index.ts
│ │ │ └── tsconfig.json
│ │ │ └── server
│ │ │ ├── index.ts
│ │ │ └── tsconfig.json
│ ├── 184-globals-are-tied-to-a-single-tsconfig.explainer
│ │ ├── package.json
│ │ └── src
│ │ │ ├── client
│ │ │ ├── index.ts
│ │ │ └── tsconfig.json
│ │ │ └── server
│ │ │ ├── index.ts
│ │ │ ├── server.d.ts
│ │ │ └── tsconfig.json
│ ├── 185-extending-from-other-tsconfig-json-files.problem
│ │ ├── package.json
│ │ └── src
│ │ │ ├── client
│ │ │ ├── index.ts
│ │ │ └── tsconfig.json
│ │ │ └── server
│ │ │ ├── index.ts
│ │ │ └── tsconfig.json
│ ├── 185-extending-from-other-tsconfig-json-files.solution
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── client
│ │ │ │ ├── index.ts
│ │ │ │ └── tsconfig.json
│ │ │ └── server
│ │ │ │ ├── index.ts
│ │ │ │ └── tsconfig.json
│ │ └── tsconfig.base.json
│ ├── 186-project-references.problem
│ │ ├── checklist.md
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── client
│ │ │ │ ├── index.ts
│ │ │ │ └── tsconfig.json
│ │ │ └── server
│ │ │ │ ├── index.ts
│ │ │ │ └── tsconfig.json
│ │ └── tsconfig.base.json
│ ├── 186-project-references.solution.1
│ │ ├── checklist.md
│ │ ├── package.json
│ │ ├── pnpm-lock.yaml
│ │ ├── src
│ │ │ ├── client
│ │ │ │ ├── index.ts
│ │ │ │ └── tsconfig.json
│ │ │ └── server
│ │ │ │ ├── index.ts
│ │ │ │ └── tsconfig.json
│ │ ├── tsconfig.base.json
│ │ └── tsconfig.json
│ ├── 186-project-references.solution.2
│ │ ├── checklist.md
│ │ ├── package.json
│ │ ├── pnpm-lock.yaml
│ │ ├── src
│ │ │ ├── client
│ │ │ │ └── index.ts
│ │ │ └── server
│ │ │ │ └── index.ts
│ │ ├── tsconfig.base.json
│ │ ├── tsconfig.client.json
│ │ ├── tsconfig.json
│ │ └── tsconfig.server.json
│ ├── 186-project-references.solution.3
│ │ ├── .config
│ │ │ ├── tsconfig.base.json
│ │ │ ├── tsconfig.client.json
│ │ │ └── tsconfig.server.json
│ │ ├── checklist.md
│ │ ├── package.json
│ │ ├── pnpm-lock.yaml
│ │ ├── src
│ │ │ ├── client
│ │ │ │ └── index.ts
│ │ │ └── server
│ │ │ │ └── index.ts
│ │ └── tsconfig.json
│ ├── 190-setting-up-types-for-node.explainer
│ │ ├── package.json
│ │ ├── pnpm-lock.yaml
│ │ ├── src
│ │ │ └── index.ts
│ │ └── tsconfig.json
│ └── plan.md
├── 082-cjs-vs-esm
│ ├── 193-intro.explainer.ts
│ ├── 194-cant-import-esm-into-cjs.problem
│ │ ├── package.json
│ │ ├── pnpm-lock.yaml
│ │ └── src
│ │ │ ├── esm-module.js
│ │ │ └── index.js
│ ├── 194-cant-import-esm-into-cjs.solution
│ │ ├── package.json
│ │ ├── pnpm-lock.yaml
│ │ └── src
│ │ │ ├── esm-module.mjs
│ │ │ └── index.js
│ ├── 195-can-import-cjs-into-esm.explainer
│ │ ├── package.json
│ │ ├── pnpm-lock.yaml
│ │ └── src
│ │ │ ├── cjs-module.cjs
│ │ │ └── index.mjs
│ ├── 196-mts-files.problem
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── esm-module.ts
│ │ │ └── index.ts
│ │ └── tsconfig.json
│ ├── 196-mts-files.solution
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── esm-module.mts
│ │ │ └── index.ts
│ │ └── tsconfig.json
│ ├── 196.5-browsers-cant-use-cjs.explainer.1
│ │ ├── .gitignore
│ │ ├── index.html
│ │ ├── package.json
│ │ ├── pnpm-lock.yaml
│ │ ├── src
│ │ │ ├── example.ts
│ │ │ └── run.ts
│ │ └── tsconfig.json
│ ├── 196.5-browsers-cant-use-cjs.explainer.2
│ │ ├── .gitignore
│ │ ├── index.html
│ │ ├── package.json
│ │ ├── pnpm-lock.yaml
│ │ ├── src
│ │ │ ├── example.mts
│ │ │ └── run.mts
│ │ └── tsconfig.json
│ ├── 197-verbatim-module-syntax.problem
│ │ ├── package.json
│ │ ├── src
│ │ │ └── cjs-module.ts
│ │ └── tsconfig.json
│ ├── 197-verbatim-module-syntax.solution
│ │ ├── package.json
│ │ ├── pnpm-lock.yaml
│ │ ├── src
│ │ │ └── cjs-module.ts
│ │ └── tsconfig.json
│ ├── 198-treat-ts-files-as-esm.problem
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── esm-module.ts
│ │ │ └── index.ts
│ │ └── tsconfig.json
│ ├── 198-treat-ts-files-as-esm.solution
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── esm-module.ts
│ │ │ └── index.ts
│ │ └── tsconfig.json
│ ├── 200-import-syntax-for-cts.problem
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── index.ts
│ │ │ └── other-module.ts
│ │ └── tsconfig.json
│ ├── 200-import-syntax-for-cts.solution
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── index.ts
│ │ │ └── other-module.ts
│ │ └── tsconfig.json
│ ├── 201-module-nodenext-emits-the-right-extensions.explainer
│ │ ├── package.json
│ │ ├── pnpm-lock.yaml
│ │ ├── src
│ │ │ ├── cjs-module.cts
│ │ │ ├── esm-module.mts
│ │ │ └── index.ts
│ │ └── tsconfig.json
│ ├── 202.5-import-type.problem
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── esm-module.ts
│ │ │ └── module-containing-types.ts
│ │ └── tsconfig.json
│ ├── 202.5-import-type.solution
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── esm-module.ts
│ │ │ └── module-containing-types.ts
│ │ └── tsconfig.json
│ ├── 202.6-should-i-use-cjs-or-esm.explainer.ts
│ └── 202.7-applications-vs-libraries.explainer.ts
├── 083-designing-your-types
│ ├── 203-domain-modelling-in-typescript.explainer.ts
│ ├── 204-intro-to-generic-types.problem.ts
│ ├── 204-intro-to-generic-types.solution.ts
│ ├── 205-multiple-type-parameters.problem.ts
│ ├── 205-multiple-type-parameters.solution.ts
│ ├── 206-result-type.explainer.ts
│ ├── 207-default-type-parameters.problem.ts
│ ├── 207-default-type-parameters.solution.ts
│ ├── 208-type-parameter-constraints.problem.ts
│ ├── 208-type-parameter-constraints.solution.ts
│ ├── 209-tighter-version-of-omit.problem.ts
│ ├── 209-tighter-version-of-omit.solution.ts
│ ├── 210-template-literal-types.problem.ts
│ ├── 210-template-literal-types.solution.ts
│ ├── 211-passing-unions-to-template-literal-types.problem.ts
│ ├── 211-passing-unions-to-template-literal-types.solution.ts
│ ├── 212-mapped-types.problem.ts
│ ├── 212-mapped-types.solution.ts
│ ├── 213-as-in-mapped-types.problem.ts
│ ├── 213-as-in-mapped-types.solution.ts
│ └── workshop.md
├── 085-the-utils-folder
│ ├── 214-intro-to-the-utils-folder.explainer.ts
│ ├── 215-generic-functions-without-inference.problem.ts
│ ├── 215-generic-functions-without-inference.solution.ts
│ ├── 216-type-parameter-defaults-in-generic-functions.problem.ts
│ ├── 216-type-parameter-defaults-in-generic-functions.solution.ts
│ ├── 217-generic-functions-with-inference.problem.ts
│ ├── 217-generic-functions-with-inference.solution.ts
│ ├── 218-type-parameter-constraints-with-generic-functions.problem.ts
│ ├── 218-type-parameter-constraints-with-generic-functions.solution.ts
│ ├── 219-combining-generic-types-with-generic-functions.problem.ts
│ ├── 219-combining-generic-types-with-generic-functions.solution.ts
│ ├── 220-multiple-type-arguments-in-generic-functions.problem.ts
│ ├── 220-multiple-type-arguments-in-generic-functions.solution.ts
│ ├── 221-type-predicates.problem.ts
│ ├── 221-type-predicates.solution.ts
│ ├── 222-assertion-functions.problem.ts
│ ├── 222-assertion-functions.solution.ts
│ ├── 223-function-overloads.problem.ts
│ ├── 223-function-overloads.solution.ts
│ └── workshop.md
├── 090-the-style-guide
│ ├── 224-hungarian-notation.problem.ts
│ ├── 224-hungarian-notation.solution.ts
│ ├── 225-where-to-put-your-types.problem.ts
│ ├── 225-where-to-put-your-types.solution.ts
│ ├── 226-colocation-of-types.problem.ts
│ ├── 226-colocation-of-types.solution.ts
│ ├── 227-setting-up-eslint.explainer.ts
│ ├── 228-explicit-any-rule-or-not.problem.ts
│ ├── 228-explicit-any-rule-or-not.solution.ts
│ ├── 229-explicit-return-types-or-not.problem.ts
│ ├── 229-explicit-return-types-or-not.solution.ts
│ ├── 230-any-vs-ts-ignore-vs-ts-expect-error.problem.ts
│ ├── 230-any-vs-ts-ignore-vs-ts-expect-error.solution.ts
│ ├── 231-dont-declare-type-and-value-with-the-same-name.problem.ts
│ ├── 231-dont-declare-type-and-value-with-the-same-name.solution.ts
│ ├── 232-types-vs-interfaces.problem.ts
│ ├── 232-types-vs-interfaces.solution.ts
│ ├── 233-dont-use-uppercase-function-object-string-boolean-as-types.problem.ts
│ ├── 233-dont-use-uppercase-function-object-string-boolean-as-types.solution.ts
│ ├── 234-dont-make-your-types-globally-available-types.problem.ts
│ ├── 234-dont-make-your-types-globally-available-types.solution.ts
│ ├── 235-how-strict-should-you-configure-ts.problem.ts
│ ├── 235-how-strict-should-you-configure-ts.solution.ts
│ ├── 236-dont-unnecessarily-widen-types.problem.ts
│ ├── 236-dont-unnecessarily-widen-types.solution.ts
│ └── plan.md
└── 095-migrating-from-javascript
│ ├── 237-strict-file-by-file-vs-ramp-up-strictness.problem.ts
│ ├── 237-strict-file-by-file-vs-ramp-up-strictness.solution.ts
│ ├── 238-dependencies-first.problem.ts
│ ├── 238-dependencies-first.solution.ts
│ ├── 239-typing-third-party-modules.problem.ts
│ ├── 239-typing-third-party-modules.solution.ts
│ ├── 240-madge.problem.ts
│ ├── 240-madge.solution.ts
│ ├── 241-understanding-the-structure-of-ts-errors.problem.ts
│ ├── 241-understanding-the-structure-of-ts-errors.solution.ts
│ ├── 242-experiments-with-jsdoc.problem.ts
│ ├── 242-experiments-with-jsdoc.solution.ts
│ ├── 243-jsdoc-cannot-pass-types-to-functions.problem.ts
│ ├── 243-jsdoc-cannot-pass-types-to-functions.solution.ts
│ └── plan.md
├── tsconfig.json
├── vite.config.mts
└── workshop.md
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | tsconfig.temp.json
3 | dist
4 | *.tsbuildinfo
5 | *.prompt.*
6 | .vscode/*.code-snippets
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "typescript.tsdk": "node_modules/typescript/lib",
3 | "typescript.enablePromptUseWorkspaceTsdk": true,
4 | "github.copilot.enable": {
5 | "*": false,
6 | },
7 | "explorer.sortOrder": "mixed",
8 | }
--------------------------------------------------------------------------------
/book-content/formatter/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "type": "module"
3 | }
4 |
--------------------------------------------------------------------------------
/book-content/formatter/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "noEmit": true,
4 | "module": "NodeNext"
5 | }
6 | }
--------------------------------------------------------------------------------
/book-content/readme.md:
--------------------------------------------------------------------------------
1 | # TypeScript Book
2 |
3 | This is the source code for the in-progress book "Total TypeScript: Essentials" by Matt Pocock. It goes through the essentials of TypeScript, from the basics to the advanced features.
4 |
5 | If you've got any feedback, I'd love to hear it at team@totaltypescript.com.
6 |
--------------------------------------------------------------------------------
/src/005-kickstart-your-typescript-setup/001-typescript-vs-javascript.explainer.ts:
--------------------------------------------------------------------------------
1 | // Explain autocomplete and type checking
2 |
3 | // Check your types are correct across your whole application
4 |
5 | // Refactor with confidence
6 |
--------------------------------------------------------------------------------
/src/005-kickstart-your-typescript-setup/002-how-typescript-works.explainer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/total-typescript/total-typescript-book/e9400f8009b70176dead19aa6c2d7b2de5614599/src/005-kickstart-your-typescript-setup/002-how-typescript-works.explainer.png
--------------------------------------------------------------------------------
/src/005-kickstart-your-typescript-setup/002-how-typescript-works.explainer.ts:
--------------------------------------------------------------------------------
1 | // Explain diagram
2 |
--------------------------------------------------------------------------------
/src/005-kickstart-your-typescript-setup/003-tools-needed.explainer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/total-typescript/total-typescript-book/e9400f8009b70176dead19aa6c2d7b2de5614599/src/005-kickstart-your-typescript-setup/003-tools-needed.explainer.png
--------------------------------------------------------------------------------
/src/005-kickstart-your-typescript-setup/003-tools-needed.explainer.ts:
--------------------------------------------------------------------------------
1 | // Explain diagram
2 |
--------------------------------------------------------------------------------
/src/005-kickstart-your-typescript-setup/004-set-up-node-js-and-vscode.explainer.ts:
--------------------------------------------------------------------------------
1 | // Explain in video
2 |
--------------------------------------------------------------------------------
/src/005-kickstart-your-typescript-setup/005-set-up-npm-and-pnpm.explainer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/total-typescript/total-typescript-book/e9400f8009b70176dead19aa6c2d7b2de5614599/src/005-kickstart-your-typescript-setup/005-set-up-npm-and-pnpm.explainer.png
--------------------------------------------------------------------------------
/src/005-kickstart-your-typescript-setup/005-set-up-npm-and-pnpm.explainer.ts:
--------------------------------------------------------------------------------
1 | // Explain pnpm
2 |
3 | // Explain why pnpm is better than npm
4 |
--------------------------------------------------------------------------------
/src/005-kickstart-your-typescript-setup/006-vscode-extension.explainer.ts:
--------------------------------------------------------------------------------
1 | // Explain the VSCode extension
2 |
3 | const num: number = "asdawd";
4 |
--------------------------------------------------------------------------------
/src/005-kickstart-your-typescript-setup/workshop.md:
--------------------------------------------------------------------------------
1 | # Fast Track
2 |
3 | ## Section 1
4 |
5 | Discuss each of the questions below in your groups.
6 |
7 | ### How is TypeScript different to JavaScript?
8 |
9 | ### Can you turn TypeScript into JavaScript?
10 |
11 | ### What kind of mistakes does TypeScript help prevent?
12 |
13 | ### Does TypeScript make your code run faster?
14 |
15 | ### What is a 'type'?
16 |
--------------------------------------------------------------------------------
/src/010-typescript-in-the-build-process/010-typescript-in-the-browser.problem/example.ts:
--------------------------------------------------------------------------------
1 | const run = (message: string) => {
2 | console.log(message);
3 | };
4 |
5 | run("Hello!");
6 |
--------------------------------------------------------------------------------
/src/010-typescript-in-the-build-process/010-typescript-in-the-browser.problem/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | My App
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/src/010-typescript-in-the-build-process/010-typescript-in-the-browser.problem/readme.md:
--------------------------------------------------------------------------------
1 | # TypeScript In The Browser
2 |
3 | ## Learning Goals
4 |
5 | - Learn how you can use TypeScript to build web apps
6 |
7 | ## Problem
8 |
9 | Try opening the `index.html` file in your browser. You'll see that it doesn't work. Why is that?
10 |
--------------------------------------------------------------------------------
/src/010-typescript-in-the-build-process/010-typescript-in-the-browser.solution/example.js:
--------------------------------------------------------------------------------
1 | const run = (message) => {
2 | console.log(message);
3 | };
4 |
5 | run("Hello!");
6 |
--------------------------------------------------------------------------------
/src/010-typescript-in-the-build-process/010-typescript-in-the-browser.solution/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | My App
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/src/010-typescript-in-the-build-process/011-compile-typescript-to-javascript.problem/example.ts:
--------------------------------------------------------------------------------
1 | const run = (message: string) => {
2 | console.log(message);
3 | };
4 |
5 | run("Hello!");
6 |
--------------------------------------------------------------------------------
/src/010-typescript-in-the-build-process/011-compile-typescript-to-javascript.problem/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | My App
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/src/010-typescript-in-the-build-process/011-compile-typescript-to-javascript.solution/.gitignore:
--------------------------------------------------------------------------------
1 | *.js
--------------------------------------------------------------------------------
/src/010-typescript-in-the-build-process/011-compile-typescript-to-javascript.solution/example.ts:
--------------------------------------------------------------------------------
1 | const run = (message: string) => {
2 | console.log(message);
3 | };
4 |
5 | run("Hello!");
6 |
--------------------------------------------------------------------------------
/src/010-typescript-in-the-build-process/011-compile-typescript-to-javascript.solution/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | My App
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/src/010-typescript-in-the-build-process/012-tsc-watch-mode.problem/.gitignore:
--------------------------------------------------------------------------------
1 | *.js
--------------------------------------------------------------------------------
/src/010-typescript-in-the-build-process/012-tsc-watch-mode.problem/example.ts:
--------------------------------------------------------------------------------
1 | const run = (message: string) => {
2 | console.log(message);
3 | };
4 |
5 | run("Hello!");
6 |
--------------------------------------------------------------------------------
/src/010-typescript-in-the-build-process/012-tsc-watch-mode.problem/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | My App
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/src/010-typescript-in-the-build-process/012-tsc-watch-mode.solution/.gitignore:
--------------------------------------------------------------------------------
1 | *.js
--------------------------------------------------------------------------------
/src/010-typescript-in-the-build-process/012-tsc-watch-mode.solution/example.ts:
--------------------------------------------------------------------------------
1 | const run = (message: string) => {
2 | console.log(message);
3 | };
4 |
5 | run("Hello!");
6 |
--------------------------------------------------------------------------------
/src/010-typescript-in-the-build-process/012-tsc-watch-mode.solution/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | My App
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/src/010-typescript-in-the-build-process/013-compiling-to-a-directory.problem/.gitignore:
--------------------------------------------------------------------------------
1 | *.js
--------------------------------------------------------------------------------
/src/010-typescript-in-the-build-process/013-compiling-to-a-directory.problem/example.ts:
--------------------------------------------------------------------------------
1 | const run = (message: string) => {
2 | console.log(message);
3 | };
4 |
5 | run("Hello!");
6 |
--------------------------------------------------------------------------------
/src/010-typescript-in-the-build-process/013-compiling-to-a-directory.problem/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | My App
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/src/010-typescript-in-the-build-process/013-compiling-to-a-directory.solution/.gitignore:
--------------------------------------------------------------------------------
1 | dist
--------------------------------------------------------------------------------
/src/010-typescript-in-the-build-process/013-compiling-to-a-directory.solution/example.ts:
--------------------------------------------------------------------------------
1 | const run = (message: string) => {
2 | console.log(message);
3 | };
4 |
5 | run("Hello!");
6 |
--------------------------------------------------------------------------------
/src/010-typescript-in-the-build-process/013-compiling-to-a-directory.solution/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | My App
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/src/010-typescript-in-the-build-process/014-setting-up-a-frontend-app-with-vite.problem/.gitignore:
--------------------------------------------------------------------------------
1 | dist
--------------------------------------------------------------------------------
/src/010-typescript-in-the-build-process/014-setting-up-a-frontend-app-with-vite.problem/example.ts:
--------------------------------------------------------------------------------
1 | const run = (message: string) => {
2 | console.log(message);
3 | };
4 |
5 | run("Hello!");
6 |
--------------------------------------------------------------------------------
/src/010-typescript-in-the-build-process/014-setting-up-a-frontend-app-with-vite.problem/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/src/010-typescript-in-the-build-process/014-setting-up-a-frontend-app-with-vite.solution/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | pnpm-debug.log*
8 | lerna-debug.log*
9 |
10 | node_modules
11 | dist
12 | dist-ssr
13 | *.local
14 |
15 | # Editor directories and files
16 | .vscode/*
17 | !.vscode/extensions.json
18 | .idea
19 | .DS_Store
20 | *.suo
21 | *.ntvs*
22 | *.njsproj
23 | *.sln
24 | *.sw?
25 |
--------------------------------------------------------------------------------
/src/010-typescript-in-the-build-process/014-setting-up-a-frontend-app-with-vite.solution/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "013-setting-up-a-frontend-app-with-vite.solution",
3 | "private": true,
4 | "version": "0.0.0",
5 | "type": "module",
6 | "scripts": {
7 | "dev": "vite",
8 | "build": "tsc && vite build",
9 | "preview": "vite preview"
10 | },
11 | "devDependencies": {
12 | "typescript": "^5.0.2",
13 | "vite": "^4.4.5"
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/010-typescript-in-the-build-process/014-setting-up-a-frontend-app-with-vite.solution/src/counter.ts:
--------------------------------------------------------------------------------
1 | export function setupCounter(element: HTMLButtonElement) {
2 | let counter = 0
3 | const setCounter = (count: number) => {
4 | counter = count
5 | element.innerHTML = `count is ${counter}`
6 | }
7 | element.addEventListener('click', () => setCounter(counter + 1))
8 | setCounter(0)
9 | }
10 |
--------------------------------------------------------------------------------
/src/010-typescript-in-the-build-process/014-setting-up-a-frontend-app-with-vite.solution/src/vite-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/src/010-typescript-in-the-build-process/015-typescript-as-a-linter.problem/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | pnpm-debug.log*
8 | lerna-debug.log*
9 |
10 | node_modules
11 | dist
12 | dist-ssr
13 | *.local
14 |
15 | # Editor directories and files
16 | .vscode/*
17 | !.vscode/extensions.json
18 | .idea
19 | .DS_Store
20 | *.suo
21 | *.ntvs*
22 | *.njsproj
23 | *.sln
24 | *.sw?
25 |
--------------------------------------------------------------------------------
/src/010-typescript-in-the-build-process/015-typescript-as-a-linter.problem/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Vite + TS
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/src/010-typescript-in-the-build-process/015-typescript-as-a-linter.problem/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "013-setting-up-a-frontend-app-with-vite.solution",
3 | "private": true,
4 | "version": "0.0.0",
5 | "type": "module",
6 | "scripts": {
7 | "dev": "vite",
8 | "build": "tsc && vite build",
9 | "preview": "vite preview"
10 | },
11 | "devDependencies": {
12 | "typescript": "^5.0.2",
13 | "vite": "^4.4.5"
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/010-typescript-in-the-build-process/015-typescript-as-a-linter.problem/src/counter.ts:
--------------------------------------------------------------------------------
1 | export function setupCounter(element: HTMLButtonElement) {
2 | let counter = 0;
3 | const setCounter = (count: number) => {
4 | counter = count;
5 | element.innerHTML = `count is ${counter}`;
6 | };
7 | element.addEventListener("click", () => setCounter(counter + 1));
8 | setCounter(0);
9 | }
10 |
--------------------------------------------------------------------------------
/src/010-typescript-in-the-build-process/015-typescript-as-a-linter.problem/src/vite-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/src/010-typescript-in-the-build-process/015-typescript-as-a-linter.solution/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | pnpm-debug.log*
8 | lerna-debug.log*
9 |
10 | node_modules
11 | dist
12 | dist-ssr
13 | *.local
14 |
15 | # Editor directories and files
16 | .vscode/*
17 | !.vscode/extensions.json
18 | .idea
19 | .DS_Store
20 | *.suo
21 | *.ntvs*
22 | *.njsproj
23 | *.sln
24 | *.sw?
25 |
--------------------------------------------------------------------------------
/src/010-typescript-in-the-build-process/015-typescript-as-a-linter.solution/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Vite + TS
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/src/010-typescript-in-the-build-process/015-typescript-as-a-linter.solution/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "013-setting-up-a-frontend-app-with-vite.solution",
3 | "private": true,
4 | "version": "0.0.0",
5 | "type": "module",
6 | "scripts": {
7 | "dev": "vite",
8 | "build": "tsc && vite build",
9 | "preview": "vite preview"
10 | },
11 | "devDependencies": {
12 | "typescript": "^5.0.2",
13 | "vite": "^4.4.5"
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/010-typescript-in-the-build-process/015-typescript-as-a-linter.solution/src/counter.ts:
--------------------------------------------------------------------------------
1 | export function setupCounter(element: HTMLButtonElement) {
2 | let counter = 0;
3 | const setCounter = (count: number) => {
4 | counter = count;
5 | element.innerHTML = `count is ${counter}`;
6 | };
7 | element.addEventListener("click", () => setCounter(counter + 1));
8 | setCounter(0);
9 | }
10 |
--------------------------------------------------------------------------------
/src/010-typescript-in-the-build-process/015-typescript-as-a-linter.solution/src/vite-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/src/010-typescript-in-the-build-process/016-typescript-on-ci.explainer/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | pnpm-debug.log*
8 | lerna-debug.log*
9 |
10 | node_modules
11 | dist
12 | dist-ssr
13 | *.local
14 |
15 | # Editor directories and files
16 | .vscode/*
17 | !.vscode/extensions.json
18 | .idea
19 | .DS_Store
20 | *.suo
21 | *.ntvs*
22 | *.njsproj
23 | *.sln
24 | *.sw?
25 |
--------------------------------------------------------------------------------
/src/010-typescript-in-the-build-process/016-typescript-on-ci.explainer/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Vite + TS
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/src/010-typescript-in-the-build-process/016-typescript-on-ci.explainer/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "013-setting-up-a-frontend-app-with-vite.solution",
3 | "private": true,
4 | "version": "0.0.0",
5 | "type": "module",
6 | "scripts": {
7 | "ci": "tsc",
8 | "dev": "vite",
9 | "build": "tsc && vite build",
10 | "preview": "vite preview"
11 | },
12 | "devDependencies": {
13 | "typescript": "^5.0.2",
14 | "vite": "^4.4.5"
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/010-typescript-in-the-build-process/016-typescript-on-ci.explainer/src/counter.ts:
--------------------------------------------------------------------------------
1 | export function setupCounter(element: HTMLButtonElement) {
2 | let counter = 0
3 | const setCounter = (count: number) => {
4 | counter = count
5 | element.innerHTML = `count is ${counter}`
6 | }
7 | element.addEventListener('click', () => setCounter(counter + 1))
8 | setCounter(0)
9 | }
10 |
--------------------------------------------------------------------------------
/src/010-typescript-in-the-build-process/016-typescript-on-ci.explainer/src/vite-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/src/010-typescript-in-the-build-process/017-blocking-your-dev-server-with-typescript.explainer.1/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | pnpm-debug.log*
8 | lerna-debug.log*
9 |
10 | node_modules
11 | dist
12 | dist-ssr
13 | *.local
14 |
15 | # Editor directories and files
16 | .vscode/*
17 | !.vscode/extensions.json
18 | .idea
19 | .DS_Store
20 | *.suo
21 | *.ntvs*
22 | *.njsproj
23 | *.sln
24 | *.sw?
25 |
--------------------------------------------------------------------------------
/src/010-typescript-in-the-build-process/017-blocking-your-dev-server-with-typescript.explainer.1/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "013-setting-up-a-frontend-app-with-vite.solution",
3 | "private": true,
4 | "version": "0.0.0",
5 | "type": "module",
6 | "scripts": {
7 | "ci": "tsc",
8 | "dev": "vite",
9 | "build": "tsc && vite build",
10 | "preview": "vite preview"
11 | },
12 | "devDependencies": {
13 | "typescript": "^5.0.2",
14 | "vite": "^4.4.5"
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/010-typescript-in-the-build-process/017-blocking-your-dev-server-with-typescript.explainer.1/src/counter.ts:
--------------------------------------------------------------------------------
1 | export function setupCounter(element: HTMLButtonElement) {
2 | let counter = 0
3 | const setCounter = (count: number) => {
4 | counter = count
5 | element.innerHTML = `count is ${counter}`
6 | }
7 | element.addEventListener('click', () => setCounter(counter + 1))
8 | setCounter(0)
9 | }
10 |
--------------------------------------------------------------------------------
/src/010-typescript-in-the-build-process/017-blocking-your-dev-server-with-typescript.explainer.1/src/vite-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/src/010-typescript-in-the-build-process/017-blocking-your-dev-server-with-typescript.explainer.2/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | pnpm-debug.log*
8 | lerna-debug.log*
9 |
10 | node_modules
11 | dist
12 | dist-ssr
13 | *.local
14 |
15 | # Editor directories and files
16 | .vscode/*
17 | !.vscode/extensions.json
18 | .idea
19 | .DS_Store
20 | *.suo
21 | *.ntvs*
22 | *.njsproj
23 | *.sln
24 | *.sw?
25 |
--------------------------------------------------------------------------------
/src/010-typescript-in-the-build-process/017-blocking-your-dev-server-with-typescript.explainer.2/src/counter.ts:
--------------------------------------------------------------------------------
1 | export function setupCounter(element: HTMLButtonElement) {
2 | let counter = 0
3 | const setCounter = (count: number) => {
4 | counter = count
5 | element.innerHTML = `count is ${counter}`
6 | }
7 | element.addEventListener('click', () => setCounter(counter + 1))
8 | setCounter(0)
9 | }
10 |
--------------------------------------------------------------------------------
/src/010-typescript-in-the-build-process/017-blocking-your-dev-server-with-typescript.explainer.2/src/vite-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/src/010-typescript-in-the-build-process/017-blocking-your-dev-server-with-typescript.explainer.2/vite.config.js:
--------------------------------------------------------------------------------
1 | import checker from "vite-plugin-checker";
2 |
3 | export default {
4 | plugins: [
5 | checker({
6 | typescript: true,
7 | }),
8 | ],
9 | };
10 |
--------------------------------------------------------------------------------
/src/010-typescript-in-the-build-process/017-blocking-your-dev-server-with-typescript.explainer.3/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | pnpm-debug.log*
8 | lerna-debug.log*
9 |
10 | node_modules
11 | dist
12 | dist-ssr
13 | *.local
14 |
15 | # Editor directories and files
16 | .vscode/*
17 | !.vscode/extensions.json
18 | .idea
19 | .DS_Store
20 | *.suo
21 | *.ntvs*
22 | *.njsproj
23 | *.sln
24 | *.sw?
25 |
--------------------------------------------------------------------------------
/src/010-typescript-in-the-build-process/017-blocking-your-dev-server-with-typescript.explainer.3/src/counter.ts:
--------------------------------------------------------------------------------
1 | export function setupCounter(element: HTMLButtonElement) {
2 | let counter = 0
3 | const setCounter = (count: number) => {
4 | counter = count
5 | element.innerHTML = `count is ${counter}`
6 | }
7 | element.addEventListener('click', () => setCounter(counter + 1))
8 | setCounter(0)
9 | }
10 |
--------------------------------------------------------------------------------
/src/010-typescript-in-the-build-process/017-blocking-your-dev-server-with-typescript.explainer.3/src/vite-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/src/010-typescript-in-the-build-process/019-using-tsx-to-create-quick-scripts.explainer/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | pnpm-debug.log*
8 | lerna-debug.log*
9 |
10 | node_modules
11 | dist
12 | dist-ssr
13 | *.local
14 |
15 | # Editor directories and files
16 | .vscode/*
17 | !.vscode/extensions.json
18 | .idea
19 | .DS_Store
20 | *.suo
21 | *.ntvs*
22 | *.njsproj
23 | *.sln
24 | *.sw?
25 |
--------------------------------------------------------------------------------
/src/010-typescript-in-the-build-process/019-using-tsx-to-create-quick-scripts.explainer/scripts/doSomething.ts:
--------------------------------------------------------------------------------
1 | console.log("The script is working!");
2 |
3 | const [, , ...args] = process.argv;
4 |
5 | console.log(args);
6 |
--------------------------------------------------------------------------------
/src/010-typescript-in-the-build-process/019-using-tsx-to-create-quick-scripts.explainer/src/counter.ts:
--------------------------------------------------------------------------------
1 | export function setupCounter(element: HTMLButtonElement) {
2 | let counter = 0
3 | const setCounter = (count: number) => {
4 | counter = count
5 | element.innerHTML = `count is ${counter}`
6 | }
7 | element.addEventListener('click', () => setCounter(counter + 1))
8 | setCounter(0)
9 | }
10 |
--------------------------------------------------------------------------------
/src/010-typescript-in-the-build-process/019-using-tsx-to-create-quick-scripts.explainer/src/vite-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/src/015-essential-types-and-annotations/020-basic-types-with-function-parameters.problem.ts:
--------------------------------------------------------------------------------
1 | import { Expect, Equal } from "@total-typescript/helpers";
2 |
3 | // CODE
4 |
5 | const add = (a: boolean, b: boolean) => {
6 | return a + b;
7 | };
8 |
9 | // TESTS
10 |
11 | const result = add(1, 2);
12 |
13 | type test = Expect>;
14 |
--------------------------------------------------------------------------------
/src/015-essential-types-and-annotations/020-basic-types-with-function-parameters.solution.ts:
--------------------------------------------------------------------------------
1 | import { Expect, Equal } from "@total-typescript/helpers";
2 |
3 | // CODE
4 |
5 | const add = (a: number, b: number) => {
6 | return a + b;
7 | };
8 |
9 | // TESTS
10 |
11 | const result = add(1, 2);
12 |
13 | type test = Expect>;
14 |
--------------------------------------------------------------------------------
/src/015-essential-types-and-annotations/021-annotating-empty-parameters.problem.ts:
--------------------------------------------------------------------------------
1 | import { Expect, Equal } from "@total-typescript/helpers";
2 |
3 | // CODE
4 |
5 | const concatTwoStrings = (a, b) => {
6 | return [a, b].join(" ");
7 | };
8 |
9 | // TESTS
10 |
11 | const result = concatTwoStrings("Hello", "World");
12 |
13 | type test = Expect>;
14 |
--------------------------------------------------------------------------------
/src/015-essential-types-and-annotations/021-annotating-empty-parameters.solution.ts:
--------------------------------------------------------------------------------
1 | import { Expect, Equal } from "@total-typescript/helpers";
2 |
3 | // CODE
4 |
5 | const concatTwoStrings = (a: string, b: string) => {
6 | return [a, b].join(" ");
7 | };
8 |
9 | // TESTS
10 |
11 | const result = concatTwoStrings("Hello", "World");
12 |
13 | type test = Expect>;
14 |
--------------------------------------------------------------------------------
/src/015-essential-types-and-annotations/022-all-types.problem.ts:
--------------------------------------------------------------------------------
1 | let example1: string = "Hello World!";
2 | let example2: string = 42;
3 | let example3: string = true;
4 | let example4: string = Symbol();
5 | let example5: string = 123n;
6 |
--------------------------------------------------------------------------------
/src/015-essential-types-and-annotations/022-all-types.solution.1.ts:
--------------------------------------------------------------------------------
1 | let example1: string = "Hello World!";
2 | let example2: number = 42;
3 | let example3: boolean = true;
4 | let example4: symbol = Symbol();
5 | let example5: bigint = 123n;
6 |
--------------------------------------------------------------------------------
/src/015-essential-types-and-annotations/022-all-types.solution.2.ts:
--------------------------------------------------------------------------------
1 | let example1 = "Hello World!";
2 | let example2 = 42;
3 | let example3 = true;
4 | let example4 = Symbol();
5 | let example5 = 123n;
6 |
--------------------------------------------------------------------------------
/src/015-essential-types-and-annotations/027-type-keyword.solution.3.ts:
--------------------------------------------------------------------------------
1 | export type Rectangle = {
2 | width: number;
3 | height: number;
4 | };
5 |
--------------------------------------------------------------------------------
/src/015-essential-types-and-annotations/028-arrays.problem.ts:
--------------------------------------------------------------------------------
1 | // CODE
2 |
3 | // How do we type 'items' in the ShoppingCart?
4 | type ShoppingCart = {
5 | userId: string;
6 | };
7 |
8 | // TESTS
9 |
10 | const processCart = (cart: ShoppingCart) => {
11 | // Do something with the cart in here
12 | };
13 |
14 | processCart({
15 | userId: "user123",
16 | items: ["item1", "item2", "item3"],
17 | });
18 |
--------------------------------------------------------------------------------
/src/015-essential-types-and-annotations/028-arrays.solution.1.ts:
--------------------------------------------------------------------------------
1 | // How do we type 'items' in the ShoppingCart?
2 | type ShoppingCart = {
3 | userId: string;
4 | items: string[];
5 | };
6 |
7 | const processCart = (cart: ShoppingCart) => {
8 | // Do something with the cart in here
9 | };
10 |
11 | processCart({
12 | userId: "user123",
13 | items: ["item1", "item2", "item3"],
14 | });
15 |
--------------------------------------------------------------------------------
/src/015-essential-types-and-annotations/028-arrays.solution.2.ts:
--------------------------------------------------------------------------------
1 | // How do we type 'items' in the ShoppingCart?
2 | type ShoppingCart = {
3 | userId: string;
4 | items: Array;
5 | };
6 |
7 | const processCart = (cart: ShoppingCart) => {
8 | // Do something with the cart in here
9 | };
10 |
11 | processCart({
12 | userId: "user123",
13 | items: ["item1", "item2", "item3"],
14 | });
15 |
--------------------------------------------------------------------------------
/src/015-essential-types-and-annotations/029-arrays-of-objects.problem.ts:
--------------------------------------------------------------------------------
1 | type Recipe = {
2 | title: string;
3 | instructions: string;
4 | };
5 |
6 | const processRecipe = (recipe: Recipe) => {
7 | // Do something with the recipe in here
8 | };
9 |
10 | processRecipe({
11 | title: "Chocolate Chip Cookies",
12 | ingredients: [
13 | { name: "Flour", quantity: "2 cups" },
14 | { name: "Sugar", quantity: "1 cup" },
15 | ],
16 | instructions: "...",
17 | });
18 |
--------------------------------------------------------------------------------
/src/015-essential-types-and-annotations/030-rest-parameters-of-functions.problem.ts:
--------------------------------------------------------------------------------
1 | import { Expect, Equal } from "@total-typescript/helpers";
2 | import { expect, it } from "vitest";
3 |
4 | export function concatenate(...strings) {
5 | return strings.join("");
6 | }
7 |
8 | it("should concatenate strings", () => {
9 | const result = concatenate("Hello", " ", "World");
10 | expect(result).toEqual("Hello World");
11 |
12 | type test = Expect>;
13 | });
14 |
--------------------------------------------------------------------------------
/src/015-essential-types-and-annotations/034-functions-returning-void.problem.ts:
--------------------------------------------------------------------------------
1 | const addClickEventListener = (listener) => {
2 | document.addEventListener("click", listener);
3 | };
4 |
5 | addClickEventListener(() => {
6 | console.log("Clicked!");
7 | });
8 |
9 | addClickEventListener(
10 | // @ts-expect-error
11 | "abc",
12 | );
13 |
--------------------------------------------------------------------------------
/src/015-essential-types-and-annotations/034-functions-returning-void.solution.ts:
--------------------------------------------------------------------------------
1 | const addClickEventListener = (listener: () => void) => {
2 | document.addEventListener("click", listener);
3 | };
4 |
5 | addClickEventListener(() => {
6 | console.log("Clicked!");
7 | });
8 |
9 | addClickEventListener(
10 | // @ts-expect-error
11 | "abc",
12 | );
13 |
--------------------------------------------------------------------------------
/src/015-essential-types-and-annotations/034.5-void-vs-undefined.problem.ts:
--------------------------------------------------------------------------------
1 | const acceptsCallback = (callback: () => undefined) => {
2 | callback();
3 | };
4 |
5 | const returnString = () => {
6 | return "Hello!";
7 | };
8 |
9 | acceptsCallback(returnString);
10 |
--------------------------------------------------------------------------------
/src/015-essential-types-and-annotations/034.5-void-vs-undefined.solution.ts:
--------------------------------------------------------------------------------
1 | const acceptsCallback = (callback: () => void) => {
2 | callback();
3 | };
4 |
5 | const returnString = () => {
6 | return "Hello!";
7 | };
8 |
9 | acceptsCallback(returnString);
10 |
--------------------------------------------------------------------------------
/src/015-essential-types-and-annotations/035-pass-types-to-set.problem.ts:
--------------------------------------------------------------------------------
1 | // CODE
2 |
3 | const userIds = new Set();
4 |
5 | // TESTS
6 |
7 | userIds.add(1);
8 | userIds.add(2);
9 | userIds.add(3);
10 |
11 | // @ts-expect-error
12 | userIds.add("123");
13 | // @ts-expect-error
14 | userIds.add({ name: "Max" });
15 |
--------------------------------------------------------------------------------
/src/015-essential-types-and-annotations/035-pass-types-to-set.solution.1.ts:
--------------------------------------------------------------------------------
1 | const userIds = new Set();
2 |
3 | userIds.add(1);
4 | userIds.add(2);
5 | userIds.add(3);
6 |
7 | // @ts-expect-error
8 | userIds.add("123");
9 | // @ts-expect-error
10 | userIds.add({ name: "Max" });
11 |
--------------------------------------------------------------------------------
/src/015-essential-types-and-annotations/035-pass-types-to-set.solution.2.ts:
--------------------------------------------------------------------------------
1 | const userIds: Set = new Set();
2 |
3 | userIds.add(1);
4 | userIds.add(2);
5 | userIds.add(3);
6 |
7 | // @ts-expect-error
8 | userIds.add("123");
9 | // @ts-expect-error
10 | userIds.add({ name: "Max" });
11 |
--------------------------------------------------------------------------------
/src/015-essential-types-and-annotations/036-pass-types-to-map.problem.ts:
--------------------------------------------------------------------------------
1 | // CODE
2 |
3 | const userMap = new Map();
4 |
5 | // TESTS
6 |
7 | userMap.set(1, { name: "Max", age: 30 });
8 | userMap.set(2, { name: "Manuel", age: 31 });
9 |
10 | // @ts-expect-error
11 | userMap.set("3", { name: "Anna", age: 29 });
12 |
13 | // @ts-expect-error
14 | userMap.set(3, "123");
15 |
--------------------------------------------------------------------------------
/src/015-essential-types-and-annotations/036-pass-types-to-map.solution.1.ts:
--------------------------------------------------------------------------------
1 | type User = {
2 | name: string;
3 | age: number;
4 | };
5 |
6 | const userMap = new Map();
7 |
8 | userMap.set(1, { name: "Max", age: 30 });
9 | userMap.set(2, { name: "Manuel", age: 31 });
10 |
11 | // @ts-expect-error
12 | userMap.set("3", { name: "Anna", age: 29 });
13 |
14 | // @ts-expect-error
15 | userMap.set(3, "123");
16 |
--------------------------------------------------------------------------------
/src/015-essential-types-and-annotations/036-pass-types-to-map.solution.2.ts:
--------------------------------------------------------------------------------
1 | const userMap = new Map();
2 |
3 | userMap.set(1, { name: "Max", age: 30 });
4 | userMap.set(2, { name: "Manuel", age: 31 });
5 |
6 | // @ts-expect-error
7 | userMap.set("3", { name: "Anna", age: 29 });
8 |
9 | // @ts-expect-error
10 | userMap.set(3, "123");
11 |
--------------------------------------------------------------------------------
/src/015-essential-types-and-annotations/036-pass-types-to-map.solution.3.ts:
--------------------------------------------------------------------------------
1 | const userMap: Map = new Map();
2 |
3 | userMap.set(1, { name: "Max", age: 30 });
4 | userMap.set(2, { name: "Manuel", age: 31 });
5 |
6 | // @ts-expect-error
7 | userMap.set("3", { name: "Anna", age: 29 });
8 |
9 | // @ts-expect-error
10 | userMap.set(3, "123");
11 |
--------------------------------------------------------------------------------
/src/015-essential-types-and-annotations/036-pass-types-to-map.solution.4.ts:
--------------------------------------------------------------------------------
1 | type User = {
2 | name: string;
3 | age: number;
4 | };
5 |
6 | const userMap: Map = new Map();
7 |
8 | userMap.set(1, { name: "Max", age: 30 });
9 | userMap.set(2, { name: "Manuel", age: 31 });
10 |
11 | // @ts-expect-error
12 | userMap.set("3", { name: "Anna", age: 29 });
13 |
14 | // @ts-expect-error
15 | userMap.set(3, "123");
16 |
--------------------------------------------------------------------------------
/src/015-essential-types-and-annotations/038-type-async-functions.problem.ts:
--------------------------------------------------------------------------------
1 | import { Expect, Equal } from "@total-typescript/helpers";
2 |
3 | async function fetchData() {
4 | const response = await fetch("https://api.example.com/data");
5 | const data = await response.json();
6 | return data;
7 | }
8 |
9 | const example = async () => {
10 | const data = await fetchData();
11 |
12 | type test = Expect>;
13 | };
14 |
--------------------------------------------------------------------------------
/src/015-essential-types-and-annotations/038-type-async-functions.solution.1.ts:
--------------------------------------------------------------------------------
1 | import { Expect, Equal } from "@total-typescript/helpers";
2 |
3 | async function fetchData(): Promise {
4 | const response = await fetch("https://api.example.com/data");
5 | const data = await response.json();
6 | return data;
7 | }
8 |
9 | const example = async () => {
10 | const data = await fetchData();
11 |
12 | type test = Expect>;
13 | };
14 |
--------------------------------------------------------------------------------
/src/015-essential-types-and-annotations/038-type-async-functions.solution.2.ts:
--------------------------------------------------------------------------------
1 | import { Expect, Equal } from "@total-typescript/helpers";
2 |
3 | async function fetchData() {
4 | const response = await fetch("https://api.example.com/data");
5 | const data: number = await response.json();
6 | return data;
7 | }
8 |
9 | const example = async () => {
10 | const data = await fetchData();
11 |
12 | type test = Expect>;
13 | };
14 |
--------------------------------------------------------------------------------
/src/016.5-ide-superpowers/039-understand-the-ts-server.explainer.ts:
--------------------------------------------------------------------------------
1 | // Explain Diagram
2 |
--------------------------------------------------------------------------------
/src/016.5-ide-superpowers/040-understand-how-to-hover-a-variable-to-see-its-type.explainer.ts:
--------------------------------------------------------------------------------
1 | let thing = 123;
2 |
3 | let otherThing = {
4 | name: "Alice",
5 | };
6 |
7 | const otherObject = {
8 | ...otherThing,
9 | thing,
10 | };
11 |
12 | otherObject.thing;
13 |
--------------------------------------------------------------------------------
/src/016.5-ide-superpowers/041-hovering-a-function-call.problem.ts:
--------------------------------------------------------------------------------
1 | const element = document.getElementById(12);
2 |
--------------------------------------------------------------------------------
/src/016.5-ide-superpowers/041-hovering-a-function-call.solution.ts:
--------------------------------------------------------------------------------
1 | const element = document.getElementById("12");
2 |
--------------------------------------------------------------------------------
/src/016.5-ide-superpowers/042-adding-tsdoc-comments-for-hovers.problem.ts:
--------------------------------------------------------------------------------
1 | const myFunction = (a: number, b: number) => {
2 | return a + b;
3 | };
4 |
--------------------------------------------------------------------------------
/src/016.5-ide-superpowers/042-adding-tsdoc-comments-for-hovers.solution.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Adds two numbers together.
3 | *
4 | * @example
5 | *
6 | * myFunction(1, 2);
7 | */
8 | const myFunction = (a: number, b: number) => {
9 | return a + b;
10 | };
11 |
--------------------------------------------------------------------------------
/src/016.5-ide-superpowers/044-manually-triggering-autocomplete.problem.ts:
--------------------------------------------------------------------------------
1 | type MyObj = {
2 | foo: string;
3 | bar: number;
4 | baz: boolean;
5 | };
6 |
7 | const acceptsObj = (obj: MyObj) => {};
8 |
9 | acceptsObj({
10 | // Autocomplete in here!
11 | });
12 |
13 | document.addEventListener(
14 | // Autocomplete this string!
15 | "",
16 | (event) => {
17 | console.log(event);
18 | },
19 | );
20 |
--------------------------------------------------------------------------------
/src/016.5-ide-superpowers/044-manually-triggering-autocomplete.solution.ts:
--------------------------------------------------------------------------------
1 | type MyObj = {
2 | foo: string;
3 | bar: number;
4 | baz: boolean;
5 | };
6 |
7 | const acceptsObj = (obj: MyObj) => {};
8 |
9 | acceptsObj({
10 | foo: "hello",
11 | bar: 123,
12 | baz: true,
13 | });
14 |
15 | document.addEventListener(
16 | // Autocomplete this string!
17 | "",
18 | (event) => {
19 | console.log(event);
20 | },
21 | );
22 |
--------------------------------------------------------------------------------
/src/016.5-ide-superpowers/046-go-to-definition.explainer.ts:
--------------------------------------------------------------------------------
1 | // You can use go to definition to jump to the definition of something
2 |
3 | const myFunction = () => {
4 | console.log("Hello!");
5 | };
6 |
7 | myFunction();
8 |
9 | // This can work across files, too:
10 |
11 | import { hiThere } from "./dummy-import";
12 |
13 | hiThere();
14 |
15 | // As well as on types:
16 |
17 | type Example = PropertyKey;
18 |
19 | // It can also take you to mysterious places:
20 |
21 | document;
22 |
--------------------------------------------------------------------------------
/src/016.5-ide-superpowers/047-rename-symbol.explainer.ts:
--------------------------------------------------------------------------------
1 | const users = [
2 | { id: "1", name: "Robin" },
3 | { id: "2", name: "Dennis" },
4 | { id: "3", name: "Sara" },
5 | ];
6 |
7 | // Imagine this function was 10x bigger
8 | // with 10x more references to `id`
9 |
10 | // How do we change id to userId?
11 | const filterUsersById = (id: string) => {
12 | return users.filter((user) => user.id === id);
13 | };
14 |
--------------------------------------------------------------------------------
/src/016.5-ide-superpowers/048-auto-import.problem.ts:
--------------------------------------------------------------------------------
1 | const expirationTimes = [
2 | SESSION_EXPIRATION_TIME,
3 | SESSION_EXPIRATION_TIME_IN_SECONDS,
4 | SESSION_EXPIRATION_TIME_IN_MINUTES,
5 | SESSION_EXPIRATION_TIME_IN_HOURS,
6 | ];
7 |
--------------------------------------------------------------------------------
/src/016.5-ide-superpowers/048-auto-import.solution.ts:
--------------------------------------------------------------------------------
1 | import {
2 | SESSION_EXPIRATION_TIME,
3 | SESSION_EXPIRATION_TIME_IN_SECONDS,
4 | SESSION_EXPIRATION_TIME_IN_MINUTES,
5 | SESSION_EXPIRATION_TIME_IN_HOURS,
6 | } from "./dummy-import";
7 |
8 | const expirationTimes = [
9 | SESSION_EXPIRATION_TIME,
10 | SESSION_EXPIRATION_TIME_IN_SECONDS,
11 | SESSION_EXPIRATION_TIME_IN_MINUTES,
12 | SESSION_EXPIRATION_TIME_IN_HOURS,
13 | ];
14 |
--------------------------------------------------------------------------------
/src/016.5-ide-superpowers/049-organize-imports.problem.ts:
--------------------------------------------------------------------------------
1 | import {
2 | MAX_PAGE,
3 | DEFAULT_COLOR,
4 | DEFAULT_FILTER,
5 | DEFAULT_PAGE,
6 | DEFAULT_SORT,
7 | DEFAULT_USERNAME,
8 | FILTER_OPTIONS,
9 | } from "./dummy-import-2";
10 |
11 | const handlePage = (page: number) => {
12 | if (page > MAX_PAGE) {
13 | console.log("Page is too large!");
14 | }
15 | };
16 |
--------------------------------------------------------------------------------
/src/016.5-ide-superpowers/049-organize-imports.solution.ts:
--------------------------------------------------------------------------------
1 | import { MAX_PAGE } from "./dummy-import-2";
2 |
3 | const handlePage = (page: number) => {
4 | if (page > MAX_PAGE) {
5 | console.log("Page is too large!");
6 | }
7 | };
8 |
--------------------------------------------------------------------------------
/src/016.5-ide-superpowers/050-refactor.problem.ts:
--------------------------------------------------------------------------------
1 | const func = () => {
2 | // Refactor this to be its own function
3 | const randomPercentage = `${(Math.random() * 100).toFixed(2)}%`;
4 | console.log(randomPercentage);
5 | };
6 |
--------------------------------------------------------------------------------
/src/016.5-ide-superpowers/050-refactor.solution.ts:
--------------------------------------------------------------------------------
1 | const func = () => {
2 | // Refactor this to be its own function
3 | const randomPercentage = getRandomPercentage();
4 | console.log(randomPercentage);
5 | };
6 |
7 | function getRandomPercentage() {
8 | return `${(Math.random() * 100).toFixed(2)}%`;
9 | }
10 |
--------------------------------------------------------------------------------
/src/016.5-ide-superpowers/051-prettier-format-on-save.explainer.ts:
--------------------------------------------------------------------------------
1 | // Explain prettier
2 |
3 | // Explain how to set up prettier
4 |
5 | // Explain how to set up formatOnSave
6 |
--------------------------------------------------------------------------------
/src/016.5-ide-superpowers/052-resetting-the-typescript-server.explainer.ts:
--------------------------------------------------------------------------------
1 | // When configs change
2 |
3 | // Sometimes TS can get out of sync because it doesn't notice a file changed
4 |
5 | // It's always good to have in your back pocket
6 |
--------------------------------------------------------------------------------
/src/018-unions-and-narrowing/056-how-big-can-a-union-be.explainer.ts:
--------------------------------------------------------------------------------
1 | type Alphabet =
2 | | "a"
3 | | "b"
4 | | "c"
5 | | "d"
6 | | "e"
7 | | "f"
8 | | "g"
9 | | "h"
10 | | "i"
11 | | "j"
12 | | "k"
13 | | "l"
14 | | "m"
15 | | "n"
16 | | "o"
17 | | "p"
18 | | "q"
19 | | "r"
20 | | "s"
21 | | "t"
22 | | "u"
23 | | "v"
24 | | "w"
25 | | "x"
26 | | "y"
27 | | "z";
28 |
29 | type TooBig = `${Alphabet}${Alphabet}${Alphabet}${Alphabet}`;
30 |
--------------------------------------------------------------------------------
/src/018-unions-and-narrowing/058-narrowing-unions-with-typeof.explainer.ts:
--------------------------------------------------------------------------------
1 | const convertTime = (time: string | number) => {
2 | if (typeof time === "string") {
3 | console.log(time); // string
4 | } else {
5 | console.log(time); // number
6 | }
7 |
8 | console.log(time); // string | number
9 | };
10 |
--------------------------------------------------------------------------------
/src/018-unions-and-narrowing/061-map-has-doesnt-narrow-map-get.problem.ts:
--------------------------------------------------------------------------------
1 | type Event = {
2 | message: string;
3 | };
4 |
5 | const processUserMap = (eventMap: Map) => {
6 | if (eventMap.has("error")) {
7 | const message = eventMap.get("error").message;
8 |
9 | throw new Error(message);
10 | }
11 | };
12 |
--------------------------------------------------------------------------------
/src/018-unions-and-narrowing/061-map-has-doesnt-narrow-map-get.solution.ts:
--------------------------------------------------------------------------------
1 | type Event = {
2 | message: string;
3 | };
4 |
5 | const processUserMap = (eventMap: Map) => {
6 | const event = eventMap.get("error");
7 | if (event) {
8 | const message = event.message;
9 |
10 | throw new Error(message);
11 | }
12 | };
13 |
--------------------------------------------------------------------------------
/src/018-unions-and-narrowing/062-throwing-errors-to-narrow.problem.ts:
--------------------------------------------------------------------------------
1 | import { Equal, Expect } from "@total-typescript/helpers";
2 |
3 | const appElement = document.getElementById("app");
4 |
5 | // How do I ensure that appElement is defined?
6 |
7 | type Test = Expect>;
8 |
--------------------------------------------------------------------------------
/src/018-unions-and-narrowing/062-throwing-errors-to-narrow.solution.ts:
--------------------------------------------------------------------------------
1 | import { Equal, Expect } from "@total-typescript/helpers";
2 |
3 | const appElement = document.getElementById("app");
4 |
5 | if (!appElement) {
6 | throw new Error("Could not find app element");
7 | }
8 |
9 | type Test = Expect>;
10 |
--------------------------------------------------------------------------------
/src/018-unions-and-narrowing/065-introduction-to-unknown.explainer.ts:
--------------------------------------------------------------------------------
1 | const fn = (input: unknown) => {};
2 |
3 | // Anything is assignable to unknown!
4 | fn("hello");
5 | fn(42);
6 | fn(true);
7 | fn({});
8 | fn([]);
9 | fn(() => {});
10 |
--------------------------------------------------------------------------------
/src/018-unions-and-narrowing/065.5-narrowing-with-instanceof-statements.problem.ts:
--------------------------------------------------------------------------------
1 | const somethingDangerous = () => {
2 | if (Math.random() > 0.5) {
3 | throw new Error("Something went wrong");
4 | }
5 |
6 | return "all good";
7 | };
8 |
9 | try {
10 | somethingDangerous();
11 | } catch (error) {
12 | // How do we change this code to make it
13 | // not show a red squiggly?
14 | if (true) {
15 | console.error(error.message);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/018-unions-and-narrowing/065.5-narrowing-with-instanceof-statements.solution.ts:
--------------------------------------------------------------------------------
1 | const somethingDangerous = () => {
2 | if (Math.random() > 0.5) {
3 | throw new Error("Something went wrong");
4 | }
5 |
6 | return "all good";
7 | };
8 |
9 | try {
10 | somethingDangerous();
11 | } catch (error) {
12 | if (error instanceof Error) {
13 | console.error(error.message);
14 | } else {
15 | throw error;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/018-unions-and-narrowing/067.5-never-array.problem.ts:
--------------------------------------------------------------------------------
1 | const shoppingCart = {
2 | items: [],
3 | };
4 |
5 | console.log(shoppingCart.items);
6 |
7 | shoppingCart.items.push("Apple");
8 | shoppingCart.items.push("Banana");
9 |
--------------------------------------------------------------------------------
/src/018-unions-and-narrowing/067.5-never-array.solution.ts:
--------------------------------------------------------------------------------
1 | type ShoppingCart = {
2 | items: string[];
3 | };
4 |
5 | const shoppingCart: ShoppingCart = {
6 | items: [],
7 | };
8 |
9 | console.log(shoppingCart.items);
10 |
11 | shoppingCart.items.push("Apple");
12 | shoppingCart.items.push("Banana");
13 |
--------------------------------------------------------------------------------
/src/018-unions-and-narrowing/068-returning-never-to-narrow.problem.ts:
--------------------------------------------------------------------------------
1 | import { Equal, Expect } from "@total-typescript/helpers";
2 |
3 | const throwError = (message: string): undefined => {
4 | throw new Error(message);
5 | };
6 |
7 | const handleSearchParams = (params: { id?: string }) => {
8 | const id = params.id || throwError("No id provided");
9 |
10 | type test = Expect>;
11 |
12 | return id;
13 | };
14 |
--------------------------------------------------------------------------------
/src/018-unions-and-narrowing/068-returning-never-to-narrow.solution.1.ts:
--------------------------------------------------------------------------------
1 | import { Equal, Expect } from "@total-typescript/helpers";
2 |
3 | const throwError = (message: string): never => {
4 | throw new Error(message);
5 | };
6 |
7 | const handleSearchParams = (params: { id?: string }) => {
8 | const id = params.id || throwError("No id provided");
9 |
10 | type test = Expect>;
11 |
12 | return id;
13 | };
14 |
--------------------------------------------------------------------------------
/src/018-unions-and-narrowing/068-returning-never-to-narrow.solution.2.ts:
--------------------------------------------------------------------------------
1 | import { Equal, Expect } from "@total-typescript/helpers";
2 |
3 | const throwError = (message: string) => {
4 | throw new Error(message);
5 | };
6 |
7 | const handleSearchParams = (params: { id?: string }) => {
8 | const id = params.id || throwError("No id provided");
9 |
10 | type test = Expect>;
11 |
12 | return id;
13 | };
14 |
--------------------------------------------------------------------------------
/src/020-objects/082.5-extending-incompatible-properties.problem.ts:
--------------------------------------------------------------------------------
1 | type UserPart = {
2 | id: string;
3 | name: string;
4 | age: number;
5 | };
6 |
7 | type UserPart2 = {
8 | id: number;
9 | phone: string;
10 | };
11 |
12 | type User = UserPart & UserPart2;
13 |
14 | const user: User = {
15 | id: "1",
16 | name: "John",
17 | age: 20,
18 | phone: "123456789",
19 | };
20 |
--------------------------------------------------------------------------------
/src/020-objects/082.5-extending-incompatible-properties.solution.ts:
--------------------------------------------------------------------------------
1 | type UserPart = {
2 | id: string;
3 | name: string;
4 | age: number;
5 | };
6 |
7 | type UserPart2 = {
8 | id: number;
9 | phone: string;
10 | };
11 |
12 | interface User extends UserPart, UserPart2 {}
13 |
14 | const user: User = {
15 | id: "1",
16 | name: "John",
17 | age: 20,
18 | phone: "123456789",
19 | };
20 |
--------------------------------------------------------------------------------
/src/020-objects/083-compare-between-intersections-and-interfaces.explainer.ts:
--------------------------------------------------------------------------------
1 | // https://github.com/microsoft/TypeScript/wiki/Performance#preferring-interfaces-over-intersections
2 |
--------------------------------------------------------------------------------
/src/020-objects/084-index-signatures.problem.ts:
--------------------------------------------------------------------------------
1 | const scores = {};
2 |
3 | scores.math = 95;
4 | scores.english = 90;
5 | scores.science = 85;
6 |
--------------------------------------------------------------------------------
/src/020-objects/084-index-signatures.solution.1.ts:
--------------------------------------------------------------------------------
1 | type Scores = {
2 | [key: string]: number;
3 | };
4 |
5 | const scores: Scores = {};
6 |
7 | scores.math = 95;
8 | scores.english = 90;
9 | scores.science = 85;
10 |
--------------------------------------------------------------------------------
/src/020-objects/084-index-signatures.solution.2.ts:
--------------------------------------------------------------------------------
1 | interface Scores {
2 | [key: string]: number;
3 | }
4 |
5 | const scores: Scores = {};
6 |
7 | scores.math = 95;
8 | scores.english = 90;
9 | scores.science = 85;
10 |
--------------------------------------------------------------------------------
/src/020-objects/084-index-signatures.solution.3.ts:
--------------------------------------------------------------------------------
1 | const scores: {
2 | [key: string]: number;
3 | } = {};
4 |
5 | scores.math = 95;
6 | scores.english = 90;
7 | scores.science = 85;
8 |
--------------------------------------------------------------------------------
/src/020-objects/084-index-signatures.solution.4.ts:
--------------------------------------------------------------------------------
1 | const scores: Record = {};
2 |
3 | scores.math = 95;
4 | scores.english = 90;
5 | scores.science = 85;
6 |
--------------------------------------------------------------------------------
/src/020-objects/085-index-signatures-with-defined-keys.problem.ts:
--------------------------------------------------------------------------------
1 | interface Scores {}
2 |
3 | // @ts-expect-error science is missing!
4 | const scores: Scores = {
5 | math: 95,
6 | english: 90,
7 | };
8 |
9 | scores.athletics = 100;
10 | scores.french = 75;
11 | scores.spanish = 70;
12 |
--------------------------------------------------------------------------------
/src/020-objects/085-index-signatures-with-defined-keys.solution.1.ts:
--------------------------------------------------------------------------------
1 | interface Scores {
2 | [key: string]: number;
3 | math: number;
4 | english: number;
5 | science: number;
6 | }
7 |
8 | // @ts-expect-error science is missing!
9 | const scores: Scores = {
10 | math: 95,
11 | english: 90,
12 | };
13 |
14 | scores.athletics = 100;
15 | scores.french = 75;
16 | scores.spanish = 70;
17 |
--------------------------------------------------------------------------------
/src/020-objects/085-index-signatures-with-defined-keys.solution.2.ts:
--------------------------------------------------------------------------------
1 | interface RequiredScores {
2 | math: number;
3 | english: number;
4 | science: number;
5 | }
6 |
7 | interface Scores extends RequiredScores {
8 | [key: string]: number;
9 | }
10 |
11 | // @ts-expect-error science is missing!
12 | const scores: Scores = {
13 | math: 95,
14 | english: 90,
15 | };
16 |
17 | scores.athletics = 100;
18 | scores.french = 75;
19 | scores.spanish = 70;
20 |
--------------------------------------------------------------------------------
/src/020-objects/088-declaration-merging-of-interfaces.problem.ts:
--------------------------------------------------------------------------------
1 | interface Logger {
2 | log(message: string, level: number): void;
3 | }
4 |
5 | interface Logger {
6 | log(message: string): void;
7 | }
8 |
9 | const myLogger: Logger = {
10 | log: (message: string) => {
11 | console.log(message);
12 | },
13 | };
14 |
15 | myLogger.log(
16 | "My message",
17 | // @ts-expect-error Level is NOT needed
18 | 123,
19 | );
20 |
--------------------------------------------------------------------------------
/src/020-objects/088-declaration-merging-of-interfaces.solution.ts:
--------------------------------------------------------------------------------
1 | type Logger = {
2 | log(message: string): void;
3 | };
4 |
5 | const myLogger: Logger = {
6 | log: (message: string) => {
7 | console.log(message);
8 | },
9 | };
10 |
11 | myLogger.log(
12 | "My message",
13 | // @ts-expect-error Level is NOT needed
14 | 123,
15 | );
16 |
--------------------------------------------------------------------------------
/src/020-objects/096-required-type-helper.explainer.ts:
--------------------------------------------------------------------------------
1 | import { Equal, Expect } from "@total-typescript/helpers";
2 |
3 | type Coordinates = {
4 | x?: number;
5 | y?: number;
6 | };
7 |
8 | type CoordinatesRequired = Required;
9 |
10 | type test = Expect>;
11 |
--------------------------------------------------------------------------------
/src/028-mutability/097-let-and-const-inference.problem.ts:
--------------------------------------------------------------------------------
1 | // CODE
2 |
3 | let type = "button";
4 |
5 | // TESTS
6 |
7 | type ButtonAttributes = {
8 | type: "button" | "submit" | "reset";
9 | };
10 |
11 | const buttonAttributes: ButtonAttributes = {
12 | type,
13 | };
14 |
--------------------------------------------------------------------------------
/src/028-mutability/097-let-and-const-inference.solution.1.ts:
--------------------------------------------------------------------------------
1 | type ButtonType = "button" | "submit" | "reset";
2 |
3 | type ButtonAttributes = {
4 | type: ButtonType;
5 | };
6 |
7 | let type: ButtonType = "button";
8 |
9 | const buttonAttributes: ButtonAttributes = {
10 | type,
11 | };
12 |
--------------------------------------------------------------------------------
/src/028-mutability/097-let-and-const-inference.solution.2.ts:
--------------------------------------------------------------------------------
1 | type ButtonAttributes = {
2 | type: "button" | "submit" | "reset";
3 | };
4 |
5 | const type = "button";
6 |
7 | const buttonAttributes: ButtonAttributes = {
8 | type,
9 | };
10 |
--------------------------------------------------------------------------------
/src/028-mutability/099-readonly-object-properties.problem.ts:
--------------------------------------------------------------------------------
1 | type User = {
2 | id: number;
3 | name: string;
4 | age: number;
5 | };
6 |
7 | const updateUser = (user: User) => {
8 | user.name = "Jane Doe";
9 | user.age = 30;
10 |
11 | // @ts-expect-error Should not be able to modify readonly
12 | user.id = 1;
13 | };
14 |
--------------------------------------------------------------------------------
/src/028-mutability/099-readonly-object-properties.solution.ts:
--------------------------------------------------------------------------------
1 | type User = {
2 | readonly id: number;
3 | name: string;
4 | age: number;
5 | };
6 |
7 | const updateUser = (user: User) => {
8 | user.name = "Jane Doe";
9 | user.age = 30;
10 |
11 | // @ts-expect-error Should not be able to modify readonly
12 | user.id = 1;
13 | };
14 |
--------------------------------------------------------------------------------
/src/028-mutability/101-intro-to-as-const.problem.ts:
--------------------------------------------------------------------------------
1 | type ButtonAttributes = {
2 | type: "button" | "submit" | "reset";
3 | };
4 |
5 | const modifyButton = (attributes: ButtonAttributes) => {};
6 |
7 | const buttonAttributes = {
8 | type: "button",
9 | };
10 |
11 | modifyButton(buttonAttributes);
12 |
--------------------------------------------------------------------------------
/src/028-mutability/101-intro-to-as-const.solution.ts:
--------------------------------------------------------------------------------
1 | type ButtonAttributes = {
2 | type: "button" | "submit" | "reset";
3 | };
4 |
5 | const modifyButton = (attributes: ButtonAttributes) => {};
6 |
7 | const buttonAttributes = {
8 | type: "button",
9 | } as const;
10 |
11 | modifyButton(buttonAttributes);
12 |
--------------------------------------------------------------------------------
/src/028-mutability/103-readonly-arrays.problem.ts:
--------------------------------------------------------------------------------
1 | function printNames(names: string[]) {
2 | for (const name of names) {
3 | console.log(name);
4 | }
5 |
6 | // @ts-expect-error
7 | names.push("John");
8 |
9 | // @ts-expect-error
10 | names[0] = "Billy";
11 | }
12 |
--------------------------------------------------------------------------------
/src/028-mutability/103-readonly-arrays.solution.1.ts:
--------------------------------------------------------------------------------
1 | function printNames(names: readonly string[]) {
2 | for (const name of names) {
3 | console.log(name);
4 | }
5 |
6 | // @ts-expect-error
7 | names.push("John");
8 |
9 | // @ts-expect-error
10 | names[0] = "Billy";
11 | }
12 |
--------------------------------------------------------------------------------
/src/028-mutability/103-readonly-arrays.solution.2.ts:
--------------------------------------------------------------------------------
1 | function printNames(names: ReadonlyArray) {
2 | for (const name of names) {
3 | console.log(name);
4 | }
5 |
6 | // @ts-expect-error
7 | names.push("John");
8 |
9 | // @ts-expect-error
10 | names[0] = "Billy";
11 | }
12 |
--------------------------------------------------------------------------------
/src/028-mutability/104.5-fixing-unsafe-tuples.problem.ts:
--------------------------------------------------------------------------------
1 | type Coordinate = [number, number];
2 | const myHouse: Coordinate = [0, 0];
3 |
4 | const dangerousFunction = (arrayOfNumbers: number[]) => {
5 | arrayOfNumbers.pop();
6 | arrayOfNumbers.pop();
7 | };
8 |
9 | dangerousFunction(
10 | // @ts-expect-error
11 | myHouse,
12 | );
13 |
--------------------------------------------------------------------------------
/src/028-mutability/104.5-fixing-unsafe-tuples.solution.ts:
--------------------------------------------------------------------------------
1 | type Coordinate = readonly [number, number];
2 | const myHouse: Coordinate = [0, 0];
3 |
4 | const dangerousFunction = (arrayOfNumbers: number[]) => {
5 | arrayOfNumbers.pop();
6 | arrayOfNumbers.pop();
7 | };
8 |
9 | dangerousFunction(
10 | // @ts-expect-error
11 | myHouse,
12 | );
13 |
--------------------------------------------------------------------------------
/src/028-mutability/105-includes-on-readonly-arrays.explainer.ts:
--------------------------------------------------------------------------------
1 | // Try uncommenting this!
2 | // import "@total-typescript/ts-reset";
3 |
4 | const users = ["matt", "sofia", "waqas"] as const;
5 |
6 | users.includes("bryan");
7 |
8 | users.indexOf("bryan");
9 |
--------------------------------------------------------------------------------
/src/030-classes/108-understand-classes.problem.ts:
--------------------------------------------------------------------------------
1 | import { expect, it } from "vitest";
2 |
3 | class CanvasNode {}
4 |
5 | it("Should store some basic properties", () => {
6 | const canvasNode = new CanvasNode();
7 |
8 | expect(canvasNode.x).toEqual(0);
9 | expect(canvasNode.y).toEqual(0);
10 |
11 | // @ts-expect-error Property is readonly
12 | canvasNode.x = 10;
13 |
14 | // @ts-expect-error Property is readonly
15 | canvasNode.y = 20;
16 | });
17 |
--------------------------------------------------------------------------------
/src/030-classes/109-class-methods.problem.ts:
--------------------------------------------------------------------------------
1 | import { expect, it } from "vitest";
2 |
3 | class CanvasNode {
4 | x = 0;
5 | y = 0;
6 | }
7 |
8 | it("Should be able to move", () => {
9 | const canvasNode = new CanvasNode();
10 |
11 | expect(canvasNode.x).toEqual(0);
12 | expect(canvasNode.y).toEqual(0);
13 |
14 | canvasNode.move(10, 20);
15 |
16 | expect(canvasNode.x).toEqual(10);
17 | expect(canvasNode.y).toEqual(20);
18 | });
19 |
--------------------------------------------------------------------------------
/src/032-typescript-only-features/116.5-intro.explainer.ts:
--------------------------------------------------------------------------------
1 | // Introduce TS-only features
2 |
--------------------------------------------------------------------------------
/src/032-typescript-only-features/120-const-enums.explainer/index.ts:
--------------------------------------------------------------------------------
1 | const enum Direction {
2 | Up,
3 | Down,
4 | Left,
5 | Right,
6 | }
7 |
8 | let directions = [
9 | Direction.Up,
10 | Direction.Down,
11 | Direction.Left,
12 | Direction.Right,
13 | ];
14 |
--------------------------------------------------------------------------------
/src/032-typescript-only-features/120-const-enums.explainer/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "117-const-enums.explainer",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "dev": "tsc --watch"
8 | },
9 | "keywords": [],
10 | "author": "Matt Pocock",
11 | "license": "ISC"
12 | }
13 |
--------------------------------------------------------------------------------
/src/032-typescript-only-features/120-const-enums.explainer/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2022",
4 | "outDir": "dist",
5 | "module": "ESNext",
6 | "moduleResolution": "Bundler",
7 | "esModuleInterop": true,
8 | "declaration": true,
9 | "strict": true,
10 | "skipLibCheck": true
11 | },
12 | }
--------------------------------------------------------------------------------
/src/032-typescript-only-features/124-prefer-es-features-to-ts-features.explainer/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "117-const-enums.explainer",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "dev": "tsc --watch"
8 | },
9 | "keywords": [],
10 | "author": "Matt Pocock",
11 | "license": "ISC"
12 | }
13 |
--------------------------------------------------------------------------------
/src/032-typescript-only-features/124-prefer-es-features-to-ts-features.explainer/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2022",
4 | "outDir": "dist",
5 | "module": "ESNext",
6 | "moduleResolution": "Bundler",
7 | "esModuleInterop": true,
8 | "declaration": true,
9 | "strict": true,
10 | "skipLibCheck": true
11 | },
12 | }
--------------------------------------------------------------------------------
/src/040-deriving-types-from-values/124.5-intro.explainer.ts:
--------------------------------------------------------------------------------
1 | // Explain why deriving types from other
2 | // types (and from values) is so important
3 |
--------------------------------------------------------------------------------
/src/040-deriving-types-from-values/128-create-runtime-values-from-types.explainer.ts:
--------------------------------------------------------------------------------
1 | // We can create types from values...
2 |
3 | const user = {
4 | id: 1,
5 | name: "Waqas",
6 | };
7 |
8 | type UserFromValue = typeof user;
9 |
10 | // ...so why not values from types?
11 |
12 | interface User {
13 | id: number;
14 | name: string;
15 | }
16 |
17 | // Can we do this?
18 | // const user = valueof User;
19 |
--------------------------------------------------------------------------------
/src/040-deriving-types-from-values/129.5-enums-cross-value-and-type-world.explainer.ts:
--------------------------------------------------------------------------------
1 | enum LogLevel {
2 | DEBUG = 0,
3 | INFO = 1,
4 | WARN = 2,
5 | ERROR = 3,
6 | }
7 |
8 | function log(opts: {
9 | globalLogLevel: LogLevel;
10 | level: LogLevel;
11 | message: string;
12 | }) {
13 | if (opts.level >= opts.globalLogLevel) {
14 | console.log(opts.message);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/040-deriving-types-from-values/131-naming-values-and-types-the-same.explainer.2.ts:
--------------------------------------------------------------------------------
1 | import { Logger } from "./131-naming-values-and-types-the-same.explainer.1";
2 |
3 | const myApp = (logger: Logger) => {
4 | logger.log("Hello");
5 | logger.info("Hello");
6 | logger.warn("Hello");
7 | logger.error("Hello");
8 | };
9 |
10 | myApp(Logger);
11 |
--------------------------------------------------------------------------------
/src/040-deriving-types-from-values/133-return-type.problem.ts:
--------------------------------------------------------------------------------
1 | import { Equal, Expect } from "@total-typescript/helpers";
2 |
3 | const createUser = (id: string) => {
4 | return {
5 | id,
6 | name: "John Doe",
7 | email: "example@email.com",
8 | };
9 | };
10 |
11 | type User = unknown;
12 |
13 | type test = Expect<
14 | Equal<
15 | User,
16 | {
17 | id: string;
18 | name: string;
19 | email: string;
20 | }
21 | >
22 | >;
23 |
--------------------------------------------------------------------------------
/src/040-deriving-types-from-values/133-return-type.solution.ts:
--------------------------------------------------------------------------------
1 | import { Equal, Expect } from "@total-typescript/helpers";
2 |
3 | const createUser = (id: string) => {
4 | return {
5 | id,
6 | name: "John Doe",
7 | email: "example@email.com",
8 | };
9 | };
10 |
11 | type User = ReturnType;
12 |
13 | type test = Expect<
14 | Equal<
15 | User,
16 | {
17 | id: string;
18 | name: string;
19 | email: string;
20 | }
21 | >
22 | >;
23 |
--------------------------------------------------------------------------------
/src/045-annotations-and-assertions/142-global-typings-use-any.problem.ts:
--------------------------------------------------------------------------------
1 | import { expect, it } from "vitest";
2 |
3 | const getObj = () => {
4 | const obj = JSON.parse('{ "a": 123, "b": 456 }');
5 |
6 | return obj;
7 | };
8 |
9 | it("Should return an obj", () => {
10 | const obj = getObj();
11 |
12 | expect(obj.b).toEqual(456);
13 |
14 | expect(
15 | // @ts-expect-error c doesn't exist on obj
16 | obj.c,
17 | ).toEqual(undefined);
18 | });
19 |
--------------------------------------------------------------------------------
/src/050-the-weird-parts/153-excess-properties-warnings-in-functions.problem.ts:
--------------------------------------------------------------------------------
1 | interface User {
2 | id: number;
3 | name: string;
4 | }
5 |
6 | const users = [
7 | {
8 | name: "Waqas",
9 | },
10 | {
11 | name: "Zain",
12 | },
13 | ];
14 |
15 | const usersWithIds: User[] = users.map((user, index) => ({
16 | ...user,
17 | id: index,
18 | // @ts-expect-error
19 | age: 30,
20 | }));
21 |
--------------------------------------------------------------------------------
/src/050-the-weird-parts/153-excess-properties-warnings-in-functions.solution.1.ts:
--------------------------------------------------------------------------------
1 | interface User {
2 | id: number;
3 | name: string;
4 | }
5 |
6 | const users = [
7 | {
8 | name: "Waqas",
9 | },
10 | {
11 | name: "Zain",
12 | },
13 | ];
14 |
15 | const usersWithIds: User[] = users.map(
16 | (user, index): User => ({
17 | ...user,
18 | id: index,
19 | // @ts-expect-error
20 | age: 30,
21 | }),
22 | );
23 |
--------------------------------------------------------------------------------
/src/050-the-weird-parts/153-excess-properties-warnings-in-functions.solution.2.ts:
--------------------------------------------------------------------------------
1 | interface User {
2 | id: number;
3 | name: string;
4 | }
5 |
6 | const users = [
7 | {
8 | name: "Waqas",
9 | },
10 | {
11 | name: "Zain",
12 | },
13 | ];
14 |
15 | const usersWithIds: User[] = users.map(
16 | (user, index) =>
17 | ({
18 | ...user,
19 | id: index,
20 | // @ts-expect-error
21 | age: 30,
22 | } satisfies User),
23 | );
24 |
--------------------------------------------------------------------------------
/src/050-the-weird-parts/154.8-evolving-any.problem.ts:
--------------------------------------------------------------------------------
1 | import { Equal, Expect } from "@total-typescript/helpers";
2 |
3 | let selectedId = 123;
4 |
5 | type test = Expect>;
6 |
7 | selectedId = "123";
8 |
9 | type test2 = Expect>;
10 |
--------------------------------------------------------------------------------
/src/050-the-weird-parts/154.8-evolving-any.solution.ts:
--------------------------------------------------------------------------------
1 | import { Equal, Expect } from "@total-typescript/helpers";
2 |
3 | let selectedId;
4 |
5 | selectedId = 123;
6 |
7 | type test = Expect>;
8 |
9 | selectedId = "123";
10 |
11 | type test2 = Expect>;
12 |
--------------------------------------------------------------------------------
/src/050-the-weird-parts/154.9-evolving-any-arrays.explainer.ts:
--------------------------------------------------------------------------------
1 | import { Equal, Expect } from "@total-typescript/helpers";
2 |
3 | const arr = [];
4 |
5 | arr.push(1);
6 |
7 | type test = Expect>;
8 |
9 | arr.push("abc");
10 |
11 | type test2 = Expect>;
12 |
--------------------------------------------------------------------------------
/src/050-the-weird-parts/157-unions-of-functions.problem.ts:
--------------------------------------------------------------------------------
1 | const objOfFunctions = {
2 | string: (input: string) => input.toUpperCase(),
3 | number: (input: number) => input.toFixed(2),
4 | boolean: (input: boolean) => (input ? "true" : "false"),
5 | };
6 |
7 | const format = (input: string | number | boolean) => {
8 | const inputType = typeof input as "string" | "number" | "boolean";
9 | const formatter = objOfFunctions[inputType];
10 |
11 | return formatter(input);
12 | };
13 |
--------------------------------------------------------------------------------
/src/060-modules-scripts-and-declaration-files/159-module-or-script.explainer/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "117-const-enums.explainer",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "dev": "tsc --watch"
8 | },
9 | "keywords": [],
10 | "author": "Matt Pocock"
11 | }
12 |
--------------------------------------------------------------------------------
/src/060-modules-scripts-and-declaration-files/159-module-or-script.explainer/src/module-1.ts:
--------------------------------------------------------------------------------
1 | export {};
2 |
3 | const myModuleFunc = () => {};
4 |
--------------------------------------------------------------------------------
/src/060-modules-scripts-and-declaration-files/159-module-or-script.explainer/src/module-2.ts:
--------------------------------------------------------------------------------
1 | export {};
2 |
3 | myModuleFunc();
4 |
--------------------------------------------------------------------------------
/src/060-modules-scripts-and-declaration-files/159-module-or-script.explainer/src/script-1.ts:
--------------------------------------------------------------------------------
1 | const myFunc = () => {
2 | console.log("Hello!");
3 | };
4 |
--------------------------------------------------------------------------------
/src/060-modules-scripts-and-declaration-files/159-module-or-script.explainer/src/script-2.ts:
--------------------------------------------------------------------------------
1 | // I can use it without importing it!
2 | myFunc();
3 |
--------------------------------------------------------------------------------
/src/060-modules-scripts-and-declaration-files/159-module-or-script.explainer/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2022",
4 | "module": "ESNext",
5 | "moduleResolution": "Bundler",
6 | "esModuleInterop": true,
7 | "declaration": true,
8 | "noEmit": true,
9 | "strict": true,
10 | "skipLibCheck": true
11 | },
12 | }
--------------------------------------------------------------------------------
/src/060-modules-scripts-and-declaration-files/160-module-detection-force.problem/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "117-const-enums.explainer",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "dev": "tsc --watch"
8 | },
9 | "keywords": [],
10 | "author": "Matt Pocock"
11 | }
12 |
--------------------------------------------------------------------------------
/src/060-modules-scripts-and-declaration-files/160-module-detection-force.problem/src/script-1.ts:
--------------------------------------------------------------------------------
1 | const myFunc = () => {
2 | console.log("Hello!");
3 | };
4 |
--------------------------------------------------------------------------------
/src/060-modules-scripts-and-declaration-files/160-module-detection-force.problem/src/script-2.ts:
--------------------------------------------------------------------------------
1 | // I can use it without importing it!
2 |
3 | // @ts-expect-error
4 | myFunc();
5 |
--------------------------------------------------------------------------------
/src/060-modules-scripts-and-declaration-files/160-module-detection-force.problem/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2022",
4 | "module": "ESNext",
5 | "moduleResolution": "Bundler",
6 | "esModuleInterop": true,
7 | "declaration": true,
8 | "noEmit": true,
9 | "strict": true,
10 | "skipLibCheck": true
11 | },
12 | }
--------------------------------------------------------------------------------
/src/060-modules-scripts-and-declaration-files/160-module-detection-force.solution/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "117-const-enums.explainer",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "dev": "tsc --watch"
8 | },
9 | "keywords": [],
10 | "author": "Matt Pocock"
11 | }
12 |
--------------------------------------------------------------------------------
/src/060-modules-scripts-and-declaration-files/160-module-detection-force.solution/src/script-1.ts:
--------------------------------------------------------------------------------
1 | // Now, everything is forced to be a module!
2 |
3 | const myFunc = () => {
4 | console.log("Hello!");
5 | };
6 |
--------------------------------------------------------------------------------
/src/060-modules-scripts-and-declaration-files/160-module-detection-force.solution/src/script-2.ts:
--------------------------------------------------------------------------------
1 | // @ts-expect-error
2 | myFunc();
3 |
--------------------------------------------------------------------------------
/src/060-modules-scripts-and-declaration-files/160-module-detection-force.solution/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2022",
4 | "module": "ESNext",
5 | "moduleResolution": "Bundler",
6 | "esModuleInterop": true,
7 | "declaration": true,
8 | "noEmit": true,
9 | "strict": true,
10 | "skipLibCheck": true,
11 | "moduleDetection": "force"
12 | },
13 | }
--------------------------------------------------------------------------------
/src/060-modules-scripts-and-declaration-files/161-declaration-files.explainer/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "117-const-enums.explainer",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "dev": "tsc --watch"
8 | },
9 | "keywords": [],
10 | "author": "Matt Pocock"
11 | }
12 |
--------------------------------------------------------------------------------
/src/060-modules-scripts-and-declaration-files/161-declaration-files.explainer/src/can-export-types.d.ts:
--------------------------------------------------------------------------------
1 | export type MyType = string;
2 |
3 | export interface MyInterface {
4 | myProp: string;
5 | }
6 |
--------------------------------------------------------------------------------
/src/060-modules-scripts-and-declaration-files/161-declaration-files.explainer/src/cant-use-runtime-code.d.ts:
--------------------------------------------------------------------------------
1 | export const myFunc = () => {};
2 |
--------------------------------------------------------------------------------
/src/060-modules-scripts-and-declaration-files/161-declaration-files.explainer/src/index.ts:
--------------------------------------------------------------------------------
1 | import { Equal, Expect } from "@total-typescript/helpers";
2 |
3 | import { MyInterface, MyType } from "./can-export-types";
4 |
5 | type test = Expect>;
6 | type test2 = Expect>;
7 |
--------------------------------------------------------------------------------
/src/060-modules-scripts-and-declaration-files/161-declaration-files.explainer/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2022",
4 | "module": "ESNext",
5 | "moduleResolution": "Bundler",
6 | "esModuleInterop": true,
7 | "declaration": true,
8 | "noEmit": true,
9 | "strict": true,
10 | "moduleDetection": "force"
11 | },
12 | }
--------------------------------------------------------------------------------
/src/060-modules-scripts-and-declaration-files/162-declaration-files-can-be-modules-or-scripts.explainer/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "117-const-enums.explainer",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "dev": "tsc --watch"
8 | },
9 | "keywords": [],
10 | "author": "Matt Pocock"
11 | }
12 |
--------------------------------------------------------------------------------
/src/060-modules-scripts-and-declaration-files/162-declaration-files-can-be-modules-or-scripts.explainer/src/index.ts:
--------------------------------------------------------------------------------
1 | import { Equal, Expect } from "@total-typescript/helpers";
2 |
3 | import { AvailableViaImport } from "./treated-as-module";
4 |
5 | type tests = [
6 | Expect>,
7 | Expect>,
8 | ];
9 |
--------------------------------------------------------------------------------
/src/060-modules-scripts-and-declaration-files/162-declaration-files-can-be-modules-or-scripts.explainer/src/treated-as-module.d.ts:
--------------------------------------------------------------------------------
1 | export type AvailableViaImport = string;
2 |
3 | type NotAvailableViaImport = number;
4 |
5 | export {};
6 |
--------------------------------------------------------------------------------
/src/060-modules-scripts-and-declaration-files/162-declaration-files-can-be-modules-or-scripts.explainer/src/treated-as-script.d.ts:
--------------------------------------------------------------------------------
1 | type GloballyAvailable = string;
2 |
--------------------------------------------------------------------------------
/src/060-modules-scripts-and-declaration-files/162-declaration-files-can-be-modules-or-scripts.explainer/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2022",
4 | "module": "ESNext",
5 | "moduleResolution": "Bundler",
6 | "esModuleInterop": true,
7 | "declaration": true,
8 | "noEmit": true,
9 | "strict": true,
10 | "moduleDetection": "force"
11 | },
12 | }
--------------------------------------------------------------------------------
/src/060-modules-scripts-and-declaration-files/164-declaration-files-can-be-used-to-type-js-files.problem/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "117-const-enums.explainer",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "dev": "tsc --watch"
8 | },
9 | "keywords": [],
10 | "author": "Matt Pocock"
11 | }
12 |
--------------------------------------------------------------------------------
/src/060-modules-scripts-and-declaration-files/164-declaration-files-can-be-used-to-type-js-files.problem/src/example.js:
--------------------------------------------------------------------------------
1 | export const myFunc = () => {
2 | return "Hello World!";
3 | };
4 |
--------------------------------------------------------------------------------
/src/060-modules-scripts-and-declaration-files/164-declaration-files-can-be-used-to-type-js-files.problem/src/index.ts:
--------------------------------------------------------------------------------
1 | import { myFunc } from "./example";
2 |
3 | myFunc();
4 |
--------------------------------------------------------------------------------
/src/060-modules-scripts-and-declaration-files/164-declaration-files-can-be-used-to-type-js-files.problem/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2022",
4 | "module": "ESNext",
5 | "moduleResolution": "Bundler",
6 | "esModuleInterop": true,
7 | "declaration": true,
8 | "noEmit": true,
9 | "strict": true,
10 | "moduleDetection": "force"
11 | },
12 | }
--------------------------------------------------------------------------------
/src/060-modules-scripts-and-declaration-files/164-declaration-files-can-be-used-to-type-js-files.solution/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "117-const-enums.explainer",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "dev": "tsc --watch"
8 | },
9 | "keywords": [],
10 | "author": "Matt Pocock"
11 | }
12 |
--------------------------------------------------------------------------------
/src/060-modules-scripts-and-declaration-files/164-declaration-files-can-be-used-to-type-js-files.solution/src/example.d.ts:
--------------------------------------------------------------------------------
1 | export function myFunc(): string;
2 |
3 | export {};
4 |
--------------------------------------------------------------------------------
/src/060-modules-scripts-and-declaration-files/164-declaration-files-can-be-used-to-type-js-files.solution/src/example.js:
--------------------------------------------------------------------------------
1 | export const myFunc = () => {
2 | return "Hello World!";
3 | };
4 |
--------------------------------------------------------------------------------
/src/060-modules-scripts-and-declaration-files/164-declaration-files-can-be-used-to-type-js-files.solution/src/index.ts:
--------------------------------------------------------------------------------
1 | import { myFunc } from "./example";
2 |
3 | myFunc();
4 |
--------------------------------------------------------------------------------
/src/060-modules-scripts-and-declaration-files/164-declaration-files-can-be-used-to-type-js-files.solution/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2022",
4 | "module": "ESNext",
5 | "moduleResolution": "Bundler",
6 | "esModuleInterop": true,
7 | "declaration": true,
8 | "noEmit": true,
9 | "strict": true,
10 | "moduleDetection": "force"
11 | },
12 | }
--------------------------------------------------------------------------------
/src/060-modules-scripts-and-declaration-files/166-ambient-context-and-declare-const.problem/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "117-const-enums.explainer",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "dev": "tsc --watch"
8 | },
9 | "keywords": [],
10 | "author": "Matt Pocock"
11 | }
12 |
--------------------------------------------------------------------------------
/src/060-modules-scripts-and-declaration-files/166-ambient-context-and-declare-const.problem/src/index.ts:
--------------------------------------------------------------------------------
1 | import { Equal, Expect } from "@total-typescript/helpers";
2 |
3 | const state = DEBUG.getState();
4 |
5 | type test = Expect>;
6 |
--------------------------------------------------------------------------------
/src/060-modules-scripts-and-declaration-files/166-ambient-context-and-declare-const.problem/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2022",
4 | "module": "ESNext",
5 | "moduleResolution": "Bundler",
6 | "esModuleInterop": true,
7 | "declaration": true,
8 | "skipLibCheck": true,
9 | "noEmit": true,
10 | "strict": true,
11 | "moduleDetection": "force"
12 | },
13 | }
--------------------------------------------------------------------------------
/src/060-modules-scripts-and-declaration-files/166-ambient-context-and-declare-const.solution/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "117-const-enums.explainer",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "dev": "tsc --watch"
8 | },
9 | "keywords": [],
10 | "author": "Matt Pocock"
11 | }
12 |
--------------------------------------------------------------------------------
/src/060-modules-scripts-and-declaration-files/166-ambient-context-and-declare-const.solution/src/index.ts:
--------------------------------------------------------------------------------
1 | import { Equal, Expect } from "@total-typescript/helpers";
2 |
3 | declare const DEBUG: {
4 | getState: () => {
5 | id: string;
6 | };
7 | };
8 |
9 | const state = DEBUG.getState();
10 |
11 | type test = Expect>;
12 |
--------------------------------------------------------------------------------
/src/060-modules-scripts-and-declaration-files/166-ambient-context-and-declare-const.solution/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2022",
4 | "module": "ESNext",
5 | "moduleResolution": "Bundler",
6 | "esModuleInterop": true,
7 | "declaration": true,
8 | "skipLibCheck": true,
9 | "noEmit": true,
10 | "strict": true,
11 | "moduleDetection": "force"
12 | },
13 | }
--------------------------------------------------------------------------------
/src/060-modules-scripts-and-declaration-files/167-declare-global.problem/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "117-const-enums.explainer",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "dev": "tsc --watch"
8 | },
9 | "keywords": [],
10 | "author": "Matt Pocock"
11 | }
12 |
--------------------------------------------------------------------------------
/src/060-modules-scripts-and-declaration-files/167-declare-global.problem/src/index.ts:
--------------------------------------------------------------------------------
1 | import { Equal, Expect } from "@total-typescript/helpers";
2 |
3 | declare const DEBUG: {
4 | getState(): { id: string };
5 | };
6 |
7 | const state = DEBUG.getState();
8 |
9 | type test = Expect>;
10 |
--------------------------------------------------------------------------------
/src/060-modules-scripts-and-declaration-files/167-declare-global.problem/src/other-file.ts:
--------------------------------------------------------------------------------
1 | import { Equal, Expect } from "@total-typescript/helpers";
2 |
3 | const state = DEBUG.getState();
4 |
5 | type test = Expect>;
6 |
--------------------------------------------------------------------------------
/src/060-modules-scripts-and-declaration-files/167-declare-global.problem/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2022",
4 | "module": "ESNext",
5 | "moduleResolution": "Bundler",
6 | "esModuleInterop": true,
7 | "declaration": true,
8 | "noEmit": true,
9 | "strict": true,
10 | "moduleDetection": "force"
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/060-modules-scripts-and-declaration-files/167-declare-global.solution.1/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "117-const-enums.explainer",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "dev": "tsc --watch"
8 | },
9 | "keywords": [],
10 | "author": "Matt Pocock"
11 | }
12 |
--------------------------------------------------------------------------------
/src/060-modules-scripts-and-declaration-files/167-declare-global.solution.1/src/index.ts:
--------------------------------------------------------------------------------
1 | import { Equal, Expect } from "@total-typescript/helpers";
2 |
3 | declare global {
4 | const DEBUG: {
5 | getState(): { id: string };
6 | };
7 | }
8 |
9 | const state = DEBUG.getState();
10 |
11 | type test = Expect>;
12 |
--------------------------------------------------------------------------------
/src/060-modules-scripts-and-declaration-files/167-declare-global.solution.1/src/other-file.ts:
--------------------------------------------------------------------------------
1 | import { Equal, Expect } from "@total-typescript/helpers";
2 |
3 | const state = DEBUG.getState();
4 |
5 | type test = Expect>;
6 |
--------------------------------------------------------------------------------
/src/060-modules-scripts-and-declaration-files/167-declare-global.solution.1/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2022",
4 | "module": "ESNext",
5 | "moduleResolution": "Bundler",
6 | "esModuleInterop": true,
7 | "declaration": true,
8 | "noEmit": true,
9 | "strict": true,
10 | "moduleDetection": "force"
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/060-modules-scripts-and-declaration-files/167-declare-global.solution.2/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "117-const-enums.explainer",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "dev": "tsc --watch"
8 | },
9 | "keywords": [],
10 | "author": "Matt Pocock"
11 | }
12 |
--------------------------------------------------------------------------------
/src/060-modules-scripts-and-declaration-files/167-declare-global.solution.2/src/debug.d.ts:
--------------------------------------------------------------------------------
1 | declare const DEBUG: {
2 | getState(): { id: string };
3 | };
4 |
--------------------------------------------------------------------------------
/src/060-modules-scripts-and-declaration-files/167-declare-global.solution.2/src/index.ts:
--------------------------------------------------------------------------------
1 | import { Equal, Expect } from "@total-typescript/helpers";
2 |
3 | const state = DEBUG.getState();
4 |
5 | type test = Expect>;
6 |
--------------------------------------------------------------------------------
/src/060-modules-scripts-and-declaration-files/167-declare-global.solution.2/src/other-file.ts:
--------------------------------------------------------------------------------
1 | import { Equal, Expect } from "@total-typescript/helpers";
2 |
3 | const state = DEBUG.getState();
4 |
5 | type test = Expect>;
6 |
--------------------------------------------------------------------------------
/src/060-modules-scripts-and-declaration-files/167-declare-global.solution.2/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2022",
4 | "module": "ESNext",
5 | "moduleResolution": "Bundler",
6 | "esModuleInterop": true,
7 | "declaration": true,
8 | "noEmit": true,
9 | "strict": true,
10 | "moduleDetection": "force"
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/065-types-you-dont-control/172-lib-d-ts.problem/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "exercise",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "type": "module",
6 | "scripts": {
7 | "dev": "tsc --watch"
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/src/065-types-you-dont-control/172-lib-d-ts.problem/src/index.ts:
--------------------------------------------------------------------------------
1 | const str = "Hello, world!";
2 |
3 | str.replaceAll("Hello", "Goodbye");
4 |
--------------------------------------------------------------------------------
/src/065-types-you-dont-control/172-lib-d-ts.problem/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES5",
4 | "module": "NodeNext",
5 | "moduleResolution": "NodeNext",
6 | "esModuleInterop": true,
7 | "outDir": "dist",
8 | "rootDir": "src",
9 | "strict": true,
10 | "skipLibCheck": true,
11 | "isolatedModules": true,
12 | "moduleDetection": "force",
13 | },
14 | }
--------------------------------------------------------------------------------
/src/065-types-you-dont-control/172-lib-d-ts.solution.1/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "exercise",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "type": "module",
6 | "scripts": {
7 | "dev": "tsc --watch"
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/src/065-types-you-dont-control/172-lib-d-ts.solution.1/src/index.ts:
--------------------------------------------------------------------------------
1 | const str = "Hello, world!";
2 |
3 | str.replaceAll("Hello", "Goodbye");
4 |
--------------------------------------------------------------------------------
/src/065-types-you-dont-control/172-lib-d-ts.solution.1/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2022",
4 | "module": "NodeNext",
5 | "moduleResolution": "NodeNext",
6 | "esModuleInterop": true,
7 | "outDir": "dist",
8 | "rootDir": "src",
9 | "strict": true,
10 | "skipLibCheck": true,
11 | "isolatedModules": true,
12 | "moduleDetection": "force",
13 | },
14 | }
--------------------------------------------------------------------------------
/src/065-types-you-dont-control/172-lib-d-ts.solution.2/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "exercise",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "type": "module",
6 | "scripts": {
7 | "dev": "tsc --watch"
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/src/065-types-you-dont-control/172-lib-d-ts.solution.2/src/index.ts:
--------------------------------------------------------------------------------
1 | const str = "Hello, world!";
2 |
3 | str.replaceAll("Hello", "Goodbye");
4 |
--------------------------------------------------------------------------------
/src/065-types-you-dont-control/172-lib-d-ts.solution.2/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2022",
4 | "lib": [
5 | "ES2022",
6 | ],
7 | "module": "NodeNext",
8 | "moduleResolution": "NodeNext",
9 | "esModuleInterop": true,
10 | "outDir": "dist",
11 | "rootDir": "src",
12 | "strict": true,
13 | "skipLibCheck": true,
14 | "isolatedModules": true,
15 | "moduleDetection": "force",
16 | },
17 | }
--------------------------------------------------------------------------------
/src/065-types-you-dont-control/173-lib-dom.problem/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "exercise",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "scripts": {
6 | "dev": "tsc --watch"
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/src/065-types-you-dont-control/173-lib-dom.problem/src/index.ts:
--------------------------------------------------------------------------------
1 | document.addEventListener("DOMContentLoaded", () => {
2 | const app = document.querySelector("#app")!;
3 | app.innerHTML = "Hello World!";
4 | });
5 |
--------------------------------------------------------------------------------
/src/065-types-you-dont-control/173-lib-dom.problem/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2022",
4 | "module": "ESNext",
5 | "moduleResolution": "Bundler",
6 | "esModuleInterop": true,
7 | "noEmit": true,
8 | "strict": true,
9 | "skipLibCheck": true,
10 | "isolatedModules": true,
11 | "lib": [
12 | "ES2022"
13 | ]
14 | },
15 | }
--------------------------------------------------------------------------------
/src/065-types-you-dont-control/173-lib-dom.solution/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "exercise",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "scripts": {
6 | "dev": "tsc --watch"
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/src/065-types-you-dont-control/173-lib-dom.solution/src/index.ts:
--------------------------------------------------------------------------------
1 | document.addEventListener("DOMContentLoaded", () => {
2 | const app = document.querySelector("#app")!;
3 | app.innerHTML = "Hello World!";
4 | });
5 |
--------------------------------------------------------------------------------
/src/065-types-you-dont-control/173-lib-dom.solution/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2022",
4 | "module": "ESNext",
5 | "moduleResolution": "Bundler",
6 | "esModuleInterop": true,
7 | "noEmit": true,
8 | "strict": true,
9 | "skipLibCheck": true,
10 | "isolatedModules": true,
11 | "lib": [
12 | "ES2022",
13 | "DOM",
14 | ]
15 | },
16 | }
--------------------------------------------------------------------------------
/src/065-types-you-dont-control/174-lib-dom-iterable.problem/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "exercise",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "scripts": {
6 | "dev": "tsc --watch"
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/src/065-types-you-dont-control/174-lib-dom-iterable.problem/src/index.ts:
--------------------------------------------------------------------------------
1 | const elements = document.querySelectorAll("div");
2 |
3 | for (const element of elements) {
4 | element.innerHTML = "Hello World!";
5 | }
6 |
--------------------------------------------------------------------------------
/src/065-types-you-dont-control/174-lib-dom-iterable.problem/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2022",
4 | "module": "ESNext",
5 | "moduleResolution": "Bundler",
6 | "esModuleInterop": true,
7 | "noEmit": true,
8 | "strict": true,
9 | "skipLibCheck": true,
10 | "isolatedModules": true,
11 | "lib": [
12 | "ES2022",
13 | "DOM",
14 | ]
15 | },
16 | }
--------------------------------------------------------------------------------
/src/065-types-you-dont-control/174-lib-dom-iterable.solution/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "exercise",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "scripts": {
6 | "dev": "tsc --watch"
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/src/065-types-you-dont-control/174-lib-dom-iterable.solution/src/index.ts:
--------------------------------------------------------------------------------
1 | const elements = document.querySelectorAll("div");
2 |
3 | for (const element of elements) {
4 | element.innerHTML = "Hello World!";
5 | }
6 |
--------------------------------------------------------------------------------
/src/065-types-you-dont-control/174-lib-dom-iterable.solution/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2022",
4 | "module": "ESNext",
5 | "moduleResolution": "Bundler",
6 | "esModuleInterop": true,
7 | "noEmit": true,
8 | "strict": true,
9 | "skipLibCheck": true,
10 | "isolatedModules": true,
11 | "lib": [
12 | "ES2022",
13 | "DOM",
14 | "DOM.Iterable"
15 | ]
16 | },
17 | }
--------------------------------------------------------------------------------
/src/065-types-you-dont-control/174.5-modifying-window.problem/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "117-const-enums.explainer",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "dev": "tsc --watch"
8 | },
9 | "keywords": [],
10 | "author": "Matt Pocock"
11 | }
12 |
--------------------------------------------------------------------------------
/src/065-types-you-dont-control/174.5-modifying-window.problem/src/index.ts:
--------------------------------------------------------------------------------
1 | import { Equal, Expect } from "@total-typescript/helpers";
2 |
3 | const state = window.DEBUG.getState();
4 |
5 | type test = Expect>;
6 |
--------------------------------------------------------------------------------
/src/065-types-you-dont-control/174.5-modifying-window.problem/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2022",
4 | "module": "ESNext",
5 | "moduleResolution": "Bundler",
6 | "esModuleInterop": true,
7 | "declaration": true,
8 | "skipLibCheck": true,
9 | "noEmit": true,
10 | "strict": true,
11 | "moduleDetection": "force"
12 | },
13 | }
--------------------------------------------------------------------------------
/src/065-types-you-dont-control/174.5-modifying-window.solution/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "117-const-enums.explainer",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "dev": "tsc --watch"
8 | },
9 | "keywords": [],
10 | "author": "Matt Pocock"
11 | }
12 |
--------------------------------------------------------------------------------
/src/065-types-you-dont-control/174.5-modifying-window.solution/src/index.ts:
--------------------------------------------------------------------------------
1 | import { Equal, Expect } from "@total-typescript/helpers";
2 |
3 | const state = window.DEBUG.getState();
4 |
5 | type test = Expect>;
6 |
--------------------------------------------------------------------------------
/src/065-types-you-dont-control/174.5-modifying-window.solution/src/window.d.ts:
--------------------------------------------------------------------------------
1 | interface Window {
2 | DEBUG: {
3 | getState(): { id: string };
4 | };
5 | }
6 |
--------------------------------------------------------------------------------
/src/065-types-you-dont-control/174.5-modifying-window.solution/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2022",
4 | "module": "ESNext",
5 | "moduleResolution": "Bundler",
6 | "esModuleInterop": true,
7 | "declaration": true,
8 | "skipLibCheck": true,
9 | "noEmit": true,
10 | "strict": true,
11 | "moduleDetection": "force"
12 | },
13 | }
--------------------------------------------------------------------------------
/src/065-types-you-dont-control/175-definitely-typed.problem/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "exercise",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "type": "module",
6 | "scripts": {
7 | "dev": "tsc --watch"
8 | },
9 | "dependencies": {
10 | "diff": "^5.1.0"
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/065-types-you-dont-control/175-definitely-typed.problem/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2022",
4 | "module": "NodeNext",
5 | "moduleResolution": "NodeNext",
6 | "esModuleInterop": true,
7 | "outDir": "dist",
8 | "rootDir": "src",
9 | "strict": true,
10 | "skipLibCheck": true,
11 | "isolatedModules": true,
12 | "moduleDetection": "force",
13 | },
14 | }
--------------------------------------------------------------------------------
/src/065-types-you-dont-control/175-definitely-typed.solution/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "exercise",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "type": "module",
6 | "scripts": {
7 | "dev": "tsc --watch"
8 | },
9 | "dependencies": {
10 | "diff": "^5.1.0"
11 | },
12 | "devDependencies": {
13 | "@types/diff": "^5.0.4"
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/065-types-you-dont-control/175-definitely-typed.solution/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2022",
4 | "module": "NodeNext",
5 | "moduleResolution": "NodeNext",
6 | "esModuleInterop": true,
7 | "outDir": "dist",
8 | "rootDir": "src",
9 | "strict": true,
10 | "skipLibCheck": true,
11 | "isolatedModules": true,
12 | "moduleDetection": "force",
13 | },
14 | }
--------------------------------------------------------------------------------
/src/065-types-you-dont-control/175.2-types-node.explainer/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "117-const-enums.explainer",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "dev": "tsc --watch"
8 | },
9 | "keywords": [],
10 | "author": "Matt Pocock",
11 | "devDependencies": {
12 | "@types/node": "^20.9.0"
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/065-types-you-dont-control/175.2-types-node.explainer/src/index.ts:
--------------------------------------------------------------------------------
1 | // Typed by @types/node!
2 | process;
3 |
--------------------------------------------------------------------------------
/src/065-types-you-dont-control/175.2-types-node.explainer/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2022",
4 | "module": "ESNext",
5 | "moduleResolution": "Bundler",
6 | "esModuleInterop": true,
7 | "declaration": true,
8 | "skipLibCheck": true,
9 | "noEmit": true,
10 | "strict": true,
11 | "moduleDetection": "force"
12 | },
13 | }
--------------------------------------------------------------------------------
/src/065-types-you-dont-control/175.5-modifying-process-env.problem/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "117-const-enums.explainer",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "dev": "tsc --watch"
8 | },
9 | "keywords": [],
10 | "author": "Matt Pocock",
11 | "devDependencies": {
12 | "@types/node": "^20.9.0"
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/065-types-you-dont-control/175.5-modifying-process-env.problem/src/index.ts:
--------------------------------------------------------------------------------
1 | import { Equal, Expect } from "@total-typescript/helpers";
2 |
3 | const envVariable = process.env.MY_ENV_VAR;
4 |
5 | type test = Expect>;
6 |
--------------------------------------------------------------------------------
/src/065-types-you-dont-control/175.5-modifying-process-env.problem/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2022",
4 | "module": "ESNext",
5 | "moduleResolution": "Bundler",
6 | "esModuleInterop": true,
7 | "declaration": true,
8 | "noEmit": true,
9 | "strict": true,
10 | "moduleDetection": "force"
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/065-types-you-dont-control/175.5-modifying-process-env.solution/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "117-const-enums.explainer",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "scripts": {
6 | "dev": "tsc --watch"
7 | },
8 | "keywords": [],
9 | "author": "Matt Pocock",
10 | "devDependencies": {
11 | "@types/node": "^20.9.0"
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/065-types-you-dont-control/175.5-modifying-process-env.solution/src/index.ts:
--------------------------------------------------------------------------------
1 | import { Equal, Expect } from "@total-typescript/helpers";
2 |
3 | const envVariable = process.env.MY_ENV_VAR;
4 |
5 | type test = Expect>;
6 |
--------------------------------------------------------------------------------
/src/065-types-you-dont-control/175.5-modifying-process-env.solution/src/process.d.ts:
--------------------------------------------------------------------------------
1 | declare namespace NodeJS {
2 | interface ProcessEnv {
3 | MY_ENV_VAR: string;
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/src/065-types-you-dont-control/175.5-modifying-process-env.solution/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2022",
4 | "module": "ESNext",
5 | "moduleResolution": "Bundler",
6 | "esModuleInterop": true,
7 | "declaration": true,
8 | "noEmit": true,
9 | "strict": true,
10 | "moduleDetection": "force"
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/065-types-you-dont-control/176-types-that-ship-with-libraries.explainer/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "exercise",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "type": "module",
6 | "scripts": {
7 | "dev": "tsc --watch"
8 | },
9 | "dependencies": {
10 | "zod": "^3.22.2"
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/065-types-you-dont-control/176-types-that-ship-with-libraries.explainer/pnpm-lock.yaml:
--------------------------------------------------------------------------------
1 | lockfileVersion: '6.0'
2 |
3 | settings:
4 | autoInstallPeers: true
5 | excludeLinksFromLockfile: false
6 |
7 | dependencies:
8 | zod:
9 | specifier: ^3.22.2
10 | version: 3.22.2
11 |
12 | packages:
13 |
14 | /zod@3.22.2:
15 | resolution: {integrity: sha512-wvWkphh5WQsJbVk1tbx1l1Ly4yg+XecD+Mq280uBGt9wa5BKSWf4Mhp6GmrkPixhMxmabYY7RbzlwVP32pbGCg==}
16 | dev: false
17 |
--------------------------------------------------------------------------------
/src/065-types-you-dont-control/176-types-that-ship-with-libraries.explainer/src/index.ts:
--------------------------------------------------------------------------------
1 | import { z } from "zod";
2 |
3 | const user = z.object({
4 | name: z.string(),
5 | });
6 |
--------------------------------------------------------------------------------
/src/065-types-you-dont-control/176-types-that-ship-with-libraries.explainer/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2022",
4 | "module": "NodeNext",
5 | "moduleResolution": "NodeNext",
6 | "esModuleInterop": true,
7 | "outDir": "dist",
8 | "rootDir": "src",
9 | "strict": true,
10 | "skipLibCheck": true,
11 | "isolatedModules": true,
12 | "moduleDetection": "force",
13 | },
14 | }
--------------------------------------------------------------------------------
/src/065-types-you-dont-control/176.2-declare-module.problem/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "117-const-enums.explainer",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "scripts": {
6 | "dev": "tsc --watch"
7 | },
8 | "keywords": [],
9 | "author": "Matt Pocock"
10 | }
11 |
--------------------------------------------------------------------------------
/src/065-types-you-dont-control/176.2-declare-module.problem/src/index.ts:
--------------------------------------------------------------------------------
1 | import { Equal, Expect } from "@total-typescript/helpers";
2 |
3 | import { myModuleFunc } from "my-module";
4 |
5 | type test = Expect void>>;
6 |
--------------------------------------------------------------------------------
/src/065-types-you-dont-control/176.2-declare-module.problem/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2022",
4 | "module": "ESNext",
5 | "moduleResolution": "Bundler",
6 | "esModuleInterop": true,
7 | "declaration": true,
8 | "noEmit": true,
9 | "strict": true,
10 | "moduleDetection": "force"
11 | },
12 | }
--------------------------------------------------------------------------------
/src/065-types-you-dont-control/176.2-declare-module.solution/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "117-const-enums.explainer",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "scripts": {
6 | "dev": "tsc --watch"
7 | },
8 | "keywords": [],
9 | "author": "Matt Pocock"
10 | }
11 |
--------------------------------------------------------------------------------
/src/065-types-you-dont-control/176.2-declare-module.solution/src/index.ts:
--------------------------------------------------------------------------------
1 | import { Equal, Expect } from "@total-typescript/helpers";
2 |
3 | import { myModuleFunc } from "my-module";
4 |
5 | type test = Expect void>>;
6 |
--------------------------------------------------------------------------------
/src/065-types-you-dont-control/176.2-declare-module.solution/src/my-module-name-does-not-matter.d.ts:
--------------------------------------------------------------------------------
1 | declare module "my-module" {
2 | export const myModuleFunc: () => void;
3 | }
4 |
--------------------------------------------------------------------------------
/src/065-types-you-dont-control/176.2-declare-module.solution/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2022",
4 | "module": "ESNext",
5 | "moduleResolution": "Bundler",
6 | "esModuleInterop": true,
7 | "declaration": true,
8 | "noEmit": true,
9 | "strict": true,
10 | "moduleDetection": "force"
11 | },
12 | }
--------------------------------------------------------------------------------
/src/065-types-you-dont-control/176.3-wildcard-in-declare-module.problem/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "117-const-enums.explainer",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "scripts": {
6 | "dev": "tsc --watch"
7 | },
8 | "keywords": [],
9 | "author": "Matt Pocock"
10 | }
11 |
--------------------------------------------------------------------------------
/src/065-types-you-dont-control/176.3-wildcard-in-declare-module.problem/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2022",
4 | "module": "ESNext",
5 | "moduleResolution": "Bundler",
6 | "esModuleInterop": true,
7 | "declaration": true,
8 | "noEmit": true,
9 | "strict": true,
10 | "moduleDetection": "force"
11 | },
12 | }
--------------------------------------------------------------------------------
/src/065-types-you-dont-control/176.3-wildcard-in-declare-module.solution/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "117-const-enums.explainer",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "scripts": {
6 | "dev": "tsc --watch"
7 | },
8 | "keywords": [],
9 | "author": "Matt Pocock"
10 | }
11 |
--------------------------------------------------------------------------------
/src/065-types-you-dont-control/176.3-wildcard-in-declare-module.solution/src/png.d.ts:
--------------------------------------------------------------------------------
1 | declare module "*.png" {
2 | const png: string;
3 |
4 | export default png;
5 | }
6 |
--------------------------------------------------------------------------------
/src/065-types-you-dont-control/176.3-wildcard-in-declare-module.solution/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2022",
4 | "module": "ESNext",
5 | "moduleResolution": "Bundler",
6 | "esModuleInterop": true,
7 | "declaration": true,
8 | "noEmit": true,
9 | "strict": true,
10 | "moduleDetection": "force"
11 | },
12 | }
--------------------------------------------------------------------------------
/src/065-types-you-dont-control/176.5-skip-lib-check-true.problem/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "117-const-enums.explainer",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "dev": "tsc --watch"
8 | },
9 | "keywords": [],
10 | "author": "Matt Pocock"
11 | }
12 |
--------------------------------------------------------------------------------
/src/065-types-you-dont-control/176.5-skip-lib-check-true.problem/src/index.d.ts:
--------------------------------------------------------------------------------
1 | export const myFunc = () => {};
2 |
--------------------------------------------------------------------------------
/src/065-types-you-dont-control/176.5-skip-lib-check-true.problem/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2022",
4 | "module": "ESNext",
5 | "moduleResolution": "Bundler",
6 | "esModuleInterop": true,
7 | "declaration": true,
8 | "skipLibCheck": true,
9 | "noEmit": true,
10 | "strict": true,
11 | "moduleDetection": "force"
12 | },
13 | }
--------------------------------------------------------------------------------
/src/065-types-you-dont-control/176.5-skip-lib-check-true.solution/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "117-const-enums.explainer",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "dev": "tsc --watch"
8 | },
9 | "keywords": [],
10 | "author": "Matt Pocock"
11 | }
12 |
--------------------------------------------------------------------------------
/src/065-types-you-dont-control/176.5-skip-lib-check-true.solution/src/index.d.ts:
--------------------------------------------------------------------------------
1 | export const myFunc = () => {};
2 |
--------------------------------------------------------------------------------
/src/065-types-you-dont-control/176.5-skip-lib-check-true.solution/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2022",
4 | "module": "ESNext",
5 | "moduleResolution": "Bundler",
6 | "esModuleInterop": true,
7 | "declaration": true,
8 | // "skipLibCheck": true,
9 | "noEmit": true,
10 | "strict": true,
11 | "moduleDetection": "force"
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/065-types-you-dont-control/176.7-should-you-use-declaration-files-to-store-your-types.explainer/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "exercise",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "type": "module",
6 | "scripts": {
7 | "dev": "tsc --watch"
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/src/065-types-you-dont-control/176.7-should-you-use-declaration-files-to-store-your-types.explainer/src/index.ts:
--------------------------------------------------------------------------------
1 | import { Example } from "./types";
2 |
3 | type Example2 = Example;
4 |
--------------------------------------------------------------------------------
/src/065-types-you-dont-control/176.7-should-you-use-declaration-files-to-store-your-types.explainer/src/types.d.ts:
--------------------------------------------------------------------------------
1 | export type Example = string;
2 |
--------------------------------------------------------------------------------
/src/065-types-you-dont-control/176.7-should-you-use-declaration-files-to-store-your-types.explainer/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2022",
4 | "module": "ESNext",
5 | "moduleResolution": "Bundler",
6 | "esModuleInterop": true,
7 | "noEmit": true,
8 | "strict": true,
9 | "noUncheckedIndexedAccess": true,
10 | "skipLibCheck": true,
11 | "isolatedModules": true,
12 | "moduleDetection": "force"
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/065-types-you-dont-control/177-declare-module-for-overriding-third-party-libraries.explainer/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "exercise",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "type": "module",
6 | "scripts": {
7 | "dev": "tsc --watch"
8 | },
9 | "dependencies": {
10 | "zod": "^3.22.2"
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/065-types-you-dont-control/177-declare-module-for-overriding-third-party-libraries.explainer/src/index.ts:
--------------------------------------------------------------------------------
1 | import { type Equal, type Expect } from "@total-typescript/helpers";
2 | import { z } from "zod";
3 |
4 | const user = z.object({
5 | name: z.string(),
6 | });
7 |
8 | type Test = Expect>;
9 |
--------------------------------------------------------------------------------
/src/065-types-you-dont-control/177-declare-module-for-overriding-third-party-libraries.explainer/src/zod.d.ts:
--------------------------------------------------------------------------------
1 | declare module "zod" {
2 | const z: any;
3 | }
4 |
--------------------------------------------------------------------------------
/src/065-types-you-dont-control/177-declare-module-for-overriding-third-party-libraries.explainer/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2022",
4 | "module": "NodeNext",
5 | "moduleResolution": "NodeNext",
6 | "esModuleInterop": true,
7 | "outDir": "dist",
8 | "rootDir": "src",
9 | "strict": true,
10 | "skipLibCheck": true,
11 | "isolatedModules": true,
12 | "moduleDetection": "force",
13 | },
14 | }
--------------------------------------------------------------------------------
/src/080-configuring-typescript/178-my-recommended-tsconfig-base.explainer/notes.ts:
--------------------------------------------------------------------------------
1 | // ALSO: https://github.com/tsconfig/bases
2 |
3 | // Note that the strictest is not what I recommend
4 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/178-my-recommended-tsconfig-base.explainer/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "117-const-enums.explainer",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {},
7 | "keywords": [],
8 | "author": "Matt Pocock",
9 | "devDependencies": {}
10 | }
11 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/178.5-isolated-modules.explainer/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "117-const-enums.explainer",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "dev": "tsc --watch"
8 | },
9 | "keywords": [],
10 | "author": "Matt Pocock"
11 | }
12 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/178.5-isolated-modules.explainer/pnpm-lock.yaml:
--------------------------------------------------------------------------------
1 | lockfileVersion: '6.0'
2 |
3 | settings:
4 | autoInstallPeers: true
5 | excludeLinksFromLockfile: false
6 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/178.5-isolated-modules.explainer/src/index.ts:
--------------------------------------------------------------------------------
1 | declare const enum Numbers {
2 | Zero,
3 | One,
4 | Two,
5 | }
6 |
7 | const example = Numbers.Zero;
8 |
9 | // It was added to support Babel:
10 | // https://devblogs.microsoft.com/typescript/typescript-and-babel-7/
11 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/178.5-isolated-modules.explainer/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2022",
4 | "module": "NodeNext",
5 | "moduleResolution": "NodeNext",
6 | "outDir": "dist",
7 | "esModuleInterop": true,
8 | "strict": true,
9 | "skipLibCheck": true,
10 | "isolatedModules": true
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/179-no-unchecked-indexed-access.problem/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "exercise",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "scripts": {
6 | "dev": "tsc --watch"
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/179-no-unchecked-indexed-access.problem/src/index.ts:
--------------------------------------------------------------------------------
1 | import { Equal, Expect } from "@total-typescript/helpers";
2 |
3 | const array = [1, 2, 3];
4 |
5 | const mightNotExist = array[3];
6 |
7 | type test = Expect>;
8 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/179-no-unchecked-indexed-access.problem/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2022",
4 | "module": "ESNext",
5 | "moduleResolution": "Bundler",
6 | "esModuleInterop": true,
7 | "noEmit": true,
8 | "strict": true,
9 | "skipLibCheck": true,
10 | "isolatedModules": true,
11 | },
12 | }
--------------------------------------------------------------------------------
/src/080-configuring-typescript/179-no-unchecked-indexed-access.solution/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "exercise",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "scripts": {
6 | "dev": "tsc --watch"
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/179-no-unchecked-indexed-access.solution/src/index.ts:
--------------------------------------------------------------------------------
1 | import { Equal, Expect } from "@total-typescript/helpers";
2 |
3 | const array = [1, 2, 3];
4 |
5 | const mightNotExist = array[3];
6 |
7 | type test = Expect>;
8 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/179-no-unchecked-indexed-access.solution/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2022",
4 | "module": "ESNext",
5 | "moduleResolution": "Bundler",
6 | "esModuleInterop": true,
7 | "noEmit": true,
8 | "strict": true,
9 | "skipLibCheck": true,
10 | "isolatedModules": true,
11 | "noUncheckedIndexedAccess": true
12 | },
13 | }
--------------------------------------------------------------------------------
/src/080-configuring-typescript/179.5-no-emit.problem/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "exercise",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "scripts": {
6 | "dev": "tsc --watch"
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/179.5-no-emit.problem/pnpm-lock.yaml:
--------------------------------------------------------------------------------
1 | lockfileVersion: '6.0'
2 |
3 | settings:
4 | autoInstallPeers: true
5 | excludeLinksFromLockfile: false
6 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/179.5-no-emit.problem/src/index.ts:
--------------------------------------------------------------------------------
1 | // How do we use TypeScript as a linter, instead of a transpiler?
2 | // We want to prevent it from emitting .js files into ./dist.
3 |
4 | export const myFunc = () => {
5 | console.log("Hello!");
6 | };
7 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/179.5-no-emit.problem/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2022",
4 | "module": "NodeNext",
5 | "moduleResolution": "NodeNext",
6 | "esModuleInterop": true,
7 | "strict": true,
8 | "skipLibCheck": true,
9 | "isolatedModules": true,
10 | "outDir": "./dist",
11 | },
12 | }
--------------------------------------------------------------------------------
/src/080-configuring-typescript/179.5-no-emit.solution/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "exercise",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "scripts": {
6 | "dev": "tsc --watch"
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/179.5-no-emit.solution/pnpm-lock.yaml:
--------------------------------------------------------------------------------
1 | lockfileVersion: '6.0'
2 |
3 | settings:
4 | autoInstallPeers: true
5 | excludeLinksFromLockfile: false
6 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/179.5-no-emit.solution/src/index.ts:
--------------------------------------------------------------------------------
1 | export const myFunc = () => {
2 | console.log("Hello!");
3 | };
4 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/179.5-no-emit.solution/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2022",
4 | "module": "NodeNext",
5 | "moduleResolution": "NodeNext",
6 | "esModuleInterop": true,
7 | "strict": true,
8 | "skipLibCheck": true,
9 | "isolatedModules": true,
10 | "noEmit": true
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/180-module-resolution-bundler-or-nodenext.explainer/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "exercise",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "type": "module",
6 | "scripts": {
7 | "dev": "tsc --watch"
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/180-module-resolution-bundler-or-nodenext.explainer/pnpm-lock.yaml:
--------------------------------------------------------------------------------
1 | lockfileVersion: '6.0'
2 |
3 | settings:
4 | autoInstallPeers: true
5 | excludeLinksFromLockfile: false
6 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/180-module-resolution-bundler-or-nodenext.explainer/src/example.ts:
--------------------------------------------------------------------------------
1 | export const example = () => {
2 | return "hello!";
3 | };
4 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/180-module-resolution-bundler-or-nodenext.explainer/src/index.ts:
--------------------------------------------------------------------------------
1 | // moduleResolution: Bundler doesn't require '.js' extensions!
2 | // import { example } from "./example";
3 |
4 | // moduleResolution: NodeNext DOES require '.js' extensions!
5 | import { example } from "./example.js";
6 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/181-lib-vs-target.explainer/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "exercise",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "type": "module",
6 | "scripts": {
7 | "dev": "tsc --watch"
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/181-lib-vs-target.explainer/pnpm-lock.yaml:
--------------------------------------------------------------------------------
1 | lockfileVersion: '6.0'
2 |
3 | settings:
4 | autoInstallPeers: true
5 | excludeLinksFromLockfile: false
6 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/181-lib-vs-target.explainer/src/index.ts:
--------------------------------------------------------------------------------
1 | // API's are NOT transformed
2 |
3 | const str = "Hello, world!";
4 |
5 | str.replaceAll("Hello", "Goodbye");
6 |
7 | // Syntax IS transformed:
8 |
9 | const myFunc = (input?: { search?: string }) => {
10 | // Optional chaining
11 | const search = input?.search;
12 |
13 | // Nullish coalescing
14 | const defaultedSearch = search ?? "Hello";
15 | };
16 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/181.2-creating-declaration-files.problem/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "exercise",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "type": "module",
6 | "scripts": {
7 | "dev": "tsc --watch"
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/181.2-creating-declaration-files.problem/pnpm-lock.yaml:
--------------------------------------------------------------------------------
1 | lockfileVersion: '6.0'
2 |
3 | settings:
4 | autoInstallPeers: true
5 | excludeLinksFromLockfile: false
6 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/181.2-creating-declaration-files.problem/src/index.ts:
--------------------------------------------------------------------------------
1 | export const myFunc = (input: string) => {};
2 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/181.2-creating-declaration-files.problem/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2022",
4 | "module": "NodeNext",
5 | "moduleResolution": "NodeNext",
6 | "esModuleInterop": true,
7 | "outDir": "dist",
8 | "rootDir": "src",
9 | "strict": true,
10 | "skipLibCheck": true,
11 | "isolatedModules": true,
12 | "moduleDetection": "force"
13 | },
14 | "include": ["src"]
15 | }
16 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/181.2-creating-declaration-files.solution/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "exercise",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "type": "module",
6 | "scripts": {
7 | "dev": "tsc --watch"
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/181.2-creating-declaration-files.solution/pnpm-lock.yaml:
--------------------------------------------------------------------------------
1 | lockfileVersion: '6.0'
2 |
3 | settings:
4 | autoInstallPeers: true
5 | excludeLinksFromLockfile: false
6 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/181.2-creating-declaration-files.solution/src/index.ts:
--------------------------------------------------------------------------------
1 | export const myFunc = (input: string) => {};
2 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/181.4-declaration-maps.problem/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "exercise",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "type": "module",
6 | "scripts": {
7 | "dev": "tsc --watch"
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/181.4-declaration-maps.problem/pnpm-lock.yaml:
--------------------------------------------------------------------------------
1 | lockfileVersion: '6.0'
2 |
3 | settings:
4 | autoInstallPeers: true
5 | excludeLinksFromLockfile: false
6 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/181.4-declaration-maps.problem/src/index.ts:
--------------------------------------------------------------------------------
1 | export const myFunc = (input: string) => {};
2 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/181.4-declaration-maps.problem/test.ts:
--------------------------------------------------------------------------------
1 | import { myFunc } from "./dist/index.js";
2 |
3 | myFunc("Hello world");
4 |
5 | myFunc(
6 | // @ts-expect-error
7 | 123,
8 | );
9 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/181.4-declaration-maps.solution/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "exercise",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "type": "module",
6 | "scripts": {
7 | "dev": "tsc --watch"
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/181.4-declaration-maps.solution/pnpm-lock.yaml:
--------------------------------------------------------------------------------
1 | lockfileVersion: '6.0'
2 |
3 | settings:
4 | autoInstallPeers: true
5 | excludeLinksFromLockfile: false
6 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/181.4-declaration-maps.solution/src/index.ts:
--------------------------------------------------------------------------------
1 | export const myFunc = (input: string) => {};
2 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/181.4-declaration-maps.solution/test.ts:
--------------------------------------------------------------------------------
1 | import { myFunc } from "./dist/index.js";
2 |
3 | myFunc("Hello world");
4 |
5 | myFunc(
6 | // @ts-expect-error
7 | 123,
8 | );
9 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/182-jsx.problem/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "exercise",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "type": "module",
6 | "scripts": {
7 | "dev": "tsc --watch"
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/182-jsx.problem/pnpm-lock.yaml:
--------------------------------------------------------------------------------
1 | lockfileVersion: '6.0'
2 |
3 | settings:
4 | autoInstallPeers: true
5 | excludeLinksFromLockfile: false
6 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/182-jsx.problem/src/index.tsx:
--------------------------------------------------------------------------------
1 | const MyComponent = () => {
2 | return ;
3 | };
4 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/182-jsx.problem/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2022",
4 | "module": "NodeNext",
5 | "moduleResolution": "NodeNext",
6 | "esModuleInterop": true,
7 | "outDir": "dist",
8 | "rootDir": "src",
9 | "strict": true,
10 | "skipLibCheck": true,
11 | "isolatedModules": true,
12 | "moduleDetection": "force",
13 | },
14 | }
--------------------------------------------------------------------------------
/src/080-configuring-typescript/182-jsx.solution.1/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "exercise",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "type": "module",
6 | "scripts": {
7 | "dev": "tsc --watch"
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/182-jsx.solution.1/pnpm-lock.yaml:
--------------------------------------------------------------------------------
1 | lockfileVersion: '6.0'
2 |
3 | settings:
4 | autoInstallPeers: true
5 | excludeLinksFromLockfile: false
6 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/182-jsx.solution.1/src/index.tsx:
--------------------------------------------------------------------------------
1 | const MyComponent = () => {
2 | return ;
3 | };
4 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/182-jsx.solution.1/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2022",
4 | "module": "NodeNext",
5 | "moduleResolution": "NodeNext",
6 | "esModuleInterop": true,
7 | "outDir": "dist",
8 | "rootDir": "src",
9 | "strict": true,
10 | "skipLibCheck": true,
11 | "isolatedModules": true,
12 | "moduleDetection": "force",
13 | "jsx": "preserve"
14 | },
15 | }
--------------------------------------------------------------------------------
/src/080-configuring-typescript/182-jsx.solution.2/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "exercise",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "type": "module",
6 | "scripts": {
7 | "dev": "tsc --watch"
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/182-jsx.solution.2/pnpm-lock.yaml:
--------------------------------------------------------------------------------
1 | lockfileVersion: '6.0'
2 |
3 | settings:
4 | autoInstallPeers: true
5 | excludeLinksFromLockfile: false
6 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/182-jsx.solution.2/src/index.tsx:
--------------------------------------------------------------------------------
1 | const MyComponent = () => {
2 | return ;
3 | };
4 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/182-jsx.solution.2/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2022",
4 | "module": "NodeNext",
5 | "moduleResolution": "NodeNext",
6 | "esModuleInterop": true,
7 | "outDir": "dist",
8 | "rootDir": "src",
9 | "strict": true,
10 | "skipLibCheck": true,
11 | "isolatedModules": true,
12 | "moduleDetection": "force",
13 | "jsx": "react-jsx"
14 | },
15 | }
--------------------------------------------------------------------------------
/src/080-configuring-typescript/183-multiple-tsconfig-json-files.problem/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "exercise",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "scripts": {
6 | "dev": "tsc --watch"
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/183-multiple-tsconfig-json-files.problem/src/client.ts:
--------------------------------------------------------------------------------
1 | document.addEventListener("DOMContentLoaded", () => {
2 | const app = document.querySelector("#app")!;
3 | app.innerHTML = "Hello World!";
4 | });
5 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/183-multiple-tsconfig-json-files.problem/src/server.ts:
--------------------------------------------------------------------------------
1 | // @ts-expect-error
2 | document;
3 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/183-multiple-tsconfig-json-files.problem/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2022",
4 | "module": "ESNext",
5 | "moduleResolution": "Bundler",
6 | "esModuleInterop": true,
7 | "noEmit": true,
8 | "strict": true,
9 | "skipLibCheck": true,
10 | "isolatedModules": true
11 | },
12 | }
--------------------------------------------------------------------------------
/src/080-configuring-typescript/183-multiple-tsconfig-json-files.solution/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "exercise",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "scripts": {
6 | "dev": "run-p dev:*",
7 | "dev:client": "tsc --project ./src/client/tsconfig.json --watch",
8 | "dev:server": "tsc --project ./src/server/tsconfig.json --watch"
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/183-multiple-tsconfig-json-files.solution/src/client/index.ts:
--------------------------------------------------------------------------------
1 | document.addEventListener("DOMContentLoaded", () => {
2 | const app = document.querySelector("#app")!;
3 | app.innerHTML = "Hello World!";
4 | });
5 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/183-multiple-tsconfig-json-files.solution/src/client/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2022",
4 | "module": "ESNext",
5 | "moduleResolution": "Bundler",
6 | "esModuleInterop": true,
7 | "noEmit": true,
8 | "strict": true,
9 | "skipLibCheck": true,
10 | "isolatedModules": true
11 | },
12 | }
--------------------------------------------------------------------------------
/src/080-configuring-typescript/183-multiple-tsconfig-json-files.solution/src/server/index.ts:
--------------------------------------------------------------------------------
1 | // @ts-expect-error
2 | document;
3 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/183-multiple-tsconfig-json-files.solution/src/server/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2022",
4 | "module": "ESNext",
5 | "moduleResolution": "Bundler",
6 | "esModuleInterop": true,
7 | "noEmit": true,
8 | "strict": true,
9 | "skipLibCheck": true,
10 | "isolatedModules": true,
11 | "lib": [
12 | "ES2022"
13 | ]
14 | },
15 | }
--------------------------------------------------------------------------------
/src/080-configuring-typescript/184-globals-are-tied-to-a-single-tsconfig.explainer/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "exercise",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "scripts": {
6 | "dev": "run-p dev:*",
7 | "dev:client": "tsc --project ./src/client/tsconfig.json --watch",
8 | "dev:server": "tsc --project ./src/server/tsconfig.json --watch"
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/184-globals-are-tied-to-a-single-tsconfig.explainer/src/client/index.ts:
--------------------------------------------------------------------------------
1 | document.addEventListener("DOMContentLoaded", () => {
2 | const app = document.querySelector("#app")!;
3 | app.innerHTML = "Hello World!";
4 | });
5 |
6 | // @ts-expect-error
7 | console.log(ONLY_AVAILABLE_ON_SERVER);
8 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/184-globals-are-tied-to-a-single-tsconfig.explainer/src/client/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2022",
4 | "module": "ESNext",
5 | "moduleResolution": "Bundler",
6 | "esModuleInterop": true,
7 | "noEmit": true,
8 | "strict": true,
9 | "skipLibCheck": true,
10 | "isolatedModules": true
11 | },
12 | }
--------------------------------------------------------------------------------
/src/080-configuring-typescript/184-globals-are-tied-to-a-single-tsconfig.explainer/src/server/index.ts:
--------------------------------------------------------------------------------
1 | // @ts-expect-error
2 | document;
3 |
4 | console.log(ONLY_AVAILABLE_ON_SERVER);
5 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/184-globals-are-tied-to-a-single-tsconfig.explainer/src/server/server.d.ts:
--------------------------------------------------------------------------------
1 | declare const ONLY_AVAILABLE_ON_SERVER: string;
2 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/184-globals-are-tied-to-a-single-tsconfig.explainer/src/server/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2022",
4 | "module": "ESNext",
5 | "moduleResolution": "Bundler",
6 | "esModuleInterop": true,
7 | "noEmit": true,
8 | "strict": true,
9 | "skipLibCheck": true,
10 | "isolatedModules": true,
11 | "lib": [
12 | "ES2022"
13 | ]
14 | },
15 | }
--------------------------------------------------------------------------------
/src/080-configuring-typescript/185-extending-from-other-tsconfig-json-files.problem/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "exercise",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "scripts": {
6 | "dev": "run-p dev:*",
7 | "dev:client": "tsc --project ./src/client/tsconfig.json --watch",
8 | "dev:server": "tsc --project ./src/server/tsconfig.json --watch"
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/185-extending-from-other-tsconfig-json-files.problem/src/client/index.ts:
--------------------------------------------------------------------------------
1 | document.addEventListener("DOMContentLoaded", () => {
2 | const app = document.querySelector("#app")!;
3 | app.innerHTML = "Hello World!";
4 | });
5 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/185-extending-from-other-tsconfig-json-files.problem/src/client/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2022",
4 | "module": "ESNext",
5 | "moduleResolution": "Bundler",
6 | "esModuleInterop": true,
7 | "noEmit": true,
8 | "strict": true,
9 | "skipLibCheck": true,
10 | "isolatedModules": true
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/185-extending-from-other-tsconfig-json-files.problem/src/server/index.ts:
--------------------------------------------------------------------------------
1 | // @ts-expect-error
2 | document;
3 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/185-extending-from-other-tsconfig-json-files.problem/src/server/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2022",
4 | "module": "ESNext",
5 | "moduleResolution": "Bundler",
6 | "esModuleInterop": true,
7 | "noEmit": true,
8 | "strict": true,
9 | "skipLibCheck": true,
10 | "isolatedModules": true,
11 | "lib": [
12 | "ES2022"
13 | ]
14 | },
15 | }
--------------------------------------------------------------------------------
/src/080-configuring-typescript/185-extending-from-other-tsconfig-json-files.solution/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "exercise",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "scripts": {
6 | "dev": "run-p dev:*",
7 | "dev:client": "tsc --project ./src/client/tsconfig.json --watch",
8 | "dev:server": "tsc --project ./src/server/tsconfig.json --watch"
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/185-extending-from-other-tsconfig-json-files.solution/src/client/index.ts:
--------------------------------------------------------------------------------
1 | document.addEventListener("DOMContentLoaded", () => {
2 | const app = document.querySelector("#app")!;
3 | app.innerHTML = "Hello World!";
4 | });
5 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/185-extending-from-other-tsconfig-json-files.solution/src/client/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.base.json"
3 | }
4 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/185-extending-from-other-tsconfig-json-files.solution/src/server/index.ts:
--------------------------------------------------------------------------------
1 | // @ts-expect-error
2 | document;
3 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/185-extending-from-other-tsconfig-json-files.solution/src/server/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.base.json",
3 | "compilerOptions": {
4 | "lib": [
5 | "ES2022"
6 | ]
7 | },
8 | }
--------------------------------------------------------------------------------
/src/080-configuring-typescript/185-extending-from-other-tsconfig-json-files.solution/tsconfig.base.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2022",
4 | "module": "ESNext",
5 | "moduleResolution": "Bundler",
6 | "esModuleInterop": true,
7 | "noEmit": true,
8 | "strict": true,
9 | "skipLibCheck": true,
10 | "isolatedModules": true,
11 | },
12 | }
--------------------------------------------------------------------------------
/src/080-configuring-typescript/186-project-references.problem/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "exercise",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "scripts": {
6 | "dev": "run-p dev:*",
7 | "dev:client": "tsc --project ./src/client/tsconfig.json --watch",
8 | "dev:server": "tsc --project ./src/server/tsconfig.json --watch"
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/186-project-references.problem/src/client/index.ts:
--------------------------------------------------------------------------------
1 | document.addEventListener("DOMContentLoaded", () => {
2 | const app = document.querySelector("#app")!;
3 | app.innerHTML = "Hello World!";
4 | });
5 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/186-project-references.problem/src/client/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.base.json",
3 | "compilerOptions": {
4 | "lib": [
5 | "ES2022",
6 | "DOM",
7 | "DOM.Iterable"
8 | ]
9 | },
10 | }
--------------------------------------------------------------------------------
/src/080-configuring-typescript/186-project-references.problem/src/server/index.ts:
--------------------------------------------------------------------------------
1 | // @ts-expect-error
2 | document;
3 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/186-project-references.problem/src/server/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.base.json",
3 | "compilerOptions": {
4 | "lib": [
5 | "ES2022"
6 | ]
7 | },
8 | }
--------------------------------------------------------------------------------
/src/080-configuring-typescript/186-project-references.problem/tsconfig.base.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2022",
4 | "module": "ESNext",
5 | "moduleResolution": "Bundler",
6 | "esModuleInterop": true,
7 | "noEmit": true,
8 | "strict": true,
9 | "skipLibCheck": true,
10 | "isolatedModules": true,
11 | },
12 | }
--------------------------------------------------------------------------------
/src/080-configuring-typescript/186-project-references.solution.1/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "exercise",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "scripts": {
6 | "dev": "tsc -b --watch"
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/186-project-references.solution.1/pnpm-lock.yaml:
--------------------------------------------------------------------------------
1 | lockfileVersion: '6.0'
2 |
3 | settings:
4 | autoInstallPeers: true
5 | excludeLinksFromLockfile: false
6 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/186-project-references.solution.1/src/client/index.ts:
--------------------------------------------------------------------------------
1 | document.addEventListener("DOMContentLoaded", () => {
2 | const app = document.querySelector("#app")!;
3 | app.innerHTML = "Hello World!";
4 | });
5 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/186-project-references.solution.1/src/client/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.base.json",
3 | "compilerOptions": {
4 | "lib": [
5 | "ES2022",
6 | "DOM",
7 | "DOM.Iterable"
8 | ]
9 | },
10 | }
--------------------------------------------------------------------------------
/src/080-configuring-typescript/186-project-references.solution.1/src/server/index.ts:
--------------------------------------------------------------------------------
1 | // @ts-expect-error
2 | document;
3 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/186-project-references.solution.1/src/server/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.base.json",
3 | "compilerOptions": {
4 | "lib": [
5 | "ES2022"
6 | ]
7 | },
8 | }
--------------------------------------------------------------------------------
/src/080-configuring-typescript/186-project-references.solution.1/tsconfig.base.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2022",
4 | "module": "ESNext",
5 | "moduleResolution": "Bundler",
6 | "esModuleInterop": true,
7 | "noEmit": true,
8 | "strict": true,
9 | "skipLibCheck": true,
10 | "isolatedModules": true,
11 | "composite": true
12 | },
13 | }
--------------------------------------------------------------------------------
/src/080-configuring-typescript/186-project-references.solution.1/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "references": [
3 | {
4 | "path": "./src/client/tsconfig.json"
5 | },
6 | {
7 | "path": "./src/server/tsconfig.json"
8 | }
9 | ],
10 | "files": []
11 | }
--------------------------------------------------------------------------------
/src/080-configuring-typescript/186-project-references.solution.2/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "exercise",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "scripts": {
6 | "dev": "tsc -b --watch"
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/186-project-references.solution.2/pnpm-lock.yaml:
--------------------------------------------------------------------------------
1 | lockfileVersion: '6.0'
2 |
3 | settings:
4 | autoInstallPeers: true
5 | excludeLinksFromLockfile: false
6 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/186-project-references.solution.2/src/client/index.ts:
--------------------------------------------------------------------------------
1 | document.addEventListener("DOMContentLoaded", () => {
2 | const app = document.querySelector("#app")!;
3 | app.innerHTML = "Hello World!";
4 | });
5 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/186-project-references.solution.2/src/server/index.ts:
--------------------------------------------------------------------------------
1 | // @ts-expect-error
2 | document;
3 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/186-project-references.solution.2/tsconfig.base.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2022",
4 | "module": "ESNext",
5 | "moduleResolution": "Bundler",
6 | "esModuleInterop": true,
7 | "noEmit": true,
8 | "strict": true,
9 | "skipLibCheck": true,
10 | "isolatedModules": true,
11 | "composite": true
12 | },
13 | }
--------------------------------------------------------------------------------
/src/080-configuring-typescript/186-project-references.solution.2/tsconfig.client.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.base.json",
3 | "compilerOptions": {
4 | "lib": [
5 | "ES2022",
6 | "DOM",
7 | "DOM.Iterable"
8 | ]
9 | },
10 | "include": [
11 | "src/client"
12 | ]
13 | }
--------------------------------------------------------------------------------
/src/080-configuring-typescript/186-project-references.solution.2/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "references": [
3 | {
4 | "path": "./tsconfig.client.json"
5 | },
6 | {
7 | "path": "./tsconfig.server.json"
8 | }
9 | ],
10 | "files": []
11 | }
--------------------------------------------------------------------------------
/src/080-configuring-typescript/186-project-references.solution.2/tsconfig.server.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.base.json",
3 | "compilerOptions": {
4 | "lib": [
5 | "ES2022"
6 | ]
7 | },
8 | "include": [
9 | "src/server"
10 | ]
11 | }
--------------------------------------------------------------------------------
/src/080-configuring-typescript/186-project-references.solution.3/.config/tsconfig.base.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2022",
4 | "module": "ESNext",
5 | "moduleResolution": "Bundler",
6 | "esModuleInterop": true,
7 | "noEmit": true,
8 | "strict": true,
9 | "skipLibCheck": true,
10 | "isolatedModules": true,
11 | "composite": true
12 | },
13 | }
--------------------------------------------------------------------------------
/src/080-configuring-typescript/186-project-references.solution.3/.config/tsconfig.client.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.base.json",
3 | "compilerOptions": {
4 | "lib": [
5 | "ES2022",
6 | "DOM",
7 | "DOM.Iterable"
8 | ]
9 | },
10 | "include": [
11 | "../src/client"
12 | ]
13 | }
--------------------------------------------------------------------------------
/src/080-configuring-typescript/186-project-references.solution.3/.config/tsconfig.server.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.base.json",
3 | "compilerOptions": {
4 | "lib": [
5 | "ES2022"
6 | ]
7 | },
8 | "include": [
9 | "../src/server"
10 | ]
11 | }
--------------------------------------------------------------------------------
/src/080-configuring-typescript/186-project-references.solution.3/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "exercise",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "scripts": {
6 | "dev": "tsc -b --watch"
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/186-project-references.solution.3/pnpm-lock.yaml:
--------------------------------------------------------------------------------
1 | lockfileVersion: '6.0'
2 |
3 | settings:
4 | autoInstallPeers: true
5 | excludeLinksFromLockfile: false
6 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/186-project-references.solution.3/src/client/index.ts:
--------------------------------------------------------------------------------
1 | document.addEventListener("DOMContentLoaded", () => {
2 | const app = document.querySelector("#app")!;
3 | app.innerHTML = "Hello World!";
4 | });
5 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/186-project-references.solution.3/src/server/index.ts:
--------------------------------------------------------------------------------
1 | // @ts-expect-error
2 | document;
3 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/186-project-references.solution.3/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "references": [
3 | {
4 | "path": "./.config/tsconfig.client.json"
5 | },
6 | {
7 | "path": "./.config/tsconfig.server.json"
8 | }
9 | ],
10 | "files": []
11 | }
--------------------------------------------------------------------------------
/src/080-configuring-typescript/190-setting-up-types-for-node.explainer/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "exercise",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "scripts": {
6 | "dev": "nodemon --exec \"tsc && node dist/index.js || exit 1\" -e ts,tsx,json --watch src"
7 | },
8 | "devDependencies": {
9 | "@types/node": "^20.6.2"
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/190-setting-up-types-for-node.explainer/pnpm-lock.yaml:
--------------------------------------------------------------------------------
1 | lockfileVersion: '6.0'
2 |
3 | settings:
4 | autoInstallPeers: true
5 | excludeLinksFromLockfile: false
6 |
--------------------------------------------------------------------------------
/src/080-configuring-typescript/190-setting-up-types-for-node.explainer/src/index.ts:
--------------------------------------------------------------------------------
1 | console.log("Hello!");
2 |
--------------------------------------------------------------------------------
/src/082-cjs-vs-esm/193-intro.explainer.ts:
--------------------------------------------------------------------------------
1 | // Explain the differences between CJS and ESM
2 |
--------------------------------------------------------------------------------
/src/082-cjs-vs-esm/194-cant-import-esm-into-cjs.problem/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "117-const-enums.explainer",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "dev": "nodemon ./src/index.js"
8 | },
9 | "keywords": [],
10 | "author": "Matt Pocock",
11 | "devDependencies": {}
12 | }
13 |
--------------------------------------------------------------------------------
/src/082-cjs-vs-esm/194-cant-import-esm-into-cjs.problem/pnpm-lock.yaml:
--------------------------------------------------------------------------------
1 | lockfileVersion: '6.0'
2 |
3 | settings:
4 | autoInstallPeers: true
5 | excludeLinksFromLockfile: false
6 |
--------------------------------------------------------------------------------
/src/082-cjs-vs-esm/194-cant-import-esm-into-cjs.problem/src/esm-module.js:
--------------------------------------------------------------------------------
1 | const hello = () => {
2 | console.log("Hello!");
3 | };
4 |
5 | export default hello;
6 |
--------------------------------------------------------------------------------
/src/082-cjs-vs-esm/194-cant-import-esm-into-cjs.problem/src/index.js:
--------------------------------------------------------------------------------
1 | const esModule = require("./esm-module.js"); // cjs require
2 |
3 | const main = async () => {
4 | esModule.default();
5 | };
6 |
7 | main();
8 |
--------------------------------------------------------------------------------
/src/082-cjs-vs-esm/194-cant-import-esm-into-cjs.solution/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "117-const-enums.explainer",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "dev": "nodemon ./src/index.js"
8 | },
9 | "keywords": [],
10 | "author": "Matt Pocock",
11 | "devDependencies": {}
12 | }
13 |
--------------------------------------------------------------------------------
/src/082-cjs-vs-esm/194-cant-import-esm-into-cjs.solution/pnpm-lock.yaml:
--------------------------------------------------------------------------------
1 | lockfileVersion: '6.0'
2 |
3 | settings:
4 | autoInstallPeers: true
5 | excludeLinksFromLockfile: false
6 |
--------------------------------------------------------------------------------
/src/082-cjs-vs-esm/194-cant-import-esm-into-cjs.solution/src/esm-module.mjs:
--------------------------------------------------------------------------------
1 | const hello = () => {
2 | console.log("Hello from Matt!");
3 | };
4 |
5 | export default hello;
6 |
--------------------------------------------------------------------------------
/src/082-cjs-vs-esm/194-cant-import-esm-into-cjs.solution/src/index.js:
--------------------------------------------------------------------------------
1 | // const esModule = require("./esm-module.js"); // cjs require
2 |
3 | const main = async () => {
4 | const esModule = await import("./esm-module.mjs");
5 | esModule.default();
6 | };
7 |
8 | main();
9 |
--------------------------------------------------------------------------------
/src/082-cjs-vs-esm/195-can-import-cjs-into-esm.explainer/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "117-const-enums.explainer",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "dev": "nodemon ./src/index.mjs"
8 | },
9 | "keywords": [],
10 | "author": "Matt Pocock",
11 | "devDependencies": {}
12 | }
13 |
--------------------------------------------------------------------------------
/src/082-cjs-vs-esm/195-can-import-cjs-into-esm.explainer/pnpm-lock.yaml:
--------------------------------------------------------------------------------
1 | lockfileVersion: '6.0'
2 |
3 | settings:
4 | autoInstallPeers: true
5 | excludeLinksFromLockfile: false
6 |
--------------------------------------------------------------------------------
/src/082-cjs-vs-esm/195-can-import-cjs-into-esm.explainer/src/cjs-module.cjs:
--------------------------------------------------------------------------------
1 | const hello = () => {
2 | console.log("Hello!");
3 | };
4 |
5 | module.exports = hello;
6 |
--------------------------------------------------------------------------------
/src/082-cjs-vs-esm/195-can-import-cjs-into-esm.explainer/src/index.mjs:
--------------------------------------------------------------------------------
1 | import hello from "./cjs-module.cjs";
2 |
3 | const main = async () => {
4 | hello();
5 | };
6 |
7 | main();
8 |
--------------------------------------------------------------------------------
/src/082-cjs-vs-esm/196-mts-files.problem/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "117-const-enums.explainer",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "dev": "nodemon --exec \"tsc && node dist/index.js\" ./src/index.ts"
8 | },
9 | "keywords": [],
10 | "author": "Matt Pocock",
11 | "devDependencies": {}
12 | }
13 |
--------------------------------------------------------------------------------
/src/082-cjs-vs-esm/196-mts-files.problem/src/esm-module.ts:
--------------------------------------------------------------------------------
1 | const hello = () => {
2 | console.log("Hello!");
3 | };
4 |
5 | export default hello;
6 |
--------------------------------------------------------------------------------
/src/082-cjs-vs-esm/196-mts-files.problem/src/index.ts:
--------------------------------------------------------------------------------
1 | const main = async () => {
2 | const esModule = await import("./esm-module.js"); // Dynamic import
3 |
4 | esModule.default();
5 | };
6 |
7 | main();
8 |
--------------------------------------------------------------------------------
/src/082-cjs-vs-esm/196-mts-files.problem/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2022",
4 | "module": "NodeNext",
5 | "moduleResolution": "NodeNext",
6 | "outDir": "dist",
7 | "esModuleInterop": true,
8 | "strict": true,
9 | "skipLibCheck": true,
10 | "isolatedModules": true
11 | },
12 | }
--------------------------------------------------------------------------------
/src/082-cjs-vs-esm/196-mts-files.solution/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "117-const-enums.explainer",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "dev": "nodemon --exec \"tsc && node dist/index.js\" ./src/index.ts"
8 | },
9 | "keywords": [],
10 | "author": "Matt Pocock",
11 | "devDependencies": {}
12 | }
13 |
--------------------------------------------------------------------------------
/src/082-cjs-vs-esm/196-mts-files.solution/src/esm-module.mts:
--------------------------------------------------------------------------------
1 | const hello = () => {
2 | console.log("Hello!");
3 | };
4 |
5 | export default hello;
6 |
--------------------------------------------------------------------------------
/src/082-cjs-vs-esm/196-mts-files.solution/src/index.ts:
--------------------------------------------------------------------------------
1 | const main = async () => {
2 | const esModule = await import("./esm-module.mjs"); // Dynamic import
3 |
4 | esModule.default();
5 | };
6 |
7 | main();
8 |
--------------------------------------------------------------------------------
/src/082-cjs-vs-esm/196-mts-files.solution/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2022",
4 | "module": "NodeNext",
5 | "moduleResolution": "NodeNext",
6 | "outDir": "dist",
7 | "esModuleInterop": true,
8 | "strict": true,
9 | "skipLibCheck": true,
10 | "isolatedModules": true
11 | },
12 | }
--------------------------------------------------------------------------------
/src/082-cjs-vs-esm/196.5-browsers-cant-use-cjs.explainer.1/.gitignore:
--------------------------------------------------------------------------------
1 | dist
--------------------------------------------------------------------------------
/src/082-cjs-vs-esm/196.5-browsers-cant-use-cjs.explainer.1/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | My App
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/src/082-cjs-vs-esm/196.5-browsers-cant-use-cjs.explainer.1/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "scripts": {
3 | "dev": "nodemon --exec \"tsc && serve . && echo \"Serving...\"\" ./src/example.ts"
4 | },
5 | "devDependencies": {
6 | "serve": "^14.2.1"
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/src/082-cjs-vs-esm/196.5-browsers-cant-use-cjs.explainer.1/src/example.ts:
--------------------------------------------------------------------------------
1 | import { run } from "./run.js";
2 |
3 | run("Hello!");
4 |
--------------------------------------------------------------------------------
/src/082-cjs-vs-esm/196.5-browsers-cant-use-cjs.explainer.1/src/run.ts:
--------------------------------------------------------------------------------
1 | export const run = (message: string) => {
2 | console.log(message);
3 | };
4 |
--------------------------------------------------------------------------------
/src/082-cjs-vs-esm/196.5-browsers-cant-use-cjs.explainer.1/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2022",
4 | "module": "NodeNext",
5 | "moduleResolution": "NodeNext",
6 | "outDir": "dist",
7 | "esModuleInterop": true,
8 | "strict": true,
9 | "skipLibCheck": true,
10 | "isolatedModules": true
11 | },
12 | }
--------------------------------------------------------------------------------
/src/082-cjs-vs-esm/196.5-browsers-cant-use-cjs.explainer.2/.gitignore:
--------------------------------------------------------------------------------
1 | dist
--------------------------------------------------------------------------------
/src/082-cjs-vs-esm/196.5-browsers-cant-use-cjs.explainer.2/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | My App
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/src/082-cjs-vs-esm/196.5-browsers-cant-use-cjs.explainer.2/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "scripts": {
3 | "dev": "nodemon --exec \"tsc && serve . && echo \"Serving...\"\" ./src/example.mts"
4 | },
5 | "devDependencies": {
6 | "serve": "^14.2.1"
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/src/082-cjs-vs-esm/196.5-browsers-cant-use-cjs.explainer.2/src/example.mts:
--------------------------------------------------------------------------------
1 | import { run } from "./run.mjs";
2 |
3 | run("Hello!");
4 |
--------------------------------------------------------------------------------
/src/082-cjs-vs-esm/196.5-browsers-cant-use-cjs.explainer.2/src/run.mts:
--------------------------------------------------------------------------------
1 | export const run = (message: string) => {
2 | console.log(message);
3 | };
4 |
--------------------------------------------------------------------------------
/src/082-cjs-vs-esm/196.5-browsers-cant-use-cjs.explainer.2/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2022",
4 | "module": "NodeNext",
5 | "moduleResolution": "NodeNext",
6 | "outDir": "dist",
7 | "esModuleInterop": true,
8 | "strict": true,
9 | "skipLibCheck": true,
10 | "isolatedModules": true
11 | },
12 | }
--------------------------------------------------------------------------------
/src/082-cjs-vs-esm/197-verbatim-module-syntax.problem/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "117-const-enums.explainer",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "dev": "nodemon --exec \"tsc && node dist/index.js\" ./src/cjs-module.ts"
8 | },
9 | "keywords": [],
10 | "author": "Matt Pocock",
11 | "devDependencies": {}
12 | }
13 |
--------------------------------------------------------------------------------
/src/082-cjs-vs-esm/197-verbatim-module-syntax.problem/src/cjs-module.ts:
--------------------------------------------------------------------------------
1 | const hello = () => {
2 | console.log("Hello!");
3 | };
4 |
5 | // @ts-expect-error
6 | export default hello;
7 |
--------------------------------------------------------------------------------
/src/082-cjs-vs-esm/197-verbatim-module-syntax.problem/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2022",
4 | "module": "NodeNext",
5 | "moduleResolution": "NodeNext",
6 | "outDir": "dist",
7 | "esModuleInterop": true,
8 | "strict": true,
9 | "skipLibCheck": true,
10 | "isolatedModules": true
11 | },
12 | }
--------------------------------------------------------------------------------
/src/082-cjs-vs-esm/197-verbatim-module-syntax.solution/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "117-const-enums.explainer",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "dev": "nodemon --exec \"tsc && node dist/index.js\" ./src/cjs-module.ts"
8 | },
9 | "keywords": [],
10 | "author": "Matt Pocock",
11 | "devDependencies": {}
12 | }
13 |
--------------------------------------------------------------------------------
/src/082-cjs-vs-esm/197-verbatim-module-syntax.solution/pnpm-lock.yaml:
--------------------------------------------------------------------------------
1 | lockfileVersion: '6.0'
2 |
3 | settings:
4 | autoInstallPeers: true
5 | excludeLinksFromLockfile: false
6 |
--------------------------------------------------------------------------------
/src/082-cjs-vs-esm/197-verbatim-module-syntax.solution/src/cjs-module.ts:
--------------------------------------------------------------------------------
1 | const hello = () => {
2 | console.log("Hello!");
3 | };
4 |
5 | // @ts-expect-error
6 | export default hello;
7 |
--------------------------------------------------------------------------------
/src/082-cjs-vs-esm/197-verbatim-module-syntax.solution/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2022",
4 | "module": "NodeNext",
5 | "moduleResolution": "NodeNext",
6 | "outDir": "dist",
7 | "esModuleInterop": true,
8 | "strict": true,
9 | "skipLibCheck": true,
10 | "isolatedModules": true,
11 | "verbatimModuleSyntax": true
12 | },
13 | }
--------------------------------------------------------------------------------
/src/082-cjs-vs-esm/198-treat-ts-files-as-esm.problem/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "117-const-enums.explainer",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "dev": "nodemon --exec \"tsc && node dist/index.js\" ./src/index.ts"
8 | },
9 | "keywords": [],
10 | "author": "Matt Pocock",
11 | "devDependencies": {}
12 | }
13 |
--------------------------------------------------------------------------------
/src/082-cjs-vs-esm/198-treat-ts-files-as-esm.problem/src/esm-module.ts:
--------------------------------------------------------------------------------
1 | const hello = () => {
2 | console.log("Hello!");
3 | };
4 |
5 | export default hello;
6 |
--------------------------------------------------------------------------------
/src/082-cjs-vs-esm/198-treat-ts-files-as-esm.problem/src/index.ts:
--------------------------------------------------------------------------------
1 | import esModule from "./esm-module";
2 |
3 | const main = async () => {
4 | esModule();
5 | };
6 |
7 | main();
8 |
--------------------------------------------------------------------------------
/src/082-cjs-vs-esm/198-treat-ts-files-as-esm.problem/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2022",
4 | "module": "NodeNext",
5 | "moduleResolution": "NodeNext",
6 | "outDir": "dist",
7 | "esModuleInterop": true,
8 | "strict": true,
9 | "skipLibCheck": true,
10 | "isolatedModules": true,
11 | "verbatimModuleSyntax": true
12 | },
13 | }
--------------------------------------------------------------------------------
/src/082-cjs-vs-esm/198-treat-ts-files-as-esm.solution/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "117-const-enums.explainer",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "dev": "nodemon --exec \"tsc && node dist/index.js\" ./src/index.ts"
8 | },
9 | "keywords": [],
10 | "author": "Matt Pocock",
11 | "devDependencies": {},
12 | "type": "module"
13 | }
14 |
--------------------------------------------------------------------------------
/src/082-cjs-vs-esm/198-treat-ts-files-as-esm.solution/src/esm-module.ts:
--------------------------------------------------------------------------------
1 | const hello = () => {
2 | console.log("Hello!");
3 | };
4 |
5 | export default hello;
6 |
--------------------------------------------------------------------------------
/src/082-cjs-vs-esm/198-treat-ts-files-as-esm.solution/src/index.ts:
--------------------------------------------------------------------------------
1 | import esModule from "./esm-module.js";
2 |
3 | const main = async () => {
4 | esModule();
5 | };
6 |
7 | main();
8 |
--------------------------------------------------------------------------------
/src/082-cjs-vs-esm/198-treat-ts-files-as-esm.solution/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2022",
4 | "module": "NodeNext",
5 | "moduleResolution": "NodeNext",
6 | "outDir": "dist",
7 | "esModuleInterop": true,
8 | "strict": true,
9 | "skipLibCheck": true,
10 | "isolatedModules": true,
11 | "verbatimModuleSyntax": true
12 | },
13 | }
--------------------------------------------------------------------------------
/src/082-cjs-vs-esm/200-import-syntax-for-cts.problem/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "117-const-enums.explainer",
3 | "version": "1.0.0",
4 | "description": "",
5 | "scripts": {
6 | "dev": "nodemon --exec \"tsc && node dist/index.js\" ./src/index.ts"
7 | },
8 | "keywords": [],
9 | "author": "Matt Pocock",
10 | "devDependencies": {}
11 | }
12 |
--------------------------------------------------------------------------------
/src/082-cjs-vs-esm/200-import-syntax-for-cts.problem/src/index.ts:
--------------------------------------------------------------------------------
1 | import otherModule from "./other-module.js";
2 |
3 | const main = async () => {
4 | otherModule();
5 | };
6 |
7 | main();
8 |
--------------------------------------------------------------------------------
/src/082-cjs-vs-esm/200-import-syntax-for-cts.problem/src/other-module.ts:
--------------------------------------------------------------------------------
1 | const hello = () => {
2 | console.log("Hello!");
3 | };
4 |
5 | export default hello;
6 |
--------------------------------------------------------------------------------
/src/082-cjs-vs-esm/200-import-syntax-for-cts.problem/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2022",
4 | "module": "NodeNext",
5 | "moduleResolution": "NodeNext",
6 | "outDir": "dist",
7 | "esModuleInterop": true,
8 | "strict": true,
9 | "skipLibCheck": true,
10 | "isolatedModules": true,
11 | "verbatimModuleSyntax": true
12 | },
13 | }
--------------------------------------------------------------------------------
/src/082-cjs-vs-esm/200-import-syntax-for-cts.solution/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "117-const-enums.explainer",
3 | "version": "1.0.0",
4 | "description": "",
5 | "scripts": {
6 | "dev": "nodemon --exec \"tsc && node dist/index.js\" ./src/index.ts"
7 | },
8 | "keywords": [],
9 | "author": "Matt Pocock",
10 | "devDependencies": {}
11 | }
12 |
--------------------------------------------------------------------------------
/src/082-cjs-vs-esm/200-import-syntax-for-cts.solution/src/index.ts:
--------------------------------------------------------------------------------
1 | import otherModule = require("./other-module.js");
2 |
3 | const main = async () => {
4 | otherModule();
5 | };
6 |
7 | main();
8 |
--------------------------------------------------------------------------------
/src/082-cjs-vs-esm/200-import-syntax-for-cts.solution/src/other-module.ts:
--------------------------------------------------------------------------------
1 | const hello = () => {
2 | console.log("Hello!");
3 | };
4 |
5 | export = hello;
6 |
--------------------------------------------------------------------------------
/src/082-cjs-vs-esm/200-import-syntax-for-cts.solution/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2022",
4 | "module": "NodeNext",
5 | "moduleResolution": "NodeNext",
6 | "outDir": "dist",
7 | "esModuleInterop": true,
8 | "strict": true,
9 | "skipLibCheck": true,
10 | "isolatedModules": true,
11 | "verbatimModuleSyntax": true
12 | },
13 | }
--------------------------------------------------------------------------------
/src/082-cjs-vs-esm/201-module-nodenext-emits-the-right-extensions.explainer/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "117-const-enums.explainer",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "dev": "tsc --watch"
8 | },
9 | "keywords": [],
10 | "author": "Matt Pocock",
11 | "devDependencies": {}
12 | }
13 |
--------------------------------------------------------------------------------
/src/082-cjs-vs-esm/201-module-nodenext-emits-the-right-extensions.explainer/pnpm-lock.yaml:
--------------------------------------------------------------------------------
1 | lockfileVersion: '6.0'
2 |
3 | settings:
4 | autoInstallPeers: true
5 | excludeLinksFromLockfile: false
6 |
--------------------------------------------------------------------------------
/src/082-cjs-vs-esm/201-module-nodenext-emits-the-right-extensions.explainer/src/cjs-module.cts:
--------------------------------------------------------------------------------
1 | const example = 123;
2 |
3 | export = example;
4 |
--------------------------------------------------------------------------------
/src/082-cjs-vs-esm/201-module-nodenext-emits-the-right-extensions.explainer/src/esm-module.mts:
--------------------------------------------------------------------------------
1 | const hello = () => {
2 | console.log("Hello!");
3 | };
4 |
5 | export default hello;
6 |
--------------------------------------------------------------------------------
/src/082-cjs-vs-esm/201-module-nodenext-emits-the-right-extensions.explainer/src/index.ts:
--------------------------------------------------------------------------------
1 | import example = require("./cjs-module.cjs");
2 |
3 | const main = async () => {
4 | const esModule = await import("./esm-module.mjs"); // Dynamic import
5 |
6 | esModule.default();
7 | };
8 |
9 | main();
10 |
--------------------------------------------------------------------------------
/src/082-cjs-vs-esm/202.5-import-type.problem/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "117-const-enums.explainer",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "type": "module",
7 | "scripts": {
8 | "dev": "tsc --watch"
9 | },
10 | "keywords": [],
11 | "author": "Matt Pocock",
12 | "devDependencies": {}
13 | }
14 |
--------------------------------------------------------------------------------
/src/082-cjs-vs-esm/202.5-import-type.problem/src/esm-module.ts:
--------------------------------------------------------------------------------
1 | import { Example } from "./module-containing-types.js";
2 |
3 | type Example2 = Example;
4 |
--------------------------------------------------------------------------------
/src/082-cjs-vs-esm/202.5-import-type.problem/src/module-containing-types.ts:
--------------------------------------------------------------------------------
1 | export type Example = string;
2 |
--------------------------------------------------------------------------------
/src/082-cjs-vs-esm/202.5-import-type.problem/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2022",
4 | "module": "NodeNext",
5 | "moduleResolution": "NodeNext",
6 | "outDir": "dist",
7 | "esModuleInterop": true,
8 | "strict": true,
9 | "skipLibCheck": true,
10 | "isolatedModules": true,
11 | "verbatimModuleSyntax": true
12 | },
13 | }
--------------------------------------------------------------------------------
/src/082-cjs-vs-esm/202.5-import-type.solution/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "117-const-enums.explainer",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "type": "module",
7 | "scripts": {
8 | "dev": "tsc --watch"
9 | },
10 | "keywords": [],
11 | "author": "Matt Pocock",
12 | "devDependencies": {}
13 | }
14 |
--------------------------------------------------------------------------------
/src/082-cjs-vs-esm/202.5-import-type.solution/src/esm-module.ts:
--------------------------------------------------------------------------------
1 | import type { Example } from "./module-containing-types.js";
2 |
3 | type Example2 = Example;
4 |
--------------------------------------------------------------------------------
/src/082-cjs-vs-esm/202.5-import-type.solution/src/module-containing-types.ts:
--------------------------------------------------------------------------------
1 | export type Example = string;
2 |
--------------------------------------------------------------------------------
/src/082-cjs-vs-esm/202.5-import-type.solution/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2022",
4 | "module": "NodeNext",
5 | "moduleResolution": "NodeNext",
6 | "outDir": "dist",
7 | "esModuleInterop": true,
8 | "strict": true,
9 | "skipLibCheck": true,
10 | "isolatedModules": true,
11 | "verbatimModuleSyntax": true
12 | },
13 | }
--------------------------------------------------------------------------------
/src/082-cjs-vs-esm/202.6-should-i-use-cjs-or-esm.explainer.ts:
--------------------------------------------------------------------------------
1 | // Should you use CJS or ESM?
2 |
--------------------------------------------------------------------------------
/src/082-cjs-vs-esm/202.7-applications-vs-libraries.explainer.ts:
--------------------------------------------------------------------------------
1 | // Discuss applications vs libraries
2 | // Discuss dual publishing cjs and esm
3 |
--------------------------------------------------------------------------------
/src/083-designing-your-types/203-domain-modelling-in-typescript.explainer.ts:
--------------------------------------------------------------------------------
1 | // Modelling your domain in TypeScript
2 |
3 | // Think of the entities in your domain as individual types
4 |
5 | // Compose those types together
6 |
7 | // Think about types as containers for other types
8 |
--------------------------------------------------------------------------------
/src/083-designing-your-types/210-template-literal-types.problem.ts:
--------------------------------------------------------------------------------
1 | type AbsoluteRoute = string;
2 |
3 | const goToRoute = (route: AbsoluteRoute) => {
4 | // ...
5 | };
6 |
7 | goToRoute("/home");
8 | goToRoute("/about");
9 | goToRoute("/contact");
10 |
11 | goToRoute(
12 | // @ts-expect-error
13 | "somewhere",
14 | );
15 |
--------------------------------------------------------------------------------
/src/083-designing-your-types/210-template-literal-types.solution.ts:
--------------------------------------------------------------------------------
1 | type AbsoluteRoute = `/${string}`;
2 |
3 | const goToRoute = (route: AbsoluteRoute) => {
4 | // ...
5 | };
6 |
7 | goToRoute("/home");
8 | goToRoute("/about");
9 | goToRoute("/contact");
10 |
11 | goToRoute(
12 | // @ts-expect-error
13 | "somewhere",
14 | );
15 |
--------------------------------------------------------------------------------
/src/085-the-utils-folder/214-intro-to-the-utils-folder.explainer.ts:
--------------------------------------------------------------------------------
1 | // Three levels of TypeScript complexity
2 |
3 | // Application Development, Library Development and Utils Folder Development
4 |
--------------------------------------------------------------------------------
/src/090-the-style-guide/224-hungarian-notation.problem.ts:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/total-typescript/total-typescript-book/e9400f8009b70176dead19aa6c2d7b2de5614599/src/090-the-style-guide/224-hungarian-notation.problem.ts
--------------------------------------------------------------------------------
/src/090-the-style-guide/224-hungarian-notation.solution.ts:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/total-typescript/total-typescript-book/e9400f8009b70176dead19aa6c2d7b2de5614599/src/090-the-style-guide/224-hungarian-notation.solution.ts
--------------------------------------------------------------------------------
/src/090-the-style-guide/225-where-to-put-your-types.problem.ts:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/total-typescript/total-typescript-book/e9400f8009b70176dead19aa6c2d7b2de5614599/src/090-the-style-guide/225-where-to-put-your-types.problem.ts
--------------------------------------------------------------------------------
/src/090-the-style-guide/225-where-to-put-your-types.solution.ts:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/total-typescript/total-typescript-book/e9400f8009b70176dead19aa6c2d7b2de5614599/src/090-the-style-guide/225-where-to-put-your-types.solution.ts
--------------------------------------------------------------------------------
/src/090-the-style-guide/226-colocation-of-types.problem.ts:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/total-typescript/total-typescript-book/e9400f8009b70176dead19aa6c2d7b2de5614599/src/090-the-style-guide/226-colocation-of-types.problem.ts
--------------------------------------------------------------------------------
/src/090-the-style-guide/226-colocation-of-types.solution.ts:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/total-typescript/total-typescript-book/e9400f8009b70176dead19aa6c2d7b2de5614599/src/090-the-style-guide/226-colocation-of-types.solution.ts
--------------------------------------------------------------------------------
/src/090-the-style-guide/227-setting-up-eslint.explainer.ts:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/total-typescript/total-typescript-book/e9400f8009b70176dead19aa6c2d7b2de5614599/src/090-the-style-guide/227-setting-up-eslint.explainer.ts
--------------------------------------------------------------------------------
/src/090-the-style-guide/228-explicit-any-rule-or-not.problem.ts:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/total-typescript/total-typescript-book/e9400f8009b70176dead19aa6c2d7b2de5614599/src/090-the-style-guide/228-explicit-any-rule-or-not.problem.ts
--------------------------------------------------------------------------------
/src/090-the-style-guide/228-explicit-any-rule-or-not.solution.ts:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/total-typescript/total-typescript-book/e9400f8009b70176dead19aa6c2d7b2de5614599/src/090-the-style-guide/228-explicit-any-rule-or-not.solution.ts
--------------------------------------------------------------------------------
/src/090-the-style-guide/229-explicit-return-types-or-not.problem.ts:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/total-typescript/total-typescript-book/e9400f8009b70176dead19aa6c2d7b2de5614599/src/090-the-style-guide/229-explicit-return-types-or-not.problem.ts
--------------------------------------------------------------------------------
/src/090-the-style-guide/229-explicit-return-types-or-not.solution.ts:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/total-typescript/total-typescript-book/e9400f8009b70176dead19aa6c2d7b2de5614599/src/090-the-style-guide/229-explicit-return-types-or-not.solution.ts
--------------------------------------------------------------------------------
/src/090-the-style-guide/230-any-vs-ts-ignore-vs-ts-expect-error.problem.ts:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/total-typescript/total-typescript-book/e9400f8009b70176dead19aa6c2d7b2de5614599/src/090-the-style-guide/230-any-vs-ts-ignore-vs-ts-expect-error.problem.ts
--------------------------------------------------------------------------------
/src/090-the-style-guide/230-any-vs-ts-ignore-vs-ts-expect-error.solution.ts:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/total-typescript/total-typescript-book/e9400f8009b70176dead19aa6c2d7b2de5614599/src/090-the-style-guide/230-any-vs-ts-ignore-vs-ts-expect-error.solution.ts
--------------------------------------------------------------------------------
/src/090-the-style-guide/231-dont-declare-type-and-value-with-the-same-name.problem.ts:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/total-typescript/total-typescript-book/e9400f8009b70176dead19aa6c2d7b2de5614599/src/090-the-style-guide/231-dont-declare-type-and-value-with-the-same-name.problem.ts
--------------------------------------------------------------------------------
/src/090-the-style-guide/231-dont-declare-type-and-value-with-the-same-name.solution.ts:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/total-typescript/total-typescript-book/e9400f8009b70176dead19aa6c2d7b2de5614599/src/090-the-style-guide/231-dont-declare-type-and-value-with-the-same-name.solution.ts
--------------------------------------------------------------------------------
/src/090-the-style-guide/232-types-vs-interfaces.problem.ts:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/total-typescript/total-typescript-book/e9400f8009b70176dead19aa6c2d7b2de5614599/src/090-the-style-guide/232-types-vs-interfaces.problem.ts
--------------------------------------------------------------------------------
/src/090-the-style-guide/232-types-vs-interfaces.solution.ts:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/total-typescript/total-typescript-book/e9400f8009b70176dead19aa6c2d7b2de5614599/src/090-the-style-guide/232-types-vs-interfaces.solution.ts
--------------------------------------------------------------------------------
/src/090-the-style-guide/233-dont-use-uppercase-function-object-string-boolean-as-types.problem.ts:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/total-typescript/total-typescript-book/e9400f8009b70176dead19aa6c2d7b2de5614599/src/090-the-style-guide/233-dont-use-uppercase-function-object-string-boolean-as-types.problem.ts
--------------------------------------------------------------------------------
/src/090-the-style-guide/233-dont-use-uppercase-function-object-string-boolean-as-types.solution.ts:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/total-typescript/total-typescript-book/e9400f8009b70176dead19aa6c2d7b2de5614599/src/090-the-style-guide/233-dont-use-uppercase-function-object-string-boolean-as-types.solution.ts
--------------------------------------------------------------------------------
/src/090-the-style-guide/234-dont-make-your-types-globally-available-types.problem.ts:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/total-typescript/total-typescript-book/e9400f8009b70176dead19aa6c2d7b2de5614599/src/090-the-style-guide/234-dont-make-your-types-globally-available-types.problem.ts
--------------------------------------------------------------------------------
/src/090-the-style-guide/234-dont-make-your-types-globally-available-types.solution.ts:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/total-typescript/total-typescript-book/e9400f8009b70176dead19aa6c2d7b2de5614599/src/090-the-style-guide/234-dont-make-your-types-globally-available-types.solution.ts
--------------------------------------------------------------------------------
/src/090-the-style-guide/235-how-strict-should-you-configure-ts.problem.ts:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/total-typescript/total-typescript-book/e9400f8009b70176dead19aa6c2d7b2de5614599/src/090-the-style-guide/235-how-strict-should-you-configure-ts.problem.ts
--------------------------------------------------------------------------------
/src/090-the-style-guide/235-how-strict-should-you-configure-ts.solution.ts:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/total-typescript/total-typescript-book/e9400f8009b70176dead19aa6c2d7b2de5614599/src/090-the-style-guide/235-how-strict-should-you-configure-ts.solution.ts
--------------------------------------------------------------------------------
/src/090-the-style-guide/236-dont-unnecessarily-widen-types.problem.ts:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/total-typescript/total-typescript-book/e9400f8009b70176dead19aa6c2d7b2de5614599/src/090-the-style-guide/236-dont-unnecessarily-widen-types.problem.ts
--------------------------------------------------------------------------------
/src/090-the-style-guide/236-dont-unnecessarily-widen-types.solution.ts:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/total-typescript/total-typescript-book/e9400f8009b70176dead19aa6c2d7b2de5614599/src/090-the-style-guide/236-dont-unnecessarily-widen-types.solution.ts
--------------------------------------------------------------------------------
/src/090-the-style-guide/plan.md:
--------------------------------------------------------------------------------
1 | # Title
2 |
3 | Title here!
4 |
5 | ## Exercises
6 |
--------------------------------------------------------------------------------
/src/095-migrating-from-javascript/237-strict-file-by-file-vs-ramp-up-strictness.problem.ts:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/total-typescript/total-typescript-book/e9400f8009b70176dead19aa6c2d7b2de5614599/src/095-migrating-from-javascript/237-strict-file-by-file-vs-ramp-up-strictness.problem.ts
--------------------------------------------------------------------------------
/src/095-migrating-from-javascript/237-strict-file-by-file-vs-ramp-up-strictness.solution.ts:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/total-typescript/total-typescript-book/e9400f8009b70176dead19aa6c2d7b2de5614599/src/095-migrating-from-javascript/237-strict-file-by-file-vs-ramp-up-strictness.solution.ts
--------------------------------------------------------------------------------
/src/095-migrating-from-javascript/238-dependencies-first.problem.ts:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/total-typescript/total-typescript-book/e9400f8009b70176dead19aa6c2d7b2de5614599/src/095-migrating-from-javascript/238-dependencies-first.problem.ts
--------------------------------------------------------------------------------
/src/095-migrating-from-javascript/238-dependencies-first.solution.ts:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/total-typescript/total-typescript-book/e9400f8009b70176dead19aa6c2d7b2de5614599/src/095-migrating-from-javascript/238-dependencies-first.solution.ts
--------------------------------------------------------------------------------
/src/095-migrating-from-javascript/239-typing-third-party-modules.problem.ts:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/total-typescript/total-typescript-book/e9400f8009b70176dead19aa6c2d7b2de5614599/src/095-migrating-from-javascript/239-typing-third-party-modules.problem.ts
--------------------------------------------------------------------------------
/src/095-migrating-from-javascript/239-typing-third-party-modules.solution.ts:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/total-typescript/total-typescript-book/e9400f8009b70176dead19aa6c2d7b2de5614599/src/095-migrating-from-javascript/239-typing-third-party-modules.solution.ts
--------------------------------------------------------------------------------
/src/095-migrating-from-javascript/240-madge.problem.ts:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/total-typescript/total-typescript-book/e9400f8009b70176dead19aa6c2d7b2de5614599/src/095-migrating-from-javascript/240-madge.problem.ts
--------------------------------------------------------------------------------
/src/095-migrating-from-javascript/240-madge.solution.ts:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/total-typescript/total-typescript-book/e9400f8009b70176dead19aa6c2d7b2de5614599/src/095-migrating-from-javascript/240-madge.solution.ts
--------------------------------------------------------------------------------
/src/095-migrating-from-javascript/241-understanding-the-structure-of-ts-errors.problem.ts:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/total-typescript/total-typescript-book/e9400f8009b70176dead19aa6c2d7b2de5614599/src/095-migrating-from-javascript/241-understanding-the-structure-of-ts-errors.problem.ts
--------------------------------------------------------------------------------
/src/095-migrating-from-javascript/241-understanding-the-structure-of-ts-errors.solution.ts:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/total-typescript/total-typescript-book/e9400f8009b70176dead19aa6c2d7b2de5614599/src/095-migrating-from-javascript/241-understanding-the-structure-of-ts-errors.solution.ts
--------------------------------------------------------------------------------
/src/095-migrating-from-javascript/242-experiments-with-jsdoc.problem.ts:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/total-typescript/total-typescript-book/e9400f8009b70176dead19aa6c2d7b2de5614599/src/095-migrating-from-javascript/242-experiments-with-jsdoc.problem.ts
--------------------------------------------------------------------------------
/src/095-migrating-from-javascript/242-experiments-with-jsdoc.solution.ts:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/total-typescript/total-typescript-book/e9400f8009b70176dead19aa6c2d7b2de5614599/src/095-migrating-from-javascript/242-experiments-with-jsdoc.solution.ts
--------------------------------------------------------------------------------
/src/095-migrating-from-javascript/243-jsdoc-cannot-pass-types-to-functions.problem.ts:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/total-typescript/total-typescript-book/e9400f8009b70176dead19aa6c2d7b2de5614599/src/095-migrating-from-javascript/243-jsdoc-cannot-pass-types-to-functions.problem.ts
--------------------------------------------------------------------------------
/src/095-migrating-from-javascript/243-jsdoc-cannot-pass-types-to-functions.solution.ts:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/total-typescript/total-typescript-book/e9400f8009b70176dead19aa6c2d7b2de5614599/src/095-migrating-from-javascript/243-jsdoc-cannot-pass-types-to-functions.solution.ts
--------------------------------------------------------------------------------
/src/095-migrating-from-javascript/plan.md:
--------------------------------------------------------------------------------
1 | # Title
2 |
3 | Title here!
4 |
5 | ## Exercises
6 |
--------------------------------------------------------------------------------
/vite.config.mts:
--------------------------------------------------------------------------------
1 | import { defineConfig } from "vitest/config";
2 | import tsconfigPaths from "vite-tsconfig-paths";
3 |
4 | export default defineConfig({
5 | test: {
6 | include: ["src/**/*{problem,solution,explainer}*.{ts,tsx}"],
7 | passWithNoTests: true,
8 | environment: "jsdom",
9 | },
10 | plugins: [tsconfigPaths()],
11 | });
12 |
--------------------------------------------------------------------------------