├── .github
└── workflows
│ ├── compile.sh
│ ├── lint.sh
│ └── validate-content.yml
├── .gitignore
├── LICENSE.MD
├── README-zh_CN.md
├── README.md
├── downloads
├── typescript-book-zh_CN.epub
├── typescript-book-zh_CN.pdf
├── typescript-book.epub
└── typescript-book.pdf
├── tools
├── .markdownlint.json
├── .nvmrc
├── .prettierrc
├── .vscode
│ ├── launch.json
│ └── settings.json
├── Makefile
├── README.md
├── compile.ts
├── config.ts
├── format.ts
├── i18n.ts
├── lint.ts
├── make-books.sh
├── make-website-content.py
├── package-lock.json
├── package.json
├── test-md
│ ├── README-zh_CN.md
│ └── README.md
├── tsconfig.json
└── utils.ts
├── website-astro
├── .gitignore
├── .prettierrc.json
├── astro.config.mjs
├── eslint.config.js
├── package.json
├── pnpm-lock.yaml
├── public
│ ├── android-chrome-192x192.png
│ ├── android-chrome-512x512.png
│ ├── apple-touch-icon.png
│ ├── favicon-16x16.png
│ ├── favicon-32x32.png
│ ├── favicon.ico
│ └── site.webmanifest
├── scripts
│ └── gen.ts
├── src
│ ├── components
│ │ └── head.astro
│ ├── content
│ │ ├── config.ts
│ │ └── docs
│ │ │ ├── books
│ │ │ ├── About the Author.md
│ │ │ ├── Any type.md
│ │ │ ├── Assignments.md
│ │ │ ├── Built-in Type Primitives.md
│ │ │ ├── Class.md
│ │ │ ├── Common Built-in JS Objects.md
│ │ │ ├── Conditional Types.md
│ │ │ ├── Control Flow Analysis.md
│ │ │ ├── Differences between Type and Interface.md
│ │ │ ├── Discriminated Unions.md
│ │ │ ├── Distributive Conditional Types.md
│ │ │ ├── Enums.md
│ │ │ ├── Erased Structural Types.md
│ │ │ ├── Exhaustiveness checking.md
│ │ │ ├── Exploring the Type System.md
│ │ │ ├── Extending Types.md
│ │ │ ├── Fixed Length Tuple.md
│ │ │ ├── Generics.md
│ │ │ ├── Getting Started With TypeScript.md
│ │ │ ├── Index Signatures.md
│ │ │ ├── Interface and Type.md
│ │ │ ├── Intersection Types.md
│ │ │ ├── Introduction.md
│ │ │ ├── Literal Inference.md
│ │ │ ├── Literal Types.md
│ │ │ ├── Mapped Type Modifiers.md
│ │ │ ├── Mapped Types.md
│ │ │ ├── Merging and Extension.md
│ │ │ ├── Named Tuple Type (Labeled).md
│ │ │ ├── Namespacing.md
│ │ │ ├── Narrowing.md
│ │ │ ├── Never type.md
│ │ │ ├── Object Types.md
│ │ │ ├── Optional Properties.md
│ │ │ ├── Others.md
│ │ │ ├── Overloads.md
│ │ │ ├── Predefined Conditional Types.md
│ │ │ ├── Primitive Types.md
│ │ │ ├── Readonly Properties.md
│ │ │ ├── Symbols.md
│ │ │ ├── Table of Contents.md
│ │ │ ├── Template Union Types.md
│ │ │ ├── The Concise TypeScript Book.md
│ │ │ ├── The never Type.md
│ │ │ ├── Triple-Slash Directives.md
│ │ │ ├── Tuple Type (Anonymous).md
│ │ │ ├── Type Annotations.md
│ │ │ ├── Type Indexing.md
│ │ │ ├── Type Manipulation.md
│ │ │ ├── Type Predicates.md
│ │ │ ├── Type from Func Return.md
│ │ │ ├── Type from Module.md
│ │ │ ├── Type from Value.md
│ │ │ ├── TypeScript Introduction.md
│ │ │ ├── Union Type.md
│ │ │ ├── Unknown type.md
│ │ │ ├── Void type.md
│ │ │ ├── infer Type Inference in Conditional Types.md
│ │ │ └── strictNullChecks.md
│ │ │ ├── index.md
│ │ │ └── zh-cn
│ │ │ ├── books
│ │ │ ├── About the Author.md
│ │ │ ├── Any type.md
│ │ │ ├── Assignments.md
│ │ │ ├── Built-in Type Primitives.md
│ │ │ ├── Class.md
│ │ │ ├── Common Built-in JS Objects.md
│ │ │ ├── Conditional Types.md
│ │ │ ├── Control Flow Analysis.md
│ │ │ ├── Differences between Type and Interface.md
│ │ │ ├── Discriminated Unions.md
│ │ │ ├── Distributive Conditional Types.md
│ │ │ ├── Enums.md
│ │ │ ├── Erased Structural Types.md
│ │ │ ├── Exhaustiveness checking.md
│ │ │ ├── Exploring the Type System.md
│ │ │ ├── Extending Types.md
│ │ │ ├── Fixed Length Tuple.md
│ │ │ ├── Generics.md
│ │ │ ├── Getting Started With TypeScript.md
│ │ │ ├── Index Signatures.md
│ │ │ ├── Interface and Type.md
│ │ │ ├── Intersection Types.md
│ │ │ ├── Introduction.md
│ │ │ ├── Literal Inference.md
│ │ │ ├── Literal Types.md
│ │ │ ├── Mapped Type Modifiers.md
│ │ │ ├── Mapped Types.md
│ │ │ ├── Merging and Extension.md
│ │ │ ├── Named Tuple Type (Labeled).md
│ │ │ ├── Namespacing.md
│ │ │ ├── Narrowing.md
│ │ │ ├── Never type.md
│ │ │ ├── Object Types.md
│ │ │ ├── Optional Properties.md
│ │ │ ├── Others.md
│ │ │ ├── Overloads.md
│ │ │ ├── Predefined Conditional Types.md
│ │ │ ├── Primitive Types.md
│ │ │ ├── Readonly Properties.md
│ │ │ ├── Symbols.md
│ │ │ ├── Table of Contents.md
│ │ │ ├── Template Union Types.md
│ │ │ ├── The Concise TypeScript Book.md
│ │ │ ├── The never Type.md
│ │ │ ├── Triple-Slash Directives.md
│ │ │ ├── Tuple Type (Anonymous).md
│ │ │ ├── Type Annotations.md
│ │ │ ├── Type Indexing.md
│ │ │ ├── Type Manipulation.md
│ │ │ ├── Type Predicates.md
│ │ │ ├── Type from Func Return.md
│ │ │ ├── Type from Module.md
│ │ │ ├── Type from Value.md
│ │ │ ├── TypeScript Introduction.md
│ │ │ ├── Union Type.md
│ │ │ ├── Unknown type.md
│ │ │ ├── Void type.md
│ │ │ ├── infer Type Inference in Conditional Types.md
│ │ │ └── strictNullChecks.md
│ │ │ └── index.md
│ ├── env.d.ts
│ └── styles
│ │ └── global.css
├── tailwind.config.ts
└── tsconfig.json
└── website
├── .gitignore
├── .nvmrc
├── .prettierrc
├── .vscode
├── extensions.json
└── launch.json
├── README.md
├── astro.config.mjs
├── package-lock.json
├── package.json
├── public
└── favicon.svg
├── src
├── assets
│ └── houston.webp
├── content
│ ├── config.ts
│ ├── docs
│ │ ├── book
│ │ │ ├── about-the-author.md
│ │ │ ├── any-type.md
│ │ │ ├── assignments.md
│ │ │ ├── built-in-type-primitives.md
│ │ │ ├── class.md
│ │ │ ├── common-built-in-js-objects.md
│ │ │ ├── conditional-types.md
│ │ │ ├── control-flow-analysis.md
│ │ │ ├── differences-between-type-and-interface.md
│ │ │ ├── discriminated-unions.md
│ │ │ ├── distributive-conditional-types.md
│ │ │ ├── downloads-and-website.md
│ │ │ ├── enums.md
│ │ │ ├── erased-structural-types.md
│ │ │ ├── exhaustiveness-checking.md
│ │ │ ├── exploring-the-type-system.md
│ │ │ ├── extending-types.md
│ │ │ ├── fixed-length-tuple.md
│ │ │ ├── generics.md
│ │ │ ├── getting-started-with-typescript.md
│ │ │ ├── index-signatures.md
│ │ │ ├── infer-type-inference-in-conditional-types.md
│ │ │ ├── interface-and-type.md
│ │ │ ├── intersection-types.md
│ │ │ ├── introduction.md
│ │ │ ├── literal-inference.md
│ │ │ ├── literal-types.md
│ │ │ ├── mapped-type-modifiers.md
│ │ │ ├── mapped-types.md
│ │ │ ├── merging-and-extension.md
│ │ │ ├── named-tuple-type-labeled.md
│ │ │ ├── namespacing.md
│ │ │ ├── narrowing.md
│ │ │ ├── never-type.md
│ │ │ ├── object-types.md
│ │ │ ├── optional-properties.md
│ │ │ ├── others.md
│ │ │ ├── overloads.md
│ │ │ ├── predefined-conditional-types.md
│ │ │ ├── primitive-types.md
│ │ │ ├── readonly-properties.md
│ │ │ ├── strictnullchecks.md
│ │ │ ├── symbols.md
│ │ │ ├── table-of-contents.md
│ │ │ ├── template-union-types.md
│ │ │ ├── the-concise-typescript-book.md
│ │ │ ├── the-never-type.md
│ │ │ ├── translations.md
│ │ │ ├── triple-slash-directives.md
│ │ │ ├── tuple-type-anonymous.md
│ │ │ ├── type-annotations.md
│ │ │ ├── type-from-func-return.md
│ │ │ ├── type-from-module.md
│ │ │ ├── type-from-value.md
│ │ │ ├── type-indexing.md
│ │ │ ├── type-manipulation.md
│ │ │ ├── type-predicates.md
│ │ │ ├── typescript-introduction.md
│ │ │ ├── union-type.md
│ │ │ ├── unknown-type.md
│ │ │ └── void-type.md
│ │ ├── index.mdx
│ │ └── zh-cn
│ │ │ ├── book
│ │ │ ├── about-the-author.md
│ │ │ ├── any-type.md
│ │ │ ├── assignments.md
│ │ │ ├── built-in-type-primitives.md
│ │ │ ├── class.md
│ │ │ ├── common-built-in-js-objects.md
│ │ │ ├── conditional-types.md
│ │ │ ├── control-flow-analysis.md
│ │ │ ├── differences-between-type-and-interface.md
│ │ │ ├── discriminated-unions.md
│ │ │ ├── distributive-conditional-types.md
│ │ │ ├── downloads-and-website.md
│ │ │ ├── enums.md
│ │ │ ├── erased-structural-types.md
│ │ │ ├── exhaustiveness-checking.md
│ │ │ ├── exploring-the-type-system.md
│ │ │ ├── extending-types.md
│ │ │ ├── fixed-length-tuple.md
│ │ │ ├── generics.md
│ │ │ ├── getting-started-with-typescript.md
│ │ │ ├── index-signatures.md
│ │ │ ├── infer-type-inference-in-conditional-types.md
│ │ │ ├── interface-and-type.md
│ │ │ ├── intersection-types.md
│ │ │ ├── introduction.md
│ │ │ ├── literal-inference.md
│ │ │ ├── literal-types.md
│ │ │ ├── mapped-type-modifiers.md
│ │ │ ├── mapped-types.md
│ │ │ ├── merging-and-extension.md
│ │ │ ├── named-tuple-type-labeled.md
│ │ │ ├── namespacing.md
│ │ │ ├── narrowing.md
│ │ │ ├── never-type.md
│ │ │ ├── object-types.md
│ │ │ ├── optional-properties.md
│ │ │ ├── others.md
│ │ │ ├── overloads.md
│ │ │ ├── predefined-conditional-types.md
│ │ │ ├── primitive-types.md
│ │ │ ├── readonly-properties.md
│ │ │ ├── strictnullchecks.md
│ │ │ ├── symbols.md
│ │ │ ├── table-of-contents.md
│ │ │ ├── template-union-types.md
│ │ │ ├── the-concise-typescript-book.md
│ │ │ ├── the-never-type.md
│ │ │ ├── translations.md
│ │ │ ├── triple-slash-directives.md
│ │ │ ├── tuple-type-anonymous.md
│ │ │ ├── type-annotations.md
│ │ │ ├── type-from-func-return.md
│ │ │ ├── type-from-module.md
│ │ │ ├── type-from-value.md
│ │ │ ├── type-indexing.md
│ │ │ ├── type-manipulation.md
│ │ │ ├── type-predicates.md
│ │ │ ├── typescript-introduction.md
│ │ │ ├── union-type.md
│ │ │ ├── unknown-type.md
│ │ │ └── void-type.md
│ │ │ └── index.mdx
│ └── i18n
│ │ └── zh-cn.json
├── env.d.ts
└── styles
│ └── custom.css
└── tsconfig.json
/.github/workflows/compile.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | set -e
3 | echo "Compiling all code snippets ..."
4 | cd tools
5 | npm ci
6 | npm run compile
--------------------------------------------------------------------------------
/.github/workflows/lint.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | set -e
3 | echo "Linting Markdown and Code files ..."
4 | cd tools
5 | npm ci
6 | npm run lint
7 | npm run lint:md
--------------------------------------------------------------------------------
/.github/workflows/validate-content.yml:
--------------------------------------------------------------------------------
1 | name: validate-content
2 | run-name: ${{ github.actor }} validate content
3 | on: [pull_request]
4 | jobs:
5 | lint-content:
6 | runs-on: ubuntu-latest
7 | steps:
8 | - uses: actions/checkout@v3
9 | - name: Run lint script
10 | run: bash ${GITHUB_WORKSPACE}/.github/workflows/lint.sh
11 | compile-snippets:
12 | runs-on: ubuntu-latest
13 | steps:
14 | - uses: actions/checkout@v3
15 | - name: Run compile script
16 | run: bash ${GITHUB_WORKSPACE}/.github/workflows/compile.sh
17 |
18 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | temp
3 | !.vscode
4 |
--------------------------------------------------------------------------------
/LICENSE.MD:
--------------------------------------------------------------------------------
1 | # Licence
2 |
3 | The Concise TypeScript Book © by Simone Poggiali is licensed under Attribution 4.0 International.
4 |
5 | For more information visit:
6 |
7 |
--------------------------------------------------------------------------------
/downloads/typescript-book-zh_CN.epub:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nnecec/typescript-book/f042af63e3471f5dc7e8f1450f87e0f57398f5e9/downloads/typescript-book-zh_CN.epub
--------------------------------------------------------------------------------
/downloads/typescript-book-zh_CN.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nnecec/typescript-book/f042af63e3471f5dc7e8f1450f87e0f57398f5e9/downloads/typescript-book-zh_CN.pdf
--------------------------------------------------------------------------------
/downloads/typescript-book.epub:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nnecec/typescript-book/f042af63e3471f5dc7e8f1450f87e0f57398f5e9/downloads/typescript-book.epub
--------------------------------------------------------------------------------
/downloads/typescript-book.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nnecec/typescript-book/f042af63e3471f5dc7e8f1450f87e0f57398f5e9/downloads/typescript-book.pdf
--------------------------------------------------------------------------------
/tools/.markdownlint.json:
--------------------------------------------------------------------------------
1 | {
2 | "code-block-style": {
3 | "style": "fenced"
4 | },
5 | "code-fence-style": {
6 | "style": "backtick"
7 | },
8 | "emphasis-style": {
9 | "style": "asterisk"
10 | },
11 | "fenced-code-language": {
12 | "allowed_languages": [
13 | "shell",
14 | "json",
15 | "typescript",
16 | "javascript",
17 | "text"
18 | ],
19 | "language_only": true
20 | },
21 | "heading-style": {
22 | "style": "atx"
23 | },
24 | "hr-style": {
25 | "style": "---"
26 | },
27 | "line-length": false,
28 | "no-duplicate-heading": {
29 | "siblings_only": true
30 | },
31 | "ol-prefix": {
32 | "style": "ordered"
33 | },
34 | "proper-names": {
35 | "code_blocks": false,
36 | "names": [
37 | "TypeScript",
38 | "Ctrl",
39 | "JavaScript",
40 | "Markdown",
41 | "Node.js",
42 | "Visual Studio Code",
43 | "Microsoft",
44 | "LinkedIn",
45 | "GitHub",
46 | "Twitter",
47 | "Email",
48 | "IntelliSense",
49 | "ECMAScript"
50 | ]
51 | },
52 | "required-headings": false,
53 | "strong-style": {
54 | "style": "asterisk"
55 | },
56 | "ul-style": {
57 | "style": "asterisk"
58 | }
59 | }
--------------------------------------------------------------------------------
/tools/.nvmrc:
--------------------------------------------------------------------------------
1 | v19.7.0
2 |
--------------------------------------------------------------------------------
/tools/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "trailingComma": "es5",
3 | "tabWidth": 4,
4 | "semi": true,
5 | "singleQuote": true,
6 | "printWidth": 80,
7 | "arrowParens": "avoid"
8 | }
--------------------------------------------------------------------------------
/tools/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "0.2.0",
3 | "configurations": [
4 | {
5 | "name": "Debug lint",
6 | "type": "node",
7 | "request": "launch",
8 | "runtimeExecutable": "node",
9 | "runtimeArgs": [
10 | "--nolazy",
11 | "-r",
12 | "${workspaceRoot}/node_modules/ts-node/register/transpile-only"
13 | ],
14 | "args": [
15 | "lint.ts",
16 | "--example",
17 | "hello"
18 | ],
19 | "cwd": "${workspaceRoot}",
20 | "internalConsoleOptions": "openOnSessionStart",
21 | "skipFiles": [
22 | "/**",
23 | "node_modules/**"
24 | ]
25 | },
26 | {
27 | "name": "Python: Current File",
28 | "type": "python",
29 | "request": "launch",
30 | "program": "${file}",
31 | "console": "integratedTerminal",
32 | "justMyCode": true
33 | }
34 | ]
35 | }
--------------------------------------------------------------------------------
/tools/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "editor.formatOnSave": true,
3 | }
--------------------------------------------------------------------------------
/tools/Makefile:
--------------------------------------------------------------------------------
1 | format:
2 | npm run format
3 |
4 | check:
5 | npm run check
6 |
7 | website:
8 | python3 ./make-website-content.py
9 |
10 | website-deploy:
11 | cd ../website && npm run deploy
12 |
13 | website-preview:
14 | cd ../website && npm run build && npm run preview
15 |
16 | books:
17 | ./make-books.sh
--------------------------------------------------------------------------------
/tools/config.ts:
--------------------------------------------------------------------------------
1 | export const PRETTIER_CONFIG_FILE_PATH = './.prettierrc'
2 |
3 | export const CODE_BLOCK_TS_REGEX = /```typescript([\s\S]*?)```/g;
--------------------------------------------------------------------------------
/tools/format.ts:
--------------------------------------------------------------------------------
1 | import * as prettier from 'prettier';
2 | import * as fs from 'fs';
3 | import { Language, languages } from './i18n';
4 | import { PrettierOptions, getPrettierOptions, makeFilePath } from './utils';
5 | import { CODE_BLOCK_TS_REGEX } from './config';
6 |
7 | const formatCodeBlocksInMarkdownFile = async (filePath: string, options: PrettierOptions, language: Language): Promise => {
8 | const markdown = await fs.promises.readFile(filePath, 'utf-8');
9 |
10 | let formattedMarkdown = markdown;
11 | let match;
12 | while ((match = CODE_BLOCK_TS_REGEX.exec(markdown)) !== null) {
13 | const codeBlock = match[0];
14 | const code = match[1].trim();
15 | const formattedCode = await prettier.format(code, {
16 | parser: 'typescript',
17 | ...options,
18 | });
19 | formattedMarkdown = formattedMarkdown.replace(codeBlock, `\`\`\`typescript\n${formattedCode}\`\`\``);
20 | }
21 |
22 | await fs.promises.writeFile(filePath, formattedMarkdown, 'utf-8');
23 | console.log(`${language} Formatted code blocks have been updated in the file: ${filePath}`);
24 | }
25 |
26 | const main = async () => {
27 | const options = await getPrettierOptions()
28 |
29 | for (const language of languages) {
30 | formatCodeBlocksInMarkdownFile(makeFilePath(language), options, language);
31 | }
32 | }
33 |
34 | main()
35 |
36 |
37 |
--------------------------------------------------------------------------------
/tools/i18n.ts:
--------------------------------------------------------------------------------
1 | export enum Language {
2 | en_EN = 'en_EN',
3 | zh_CN = 'zh_CN',
4 | }
5 | export type Languages = [Language.en_EN, Language.zh_CN]
6 |
7 | export const languages: Languages = [Language.en_EN, Language.zh_CN]
--------------------------------------------------------------------------------
/tools/lint.ts:
--------------------------------------------------------------------------------
1 | import * as prettier from 'prettier';
2 | import * as fs from 'fs';
3 | import { Language, languages } from './i18n';
4 | import { PrettierOptions, getPrettierOptions, makeFilePath } from './utils';
5 | import { CODE_BLOCK_TS_REGEX } from './config';
6 |
7 | const lintCodeBlocksInMarkdownFile = async (filePath: string, options: PrettierOptions, language: Language): Promise => {
8 | const markdown = await fs.promises.readFile(filePath, 'utf-8');
9 |
10 | let reportSnippetsNotLinted = '';
11 | let match;
12 | while ((match = CODE_BLOCK_TS_REGEX.exec(markdown)) !== null) {
13 | const code = match[1].trim() + '\n'
14 | const isCodeLinted = await prettier.check(code, {
15 | parser: 'typescript',
16 | ...options,
17 | });
18 | if (isCodeLinted === false) {
19 | reportSnippetsNotLinted += code
20 | reportSnippetsNotLinted += '\n'
21 | }
22 | }
23 | if (reportSnippetsNotLinted.length === 0) {
24 | console.log(`${language} All snippets are linted!`)
25 | } else {
26 | console.error(`${language} Not all snippets are linted! Please use this command to automatically format the snippets: npm run format\n`)
27 | console.error(reportSnippetsNotLinted)
28 | process.exit(1)
29 | }
30 | }
31 |
32 | const main = async () => {
33 | const options = await getPrettierOptions()
34 |
35 | for (const language of languages) {
36 | lintCodeBlocksInMarkdownFile(makeFilePath(language), options, language);
37 | }
38 | }
39 |
40 | main()
41 |
42 |
43 |
--------------------------------------------------------------------------------
/tools/make-books.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | DIR_DOWNLOADS="downloads"
3 |
4 | INPUT_EN="README"
5 | INPUT_CN="README-zh_CN"
6 |
7 | OUTPUT_EN="typescript-book"
8 | OUTPUT_CN="typescript-book-zh_CN"
9 |
10 | AUTHOR="Simone Poggiali"
11 | TITLE_EN="The Concise TypeScript Book"
12 | TITLE_CN="# 简洁的TypeScript之书"
13 |
14 | cd ../
15 |
16 | echo "Making ebooks ..."
17 |
18 | # Check dependencies
19 | if command -v pandoc &>/dev/null; then
20 | echo "pandoc is installed"
21 | else
22 | echo "You need to install pandoc. Please visit: https://pandoc.org/installing.html"
23 | exit 1
24 | fi
25 | if command -v epubcheck &>/dev/null; then
26 | echo "epubcheck is installed"
27 | else
28 | echo "You need to install epubcheck. Please visit: https://www.w3.org/publishing/epubcheck/docs/installation/"
29 | exit 1
30 | fi
31 | if command -v ebook-convert &>/dev/null; then
32 | echo "calibre is installed"
33 | else
34 | echo "You need to install calibre. Please visit: https://calibre-ebook.com/download"
35 | exit 1
36 | fi
37 |
38 | # Generate eBooks
39 | pandoc -o $DIR_DOWNLOADS/$OUTPUT_EN.epub --metadata title="$TITLE_EN" --metadata author="$AUTHOR" -s $INPUT_EN.md
40 | pandoc -o $DIR_DOWNLOADS/$OUTPUT_CN.epub --metadata title="$TITLE_CN" --metadata author="$AUTHOR" -s $INPUT_CN.md
41 |
42 | # Validate eBooks
43 | epubcheck $DIR_DOWNLOADS/$OUTPUT_CN.epub
44 | epubcheck $DIR_DOWNLOADS/$OUTPUT_CN.epub
45 |
46 | # Generate PDFs
47 | ebook-convert $DIR_DOWNLOADS/$OUTPUT_EN.epub $DIR_DOWNLOADS/$OUTPUT_EN.pdf --pdf-page-numbers
48 | ebook-convert $DIR_DOWNLOADS/$OUTPUT_CN.epub $DIR_DOWNLOADS/$OUTPUT_CN.pdf --pdf-page-numbers
49 |
50 | echo "Books were created. Please commit!"
--------------------------------------------------------------------------------
/tools/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "typescript-book",
3 | "version": "1.0.0",
4 | "description": "The Concise TypeScript Book provides a comprehensive and succinct overview of TypeScript's capabilities. It offers clear explanations covering all aspects found in the latest version of the language, from its powerful type system to advanced features. Whether you're a beginner or an experienced developer, this book is an invaluable resource to enhance your understanding and proficiency in TypeScript.",
5 | "main": "index.js",
6 | "scripts": {
7 | "format": "ts-node format",
8 | "compile": "ts-node compile",
9 | "test": "echo \"Error: no test specified\" && exit 1",
10 | "lint": "ts-node lint",
11 | "lint:md": "markdownlint \"./*.md\" markdownlint \"../*.md\"",
12 | "check": "npm run lint:md && npm run format && npm run compile"
13 | },
14 | "author": "",
15 | "license": "ISC",
16 | "devDependencies": {
17 | "@types/fs-extra": "^11.0.1",
18 | "@types/marked": "^5.0.0",
19 | "@types/node": "^20.3.1",
20 | "@types/prettier": "^2.7.3",
21 | "fp-ts": "^2.16.0",
22 | "fs-extra": "^11.1.1",
23 | "markdownlint-cli": "^0.35.0",
24 | "marked": "^5.1.0",
25 | "prettier": "^3.3.0",
26 | "ts-node": "^10.9.1",
27 | "typescript": "^5.4.5"
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/tools/test-md/README-zh_CN.md:
--------------------------------------------------------------------------------
1 | # 简洁 TypeScript 书
2 | TypeScript 有效开发简明指南。 **免费和开源**。
3 | ## 创建文件和文件夹
4 | 可使用 按钮访问文件资源管理器。
5 | ## 切换到另一个文件
6 | 您的所有文件和文件夹都在文件资源管理器中显示为树。 您可以通过单击树中的文件从一个文件切换到另一个文件。
7 | ### 新标题
8 | 一些家长内容。
9 | #### 嵌套内容 1
10 | 更多内容在这里。
11 | ##### 嵌套内容 2
12 | 内容甚至更多。
--------------------------------------------------------------------------------
/tools/test-md/README.md:
--------------------------------------------------------------------------------
1 | # The Concise TypeScript Book
2 | A Concise Guide to Effective Development in TypeScript. **Free and Open Source**.
3 | ## Create files and folders
4 | The file explorer is accessible using the button.
5 | ## Switch to another file
6 | All your files and folders are presented as a tree in the file explorer. You can switch from one to another by clicking a file in the tree.
7 | ### New title
8 | Some parent content.
9 | #### Nested content 1
10 | More content here.
11 | ##### Nested content 2
12 | Even more content.
--------------------------------------------------------------------------------
/tools/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es2022",
4 | "module": "commonjs",
5 | "noImplicitAny": true,
6 | "esModuleInterop": true,
7 | "noEmitOnError": true,
8 | "moduleDetection": "force",
9 | "noUnusedLocals": false,
10 | "forceConsistentCasingInFileNames": true,
11 | "strict": true,
12 | "skipLibCheck": true,
13 | "lib": [
14 | "es2022",
15 | "esnext.disposable",
16 | "esnext.decorators",
17 | "dom"
18 | ]
19 | }
20 | }
--------------------------------------------------------------------------------
/tools/utils.ts:
--------------------------------------------------------------------------------
1 | import { PRETTIER_CONFIG_FILE_PATH } from "./config";
2 | import { Language } from "./i18n";
3 | import * as prettier from 'prettier';
4 |
5 | export const makeFilePath = (item: Language) =>
6 | item === Language.en_EN ? '../README.md' : `../README-${item}.md`
7 |
8 | export type PrettierOptions = Exclude
9 |
10 | export const getPrettierOptions = async (): Promise => {
11 | const options = await prettier.resolveConfig(PRETTIER_CONFIG_FILE_PATH)
12 | if (options === null) {
13 | throw `No Prettier options are found! Check your Prettier configuration file.`
14 | }
15 | return options
16 | }
--------------------------------------------------------------------------------
/website-astro/.gitignore:
--------------------------------------------------------------------------------
1 | # build output
2 | dist/
3 | # generated types
4 | .astro/
5 |
6 | # dependencies
7 | node_modules/
8 |
9 | # logs
10 | npm-debug.log*
11 | yarn-debug.log*
12 | yarn-error.log*
13 | pnpm-debug.log*
14 |
15 |
16 | # environment variables
17 | .env
18 | .env.production
19 |
20 | # macOS-specific files
21 | .DS_Store
22 |
--------------------------------------------------------------------------------
/website-astro/.prettierrc.json:
--------------------------------------------------------------------------------
1 | "@nnecec/prettier-config"
2 |
--------------------------------------------------------------------------------
/website-astro/eslint.config.js:
--------------------------------------------------------------------------------
1 | import nnecec from '@nnecec/eslint-config'
2 |
3 | /** @type {import('eslint').Linter.FlatConfig[]} */
4 | export default [
5 | ...nnecec({
6 | tailwindcss: true,
7 | typescript: true,
8 | }),
9 | {
10 | files: ['**/*.ts', '**/*.tsx'],
11 | rules: {
12 | '@typescript-eslint/no-explicit-any': 'off',
13 | },
14 | },
15 | ]
16 |
--------------------------------------------------------------------------------
/website-astro/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "website",
3 | "version": "0.0.0",
4 | "private": true,
5 | "type": "module",
6 | "scripts": {
7 | "astro": "astro",
8 | "build": "astro check && astro build",
9 | "dev": "astro dev",
10 | "gen": "tsx scripts/gen.ts",
11 | "preview": "astro preview",
12 | "start": "astro dev"
13 | },
14 | "dependencies": {
15 | "@astrojs/check": "^0.9.4",
16 | "@astrojs/partytown": "^2.1.2",
17 | "@astrojs/starlight": "^0.28.6",
18 | "@astrojs/starlight-tailwind": "^2.0.3",
19 | "@astrojs/tailwind": "^5.1.2",
20 | "astro": "^4.16.10",
21 | "react": "^18.3.1",
22 | "react-dom": "^18.3.1",
23 | "remark": "^15.0.1",
24 | "remark-frontmatter": "^5.0.0",
25 | "sharp": "^0.33.5",
26 | "tailwindcss": "^3.4.14",
27 | "typescript": "^5.6.3",
28 | "unist-util-visit": "^5.0.0"
29 | },
30 | "devDependencies": {
31 | "@nnecec/eslint-config": "^0.11.0",
32 | "@nnecec/prettier-config": "^0.4.3",
33 | "tsx": "^4.19.2"
34 | },
35 | "packageManager": "pnpm@9.12.3+sha512.cce0f9de9c5a7c95bef944169cc5dfe8741abfb145078c0d508b868056848a87c81e626246cb60967cbd7fd29a6c062ef73ff840d96b3c86c40ac92cf4a813ee"
36 | }
37 |
--------------------------------------------------------------------------------
/website-astro/public/android-chrome-192x192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nnecec/typescript-book/f042af63e3471f5dc7e8f1450f87e0f57398f5e9/website-astro/public/android-chrome-192x192.png
--------------------------------------------------------------------------------
/website-astro/public/android-chrome-512x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nnecec/typescript-book/f042af63e3471f5dc7e8f1450f87e0f57398f5e9/website-astro/public/android-chrome-512x512.png
--------------------------------------------------------------------------------
/website-astro/public/apple-touch-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nnecec/typescript-book/f042af63e3471f5dc7e8f1450f87e0f57398f5e9/website-astro/public/apple-touch-icon.png
--------------------------------------------------------------------------------
/website-astro/public/favicon-16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nnecec/typescript-book/f042af63e3471f5dc7e8f1450f87e0f57398f5e9/website-astro/public/favicon-16x16.png
--------------------------------------------------------------------------------
/website-astro/public/favicon-32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nnecec/typescript-book/f042af63e3471f5dc7e8f1450f87e0f57398f5e9/website-astro/public/favicon-32x32.png
--------------------------------------------------------------------------------
/website-astro/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nnecec/typescript-book/f042af63e3471f5dc7e8f1450f87e0f57398f5e9/website-astro/public/favicon.ico
--------------------------------------------------------------------------------
/website-astro/public/site.webmanifest:
--------------------------------------------------------------------------------
1 | {"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"}
--------------------------------------------------------------------------------
/website-astro/src/components/head.astro:
--------------------------------------------------------------------------------
1 | ---
2 | import type { Props } from '@astrojs/starlight/props'
3 | import Default from '@astrojs/starlight/components/Head.astro'
4 |
5 | const gaId = import.meta.env.PUBLIC_GA_ID
6 | ---
7 |
8 |
10 |
18 |
19 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/website-astro/src/content/config.ts:
--------------------------------------------------------------------------------
1 | import { docsSchema, i18nSchema } from '@astrojs/starlight/schema'
2 | import { defineCollection } from 'astro:content'
3 |
4 | export const collections = {
5 | docs: defineCollection({ schema: docsSchema() }),
6 | i18n: defineCollection({ schema: i18nSchema(), type: 'data' }),
7 | }
8 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/books/About the Author.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: About the Author
3 | sidebar:
4 | order: 4
5 | label: 4. About the Author
6 | ---
7 |
8 | Simone Poggiali is an experienced Senior Front-end Developer with a passion for writing professional-grade code since the 90s. Throughout his international career, he has contributed to numerous projects for a wide range of clients, from startups to large organizations. Notable companies such as HelloFresh, Siemens, O2, and Leroy Merlin have benefited from his expertise and dedication.
9 |
10 | You can reach Simone Poggiali on the following platforms:
11 |
12 | * LinkedIn:
13 | * GitHub:
14 | * X.com:
15 | * Email: gibbok.coding📧gmail.com
16 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/books/Any type.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Any type
3 | sidebar:
4 | order: 42
5 | label: 42. Any type
6 | ---
7 |
8 | The `any` type is a special type (universal supertype) that can be used to represent any type of value (primitives, objects, arrays, functions, errors, symbols). It is often used in situations where the type of a value is not known at compile time, or when working with values from external APIs or libraries that do not have TypeScript typings.
9 |
10 | By utilizing `any` type, you are indicating to the TypeScript compiler that values should be represented without any limitations. In order to maximizing type safety in your code consider the following:
11 |
12 | * Limit the usage of `any` to specific cases where the type is truly unknown.
13 | * Do not return `any` types from a function as you will lose type safety in the code using that function weakening your type safety.
14 | * Instead of `any` use `@ts-ignore` if you need to silence the compiler.
15 |
16 | ```typescript
17 | let value: any;
18 | value = true; // Valid
19 | value = 7; // Valid
20 | ```
21 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/books/Assignments.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Assignments
3 | sidebar:
4 | order: 19
5 | label: 19. Assignments
6 | ---
7 |
8 | TypeScript narrowing using assignments is a way to narrow the type of a variable based on the value assigned to it. When a variable is assigned a value, TypeScript infers its type based on the assigned value, and it narrows the type of the variable to match the inferred type.
9 |
10 | ```typescript
11 | let value: string | number;
12 | value = 'hello';
13 | if (typeof value === 'string') {
14 | console.log(value.toUpperCase());
15 | }
16 | value = 42;
17 | if (typeof value === 'number') {
18 | console.log(value.toFixed(2));
19 | }
20 | ```
21 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/books/Built-in Type Primitives.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Built-in Type Primitives
3 | sidebar:
4 | order: 47
5 | label: 47. Built-in Type Primitives
6 | ---
7 |
8 | TypeScript has several built-in type primitives that can be used to define variables, function parameters, and return types:
9 |
10 | * `number`: Represents numeric values, including integers and floating-point numbers.
11 | * `string`: Represents textual data
12 | * `boolean`: Represents logical values, which can be either true or false.
13 | * `null`: Represents the absence of a value.
14 | * `undefined`: Represents a value that has not been assigned or has not been defined.
15 | * `symbol`: Represents a unique identifier. Symbols are typically used as keys for object properties.
16 | * `bigint`: Represents arbitrary-precision integers.
17 | * `any`: Represents a dynamic or unknown type. Variables of type any can hold values of any type, and they bypass type checking.
18 | * `void`: Represents the absence of any type. It is commonly used as the return type of functions that do not return a value.
19 | * `never`: Represents a type for values that never occur. It is typically used as the return type of functions that throw an error or enter an infinite loop.
20 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/books/Common Built-in JS Objects.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Common Built-in JS Objects
3 | sidebar:
4 | order: 48
5 | label: 48. Common Built-in JS Objects
6 | ---
7 |
8 | TypeScript is a superset of JavaScript, it includes all the commonly used built-in JavaScript objects. You can find an extensive list of these objects on the Mozilla Developer Network (MDN) documentation website:
9 |
10 |
11 | Here is a list of some commonly used built-in JavaScript objects:
12 |
13 | * Function
14 | * Object
15 | * Boolean
16 | * Error
17 | * Number
18 | * BigInt
19 | * Math
20 | * Date
21 | * String
22 | * RegExp
23 | * Array
24 | * Map
25 | * Set
26 | * Promise
27 | * Intl
28 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/books/Conditional Types.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Conditional Types
3 | sidebar:
4 | order: 37
5 | label: 37. Conditional Types
6 | ---
7 |
8 | Conditional Types are a way to create a type that depends on a condition, where the type to be created is determined based on the result of the condition. They are defined using the `extends` keyword and a ternary operator to conditionally choose between two types.
9 |
10 | ```typescript
11 | type IsArray = T extends any[] ? true : false;
12 |
13 | const myArray = [1, 2, 3];
14 | const myNumber = 42;
15 |
16 | type IsMyArrayAnArray = IsArray; // Type true
17 | type IsMyNumberAnArray = IsArray; // Type false
18 | ```
19 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/books/Control Flow Analysis.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Control Flow Analysis
3 | sidebar:
4 | order: 20
5 | label: 20. Control Flow Analysis
6 | ---
7 |
8 | Control Flow Analysis in TypeScript is a way to statically analyze the code flow to infer the types of variables, allowing the compiler to narrow the types of those variables as needed, based on the results of the analysis.
9 |
10 | Prior to TypeScript 4.4, code flow analysis would only be applied to code within an if statement, but from TypeScript 4.4, it can also be applied to conditional expressions and discriminant property accesses indirectly referenced through const variables.
11 |
12 | For example:
13 |
14 | ```typescript
15 | const f1 = (x: unknown) => {
16 | const isString = typeof x === 'string';
17 | if (isString) {
18 | x.length;
19 | }
20 | };
21 |
22 | const f2 = (
23 | obj: { kind: 'foo'; foo: string } | { kind: 'bar'; bar: number }
24 | ) => {
25 | const isFoo = obj.kind === 'foo';
26 | if (isFoo) {
27 | obj.foo;
28 | } else {
29 | obj.bar;
30 | }
31 | };
32 | ```
33 |
34 | Some examples where narrowing does not occur:
35 |
36 |
37 |
38 | ```typescript
39 | const f1 = (x: unknown) => {
40 | let isString = typeof x === 'string';
41 | if (isString) {
42 | x.length; // Error, no narrowing because isString it is not const
43 | }
44 | };
45 |
46 | const f6 = (
47 | obj: { kind: 'foo'; foo: string } | { kind: 'bar'; bar: number }
48 | ) => {
49 | const isFoo = obj.kind === 'foo';
50 | obj = obj;
51 | if (isFoo) {
52 | obj.foo; // Error, no narrowing because obj is assigned in function body
53 | }
54 | };
55 | ```
56 |
57 | Notes: Up to five levels of indirection are analyzed in conditional expressions.
58 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/books/Differences between Type and Interface.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Differences between Type and Interface
3 | sidebar:
4 | order: 51
5 | label: 51. Differences between Type and Interface
6 | ---
7 |
8 | Declaration merging (augmentation):
9 |
10 | Interfaces support declaration merging, which means that you can define multiple interfaces with the same name, and TypeScript will merge them into a single interface with the combined properties and methods. On the other hand, types do not support declaration merging. This can be helpful when you want to add extra functionality or customize existing types without modifying the original definitions or patching missing or incorrect types.
11 |
12 | ```typescript
13 | interface A {
14 | x: string;
15 | }
16 | interface A {
17 | y: string;
18 | }
19 | const j: A = {
20 | x: 'xx',
21 | y: 'yy',
22 | };
23 | ```
24 |
25 | Extending other types/interfaces:
26 |
27 | Both types and interfaces can extend other types/interfaces, but the syntax is different. With interfaces, you use the `extends` keyword to inherit properties and methods from other interfaces. However, an interface cannot extend a complex type like a union type.
28 |
29 | ```typescript
30 | interface A {
31 | x: string;
32 | y: number;
33 | }
34 | interface B extends A {
35 | z: string;
36 | }
37 | const car: B = {
38 | x: 'x',
39 | y: 123,
40 | z: 'z',
41 | };
42 | ```
43 |
44 | For types, you use the & operator to combine multiple types into a single type (intersection).
45 |
46 | ```typescript
47 | interface A {
48 | x: string;
49 | y: number;
50 | }
51 |
52 | type B = A & {
53 | j: string;
54 | };
55 |
56 | const c: B = {
57 | x: 'x',
58 | y: 123,
59 | j: 'j',
60 | };
61 | ```
62 |
63 | Union and Intersection Types:
64 |
65 | Types are more flexible when it comes to defining Union and Intersection Types. With the `type` keyword, you can easily create union types using the `|` operator and intersection types using the `&` operator. While interfaces can also represent union types indirectly, they don't have built-in support for intersection types.
66 |
67 | ```typescript
68 | type Department = 'dep-x' | 'dep-y'; // Union
69 |
70 | type Person = {
71 | name: string;
72 | age: number;
73 | };
74 |
75 | type Employee = {
76 | id: number;
77 | department: Department;
78 | };
79 |
80 | type EmployeeInfo = Person & Employee; // Intersection
81 | ```
82 |
83 | Example with interfaces:
84 |
85 | ```typescript
86 | interface A {
87 | x: 'x';
88 | }
89 | interface B {
90 | y: 'y';
91 | }
92 |
93 | type C = A | B; // Union of interfaces
94 | ```
95 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/books/Discriminated Unions.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Discriminated Unions
3 | sidebar:
4 | order: 22
5 | label: 22. Discriminated Unions
6 | ---
7 |
8 | Discriminated Unions in TypeScript are a type of union type that uses a common property, known as the discriminant, to narrow down the set of possible types for the union.
9 |
10 | ```typescript
11 | type Square = {
12 | kind: 'square'; // Discriminant
13 | size: number;
14 | };
15 |
16 | type Circle = {
17 | kind: 'circle'; // Discriminant
18 | radius: number;
19 | };
20 |
21 | type Shape = Square | Circle;
22 |
23 | const area = (shape: Shape) => {
24 | switch (shape.kind) {
25 | case 'square':
26 | return Math.pow(shape.size, 2);
27 | case 'circle':
28 | return Math.PI * Math.pow(shape.radius, 2);
29 | }
30 | };
31 |
32 | const square: Square = { kind: 'square', size: 5 };
33 | const circle: Circle = { kind: 'circle', radius: 2 };
34 |
35 | console.log(area(square)); // 25
36 | console.log(area(circle)); // 12.566370614359172
37 | ```
38 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/books/Distributive Conditional Types.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Distributive Conditional Types
3 | sidebar:
4 | order: 38
5 | label: 38. Distributive Conditional Types
6 | ---
7 |
8 | Distributive Conditional Types are a feature that allow a type to be distributed over a union of types, by applying a transformation to each member of the union individually.
9 | This can be especially useful when working with mapped types or higher-order types.
10 |
11 | ```typescript
12 | type Nullable = T extends any ? T | null : never;
13 | type NumberOrBool = number | boolean;
14 | type NullableNumberOrBool = Nullable; // number | boolean | null
15 | ```
16 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/books/Erased Structural Types.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Erased Structural Types
3 | sidebar:
4 | order: 54
5 | label: 54. Erased Structural Types
6 | ---
7 |
8 | In TypeScript, objects do not have to match a specific, exact type. For instance, if we create an object that fulfills an interface's requirements, we can utilize that object in places where that interface is required, even if there was no explicit connection between them.
9 | Example:
10 |
11 | ```typescript
12 | type NameProp1 = {
13 | prop1: string;
14 | };
15 |
16 | function log(x: NameProp1) {
17 | console.log(x.prop1);
18 | }
19 |
20 | const obj = {
21 | prop2: 123,
22 | prop1: 'Origin',
23 | };
24 |
25 | log(obj); // Valid
26 | ```
27 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/books/Exhaustiveness checking.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Exhaustiveness checking
3 | sidebar:
4 | order: 24
5 | label: 24. Exhaustiveness checking
6 | ---
7 |
8 | Exhaustiveness checking is a feature in TypeScript that ensures all possible cases of a discriminated union are handled in a `switch` statement or an `if` statement.
9 |
10 | ```typescript
11 | type Direction = 'up' | 'down';
12 |
13 | const move = (direction: Direction) => {
14 | switch (direction) {
15 | case 'up':
16 | console.log('Moving up');
17 | break;
18 | case 'down':
19 | console.log('Moving down');
20 | break;
21 | default:
22 | const exhaustiveCheck: never = direction;
23 | console.log(exhaustiveCheck); // This line will never be executed
24 | }
25 | };
26 | ```
27 |
28 | The `never` type is used to ensure that the default case is exhaustive and that TypeScript will raise an error if a new value is added to the Direction type without being handled in the switch statement.
29 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/books/Extending Types.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Extending Types
3 | sidebar:
4 | order: 13
5 | label: 13. Extending Types
6 | ---
7 |
8 | It is possible to extend an `interface` (copy members from another type):
9 |
10 | ```typescript
11 | interface X {
12 | a: string;
13 | }
14 | interface Y extends X {
15 | b: string;
16 | }
17 | ```
18 |
19 | It is also possible to extend from multiple types:
20 |
21 | ```typescript
22 | interface A {
23 | a: string;
24 | }
25 | interface B {
26 | b: string;
27 | }
28 | interface Y extends A, B {
29 | y: string;
30 | }
31 | ```
32 |
33 | The `extends` keyword works only on interfaces and classes, for types use an intersection:
34 |
35 | ```typescript
36 | type A = {
37 | a: number;
38 | };
39 | type B = {
40 | b: number;
41 | };
42 | type C = A & B;
43 | ```
44 |
45 | It is possible to extend a type using an inference but not vice versa:
46 |
47 | ```typescript
48 | type A = {
49 | a: string;
50 | };
51 | interface B extends A {
52 | b: string;
53 | }
54 | ```
55 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/books/Fixed Length Tuple.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Fixed Length Tuple
3 | sidebar:
4 | order: 28
5 | label: 28. Fixed Length Tuple
6 | ---
7 |
8 | A Fixed Length Tuple is a specific type of tuple that enforces a fixed number of elements of specific types, and disallows any modifications to the length of the tuple once it is defined.
9 |
10 | Fixed Length Tuples are useful when you need to represent a collection of values with a specific number of elements and specific types, and you want to ensure that the length and types of the tuple cannot be changed inadvertently.
11 |
12 |
13 |
14 | ```typescript
15 | const x = [10, 'hello'] as const;
16 | x.push(2); // Error
17 | ```
18 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/books/Index Signatures.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Index Signatures
3 | sidebar:
4 | order: 12
5 | label: 12. Index Signatures
6 | ---
7 |
8 | In TypeScript we can use as index signature `string`, `number`, and `symbol`:
9 |
10 | ```typescript
11 | type K = {
12 | [name: string | number]: string;
13 | };
14 | const k: K = { x: 'x', 1: 'b' };
15 | console.log(k['x']);
16 | console.log(k[1]);
17 | console.log(k['1']); // Same result as k[1]
18 | ```
19 |
20 | Please note that JavaScript automatically converts an index with `number` to an index with `string` so `k[1]` or `k["1"]` return the same value.
21 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/books/Interface and Type.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Interface and Type
3 | sidebar:
4 | order: 46
5 | label: 46. Interface and Type
6 | ---
7 |
8 | ### Common Syntax
9 |
10 | In TypeScript, interfaces define the structure of objects, specifying the names and types of properties or methods that an object must have. The common syntax for defining an interface in TypeScript is as follows:
11 |
12 |
13 |
14 | ```typescript
15 | interface InterfaceName {
16 | property1: Type1;
17 | // ...
18 | method1(arg1: ArgType1, arg2: ArgType2): ReturnType;
19 | // ...
20 | }
21 | ```
22 |
23 | Similarly for type definition:
24 |
25 |
26 |
27 | ```typescript
28 | type TypeName = {
29 | property1: Type1;
30 | // ...
31 | method1(arg1: ArgType1, arg2: ArgType2): ReturnType;
32 | // ...
33 | };
34 | ```
35 |
36 | `interface InterfaceName` or `type TypeName`: Defines the name of the interface.
37 | `property1`: `Type1`: Specifies the properties of the interface along with their corresponding types. Multiple properties can be defined, each separated by a semicolon.
38 | `method1(arg1: ArgType1, arg2: ArgType2): ReturnType;`: Specifies the methods of the interface. Methods are defined with their names, followed by a parameter list in parentheses and the return type. Multiple methods can be defined, each separated by a semicolon.
39 |
40 | Example interface:
41 |
42 | ```typescript
43 | interface Person {
44 | name: string;
45 | age: number;
46 | greet(): void;
47 | }
48 | ```
49 |
50 | Example of type:
51 |
52 | ```typescript
53 | type TypeName = {
54 | property1: string;
55 | method1(arg1: string, arg2: string): string;
56 | };
57 | ```
58 |
59 | In TypeScript, types are used to define the shape of data and enforce type checking. There are several common syntaxes for defining types in TypeScript, depending on the specific use case. Here are some examples:
60 |
61 | ### Basic Types
62 |
63 | ```typescript
64 | let myNumber: number = 123; // number type
65 | let myBoolean: boolean = true; // boolean type
66 | let myArray: string[] = ['a', 'b']; // array of strings
67 | let myTuple: [string, number] = ['a', 123]; // tuple
68 | ```
69 |
70 | ### Objects and Interfaces
71 |
72 | ```typescript
73 | const x: { name: string; age: number } = { name: 'Simon', age: 7 };
74 | ```
75 |
76 | ### Union and Intersection Types
77 |
78 | ```typescript
79 | type MyType = string | number; // Union type
80 | let myUnion: MyType = 'hello'; // Can be a string
81 | myUnion = 123; // Or a number
82 |
83 | type TypeA = { name: string };
84 | type TypeB = { age: number };
85 | type CombinedType = TypeA & TypeB; // Intersection type
86 | let myCombined: CombinedType = { name: 'John', age: 25 }; // Object with both name and age properties
87 | ```
88 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/books/Intersection Types.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Intersection Types
3 | sidebar:
4 | order: 30
5 | label: 30. Intersection Types
6 | ---
7 |
8 | An Intersection Type is a type that represents a value that has all the properties of two or more types. Intersection Types are denoted using the `&` symbol between each type.
9 |
10 | ```typescript
11 | type X = {
12 | a: string;
13 | };
14 |
15 | type Y = {
16 | b: string;
17 | };
18 |
19 | type J = X & Y; // Intersection
20 |
21 | const j: J = {
22 | a: 'a',
23 | b: 'b',
24 | };
25 | ```
26 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/books/Introduction.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Introduction
3 | sidebar:
4 | order: 3
5 | label: 3. Introduction
6 | ---
7 |
8 | Welcome to The Concise TypeScript Book! This guide equips you with essential knowledge and practical skills for effective TypeScript development. Discover key concepts and techniques to write clean, robust code. Whether you're a beginner or an experienced developer, this book serves as both a comprehensive guide and a handy reference for leveraging TypeScript's power in your projects.
9 |
10 | This book covers TypeScript 5.2.
11 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/books/Literal Inference.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Literal Inference
3 | sidebar:
4 | order: 15
5 | label: 15. Literal Inference
6 | ---
7 |
8 | Literal Inference is a feature in TypeScript that allows the type of a variable or parameter to be inferred based on its value.
9 |
10 | In the following example we can see that TypeScript considers `x` a literal type as the value cannot be changed any time later, when instead `y` is inferred as string as it can be modified any time later.
11 |
12 | ```typescript
13 | const x = 'x'; // Literal type of 'x', because this value cannot be changed
14 | let y = 'y'; // Type string, as we can change this value
15 | ```
16 |
17 | In the following example we can see that `o.x` was inferred as a `string` (and not a literal of `a`) as TypeScript considers that the value can be changed any time later.
18 |
19 |
20 |
21 | ```typescript
22 | type X = 'a' | 'b';
23 |
24 | let o = {
25 | x: 'a', // This is a wider string
26 | };
27 |
28 | const fn = (x: X) => `${x}-foo`;
29 |
30 | console.log(fn(o.x)); // Argument of type 'string' is not assignable to parameter of type 'X'
31 | ```
32 |
33 | As you can see the code throws an error when passing `o.x` to `fn` as X is a narrower type.
34 |
35 | We can solve this issue by using type assertion using `const` or the `X` type:
36 |
37 |
38 |
39 | ```typescript
40 | let o = {
41 | x: 'a' as const,
42 | };
43 | ```
44 |
45 | or:
46 |
47 |
48 |
49 | ```typescript
50 | let o = {
51 | x: 'a' as X,
52 | };
53 | ```
54 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/books/Literal Types.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Literal Types
3 | sidebar:
4 | order: 14
5 | label: 14. Literal Types
6 | ---
7 |
8 | A Literal Type is a single element set from a collective type, it defines a very exact value that is a JavaScript primitive.
9 |
10 | Literal Types in TypeScript are numbers, strings, and booleans.
11 |
12 | Example of literals:
13 |
14 | ```typescript
15 | const a = 'a'; // String literal type
16 | const b = 1; // Numeric literal type
17 | const c = true; // Boolean literal type
18 | ```
19 |
20 | String, Numeric, and Boolean Literal Types are used in the union, type guard, and type aliases.
21 | In the following example you can see a type alias union, `O` can be the only value specified and not any other string:
22 |
23 | ```typescript
24 | type O = 'a' | 'b' | 'c';
25 | ```
26 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/books/Mapped Type Modifiers.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Mapped Type Modifiers
3 | sidebar:
4 | order: 36
5 | label: 36. Mapped Type Modifiers
6 | ---
7 |
8 | Mapped Type Modifiers in TypeScript enable the transformation of properties within an existing type:
9 |
10 | * `readonly` or `+readonly`: This renders a property in the mapped type as read-only.
11 | * `-readonly`: This allows a property in the mapped type to be mutable.
12 | * `?`: This designates a property in the mapped type as optional.
13 |
14 | Examples:
15 |
16 | ```typescript
17 | type ReadOnly = { readonly [P in keyof T]: T[P] }; // All properties marked as read-only
18 |
19 | type Mutable = { -readonly [P in keyof T]: T[P] }; // All properties marked as mutable
20 |
21 | type MyPartial = { [P in keyof T]?: T[P] }; // All properties marked as optional
22 | ```
23 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/books/Mapped Types.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Mapped Types
3 | sidebar:
4 | order: 35
5 | label: 35. Mapped Types
6 | ---
7 |
8 | Mapped Types in TypeScript allow you to create new types based on an existing type by transforming each property using a mapping function. By mapping existing types, you can create new types that represent the same information in a different format. To create a mapped type, you access the properties of an existing type using the `keyof` operator and then alter them to produce a new type.
9 | In the following example:
10 |
11 | ```typescript
12 | type MyMappedType = {
13 | [P in keyof T]: T[P][];
14 | };
15 | type MyType = {
16 | foo: string;
17 | bar: number;
18 | };
19 | type MyNewType = MyMappedType;
20 | const x: MyNewType = {
21 | foo: ['hello', 'world'],
22 | bar: [1, 2, 3],
23 | };
24 | ```
25 |
26 | we define MyMappedType to map over T's properties, creating a new type with each property as an array of its original type. Using this, we create MyNewType to represent the same info as MyType, but with each property as an array.
27 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/books/Merging and Extension.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Merging and Extension
3 | sidebar:
4 | order: 50
5 | label: 50. Merging and Extension
6 | ---
7 |
8 | Merging and extension refer to two different concepts related to working with types and interfaces.
9 |
10 | Merging allows you to combine multiple declarations of the same name into a single definition, for example, when you define an interface with the same name multiple times:
11 |
12 | ```typescript
13 | interface X {
14 | a: string;
15 | }
16 |
17 | interface X {
18 | b: number;
19 | }
20 |
21 | const person: X = {
22 | a: 'a',
23 | b: 7,
24 | };
25 | ```
26 |
27 | Extension refers to the ability to extend or inherit from existing types or interfaces to create new ones. It is a mechanism to add additional properties or methods to an existing type without modifying its original definition. Example:
28 |
29 | ```typescript
30 | interface Animal {
31 | name: string;
32 | eat(): void;
33 | }
34 |
35 | interface Bird extends Animal {
36 | sing(): void;
37 | }
38 |
39 | const dog: Bird = {
40 | name: 'Bird 1',
41 | eat() {
42 | console.log('Eating');
43 | },
44 | sing() {
45 | console.log('Singing');
46 | },
47 | };
48 | ```
49 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/books/Named Tuple Type (Labeled).md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Named Tuple Type (Labeled)
3 | sidebar:
4 | order: 27
5 | label: 27. Named Tuple Type (Labeled)
6 | ---
7 |
8 | Tuple types can include optional labels or names for each element. These labels are for readability and tooling assistance, and do not affect the operations you can perform with them.
9 |
10 | ```typescript
11 | type T = string;
12 | type Tuple1 = [T, T];
13 | type Tuple2 = [a: T, b: T];
14 | type Tuple3 = [a: T, T]; // Named Tuple plus Anonymous Tuple
15 | ```
16 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/books/Namespacing.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Namespacing
3 | sidebar:
4 | order: 55
5 | label: 55. Namespacing
6 | ---
7 |
8 | In TypeScript, namespaces are used to organize code into logical containers, preventing naming collisions and providing a way to group related code together.
9 | The usage of the `export` keywords allows access to the namespace in "outside" modules.
10 |
11 | ```typescript
12 | export namespace MyNamespace {
13 | export interface MyInterface1 {
14 | prop1: boolean;
15 | }
16 | export interface MyInterface2 {
17 | prop2: string;
18 | }
19 | }
20 |
21 | const a: MyNamespace.MyInterface1 = {
22 | prop1: true,
23 | };
24 | ```
25 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/books/Never type.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Never type
3 | sidebar:
4 | order: 45
5 | label: 45. Never type
6 | ---
7 |
8 | The `never` type represents values that never occur. It is used to denote functions or expressions that never return or throw an error.
9 |
10 | For instance an infinite loop:
11 |
12 | ```typescript
13 | const infiniteLoop = (): never => {
14 | while (true) {
15 | // do something
16 | }
17 | };
18 | ```
19 |
20 | Throwing an error:
21 |
22 | ```typescript
23 | const throwError = (message: string): never => {
24 | throw new Error(message);
25 | };
26 | ```
27 |
28 | The `never` type is useful in ensuring type safety and catching potential errors in your code. It helps TypeScript analyze and infer more precise types when used in combination with other types and control flow statements, for instance:
29 |
30 | ```typescript
31 | type Direction = 'up' | 'down';
32 | const move = (direction: Direction): void => {
33 | switch (direction) {
34 | case 'up':
35 | // move up
36 | break;
37 | case 'down':
38 | // move down
39 | break;
40 | default:
41 | const exhaustiveCheck: never = direction;
42 | throw new Error(`Unhandled direction: ${exhaustiveCheck}`);
43 | }
44 | };
45 | ```
46 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/books/Object Types.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Object Types
3 | sidebar:
4 | order: 25
5 | label: 25. Object Types
6 | ---
7 |
8 | In TypeScript, object types describe the shape of an object. They specify the names and types of the object's properties, as well as whether those properties are required or optional.
9 |
10 | In TypeScript, you can define object types in two primary ways:
11 |
12 | Interface which defines the shape of an object by specifying the names, types, and optionality of its properties.
13 |
14 | ```typescript
15 | interface User {
16 | name: string;
17 | age: number;
18 | email?: string;
19 | }
20 | ```
21 |
22 | Type alias, similar to an interface, defines the shape of an object. However, it can also create a new custom type that is based on an existing type or a combination of existing types. This includes defining union types, intersection types, and other complex types.
23 |
24 | ```typescript
25 | type Point = {
26 | x: number;
27 | y: number;
28 | };
29 | ```
30 |
31 | It also possible to define a type anonymously:
32 |
33 | ```typescript
34 | const sum = (x: { a: number; b: number }) => x.a + x.b;
35 | console.log(sum({ a: 5, b: 1 }));
36 | ```
37 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/books/Optional Properties.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Optional Properties
3 | sidebar:
4 | order: 10
5 | label: 10. Optional Properties
6 | ---
7 |
8 | An object can specify Optional Properties by adding a question mark `?` to the end of the property name:
9 |
10 | ```typescript
11 | type X = {
12 | a: number;
13 | b?: number; // Optional
14 | };
15 | ```
16 |
17 | It is possible to specify a default value when a property is optional"
18 |
19 | ```typescript
20 | type X = {
21 | a: number;
22 | b?: number;
23 | };
24 | const x = ({ a, b = 100 }: X) => a + b;
25 | ```
26 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/books/Overloads.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Overloads
3 | sidebar:
4 | order: 49
5 | label: 49. Overloads
6 | ---
7 |
8 | Function overloads in TypeScript allow you to define multiple function signatures for a single function name, enabling you to define functions that can be called in multiple ways. Here's an example:
9 |
10 | ```typescript
11 | // Overloads
12 | function sayHi(name: string): string;
13 | function sayHi(names: string[]): string[];
14 |
15 | // Implementation
16 | function sayHi(name: unknown): unknown {
17 | if (typeof name === 'string') {
18 | return `Hi, ${name}!`;
19 | } else if (Array.isArray(name)) {
20 | return name.map(name => `Hi, ${name}!`);
21 | }
22 | throw new Error('Invalid value');
23 | }
24 |
25 | sayHi('xx'); // Valid
26 | sayHi(['aa', 'bb']); // Valid
27 | ```
28 |
29 | Here's another example of using function overloads within a `class`:
30 |
31 | ```typescript
32 | class Greeter {
33 | message: string;
34 |
35 | constructor(message: string) {
36 | this.message = message;
37 | }
38 |
39 | // overload
40 | sayHi(name: string): string;
41 | sayHi(names: string[]): ReadonlyArray;
42 |
43 | // implementation
44 | sayHi(name: unknown): unknown {
45 | if (typeof name === 'string') {
46 | return `${this.message}, ${name}!`;
47 | } else if (Array.isArray(name)) {
48 | return name.map(name => `${this.message}, ${name}!`);
49 | }
50 | throw new Error('value is invalid');
51 | }
52 | }
53 | console.log(new Greeter('Hello').sayHi('Simon'));
54 | ```
55 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/books/Predefined Conditional Types.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Predefined Conditional Types
3 | sidebar:
4 | order: 40
5 | label: 40. Predefined Conditional Types
6 | ---
7 |
8 | In TypeScript, Predefined Conditional Types are built-in conditional types provided by the language. They are designed to perform common type transformations based on the characteristics of a given type.
9 |
10 | `Exclude`: This type removes all the types from Type that are assignable to ExcludedType.
11 |
12 | `Extract`: This type extracts all the types from Union that are assignable to Type.
13 |
14 | `NonNullable`: This type removes null and undefined from Type.
15 |
16 | `ReturnType`: This type extracts the return type of a function Type.
17 |
18 | `Parameters`: This type extracts the parameter types of a function Type.
19 |
20 | `Required`: This type makes all properties in Type required.
21 |
22 | `Partial`: This type makes all properties in Type optional.
23 |
24 | `Readonly`: This type makes all properties in Type readonly.
25 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/books/Readonly Properties.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Readonly Properties
3 | sidebar:
4 | order: 11
5 | label: 11. Readonly Properties
6 | ---
7 |
8 | Is it possible to prevent writing on a property by using the modifier `readonly`which makes sure that the property cannot be re-written but does not provide any guarantee of total immutability:
9 |
10 | ```typescript
11 | interface Y {
12 | readonly a: number;
13 | }
14 |
15 | type X = {
16 | readonly a: number;
17 | };
18 |
19 | type J = Readonly<{
20 | a: number;
21 | }>;
22 |
23 | type K = {
24 | readonly [index: number]: string;
25 | };
26 | ```
27 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/books/Symbols.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Symbols
3 | sidebar:
4 | order: 56
5 | label: 56. Symbols
6 | ---
7 |
8 | Symbols are a primitive data type that represents an immutable value which is guaranteed to be globally unique throughout the lifetime of the program.
9 |
10 | Symbols can be used as keys for object properties and provide a way to create non-enumerable properties.
11 |
12 | ```typescript
13 | const key1: symbol = Symbol('key1');
14 | const key2: symbol = Symbol('key2');
15 |
16 | const obj = {
17 | [key1]: 'value 1',
18 | [key2]: 'value 2',
19 | };
20 |
21 | console.log(obj[key1]); // value 1
22 | console.log(obj[key2]); // value 2
23 | ```
24 |
25 | In WeakMaps and WeakSets, symbols are now permissible as keys.
26 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/books/Template Union Types.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Template Union Types
3 | sidebar:
4 | order: 41
5 | label: 41. Template Union Types
6 | ---
7 |
8 | Template union types can be used to merge and manipulate text inside the type system for instance:
9 |
10 | ```typescript
11 | type Status = 'active' | 'inactive';
12 | type Products = 'p1' | 'p2';
13 | type ProductId = `id-${Products}-${Status}`; // "id-p1-active" | "id-p1-inactive" | "id-p2-active" | "id-p2-inactive"
14 | ```
15 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/books/The Concise TypeScript Book.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: The Concise TypeScript Book
3 | sidebar:
4 | order: 1
5 | label: 1. The Concise TypeScript Book
6 | ---
7 |
8 | The Concise TypeScript Book provides a comprehensive and succinct overview of TypeScript's capabilities. It offers clear explanations covering all aspects found in the latest version of the language, from its powerful type system to advanced features. Whether you're a beginner or an experienced developer, this book is an invaluable resource to enhance your understanding and proficiency in TypeScript.
9 |
10 | This book is completely Free and Open Source.
11 |
12 | If you found this TypeScript book valuable and wish to contribute, consider supporting my efforts via PayPal. Thanks!
13 |
14 | [](https://www.paypal.com/donate/?business=QW82ZS956XLFY\&no_recurring=0\¤cy_code=EUR)
15 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/books/The never Type.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: The never Type
3 | sidebar:
4 | order: 23
5 | label: 23. The never Type
6 | ---
7 |
8 | When a variable is narrowed to a type that cannot contain any values, the TypeScript compiler will infer that the variable must be of the `never` type. This is because The never Type represents a value that can never be produced.
9 |
10 | ```typescript
11 | const printValue = (val: string | number) => {
12 | if (typeof val === 'string') {
13 | console.log(val.toUpperCase());
14 | } else if (typeof val === 'number') {
15 | console.log(val.toFixed(2));
16 | } else {
17 | // val has type never here because it can never be anything other than a string or a number
18 | const neverVal: never = val;
19 | console.log(`Unexpected value: ${neverVal}`);
20 | }
21 | };
22 | ```
23 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/books/Triple-Slash Directives.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Triple-Slash Directives
3 | sidebar:
4 | order: 57
5 | label: 57. Triple-Slash Directives
6 | ---
7 |
8 | Triple-slash directives are special comments that provide instructions to the compiler about how to process a file. These directives begin with three consecutive slashes (`///`) and are typically placed at the top of a TypeScript file and have no effects on the runtime behavior.
9 |
10 | Triple-slash directives are used to reference external dependencies, specify module loading behavior, enable/disable certain compiler features, and more. Few examples:
11 |
12 | Referencing a declaration file:
13 |
14 |
15 |
16 | ```typescript
17 | ///
18 | ```
19 |
20 | Indicate the module format:
21 |
22 |
23 |
24 | ```typescript
25 | ///
26 | ```
27 |
28 | Enable compiler options, in the following example strict mode:
29 |
30 |
31 |
32 | ```typescript
33 | ///
34 | ```
35 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/books/Tuple Type (Anonymous).md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Tuple Type (Anonymous)
3 | sidebar:
4 | order: 26
5 | label: 26. Tuple Type (Anonymous)
6 | ---
7 |
8 | A Tuple Type is a type that represents an array with a fixed number of elements and their corresponding types. A tuple type enforces a specific number of elements and their respective types in a fixed order. Tuple types are useful when you want to represent a collection of values with specific types, where the position of each element in the array has a specific meaning.
9 |
10 | ```typescript
11 | type Point = [number, number];
12 | ```
13 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/books/Type Annotations.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Type Annotations
3 | sidebar:
4 | order: 9
5 | label: 9. Type Annotations
6 | ---
7 |
8 | On variables declared using `var`, `let` and `const`, it is possible to optionally add a type:
9 |
10 | ```typescript
11 | const x: number = 1;
12 | ```
13 |
14 | TypeScript does a good job of inferring types, especially when simple one, so these declarations in most cases are not necessary.
15 |
16 | On functions is possible to add type annotations to parameters:
17 |
18 | ```typescript
19 | function sum(a: number, b: number) {
20 | return a + b;
21 | }
22 | ```
23 |
24 | The following is an example using a anonymous functions (so called lambda function):
25 |
26 | ```typescript
27 | const sum = (a: number, b: number) => a + b;
28 | ```
29 |
30 | These annotation can be avoided when a default value for a parameter is present:
31 |
32 | ```typescript
33 | const sum = (a = 10, b: number) => a + b;
34 | ```
35 |
36 | Return type annotations can be added to functions:
37 |
38 | ```typescript
39 | const sum = (a = 10, b: number): number => a + b;
40 | ```
41 |
42 | This is useful especially for more complex functions as writing expliciting the return type before an implementation can help better think about the function.
43 |
44 | Generally consider annotating type signatures but not the body local variables and add types always to object literals.
45 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/books/Type Indexing.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Type Indexing
3 | sidebar:
4 | order: 31
5 | label: 31. Type Indexing
6 | ---
7 |
8 | Type indexing refers to the ability to define types that can be indexed by a key that is not known in advance, using an index signature to specify the type for properties that are not explicitly declared.
9 |
10 | ```typescript
11 | type Dictionary = {
12 | [key: string]: T;
13 | };
14 | const myDict: Dictionary = { a: 'a', b: 'b' };
15 | console.log(myDict['a']); // Returns a
16 | ```
17 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/books/Type Predicates.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Type Predicates
3 | sidebar:
4 | order: 21
5 | label: 21. Type Predicates
6 | ---
7 |
8 | Type Predicates in TypeScript are functions that return a boolean value and are used to narrow the type of a variable to a more specific type.
9 |
10 | ```typescript
11 | const isString = (value: unknown): value is string => typeof value === 'string';
12 |
13 | const foo = (bar: unknown) => {
14 | if (isString(bar)) {
15 | console.log(bar.toUpperCase());
16 | } else {
17 | console.log('not a string');
18 | }
19 | };
20 | ```
21 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/books/Type from Func Return.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Type from Func Return
3 | sidebar:
4 | order: 33
5 | label: 33. Type from Func Return
6 | ---
7 |
8 | Type from Func Return refers to the ability to automatically infer the return type of a function based on its implementation. This allows TypeScript to determine the type of the value returned by the function without explicit type annotations.
9 |
10 | ```typescript
11 | const add = (x: number, y: number) => x + y; // TypeScript can infer that the return type of the function is a number
12 | ```
13 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/books/Type from Module.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Type from Module
3 | sidebar:
4 | order: 34
5 | label: 34. Type from Module
6 | ---
7 |
8 | Type from Module refers to the ability to use a module's exported values to automatically infer their types. When a module exports a value with a specific type, TypeScript can use that information to automatically infer the type of that value when it is imported into another module.
9 |
10 |
11 |
12 | ```typescript
13 | // calc.ts
14 | export const add = (x: number, y: number) => x + y;
15 | // index.ts
16 | import { add } from 'calc';
17 | const r = add(1, 2); // r is number
18 | ```
19 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/books/Type from Value.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Type from Value
3 | sidebar:
4 | order: 32
5 | label: 32. Type from Value
6 | ---
7 |
8 | Type from Value in TypeScript refers to the automatic inference of a type from a value or expression through type inference.
9 |
10 | ```typescript
11 | const x = 'x'; // TypeScript can automatically infer that the type of the message variable is string
12 | ```
13 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/books/Union Type.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Union Type
3 | sidebar:
4 | order: 29
5 | label: 29. Union Type
6 | ---
7 |
8 | A Union Type is a type that represents a value that can be one of several types. Union Types are denoted using the `|` symbol between each possible type.
9 |
10 | ```typescript
11 | let x: string | number;
12 | x = 'hello'; // Valid
13 | x = 123; // Valid
14 | ```
15 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/books/Unknown type.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Unknown type
3 | sidebar:
4 | order: 43
5 | label: 43. Unknown type
6 | ---
7 |
8 | In TypeScript, the `unknown` type represents a value that is of an unknown type. Unlike `any` type, which allows for any type of value, `unknown` requires a type check or assertion before it can be used in a specific way so no operations are permitted on an `unknown` without first asserting or narrowing to a more specific type.
9 |
10 | The `unknown` type is only assignable to any type and the `unknown` type itself, it is a type-safe alternative to `any`.
11 |
12 |
13 |
14 | ```typescript
15 | let value: unknown;
16 |
17 | let value1: unknown = value; // Valid
18 | let value2: any = value; // Valid
19 | let value3: boolean = value; // Invalid
20 | let value4: number = value; // Invalid
21 | ```
22 |
23 | ```typescript
24 | const add = (a: unknown, b: unknown): number | undefined =>
25 | typeof a === 'number' && typeof b === 'number' ? a + b : undefined;
26 | console.log(add(1, 2)); // 3
27 | console.log(add('x', 2)); // undefined
28 | ```
29 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/books/Void type.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Void type
3 | sidebar:
4 | order: 44
5 | label: 44. Void type
6 | ---
7 |
8 | The `void` type is used to indicate that a function does not return a value.
9 |
10 | ```typescript
11 | const sayHello = (): void => {
12 | console.log('Hello!');
13 | };
14 | ```
15 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/books/infer Type Inference in Conditional Types.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: infer Type Inference in Conditional Types
3 | sidebar:
4 | order: 39
5 | label: 39. infer Type Inference in Conditional Types
6 | ---
7 |
8 | The `infer`keyword is used in conditional types to infer (extract) the type of a generic parameter from a type that depends on it. This allows you to write more flexible and reusable type definitions.
9 |
10 | ```typescript
11 | type ElementType = T extends (infer U)[] ? U : never;
12 | type Numbers = ElementType; // number
13 | type Strings = ElementType; // string
14 | ```
15 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/books/strictNullChecks.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: strictNullChecks
3 | sidebar:
4 | order: 16
5 | label: 16. strictNullChecks
6 | ---
7 |
8 | `strictNullChecks` is a TypeScript compiler option that enforces strict null checking. When this option is enabled, variables and parameters can only be assigned `null` or `undefined` if they have been explicitly declared to be of that type using the union type `null` | `undefined`. If a variable or parameter is not explicitly declared as nullable, TypeScript will generate an error to prevent potential runtime errors.
9 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Typescript Book
3 | description: The Concise TypeScript Book
4 | template: splash
5 | hero:
6 | tagline: The Concise TypeScript Book provides a comprehensive and succinct overview of TypeScript's capabilities. It offers clear explanations covering all aspects found in the latest version of the language, from its powerful type system to advanced features. Whether you're a beginner or an experienced developer, this book is an invaluable resource to enhance your understanding and proficiency in TypeScript.
This book is completely Free and Open Source.
7 | actions:
8 | - text: Reading now!
9 | link: /books/the-concise-typescript-book/
10 | icon: right-arrow
11 | variant: primary
12 | ---
13 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/zh-cn/books/About the Author.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 关于作者
3 | sidebar:
4 | order: 4
5 | label: 4. 关于作者
6 | ---
7 |
8 | Simone Poggiali 是一位经验丰富的高级前端开发人员,自 90 年代以来就热衷于编写专业级代码。在他的国际职业生涯中,他为从初创公司到大型组织的广泛客户提供了众多项目。HelloFresh、Siemens、O2 和 Leroy Merlin 等著名公司都受益于他的专业知识和奉献精神。
9 |
10 | 您可以通过以下平台联系 Simone Poggiali:
11 |
12 | * 领英:
13 | * GitHub:
14 | * X.com:
15 | * 电子邮箱: gibbok.coding📧gmail.com
16 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/zh-cn/books/Any type.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 任意类型
3 | sidebar:
4 | order: 42
5 | label: 42. 任意类型
6 | ---
7 |
8 | `any` 类型是一种特殊类型(通用超类型),可用于表示任何类型的值(基元、对象、数组、函数、错误、符号)。它通常用于编译时未知值类型的情况,或者使用来自没有 TypeScript 类型的外部 API 或库的值时。
9 |
10 | 通过使用任何类型,您向 TypeScript 编译器指示值应该不受任何限制地表示。为了最大限度地提高代码中的类型安全性,请考虑以下事项:
11 |
12 | * 将 `any` 的使用限制在类型确实未知的特定情况下。
13 | * 不要从函数返回 `any` 类型,因为使用该函数会在代码中失去类型安全性,从而削弱类型安全性。
14 | * 如果您需要使编译器保持沉默,请使用 `@ts-ignore` 而不是 `any`。
15 |
16 | ```typescript
17 | let value: any;
18 | value = true; // 有效
19 | value = 7; // 有效
20 | ```
21 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/zh-cn/books/Assignments.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 赋值
3 | sidebar:
4 | order: 19
5 | label: 19. 赋值
6 | ---
7 |
8 | 使用赋值缩小 TypeScript 是一种根据分配给变量的值来缩小变量类型的方法。当为变量分配值时,TypeScript 会根据分配的值推断其类型,并缩小变量的类型以匹配推断的类型。
9 |
10 | ```typescript
11 | let value: string | number;
12 | value = 'hello';
13 | if (typeof value === 'string') {
14 | console.log(value.toUpperCase());
15 | }
16 | value = 42;
17 | if (typeof value === 'number') {
18 | console.log(value.toFixed(2));
19 | }
20 | ```
21 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/zh-cn/books/Built-in Type Primitives.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 内置原始数据类型
3 | sidebar:
4 | order: 47
5 | label: 47. 内置原始数据类型
6 | ---
7 |
8 | TypeScript 有几个内置的原属数据类型,可用于定义变量、函数参数和返回类型:
9 |
10 | `number`: 表示数值,包括整数和浮点数。
11 | `string`: 代表文本数据。
12 | `boolean`: 代表逻辑值,可以是 true 或 false。
13 | `null`: 表示没有值。
14 | `undefined`: 表示尚未赋值或未定义的值。
15 | `symbol`: 代表唯一标识符。符号通常用作对象属性的键。
16 | `bigint`: 表示任意精度整数。
17 | `any`: 代表动态或未知类型。any 类型的变量可以保存任何类型的值,并且它们绕过类型检查。
18 | `void`: 表示不存在任何类型。它通常用作不返回值的函数的返回类型。
19 | `never`: 表示从未出现过的值的类型。它通常用作引发错误或进入无限循环的函数的返回类型。
20 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/zh-cn/books/Common Built-in JS Objects.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 常见的内置JS对象
3 | sidebar:
4 | order: 48
5 | label: 48. 常见的内置JS对象
6 | ---
7 |
8 | TypeScript 是 JavaScript 的超集,它包含所有常用的内置 JavaScript 对象。您可以在 Mozilla 开发者网络 (MDN) 文档网站上找到这些对象的详细列表:
9 |
10 |
11 | 以下是一些常用的内置 JavaScript 对象的列表:
12 |
13 | * Function
14 | * Object
15 | * Boolean
16 | * Error
17 | * Number
18 | * BigInt
19 | * Math
20 | * Date
21 | * String
22 | * RegExp
23 | * Array
24 | * Map
25 | * Set
26 | * Promise
27 | * Intl
28 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/zh-cn/books/Conditional Types.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 条件类型
3 | sidebar:
4 | order: 37
5 | label: 37. 条件类型
6 | ---
7 |
8 | 条件类型是一种创建依赖于条件的类型的方法,其中要创建的类型是根据条件的结果确定的。它们是使用 `extends` 关键字和三元运算符来定义的,以便有条件地在两种类型之间进行选择。
9 |
10 | ```typescript
11 | type IsArray = T extends any[] ? true : false;
12 |
13 | const myArray = [1, 2, 3];
14 | const myNumber = 42;
15 |
16 | type IsMyArrayAnArray = IsArray; // true 类型
17 | type IsMyNumberAnArray = IsArray; // false 类型
18 | ```
19 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/zh-cn/books/Control Flow Analysis.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 控制流分析
3 | sidebar:
4 | order: 20
5 | label: 20. 控制流分析
6 | ---
7 |
8 | TypeScript 中的控制流分析是一种静态分析代码流以推断变量类型的方法,允许编译器根据分析结果根据需要缩小这些变量的类型。
9 |
10 | 在 TypeScript 4.4 之前,代码流分析仅适用于 if 语句中的代码,但从 TypeScript 4.4 开始,它还可以应用于条件表达式和通过 const 变量间接引用的判别式属性访问。
11 |
12 | 例如:
13 |
14 | ```typescript
15 | const f1 = (x: unknown) => {
16 | const isString = typeof x === 'string';
17 | if (isString) {
18 | x.length;
19 | }
20 | };
21 |
22 | const f2 = (
23 | obj: { kind: 'foo'; foo: string } | { kind: 'bar'; bar: number }
24 | ) => {
25 | const isFoo = obj.kind === 'foo';
26 | if (isFoo) {
27 | obj.foo;
28 | } else {
29 | obj.bar;
30 | }
31 | };
32 | ```
33 |
34 | 一些未发生缩小的示例:
35 |
36 |
37 |
38 | ```typescript
39 | const f1 = (x: unknown) => {
40 | let isString = typeof x === 'string';
41 | if (isString) {
42 | x.length; // 错误, 没有缩小,因为 isString 不是常量
43 | }
44 | };
45 |
46 | const f6 = (
47 | obj: { kind: 'foo'; foo: string } | { kind: 'bar'; bar: number }
48 | ) => {
49 | const isFoo = obj.kind === 'foo';
50 | obj = obj;
51 | if (isFoo) {
52 | obj.foo; // 错误, 没有缩小,因为 obj 在函数体中被赋值
53 | }
54 | };
55 | ```
56 |
57 | 注意: 在条件表达式中最多分析五个间接级别。
58 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/zh-cn/books/Differences between Type and Interface.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 类型和接口之间的差异
3 | sidebar:
4 | order: 51
5 | label: 51. 类型和接口之间的差异
6 | ---
7 |
8 | 声明合并(增强):
9 |
10 | 接口支持声明合并,这意味着您可以定义多个具有相同名称的接口,TypeScript 会将它们合并为具有组合属性和方法的单个接口。 另一方面,类型不支持声明合并。 当您想要添加额外的功能或自定义现有类型而不修改原始定义或修补丢失或不正确的类型时,这可能会很有帮助。
11 |
12 | ```typescript
13 | interface A {
14 | x: string;
15 | }
16 | interface A {
17 | y: string;
18 | }
19 | const j: A = {
20 | x: 'xx',
21 | y: 'yy',
22 | };
23 | ```
24 |
25 | 扩展其他类型/接口:
26 |
27 | 类型和接口都可以扩展其他类型/接口,但语法不同。 对于接口,您可以使用“extends”关键字从其他接口继承属性和方法。 但是,接口无法扩展像联合类型这样的复杂类型。
28 |
29 | ```typescript
30 | interface A {
31 | x: string;
32 | y: number;
33 | }
34 | interface B extends A {
35 | z: string;
36 | }
37 | const car: B = {
38 | x: 'x',
39 | y: 123,
40 | z: 'z',
41 | };
42 | ```
43 |
44 | 对于类型,您可以使用 & 运算符将多个类型合并为单个类型(交集)。
45 |
46 | ```typescript
47 | interface A {
48 | x: string;
49 | y: number;
50 | }
51 |
52 | type B = A & {
53 | j: string;
54 | };
55 |
56 | const c: B = {
57 | x: 'x',
58 | y: 123,
59 | j: 'j',
60 | };
61 | ```
62 |
63 | 并集和交集类型:
64 |
65 | 在定义并集和交集类型时,类型更加灵活。 通过“type”关键字,您可以使用“|”运算符轻松创建联合类型,并使用“&”运算符创建交集类型。 虽然接口也可以间接表示联合类型,但它们没有对交集类型的内置支持。
66 |
67 | ```typescript
68 | type Department = 'dep-x' | 'dep-y'; // 并集
69 |
70 | type Person = {
71 | name: string;
72 | age: number;
73 | };
74 |
75 | type Employee = {
76 | id: number;
77 | department: Department;
78 | };
79 |
80 | type EmployeeInfo = Person & Employee; // 交集
81 | ```
82 |
83 | 接口示例:
84 |
85 | ```typescript
86 | interface A {
87 | x: 'x';
88 | }
89 | interface B {
90 | y: 'y';
91 | }
92 |
93 | type C = A | B; // 接口的并集
94 | ```
95 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/zh-cn/books/Discriminated Unions.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 可区分联合
3 | sidebar:
4 | order: 22
5 | label: 22. 可区分联合
6 | ---
7 |
8 | TypeScript 中的可区分联合是一种联合类型,它使用称为判别式的公共属性来缩小联合的可能类型集。
9 |
10 | ```typescript
11 | type Square = {
12 | kind: 'square'; // 判别式
13 | size: number;
14 | };
15 |
16 | type Circle = {
17 | kind: 'circle'; // 判别式
18 | radius: number;
19 | };
20 |
21 | type Shape = Square | Circle;
22 |
23 | const area = (shape: Shape) => {
24 | switch (shape.kind) {
25 | case 'square':
26 | return Math.pow(shape.size, 2);
27 | case 'circle':
28 | return Math.PI * Math.pow(shape.radius, 2);
29 | }
30 | };
31 |
32 | const square: Square = { kind: 'square', size: 5 };
33 | const circle: Circle = { kind: 'circle', radius: 2 };
34 |
35 | console.log(area(square)); // 25
36 | console.log(area(circle)); // 12.566370614359172
37 | ```
38 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/zh-cn/books/Distributive Conditional Types.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 分配条件类型
3 | sidebar:
4 | order: 38
5 | label: 38. 分配条件类型
6 | ---
7 |
8 | 分布式条件类型是一种功能,通过单独对联合的每个成员应用转换,允许类型分布在类型的联合上。当使用映射类型或高阶类型时,这尤其有用。
9 |
10 | ```typescript
11 | type Nullable = T extends any ? T | null : never;
12 | type NumberOrBool = number | boolean;
13 | type NullableNumberOrBool = Nullable; // number | boolean | null
14 | ```
15 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/zh-cn/books/Erased Structural Types.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 擦除的结构类型
3 | sidebar:
4 | order: 54
5 | label: 54. 擦除的结构类型
6 | ---
7 |
8 | 在 TypeScript 中,对象不必匹配特定的、精确的类型。例如,如果我们创建一个满足接口要求的对象,我们就可以在需要该接口的地方使用该对象,即使它们之间没有显式连接。例子:
9 |
10 | ```typescript
11 | type NameProp1 = {
12 | prop1: string;
13 | };
14 |
15 | function log(x: NameProp1) {
16 | console.log(x.prop1);
17 | }
18 |
19 | const obj = {
20 | prop2: 123,
21 | prop1: 'Origin',
22 | };
23 |
24 | log(obj); // 有效
25 | ```
26 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/zh-cn/books/Exhaustiveness checking.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 详尽性检查
3 | sidebar:
4 | order: 24
5 | label: 24. 详尽性检查
6 | ---
7 |
8 | 详尽性检查是 TypeScript 中的一项功能,可确保在 `switch` 语句或 `if` 语句中处理可区分联合的所有可能情况。
9 |
10 | ```typescript
11 | type Direction = 'up' | 'down';
12 |
13 | const move = (direction: Direction) => {
14 | switch (direction) {
15 | case 'up':
16 | console.log('Moving up');
17 | break;
18 | case 'down':
19 | console.log('Moving down');
20 | break;
21 | default:
22 | const exhaustiveCheck: never = direction;
23 | console.log(exhaustiveCheck); // 这行永远不会被执行
24 | }
25 | };
26 | ```
27 |
28 | 该 `never` 类型用于确保默认情况是详尽的,并且如果将新值添加到 Direction 类型而未在 switch 语句中进行处理,则 TypeScript 将引发错误。
29 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/zh-cn/books/Extending Types.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 扩展类型
3 | sidebar:
4 | order: 13
5 | label: 13. 扩展类型
6 | ---
7 |
8 | 可以扩展 `interface`(从另一种类型复制成员):
9 |
10 | ```typescript
11 | interface X {
12 | a: string;
13 | }
14 | interface Y extends X {
15 | b: string;
16 | }
17 | ```
18 |
19 | 还可以从多种 `interface` 进行扩展:
20 |
21 | ```typescript
22 | interface A {
23 | a: string;
24 | }
25 | interface B {
26 | b: string;
27 | }
28 | interface Y extends A, B {
29 | y: string;
30 | }
31 | ```
32 |
33 | 该 `extends` 关键字仅适用于 `interface`,因为 `type` 使用交集:
34 |
35 | ```typescript
36 | type A = {
37 | a: number;
38 | };
39 | type B = {
40 | b: number;
41 | };
42 | type C = A & B;
43 | ```
44 |
45 | 可以使用 `interface` 来扩展类 `type`,但反之则不然:
46 |
47 | ```typescript
48 | type A = {
49 | a: string;
50 | };
51 | interface B extends A {
52 | b: string;
53 | }
54 | ```
55 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/zh-cn/books/Fixed Length Tuple.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 固定长度元组
3 | sidebar:
4 | order: 28
5 | label: 28. 固定长度元组
6 | ---
7 |
8 | 固定长度元组是一种特定类型的元组,它强制执行特定类型的固定数量的元素,并且一旦定义元组就不允许对其长度进行任何修改。
9 |
10 | 当您需要表示具有特定数量的元素和特定类型的值的集合,并且您希望确保元组的长度和类型不会无意中更改时,固定长度元组非常有用。
11 |
12 |
13 |
14 | ```typescript
15 | const x = [10, 'hello'] as const;
16 | x.push(2); // 错误
17 | ```
18 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/zh-cn/books/Generics.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 泛型
3 | sidebar:
4 | order: 53
5 | label: 53. 泛型
6 | ---
7 |
8 | 泛型允许您创建可与多种类型一起使用的可重用组件和函数。使用泛型,您可以参数化类型、函数和接口,从而允许它们对不同类型进行操作,而无需事先显式指定它们。
9 |
10 | 泛型允许您使代码更加灵活和可重用。
11 |
12 | ### 泛型类型
13 |
14 | 要定义泛型类型,可以使用尖括号 (`<>`) 来指定类型参数,例如:
15 |
16 | ```typescript
17 | function identity(arg: T): T {
18 | return arg;
19 | }
20 | const a = identity('x');
21 | const b = identity(123);
22 |
23 | const getLen = (data: ReadonlyArray) => data.length;
24 | const len = getLen([1, 2, 3]);
25 | ```
26 |
27 | ### 泛型类
28 |
29 | 泛型也可以应用于类,这样它们就可以通过使用类型参数来处理多种类型。这对于创建可重用的类定义非常有用,这些定义可以在保持类型安全的同时对不同的数据类型进行操作。
30 |
31 | ```typescript
32 | class Container {
33 | private item: T;
34 |
35 | constructor(item: T) {
36 | this.item = item;
37 | }
38 |
39 | getItem(): T {
40 | return this.item;
41 | }
42 | }
43 |
44 | const numberContainer = new Container(123);
45 | console.log(numberContainer.getItem()); // 123
46 |
47 | const stringContainer = new Container('hello');
48 | console.log(stringContainer.getItem()); // hello
49 | ```
50 |
51 | ### 泛型约束
52 |
53 | 可以使用关键字 `extends` 后跟类型参数必须满足的类型或接口来约束泛型参数。
54 |
55 | 在下面的示例中,T 必须正确包含 `length` 才能有效:
56 |
57 |
58 |
59 | ```typescript
60 | const printLen = (value: T): void => {
61 | console.log(value.length);
62 | };
63 |
64 | printLen('Hello'); // 5
65 | printLen([1, 2, 3]); // 3
66 | printLen({ length: 10 }); // 10
67 | printLen(123); // 无效
68 | ```
69 |
70 | 3.4 RC 版中引入的泛型的一个有趣功能是高阶函数类型推断,它引入了传播泛型类型参数:
71 |
72 | ```typescript
73 | declare function pipe(
74 | ab: (...args: A) => B,
75 | bc: (b: B) => C
76 | ): (...args: A) => C;
77 |
78 | declare function list(a: T): T[];
79 | declare function box(x: V): { value: V };
80 |
81 | const listBox = pipe(list, box); // (a: T) => { value: T[] }
82 | const boxList = pipe(box, list); // (x: V) => { value: V }[]
83 | ```
84 |
85 | 此功能允许更轻松地键入安全的无点风格编程,这在函数式编程中很常见。
86 |
87 | ### 泛型上下文缩小
88 |
89 | 泛型上下文缩小是 TypeScript 中的机制,允许编译器根据使用泛型参数的上下文来缩小泛型参数的类型,在条件语句中使用泛型类型时非常有用:
90 |
91 | ```typescript
92 | function process(value: T): void {
93 | if (typeof value === 'string') {
94 | // Value 的类型被缩小到 'string' 类型
95 | console.log(value.length);
96 | } else if (typeof value === 'number') {
97 | // Value 的类型被缩小到 'number' 类型
98 | console.log(value.toFixed(2));
99 | }
100 | }
101 |
102 | process('hello'); // 5
103 | process(3.14159); // 3.14
104 | ```
105 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/zh-cn/books/Index Signatures.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 索引签名
3 | sidebar:
4 | order: 12
5 | label: 12. 索引签名
6 | ---
7 |
8 | 在 TypeScript 中,我们可以使用 `string` 、`number` 和 `symbol` 作为索引签名:
9 |
10 | ```typescript
11 | type K = {
12 | [name: string | number]: string;
13 | };
14 | const k: K = { x: 'x', 1: 'b' };
15 | console.log(k['x']);
16 | console.log(k[1]);
17 | console.log(k['1']); // 同 k[1] 的结果相同
18 | ```
19 |
20 | 请注意,JavaScript 会自动将 `number` 的索引转换相同值的 'string'索引, 比如 `k[1]` 和 `k["1"]` 返回相同值。
21 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/zh-cn/books/Interface and Type.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 接口及类型
3 | sidebar:
4 | order: 46
5 | label: 46. 接口及类型
6 | ---
7 |
8 | ### 通用语法
9 |
10 | 在 TypeScript 中,接口定义对象的结构,指定对象必须具有的属性或方法的名称和类型。在 TypeScript 中定义接口的常用语法如下:
11 |
12 |
13 |
14 | ```typescript
15 | interface InterfaceName {
16 | property1: Type1;
17 | // ...
18 | method1(arg1: ArgType1, arg2: ArgType2): ReturnType;
19 | // ...
20 | }
21 | ```
22 |
23 | 类型定义也类似:
24 |
25 |
26 |
27 | ```typescript
28 | type TypeName = {
29 | property1: Type1;
30 | // ...
31 | method1(arg1: ArgType1, arg2: ArgType2): ReturnType;
32 | // ...
33 | };
34 | ```
35 |
36 | `interface InterfaceName` 或者 `type TypeName`: 定义接口的名称。
37 | `property1`: `Type1`: 指定接口的属性及其相应的类型。可以定义多个属性,每个属性用分号分隔。
38 | `method1(arg1: ArgType1, arg2: ArgType2): ReturnType;`: 指定接口的方法。方法用其名称进行定义,后跟括号中的参数列表和返回类型。可以定义多个方法,每个方法用分号分隔。
39 |
40 | 接口示例:
41 |
42 | ```typescript
43 | interface Person {
44 | name: string;
45 | age: number;
46 | greet(): void;
47 | }
48 | ```
49 |
50 | 类型示例:
51 |
52 | ```typescript
53 | type TypeName = {
54 | property1: string;
55 | method1(arg1: string, arg2: string): string;
56 | };
57 | ```
58 |
59 | 在 TypeScript 中,类型用于定义数据的形状并强制执行类型检查。在 TypeScript 中定义类型有几种常见的语法,具体取决于具体的用例。这里有些例子:
60 |
61 | ### 基本类型
62 |
63 | ```typescript
64 | let myNumber: number = 123; // 数字类型
65 | let myBoolean: boolean = true; // 布尔类型
66 | let myArray: string[] = ['a', 'b']; // 字符串数组
67 | let myTuple: [string, number] = ['a', 123]; // 元组
68 | ```
69 |
70 | ### 对象和接口
71 |
72 | ```typescript
73 | const x: { name: string; age: number } = { name: 'Simon', age: 7 };
74 | ```
75 |
76 | ### 并集和交集类型
77 |
78 | ```typescript
79 | type MyType = string | number; // 并集
80 | let myUnion: MyType = 'hello'; // 可以是字符串
81 | myUnion = 123; // 或者是一个数字
82 |
83 | type TypeA = { name: string };
84 | type TypeB = { age: number };
85 | type CombinedType = TypeA & TypeB; // 交集
86 | let myCombined: CombinedType = { name: 'John', age: 25 }; // 对象同时有name和age属性
87 | ```
88 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/zh-cn/books/Intersection Types.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 交集类型
3 | sidebar:
4 | order: 30
5 | label: 30. 交集类型
6 | ---
7 |
8 | 交集类型是表示具有两种或多种类型的所有属性的值的类型。交叉类型在每种类型之间使用 & 符号表示。
9 |
10 | ```typescript
11 | type X = {
12 | a: string;
13 | };
14 |
15 | type Y = {
16 | b: string;
17 | };
18 |
19 | type J = X & Y; // 交集
20 |
21 | const j: J = {
22 | a: 'a',
23 | b: 'b',
24 | };
25 | ```
26 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/zh-cn/books/Introduction.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 介绍
3 | sidebar:
4 | order: 3
5 | label: 3. 介绍
6 | ---
7 |
8 | 欢迎来到简洁的TypeScript之书!本指南为您提供有效 TypeScript 开发的基本知识和实践技能。发现编写干净、健壮的代码的关键概念和技术。无论您是初学者还是经验丰富的开发人员,本书都可以作为在项目中利用 TypeScript 强大功能的综合指南和便捷参考。
9 |
10 | 本书涵盖了 TypeScript 5.2。
11 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/zh-cn/books/Literal Inference.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 字面量推断
3 | sidebar:
4 | order: 15
5 | label: 15. 字面量推断
6 | ---
7 |
8 | 字面量推断是 TypeScript 中的一项功能,允许根据变量或参数的值推断其类型。
9 |
10 | 在下面的示例中,我们可以看到 TypeScript 认为x文字类型是因为该值以后不能随时更改,而y被推断为字符串,因为它以后可以随时修改。
11 |
12 | ```typescript
13 | const x = 'x'; // x 为字面量类型, 因为值不能改变
14 | let y = 'y'; // string, 我们能改变这个值
15 | ```
16 |
17 | 在下面的示例中,我们可以看到 `o.x` 被推断为 `string`(而不是字面量的a),因为 TypeScript 认为该值可以在以后随时更改。
18 |
19 |
20 |
21 | ```typescript
22 | type X = 'a' | 'b';
23 |
24 | let o = {
25 | x: 'a', // 这是一个更宽的 string
26 | };
27 |
28 | const fn = (x: X) => `${x}-foo`;
29 |
30 | console.log(fn(o.x)); // 'string' 类型的参数不能赋值给 'X' 类型的参数
31 | ```
32 |
33 | 正如你所看到的代码在传递 `o.x` 给 `fn` 作为一个狭窄类型时,抛出了一个错误。
34 |
35 | 我们能通过使用 `const` 或者 `X` 来借助类型推断解决这个问题:
36 |
37 |
38 |
39 | ```typescript
40 | let o = {
41 | x: 'a' as const,
42 | };
43 | ```
44 |
45 | or:
46 |
47 |
48 |
49 | ```typescript
50 | let o = {
51 | x: 'a' as X,
52 | };
53 | ```
54 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/zh-cn/books/Literal Types.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 字面量类型
3 | sidebar:
4 | order: 14
5 | label: 14. 字面量类型
6 | ---
7 |
8 | 文字类型是来自集体类型的单个元素集,它定义了一个非常精确的值,即 JavaScript 原始数据。
9 |
10 | TypeScript 中的文字类型是数字、字符串和布尔值。
11 |
12 | 示例如下:
13 |
14 | ```typescript
15 | const a = 'a'; // 字符串字面量类型
16 | const b = 1; // 数字字面量类型
17 | const c = true; // 布尔字面量类型
18 | ```
19 |
20 | 字符串、数字和布尔字面量类型用于联合、类型保护和类型别名。在下面的示例中,您可以看到类型别名联合,O可以是指定的唯一值,而不是任何其他字符串:
21 |
22 | ```typescript
23 | type O = 'a' | 'b' | 'c';
24 | ```
25 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/zh-cn/books/Mapped Type Modifiers.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 映射类型修饰符
3 | sidebar:
4 | order: 36
5 | label: 36. 映射类型修饰符
6 | ---
7 |
8 | TypeScript 中的映射类型修饰符支持对现有类型中的属性进行转换:
9 |
10 | * `readonly` 或 `+readonly`:这会将映射类型中的属性呈现为只读。
11 | * `-readonly`:这允许映射类型中的属性是可变的。
12 | * `?`:这将映射类型中的属性指定为可选。
13 |
14 | 例子:
15 |
16 | ```typescript
17 | type ReadOnly = { readonly [P in keyof T]: T[P] }; // 所有属性标记为只读
18 |
19 | type Mutable = { -readonly [P in keyof T]: T[P] }; // 所有标记为可变的属性
20 |
21 | type MyPartial = { [P in keyof T]?: T[P] }; // 所有标记为可选的属性
22 | ```
23 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/zh-cn/books/Mapped Types.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 映射类型
3 | sidebar:
4 | order: 35
5 | label: 35. 映射类型
6 | ---
7 |
8 | TypeScript 中的映射类型允许您通过使用映射函数转换每个属性来基于现有类型创建新类型。通过映射现有类型,您可以创建以不同格式表示相同信息的新类型。要创建映射类型,您可以使用运算符访问现有类型的属性 `keyof` ,然后更改它们以生成新类型。在以下示例中:
9 |
10 | ```typescript
11 | type MyMappedType = {
12 | [P in keyof T]: T[P][];
13 | };
14 | type MyType = {
15 | foo: string;
16 | bar: number;
17 | };
18 | type MyNewType = MyMappedType;
19 | const x: MyNewType = {
20 | foo: ['hello', 'world'],
21 | bar: [1, 2, 3],
22 | };
23 | ```
24 |
25 | 我们定义 MyMappedType 来映射 T 的属性,创建一个新类型,其中每个属性都是其原始类型的数组。使用它,我们创建 MyNewType 来表示与 MyType 相同的信息,但每个属性都是一个数组。
26 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/zh-cn/books/Merging and Extension.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 合并与扩展
3 | sidebar:
4 | order: 50
5 | label: 50. 合并与扩展
6 | ---
7 |
8 | 合并和扩展是指与使用类型和接口相关的两个不同概念。
9 |
10 | 合并允许您将多个同名声明合并到一个定义中,例如,当您多次定义同名接口时:
11 |
12 | ```typescript
13 | interface X {
14 | a: string;
15 | }
16 |
17 | interface X {
18 | b: number;
19 | }
20 |
21 | const person: X = {
22 | a: 'a',
23 | b: 7,
24 | };
25 | ```
26 |
27 | 扩展是指扩展或继承现有类型或接口以创建新类型或接口的能力。它是一种向现有类型添加附加属性或方法而不修改其原始定义的机制。例子:
28 |
29 | ```typescript
30 | interface Animal {
31 | name: string;
32 | eat(): void;
33 | }
34 |
35 | interface Bird extends Animal {
36 | sing(): void;
37 | }
38 |
39 | const dog: Bird = {
40 | name: 'Bird 1',
41 | eat() {
42 | console.log('Eating');
43 | },
44 | sing() {
45 | console.log('Singing');
46 | },
47 | };
48 | ```
49 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/zh-cn/books/Named Tuple Type (Labeled).md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 命名元组类型(已标记)
3 | sidebar:
4 | order: 27
5 | label: 27. 命名元组类型(已标记)
6 | ---
7 |
8 | 元组类型可以包含每个元素的可选标签或名称。 这些标签用于提高可读性和工具帮助,不会影响您可以使用它们执行的操作。
9 |
10 | ```typescript
11 | type T = string;
12 | type Tuple1 = [T, T];
13 | type Tuple2 = [a: T, b: T];
14 | type Tuple3 = [a: T, T]; // 命名元组加匿名元组
15 | ```
16 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/zh-cn/books/Namespacing.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 命名空间
3 | sidebar:
4 | order: 55
5 | label: 55. 命名空间
6 | ---
7 |
8 | 在 TypeScript 中,命名空间用于将代码组织到逻辑容器中,防止命名冲突并提供一种将相关代码分组在一起的方法。使用关键字 `export` 允许在"外部"模块中访问名称空间。
9 |
10 | ```typescript
11 | export namespace MyNamespace {
12 | export interface MyInterface1 {
13 | prop1: boolean;
14 | }
15 | export interface MyInterface2 {
16 | prop2: string;
17 | }
18 | }
19 |
20 | const a: MyNamespace.MyInterface1 = {
21 | prop1: true,
22 | };
23 | ```
24 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/zh-cn/books/Narrowing.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 缩小范围
3 | sidebar:
4 | order: 18
5 | label: 18. 缩小范围
6 | ---
7 |
8 | TypeScript 缩小范围是细化条件块内变量类型的过程。这在使用联合类型时很有用,其中一个变量可以有多个类型。
9 |
10 | TypeScript 可识别多种缩小类型范围的方法:
11 |
12 | ### typeof 类型保护
13 |
14 | typeof 类型保护是 TypeScript 中的一种特定类型保护,它根据变量的内置 JavaScript 类型检查变量的类型。
15 |
16 | ```typescript
17 | const fn = (x: number | string) => {
18 | if (typeof x === 'number') {
19 | return x + 1; // x 是数字
20 | }
21 | return -1;
22 | };
23 | ```
24 |
25 | ### 真实性缩小
26 |
27 | TypeScript 中的真实性缩小是通过检查变量是真还是假来相应地缩小其类型来实现的。
28 |
29 | ```typescript
30 | const toUpperCase = (name: string | null) => {
31 | if (name) {
32 | return name.toUpperCase();
33 | } else {
34 | return null;
35 | }
36 | };
37 | ```
38 |
39 | ### 相等缩小
40 |
41 | TypeScript 中的相等缩小通过检查变量是否等于特定值来相应缩小其类型。
42 |
43 | 它与`switch`语句和等号运算符(例如`===`、`!==`、`==`和`!=`)结合使用来缩小类型范围。
44 |
45 | ```typescript
46 | const checkStatus = (status: 'success' | 'error') => {
47 | switch (status) {
48 | case 'success':
49 | return true
50 | case 'error':
51 | return null
52 | }
53 | };
54 | ```
55 |
56 | ### In运算符缩小
57 |
58 | TypeScript 中的 `in` 运算符缩小范围是一种根据变量类型中是否存在属性来缩小变量类型的方法。
59 |
60 | ```typescript
61 | type Dog = {
62 | name: string;
63 | breed: string;
64 | };
65 |
66 | type Cat = {
67 | name: string;
68 | likesCream: boolean;
69 | };
70 |
71 | const getAnimalType = (pet: Dog | Cat) => {
72 | if ('breed' in pet) {
73 | return 'dog';
74 | } else {
75 | return 'cat';
76 | }
77 | };
78 | ```
79 |
80 | ### instanceof 缩小
81 |
82 | TypeScript 中的 `instanceof` 运算符缩小是一种根据变量的构造函数缩小变量类型的方法,方法是检查对象是否是某个类或接口的实例。
83 |
84 | ```typescript
85 | class Square {
86 | constructor(public width: number) {}
87 | }
88 | class Rectangle {
89 | constructor(
90 | public width: number,
91 | public height: number
92 | ) {}
93 | }
94 | function area(shape: Square | Rectangle) {
95 | if (shape instanceof Square) {
96 | return shape.width * shape.width;
97 | } else {
98 | return shape.width * shape.height;
99 | }
100 | }
101 | const square = new Square(5);
102 | const rectangle = new Rectangle(5, 10);
103 | console.log(area(square)); // 25
104 | console.log(area(rectangle)); // 50
105 | ```
106 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/zh-cn/books/Never type.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Never类型
3 | sidebar:
4 | order: 45
5 | label: 45. Never类型
6 | ---
7 |
8 | `never` 类型表示从未出现过的值。它用于表示从不返回或抛出错误的函数或表达式。
9 |
10 | 例如无限循环:
11 |
12 | ```typescript
13 | const infiniteLoop = (): never => {
14 | while (true) {
15 | // 做点什么
16 | }
17 | };
18 | ```
19 |
20 | 抛出错误:
21 |
22 | ```typescript
23 | const throwError = (message: string): never => {
24 | throw new Error(message);
25 | };
26 | ```
27 |
28 | `never` 类型对于确保类型安全和捕获代码中的潜在错误很有用。当与其他类型和控制流语句结合使用时,它可以帮助 TypeScript 分析和推断更精确的类型,例如:
29 |
30 | ```typescript
31 | type Direction = 'up' | 'down';
32 | const move = (direction: Direction): void => {
33 | switch (direction) {
34 | case 'up':
35 | // 向上移动
36 | break;
37 | case 'down':
38 | // 向下移动
39 | break;
40 | default:
41 | const exhaustiveCheck: never = direction;
42 | throw new Error(`Unhandled direction: ${exhaustiveCheck}`);
43 | }
44 | };
45 | ```
46 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/zh-cn/books/Object Types.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 对象类型
3 | sidebar:
4 | order: 25
5 | label: 25. 对象类型
6 | ---
7 |
8 | 在 TypeScript 中,对象类型描述对象的形状。它们指定对象属性的名称和类型,以及这些属性是必需的还是可选的。
9 |
10 | 在 TypeScript 中,您可以通过两种主要方式定义对象类型:
11 |
12 | 通过指定对象属性的名称、类型和可选性来定义对象的形状的接口。
13 |
14 | ```typescript
15 | interface User {
16 | name: string;
17 | age: number;
18 | email?: string;
19 | }
20 | ```
21 |
22 | 类型别名与接口类似,定义了对象的形状。但是,它还可以基于现有类型或现有类型的组合创建新的自定义类型。这包括定义联合类型、交集类型和其他复杂类型。
23 |
24 | ```typescript
25 | type Point = {
26 | x: number;
27 | y: number;
28 | };
29 | ```
30 |
31 | 也可以匿名定义类型:
32 |
33 | ```typescript
34 | const sum = (x: { a: number; b: number }) => x.a + x.b;
35 | console.log(sum({ a: 5, b: 1 }));
36 | ```
37 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/zh-cn/books/Optional Properties.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 可选属性
3 | sidebar:
4 | order: 10
5 | label: 10. 可选属性
6 | ---
7 |
8 | 对象可以通过在属性名称末尾添加问号 `?` 来指定可选属性:
9 |
10 | ```typescript
11 | type X = {
12 | a: number;
13 | b?: number; // 可选的
14 | };
15 | ```
16 |
17 | 当属性是可选的时,可以指定默认值
18 |
19 | ```typescript
20 | type X = {
21 | a: number;
22 | b?: number;
23 | };
24 | const x = ({ a, b = 100 }: X) => a + b;
25 | ```
26 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/zh-cn/books/Overloads.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 重载
3 | sidebar:
4 | order: 49
5 | label: 49. 重载
6 | ---
7 |
8 | TypeScript 中的函数重载允许您为单个函数名称定义多个函数签名,从而使您能够定义可以多种方式调用的函数。这是一个例子:
9 |
10 | ```typescript
11 | // 重载
12 | function sayHi(name: string): string;
13 | function sayHi(names: string[]): string[];
14 |
15 | // 实现
16 | function sayHi(name: unknown): unknown {
17 | if (typeof name === 'string') {
18 | return `Hi, ${name}!`;
19 | } else if (Array.isArray(name)) {
20 | return name.map(name => `Hi, ${name}!`);
21 | }
22 | throw new Error('Invalid value');
23 | }
24 |
25 | sayHi('xx'); // 有效
26 | sayHi(['aa', 'bb']); // 有效
27 | ```
28 |
29 | 这是在 `class` 中使用函数重载的另一个示例:
30 |
31 | ```typescript
32 | class Greeter {
33 | message: string;
34 |
35 | constructor(message: string) {
36 | this.message = message;
37 | }
38 |
39 | // 重载
40 | sayHi(name: string): string;
41 | sayHi(names: string[]): ReadonlyArray;
42 |
43 | // 实现
44 | sayHi(name: unknown): unknown {
45 | if (typeof name === 'string') {
46 | return `${this.message}, ${name}!`;
47 | } else if (Array.isArray(name)) {
48 | return name.map(name => `${this.message}, ${name}!`);
49 | }
50 | throw new Error('value is invalid');
51 | }
52 | }
53 | console.log(new Greeter('Hello').sayHi('Simon'));
54 | ```
55 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/zh-cn/books/Predefined Conditional Types.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 预定义条件类型
3 | sidebar:
4 | order: 40
5 | label: 40. 预定义条件类型
6 | ---
7 |
8 | 在 TypeScript 中,预定义的条件类型是语言提供的内置条件类型。它们旨在根据给定类型的特征执行常见的类型转换。
9 |
10 | `Exclude`: 此类型从 Type 中删除可分配给 ExcludedType 的所有类型。
11 |
12 | `Extract`: 此类型从 Union 中提取可分配给 Type 的所有类型。
13 |
14 | `NonNullable`: 此类型从 Type 中删除 null 和 undefined。
15 |
16 | `ReturnType`: 此类型提取函数 Type 的返回类型。
17 |
18 | `Parameters`: 该类型提取函数类型的参数类型。
19 |
20 | `Required`: 此类型使 Type 中的所有属性成为必需。
21 |
22 | `Partial`: 此类型使 Type 中的所有属性都是可选的。
23 |
24 | `Readonly`: 此类型使 Type 中的所有属性变为只读。
25 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/zh-cn/books/Readonly Properties.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 只读属性
3 | sidebar:
4 | order: 11
5 | label: 11. 只读属性
6 | ---
7 |
8 | 是否可以通过使用修饰符来防止对属性进行写入,`readonly` 以确保该属性不能被重写,但不提供任何完全不变性的保证:
9 |
10 | ```typescript
11 | interface Y {
12 | readonly a: number;
13 | }
14 |
15 | type X = {
16 | readonly a: number;
17 | };
18 |
19 | type J = Readonly<{
20 | a: number;
21 | }>;
22 |
23 | type K = {
24 | readonly [index: number]: string;
25 | };
26 | ```
27 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/zh-cn/books/Symbols.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Symbols
3 | sidebar:
4 | order: 56
5 | label: 56. Symbols
6 | ---
7 |
8 | 符号是一种原始数据类型,表示不可变值,保证在程序的整个生命周期中全局唯一。
9 |
10 | 符号可以用作对象属性的键,并提供一种创建不可枚举属性的方法。
11 |
12 | ```typescript
13 | const key1: symbol = Symbol('key1');
14 | const key2: symbol = Symbol('key2');
15 |
16 | const obj = {
17 | [key1]: 'value 1',
18 | [key2]: 'value 2',
19 | };
20 |
21 | console.log(obj[key1]); // value 1
22 | console.log(obj[key2]); // value 2
23 | ```
24 |
25 | 在 WeakMap 和 WeakSet 中,现在允许符号作为键。
26 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/zh-cn/books/Template Union Types.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 模板联合类型
3 | sidebar:
4 | order: 41
5 | label: 41. 模板联合类型
6 | ---
7 |
8 | 模板联合类型可用于合并和操作类型系统内的文本,例如:
9 |
10 | ```typescript
11 | type Status = 'active' | 'inactive';
12 | type Products = 'p1' | 'p2';
13 | type ProductId = `id-${Products}-${Status}`; // "id-p1-active" | "id-p1-inactive" | "id-p2-active" | "id-p2-inactive"
14 | ```
15 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/zh-cn/books/The Concise TypeScript Book.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 简洁的TypeScript之书
3 | sidebar:
4 | order: 1
5 | label: 1. 简洁的TypeScript之书
6 | ---
7 |
8 | 《Concise TypeScript Book》全面而简洁地概述了 TypeScript 的功能。它提供了清晰的解释,涵盖了该语言最新版本中的所有方面,从强大的类型系统到高级功能。无论您是初学者还是经验丰富的开发人员,本书都是增强您对 TypeScript 的理解和熟练程度的宝贵资源。
9 |
10 | 本书完全免费且开源。
11 |
12 | 如果您发现这本 TypeScript 书籍很有价值并希望做出贡献,请考虑通过 PayPal 支持我的努力。谢谢!
13 |
14 | [](https://www.paypal.com/donate/?business=QW82ZS956XLFY\&no_recurring=0\¤cy_code=EUR)
15 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/zh-cn/books/The never Type.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: never 类型
3 | sidebar:
4 | order: 23
5 | label: 23. never 类型
6 | ---
7 |
8 | 当变量缩小为不能包含任何值的类型时,TypeScript 编译器将推断该变量必须属于该never类型。这是因为 never 类型代表永远无法生成的值。
9 |
10 | ```typescript
11 | const printValue = (val: string | number) => {
12 | if (typeof val === 'string') {
13 | console.log(val.toUpperCase());
14 | } else if (typeof val === 'number') {
15 | console.log(val.toFixed(2));
16 | } else {
17 | // val 在这里的类型为 never,因为它只能是字符串或数字
18 | const neverVal: never = val;
19 | console.log(`Unexpected value: ${neverVal}`);
20 | }
21 | };
22 | ```
23 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/zh-cn/books/Triple-Slash Directives.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 三斜杠指令
3 | sidebar:
4 | order: 57
5 | label: 57. 三斜杠指令
6 | ---
7 |
8 | 三斜杠指令是特殊注释,为编译器提供有关如何处理文件的说明。这些指令以三个连续斜杠 (`///`) 开头,通常放置在 TypeScript 文件的顶部,对运行时行为没有影响。
9 |
10 | 三斜杠指令用于引用外部依赖项、指定模块加载行为、启用/禁用某些编译器功能等等。几个例子:
11 |
12 | 引用声明文件:
13 |
14 |
15 |
16 | ```typescript
17 | ///
18 | ```
19 |
20 | 指明模块格式:
21 |
22 |
23 |
24 | ```typescript
25 | ///
26 | ```
27 |
28 | 启用编译器选项,在以下示例中严格模式:
29 |
30 |
31 |
32 | ```typescript
33 | ///
34 | ```
35 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/zh-cn/books/Tuple Type (Anonymous).md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 元组类型(匿名)
3 | sidebar:
4 | order: 26
5 | label: 26. 元组类型(匿名)
6 | ---
7 |
8 | 元组类型是一种表示具有固定数量的元素及其相应类型的数组的类型。元组类型以固定顺序强制执行特定数量的元素及其各自的类型。当您想要表示具有特定类型的值的集合时,元组类型非常有用,其中数组中每个元素的位置都有特定的含义。
9 |
10 | ```typescript
11 | type Point = [number, number];
12 | ```
13 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/zh-cn/books/Type Annotations.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 类型注释
3 | sidebar:
4 | order: 9
5 | label: 9. 类型注释
6 | ---
7 |
8 | 在使用 `var` 、 `let` 和 `const` 声明变量时,可以选择添加类型:
9 |
10 | ```typescript
11 | const x: number = 1;
12 | ```
13 |
14 | TypeScript 在推断类型方面做得很好,尤其是简单类型时,因此在大多数情况下这些声明是不必要的。
15 |
16 | 在函数上可以向参数添加类型注释:
17 |
18 | ```typescript
19 | function sum(a: number, b: number) {
20 | return a + b;
21 | }
22 | ```
23 |
24 | 以下是使用匿名函数(所谓的 lambda 函数)的示例:
25 |
26 | ```typescript
27 | const sum = (a: number, b: number) => a + b;
28 | ```
29 |
30 | 当参数存在默认值时可以避免这些注释:
31 |
32 | ```typescript
33 | const sum = (a = 10, b: number) => a + b;
34 | ```
35 |
36 | 可以将返回类型注释添加到函数中:
37 |
38 | ```typescript
39 | const sum = (a = 10, b: number): number => a + b;
40 | ```
41 |
42 | 这对于更复杂的函数尤其有用,因为在实现之前编写显式返回类型可以帮助更好地思考该函数。
43 |
44 | 通常考虑注释类型签名,但不注释主体局部变量,并始终将类型添加到对象字面量中。
45 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/zh-cn/books/Type Indexing.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 类型索引
3 | sidebar:
4 | order: 31
5 | label: 31. 类型索引
6 | ---
7 |
8 | 类型索引是指能够通过预先未知的键来定义可以索引的类型,使用索引签名来指定未显式声明的属性的类型。
9 |
10 | ```typescript
11 | type Dictionary = {
12 | [key: string]: T;
13 | };
14 | const myDict: Dictionary = { a: 'a', b: 'b' };
15 | console.log(myDict['a']); // 返回 a
16 | ```
17 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/zh-cn/books/Type Predicates.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 类型谓词
3 | sidebar:
4 | order: 21
5 | label: 21. 类型谓词
6 | ---
7 |
8 | TypeScript 中的类型谓词是返回布尔值的函数,用于将变量的类型缩小为更具体的类型。
9 |
10 | ```typescript
11 | const isString = (value: unknown): value is string => typeof value === 'string';
12 |
13 | const foo = (bar: unknown) => {
14 | if (isString(bar)) {
15 | console.log(bar.toUpperCase());
16 | } else {
17 | console.log('not a string');
18 | }
19 | };
20 | ```
21 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/zh-cn/books/Type from Func Return.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Func 返回值的类型
3 | sidebar:
4 | order: 33
5 | label: 33. Func 返回值的类型
6 | ---
7 |
8 | Func Return 中的类型是指根据函数的实现自动推断函数的返回类型的能力。这允许 TypeScript 无需显式类型注释即可确定函数返回值的类型。
9 |
10 | ```typescript
11 | const add = (x: number, y: number) => x + y; // TypeScript 可以推断函数的返回类型是数字
12 | ```
13 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/zh-cn/books/Type from Module.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 模块的类型
3 | sidebar:
4 | order: 34
5 | label: 34. 模块的类型
6 | ---
7 |
8 | 模块的类型是指使用模块的导出值自动推断其类型的能力。当模块导出特定类型的值时,TypeScript 可以使用该信息在将该值导入到另一个模块时自动推断该值的类型。
9 |
10 |
11 |
12 | ```typescript
13 | export const add = (x: number, y: number) => x + y;
14 | // index.ts
15 | import { add } from 'calc';
16 | const r = add(1, 2); // r 是 number 类型
17 | ```
18 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/zh-cn/books/Type from Value.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 值的类型
3 | sidebar:
4 | order: 32
5 | label: 32. 值的类型
6 | ---
7 |
8 | TypeScript 中的"Type from Value"是指通过类型推断从值或表达式自动推断出类型。
9 |
10 | ```typescript
11 | const x = 'x'; // TypeScript 可以自动推断变量的类型是 string
12 | ```
13 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/zh-cn/books/Union Type.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 联合类型
3 | sidebar:
4 | order: 29
5 | label: 29. 联合类型
6 | ---
7 |
8 | 联合类型是一种表示值的类型,该值可以是多种类型之一。联合类型使用 `|` 表示 每种可能类型之间的符号。
9 |
10 | ```typescript
11 | let x: string | number;
12 | x = 'hello'; // 有效
13 | x = 123; // 有效
14 | ```
15 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/zh-cn/books/Unknown type.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 未知类型
3 | sidebar:
4 | order: 43
5 | label: 43. 未知类型
6 | ---
7 |
8 | 在 TypeScript 中,未知类型表示未知类型的值。与允许任何类型值的 `any` 类型不同,`unknown` 需要在以特定方式使用它之前进行类型检查或断言,因此在未首先断言或缩小到更具体的类型的情况下,不允许对 `unknown` 进行任何操作 。
9 |
10 | `unknown` 类型只能分配给任何类型和未知类型本身,它是any 的类型安全替代方案。
11 |
12 |
13 |
14 | ```typescript
15 | let value: unknown;
16 |
17 | let value1: unknown = value; // 有效
18 | let value2: any = value; // 有效
19 | let value3: boolean = value; // 无效
20 | let value4: number = value; // 无效
21 | ```
22 |
23 | ```typescript
24 | const add = (a: unknown, b: unknown): number | undefined =>
25 | typeof a === 'number' && typeof b === 'number' ? a + b : undefined;
26 | console.log(add(1, 2)); // 3
27 | console.log(add('x', 2)); // undefined
28 | ```
29 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/zh-cn/books/Void type.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 空类型
3 | sidebar:
4 | order: 44
5 | label: 44. 空类型
6 | ---
7 |
8 | `void` 类型用于指示函数不返回值。
9 |
10 | ```typescript
11 | const sayHello = (): void => {
12 | console.log('Hello!');
13 | };
14 | ```
15 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/zh-cn/books/infer Type Inference in Conditional Types.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: infer 条件类型中的类型推断
3 | sidebar:
4 | order: 39
5 | label: 39. infer 条件类型中的类型推断
6 | ---
7 |
8 | `infer` 关键字在条件类型中使用,用于从依赖于泛型参数的类型中推断(提取)泛型参数的类型。这允许您编写更灵活且可重用的类型定义。
9 |
10 | ```typescript
11 | type ElementType = T extends (infer U)[] ? U : never;
12 | type Numbers = ElementType; // number
13 | type Strings = ElementType; // string
14 | ```
15 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/zh-cn/books/strictNullChecks.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 严格空检查
3 | sidebar:
4 | order: 16
5 | label: 16. 严格空检查
6 | ---
7 |
8 | `strictNullChecks` 是一个 TypeScript 编译器选项,强制执行严格的 null 检查。启用此选项后,只有在变量和参数已使用联合类型 `null` | `undefined` 显式声明为该类型时,才可以对其进行赋值`null` 或者 `undefined`。如果变量或参数未显式声明为可为空,TypeScript 将生成错误以防止潜在的运行时错误。
9 |
--------------------------------------------------------------------------------
/website-astro/src/content/docs/zh-cn/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Typescript Book
3 | description: The Concise TypeScript Book
4 | template: splash
5 | hero:
6 | tagline:
7 | 《Concise TypeScript Book》全面而简洁地概述了 TypeScript
8 | 的功能。它提供了清晰的解释,涵盖了该语言最新版本中的所有方面,从强大的类型系统到高级功能。无论您是初学者还是经验丰富的开发人员,本书都是增强您对
9 | TypeScript 的理解和熟练程度的宝贵资源。
本书完全免费且开源。
10 | actions:
11 | - text: 开始阅读!
12 | link: /zh-cn/books/the-concise-typescript-book/
13 | icon: right-arrow
14 | variant: primary
15 | ---
16 |
--------------------------------------------------------------------------------
/website-astro/src/env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 | ///
3 |
--------------------------------------------------------------------------------
/website-astro/src/styles/global.css:
--------------------------------------------------------------------------------
1 | :root {
2 | --sl-color-text-accent: #3178c6;
3 | --sl-color-text-invert: #fff;
4 | }
5 |
--------------------------------------------------------------------------------
/website-astro/tailwind.config.ts:
--------------------------------------------------------------------------------
1 | import type { Config } from 'tailwindcss'
2 |
3 | import starlightPlugin from '@astrojs/starlight-tailwind'
4 |
5 | export default {
6 | content: ['./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}', 'node_modules/@color-kit/**/*'],
7 | plugins: [starlightPlugin()],
8 | theme: {
9 | extend: {},
10 | },
11 | } satisfies Config
12 |
--------------------------------------------------------------------------------
/website-astro/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "astro/tsconfigs/strict",
3 | "compilerOptions": {
4 | "baseUrl": ".",
5 | "paths": {
6 | "@color-kit/crystal": ["../../packages/crystal/src"]
7 | }
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/website/.gitignore:
--------------------------------------------------------------------------------
1 | # build output
2 | dist/
3 | # generated types
4 | .astro/
5 |
6 | # dependencies
7 | node_modules/
8 |
9 | # logs
10 | npm-debug.log*
11 | yarn-debug.log*
12 | yarn-error.log*
13 | pnpm-debug.log*
14 |
15 |
16 | # environment variables
17 | .env
18 | .env.production
19 |
20 | # macOS-specific files
21 | .DS_Store
22 |
--------------------------------------------------------------------------------
/website/.nvmrc:
--------------------------------------------------------------------------------
1 | v19.7.0
2 |
--------------------------------------------------------------------------------
/website/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "trailingComma": "es5",
3 | "tabWidth": 4,
4 | "semi": true,
5 | "singleQuote": true,
6 | "printWidth": 80,
7 | "arrowParens": "avoid"
8 | }
--------------------------------------------------------------------------------
/website/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": ["astro-build.astro-vscode"],
3 | "unwantedRecommendations": []
4 | }
5 |
--------------------------------------------------------------------------------
/website/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "0.2.0",
3 | "configurations": [
4 | {
5 | "command": "./node_modules/.bin/astro dev",
6 | "name": "Development server",
7 | "request": "launch",
8 | "type": "node-terminal"
9 | }
10 | ]
11 | }
12 |
--------------------------------------------------------------------------------
/website/README.md:
--------------------------------------------------------------------------------
1 | # Starlight Starter Kit: Basics
2 |
3 | [](https://starlight.astro.build)
4 |
5 | ```
6 | npm create astro@latest -- --template starlight
7 | ```
8 |
9 | [](https://stackblitz.com/github/withastro/starlight/tree/main/examples/basics)
10 | [](https://codesandbox.io/p/sandbox/github/withastro/starlight/tree/main/examples/basics)
11 | [](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fwithastro%2Fstarlight%2Ftree%2Fmain%2Fexamples%2Fbasics&project-name=my-starlight-docs&repository-name=my-starlight-docs)
12 |
13 | > 🧑🚀 **Seasoned astronaut?** Delete this file. Have fun!
14 |
15 | ## 🚀 Project Structure
16 |
17 | Inside of your Astro + Starlight project, you'll see the following folders and files:
18 |
19 | ```
20 | .
21 | ├── public/
22 | ├── src/
23 | │ ├── assets/
24 | │ ├── content/
25 | │ │ ├── docs/
26 | │ │ └── config.ts
27 | │ └── env.d.ts
28 | ├── astro.config.mjs
29 | ├── package.json
30 | └── tsconfig.json
31 | ```
32 |
33 | Starlight looks for `.md` or `.mdx` files in the `src/content/docs/` directory. Each file is exposed as a route based on its file name.
34 |
35 | Images can be added to `src/assets/` and embedded in Markdown with a relative link.
36 |
37 | Static assets, like favicons, can be placed in the `public/` directory.
38 |
39 | ## 🧞 Commands
40 |
41 | All commands are run from the root of the project, from a terminal:
42 |
43 | | Command | Action |
44 | | :------------------------ | :----------------------------------------------- |
45 | | `npm install` | Installs dependencies |
46 | | `npm run dev` | Starts local dev server at `localhost:4321` |
47 | | `npm run build` | Build your production site to `./dist/` |
48 | | `npm run preview` | Preview your build locally, before deploying |
49 | | `npm run astro ...` | Run CLI commands like `astro add`, `astro check` |
50 | | `npm run astro -- --help` | Get help using the Astro CLI |
51 |
52 | ## 👀 Want to learn more?
53 |
54 | Check out [Starlight’s docs](https://starlight.astro.build/), read [the Astro documentation](https://docs.astro.build), or jump into the [Astro Discord server](https://astro.build/chat).
55 |
--------------------------------------------------------------------------------
/website/astro.config.mjs:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'astro/config';
2 | import starlight from '@astrojs/starlight';
3 |
4 | // https://astro.build/config
5 | export default defineConfig({
6 | site: 'https://gibbok.github.io',
7 | base: '/typescript-book',
8 | build: {
9 | assets: 'app_assets',
10 | },
11 | integrations: [
12 | starlight({
13 | title: 'TypeScript Book',
14 | customCss: ['./src/styles/custom.css'],
15 | social: {
16 | github: 'https://github.com/gibbok/typescript-book',
17 | 'x.com': 'https://twitter.com/gibbok_coding',
18 | },
19 | defaultLocale: 'root',
20 | locales: {
21 | root: {
22 | label: 'English',
23 | lang: 'en',
24 | },
25 | 'zh-cn': {
26 | label: '简体中文',
27 | lang: 'zh-CN',
28 | },
29 | },
30 | sidebar: [
31 | {
32 | label: 'TypeScript Book',
33 | autogenerate: { directory: 'book' },
34 | },
35 | ],
36 | }),
37 | ],
38 | });
39 |
--------------------------------------------------------------------------------
/website/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "website",
3 | "type": "module",
4 | "version": "0.0.1",
5 | "scripts": {
6 | "dev": "astro dev",
7 | "start": "astro dev",
8 | "build": "astro check && astro build",
9 | "preview": "astro preview",
10 | "astro": "astro",
11 | "deploy": "npm run build && npx gh-pages -d dist"
12 | },
13 | "dependencies": {
14 | "@astrojs/check": "^0.4.1",
15 | "@astrojs/starlight": "^0.15.3",
16 | "astro": "^4.0.1",
17 | "sharp": "^0.32.5",
18 | "typescript": "^5.3.3"
19 | },
20 | "devDependencies": {
21 | "gh-pages": "^6.1.1"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/website/public/favicon.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/website/src/assets/houston.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nnecec/typescript-book/f042af63e3471f5dc7e8f1450f87e0f57398f5e9/website/src/assets/houston.webp
--------------------------------------------------------------------------------
/website/src/content/config.ts:
--------------------------------------------------------------------------------
1 | import { defineCollection } from 'astro:content';
2 | import { docsSchema, i18nSchema } from '@astrojs/starlight/schema';
3 |
4 | export const collections = {
5 | docs: defineCollection({ schema: docsSchema() }),
6 | i18n: defineCollection({ type: 'data', schema: i18nSchema() }),
7 | };
8 |
--------------------------------------------------------------------------------
/website/src/content/docs/book/about-the-author.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: About the Author
3 | sidebar:
4 | order: 6
5 | label: 6. About the Author
6 | ---
7 |
8 |
9 | Simone Poggiali is an experienced Senior Front-end Developer with a passion for writing professional-grade code since the 90s. Throughout his international career, he has contributed to numerous projects for a wide range of clients, from startups to large organizations. Notable companies such as HelloFresh, Siemens, O2, and Leroy Merlin have benefited from his expertise and dedication.
10 |
11 | You can reach Simone Poggiali on the following platforms:
12 |
13 | * LinkedIn: [https://www.linkedin.com/in/simone-poggiali](https://www.linkedin.com/in/simone-poggiali)
14 | * GitHub: [https://github.com/gibbok](https://github.com/gibbok)
15 | * X.com: [https://x.com/gibbok_coding](https://x.com/gibbok_coding)
16 | * Email: gibbok.coding📧gmail.com
17 |
18 |
--------------------------------------------------------------------------------
/website/src/content/docs/book/any-type.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Any type
3 | sidebar:
4 | order: 44
5 | label: 44. Any type
6 | ---
7 |
8 |
9 | The `any` type is a special type (universal supertype) that can be used to represent any type of value (primitives, objects, arrays, functions, errors, symbols). It is often used in situations where the type of a value is not known at compile time, or when working with values from external APIs or libraries that do not have TypeScript typings.
10 |
11 | By utilizing `any` type, you are indicating to the TypeScript compiler that values should be represented without any limitations. In order to maximizing type safety in your code consider the following:
12 |
13 | * Limit the usage of `any` to specific cases where the type is truly unknown.
14 | * Do not return `any` types from a function as you will lose type safety in the code using that function weakening your type safety.
15 | * Instead of `any` use `@ts-ignore` if you need to silence the compiler.
16 |
17 | ```typescript
18 | let value: any;
19 | value = true; // Valid
20 | value = 7; // Valid
21 | ```
22 |
23 |
--------------------------------------------------------------------------------
/website/src/content/docs/book/assignments.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Assignments
3 | sidebar:
4 | order: 21
5 | label: 21. Assignments
6 | ---
7 |
8 |
9 | TypeScript narrowing using assignments is a way to narrow the type of a variable based on the value assigned to it. When a variable is assigned a value, TypeScript infers its type based on the assigned value, and it narrows the type of the variable to match the inferred type.
10 |
11 | ```typescript
12 | let value: string | number;
13 | value = 'hello';
14 | if (typeof value === 'string') {
15 | console.log(value.toUpperCase());
16 | }
17 | value = 42;
18 | if (typeof value === 'number') {
19 | console.log(value.toFixed(2));
20 | }
21 | ```
22 |
23 |
--------------------------------------------------------------------------------
/website/src/content/docs/book/built-in-type-primitives.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Built-in Type Primitives
3 | sidebar:
4 | order: 49
5 | label: 49. Built-in Type Primitives
6 | ---
7 |
8 |
9 | TypeScript has several built-in type primitives that can be used to define variables, function parameters, and return types:
10 |
11 | * `number`: Represents numeric values, including integers and floating-point numbers.
12 | * `string`: Represents textual data
13 | * `boolean`: Represents logical values, which can be either true or false.
14 | * `null`: Represents the absence of a value.
15 | * `undefined`: Represents a value that has not been assigned or has not been defined.
16 | * `symbol`: Represents a unique identifier. Symbols are typically used as keys for object properties.
17 | * `bigint`: Represents arbitrary-precision integers.
18 | * `any`: Represents a dynamic or unknown type. Variables of type any can hold values of any type, and they bypass type checking.
19 | * `void`: Represents the absence of any type. It is commonly used as the return type of functions that do not return a value.
20 | * `never`: Represents a type for values that never occur. It is typically used as the return type of functions that throw an error or enter an infinite loop.
21 |
22 |
--------------------------------------------------------------------------------
/website/src/content/docs/book/common-built-in-js-objects.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Common Built-in JS Objects
3 | sidebar:
4 | order: 50
5 | label: 50. Common Built-in JS Objects
6 | ---
7 |
8 |
9 | TypeScript is a superset of JavaScript, it includes all the commonly used built-in JavaScript objects. You can find an extensive list of these objects on the Mozilla Developer Network (MDN) documentation website:
10 | [https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects)
11 |
12 | Here is a list of some commonly used built-in JavaScript objects:
13 |
14 | * Function
15 | * Object
16 | * Boolean
17 | * Error
18 | * Number
19 | * BigInt
20 | * Math
21 | * Date
22 | * String
23 | * RegExp
24 | * Array
25 | * Map
26 | * Set
27 | * Promise
28 | * Intl
29 |
30 |
--------------------------------------------------------------------------------
/website/src/content/docs/book/conditional-types.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Conditional Types
3 | sidebar:
4 | order: 39
5 | label: 39. Conditional Types
6 | ---
7 |
8 |
9 | Conditional Types are a way to create a type that depends on a condition, where the type to be created is determined based on the result of the condition. They are defined using the `extends` keyword and a ternary operator to conditionally choose between two types.
10 |
11 | ```typescript
12 | type IsArray = T extends any[] ? true : false;
13 |
14 | const myArray = [1, 2, 3];
15 | const myNumber = 42;
16 |
17 | type IsMyArrayAnArray = IsArray; // Type true
18 | type IsMyNumberAnArray = IsArray; // Type false
19 | ```
20 |
21 |
--------------------------------------------------------------------------------
/website/src/content/docs/book/control-flow-analysis.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Control Flow Analysis
3 | sidebar:
4 | order: 22
5 | label: 22. Control Flow Analysis
6 | ---
7 |
8 |
9 | Control Flow Analysis in TypeScript is a way to statically analyze the code flow to infer the types of variables, allowing the compiler to narrow the types of those variables as needed, based on the results of the analysis.
10 |
11 | Prior to TypeScript 4.4, code flow analysis would only be applied to code within an if statement, but from TypeScript 4.4, it can also be applied to conditional expressions and discriminant property accesses indirectly referenced through const variables.
12 |
13 | For example:
14 |
15 | ```typescript
16 | const f1 = (x: unknown) => {
17 | const isString = typeof x === 'string';
18 | if (isString) {
19 | x.length;
20 | }
21 | };
22 |
23 | const f2 = (
24 | obj: { kind: 'foo'; foo: string } | { kind: 'bar'; bar: number }
25 | ) => {
26 | const isFoo = obj.kind === 'foo';
27 | if (isFoo) {
28 | obj.foo;
29 | } else {
30 | obj.bar;
31 | }
32 | };
33 | ```
34 |
35 | Some examples where narrowing does not occur:
36 |
37 |
38 | ```typescript
39 | const f1 = (x: unknown) => {
40 | let isString = typeof x === 'string';
41 | if (isString) {
42 | x.length; // Error, no narrowing because isString it is not const
43 | }
44 | };
45 |
46 | const f6 = (
47 | obj: { kind: 'foo'; foo: string } | { kind: 'bar'; bar: number }
48 | ) => {
49 | const isFoo = obj.kind === 'foo';
50 | obj = obj;
51 | if (isFoo) {
52 | obj.foo; // Error, no narrowing because obj is assigned in function body
53 | }
54 | };
55 | ```
56 |
57 | Notes: Up to five levels of indirection are analyzed in conditional expressions.
58 |
59 |
--------------------------------------------------------------------------------
/website/src/content/docs/book/differences-between-type-and-interface.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Differences between Type and Interface
3 | sidebar:
4 | order: 53
5 | label: 53. Differences between Type and Interface
6 | ---
7 |
8 |
9 | Declaration merging (augmentation):
10 |
11 | Interfaces support declaration merging, which means that you can define multiple interfaces with the same name, and TypeScript will merge them into a single interface with the combined properties and methods. On the other hand, types do not support declaration merging. This can be helpful when you want to add extra functionality or customize existing types without modifying the original definitions or patching missing or incorrect types.
12 |
13 | ```typescript
14 | interface A {
15 | x: string;
16 | }
17 | interface A {
18 | y: string;
19 | }
20 | const j: A = {
21 | x: 'xx',
22 | y: 'yy',
23 | };
24 | ```
25 |
26 | Extending other types/interfaces:
27 |
28 | Both types and interfaces can extend other types/interfaces, but the syntax is different. With interfaces, you use the `extends` keyword to inherit properties and methods from other interfaces. However, an interface cannot extend a complex type like a union type.
29 |
30 | ```typescript
31 | interface A {
32 | x: string;
33 | y: number;
34 | }
35 | interface B extends A {
36 | z: string;
37 | }
38 | const car: B = {
39 | x: 'x',
40 | y: 123,
41 | z: 'z',
42 | };
43 | ```
44 |
45 | For types, you use the & operator to combine multiple types into a single type (intersection).
46 |
47 | ```typescript
48 | interface A {
49 | x: string;
50 | y: number;
51 | }
52 |
53 | type B = A & {
54 | j: string;
55 | };
56 |
57 | const c: B = {
58 | x: 'x',
59 | y: 123,
60 | j: 'j',
61 | };
62 | ```
63 |
64 | Union and Intersection Types:
65 |
66 | Types are more flexible when it comes to defining Union and Intersection Types. With the `type` keyword, you can easily create union types using the `|` operator and intersection types using the `&` operator. While interfaces can also represent union types indirectly, they don't have built-in support for intersection types.
67 |
68 | ```typescript
69 | type Department = 'dep-x' | 'dep-y'; // Union
70 |
71 | type Person = {
72 | name: string;
73 | age: number;
74 | };
75 |
76 | type Employee = {
77 | id: number;
78 | department: Department;
79 | };
80 |
81 | type EmployeeInfo = Person & Employee; // Intersection
82 | ```
83 |
84 | Example with interfaces:
85 |
86 | ```typescript
87 | interface A {
88 | x: 'x';
89 | }
90 | interface B {
91 | y: 'y';
92 | }
93 |
94 | type C = A | B; // Union of interfaces
95 | ```
96 |
97 |
--------------------------------------------------------------------------------
/website/src/content/docs/book/discriminated-unions.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Discriminated Unions
3 | sidebar:
4 | order: 24
5 | label: 24. Discriminated Unions
6 | ---
7 |
8 |
9 | Discriminated Unions in TypeScript are a type of union type that uses a common property, known as the discriminant, to narrow down the set of possible types for the union.
10 |
11 | ```typescript
12 | type Square = {
13 | kind: 'square'; // Discriminant
14 | size: number;
15 | };
16 |
17 | type Circle = {
18 | kind: 'circle'; // Discriminant
19 | radius: number;
20 | };
21 |
22 | type Shape = Square | Circle;
23 |
24 | const area = (shape: Shape) => {
25 | switch (shape.kind) {
26 | case 'square':
27 | return Math.pow(shape.size, 2);
28 | case 'circle':
29 | return Math.PI * Math.pow(shape.radius, 2);
30 | }
31 | };
32 |
33 | const square: Square = { kind: 'square', size: 5 };
34 | const circle: Circle = { kind: 'circle', radius: 2 };
35 |
36 | console.log(area(square)); // 25
37 | console.log(area(circle)); // 12.566370614359172
38 | ```
39 |
40 |
--------------------------------------------------------------------------------
/website/src/content/docs/book/distributive-conditional-types.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Distributive Conditional Types
3 | sidebar:
4 | order: 40
5 | label: 40. Distributive Conditional Types
6 | ---
7 |
8 |
9 | Distributive Conditional Types are a feature that allow a type to be distributed over a union of types, by applying a transformation to each member of the union individually.
10 | This can be especially useful when working with mapped types or higher-order types.
11 |
12 | ```typescript
13 | type Nullable = T extends any ? T | null : never;
14 | type NumberOrBool = number | boolean;
15 | type NullableNumberOrBool = Nullable; // number | boolean | null
16 | ```
17 |
18 |
--------------------------------------------------------------------------------
/website/src/content/docs/book/downloads-and-website.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Downloads and website
3 | sidebar:
4 | order: 3
5 | label: 3. Downloads and website
6 | ---
7 |
8 |
9 | You can also download the Epub version:
10 |
11 | [https://github.com/gibbok/typescript-book/tree/main/downloads](https://github.com/gibbok/typescript-book/tree/main/downloads)
12 |
13 | An online version is available at:
14 |
15 | [https://gibbok.github.io/typescript-book](https://gibbok.github.io/typescript-book)
16 |
17 |
--------------------------------------------------------------------------------
/website/src/content/docs/book/erased-structural-types.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Erased Structural Types
3 | sidebar:
4 | order: 56
5 | label: 56. Erased Structural Types
6 | ---
7 |
8 |
9 | In TypeScript, objects do not have to match a specific, exact type. For instance, if we create an object that fulfills an interface's requirements, we can utilize that object in places where that interface is required, even if there was no explicit connection between them.
10 | Example:
11 |
12 | ```typescript
13 | type NameProp1 = {
14 | prop1: string;
15 | };
16 |
17 | function log(x: NameProp1) {
18 | console.log(x.prop1);
19 | }
20 |
21 | const obj = {
22 | prop2: 123,
23 | prop1: 'Origin',
24 | };
25 |
26 | log(obj); // Valid
27 | ```
28 |
29 |
--------------------------------------------------------------------------------
/website/src/content/docs/book/exhaustiveness-checking.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Exhaustiveness checking
3 | sidebar:
4 | order: 26
5 | label: 26. Exhaustiveness checking
6 | ---
7 |
8 |
9 | Exhaustiveness checking is a feature in TypeScript that ensures all possible cases of a discriminated union are handled in a `switch` statement or an `if` statement.
10 |
11 | ```typescript
12 | type Direction = 'up' | 'down';
13 |
14 | const move = (direction: Direction) => {
15 | switch (direction) {
16 | case 'up':
17 | console.log('Moving up');
18 | break;
19 | case 'down':
20 | console.log('Moving down');
21 | break;
22 | default:
23 | const exhaustiveCheck: never = direction;
24 | console.log(exhaustiveCheck); // This line will never be executed
25 | }
26 | };
27 | ```
28 |
29 | The `never` type is used to ensure that the default case is exhaustive and that TypeScript will raise an error if a new value is added to the Direction type without being handled in the switch statement.
30 |
31 |
--------------------------------------------------------------------------------
/website/src/content/docs/book/extending-types.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Extending Types
3 | sidebar:
4 | order: 15
5 | label: 15. Extending Types
6 | ---
7 |
8 |
9 | It is possible to extend an `interface` (copy members from another type):
10 |
11 | ```typescript
12 | interface X {
13 | a: string;
14 | }
15 | interface Y extends X {
16 | b: string;
17 | }
18 | ```
19 |
20 | It is also possible to extend from multiple types:
21 |
22 | ```typescript
23 | interface A {
24 | a: string;
25 | }
26 | interface B {
27 | b: string;
28 | }
29 | interface Y extends A, B {
30 | y: string;
31 | }
32 | ```
33 |
34 | The `extends` keyword works only on interfaces and classes, for types use an intersection:
35 |
36 | ```typescript
37 | type A = {
38 | a: number;
39 | };
40 | type B = {
41 | b: number;
42 | };
43 | type C = A & B;
44 | ```
45 |
46 | It is possible to extend a type using an inference but not vice versa:
47 |
48 | ```typescript
49 | type A = {
50 | a: string;
51 | };
52 | interface B extends A {
53 | b: string;
54 | }
55 | ```
56 |
57 |
--------------------------------------------------------------------------------
/website/src/content/docs/book/fixed-length-tuple.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Fixed Length Tuple
3 | sidebar:
4 | order: 30
5 | label: 30. Fixed Length Tuple
6 | ---
7 |
8 |
9 | A Fixed Length Tuple is a specific type of tuple that enforces a fixed number of elements of specific types, and disallows any modifications to the length of the tuple once it is defined.
10 |
11 | Fixed Length Tuples are useful when you need to represent a collection of values with a specific number of elements and specific types, and you want to ensure that the length and types of the tuple cannot be changed inadvertently.
12 |
13 |
14 | ```typescript
15 | const x = [10, 'hello'] as const;
16 | x.push(2); // Error
17 | ```
18 |
19 |
--------------------------------------------------------------------------------
/website/src/content/docs/book/index-signatures.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Index Signatures
3 | sidebar:
4 | order: 14
5 | label: 14. Index Signatures
6 | ---
7 |
8 |
9 | In TypeScript we can use as index signature `string`, `number`, and `symbol`:
10 |
11 | ```typescript
12 | type K = {
13 | [name: string | number]: string;
14 | };
15 | const k: K = { x: 'x', 1: 'b' };
16 | console.log(k['x']);
17 | console.log(k[1]);
18 | console.log(k['1']); // Same result as k[1]
19 | ```
20 |
21 | Please note that JavaScript automatically converts an index with `number` to an index with `string` so `k[1]` or `k["1"]` return the same value.
22 |
23 |
--------------------------------------------------------------------------------
/website/src/content/docs/book/infer-type-inference-in-conditional-types.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: infer Type Inference in Conditional Types
3 | sidebar:
4 | order: 41
5 | label: 41. infer Type Inference in Conditional Types
6 | ---
7 |
8 |
9 | The `infer`keyword is used in conditional types to infer (extract) the type of a generic parameter from a type that depends on it. This allows you to write more flexible and reusable type definitions.
10 |
11 | ```typescript
12 | type ElementType = T extends (infer U)[] ? U : never;
13 | type Numbers = ElementType; // number
14 | type Strings = ElementType; // string
15 | ```
16 |
17 |
--------------------------------------------------------------------------------
/website/src/content/docs/book/interface-and-type.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Interface and Type
3 | sidebar:
4 | order: 48
5 | label: 48. Interface and Type
6 | ---
7 |
8 |
9 | ### Common Syntax
10 |
11 | In TypeScript, interfaces define the structure of objects, specifying the names and types of properties or methods that an object must have. The common syntax for defining an interface in TypeScript is as follows:
12 |
13 |
14 | ```typescript
15 | interface InterfaceName {
16 | property1: Type1;
17 | // ...
18 | method1(arg1: ArgType1, arg2: ArgType2): ReturnType;
19 | // ...
20 | }
21 | ```
22 |
23 | Similarly for type definition:
24 |
25 |
26 | ```typescript
27 | type TypeName = {
28 | property1: Type1;
29 | // ...
30 | method1(arg1: ArgType1, arg2: ArgType2): ReturnType;
31 | // ...
32 | };
33 | ```
34 |
35 | `interface InterfaceName` or `type TypeName`: Defines the name of the interface.
36 | `property1`: `Type1`: Specifies the properties of the interface along with their corresponding types. Multiple properties can be defined, each separated by a semicolon.
37 | `method1(arg1: ArgType1, arg2: ArgType2): ReturnType;`: Specifies the methods of the interface. Methods are defined with their names, followed by a parameter list in parentheses and the return type. Multiple methods can be defined, each separated by a semicolon.
38 |
39 | Example interface:
40 |
41 | ```typescript
42 | interface Person {
43 | name: string;
44 | age: number;
45 | greet(): void;
46 | }
47 | ```
48 |
49 | Example of type:
50 |
51 | ```typescript
52 | type TypeName = {
53 | property1: string;
54 | method1(arg1: string, arg2: string): string;
55 | };
56 | ```
57 |
58 | In TypeScript, types are used to define the shape of data and enforce type checking. There are several common syntaxes for defining types in TypeScript, depending on the specific use case. Here are some examples:
59 |
60 | ### Basic Types
61 |
62 | ```typescript
63 | let myNumber: number = 123; // number type
64 | let myBoolean: boolean = true; // boolean type
65 | let myArray: string[] = ['a', 'b']; // array of strings
66 | let myTuple: [string, number] = ['a', 123]; // tuple
67 | ```
68 |
69 | ### Objects and Interfaces
70 |
71 | ```typescript
72 | const x: { name: string; age: number } = { name: 'Simon', age: 7 };
73 | ```
74 |
75 | ### Union and Intersection Types
76 |
77 | ```typescript
78 | type MyType = string | number; // Union type
79 | let myUnion: MyType = 'hello'; // Can be a string
80 | myUnion = 123; // Or a number
81 |
82 | type TypeA = { name: string };
83 | type TypeB = { age: number };
84 | type CombinedType = TypeA & TypeB; // Intersection type
85 | let myCombined: CombinedType = { name: 'John', age: 25 }; // Object with both name and age properties
86 | ```
87 |
88 |
--------------------------------------------------------------------------------
/website/src/content/docs/book/intersection-types.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Intersection Types
3 | sidebar:
4 | order: 32
5 | label: 32. Intersection Types
6 | ---
7 |
8 |
9 | An Intersection Type is a type that represents a value that has all the properties of two or more types. Intersection Types are denoted using the `&` symbol between each type.
10 |
11 | ```typescript
12 | type X = {
13 | a: string;
14 | };
15 |
16 | type Y = {
17 | b: string;
18 | };
19 |
20 | type J = X & Y; // Intersection
21 |
22 | const j: J = {
23 | a: 'a',
24 | b: 'b',
25 | };
26 | ```
27 |
28 |
--------------------------------------------------------------------------------
/website/src/content/docs/book/introduction.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Introduction
3 | sidebar:
4 | order: 5
5 | label: 5. Introduction
6 | ---
7 |
8 |
9 | Welcome to The Concise TypeScript Book! This guide equips you with essential knowledge and practical skills for effective TypeScript development. Discover key concepts and techniques to write clean, robust code. Whether you're a beginner or an experienced developer, this book serves as both a comprehensive guide and a handy reference for leveraging TypeScript's power in your projects.
10 |
11 | This book covers TypeScript 5.2.
12 |
13 |
--------------------------------------------------------------------------------
/website/src/content/docs/book/literal-inference.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Literal Inference
3 | sidebar:
4 | order: 17
5 | label: 17. Literal Inference
6 | ---
7 |
8 |
9 | Literal Inference is a feature in TypeScript that allows the type of a variable or parameter to be inferred based on its value.
10 |
11 | In the following example we can see that TypeScript considers `x` a literal type as the value cannot be changed any time later, when instead `y` is inferred as string as it can be modified any time later.
12 |
13 | ```typescript
14 | const x = 'x'; // Literal type of 'x', because this value cannot be changed
15 | let y = 'y'; // Type string, as we can change this value
16 | ```
17 |
18 | In the following example we can see that `o.x` was inferred as a `string` (and not a literal of `a`) as TypeScript considers that the value can be changed any time later.
19 |
20 |
21 | ```typescript
22 | type X = 'a' | 'b';
23 |
24 | let o = {
25 | x: 'a', // This is a wider string
26 | };
27 |
28 | const fn = (x: X) => `${x}-foo`;
29 |
30 | console.log(fn(o.x)); // Argument of type 'string' is not assignable to parameter of type 'X'
31 | ```
32 |
33 | As you can see the code throws an error when passing `o.x` to `fn` as X is a narrower type.
34 |
35 | We can solve this issue by using type assertion using `const` or the `X` type:
36 |
37 |
38 | ```typescript
39 | let o = {
40 | x: 'a' as const,
41 | };
42 | ```
43 |
44 | or:
45 |
46 |
47 | ```typescript
48 | let o = {
49 | x: 'a' as X,
50 | };
51 | ```
52 |
53 |
--------------------------------------------------------------------------------
/website/src/content/docs/book/literal-types.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Literal Types
3 | sidebar:
4 | order: 16
5 | label: 16. Literal Types
6 | ---
7 |
8 |
9 | A Literal Type is a single element set from a collective type, it defines a very exact value that is a JavaScript primitive.
10 |
11 | Literal Types in TypeScript are numbers, strings, and booleans.
12 |
13 | Example of literals:
14 |
15 | ```typescript
16 | const a = 'a'; // String literal type
17 | const b = 1; // Numeric literal type
18 | const c = true; // Boolean literal type
19 | ```
20 |
21 | String, Numeric, and Boolean Literal Types are used in the union, type guard, and type aliases.
22 | In the following example you can see a type alias union, `O` can be the only value specified and not any other string:
23 |
24 | ```typescript
25 | type O = 'a' | 'b' | 'c';
26 | ```
27 |
28 |
--------------------------------------------------------------------------------
/website/src/content/docs/book/mapped-type-modifiers.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Mapped Type Modifiers
3 | sidebar:
4 | order: 38
5 | label: 38. Mapped Type Modifiers
6 | ---
7 |
8 |
9 | Mapped Type Modifiers in TypeScript enable the transformation of properties within an existing type:
10 |
11 | * `readonly` or `+readonly`: This renders a property in the mapped type as read-only.
12 | * `-readonly`: This allows a property in the mapped type to be mutable.
13 | * `?`: This designates a property in the mapped type as optional.
14 |
15 | Examples:
16 |
17 | ```typescript
18 | type ReadOnly = { readonly [P in keyof T]: T[P] }; // All properties marked as read-only
19 |
20 | type Mutable = { -readonly [P in keyof T]: T[P] }; // All properties marked as mutable
21 |
22 | type MyPartial = { [P in keyof T]?: T[P] }; // All properties marked as optional
23 | ```
24 |
25 |
--------------------------------------------------------------------------------
/website/src/content/docs/book/mapped-types.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Mapped Types
3 | sidebar:
4 | order: 37
5 | label: 37. Mapped Types
6 | ---
7 |
8 |
9 | Mapped Types in TypeScript allow you to create new types based on an existing type by transforming each property using a mapping function. By mapping existing types, you can create new types that represent the same information in a different format. To create a mapped type, you access the properties of an existing type using the `keyof` operator and then alter them to produce a new type.
10 | In the following example:
11 |
12 | ```typescript
13 | type MyMappedType = {
14 | [P in keyof T]: T[P][];
15 | };
16 | type MyType = {
17 | foo: string;
18 | bar: number;
19 | };
20 | type MyNewType = MyMappedType;
21 | const x: MyNewType = {
22 | foo: ['hello', 'world'],
23 | bar: [1, 2, 3],
24 | };
25 | ```
26 |
27 | we define MyMappedType to map over T's properties, creating a new type with each property as an array of its original type. Using this, we create MyNewType to represent the same info as MyType, but with each property as an array.
28 |
29 |
--------------------------------------------------------------------------------
/website/src/content/docs/book/merging-and-extension.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Merging and Extension
3 | sidebar:
4 | order: 52
5 | label: 52. Merging and Extension
6 | ---
7 |
8 |
9 | Merging and extension refer to two different concepts related to working with types and interfaces.
10 |
11 | Merging allows you to combine multiple declarations of the same name into a single definition, for example, when you define an interface with the same name multiple times:
12 |
13 | ```typescript
14 | interface X {
15 | a: string;
16 | }
17 |
18 | interface X {
19 | b: number;
20 | }
21 |
22 | const person: X = {
23 | a: 'a',
24 | b: 7,
25 | };
26 | ```
27 |
28 | Extension refers to the ability to extend or inherit from existing types or interfaces to create new ones. It is a mechanism to add additional properties or methods to an existing type without modifying its original definition. Example:
29 |
30 | ```typescript
31 | interface Animal {
32 | name: string;
33 | eat(): void;
34 | }
35 |
36 | interface Bird extends Animal {
37 | sing(): void;
38 | }
39 |
40 | const dog: Bird = {
41 | name: 'Bird 1',
42 | eat() {
43 | console.log('Eating');
44 | },
45 | sing() {
46 | console.log('Singing');
47 | },
48 | };
49 | ```
50 |
51 |
--------------------------------------------------------------------------------
/website/src/content/docs/book/named-tuple-type-labeled.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Named Tuple Type (Labeled)
3 | sidebar:
4 | order: 29
5 | label: 29. Named Tuple Type (Labeled)
6 | ---
7 |
8 |
9 | Tuple types can include optional labels or names for each element. These labels are for readability and tooling assistance, and do not affect the operations you can perform with them.
10 |
11 | ```typescript
12 | type T = string;
13 | type Tuple1 = [T, T];
14 | type Tuple2 = [a: T, b: T];
15 | type Tuple3 = [a: T, T]; // Named Tuple plus Anonymous Tuple
16 | ```
17 |
18 |
--------------------------------------------------------------------------------
/website/src/content/docs/book/namespacing.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Namespacing
3 | sidebar:
4 | order: 57
5 | label: 57. Namespacing
6 | ---
7 |
8 |
9 | In TypeScript, namespaces are used to organize code into logical containers, preventing naming collisions and providing a way to group related code together.
10 | The usage of the `export` keywords allows access to the namespace in "outside" modules.
11 |
12 | ```typescript
13 | export namespace MyNamespace {
14 | export interface MyInterface1 {
15 | prop1: boolean;
16 | }
17 | export interface MyInterface2 {
18 | prop2: string;
19 | }
20 | }
21 |
22 | const a: MyNamespace.MyInterface1 = {
23 | prop1: true,
24 | };
25 | ```
26 |
27 |
--------------------------------------------------------------------------------
/website/src/content/docs/book/never-type.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Never type
3 | sidebar:
4 | order: 47
5 | label: 47. Never type
6 | ---
7 |
8 |
9 | The `never` type represents values that never occur. It is used to denote functions or expressions that never return or throw an error.
10 |
11 | For instance an infinite loop:
12 |
13 | ```typescript
14 | const infiniteLoop = (): never => {
15 | while (true) {
16 | // do something
17 | }
18 | };
19 | ```
20 |
21 | Throwing an error:
22 |
23 | ```typescript
24 | const throwError = (message: string): never => {
25 | throw new Error(message);
26 | };
27 | ```
28 |
29 | The `never` type is useful in ensuring type safety and catching potential errors in your code. It helps TypeScript analyze and infer more precise types when used in combination with other types and control flow statements, for instance:
30 |
31 | ```typescript
32 | type Direction = 'up' | 'down';
33 | const move = (direction: Direction): void => {
34 | switch (direction) {
35 | case 'up':
36 | // move up
37 | break;
38 | case 'down':
39 | // move down
40 | break;
41 | default:
42 | const exhaustiveCheck: never = direction;
43 | throw new Error(`Unhandled direction: ${exhaustiveCheck}`);
44 | }
45 | };
46 | ```
47 |
48 |
--------------------------------------------------------------------------------
/website/src/content/docs/book/object-types.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Object Types
3 | sidebar:
4 | order: 27
5 | label: 27. Object Types
6 | ---
7 |
8 |
9 | In TypeScript, object types describe the shape of an object. They specify the names and types of the object's properties, as well as whether those properties are required or optional.
10 |
11 | In TypeScript, you can define object types in two primary ways:
12 |
13 | Interface which defines the shape of an object by specifying the names, types, and optionality of its properties.
14 |
15 | ```typescript
16 | interface User {
17 | name: string;
18 | age: number;
19 | email?: string;
20 | }
21 | ```
22 |
23 | Type alias, similar to an interface, defines the shape of an object. However, it can also create a new custom type that is based on an existing type or a combination of existing types. This includes defining union types, intersection types, and other complex types.
24 |
25 | ```typescript
26 | type Point = {
27 | x: number;
28 | y: number;
29 | };
30 | ```
31 |
32 | It also possible to define a type anonymously:
33 |
34 | ```typescript
35 | const sum = (x: { a: number; b: number }) => x.a + x.b;
36 | console.log(sum({ a: 5, b: 1 }));
37 | ```
38 |
39 |
--------------------------------------------------------------------------------
/website/src/content/docs/book/optional-properties.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Optional Properties
3 | sidebar:
4 | order: 12
5 | label: 12. Optional Properties
6 | ---
7 |
8 |
9 | An object can specify Optional Properties by adding a question mark `?` to the end of the property name:
10 |
11 | ```typescript
12 | type X = {
13 | a: number;
14 | b?: number; // Optional
15 | };
16 | ```
17 |
18 | It is possible to specify a default value when a property is optional"
19 |
20 | ```typescript
21 | type X = {
22 | a: number;
23 | b?: number;
24 | };
25 | const x = ({ a, b = 100 }: X) => a + b;
26 | ```
27 |
28 |
--------------------------------------------------------------------------------
/website/src/content/docs/book/overloads.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Overloads
3 | sidebar:
4 | order: 51
5 | label: 51. Overloads
6 | ---
7 |
8 |
9 | Function overloads in TypeScript allow you to define multiple function signatures for a single function name, enabling you to define functions that can be called in multiple ways. Here's an example:
10 |
11 | ```typescript
12 | // Overloads
13 | function sayHi(name: string): string;
14 | function sayHi(names: string[]): string[];
15 |
16 | // Implementation
17 | function sayHi(name: unknown): unknown {
18 | if (typeof name === 'string') {
19 | return `Hi, ${name}!`;
20 | } else if (Array.isArray(name)) {
21 | return name.map(name => `Hi, ${name}!`);
22 | }
23 | throw new Error('Invalid value');
24 | }
25 |
26 | sayHi('xx'); // Valid
27 | sayHi(['aa', 'bb']); // Valid
28 | ```
29 |
30 | Here's another example of using function overloads within a `class`:
31 |
32 | ```typescript
33 | class Greeter {
34 | message: string;
35 |
36 | constructor(message: string) {
37 | this.message = message;
38 | }
39 |
40 | // overload
41 | sayHi(name: string): string;
42 | sayHi(names: string[]): ReadonlyArray;
43 |
44 | // implementation
45 | sayHi(name: unknown): unknown {
46 | if (typeof name === 'string') {
47 | return `${this.message}, ${name}!`;
48 | } else if (Array.isArray(name)) {
49 | return name.map(name => `${this.message}, ${name}!`);
50 | }
51 | throw new Error('value is invalid');
52 | }
53 | }
54 | console.log(new Greeter('Hello').sayHi('Simon'));
55 | ```
56 |
57 |
--------------------------------------------------------------------------------
/website/src/content/docs/book/predefined-conditional-types.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Predefined Conditional Types
3 | sidebar:
4 | order: 42
5 | label: 42. Predefined Conditional Types
6 | ---
7 |
8 |
9 | In TypeScript, Predefined Conditional Types are built-in conditional types provided by the language. They are designed to perform common type transformations based on the characteristics of a given type.
10 |
11 | `Exclude`: This type removes all the types from Type that are assignable to ExcludedType.
12 |
13 | `Extract`: This type extracts all the types from Union that are assignable to Type.
14 |
15 | `NonNullable`: This type removes null and undefined from Type.
16 |
17 | `ReturnType`: This type extracts the return type of a function Type.
18 |
19 | `Parameters`: This type extracts the parameter types of a function Type.
20 |
21 | `Required`: This type makes all properties in Type required.
22 |
23 | `Partial`: This type makes all properties in Type optional.
24 |
25 | `Readonly`: This type makes all properties in Type readonly.
26 |
27 |
--------------------------------------------------------------------------------
/website/src/content/docs/book/readonly-properties.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Readonly Properties
3 | sidebar:
4 | order: 13
5 | label: 13. Readonly Properties
6 | ---
7 |
8 |
9 | Is it possible to prevent writing on a property by using the modifier `readonly`which makes sure that the property cannot be re-written but does not provide any guarantee of total immutability:
10 |
11 | ```typescript
12 | interface Y {
13 | readonly a: number;
14 | }
15 |
16 | type X = {
17 | readonly a: number;
18 | };
19 |
20 | type J = Readonly<{
21 | a: number;
22 | }>;
23 |
24 | type K = {
25 | readonly [index: number]: string;
26 | };
27 | ```
28 |
29 |
--------------------------------------------------------------------------------
/website/src/content/docs/book/strictnullchecks.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: strictNullChecks
3 | sidebar:
4 | order: 18
5 | label: 18. strictNullChecks
6 | ---
7 |
8 |
9 | `strictNullChecks` is a TypeScript compiler option that enforces strict null checking. When this option is enabled, variables and parameters can only be assigned `null` or `undefined` if they have been explicitly declared to be of that type using the union type `null` | `undefined`. If a variable or parameter is not explicitly declared as nullable, TypeScript will generate an error to prevent potential runtime errors.
10 |
11 |
--------------------------------------------------------------------------------
/website/src/content/docs/book/symbols.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Symbols
3 | sidebar:
4 | order: 58
5 | label: 58. Symbols
6 | ---
7 |
8 |
9 | Symbols are a primitive data type that represents an immutable value which is guaranteed to be globally unique throughout the lifetime of the program.
10 |
11 | Symbols can be used as keys for object properties and provide a way to create non-enumerable properties.
12 |
13 | ```typescript
14 | const key1: symbol = Symbol('key1');
15 | const key2: symbol = Symbol('key2');
16 |
17 | const obj = {
18 | [key1]: 'value 1',
19 | [key2]: 'value 2',
20 | };
21 |
22 | console.log(obj[key1]); // value 1
23 | console.log(obj[key2]); // value 2
24 | ```
25 |
26 | In WeakMaps and WeakSets, symbols are now permissible as keys.
27 |
28 |
--------------------------------------------------------------------------------
/website/src/content/docs/book/template-union-types.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Template Union Types
3 | sidebar:
4 | order: 43
5 | label: 43. Template Union Types
6 | ---
7 |
8 |
9 | Template union types can be used to merge and manipulate text inside the type system for instance:
10 |
11 | ```typescript
12 | type Status = 'active' | 'inactive';
13 | type Products = 'p1' | 'p2';
14 | type ProductId = `id-${Products}-${Status}`; // "id-p1-active" | "id-p1-inactive" | "id-p2-active" | "id-p2-inactive"
15 | ```
16 |
17 |
--------------------------------------------------------------------------------
/website/src/content/docs/book/the-concise-typescript-book.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: The Concise TypeScript Book
3 | sidebar:
4 | order: 1
5 | label: 1. The Concise TypeScript Book
6 | ---
7 |
8 |
9 | The Concise TypeScript Book provides a comprehensive and succinct overview of TypeScript's capabilities. It offers clear explanations covering all aspects found in the latest version of the language, from its powerful type system to advanced features. Whether you're a beginner or an experienced developer, this book is an invaluable resource to enhance your understanding and proficiency in TypeScript.
10 |
11 | This book is completely Free and Open Source.
12 |
13 | If you found this TypeScript book valuable and wish to contribute, consider supporting my efforts via PayPal. Thanks!
14 |
15 | [](https://www.paypal.com/donate/?business=QW82ZS956XLFY&no_recurring=0¤cy_code=EUR)
16 |
17 |
--------------------------------------------------------------------------------
/website/src/content/docs/book/the-never-type.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: The never Type
3 | sidebar:
4 | order: 25
5 | label: 25. The never Type
6 | ---
7 |
8 |
9 | When a variable is narrowed to a type that cannot contain any values, the TypeScript compiler will infer that the variable must be of the `never` type. This is because The never Type represents a value that can never be produced.
10 |
11 | ```typescript
12 | const printValue = (val: string | number) => {
13 | if (typeof val === 'string') {
14 | console.log(val.toUpperCase());
15 | } else if (typeof val === 'number') {
16 | console.log(val.toFixed(2));
17 | } else {
18 | // val has type never here because it can never be anything other than a string or a number
19 | const neverVal: never = val;
20 | console.log(`Unexpected value: ${neverVal}`);
21 | }
22 | };
23 | ```
24 |
25 |
--------------------------------------------------------------------------------
/website/src/content/docs/book/translations.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Translations
3 | sidebar:
4 | order: 2
5 | label: 2. Translations
6 | ---
7 |
8 |
9 | This book has been translated into several language versions, including:
10 |
11 | [Chinese](https://github.com/gibbok/typescript-book/blob/main/README-zh_CN.md)
12 |
13 |
--------------------------------------------------------------------------------
/website/src/content/docs/book/triple-slash-directives.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Triple-Slash Directives
3 | sidebar:
4 | order: 59
5 | label: 59. Triple-Slash Directives
6 | ---
7 |
8 |
9 | Triple-slash directives are special comments that provide instructions to the compiler about how to process a file. These directives begin with three consecutive slashes (`///`) and are typically placed at the top of a TypeScript file and have no effects on the runtime behavior.
10 |
11 | Triple-slash directives are used to reference external dependencies, specify module loading behavior, enable/disable certain compiler features, and more. Few examples:
12 |
13 | Referencing a declaration file:
14 |
15 |
16 | ```typescript
17 | ///
18 | ```
19 |
20 | Indicate the module format:
21 |
22 |
23 | ```typescript
24 | ///
25 | ```
26 |
27 | Enable compiler options, in the following example strict mode:
28 |
29 |
30 | ```typescript
31 | ///
32 | ```
33 |
34 |
--------------------------------------------------------------------------------
/website/src/content/docs/book/tuple-type-anonymous.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Tuple Type (Anonymous)
3 | sidebar:
4 | order: 28
5 | label: 28. Tuple Type (Anonymous)
6 | ---
7 |
8 |
9 | A Tuple Type is a type that represents an array with a fixed number of elements and their corresponding types. A tuple type enforces a specific number of elements and their respective types in a fixed order. Tuple types are useful when you want to represent a collection of values with specific types, where the position of each element in the array has a specific meaning.
10 |
11 | ```typescript
12 | type Point = [number, number];
13 | ```
14 |
15 |
--------------------------------------------------------------------------------
/website/src/content/docs/book/type-annotations.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Type Annotations
3 | sidebar:
4 | order: 11
5 | label: 11. Type Annotations
6 | ---
7 |
8 |
9 | On variables declared using `var`, `let` and `const`, it is possible to optionally add a type:
10 |
11 | ```typescript
12 | const x: number = 1;
13 | ```
14 |
15 | TypeScript does a good job of inferring types, especially when simple one, so these declarations in most cases are not necessary.
16 |
17 | On functions is possible to add type annotations to parameters:
18 |
19 | ```typescript
20 | function sum(a: number, b: number) {
21 | return a + b;
22 | }
23 | ```
24 |
25 | The following is an example using a anonymous functions (so called lambda function):
26 |
27 | ```typescript
28 | const sum = (a: number, b: number) => a + b;
29 | ```
30 |
31 | These annotation can be avoided when a default value for a parameter is present:
32 |
33 | ```typescript
34 | const sum = (a = 10, b: number) => a + b;
35 | ```
36 |
37 | Return type annotations can be added to functions:
38 |
39 | ```typescript
40 | const sum = (a = 10, b: number): number => a + b;
41 | ```
42 |
43 | This is useful especially for more complex functions as writing expliciting the return type before an implementation can help better think about the function.
44 |
45 | Generally consider annotating type signatures but not the body local variables and add types always to object literals.
46 |
47 |
--------------------------------------------------------------------------------
/website/src/content/docs/book/type-from-func-return.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Type from Func Return
3 | sidebar:
4 | order: 35
5 | label: 35. Type from Func Return
6 | ---
7 |
8 |
9 | Type from Func Return refers to the ability to automatically infer the return type of a function based on its implementation. This allows TypeScript to determine the type of the value returned by the function without explicit type annotations.
10 |
11 | ```typescript
12 | const add = (x: number, y: number) => x + y; // TypeScript can infer that the return type of the function is a number
13 | ```
14 |
15 |
--------------------------------------------------------------------------------
/website/src/content/docs/book/type-from-module.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Type from Module
3 | sidebar:
4 | order: 36
5 | label: 36. Type from Module
6 | ---
7 |
8 |
9 | Type from Module refers to the ability to use a module's exported values to automatically infer their types. When a module exports a value with a specific type, TypeScript can use that information to automatically infer the type of that value when it is imported into another module.
10 |
11 |
12 | ```typescript
13 | // calc.ts
14 | export const add = (x: number, y: number) => x + y;
15 | // index.ts
16 | import { add } from 'calc';
17 | const r = add(1, 2); // r is number
18 | ```
19 |
20 |
--------------------------------------------------------------------------------
/website/src/content/docs/book/type-from-value.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Type from Value
3 | sidebar:
4 | order: 34
5 | label: 34. Type from Value
6 | ---
7 |
8 |
9 | Type from Value in TypeScript refers to the automatic inference of a type from a value or expression through type inference.
10 |
11 | ```typescript
12 | const x = 'x'; // TypeScript can automatically infer that the type of the message variable is string
13 | ```
14 |
15 |
--------------------------------------------------------------------------------
/website/src/content/docs/book/type-indexing.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Type Indexing
3 | sidebar:
4 | order: 33
5 | label: 33. Type Indexing
6 | ---
7 |
8 |
9 | Type indexing refers to the ability to define types that can be indexed by a key that is not known in advance, using an index signature to specify the type for properties that are not explicitly declared.
10 |
11 | ```typescript
12 | type Dictionary = {
13 | [key: string]: T;
14 | };
15 | const myDict: Dictionary = { a: 'a', b: 'b' };
16 | console.log(myDict['a']); // Returns a
17 | ```
18 |
19 |
--------------------------------------------------------------------------------
/website/src/content/docs/book/type-predicates.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Type Predicates
3 | sidebar:
4 | order: 23
5 | label: 23. Type Predicates
6 | ---
7 |
8 |
9 | Type Predicates in TypeScript are functions that return a boolean value and are used to narrow the type of a variable to a more specific type.
10 |
11 | ```typescript
12 | const isString = (value: unknown): value is string => typeof value === 'string';
13 |
14 | const foo = (bar: unknown) => {
15 | if (isString(bar)) {
16 | console.log(bar.toUpperCase());
17 | } else {
18 | console.log('not a string');
19 | }
20 | };
21 | ```
22 |
23 |
--------------------------------------------------------------------------------
/website/src/content/docs/book/union-type.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Union Type
3 | sidebar:
4 | order: 31
5 | label: 31. Union Type
6 | ---
7 |
8 |
9 | A Union Type is a type that represents a value that can be one of several types. Union Types are denoted using the `|` symbol between each possible type.
10 |
11 | ```typescript
12 | let x: string | number;
13 | x = 'hello'; // Valid
14 | x = 123; // Valid
15 | ```
16 |
17 |
--------------------------------------------------------------------------------
/website/src/content/docs/book/unknown-type.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Unknown type
3 | sidebar:
4 | order: 45
5 | label: 45. Unknown type
6 | ---
7 |
8 |
9 | In TypeScript, the `unknown` type represents a value that is of an unknown type. Unlike `any` type, which allows for any type of value, `unknown` requires a type check or assertion before it can be used in a specific way so no operations are permitted on an `unknown` without first asserting or narrowing to a more specific type.
10 |
11 | The `unknown` type is only assignable to any type and the `unknown` type itself, it is a type-safe alternative to `any`.
12 |
13 |
14 | ```typescript
15 | let value: unknown;
16 |
17 | let value1: unknown = value; // Valid
18 | let value2: any = value; // Valid
19 | let value3: boolean = value; // Invalid
20 | let value4: number = value; // Invalid
21 | ```
22 |
23 | ```typescript
24 | const add = (a: unknown, b: unknown): number | undefined =>
25 | typeof a === 'number' && typeof b === 'number' ? a + b : undefined;
26 | console.log(add(1, 2)); // 3
27 | console.log(add('x', 2)); // undefined
28 | ```
29 |
30 |
--------------------------------------------------------------------------------
/website/src/content/docs/book/void-type.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Void type
3 | sidebar:
4 | order: 46
5 | label: 46. Void type
6 | ---
7 |
8 |
9 | The `void` type is used to indicate that a function does not return a value.
10 |
11 | ```typescript
12 | const sayHello = (): void => {
13 | console.log('Hello!');
14 | };
15 | ```
16 |
17 |
--------------------------------------------------------------------------------
/website/src/content/docs/index.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Typescript Book
3 | description: The Concise TypeScript Book
4 | template: splash
5 | hero:
6 | tagline: The Concise TypeScript Book provides a comprehensive and succinct overview of TypeScript's capabilities. It offers clear explanations covering all aspects found in the latest version of the language, from its powerful type system to advanced features. Whether you're a beginner or an experienced developer, this book is an invaluable resource to enhance your understanding and proficiency in TypeScript.
This book is completely Free and Open Source.
7 | actions:
8 | - text: Read now!
9 | link: /typescript-book/book/the-concise-typescript-book/
10 | icon: right-arrow
11 | variant: primary
12 | - text: GitHub
13 | link: https://github.com/gibbok/typescript-book
14 | icon: github
15 | variant: secondary
16 | - text: X.com
17 | link: https://twitter.com/gibbok_coding
18 | icon: x.com
19 | variant: secondary
20 | ---
21 |
--------------------------------------------------------------------------------
/website/src/content/docs/zh-cn/book/about-the-author.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 关于作者
3 | sidebar:
4 | order: 6
5 | label: 6. 关于作者
6 | ---
7 |
8 |
9 | Simone Poggiali 是一位经验丰富的高级前端开发人员,自 90 年代以来就热衷于编写专业级代码。在他的国际职业生涯中,他为从初创公司到大型组织的广泛客户提供了众多项目。HelloFresh、Siemens、O2 和 Leroy Merlin 等著名公司都受益于他的专业知识和奉献精神。
10 |
11 | 您可以通过以下平台联系 Simone Poggiali:
12 |
13 | * 领英: [https://www.linkedin.com/in/simone-poggiali](https://www.linkedin.com/in/simone-poggiali)
14 | * GitHub: [https://github.com/gibbok](https://github.com/gibbok)
15 | * X.com: [https://x.com/gibbok_coding](https://x.com/gibbok_coding)
16 | * 电子邮箱: gibbok.coding📧gmail.com
17 |
18 |
--------------------------------------------------------------------------------
/website/src/content/docs/zh-cn/book/any-type.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 任意类型
3 | sidebar:
4 | order: 44
5 | label: 44. 任意类型
6 | ---
7 |
8 |
9 | `any` 类型是一种特殊类型(通用超类型),可用于表示任何类型的值(基元、对象、数组、函数、错误、符号)。它通常用于编译时未知值类型的情况,或者使用来自没有 TypeScript 类型的外部 API 或库的值时。
10 |
11 | 通过使用任何类型,您向 TypeScript 编译器指示值应该不受任何限制地表示。为了最大限度地提高代码中的类型安全性,请考虑以下事项:
12 |
13 | * 将 `any` 的使用限制在类型确实未知的特定情况下。
14 | * 不要从函数返回 `any` 类型,因为使用该函数会在代码中失去类型安全性,从而削弱类型安全性。
15 | * 如果您需要使编译器保持沉默,请使用 `@ts-ignore` 而不是 `any`。
16 |
17 | ```typescript
18 | let value: any;
19 | value = true; // 有效
20 | value = 7; // 有效
21 | ```
22 |
23 |
--------------------------------------------------------------------------------
/website/src/content/docs/zh-cn/book/assignments.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 赋值
3 | sidebar:
4 | order: 21
5 | label: 21. 赋值
6 | ---
7 |
8 |
9 | 使用赋值缩小 TypeScript 是一种根据分配给变量的值来缩小变量类型的方法。当为变量分配值时,TypeScript 会根据分配的值推断其类型,并缩小变量的类型以匹配推断的类型。
10 |
11 | ```typescript
12 | let value: string | number;
13 | value = 'hello';
14 | if (typeof value === 'string') {
15 | console.log(value.toUpperCase());
16 | }
17 | value = 42;
18 | if (typeof value === 'number') {
19 | console.log(value.toFixed(2));
20 | }
21 | ```
22 |
23 |
--------------------------------------------------------------------------------
/website/src/content/docs/zh-cn/book/built-in-type-primitives.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 内置原始数据类型
3 | sidebar:
4 | order: 49
5 | label: 49. 内置原始数据类型
6 | ---
7 |
8 |
9 | TypeScript 有几个内置的原属数据类型,可用于定义变量、函数参数和返回类型:
10 |
11 | `number`: 表示数值,包括整数和浮点数。
12 | `string`: 代表文本数据。
13 | `boolean`: 代表逻辑值,可以是 true 或 false。
14 | `null`: 表示没有值。
15 | `undefined`: 表示尚未赋值或未定义的值。
16 | `symbol`: 代表唯一标识符。符号通常用作对象属性的键。
17 | `bigint`: 表示任意精度整数。
18 | `any`: 代表动态或未知类型。any 类型的变量可以保存任何类型的值,并且它们绕过类型检查。
19 | `void`: 表示不存在任何类型。它通常用作不返回值的函数的返回类型。
20 | `never`: 表示从未出现过的值的类型。它通常用作引发错误或进入无限循环的函数的返回类型。
21 |
22 |
--------------------------------------------------------------------------------
/website/src/content/docs/zh-cn/book/common-built-in-js-objects.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 常见的内置JS对象
3 | sidebar:
4 | order: 50
5 | label: 50. 常见的内置JS对象
6 | ---
7 |
8 |
9 | TypeScript 是 JavaScript 的超集,它包含所有常用的内置 JavaScript 对象。您可以在 Mozilla 开发者网络 (MDN) 文档网站上找到这些对象的详细列表:
10 | [https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects)
11 |
12 | 以下是一些常用的内置 JavaScript 对象的列表:
13 |
14 | * Function
15 | * Object
16 | * Boolean
17 | * Error
18 | * Number
19 | * BigInt
20 | * Math
21 | * Date
22 | * String
23 | * RegExp
24 | * Array
25 | * Map
26 | * Set
27 | * Promise
28 | * Intl
29 |
30 |
--------------------------------------------------------------------------------
/website/src/content/docs/zh-cn/book/conditional-types.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 条件类型
3 | sidebar:
4 | order: 39
5 | label: 39. 条件类型
6 | ---
7 |
8 |
9 | 条件类型是一种创建依赖于条件的类型的方法,其中要创建的类型是根据条件的结果确定的。它们是使用 `extends` 关键字和三元运算符来定义的,以便有条件地在两种类型之间进行选择。
10 |
11 | ```typescript
12 | type IsArray = T extends any[] ? true : false;
13 |
14 | const myArray = [1, 2, 3];
15 | const myNumber = 42;
16 |
17 | type IsMyArrayAnArray = IsArray; // true 类型
18 | type IsMyNumberAnArray = IsArray; // false 类型
19 | ```
20 |
21 |
--------------------------------------------------------------------------------
/website/src/content/docs/zh-cn/book/control-flow-analysis.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 控制流分析
3 | sidebar:
4 | order: 22
5 | label: 22. 控制流分析
6 | ---
7 |
8 |
9 | TypeScript 中的控制流分析是一种静态分析代码流以推断变量类型的方法,允许编译器根据分析结果根据需要缩小这些变量的类型。
10 |
11 | 在 TypeScript 4.4 之前,代码流分析仅适用于 if 语句中的代码,但从 TypeScript 4.4 开始,它还可以应用于条件表达式和通过 const 变量间接引用的判别式属性访问。
12 |
13 | 例如:
14 |
15 | ```typescript
16 | const f1 = (x: unknown) => {
17 | const isString = typeof x === 'string';
18 | if (isString) {
19 | x.length;
20 | }
21 | };
22 |
23 | const f2 = (
24 | obj: { kind: 'foo'; foo: string } | { kind: 'bar'; bar: number }
25 | ) => {
26 | const isFoo = obj.kind === 'foo';
27 | if (isFoo) {
28 | obj.foo;
29 | } else {
30 | obj.bar;
31 | }
32 | };
33 | ```
34 |
35 | 一些未发生缩小的示例:
36 |
37 |
38 | ```typescript
39 | const f1 = (x: unknown) => {
40 | let isString = typeof x === 'string';
41 | if (isString) {
42 | x.length; // 错误, 没有缩小,因为 isString 不是常量
43 | }
44 | };
45 |
46 | const f6 = (
47 | obj: { kind: 'foo'; foo: string } | { kind: 'bar'; bar: number }
48 | ) => {
49 | const isFoo = obj.kind === 'foo';
50 | obj = obj;
51 | if (isFoo) {
52 | obj.foo; // 错误, 没有缩小,因为 obj 在函数体中被赋值
53 | }
54 | };
55 | ```
56 |
57 | 注意: 在条件表达式中最多分析五个间接级别。
58 |
59 |
--------------------------------------------------------------------------------
/website/src/content/docs/zh-cn/book/differences-between-type-and-interface.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 类型和接口之间的差异
3 | sidebar:
4 | order: 53
5 | label: 53. 类型和接口之间的差异
6 | ---
7 |
8 |
9 | 声明合并(增强):
10 |
11 | 接口支持声明合并,这意味着您可以定义多个具有相同名称的接口,TypeScript 会将它们合并为具有组合属性和方法的单个接口。 另一方面,类型不支持声明合并。 当您想要添加额外的功能或自定义现有类型而不修改原始定义或修补丢失或不正确的类型时,这可能会很有帮助。
12 |
13 | ```typescript
14 | interface A {
15 | x: string;
16 | }
17 | interface A {
18 | y: string;
19 | }
20 | const j: A = {
21 | x: 'xx',
22 | y: 'yy',
23 | };
24 | ```
25 |
26 | 扩展其他类型/接口:
27 |
28 | 类型和接口都可以扩展其他类型/接口,但语法不同。 对于接口,您可以使用“extends”关键字从其他接口继承属性和方法。 但是,接口无法扩展像联合类型这样的复杂类型。
29 |
30 | ```typescript
31 | interface A {
32 | x: string;
33 | y: number;
34 | }
35 | interface B extends A {
36 | z: string;
37 | }
38 | const car: B = {
39 | x: 'x',
40 | y: 123,
41 | z: 'z',
42 | };
43 | ```
44 |
45 | 对于类型,您可以使用 & 运算符将多个类型合并为单个类型(交集)。
46 |
47 | ```typescript
48 | interface A {
49 | x: string;
50 | y: number;
51 | }
52 |
53 | type B = A & {
54 | j: string;
55 | };
56 |
57 | const c: B = {
58 | x: 'x',
59 | y: 123,
60 | j: 'j',
61 | };
62 | ```
63 |
64 | 并集和交集类型:
65 |
66 | 在定义并集和交集类型时,类型更加灵活。 通过“type”关键字,您可以使用“|”运算符轻松创建联合类型,并使用“&”运算符创建交集类型。 虽然接口也可以间接表示联合类型,但它们没有对交集类型的内置支持。
67 |
68 | ```typescript
69 | type Department = 'dep-x' | 'dep-y'; // 并集
70 |
71 | type Person = {
72 | name: string;
73 | age: number;
74 | };
75 |
76 | type Employee = {
77 | id: number;
78 | department: Department;
79 | };
80 |
81 | type EmployeeInfo = Person & Employee; // 交集
82 | ```
83 |
84 | 接口示例:
85 |
86 | ```typescript
87 | interface A {
88 | x: 'x';
89 | }
90 | interface B {
91 | y: 'y';
92 | }
93 |
94 | type C = A | B; // 接口的并集
95 | ```
96 |
97 |
--------------------------------------------------------------------------------
/website/src/content/docs/zh-cn/book/discriminated-unions.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 可区分联合
3 | sidebar:
4 | order: 24
5 | label: 24. 可区分联合
6 | ---
7 |
8 |
9 | TypeScript 中的可区分联合是一种联合类型,它使用称为判别式的公共属性来缩小联合的可能类型集。
10 |
11 | ```typescript
12 | type Square = {
13 | kind: 'square'; // 判别式
14 | size: number;
15 | };
16 |
17 | type Circle = {
18 | kind: 'circle'; // 判别式
19 | radius: number;
20 | };
21 |
22 | type Shape = Square | Circle;
23 |
24 | const area = (shape: Shape) => {
25 | switch (shape.kind) {
26 | case 'square':
27 | return Math.pow(shape.size, 2);
28 | case 'circle':
29 | return Math.PI * Math.pow(shape.radius, 2);
30 | }
31 | };
32 |
33 | const square: Square = { kind: 'square', size: 5 };
34 | const circle: Circle = { kind: 'circle', radius: 2 };
35 |
36 | console.log(area(square)); // 25
37 | console.log(area(circle)); // 12.566370614359172
38 | ```
39 |
40 |
--------------------------------------------------------------------------------
/website/src/content/docs/zh-cn/book/distributive-conditional-types.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 分配条件类型
3 | sidebar:
4 | order: 40
5 | label: 40. 分配条件类型
6 | ---
7 |
8 |
9 | 分布式条件类型是一种功能,通过单独对联合的每个成员应用转换,允许类型分布在类型的联合上。当使用映射类型或高阶类型时,这尤其有用。
10 |
11 | ```typescript
12 | type Nullable = T extends any ? T | null : never;
13 | type NumberOrBool = number | boolean;
14 | type NullableNumberOrBool = Nullable; // number | boolean | null
15 | ```
16 |
17 |
--------------------------------------------------------------------------------
/website/src/content/docs/zh-cn/book/downloads-and-website.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 下载和网站
3 | sidebar:
4 | order: 3
5 | label: 3. 下载和网站
6 | ---
7 |
8 |
9 | 您还可以下载 Epub 版本:
10 |
11 | [https://github.com/gibbok/typescript-book/tree/main/downloads](https://github.com/gibbok/typescript-book/tree/main/downloads)
12 |
13 | 在线版本可在以下位置获得:
14 |
15 | [https://gibbok.github.io/typescript-book](https://gibbok.github.io/typescript-book)
16 |
17 |
--------------------------------------------------------------------------------
/website/src/content/docs/zh-cn/book/erased-structural-types.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 擦除的结构类型
3 | sidebar:
4 | order: 56
5 | label: 56. 擦除的结构类型
6 | ---
7 |
8 |
9 | 在 TypeScript 中,对象不必匹配特定的、精确的类型。例如,如果我们创建一个满足接口要求的对象,我们就可以在需要该接口的地方使用该对象,即使它们之间没有显式连接。例子:
10 |
11 | ```typescript
12 | type NameProp1 = {
13 | prop1: string;
14 | };
15 |
16 | function log(x: NameProp1) {
17 | console.log(x.prop1);
18 | }
19 |
20 | const obj = {
21 | prop2: 123,
22 | prop1: 'Origin',
23 | };
24 |
25 | log(obj); // 有效
26 | ```
27 |
28 |
--------------------------------------------------------------------------------
/website/src/content/docs/zh-cn/book/exhaustiveness-checking.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 详尽性检查
3 | sidebar:
4 | order: 26
5 | label: 26. 详尽性检查
6 | ---
7 |
8 |
9 | 详尽性检查是 TypeScript 中的一项功能,可确保在 `switch` 语句或 `if` 语句中处理可区分联合的所有可能情况。
10 |
11 | ```typescript
12 | type Direction = 'up' | 'down';
13 |
14 | const move = (direction: Direction) => {
15 | switch (direction) {
16 | case 'up':
17 | console.log('Moving up');
18 | break;
19 | case 'down':
20 | console.log('Moving down');
21 | break;
22 | default:
23 | const exhaustiveCheck: never = direction;
24 | console.log(exhaustiveCheck); // 这行永远不会被执行
25 | }
26 | };
27 | ```
28 |
29 | 该 `never` 类型用于确保默认情况是详尽的,并且如果将新值添加到 Direction 类型而未在 switch 语句中进行处理,则 TypeScript 将引发错误。
30 |
31 |
--------------------------------------------------------------------------------
/website/src/content/docs/zh-cn/book/extending-types.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 扩展类型
3 | sidebar:
4 | order: 15
5 | label: 15. 扩展类型
6 | ---
7 |
8 |
9 | 可以扩展 `interface`(从另一种类型复制成员):
10 |
11 | ```typescript
12 | interface X {
13 | a: string;
14 | }
15 | interface Y extends X {
16 | b: string;
17 | }
18 | ```
19 |
20 | 还可以从多种 `interface` 进行扩展:
21 |
22 | ```typescript
23 | interface A {
24 | a: string;
25 | }
26 | interface B {
27 | b: string;
28 | }
29 | interface Y extends A, B {
30 | y: string;
31 | }
32 | ```
33 |
34 | 该 `extends` 关键字仅适用于 `interface`,因为 `type` 使用交集:
35 |
36 | ```typescript
37 | type A = {
38 | a: number;
39 | };
40 | type B = {
41 | b: number;
42 | };
43 | type C = A & B;
44 | ```
45 |
46 | 可以使用 `interface` 来扩展类 `type`,但反之则不然:
47 |
48 | ```typescript
49 | type A = {
50 | a: string;
51 | };
52 | interface B extends A {
53 | b: string;
54 | }
55 | ```
56 |
57 |
--------------------------------------------------------------------------------
/website/src/content/docs/zh-cn/book/fixed-length-tuple.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 固定长度元组
3 | sidebar:
4 | order: 30
5 | label: 30. 固定长度元组
6 | ---
7 |
8 |
9 | 固定长度元组是一种特定类型的元组,它强制执行特定类型的固定数量的元素,并且一旦定义元组就不允许对其长度进行任何修改。
10 |
11 | 当您需要表示具有特定数量的元素和特定类型的值的集合,并且您希望确保元组的长度和类型不会无意中更改时,固定长度元组非常有用。
12 |
13 |
14 | ```typescript
15 | const x = [10, 'hello'] as const;
16 | x.push(2); // 错误
17 | ```
18 |
19 |
--------------------------------------------------------------------------------
/website/src/content/docs/zh-cn/book/generics.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 泛型
3 | sidebar:
4 | order: 55
5 | label: 55. 泛型
6 | ---
7 |
8 |
9 | 泛型允许您创建可与多种类型一起使用的可重用组件和函数。使用泛型,您可以参数化类型、函数和接口,从而允许它们对不同类型进行操作,而无需事先显式指定它们。
10 |
11 | 泛型允许您使代码更加灵活和可重用。
12 |
13 | ### 泛型类型
14 |
15 | 要定义泛型类型,可以使用尖括号 (`<>`) 来指定类型参数,例如:
16 |
17 | ```typescript
18 | function identity(arg: T): T {
19 | return arg;
20 | }
21 | const a = identity('x');
22 | const b = identity(123);
23 |
24 | const getLen = (data: ReadonlyArray) => data.length;
25 | const len = getLen([1, 2, 3]);
26 | ```
27 |
28 | ### 泛型类
29 |
30 | 泛型也可以应用于类,这样它们就可以通过使用类型参数来处理多种类型。这对于创建可重用的类定义非常有用,这些定义可以在保持类型安全的同时对不同的数据类型进行操作。
31 |
32 | ```typescript
33 | class Container {
34 | private item: T;
35 |
36 | constructor(item: T) {
37 | this.item = item;
38 | }
39 |
40 | getItem(): T {
41 | return this.item;
42 | }
43 | }
44 |
45 | const numberContainer = new Container(123);
46 | console.log(numberContainer.getItem()); // 123
47 |
48 | const stringContainer = new Container('hello');
49 | console.log(stringContainer.getItem()); // hello
50 | ```
51 |
52 | ### 泛型约束
53 |
54 | 可以使用关键字 `extends` 后跟类型参数必须满足的类型或接口来约束泛型参数。
55 |
56 | 在下面的示例中,T 必须正确包含 `length` 才能有效:
57 |
58 |
59 | ```typescript
60 | const printLen = (value: T): void => {
61 | console.log(value.length);
62 | };
63 |
64 | printLen('Hello'); // 5
65 | printLen([1, 2, 3]); // 3
66 | printLen({ length: 10 }); // 10
67 | printLen(123); // 无效
68 | ```
69 |
70 | 3.4 RC 版中引入的泛型的一个有趣功能是高阶函数类型推断,它引入了传播泛型类型参数:
71 |
72 | ```typescript
73 | declare function pipe(
74 | ab: (...args: A) => B,
75 | bc: (b: B) => C
76 | ): (...args: A) => C;
77 |
78 | declare function list(a: T): T[];
79 | declare function box(x: V): { value: V };
80 |
81 | const listBox = pipe(list, box); // (a: T) => { value: T[] }
82 | const boxList = pipe(box, list); // (x: V) => { value: V }[]
83 | ```
84 |
85 | 此功能允许更轻松地键入安全的无点风格编程,这在函数式编程中很常见。
86 |
87 | ### 泛型上下文缩小
88 |
89 | 泛型上下文缩小是 TypeScript 中的机制,允许编译器根据使用泛型参数的上下文来缩小泛型参数的类型,在条件语句中使用泛型类型时非常有用:
90 |
91 | ```typescript
92 | function process(value: T): void {
93 | if (typeof value === 'string') {
94 | // Value 的类型被缩小到 'string' 类型
95 | console.log(value.length);
96 | } else if (typeof value === 'number') {
97 | // Value 的类型被缩小到 'number' 类型
98 | console.log(value.toFixed(2));
99 | }
100 | }
101 |
102 | process('hello'); // 5
103 | process(3.14159); // 3.14
104 | ```
105 |
106 |
--------------------------------------------------------------------------------
/website/src/content/docs/zh-cn/book/index-signatures.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 索引签名
3 | sidebar:
4 | order: 14
5 | label: 14. 索引签名
6 | ---
7 |
8 |
9 | 在 TypeScript 中,我们可以使用 `string` 、`number` 和 `symbol` 作为索引签名:
10 |
11 | ```typescript
12 | type K = {
13 | [name: string | number]: string;
14 | };
15 | const k: K = { x: 'x', 1: 'b' };
16 | console.log(k['x']);
17 | console.log(k[1]);
18 | console.log(k['1']); // 同 k[1] 的结果相同
19 | ```
20 |
21 | 请注意,JavaScript 会自动将 `number` 的索引转换相同值的 'string'索引, 比如 `k[1]` 和 `k["1"]` 返回相同值。
22 |
23 |
--------------------------------------------------------------------------------
/website/src/content/docs/zh-cn/book/infer-type-inference-in-conditional-types.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: infer 条件类型中的类型推断
3 | sidebar:
4 | order: 41
5 | label: 41. infer 条件类型中的类型推断
6 | ---
7 |
8 |
9 | `infer` 关键字在条件类型中使用,用于从依赖于泛型参数的类型中推断(提取)泛型参数的类型。这允许您编写更灵活且可重用的类型定义。
10 |
11 | ```typescript
12 | type ElementType = T extends (infer U)[] ? U : never;
13 | type Numbers = ElementType; // number
14 | type Strings = ElementType; // string
15 | ```
16 |
17 |
--------------------------------------------------------------------------------
/website/src/content/docs/zh-cn/book/interface-and-type.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 接口及类型
3 | sidebar:
4 | order: 48
5 | label: 48. 接口及类型
6 | ---
7 |
8 |
9 | ### 通用语法
10 |
11 | 在 TypeScript 中,接口定义对象的结构,指定对象必须具有的属性或方法的名称和类型。在 TypeScript 中定义接口的常用语法如下:
12 |
13 |
14 | ```typescript
15 | interface InterfaceName {
16 | property1: Type1;
17 | // ...
18 | method1(arg1: ArgType1, arg2: ArgType2): ReturnType;
19 | // ...
20 | }
21 | ```
22 |
23 | 类型定义也类似:
24 |
25 |
26 | ```typescript
27 | type TypeName = {
28 | property1: Type1;
29 | // ...
30 | method1(arg1: ArgType1, arg2: ArgType2): ReturnType;
31 | // ...
32 | };
33 | ```
34 |
35 | `interface InterfaceName` 或者 `type TypeName`: 定义接口的名称。
36 | `property1`: `Type1`: 指定接口的属性及其相应的类型。可以定义多个属性,每个属性用分号分隔。
37 | `method1(arg1: ArgType1, arg2: ArgType2): ReturnType;`: 指定接口的方法。方法用其名称进行定义,后跟括号中的参数列表和返回类型。可以定义多个方法,每个方法用分号分隔。
38 |
39 | 接口示例:
40 |
41 | ```typescript
42 | interface Person {
43 | name: string;
44 | age: number;
45 | greet(): void;
46 | }
47 | ```
48 |
49 | 类型示例:
50 |
51 | ```typescript
52 | type TypeName = {
53 | property1: string;
54 | method1(arg1: string, arg2: string): string;
55 | };
56 | ```
57 |
58 | 在 TypeScript 中,类型用于定义数据的形状并强制执行类型检查。在 TypeScript 中定义类型有几种常见的语法,具体取决于具体的用例。这里有些例子:
59 |
60 | ### 基本类型
61 |
62 | ```typescript
63 | let myNumber: number = 123; // 数字类型
64 | let myBoolean: boolean = true; // 布尔类型
65 | let myArray: string[] = ['a', 'b']; // 字符串数组
66 | let myTuple: [string, number] = ['a', 123]; // 元组
67 | ```
68 |
69 | ### 对象和接口
70 |
71 | ```typescript
72 | const x: { name: string; age: number } = { name: 'Simon', age: 7 };
73 | ```
74 |
75 | ### 并集和交集类型
76 |
77 | ```typescript
78 | type MyType = string | number; // 并集
79 | let myUnion: MyType = 'hello'; // 可以是字符串
80 | myUnion = 123; // 或者是一个数字
81 |
82 | type TypeA = { name: string };
83 | type TypeB = { age: number };
84 | type CombinedType = TypeA & TypeB; // 交集
85 | let myCombined: CombinedType = { name: 'John', age: 25 }; // 对象同时有name和age属性
86 | ```
87 |
88 |
--------------------------------------------------------------------------------
/website/src/content/docs/zh-cn/book/intersection-types.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 交集类型
3 | sidebar:
4 | order: 32
5 | label: 32. 交集类型
6 | ---
7 |
8 |
9 | 交集类型是表示具有两种或多种类型的所有属性的值的类型。交叉类型在每种类型之间使用 & 符号表示。
10 |
11 | ```typescript
12 | type X = {
13 | a: string;
14 | };
15 |
16 | type Y = {
17 | b: string;
18 | };
19 |
20 | type J = X & Y; // 交集
21 |
22 | const j: J = {
23 | a: 'a',
24 | b: 'b',
25 | };
26 | ```
27 |
28 |
--------------------------------------------------------------------------------
/website/src/content/docs/zh-cn/book/introduction.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 介绍
3 | sidebar:
4 | order: 5
5 | label: 5. 介绍
6 | ---
7 |
8 |
9 | 欢迎来到简洁的TypeScript之书!本指南为您提供有效 TypeScript 开发的基本知识和实践技能。发现编写干净、健壮的代码的关键概念和技术。无论您是初学者还是经验丰富的开发人员,本书都可以作为在项目中利用 TypeScript 强大功能的综合指南和便捷参考。
10 |
11 | 本书涵盖了 TypeScript 5.2。
12 |
13 |
--------------------------------------------------------------------------------
/website/src/content/docs/zh-cn/book/literal-inference.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 字面量推断
3 | sidebar:
4 | order: 17
5 | label: 17. 字面量推断
6 | ---
7 |
8 |
9 | 字面量推断是 TypeScript 中的一项功能,允许根据变量或参数的值推断其类型。
10 |
11 | 在下面的示例中,我们可以看到 TypeScript 认为x文字类型是因为该值以后不能随时更改,而y被推断为字符串,因为它以后可以随时修改。
12 |
13 | ```typescript
14 | const x = 'x'; // x 为字面量类型, 因为值不能改变
15 | let y = 'y'; // string, 我们能改变这个值
16 | ```
17 |
18 | 在下面的示例中,我们可以看到 `o.x` 被推断为 `string`(而不是字面量的a),因为 TypeScript 认为该值可以在以后随时更改。
19 |
20 |
21 | ```typescript
22 | type X = 'a' | 'b';
23 |
24 | let o = {
25 | x: 'a', // 这是一个更宽的 string
26 | };
27 |
28 | const fn = (x: X) => `${x}-foo`;
29 |
30 | console.log(fn(o.x)); // 'string' 类型的参数不能赋值给 'X' 类型的参数
31 | ```
32 |
33 | 正如你所看到的代码在传递 `o.x` 给 `fn` 作为一个狭窄类型时,抛出了一个错误。
34 |
35 | 我们能通过使用 `const` 或者 `X` 来借助类型推断解决这个问题:
36 |
37 |
38 | ```typescript
39 | let o = {
40 | x: 'a' as const,
41 | };
42 | ```
43 |
44 | or:
45 |
46 |
47 | ```typescript
48 | let o = {
49 | x: 'a' as X,
50 | };
51 | ```
52 |
53 |
--------------------------------------------------------------------------------
/website/src/content/docs/zh-cn/book/literal-types.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 字面量类型
3 | sidebar:
4 | order: 16
5 | label: 16. 字面量类型
6 | ---
7 |
8 |
9 | 文字类型是来自集体类型的单个元素集,它定义了一个非常精确的值,即 JavaScript 原始数据。
10 |
11 | TypeScript 中的文字类型是数字、字符串和布尔值。
12 |
13 | 示例如下:
14 |
15 | ```typescript
16 | const a = 'a'; // 字符串字面量类型
17 | const b = 1; // 数字字面量类型
18 | const c = true; // 布尔字面量类型
19 | ```
20 |
21 | 字符串、数字和布尔字面量类型用于联合、类型保护和类型别名。在下面的示例中,您可以看到类型别名联合,O可以是指定的唯一值,而不是任何其他字符串:
22 |
23 | ```typescript
24 | type O = 'a' | 'b' | 'c';
25 | ```
26 |
27 |
--------------------------------------------------------------------------------
/website/src/content/docs/zh-cn/book/mapped-type-modifiers.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 映射类型修饰符
3 | sidebar:
4 | order: 38
5 | label: 38. 映射类型修饰符
6 | ---
7 |
8 |
9 | TypeScript 中的映射类型修饰符支持对现有类型中的属性进行转换:
10 |
11 | * `readonly` 或 `+readonly`:这会将映射类型中的属性呈现为只读。
12 | * `-readonly`:这允许映射类型中的属性是可变的。
13 | * `?`:这将映射类型中的属性指定为可选。
14 |
15 | 例子:
16 |
17 | ```typescript
18 | type ReadOnly = { readonly [P in keyof T]: T[P] }; // 所有属性标记为只读
19 |
20 | type Mutable = { -readonly [P in keyof T]: T[P] }; // 所有标记为可变的属性
21 |
22 | type MyPartial = { [P in keyof T]?: T[P] }; // 所有标记为可选的属性
23 | ````
24 |
25 |
--------------------------------------------------------------------------------
/website/src/content/docs/zh-cn/book/mapped-types.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 映射类型
3 | sidebar:
4 | order: 37
5 | label: 37. 映射类型
6 | ---
7 |
8 |
9 | TypeScript 中的映射类型允许您通过使用映射函数转换每个属性来基于现有类型创建新类型。通过映射现有类型,您可以创建以不同格式表示相同信息的新类型。要创建映射类型,您可以使用运算符访问现有类型的属性 `keyof` ,然后更改它们以生成新类型。在以下示例中:
10 |
11 | ```typescript
12 | type MyMappedType = {
13 | [P in keyof T]: T[P][];
14 | };
15 | type MyType = {
16 | foo: string;
17 | bar: number;
18 | };
19 | type MyNewType = MyMappedType;
20 | const x: MyNewType = {
21 | foo: ['hello', 'world'],
22 | bar: [1, 2, 3],
23 | };
24 | ```
25 |
26 | 我们定义 MyMappedType 来映射 T 的属性,创建一个新类型,其中每个属性都是其原始类型的数组。使用它,我们创建 MyNewType 来表示与 MyType 相同的信息,但每个属性都是一个数组。
27 |
28 |
--------------------------------------------------------------------------------
/website/src/content/docs/zh-cn/book/merging-and-extension.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 合并与扩展
3 | sidebar:
4 | order: 52
5 | label: 52. 合并与扩展
6 | ---
7 |
8 |
9 | 合并和扩展是指与使用类型和接口相关的两个不同概念。
10 |
11 | 合并允许您将多个同名声明合并到一个定义中,例如,当您多次定义同名接口时:
12 |
13 | ```typescript
14 | interface X {
15 | a: string;
16 | }
17 |
18 | interface X {
19 | b: number;
20 | }
21 |
22 | const person: X = {
23 | a: 'a',
24 | b: 7,
25 | };
26 | ```
27 |
28 | 扩展是指扩展或继承现有类型或接口以创建新类型或接口的能力。它是一种向现有类型添加附加属性或方法而不修改其原始定义的机制。例子:
29 |
30 | ```typescript
31 | interface Animal {
32 | name: string;
33 | eat(): void;
34 | }
35 |
36 | interface Bird extends Animal {
37 | sing(): void;
38 | }
39 |
40 | const dog: Bird = {
41 | name: 'Bird 1',
42 | eat() {
43 | console.log('Eating');
44 | },
45 | sing() {
46 | console.log('Singing');
47 | },
48 | };
49 | ```
50 |
51 |
--------------------------------------------------------------------------------
/website/src/content/docs/zh-cn/book/named-tuple-type-labeled.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 命名元组类型(已标记)
3 | sidebar:
4 | order: 29
5 | label: 29. 命名元组类型(已标记)
6 | ---
7 |
8 |
9 | 元组类型可以包含每个元素的可选标签或名称。 这些标签用于提高可读性和工具帮助,不会影响您可以使用它们执行的操作。
10 |
11 | ```typescript
12 | type T = string;
13 | type Tuple1 = [T, T];
14 | type Tuple2 = [a: T, b: T];
15 | type Tuple3 = [a: T, T]; // 命名元组加匿名元组
16 | ```
17 |
18 |
--------------------------------------------------------------------------------
/website/src/content/docs/zh-cn/book/namespacing.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 命名空间
3 | sidebar:
4 | order: 57
5 | label: 57. 命名空间
6 | ---
7 |
8 |
9 | 在 TypeScript 中,命名空间用于将代码组织到逻辑容器中,防止命名冲突并提供一种将相关代码分组在一起的方法。使用关键字 `export` 允许在"外部"模块中访问名称空间。
10 |
11 | ```typescript
12 | export namespace MyNamespace {
13 | export interface MyInterface1 {
14 | prop1: boolean;
15 | }
16 | export interface MyInterface2 {
17 | prop2: string;
18 | }
19 | }
20 |
21 | const a: MyNamespace.MyInterface1 = {
22 | prop1: true,
23 | };
24 | ```
25 |
26 |
--------------------------------------------------------------------------------
/website/src/content/docs/zh-cn/book/narrowing.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 缩小范围
3 | sidebar:
4 | order: 20
5 | label: 20. 缩小范围
6 | ---
7 |
8 |
9 | TypeScript 缩小范围是细化条件块内变量类型的过程。这在使用联合类型时很有用,其中一个变量可以有多个类型。
10 |
11 | TypeScript 可识别多种缩小类型范围的方法:
12 |
13 | ### typeof 类型保护
14 |
15 | typeof 类型保护是 TypeScript 中的一种特定类型保护,它根据变量的内置 JavaScript 类型检查变量的类型。
16 |
17 | ```typescript
18 | const fn = (x: number | string) => {
19 | if (typeof x === 'number') {
20 | return x + 1; // x 是数字
21 | }
22 | return -1;
23 | };
24 | ```
25 |
26 | ### 真实性缩小
27 |
28 | TypeScript 中的真实性缩小是通过检查变量是真还是假来相应地缩小其类型来实现的。
29 |
30 | ```typescript
31 | const toUpperCase = (name: string | null) => {
32 | if (name) {
33 | return name.toUpperCase();
34 | } else {
35 | return null;
36 | }
37 | };
38 | ```
39 |
40 | ### 相等缩小
41 |
42 | TypeScript 中的相等缩小通过检查变量是否等于特定值来相应缩小其类型。
43 |
44 | 它与`switch`语句和等号运算符(例如`===`、`!==`、`==`和`!=`)结合使用来缩小类型范围。
45 |
46 | ```typescript
47 | const checkStatus = (status: 'success' | 'error') => {
48 | switch (status) {
49 | case 'success':
50 | return true
51 | case 'error':
52 | return null
53 | }
54 | };
55 | ```
56 |
57 | ### In运算符缩小
58 |
59 | TypeScript 中的 `in` 运算符缩小范围是一种根据变量类型中是否存在属性来缩小变量类型的方法。
60 |
61 | ```typescript
62 | type Dog = {
63 | name: string;
64 | breed: string;
65 | };
66 |
67 | type Cat = {
68 | name: string;
69 | likesCream: boolean;
70 | };
71 |
72 | const getAnimalType = (pet: Dog | Cat) => {
73 | if ('breed' in pet) {
74 | return 'dog';
75 | } else {
76 | return 'cat';
77 | }
78 | };
79 | ```
80 |
81 | ### instanceof 缩小
82 |
83 | TypeScript 中的 `instanceof` 运算符缩小是一种根据变量的构造函数缩小变量类型的方法,方法是检查对象是否是某个类或接口的实例。
84 |
85 | ```typescript
86 | class Square {
87 | constructor(public width: number) {}
88 | }
89 | class Rectangle {
90 | constructor(
91 | public width: number,
92 | public height: number
93 | ) {}
94 | }
95 | function area(shape: Square | Rectangle) {
96 | if (shape instanceof Square) {
97 | return shape.width * shape.width;
98 | } else {
99 | return shape.width * shape.height;
100 | }
101 | }
102 | const square = new Square(5);
103 | const rectangle = new Rectangle(5, 10);
104 | console.log(area(square)); // 25
105 | console.log(area(rectangle)); // 50
106 | ```
107 |
108 |
--------------------------------------------------------------------------------
/website/src/content/docs/zh-cn/book/never-type.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Never类型
3 | sidebar:
4 | order: 47
5 | label: 47. Never类型
6 | ---
7 |
8 |
9 | `never` 类型表示从未出现过的值。它用于表示从不返回或抛出错误的函数或表达式。
10 |
11 | 例如无限循环:
12 |
13 | ```typescript
14 | const infiniteLoop = (): never => {
15 | while (true) {
16 | // 做点什么
17 | }
18 | };
19 | ```
20 |
21 | 抛出错误:
22 |
23 | ```typescript
24 | const throwError = (message: string): never => {
25 | throw new Error(message);
26 | };
27 | ```
28 |
29 | `never` 类型对于确保类型安全和捕获代码中的潜在错误很有用。当与其他类型和控制流语句结合使用时,它可以帮助 TypeScript 分析和推断更精确的类型,例如:
30 |
31 | ```typescript
32 | type Direction = 'up' | 'down';
33 | const move = (direction: Direction): void => {
34 | switch (direction) {
35 | case 'up':
36 | // 向上移动
37 | break;
38 | case 'down':
39 | // 向下移动
40 | break;
41 | default:
42 | const exhaustiveCheck: never = direction;
43 | throw new Error(`Unhandled direction: ${exhaustiveCheck}`);
44 | }
45 | };
46 | ```
47 |
48 |
--------------------------------------------------------------------------------
/website/src/content/docs/zh-cn/book/object-types.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 对象类型
3 | sidebar:
4 | order: 27
5 | label: 27. 对象类型
6 | ---
7 |
8 |
9 | 在 TypeScript 中,对象类型描述对象的形状。它们指定对象属性的名称和类型,以及这些属性是必需的还是可选的。
10 |
11 | 在 TypeScript 中,您可以通过两种主要方式定义对象类型:
12 |
13 | 通过指定对象属性的名称、类型和可选性来定义对象的形状的接口。
14 |
15 | ```typescript
16 | interface User {
17 | name: string;
18 | age: number;
19 | email?: string;
20 | }
21 | ```
22 |
23 | 类型别名与接口类似,定义了对象的形状。但是,它还可以基于现有类型或现有类型的组合创建新的自定义类型。这包括定义联合类型、交集类型和其他复杂类型。
24 |
25 | ```typescript
26 | type Point = {
27 | x: number;
28 | y: number;
29 | };
30 | ```
31 |
32 | 也可以匿名定义类型:
33 |
34 | ```typescript
35 | const sum = (x: { a: number; b: number }) => x.a + x.b;
36 | console.log(sum({ a: 5, b: 1 }));
37 | ```
38 |
39 |
--------------------------------------------------------------------------------
/website/src/content/docs/zh-cn/book/optional-properties.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 可选属性
3 | sidebar:
4 | order: 12
5 | label: 12. 可选属性
6 | ---
7 |
8 |
9 | 对象可以通过在属性名称末尾添加问号 `?` 来指定可选属性:
10 |
11 | ```typescript
12 | type X = {
13 | a: number;
14 | b?: number; // 可选的
15 | };
16 | ```
17 |
18 | 当属性是可选的时,可以指定默认值
19 |
20 | ```typescript
21 | type X = {
22 | a: number;
23 | b?: number;
24 | };
25 | const x = ({ a, b = 100 }: X) => a + b;
26 | ```
27 |
28 |
--------------------------------------------------------------------------------
/website/src/content/docs/zh-cn/book/overloads.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 重载
3 | sidebar:
4 | order: 51
5 | label: 51. 重载
6 | ---
7 |
8 |
9 | TypeScript 中的函数重载允许您为单个函数名称定义多个函数签名,从而使您能够定义可以多种方式调用的函数。这是一个例子:
10 |
11 | ```typescript
12 | // 重载
13 | function sayHi(name: string): string;
14 | function sayHi(names: string[]): string[];
15 |
16 | // 实现
17 | function sayHi(name: unknown): unknown {
18 | if (typeof name === 'string') {
19 | return `Hi, ${name}!`;
20 | } else if (Array.isArray(name)) {
21 | return name.map(name => `Hi, ${name}!`);
22 | }
23 | throw new Error('Invalid value');
24 | }
25 |
26 | sayHi('xx'); // 有效
27 | sayHi(['aa', 'bb']); // 有效
28 | ```
29 |
30 | 这是在 `class` 中使用函数重载的另一个示例:
31 |
32 | ```typescript
33 | class Greeter {
34 | message: string;
35 |
36 | constructor(message: string) {
37 | this.message = message;
38 | }
39 |
40 | // 重载
41 | sayHi(name: string): string;
42 | sayHi(names: string[]): ReadonlyArray;
43 |
44 | // 实现
45 | sayHi(name: unknown): unknown {
46 | if (typeof name === 'string') {
47 | return `${this.message}, ${name}!`;
48 | } else if (Array.isArray(name)) {
49 | return name.map(name => `${this.message}, ${name}!`);
50 | }
51 | throw new Error('value is invalid');
52 | }
53 | }
54 | console.log(new Greeter('Hello').sayHi('Simon'));
55 | ```
56 |
57 |
--------------------------------------------------------------------------------
/website/src/content/docs/zh-cn/book/predefined-conditional-types.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 预定义条件类型
3 | sidebar:
4 | order: 42
5 | label: 42. 预定义条件类型
6 | ---
7 |
8 |
9 | 在 TypeScript 中,预定义的条件类型是语言提供的内置条件类型。它们旨在根据给定类型的特征执行常见的类型转换。
10 |
11 | `Exclude`: 此类型从 Type 中删除可分配给 ExcludedType 的所有类型。
12 |
13 | `Extract`: 此类型从 Union 中提取可分配给 Type 的所有类型。
14 |
15 | `NonNullable`: 此类型从 Type 中删除 null 和 undefined。
16 |
17 | `ReturnType`: 此类型提取函数 Type 的返回类型。
18 |
19 | `Parameters`: 该类型提取函数类型的参数类型。
20 |
21 | `Required`: 此类型使 Type 中的所有属性成为必需。
22 |
23 | `Partial`: 此类型使 Type 中的所有属性都是可选的。
24 |
25 | `Readonly`: 此类型使 Type 中的所有属性变为只读。
26 |
27 |
--------------------------------------------------------------------------------
/website/src/content/docs/zh-cn/book/readonly-properties.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 只读属性
3 | sidebar:
4 | order: 13
5 | label: 13. 只读属性
6 | ---
7 |
8 |
9 | 是否可以通过使用修饰符来防止对属性进行写入,`readonly` 以确保该属性不能被重写,但不提供任何完全不变性的保证:
10 |
11 | ```typescript
12 | interface Y {
13 | readonly a: number;
14 | }
15 |
16 | type X = {
17 | readonly a: number;
18 | };
19 |
20 | type J = Readonly<{
21 | a: number;
22 | }>;
23 |
24 | type K = {
25 | readonly [index: number]: string;
26 | };
27 | ```
28 |
29 |
--------------------------------------------------------------------------------
/website/src/content/docs/zh-cn/book/strictnullchecks.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 严格空检查
3 | sidebar:
4 | order: 18
5 | label: 18. 严格空检查
6 | ---
7 |
8 |
9 | `strictNullChecks` 是一个 TypeScript 编译器选项,强制执行严格的 null 检查。启用此选项后,只有在变量和参数已使用联合类型 `null` | `undefined` 显式声明为该类型时,才可以对其进行赋值`null` 或者 `undefined`。如果变量或参数未显式声明为可为空,TypeScript 将生成错误以防止潜在的运行时错误。
10 |
11 |
--------------------------------------------------------------------------------
/website/src/content/docs/zh-cn/book/symbols.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Symbols
3 | sidebar:
4 | order: 58
5 | label: 58. Symbols
6 | ---
7 |
8 |
9 | 符号是一种原始数据类型,表示不可变值,保证在程序的整个生命周期中全局唯一。
10 |
11 | 符号可以用作对象属性的键,并提供一种创建不可枚举属性的方法。
12 |
13 | ```typescript
14 | const key1: symbol = Symbol('key1');
15 | const key2: symbol = Symbol('key2');
16 |
17 | const obj = {
18 | [key1]: 'value 1',
19 | [key2]: 'value 2',
20 | };
21 |
22 | console.log(obj[key1]); // value 1
23 | console.log(obj[key2]); // value 2
24 | ```
25 |
26 | 在 WeakMap 和 WeakSet 中,现在允许符号作为键。
27 |
28 |
--------------------------------------------------------------------------------
/website/src/content/docs/zh-cn/book/template-union-types.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 模板联合类型
3 | sidebar:
4 | order: 43
5 | label: 43. 模板联合类型
6 | ---
7 |
8 |
9 | 模板联合类型可用于合并和操作类型系统内的文本,例如:
10 |
11 | ```typescript
12 | type Status = 'active' | 'inactive';
13 | type Products = 'p1' | 'p2';
14 | type ProductId = `id-${Products}-${Status}`; // "id-p1-active" | "id-p1-inactive" | "id-p2-active" | "id-p2-inactive"
15 | ```
16 |
17 |
--------------------------------------------------------------------------------
/website/src/content/docs/zh-cn/book/the-concise-typescript-book.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 简洁的TypeScript之书
3 | sidebar:
4 | order: 1
5 | label: 1. 简洁的TypeScript之书
6 | ---
7 |
8 |
9 | 《Concise TypeScript Book》全面而简洁地概述了 TypeScript 的功能。它提供了清晰的解释,涵盖了该语言最新版本中的所有方面,从强大的类型系统到高级功能。无论您是初学者还是经验丰富的开发人员,本书都是增强您对 TypeScript 的理解和熟练程度的宝贵资源。
10 |
11 | 本书完全免费且开源。
12 |
13 | 如果您发现这本 TypeScript 书籍很有价值并希望做出贡献,请考虑通过 PayPal 支持我的努力。谢谢!
14 |
15 | [](https://www.paypal.com/donate/?business=QW82ZS956XLFY&no_recurring=0¤cy_code=EUR)
16 |
17 |
--------------------------------------------------------------------------------
/website/src/content/docs/zh-cn/book/the-never-type.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: never 类型
3 | sidebar:
4 | order: 25
5 | label: 25. never 类型
6 | ---
7 |
8 |
9 | 当变量缩小为不能包含任何值的类型时,TypeScript 编译器将推断该变量必须属于该never类型。这是因为 never 类型代表永远无法生成的值。
10 |
11 | ```typescript
12 | const printValue = (val: string | number) => {
13 | if (typeof val === 'string') {
14 | console.log(val.toUpperCase());
15 | } else if (typeof val === 'number') {
16 | console.log(val.toFixed(2));
17 | } else {
18 | // val 在这里的类型为 never,因为它只能是字符串或数字
19 | const neverVal: never = val;
20 | console.log(`Unexpected value: ${neverVal}`);
21 | }
22 | };
23 | ```
24 |
25 |
--------------------------------------------------------------------------------
/website/src/content/docs/zh-cn/book/translations.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 翻译
3 | sidebar:
4 | order: 2
5 | label: 2. 翻译
6 | ---
7 |
8 |
9 | 本书已被翻译成多种语言版本,包括:
10 |
11 | [中文](https://github.com/gibbok/typescript-book/blob/main/README-zh_CN.md)
12 |
13 |
--------------------------------------------------------------------------------
/website/src/content/docs/zh-cn/book/triple-slash-directives.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 三斜杠指令
3 | sidebar:
4 | order: 59
5 | label: 59. 三斜杠指令
6 | ---
7 |
8 |
9 | 三斜杠指令是特殊注释,为编译器提供有关如何处理文件的说明。这些指令以三个连续斜杠 (`///`) 开头,通常放置在 TypeScript 文件的顶部,对运行时行为没有影响。
10 |
11 | 三斜杠指令用于引用外部依赖项、指定模块加载行为、启用/禁用某些编译器功能等等。几个例子:
12 |
13 | 引用声明文件:
14 |
15 |
16 | ```typescript
17 | ///
18 | ```
19 |
20 | 指明模块格式:
21 |
22 |
23 | ```typescript
24 | ///
25 | ```
26 |
27 | 启用编译器选项,在以下示例中严格模式:
28 |
29 |
30 | ```typescript
31 | ///
32 | ```
33 |
34 |
--------------------------------------------------------------------------------
/website/src/content/docs/zh-cn/book/tuple-type-anonymous.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 元组类型(匿名)
3 | sidebar:
4 | order: 28
5 | label: 28. 元组类型(匿名)
6 | ---
7 |
8 |
9 | 元组类型是一种表示具有固定数量的元素及其相应类型的数组的类型。元组类型以固定顺序强制执行特定数量的元素及其各自的类型。当您想要表示具有特定类型的值的集合时,元组类型非常有用,其中数组中每个元素的位置都有特定的含义。
10 |
11 | ```typescript
12 | type Point = [number, number];
13 | ```
14 |
15 |
--------------------------------------------------------------------------------
/website/src/content/docs/zh-cn/book/type-annotations.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 类型注释
3 | sidebar:
4 | order: 11
5 | label: 11. 类型注释
6 | ---
7 |
8 |
9 | 在使用 `var` 、 `let` 和 `const` 声明变量时,可以选择添加类型:
10 |
11 | ```typescript
12 | const x: number = 1;
13 | ```
14 |
15 | TypeScript 在推断类型方面做得很好,尤其是简单类型时,因此在大多数情况下这些声明是不必要的。
16 |
17 | 在函数上可以向参数添加类型注释:
18 |
19 | ```typescript
20 | function sum(a: number, b: number) {
21 | return a + b;
22 | }
23 | ```
24 |
25 | 以下是使用匿名函数(所谓的 lambda 函数)的示例:
26 |
27 | ```typescript
28 | const sum = (a: number, b: number) => a + b;
29 | ```
30 |
31 | 当参数存在默认值时可以避免这些注释:
32 |
33 | ```typescript
34 | const sum = (a = 10, b: number) => a + b;
35 | ```
36 |
37 | 可以将返回类型注释添加到函数中:
38 |
39 | ```typescript
40 | const sum = (a = 10, b: number): number => a + b;
41 | ```
42 |
43 | 这对于更复杂的函数尤其有用,因为在实现之前编写显式返回类型可以帮助更好地思考该函数。
44 |
45 | 通常考虑注释类型签名,但不注释主体局部变量,并始终将类型添加到对象字面量中。
46 |
47 |
--------------------------------------------------------------------------------
/website/src/content/docs/zh-cn/book/type-from-func-return.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Func 返回值的类型
3 | sidebar:
4 | order: 35
5 | label: 35. Func 返回值的类型
6 | ---
7 |
8 |
9 | Func Return 中的类型是指根据函数的实现自动推断函数的返回类型的能力。这允许 TypeScript 无需显式类型注释即可确定函数返回值的类型。
10 |
11 | ```typescript
12 | const add = (x: number, y: number) => x + y; // TypeScript 可以推断函数的返回类型是数字
13 | ```
14 |
15 |
--------------------------------------------------------------------------------
/website/src/content/docs/zh-cn/book/type-from-module.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 模块的类型
3 | sidebar:
4 | order: 36
5 | label: 36. 模块的类型
6 | ---
7 |
8 |
9 | 模块的类型是指使用模块的导出值自动推断其类型的能力。当模块导出特定类型的值时,TypeScript 可以使用该信息在将该值导入到另一个模块时自动推断该值的类型。
10 |
11 |
12 | ```typescript
13 | export const add = (x: number, y: number) => x + y;
14 | // index.ts
15 | import { add } from 'calc';
16 | const r = add(1, 2); // r 是 number 类型
17 | ```
18 |
19 |
--------------------------------------------------------------------------------
/website/src/content/docs/zh-cn/book/type-from-value.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 值的类型
3 | sidebar:
4 | order: 34
5 | label: 34. 值的类型
6 | ---
7 |
8 |
9 | TypeScript 中的"Type from Value"是指通过类型推断从值或表达式自动推断出类型。
10 |
11 | ```typescript
12 | const x = 'x'; // TypeScript 可以自动推断变量的类型是 string
13 | ```
14 |
15 |
--------------------------------------------------------------------------------
/website/src/content/docs/zh-cn/book/type-indexing.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 类型索引
3 | sidebar:
4 | order: 33
5 | label: 33. 类型索引
6 | ---
7 |
8 |
9 | 类型索引是指能够通过预先未知的键来定义可以索引的类型,使用索引签名来指定未显式声明的属性的类型。
10 |
11 | ```typescript
12 | type Dictionary = {
13 | [key: string]: T;
14 | };
15 | const myDict: Dictionary = { a: 'a', b: 'b' };
16 | console.log(myDict['a']); // 返回 a
17 | ```
18 |
19 |
--------------------------------------------------------------------------------
/website/src/content/docs/zh-cn/book/type-predicates.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 类型谓词
3 | sidebar:
4 | order: 23
5 | label: 23. 类型谓词
6 | ---
7 |
8 |
9 | TypeScript 中的类型谓词是返回布尔值的函数,用于将变量的类型缩小为更具体的类型。
10 |
11 | ```typescript
12 | const isString = (value: unknown): value is string => typeof value === 'string';
13 |
14 | const foo = (bar: unknown) => {
15 | if (isString(bar)) {
16 | console.log(bar.toUpperCase());
17 | } else {
18 | console.log('not a string');
19 | }
20 | };
21 | ```
22 |
23 |
--------------------------------------------------------------------------------
/website/src/content/docs/zh-cn/book/union-type.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 联合类型
3 | sidebar:
4 | order: 31
5 | label: 31. 联合类型
6 | ---
7 |
8 |
9 | 联合类型是一种表示值的类型,该值可以是多种类型之一。联合类型使用 `|` 表示 每种可能类型之间的符号。
10 |
11 | ```typescript
12 | let x: string | number;
13 | x = 'hello'; // 有效
14 | x = 123; // 有效
15 | ```
16 |
17 |
--------------------------------------------------------------------------------
/website/src/content/docs/zh-cn/book/unknown-type.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 未知类型
3 | sidebar:
4 | order: 45
5 | label: 45. 未知类型
6 | ---
7 |
8 |
9 | 在 TypeScript 中,未知类型表示未知类型的值。与允许任何类型值的 `any` 类型不同,`unknown` 需要在以特定方式使用它之前进行类型检查或断言,因此在未首先断言或缩小到更具体的类型的情况下,不允许对 `unknown` 进行任何操作 。
10 |
11 | `unknown` 类型只能分配给任何类型和未知类型本身,它是any 的类型安全替代方案。
12 |
13 |
14 | ```typescript
15 | let value: unknown;
16 |
17 | let value1: unknown = value; // 有效
18 | let value2: any = value; // 有效
19 | let value3: boolean = value; // 无效
20 | let value4: number = value; // 无效
21 | ```
22 |
23 | ```typescript
24 | const add = (a: unknown, b: unknown): number | undefined =>
25 | typeof a === 'number' && typeof b === 'number' ? a + b : undefined;
26 | console.log(add(1, 2)); // 3
27 | console.log(add('x', 2)); // undefined
28 | ```
29 |
30 |
--------------------------------------------------------------------------------
/website/src/content/docs/zh-cn/book/void-type.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 空类型
3 | sidebar:
4 | order: 46
5 | label: 46. 空类型
6 | ---
7 |
8 |
9 | `void` 类型用于指示函数不返回值。
10 |
11 | ```typescript
12 | const sayHello = (): void => {
13 | console.log('Hello!');
14 | };
15 | ```
16 |
17 |
--------------------------------------------------------------------------------
/website/src/content/docs/zh-cn/index.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Typescript Book
3 | description: The Concise TypeScript Book
4 | template: splash
5 | hero:
6 | tagline: 《Concise TypeScript Book》全面而简洁地概述了 TypeScript
7 | 的功能。它提供了清晰的解释,涵盖了该语言最新版本中的所有方面,从强大的类型系统到高级功能。无论您是初学者还是经验丰富的开发人员,本书都是增强您对
8 | TypeScript 的理解和熟练程度的宝贵资源。
本书完全免费且开源。
9 | actions:
10 | - text: 现在读!
11 | link: /typescript-book/zh-cn/book/the-concise-typescript-book/
12 | icon: right-arrow
13 | variant: primary
14 | - text: GitHub
15 | link: https://github.com/gibbok/typescript-book
16 | icon: github
17 | variant: secondary
18 | - text: X.com
19 | link: https://twitter.com/gibbok_coding
20 | icon: x.com
21 | variant: secondary
22 | ---
23 |
--------------------------------------------------------------------------------
/website/src/content/i18n/zh-cn.json:
--------------------------------------------------------------------------------
1 | {}
--------------------------------------------------------------------------------
/website/src/env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 | ///
3 |
--------------------------------------------------------------------------------
/website/src/styles/custom.css:
--------------------------------------------------------------------------------
1 | /* Dark mode colors. */
2 | :root {
3 | --sl-color-accent-low: #36113e;
4 | --sl-color-accent: #a400c0;
5 | --sl-color-accent-high: #e3b6ed;
6 | --sl-color-white: #ffffff;
7 | --sl-color-gray-1: #f2e9fd;
8 | --sl-color-gray-2: #c7bdd5;
9 | --sl-color-gray-3: #9581ae;
10 | --sl-color-gray-4: #614e78;
11 | --sl-color-gray-5: #412e55;
12 | --sl-color-gray-6: #2f1c42;
13 | --sl-color-black: #1c1425;
14 | }
15 | /* Light mode colors. */
16 | :root[data-theme='light'] {
17 | --sl-color-accent-low: #ebc9f3;
18 | --sl-color-accent: #a700c3;
19 | --sl-color-accent-high: #4e0e5b;
20 | --sl-color-white: #1c1425;
21 | --sl-color-gray-1: #2f1c42;
22 | --sl-color-gray-2: #412e55;
23 | --sl-color-gray-3: #614e78;
24 | --sl-color-gray-4: #9581ae;
25 | --sl-color-gray-5: #c7bdd5;
26 | --sl-color-gray-6: #f2e9fd;
27 | --sl-color-gray-7: #f8f4fe;
28 | --sl-color-black: #ffffff;
29 | }
--------------------------------------------------------------------------------
/website/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "astro/tsconfigs/strict"
3 | }
--------------------------------------------------------------------------------