├── .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 | --------------------------------------------------------------------------------