├── github-page ├── static │ ├── .nojekyll │ └── img │ │ ├── favicon.ico │ │ ├── docusaurus.png │ │ └── logo.svg ├── blog │ ├── _2023-04-13-equality-is-hard.mdx │ ├── authors.yml │ └── 2022-05-15-eslint-plugin-peer-deps.mdx ├── docs │ ├── typescript_features │ │ ├── _category_.yml │ │ └── _type_guard.mdx │ ├── guidelines │ │ ├── files_and_folders │ │ │ └── _category_.yml │ │ ├── README.md │ │ └── project │ │ │ ├── npmignore.mdx │ │ │ ├── package_name.mdx │ │ │ └── package_json.mdx │ ├── tsconfig │ │ ├── _isolated_modules.mdx │ │ ├── _module_resolution.mdx │ │ └── declaration_map.mdx │ ├── tips │ │ └── _type_cannot_be_named.md │ └── README.md ├── babel.config.js ├── src │ ├── pages │ │ ├── markdown-page.md │ │ ├── index.module.css │ │ └── index.js │ ├── components │ │ └── HomepageFeatures │ │ │ ├── styles.module.css │ │ │ └── index.js │ └── css │ │ └── custom.css ├── docusaurus-example │ ├── docs │ │ ├── tutorial-extras │ │ │ ├── _category_.json │ │ │ ├── img │ │ │ │ ├── localeDropdown.png │ │ │ │ └── docsVersionDropdown.png │ │ │ ├── manage-docs-versions.md │ │ │ └── translate-your-site.md │ │ ├── tutorial-basics │ │ │ ├── _category_.json │ │ │ ├── deploy-your-site.md │ │ │ ├── congratulations.md │ │ │ ├── create-a-blog-post.md │ │ │ ├── create-a-page.md │ │ │ └── create-a-document.md │ │ └── intro.md │ └── blog │ │ ├── 2021-08-26-welcome │ │ ├── docusaurus-plushie-banner.jpeg │ │ └── index.md │ │ ├── 2019-05-28-first-blog-post.md │ │ ├── 2021-08-01-mdx-blog-post.mdx │ │ └── authors.yml ├── .gitignore ├── sidebars.js └── package.json ├── docs ├── drafts │ ├── 09-tooling │ │ ├── eslint.md │ │ ├── tersify.md │ │ ├── assertron.md │ │ ├── mocktomata.md │ │ ├── prettier.md │ │ ├── satisfier.md │ │ └── README.md │ ├── 02-javascript-syntax │ │ ├── symbol.md │ │ ├── generator.md │ │ └── ternary.md │ ├── 04-typescript-syntax │ │ ├── type-guard.md │ │ ├── indexed-type.md │ │ ├── type-definition.md │ │ ├── mapped-type.md │ │ ├── intersection-type.md │ │ ├── type-modifier.md │ │ └── generics.md │ ├── 06-files-and-projects │ │ └── projects.md │ ├── extra-material.md │ ├── es2015.md │ ├── types.md │ ├── control-statements.md │ ├── events.md │ ├── properties.md │ ├── semicolons.md │ ├── iterators-and-generators.md │ ├── emoji.md │ ├── modules.md │ ├── file-structures.md │ ├── commas.md │ ├── destructuring.md │ ├── type-casting-and-coercion.md │ ├── blocks.md │ └── strings.md ├── pages │ ├── 04-typescript-syntax │ │ ├── namespace.md │ │ ├── basic-types.md │ │ ├── type-alias.md │ │ ├── optional-parameters.md │ │ ├── README.md │ │ ├── conditional-types.md │ │ ├── union-type.md │ │ ├── any.md │ │ ├── enum.md │ │ ├── modules.md │ │ ├── interfaces.md │ │ └── namespaces-and-modules.md │ ├── 05-typescript-features │ │ ├── configuration.md │ │ ├── build-in-types.md │ │ ├── README.md │ │ ├── language-service-plugin.md │ │ └── recursive-types.md │ ├── 09-tooling │ │ ├── sort-package.json.md │ │ ├── README.md │ │ ├── jest.md │ │ └── vscode.md │ ├── typings │ │ ├── TOPICS.md │ │ ├── distribution.md │ │ ├── functions │ │ │ ├── param-types.md │ │ │ └── overloading.md │ │ ├── README.md │ │ ├── functions.md │ │ ├── shape-of-typings.md │ │ ├── tslint.md │ │ └── namespaces-and-modules.md │ ├── 06-typescript-usage │ │ ├── README.md │ │ ├── styling.md │ │ └── explicit-vs-implicit-types.md │ ├── 03-javascript-features │ │ ├── eval.md │ │ └── optional-parameters.md │ ├── 07-files-and-projects │ │ ├── package.json.md │ │ ├── file-organization.md │ │ ├── README.md │ │ └── file-types.md │ ├── 02-javascript-syntax │ │ ├── object-literal.md │ │ ├── assignment.md │ │ ├── object-destructuring.md │ │ ├── README.md │ │ ├── decorator.md │ │ ├── error.md │ │ ├── boolean.md │ │ ├── async-await.md │ │ └── this.md │ ├── 00-updates │ │ └── README.md │ └── 01-introduction │ │ └── what-is-typescript.md ├── package.json ├── GLOSSARY.md └── scripts │ └── lint.ts ├── .husky └── commit-msg ├── examples ├── eslint-plugin-peer │ ├── src │ │ └── index.ts │ ├── .eslintrc.json │ └── package.json ├── array │ └── standard │ │ ├── declare-style.bad.ts │ │ ├── empty-must-declare.ts │ │ ├── declare-style.good.ts │ │ ├── declare-generic.bad.ts │ │ ├── declare-generic.good.ts │ │ ├── declare-generic.ok.ts │ │ └── tsconfig.json ├── tuple │ └── standard │ │ ├── labeled-tuple.bad.ts │ │ ├── labeled-tuple.good.ts │ │ ├── as-const.ts │ │ ├── tsconfig.json │ │ └── variadic.ts ├── property-accessor │ └── standard │ │ ├── no-passthrough.good.ts │ │ ├── no-passthrough.bad.ts │ │ └── tsconfig.json └── unknown │ └── standard │ ├── catch-clauses.good.ts │ ├── function-param.ts │ ├── catch-clauses.bad.ts │ ├── tsconfig.json │ └── catch-clauses.type-plus.good.ts ├── .npmrc ├── apps ├── starlight │ ├── tsconfig.json │ ├── src │ │ ├── content │ │ │ ├── drafts │ │ │ │ └── blogs │ │ │ │ │ └── _2023-04-13-equality-is-hard.mdx │ │ │ ├── docs │ │ │ │ ├── tsconfig │ │ │ │ │ ├── _isolated_modules.mdx │ │ │ │ │ ├── _module_resolution.mdx │ │ │ │ │ └── declaration-map.mdx │ │ │ │ ├── tips │ │ │ │ │ └── _type_cannot_be_named.md │ │ │ │ ├── guidelines │ │ │ │ │ └── project │ │ │ │ │ │ ├── npmignore.mdx │ │ │ │ │ │ ├── package-name.mdx │ │ │ │ │ │ └── package-json.mdx │ │ │ │ ├── index.mdx │ │ │ │ ├── typescript-features │ │ │ │ │ └── _type_guard.mdx │ │ │ │ └── guides │ │ │ │ │ └── welcome.md │ │ │ ├── config.ts │ │ │ └── blogs │ │ │ │ └── 2022-05-15-eslint-plugin-peer-deps.mdx │ │ ├── env.d.ts │ │ ├── assets │ │ │ ├── houston.webp │ │ │ └── logo.svg │ │ ├── pages │ │ │ └── blogs │ │ │ │ ├── index.astro │ │ │ │ └── [...slug].astro │ │ └── components │ │ │ ├── blogs_list.astro │ │ │ └── blog_post_info.astro │ ├── tailwind.config.mjs │ ├── .gitignore │ ├── package.json │ ├── public │ │ └── favicon.svg │ └── astro.config.mjs └── tutorial │ ├── src │ ├── env.d.ts │ ├── components │ │ ├── navigation.astro │ │ ├── hamburger.astro │ │ ├── header.astro │ │ ├── social.astro │ │ └── footer.astro │ ├── scripts │ │ └── menu.js │ ├── pages │ │ ├── index.astro │ │ ├── blog.astro │ │ ├── posts │ │ │ └── [...slug].astro │ │ └── about.astro │ ├── layouts │ │ ├── markdown_post_layout.astro │ │ └── base_layout.astro │ ├── content │ │ ├── config.ts │ │ └── posts │ │ │ ├── post-1.md │ │ │ └── post-2.md │ └── styles │ │ └── global.css │ ├── tsconfig.json │ ├── .vscode │ ├── extensions.json │ └── launch.json │ ├── astro.config.mjs │ ├── .gitignore │ ├── package.json │ ├── public │ └── favicon.svg │ └── README.md ├── pnpm-workspace.yaml ├── commitlint.config.js ├── .github ├── renovate.json ├── workflows │ ├── pull-request.yaml │ ├── release.yml │ └── deploy-page.yml └── mergify.yml ├── page ├── src │ ├── env.d.ts │ ├── pages │ │ ├── tsconfig │ │ │ ├── declaration-map.png │ │ │ └── declaration-map.mdx │ │ ├── index.astro │ │ ├── blogs.astro │ │ └── blackbook.astro │ ├── layouts │ │ ├── Layout.astro │ │ └── DocLayout.astro │ └── components │ │ ├── GitHubBadge.tsx │ │ ├── Header.tsx │ │ └── Card.astro ├── .vscode │ ├── extensions.json │ └── launch.json ├── tsconfig.json ├── astro.config.mjs ├── .gitignore ├── tailwind.config.cjs ├── package.json ├── public │ └── svgs │ │ ├── github-mark-white.svg │ │ ├── github-mark.svg │ │ └── readme-svgrepo-com.svg └── README.md ├── slides ├── _revealjs │ └── uni.png ├── ts.declaration-map.png ├── ts.declaration-map.slides.md └── ts.module-resolution.slides.md ├── .prettierignore ├── .gitattributes ├── tools ├── devpkg-typescript │ ├── tsconfig.json │ └── templates │ │ ├── tsconfig.json │ │ └── tsconfig.base.json └── style │ └── package.json ├── exercises └── this.ts ├── .vscode ├── launch.json ├── extensions.json ├── ltex.hiddenFalsePositives.en-US.txt ├── ltex.dictionary.en-US.txt └── settings.json ├── .editorconfig ├── tsconfig.json ├── .markdownlint-cli2.jsonc ├── .prettierrc.js ├── package.json ├── turbo.json ├── LICENSE ├── .cursor └── rules │ ├── templates │ └── cursor_rules.mdc │ ├── guidelines │ ├── voice_and_tone.mdc │ └── review_rubric.mdc │ └── project │ ├── repository_structure.mdc │ └── overview.mdc └── .gitignore /github-page/static/.nojekyll: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/drafts/09-tooling/eslint.md: -------------------------------------------------------------------------------- 1 | # eslint 2 | -------------------------------------------------------------------------------- /docs/drafts/09-tooling/tersify.md: -------------------------------------------------------------------------------- 1 | # tersify 2 | -------------------------------------------------------------------------------- /docs/drafts/09-tooling/assertron.md: -------------------------------------------------------------------------------- 1 | # assertron 2 | -------------------------------------------------------------------------------- /docs/drafts/09-tooling/mocktomata.md: -------------------------------------------------------------------------------- 1 | # mocktomata 2 | -------------------------------------------------------------------------------- /docs/drafts/09-tooling/prettier.md: -------------------------------------------------------------------------------- 1 | # prettier 2 | -------------------------------------------------------------------------------- /docs/drafts/09-tooling/satisfier.md: -------------------------------------------------------------------------------- 1 | # satisfier 2 | -------------------------------------------------------------------------------- /docs/drafts/02-javascript-syntax/symbol.md: -------------------------------------------------------------------------------- 1 | # symbol 2 | -------------------------------------------------------------------------------- /.husky/commit-msg: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | pnpm commitlint --edit $1 3 | -------------------------------------------------------------------------------- /docs/drafts/02-javascript-syntax/generator.md: -------------------------------------------------------------------------------- 1 | # generator 2 | -------------------------------------------------------------------------------- /docs/drafts/04-typescript-syntax/type-guard.md: -------------------------------------------------------------------------------- 1 | # Type Guard 2 | -------------------------------------------------------------------------------- /docs/drafts/06-files-and-projects/projects.md: -------------------------------------------------------------------------------- 1 | # projects 2 | -------------------------------------------------------------------------------- /docs/drafts/04-typescript-syntax/indexed-type.md: -------------------------------------------------------------------------------- 1 | # Indexed Type 2 | -------------------------------------------------------------------------------- /examples/eslint-plugin-peer/src/index.ts: -------------------------------------------------------------------------------- 1 | export const empty = {} 2 | -------------------------------------------------------------------------------- /docs/drafts/04-typescript-syntax/type-definition.md: -------------------------------------------------------------------------------- 1 | # type definition 2 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | # Expose Astro dependencies for `pnpm` users 2 | shamefully-hoist=true -------------------------------------------------------------------------------- /apps/starlight/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "astro/tsconfigs/strict" 3 | } -------------------------------------------------------------------------------- /apps/tutorial/src/env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /github-page/blog/_2023-04-13-equality-is-hard.mdx: -------------------------------------------------------------------------------- 1 | 2 | 3 | - not sound 4 | - 5 | -------------------------------------------------------------------------------- /github-page/docs/typescript_features/_category_.yml: -------------------------------------------------------------------------------- 1 | label: TypeScript Features 2 | -------------------------------------------------------------------------------- /pnpm-workspace.yaml: -------------------------------------------------------------------------------- 1 | packages: 2 | - apps/* 3 | - github-page 4 | - page 5 | -------------------------------------------------------------------------------- /commitlint.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { extends: ['@commitlint/config-conventional'] } 2 | -------------------------------------------------------------------------------- /examples/array/standard/declare-style.bad.ts: -------------------------------------------------------------------------------- 1 | const arrayGeneric = new Array() 2 | -------------------------------------------------------------------------------- /github-page/docs/guidelines/files_and_folders/_category_.yml: -------------------------------------------------------------------------------- 1 | label: Files and Folders 2 | -------------------------------------------------------------------------------- /examples/array/standard/empty-must-declare.ts: -------------------------------------------------------------------------------- 1 | export const x: string[] = [] 2 | x.push('abc') 3 | -------------------------------------------------------------------------------- /examples/tuple/standard/labeled-tuple.bad.ts: -------------------------------------------------------------------------------- 1 | type RangeObj = { start: number, end: number } 2 | -------------------------------------------------------------------------------- /examples/tuple/standard/labeled-tuple.good.ts: -------------------------------------------------------------------------------- 1 | type RangeTuple = [start: number, end: number] 2 | -------------------------------------------------------------------------------- /.github/renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "github>unional/renovate-preset" 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /apps/starlight/src/content/drafts/blogs/_2023-04-13-equality-is-hard.mdx: -------------------------------------------------------------------------------- 1 | 2 | 3 | - not sound 4 | - 5 | -------------------------------------------------------------------------------- /examples/property-accessor/standard/no-passthrough.good.ts: -------------------------------------------------------------------------------- 1 | const justProperty = { 2 | age: 10 3 | } 4 | -------------------------------------------------------------------------------- /page/src/env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | -------------------------------------------------------------------------------- /slides/_revealjs/uni.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unional/typescript-blackbook/HEAD/slides/_revealjs/uni.png -------------------------------------------------------------------------------- /apps/starlight/src/env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | -------------------------------------------------------------------------------- /docs/drafts/04-typescript-syntax/mapped-type.md: -------------------------------------------------------------------------------- 1 | # Mapped Type 2 | 3 | `{ [k in X]: Y }` 4 | `{ [k in keyof X]: Y }` 5 | -------------------------------------------------------------------------------- /examples/array/standard/declare-style.good.ts: -------------------------------------------------------------------------------- 1 | const arrayLiteral: string[] = [] 2 | const arrayCast = [] as string[] 3 | -------------------------------------------------------------------------------- /slides/ts.declaration-map.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unional/typescript-blackbook/HEAD/slides/ts.declaration-map.png -------------------------------------------------------------------------------- /github-page/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [require.resolve('@docusaurus/core/lib/babel/preset')], 3 | }; 4 | -------------------------------------------------------------------------------- /examples/tuple/standard/as-const.ts: -------------------------------------------------------------------------------- 1 | const obj = { a: 1 } 2 | 3 | // [1, 2, { a: 1 }] 4 | const tupleConst = [1, 2, obj] as const 5 | -------------------------------------------------------------------------------- /github-page/static/img/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unional/typescript-blackbook/HEAD/github-page/static/img/favicon.ico -------------------------------------------------------------------------------- /page/.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": ["astro-build.astro-vscode"], 3 | "unwantedRecommendations": [] 4 | } 5 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | dist 2 | node_modules 3 | .github 4 | .changeset 5 | 6 | *.json 7 | *.md 8 | *.mdx 9 | *.yml 10 | *.yaml 11 | -------------------------------------------------------------------------------- /apps/tutorial/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "astro/tsconfigs/strict", 3 | "compilerOptions": { 4 | "allowJs": true 5 | } 6 | } -------------------------------------------------------------------------------- /docs/drafts/04-typescript-syntax/intersection-type.md: -------------------------------------------------------------------------------- 1 | # Intersaction Type 2 | 3 | Intersaction type combines multiple types into one. 4 | -------------------------------------------------------------------------------- /github-page/static/img/docusaurus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unional/typescript-blackbook/HEAD/github-page/static/img/docusaurus.png -------------------------------------------------------------------------------- /page/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "astro/tsconfigs/strict", 3 | "compilerOptions": { 4 | "jsx": "react-jsx" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /apps/starlight/src/assets/houston.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unional/typescript-blackbook/HEAD/apps/starlight/src/assets/houston.webp -------------------------------------------------------------------------------- /apps/tutorial/.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": ["astro-build.astro-vscode"], 3 | "unwantedRecommendations": [] 4 | } 5 | -------------------------------------------------------------------------------- /docs/drafts/04-typescript-syntax/type-modifier.md: -------------------------------------------------------------------------------- 1 | # Type Modifier 2 | 3 | ## Remove optional 4 | 5 | `{ [key in typeof T]-?: string }` 6 | -------------------------------------------------------------------------------- /page/src/pages/tsconfig/declaration-map.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unional/typescript-blackbook/HEAD/page/src/pages/tsconfig/declaration-map.png -------------------------------------------------------------------------------- /examples/array/standard/declare-generic.bad.ts: -------------------------------------------------------------------------------- 1 | let simpleGeneric: Array 2 | 3 | type Person = {} 4 | let complexGeneric: { people: Person[] }[] 5 | -------------------------------------------------------------------------------- /examples/eslint-plugin-peer/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "react-app" 4 | ], 5 | "plugins": [ 6 | "@typescript-eslint" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /examples/array/standard/declare-generic.good.ts: -------------------------------------------------------------------------------- 1 | let declareSimpleArray: string[] 2 | 3 | type Car = {} 4 | let declareComplexArray: Array<{ cars: Car[] }> 5 | -------------------------------------------------------------------------------- /examples/array/standard/declare-generic.ok.ts: -------------------------------------------------------------------------------- 1 | let declareSimpleUnionArray: (string | string[])[] 2 | let declareUnionArrayGeneric: Array 3 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # .gitattributes 2 | * text=auto eol=lf 3 | *.zip binary 4 | # GitHub Linguist Override 5 | .yarn/* linguist-vendored 6 | .pnp.js linguist-vendored 7 | -------------------------------------------------------------------------------- /apps/tutorial/astro.config.mjs: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | import { defineConfig } from 'astro/config'; 3 | 4 | // https://astro.build/config 5 | export default defineConfig({}); 6 | -------------------------------------------------------------------------------- /apps/tutorial/src/components/navigation.astro: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /apps/tutorial/src/components/hamburger.astro: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 | 5 |
-------------------------------------------------------------------------------- /examples/unknown/standard/catch-clauses.good.ts: -------------------------------------------------------------------------------- 1 | try { throw new Error() } 2 | catch (e: unknown) { 3 | if (e instanceof Error) { 4 | console.error(e.message) 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /apps/tutorial/src/scripts/menu.js: -------------------------------------------------------------------------------- 1 | document.querySelector('.hamburger').addEventListener('click', () => { 2 | document.querySelector('.nav-links').classList.toggle('expanded'); 3 | }); -------------------------------------------------------------------------------- /github-page/blog/authors.yml: -------------------------------------------------------------------------------- 1 | unional: 2 | name: Homa Wong (unional) 3 | title: Clean Architect 4 | url: https://github.com/unional 5 | image_url: https://github.com/unional.png 6 | -------------------------------------------------------------------------------- /github-page/src/pages/markdown-page.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Markdown page example 3 | --- 4 | 5 | # Markdown page example 6 | 7 | You don't need React to write simple standalone pages. 8 | -------------------------------------------------------------------------------- /tools/devpkg-typescript/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./templates/tsconfig.base.json", 3 | "compilerOptions": { 4 | "composite": true, 5 | "declarationMap": true 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /github-page/docusaurus-example/docs/tutorial-extras/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Tutorial - Extras", 3 | "position": 3, 4 | "link": { 5 | "type": "generated-index" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /examples/unknown/standard/function-param.ts: -------------------------------------------------------------------------------- 1 | function castNumber(value: unknown) { 2 | return typeof value === 'number' ? value : -1 3 | } 4 | 5 | castNumber(1) // 1 6 | castNumber({ a: 1 }) // -1 7 | -------------------------------------------------------------------------------- /docs/pages/04-typescript-syntax/namespace.md: -------------------------------------------------------------------------------- 1 | # Namespace 2 | 3 | You **should not** use namespace to organize values and functions. 4 | 5 | --- 6 | 7 | You **should** use namespace to export types. 8 | -------------------------------------------------------------------------------- /examples/property-accessor/standard/no-passthrough.bad.ts: -------------------------------------------------------------------------------- 1 | const meaninglessPassthrough = { 2 | _age: 10, 3 | get age1() { return this._age }, 4 | set age2(newAge: number) { this._age = newAge } 5 | } 6 | -------------------------------------------------------------------------------- /exercises/this.ts: -------------------------------------------------------------------------------- 1 | module.exports.a = 1 2 | 3 | console.log('this', this) 4 | 5 | console.log('module', module) 6 | 7 | console.log('exports', module.exports) 8 | 9 | console.log('global', global) 10 | -------------------------------------------------------------------------------- /github-page/docusaurus-example/docs/tutorial-extras/img/localeDropdown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unional/typescript-blackbook/HEAD/github-page/docusaurus-example/docs/tutorial-extras/img/localeDropdown.png -------------------------------------------------------------------------------- /examples/unknown/standard/catch-clauses.bad.ts: -------------------------------------------------------------------------------- 1 | try { throw new Error() } 2 | catch (e) { 3 | // handle error 4 | } 5 | 6 | try { throw new Error() } 7 | catch (e: any) { 8 | // handle error 9 | } 10 | -------------------------------------------------------------------------------- /github-page/docs/guidelines/README.md: -------------------------------------------------------------------------------- 1 | # Guidelines 2 | 3 | This section contains the guidelines - what you should and should not do. 4 | 5 | We will focus on HOW, while still give you sufficient reasoning on the WHY. 6 | -------------------------------------------------------------------------------- /github-page/docusaurus-example/docs/tutorial-extras/img/docsVersionDropdown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unional/typescript-blackbook/HEAD/github-page/docusaurus-example/docs/tutorial-extras/img/docsVersionDropdown.png -------------------------------------------------------------------------------- /examples/array/standard/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "esModuleInterop": true, 5 | "outDir": "out", 6 | "target": "ESNext", 7 | "strict": true 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /examples/tuple/standard/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "esModuleInterop": true, 5 | "outDir": "out", 6 | "target": "ESNext", 7 | "strict": true 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /page/src/pages/index.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { Header } from '../components/Header' 3 | import Layout from '../layouts/Layout.astro' 4 | --- 5 | 6 | 7 |
8 | 9 | -------------------------------------------------------------------------------- /github-page/docusaurus-example/blog/2021-08-26-welcome/docusaurus-plushie-banner.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unional/typescript-blackbook/HEAD/github-page/docusaurus-example/blog/2021-08-26-welcome/docusaurus-plushie-banner.jpeg -------------------------------------------------------------------------------- /apps/starlight/tailwind.config.mjs: -------------------------------------------------------------------------------- 1 | /** @type {import('tailwindcss').Config} */ 2 | export default { 3 | content: ['./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}'], 4 | theme: { 5 | extend: {}, 6 | }, 7 | plugins: [], 8 | } 9 | -------------------------------------------------------------------------------- /examples/property-accessor/standard/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "esModuleInterop": true, 5 | "outDir": "out", 6 | "target": "ESNext", 7 | "strict": true 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /docs/pages/05-typescript-features/configuration.md: -------------------------------------------------------------------------------- 1 | # Configuration 2 | 3 | In this section, 4 | I'll talk about how to configure TypeScript in for different purposes. 5 | 6 | ## Library 7 | 8 | ## Application 9 | 10 | ## Monorepo 11 | -------------------------------------------------------------------------------- /docs/pages/09-tooling/sort-package.json.md: -------------------------------------------------------------------------------- 1 | # sort-package-json 2 | 3 | Order your `package.json` nicely. 4 | 5 | ```sh 6 | your-project-root> npx sort-package-json 7 | ``` 8 | 9 | 10 | -------------------------------------------------------------------------------- /docs/drafts/04-typescript-syntax/generics.md: -------------------------------------------------------------------------------- 1 | # generics 2 | 3 | ## Using generics 4 | 5 | You **should** rely on type inference for generic types. 6 | 7 | ❌ bad 8 | 9 | ```ts 10 | [1, 2, 3].reduce((p, v) => p += v, '') 11 | ``` 12 | -------------------------------------------------------------------------------- /docs/pages/typings/TOPICS.md: -------------------------------------------------------------------------------- 1 | # Topics 2 | 3 | - What is typings? 4 | - Types of typings 5 | - Creating typings 6 | - Distributing typings 7 | - Typings Guidelines 8 | - functions 9 | - Tools 10 | - generator-typings 11 | - tslint 12 | -------------------------------------------------------------------------------- /github-page/src/components/HomepageFeatures/styles.module.css: -------------------------------------------------------------------------------- 1 | .features { 2 | display: flex; 3 | align-items: center; 4 | padding: 2rem 0; 5 | width: 100%; 6 | } 7 | 8 | .featureSvg { 9 | height: 200px; 10 | width: 200px; 11 | } 12 | -------------------------------------------------------------------------------- /docs/pages/04-typescript-syntax/basic-types.md: -------------------------------------------------------------------------------- 1 | # Basic Types 2 | 3 | - [`any`](./any.md) 4 | - [`unknown`](./unknown.md) 5 | - [`enum`](./enum.md) 6 | 7 | ## References 8 | 9 | - 10 | -------------------------------------------------------------------------------- /page/src/pages/blogs.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { Header } from '../components/Header' 3 | import Layout from '../layouts/DocLayout.astro' 4 | --- 5 | 6 | 7 |
8 | 9 | -------------------------------------------------------------------------------- /examples/unknown/standard/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "esModuleInterop": true, 5 | "moduleResolution": "node", 6 | "outDir": "out", 7 | "target": "ESNext", 8 | "strict": true 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /github-page/docs/tsconfig/_isolated_modules.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | slug: isolated_modules 3 | title: "Isolated Modules" 4 | authors: [unional] 5 | tags: [typescript, tsconfig] 6 | --- 7 | 8 | You **should** turn on `isolatedModules`. 9 | 10 | > Why? 11 | 12 | `SFT` 13 | -------------------------------------------------------------------------------- /page/src/pages/blackbook.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { Header } from '../components/Header' 3 | import Layout from '../layouts/DocLayout.astro' 4 | --- 5 | 6 | 7 |
8 | 9 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /github-page/docusaurus-example/docs/tutorial-basics/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Tutorial - Basics", 3 | "position": 2, 4 | "link": { 5 | "type": "generated-index", 6 | "description": "5 minutes to learn the most important Docusaurus concepts." 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /apps/starlight/src/content/docs/tsconfig/_isolated_modules.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | slug: isolated_modules 3 | title: "Isolated Modules" 4 | authors: [unional] 5 | tags: [typescript, tsconfig] 6 | --- 7 | 8 | You **should** turn on `isolatedModules`. 9 | 10 | > Why? 11 | 12 | `SFT` 13 | -------------------------------------------------------------------------------- /apps/tutorial/src/pages/index.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import BaseLayout from '../layouts/base_layout.astro' 3 | import '../styles/global.css' 4 | 5 | const pageTitle = 'Home Page' 6 | --- 7 | 8 | 9 |

My awesome blog subtitle

10 |
-------------------------------------------------------------------------------- /page/.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 | -------------------------------------------------------------------------------- /apps/tutorial/.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 | -------------------------------------------------------------------------------- /github-page/docs/tips/_type_cannot_be_named.md: -------------------------------------------------------------------------------- 1 | # Type 2 | 3 | When using a package written in TypeScript, 4 | 5 | - Generic default value 6 | - Properties 7 | 8 | 9 | ```ts 10 | export type Foo = { 11 | bar: Boo 12 | } 13 | 14 | export type Koo = Foo & { a: number } 15 | ``` 16 | -------------------------------------------------------------------------------- /apps/starlight/src/content/docs/tips/_type_cannot_be_named.md: -------------------------------------------------------------------------------- 1 | # Type 2 | 3 | When using a package written in TypeScript, 4 | 5 | - Generic default value 6 | - Properties 7 | 8 | 9 | ```ts 10 | export type Foo = { 11 | bar: Boo 12 | } 13 | 14 | export type Koo = Foo & { a: number } 15 | ``` 16 | -------------------------------------------------------------------------------- /apps/tutorial/src/components/header.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import Hamburger from './hamburger.astro' 3 | import Navigation from './navigation.astro' 4 | --- 5 |
6 | 10 |
11 | -------------------------------------------------------------------------------- /docs/pages/06-typescript-usage/README.md: -------------------------------------------------------------------------------- 1 | # TypeScript Usages 2 | 3 | In this chapter, 4 | we will talk about how to use TypeScript other than recommendations about its syntax and features. 5 | 6 | ## Table of Content 7 | 8 | - incremental builds 9 | - monorepo support 10 | - typings 11 | - styling 12 | -------------------------------------------------------------------------------- /docs/pages/05-typescript-features/build-in-types.md: -------------------------------------------------------------------------------- 1 | # Build in types 2 | 3 | ## Partial 4 | 5 | ## Pick 6 | 7 | ## ReturnType 8 | 9 | ## Record\ 10 | 11 | ## Readonly 12 | 13 | ## Exclude\ 14 | 15 | ## Extract\ 16 | 17 | ## NonNullable 18 | 19 | ## InstanceType 20 | -------------------------------------------------------------------------------- /page/astro.config.mjs: -------------------------------------------------------------------------------- 1 | import mdx from '@astrojs/mdx' 2 | import react from '@astrojs/react' 3 | import tailwind from '@astrojs/tailwind' 4 | import { defineConfig } from 'astro/config' 5 | 6 | // https://astro.build/config 7 | export default defineConfig({ 8 | integrations: [react(), mdx(), tailwind()] 9 | }) 10 | -------------------------------------------------------------------------------- /docs/pages/05-typescript-features/README.md: -------------------------------------------------------------------------------- 1 | # TypeScript Features 2 | 3 | In this chapter, 4 | we will talk about additional features provided by TypeScript other than the added syntax. 5 | 6 | ## Table of Content 7 | 8 | - [build in types](build-in-types.md) 9 | - incremental builds 10 | - monorepo support 11 | - typings 12 | -------------------------------------------------------------------------------- /page/.gitignore: -------------------------------------------------------------------------------- 1 | # build output 2 | dist/ 3 | .output/ 4 | 5 | # dependencies 6 | node_modules/ 7 | 8 | # logs 9 | npm-debug.log* 10 | yarn-debug.log* 11 | yarn-error.log* 12 | pnpm-debug.log* 13 | 14 | 15 | # environment variables 16 | .env 17 | .env.production 18 | 19 | # macOS-specific files 20 | .DS_Store 21 | 22 | .astro -------------------------------------------------------------------------------- /docs/pages/typings/distribution.md: -------------------------------------------------------------------------------- 1 | # Distributing typings 2 | 3 | You should avoid distributing the actual typings of your dependencies with your package. 4 | 5 | > Why? Doing so might create conflict to the consumers if they have the same typings but different version. 6 | 7 | It is better to rely on npm dependencies or `typings.json`. 8 | -------------------------------------------------------------------------------- /apps/tutorial/src/components/social.astro: -------------------------------------------------------------------------------- 1 | --- 2 | const { platform, username } = Astro.props; 3 | --- 4 | {platform} 5 | 6 | -------------------------------------------------------------------------------- /apps/tutorial/src/layouts/markdown_post_layout.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import BaseLayout from './base_layout.astro' 3 | 4 | const { frontmatter } = Astro.props 5 | --- 6 | 7 | 8 |

Published on {frontmatter.pubDate}

9 |

Written by {frontmatter.author}

10 | 11 |
12 | -------------------------------------------------------------------------------- /docs/drafts/09-tooling/README.md: -------------------------------------------------------------------------------- 1 | # Tooling 2 | 3 | In this chapter, we will go through various tools that are used in junction with TypeScript. 4 | 5 | These tools include: 6 | 7 | - transpilers/compilers 8 | - editors/IDEs 9 | - linters 10 | - formatters 11 | - test runners 12 | - bundlers 13 | - CIs 14 | - and specific packages/libraries 15 | -------------------------------------------------------------------------------- /docs/pages/09-tooling/README.md: -------------------------------------------------------------------------------- 1 | # Tooling 2 | 3 | In this chapter, we will go through various tools that are used in junction with TypeScript. 4 | 5 | These tools include: 6 | 7 | - transpilers/compilers 8 | - editors/IDEs 9 | - linters 10 | - formatters 11 | - test runners 12 | - bundlers 13 | - CIs 14 | - and specific packages/libraries 15 | -------------------------------------------------------------------------------- /examples/eslint-plugin-peer/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@unional/eslint-plugin-peer", 3 | "private": true, 4 | "scripts": { 5 | "lint": "eslint --ext=ts ." 6 | }, 7 | "devDependencies": { 8 | "@typescript-eslint/eslint-plugin": "5.4", 9 | "eslint": "^8.15.0", 10 | "eslint-config-react-app": "^7.0.1" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /github-page/.gitignore: -------------------------------------------------------------------------------- 1 | # Dependencies 2 | /node_modules 3 | 4 | # Production 5 | /build 6 | 7 | # Generated files 8 | .docusaurus 9 | .cache-loader 10 | 11 | # Misc 12 | .DS_Store 13 | .env.local 14 | .env.development.local 15 | .env.test.local 16 | .env.production.local 17 | 18 | npm-debug.log* 19 | yarn-debug.log* 20 | yarn-error.log* 21 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig is awesome: http://EditorConfig.org 2 | 3 | # top-most EditorConfig file 4 | root = true 5 | 6 | [*] 7 | charset = utf-8 8 | end_of_line = lf 9 | insert_final_newline = true 10 | indent_size = 2 11 | indent_style = tab 12 | trim_trailing_whitespace = true 13 | 14 | [*.{md,mdx,yml,yaml}] 15 | indent_style = space 16 | -------------------------------------------------------------------------------- /apps/starlight/.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 | -------------------------------------------------------------------------------- /docs/pages/04-typescript-syntax/type-alias.md: -------------------------------------------------------------------------------- 1 | # type alias 2 | 3 | - Use `type` instead of `interface` to combine types. 4 | 5 | ```ts 6 | interface Fizz { fizz: string } 7 | interface Buzz { buzz: string } 8 | 9 | // bad 10 | interface FizzBuzz extends Fizz, Buzz { } 11 | 12 | // good 13 | type FizzBuzz = Fizz | Buzz 14 | ``` 15 | -------------------------------------------------------------------------------- /page/tailwind.config.cjs: -------------------------------------------------------------------------------- 1 | /** @type {import('tailwindcss').Config} */ 2 | module.exports = { 3 | content: ['./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}'], 4 | theme: { 5 | extend: { 6 | fontFamily: { 7 | chalk: ['Chalkduster', 'Chalkboard SE', 'cursive'] 8 | } 9 | } 10 | }, 11 | plugins: [] 12 | } 13 | -------------------------------------------------------------------------------- /docs/pages/05-typescript-features/language-service-plugin.md: -------------------------------------------------------------------------------- 1 | # Language Service Plugin 2 | 3 | Starting from TypeScript 2.2, 4 | TypeScript laugange serice provides plugin support. 5 | 6 | It is for changing the *editing experience* only. 7 | 8 | ## References 9 | 10 | - 11 | -------------------------------------------------------------------------------- /examples/tuple/standard/variadic.ts: -------------------------------------------------------------------------------- 1 | function tail(arr: readonly [any, ...T]): T { 2 | const [_ignored, ...rest] = arr; 3 | return rest; 4 | } 5 | 6 | type Strings = [string, string]; 7 | type Numbers = [number, number]; 8 | 9 | // [string, string, number, number, boolean] 10 | type StrStrNumNumBool = [...Strings, ...Numbers, boolean]; 11 | -------------------------------------------------------------------------------- /.github/workflows/pull-request.yaml: -------------------------------------------------------------------------------- 1 | name: pull-request 2 | on: 3 | workflow_dispatch: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | types: [opened, synchronize] 9 | 10 | jobs: 11 | code: 12 | uses: unional/.github/.github/workflows/pnpm-verify.yml@main 13 | secrets: inherit 14 | with: 15 | node-version: '[18]' 16 | -------------------------------------------------------------------------------- /docs/pages/03-javascript-features/eval.md: -------------------------------------------------------------------------------- 1 | # eval 2 | 3 | `eval()` is evil. 4 | 5 | You probably heard of this when you first learn JavaScript. 6 | But how evil it is? 7 | 8 | We will find out in this section. 9 | 10 | ```ts 11 | const result = eval('this') 12 | function foo() { 13 | const value = 'secret' 14 | eval('console.log(value)') 15 | } 16 | ``` 17 | -------------------------------------------------------------------------------- /docs/pages/06-typescript-usage/styling.md: -------------------------------------------------------------------------------- 1 | # Styling 2 | 3 | ## indentation 4 | 5 | ## multi-line 6 | 7 | You **should not** use tool to restrict line length. 8 | 9 | > Why? 10 | 11 | While we should not have lines more than 80~120 long, 12 | using tools to enforce it forcing user to break a single line to multiple line hinders readability and maintainability. 13 | -------------------------------------------------------------------------------- /github-page/docs/tsconfig/_module_resolution.mdx: -------------------------------------------------------------------------------- 1 | # Module Resolution 2 | 3 | You **should** use `Node16` when possible. 4 | 5 | It depends on your dependencies. 6 | 7 | Problem with source map 8 | 9 | 10 | [tsconfig#module]: https://www.typescriptlang.org/tsconfig#module 11 | [tsconfig.es2022]: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-5.html#module-es2022 12 | -------------------------------------------------------------------------------- /apps/tutorial/.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 | 23 | # jetbrains setting folder 24 | .idea/ 25 | -------------------------------------------------------------------------------- /apps/starlight/src/content/docs/tsconfig/_module_resolution.mdx: -------------------------------------------------------------------------------- 1 | # Module Resolution 2 | 3 | You **should** use `Node16` when possible. 4 | 5 | It depends on your dependencies. 6 | 7 | Problem with source map 8 | 9 | 10 | [tsconfig#module]: https://www.typescriptlang.org/tsconfig#module 11 | [tsconfig.es2022]: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-5.html#module-es2022 12 | -------------------------------------------------------------------------------- /apps/starlight/src/pages/blogs/index.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import StarlightPage from '@astrojs/starlight/components/StarlightPage.astro' 3 | import BlogsList from '../../components/blogs_list.astro' 4 | --- 5 | 6 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /docs/pages/typings/functions/param-types.md: -------------------------------------------------------------------------------- 1 | # Types used in function signatures 2 | 3 | ## Parameters 4 | 5 | - Type loosely. 6 | 7 | ## Return Values 8 | 9 | - Be specific. 10 | 11 | ## Generics 12 | 13 | When deciding what type should be used on generics, you need to understand the concept of [covariance and contravariance](https://en.wikipedia.org/wiki/Covariance_and_contravariance_\(computer_science\)). 14 | -------------------------------------------------------------------------------- /examples/unknown/standard/catch-clauses.type-plus.good.ts: -------------------------------------------------------------------------------- 1 | import { checkUnknown } from 'type-plus' 2 | class ErrorA extends Error { } 3 | class ErrorB extends Error { } 4 | 5 | try { throw new ErrorA() } 6 | catch (e: unknown) { 7 | if (checkUnknown(e, ErrorA)) { 8 | // handle ErrorA 9 | } else if (checkUnknown(e, ErrorB)) { 10 | // handle ErrorB 11 | } else { 12 | // handle generic Error 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /apps/tutorial/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tutorial", 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 | }, 12 | "dependencies": { 13 | "astro": "^5.0.0", 14 | "@astrojs/check": "^0.9.4", 15 | "typescript": "^5.6.2" 16 | } 17 | } -------------------------------------------------------------------------------- /docs/pages/07-files-and-projects/package.json.md: -------------------------------------------------------------------------------- 1 | # package.json 2 | 3 | ## files 4 | 5 | If you do not use the `inlineSources` compiler options, 6 | add your source folder into the `files` array. 7 | 8 | > Why? 9 | 10 | The source map generated by `tsc` has `"sources":["../src/.ts"]`. 11 | If the source code is not distributed, 12 | tools such as `webpack` will emit a warning saying it cannot resolve the source file. 13 | -------------------------------------------------------------------------------- /tools/devpkg-typescript/templates/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "downlevelIteration": true, 4 | "esModuleInterop": true, 5 | "forceConsistentCasingInFileNames": true, 6 | "noImplicitReturns": true, 7 | "noUnusedLocals": true, 8 | "noUnusedParameters": true, 9 | "strict": true, 10 | "declaration": true, 11 | "useDefineForClassFields": true, 12 | "target": "ES2017" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "aaron-bond.better-comments", 4 | "astro-build.astro-vscode", 5 | "bierner.emojisense", 6 | "bradlc.vscode-tailwindcss", 7 | "davidanson.vscode-markdownlint", 8 | "dbaeumer.vscode-eslint", 9 | "editorconfig.editorconfig", 10 | "unifiedjs.vscode-mdx", 11 | "yzhang.markdown-all-in-one", 12 | "astro-build.astro-vscode", 13 | "esbenp.prettier-vscode", 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /docs/drafts/extra-material.md: -------------------------------------------------------------------------------- 1 | # Extra Material 2 | 3 | This are note and ideas that I might add to the guideline in the future 4 | 5 | ## Engineering 6 | 7 | No matter what tools do you use or what process do you practice, 8 | the fundamental of programming is still about design, architecture, and organization. 9 | 10 | If you do not get these right, no tool or practice can help you to produce high-quality result with less time, and less stress. 11 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: release 2 | 3 | on: 4 | push: 5 | branches: [main] 6 | 7 | jobs: 8 | code: 9 | uses: unional/.github/.github/workflows/pnpm-verify.yml@main 10 | secrets: inherit 11 | with: 12 | node-version: '[18]' 13 | 14 | docs: 15 | uses: unional/.github/.github/workflows/pnpm-docs.yml@main 16 | needs: code 17 | secrets: inherit 18 | with: 19 | publish_dir: ./github-page/build 20 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "esModuleInterop": true, 4 | "moduleResolution": "node" 5 | }, 6 | "files": [], 7 | "references": [ 8 | { 9 | "path": "examples/array/standard" 10 | }, 11 | { 12 | "path": "examples/property-accessor/standard" 13 | }, 14 | { 15 | "path": "examples/unknown/standard" 16 | }, 17 | { 18 | "path": "examples/tuple/standard" 19 | } 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /apps/starlight/src/components/blogs_list.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { getCollection } from 'astro:content' 3 | import BlogPostInfo from './blog_post_info.astro' 4 | 5 | const blogs = (await getCollection('blogs')).sort( 6 | (a, b) => new Date(b.data.pubDate).valueOf() - new Date(a.data.pubDate).valueOf() 7 | ) 8 | --- 9 | 10 |
11 | {blogs.map(post => )} 12 |
13 | -------------------------------------------------------------------------------- /docs/pages/03-javascript-features/optional-parameters.md: -------------------------------------------------------------------------------- 1 | # Optional Parameters 2 | 3 | > In JavaScript, every parameter is optional, and users may leave them off as they see fit. When they do, their value is undefined. We can get this functionality in TypeScript by adding a ? to the end of parameters we want to be optional. 4 | 5 | 6 | 7 | Should we use it? When should we not use it? 8 | -------------------------------------------------------------------------------- /docs/pages/04-typescript-syntax/optional-parameters.md: -------------------------------------------------------------------------------- 1 | # Optional Parameters 2 | 3 | > In JavaScript, every parameter is optional, and users may leave them off as they see fit. When they do, their value is undefined. We can get this functionality in TypeScript by adding a ? to the end of parameters we want to be optional. 4 | 5 | 6 | 7 | Should we use it? When should we not use it? 8 | -------------------------------------------------------------------------------- /docs/pages/07-files-and-projects/file-organization.md: -------------------------------------------------------------------------------- 1 | # File Organization 2 | 3 | ## Types and Interfaces 4 | 5 | - Create a `types.ts` or `interfaces.ts` at the top for public interfaces and types. 6 | 7 | > Why? 8 | 9 | Types are common culprit of coupling. 10 | While TypeScript is structural typed, 11 | defining and referencing types can easily leads to circular reference. 12 | 13 | - Create a `typesInternal.ts` or `interfacesInternal.ts` for shared internal types. 14 | -------------------------------------------------------------------------------- /apps/tutorial/src/components/footer.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import Social from './social.astro'; 3 | const platform = "github"; 4 | const username = "withastro"; 5 | --- 6 | 13 | 14 |
15 | 16 | 17 | 18 |
-------------------------------------------------------------------------------- /.markdownlint-cli2.jsonc: -------------------------------------------------------------------------------- 1 | { 2 | "ignores": [ 3 | ".changeset/*.md", 4 | "**/CHANGELOG.md", 5 | "**/docs", 6 | "**/LICENSE", 7 | "flow-types.md", 8 | "github-page", 9 | "slides/*.slides.md" 10 | ], 11 | "config": { 12 | "line-length": false, 13 | "hard-tab": false, 14 | "no-missing-space-atx": false, 15 | "no-duplicate-heading": false, 16 | "no-trailing-punctuation": false, 17 | "no-inline-html": false, 18 | "no-space-in-emphasis": false 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /.prettierrc.js: -------------------------------------------------------------------------------- 1 | /** @type {import('prettier').Config} */ 2 | module.exports = { 3 | arrowParens: 'avoid', 4 | printWidth: 110, 5 | semi: false, 6 | singleQuote: true, 7 | // For ES5, trailing commas cannot be used in function parameters; it is counterintuitive 8 | // to use them for arrays only 9 | trailingComma: 'none', 10 | useTabs: true, 11 | plugins: [require.resolve('prettier-plugin-astro')], 12 | overrides: [{ files: '*.astro', options: { parser: 'astro' } }] 13 | } 14 | -------------------------------------------------------------------------------- /github-page/docusaurus-example/blog/2019-05-28-first-blog-post.md: -------------------------------------------------------------------------------- 1 | --- 2 | slug: first-blog-post 3 | title: First Blog Post 4 | authors: 5 | name: Gao Wei 6 | title: Docusaurus Core Team 7 | url: https://github.com/wgao19 8 | image_url: https://github.com/wgao19.png 9 | tags: [hola, docusaurus] 10 | --- 11 | 12 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet 13 | -------------------------------------------------------------------------------- /slides/ts.declaration-map.slides.md: -------------------------------------------------------------------------------- 1 | --- 2 | customTheme: "_revealjs/style-basic" 3 | transition: "fade" 4 | logoImg: "_revealjs/uni.png" 5 | enableMenu: false 6 | enableTitleFooter: false 7 | enableChalkboard: false 8 | highlightTheme: vs2015 9 | autoPlayMedia: true 10 | --- 11 | 12 | ## `declarationMap` 13 | 14 | ```json 15 | { 16 | "compilerOptions": { 17 | "declaration": true, 18 | "declarationMap": ??? 19 | } 20 | } 21 | ``` 22 | 23 | --- 24 | 25 | ![](ts.declaration-map.png) 26 | -------------------------------------------------------------------------------- /docs/pages/04-typescript-syntax/README.md: -------------------------------------------------------------------------------- 1 | # TypeScript Syntax 2 | 3 | This chapter will focus on syntax specific to TypeScript. 4 | 5 | ## Table of Contents 6 | 7 | - [Type Declaration](/docs/pages/04-typescript-syntax/type-declaration.md) 8 | - [Basic Types](/docs/pages/04-typescript-syntx/basic-types.md) 9 | - [Interfaces](/docs/pages/04-typescript-syntax/interfaces.md) 10 | - [Modules](/docs/pages/04-typescript-syntax/modules.md) 11 | - [Tuple Type](/docs/pages/04-typescript-syntax/tuple-type.md) 12 | -------------------------------------------------------------------------------- /github-page/src/pages/index.module.css: -------------------------------------------------------------------------------- 1 | /** 2 | * CSS files with the .module.css suffix will be treated as CSS modules 3 | * and scoped locally. 4 | */ 5 | 6 | .heroBanner { 7 | padding: 4rem 0; 8 | text-align: center; 9 | position: relative; 10 | overflow: hidden; 11 | } 12 | 13 | @media screen and (max-width: 996px) { 14 | .heroBanner { 15 | padding: 2rem; 16 | } 17 | } 18 | 19 | .buttons { 20 | display: flex; 21 | align-items: center; 22 | justify-content: center; 23 | } 24 | -------------------------------------------------------------------------------- /tools/devpkg-typescript/templates/tsconfig.base.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./templates/tsconfig.base.json", 3 | "compilerOptions": { 4 | "downlevelIteration": true, 5 | "declaration": true, 6 | "esModuleInterop": true, 7 | "isolatedModules": true, 8 | "forceConsistentCasingInFileNames": true, 9 | "noImplicitReturns": true, 10 | "noUnusedLocals": true, 11 | "noUnusedParameters": true, 12 | "strict": true, 13 | "useDefineForClassFields": true, 14 | "target": "ES2017" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /docs/pages/04-typescript-syntax/conditional-types.md: -------------------------------------------------------------------------------- 1 | # Conditional Types 2 | 3 | Conditional type is introduced in TypeScript 2.8. 4 | 5 | > A conditional type selects one of two possible types based on a condition expressed as a type relationship test. 6 | 7 | ## References 8 | 9 | - 10 | - 11 | - 12 | -------------------------------------------------------------------------------- /apps/tutorial/src/pages/blog.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { getCollection } from 'astro:content' 3 | import BaseLayout from '../layouts/base_layout.astro' 4 | import '../styles/global.css' 5 | 6 | const posts = await getCollection('posts') 7 | --- 8 | 9 | 10 |

This is where I will post about my journey learning Astro.

11 |
    12 | { 13 | posts.map(post => ( 14 |
  • 15 | {post.data.title} 16 |
  • 17 | )) 18 | } 19 |
20 |
21 | -------------------------------------------------------------------------------- /apps/starlight/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "starlight", 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 | }, 12 | "dependencies": { 13 | "@astrojs/check": "^0.9.5", 14 | "@astrojs/starlight": "^0.37.0", 15 | "@astrojs/tailwind": "^6.0.2", 16 | "astro": "^5.16.0", 17 | "sharp": "^0.34.5", 18 | "tailwindcss": "^3.4.13", 19 | "typescript": "^5.6.2" 20 | } 21 | } -------------------------------------------------------------------------------- /apps/starlight/src/pages/blogs/[...slug].astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { getCollection } from 'astro:content'; 3 | import StarlightPage from '@astrojs/starlight/components/StarlightPage.astro'; 4 | 5 | export async function getStaticPaths() { 6 | const blogEntries = await getCollection('blogs'); 7 | return blogEntries.map(entry => ({ 8 | params: { slug: entry.slug }, props: { entry }, 9 | })); 10 | } 11 | 12 | const { entry } = Astro.props; 13 | const { Content } = await entry.render(); 14 | --- 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /github-page/docusaurus-example/blog/2021-08-01-mdx-blog-post.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | slug: mdx-blog-post 3 | title: MDX Blog Post 4 | authors: [slorber] 5 | tags: [docusaurus] 6 | --- 7 | 8 | Blog posts support [Docusaurus Markdown features](https://docusaurus.io/docs/markdown-features), such as [MDX](https://mdxjs.com/). 9 | 10 | :::tip 11 | 12 | Use the power of React to create interactive blog posts. 13 | 14 | ```js 15 | 16 | ``` 17 | 18 | 19 | 20 | ::: 21 | -------------------------------------------------------------------------------- /apps/tutorial/src/pages/posts/[...slug].astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { getCollection } from 'astro:content'; 3 | import MarkdownPostLayout from '../../layouts/markdown_post_layout.astro'; 4 | 5 | export async function getStaticPaths() { 6 | const blogEntries = await getCollection('posts'); 7 | return blogEntries.map(entry => ({ 8 | params: { slug: entry.slug }, props: { entry }, 9 | })); 10 | } 11 | 12 | const { entry } = Astro.props; 13 | const { Content } = await entry.render(); 14 | --- 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /tools/style/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "typescript-style", 3 | "version": "0.8.1", 4 | "description": "Some kind of styling tool for TypeScript.", 5 | "homepage": "https://github.com/unional/typescript-guidebook", 6 | "keywords": [ 7 | "lint", 8 | "style guide", 9 | "ts", 10 | "eslint", 11 | "typescript" 12 | ], 13 | "bugs": { 14 | "url": "https://github.com/unional/typescript-guidebook/issues" 15 | }, 16 | "repository": { 17 | "type": "git", 18 | "url": "https://github.com/unional/typescript-guidebook.git" 19 | }, 20 | "license": "MIT", 21 | "author": "unional" 22 | } 23 | -------------------------------------------------------------------------------- /apps/tutorial/src/layouts/base_layout.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import Footer from '../components/footer.astro' 3 | import Header from '../components/header.astro' 4 | import '../styles/global.css' 5 | 6 | const { pageTitle } = Astro.props; 7 | --- 8 | 9 | 10 | 11 | 12 | 13 | 14 | {pageTitle} 15 | 16 | 17 |
18 |

{pageTitle}

19 | 20 |