[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-83012":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":10,"languages":10,"totalLinesOfCode":10,"stars":11,"forks":12,"watchers":13,"openIssues":14,"contributorsCount":14,"subscribersCount":14,"size":14,"stars1d":15,"stars7d":16,"stars30d":17,"stars90d":14,"forks30d":14,"starsTrendScore":18,"compositeScore":19,"rankGlobal":10,"rankLanguage":10,"license":20,"archived":21,"fork":21,"defaultBranch":22,"hasWiki":23,"hasPages":21,"topics":24,"createdAt":10,"pushedAt":10,"updatedAt":38,"readmeContent":39,"aiSummary":40,"trendingCount":14,"starSnapshotCount":14,"syncStatus":12,"lastSyncTime":41,"discoverSource":42},83012,"typescript-tips-everyone-should-know","AllThingsSmitty\u002Ftypescript-tips-everyone-should-know","AllThingsSmitty","✅ A curated collection of practical TypeScript patterns that improve safety, readability, maintainability, and developer experience. 🧠","",null,328,2,4,0,3,172,208,32,1.43,"Creative Commons Zero v1.0 Universal",false,"main",true,[25,26,27,28,29,30,31,32,33,34,35,36,37],"best-practices","clean-code","code-quality","developer-experience","front-end","frontend","generics","javascript","maintainability","runtime-validation","static-analysis","type-safety","typescript","2026-06-12 02:04:30","# TypeScript Tips Everyone Should Know\n\nA curated collection of practical TypeScript patterns that improve safety, readability, maintainability, and developer experience.\n\nMost of these are small individually. Together, they dramatically change how TypeScript code feels to work in.\n\n## Table of Contents\n\n1. [Prefer `unknown` Over `any`](#prefer-unknown-over-any)\n2. [Let Type Inference Do the Work](#let-type-inference-do-the-work)\n3. [Prefer `satisfies` Over `as`](#prefer-satisfies-over-as)\n4. [Derive Types From Values](#derive-types-from-values-instead-of-duplicating-them)\n5. [Model Impossible States With Discriminated Unions](#model-impossible-states-with-discriminated-unions)\n6. [Use Exhaustive Checks With `never`](#use-exhaustive-checks-with-never)\n7. [Use `as const` for Constants](#use-as-const-for-configuration-and-constants)\n8. [Use Type Predicates](#use-type-predicates-for-reusable-narrowing)\n9. [Build Types From Existing Types](#build-new-types-from-existing-types)\n10. [Validate External Data at Runtime](#validate-external-data-at-runtime)\n11. [Avoid `enum` in Most Cases](#avoid-enum-in-most-cases)\n12. [Prefer Inferable Generics](#prefer-generics-that-infer-automatically)\n13. [Enable Strict Compiler Options](#turn-on-the-strict-compiler-options)\n14. [Learn Template Literal Types](#learn-template-literal-types)\n15. [Type Safety ≠ Runtime Safety](#type-safe-does-not-mean-runtime-safe)\n\n### Prefer `unknown` Over `any`\n\nA lot of type safety starts here.\n\nMost TypeScript problems start when `any` enters the system.\n\n```ts\nfunction parse(data: unknown) {\n  if (typeof data === \"string\") {\n    return data.toUpperCase();\n  }\n}\n```\n\n#### Why it matters\n\n- Forces validation\n- Preserves safety\n- Prevents type leakage\n\n\u003Csup>[Table of Contents](#table-of-contents)\u003C\u002Fsup>\n\n### Let Type Inference Do the Work\n\nThe best TypeScript code often has fewer explicit types than beginners expect.\n\n```ts\nconst name = \"Ada\";\n```\n\nInstead of:\n\n```ts\nconst name: string = \"Ada\";\n```\n\n#### Over-annotation\n\n- Widens types\n- Hurts inference\n- Creates maintenance overhead\n\nInference tends to scale better than annotation.\n\n\u003Csup>[Table of Contents](#table-of-contents)\u003C\u002Fsup>\n\n### Prefer `satisfies` Over `as`\n\nOne of the most important modern TypeScript features.\n\n```ts\nconst routes = {\n  home: \"\u002F\",\n  about: \"\u002Fabout\",\n} satisfies Record\u003Cstring, string>;\n```\n\nInstead of:\n\n```ts\nconst routes = {\n  home: \"\u002F\",\n  about: \"\u002Fabout\",\n} as Record\u003Cstring, string>;\n```\n\n`satisfies` validates without losing inference.\n\n\u003Csup>[Table of Contents](#table-of-contents)\u003C\u002Fsup>\n\n### Derive Types From Values Instead of Duplicating Them\n\nOne of the biggest TypeScript mindset shifts.\n\n```ts\nconst roles = [\"admin\", \"user\", \"guest\"] as const;\n\ntype Role = (typeof roles)[number];\n```\n\nKeeping runtime values and types in sync manually almost always drifts over time.\n\n\u003Csup>[Table of Contents](#table-of-contents)\u003C\u002Fsup>\n\n### Model Impossible States With Discriminated Unions\n\nThis is where TypeScript starts becoming architectural.\n\n```ts\ntype State =\n  | { status: \"loading\" }\n  | { status: \"success\"; data: User }\n  | { status: \"error\"; error: Error };\n```\n\nThese models tend to scale much better than loose optional-property blobs.\n\n\u003Csup>[Table of Contents](#table-of-contents)\u003C\u002Fsup>\n\n### Use Exhaustive Checks With `never`\n\nDiscriminated unions become much more powerful with exhaustiveness checking.\n\n```ts\ndefault: {\n  const exhaustive: never = state;\n  return exhaustive;\n}\n```\n\nFuture refactors become compiler errors instead of runtime bugs.\n\n\u003Csup>[Table of Contents](#table-of-contents)\u003C\u002Fsup>\n\n### Use `as const` for Configuration and Constants\n\nWithout `as const`:\n\n```ts\nconst theme = {\n  mode: \"dark\",\n};\n```\n\n`mode` becomes `string`.\n\nWith `as const`:\n\n```ts\nconst theme = {\n  mode: \"dark\",\n} as const;\n```\n\nNow it becomes `'dark'`.\n\nTiny feature, huge usefulness.\n\n\u003Csup>[Table of Contents](#table-of-contents)\u003C\u002Fsup>\n\n### Use Type Predicates for Reusable Narrowing\n\nConnect runtime checks to compile-time intelligence.\n\n```ts\nfunction isUser(value: unknown): value is User {\n  return typeof value === \"object\" && value !== null && \"id\" in value;\n}\n```\n\nThen:\n\n```ts\nif (isUser(data)) {\n  data.id;\n}\n```\n\nThis becomes especially useful around APIs and external input boundaries.\n\n\u003Csup>[Table of Contents](#table-of-contents)\u003C\u002Fsup>\n\n### Build New Types From Existing Types\n\nThink in transformations instead of duplication.\n\n```ts\ntype UserPreview = Pick\u003CUser, \"id\" | \"name\">;\n```\n\n### Learn these utility types\n\n- `Pick`\n- `Omit`\n- `Partial`\n- `Required`\n- Indexed access types\n\nThese utilities become much more valuable as applications grow.\n\n\u003Csup>[Table of Contents](#table-of-contents)\u003C\u002Fsup>\n\n### Validate External Data at Runtime\n\nTypeScript does **not** validate API responses.\n\nThis is one of the most misunderstood parts of TypeScript.\n\n```ts\nconst UserSchema = z.object({\n  id: z.string(),\n  name: z.string(),\n});\n```\n\nType safety ends at runtime boundaries unless you validate.\n\n\u003Csup>[Table of Contents](#table-of-contents)\u003C\u002Fsup>\n\n### Avoid `enum` in Most Cases\n\nUsually simpler:\n\n```ts\nconst roles = [\"admin\", \"user\"] as const;\n```\n\nThan:\n\n```ts\nenum Role {\n  Admin,\n  User,\n}\n```\n\nIn most applications, literal unions end up simpler to refactor, easier to serialize, and less surprising at runtime than enums.\n\n\u003Csup>[Table of Contents](#table-of-contents)\u003C\u002Fsup>\n\n### Prefer Generics That Infer Automatically\n\nGreat TypeScript APIs rarely require manual generic arguments.\n\nLess ideal:\n\n```ts\ngetData\u003CUser>();\n```\n\nBetter:\n\n```ts\ngetData(userSchema);\n```\n\nInference usually scales better than annotation-heavy APIs.\n\n\u003Csup>[Table of Contents](#table-of-contents)\u003C\u002Fsup>\n\n### Turn On the Strict Compiler Options\n\nMany teams use TypeScript in \"autocomplete mode.\"\n\nStrict mode is where TypeScript really starts paying off.\n\n```json\n{\n  \"strict\": true,\n  \"noUncheckedIndexedAccess\": true,\n  \"exactOptionalPropertyTypes\": true\n}\n```\n\nThese flags dramatically improve correctness.\n\n\u003Csup>[Table of Contents](#table-of-contents)\u003C\u002Fsup>\n\n### Learn Template Literal Types\n\nOne of the most powerful modern TypeScript features.\n\n```ts\ntype Route = `\u002Fapi\u002F${string}`;\n```\n\nExcellent for:\n\n- Routes\n- Event names\n- CSS utilities\n- Design systems\n- Query keys\n\nOnce you start using them, they show up everywhere.\n\n\u003Csup>[Table of Contents](#table-of-contents)\u003C\u002Fsup>\n\n### \"Type-Safe\" Does Not Mean \"Runtime Safe\"\n\nA perfect final tip because it reframes everything.\n\nThis compiles:\n\n```ts\nconst user = (await response.json()) as User;\n```\n\nBut may still explode at runtime.\n\nTypeScript improves correctness:\n\n- It does not replace validation\n- It does not guarantee good architecture\n- It does not eliminate runtime bugs\n\nThis distinction becomes increasingly important in larger systems.\n\n\u003Csup>[Table of Contents](#table-of-contents)\u003C\u002Fsup>\n","该项目是一个精选的TypeScript模式集合，旨在提高代码的安全性、可读性、可维护性和开发体验。它通过一系列实用技巧如偏好使用`unknown`而非`any`、利用类型推断减少显式类型声明、使用`satisfies`关键字进行类型验证等，展示了如何更有效地编写TypeScript代码。此外，项目还介绍了如何从值中导出类型以避免重复定义、如何运用判别联合来处理不可能的状态以及运行时数据验证等高级用法。适合希望提升TypeScript编程技能的前端开发者或团队，在实际项目中实施这些最佳实践可以显著改善代码质量和开发效率。","2026-06-11 04:09:53","CREATED_QUERY"]