@umacloud/knowledge 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/00-governance/governance-capabilities.md +557 -0
- package/00-governance/knowledge-map.md +39 -0
- package/00-governance/maintenance-policy.md +76 -0
- package/00-governance/review-checklist.md +81 -0
- package/README.md +13 -0
- package/ai/01-standards/agent-development-complete.md +691 -0
- package/ai/01-standards/llm-application-complete.md +488 -0
- package/ai/01-standards/mlops-complete.md +798 -0
- package/ai/01-standards/prompt-engineering-complete.md +646 -0
- package/ai/01-standards/rag-architecture-complete.md +649 -0
- package/ai/02-playbooks/llm-evaluation-playbook.md +847 -0
- package/ai/03-checklists/ai-project-checklist.md +215 -0
- package/ai/04-antipatterns/ai-antipatterns.md +661 -0
- package/ai/05-cases/case-rag-production.md +147 -0
- package/ai/06-glossary/ai-glossary.md +162 -0
- package/ai/agent-evaluation-benchmark.md +53 -0
- package/ai/ai-agent-memory-context-management.md +41 -0
- package/ai/ai-cost-capacity-optimization-playbook.md +42 -0
- package/ai/ai-data-security-and-compliance-playbook.md +37 -0
- package/ai/ai-domain-index-and-checklist.md +40 -0
- package/ai/ai-governance-maturity-model.md +50 -0
- package/ai/ai-model-selection-and-routing-strategy.md +47 -0
- package/ai/ai-observability-and-oncall-runbook.md +52 -0
- package/ai/ai-rag-engineering-playbook.md +42 -0
- package/ai/ai-red-team-and-safety-evaluation.md +42 -0
- package/ai/ai-release-readiness-and-rollback-gate.md +42 -0
- package/ai/llm-agent-engineering-deep-dive.md +57 -0
- package/ai/prompt-and-tool-guardrails.md +52 -0
- package/api/01-standards/enterprise-api-standards.md +198 -0
- package/api/01-standards/rest-api-design-guide.md +63 -0
- package/api/02-playbooks/api-pagination-playbook.md +93 -0
- package/api/02-playbooks/graphql-production-playbook.md +176 -0
- package/api/03-checklists/api-review-checklist.md +55 -0
- package/api/04-antipatterns/api-antipatterns.md +112 -0
- package/architecture/01-standards/api-gateway-patterns.md +496 -0
- package/architecture/01-standards/cloud-native-patterns.md +644 -0
- package/architecture/01-standards/distributed-systems-patterns.md +591 -0
- package/architecture/01-standards/event-driven-architecture.md +595 -0
- package/architecture/01-standards/microservices-patterns-complete.md +968 -0
- package/architecture/01-standards/microservices-patterns.md +495 -0
- package/architecture/01-standards/system-design-interview.md +664 -0
- package/architecture/02-playbooks/microservices-patterns-playbook.md +137 -0
- package/architecture/02-playbooks/migration-playbook.md +780 -0
- package/architecture/02-playbooks/system-design-playbook.md +779 -0
- package/architecture/03-checklists/architecture-decision-checklist.md +297 -0
- package/architecture/04-antipatterns/architecture-antipatterns.md +417 -0
- package/architecture/05-cases/case-netflix-microservices.md +413 -0
- package/architecture/06-glossary/architecture-glossary.md +164 -0
- package/architecture/adr-template-and-examples.md +38 -0
- package/architecture/api-gateway-deep-dive.md +1291 -0
- package/architecture/configuration-management.md +1162 -0
- package/architecture/distributed-transactions.md +1220 -0
- package/architecture/microservices-complete.md +735 -0
- package/architecture/resilience-and-disaster-patterns.md +37 -0
- package/architecture/service-governance.md +1198 -0
- package/architecture/system-architecture-deep-dive.md +37 -0
- package/backend/01-standards/analytics-and-growth.md +65 -0
- package/backend/01-standards/api-and-error-conventions.md +120 -0
- package/backend/01-standards/application-layering-and-packaging.md +160 -0
- package/backend/01-standards/auth-implementation.md +104 -0
- package/backend/01-standards/backend-framework-idioms.md +74 -0
- package/backend/01-standards/background-jobs-and-async.md +66 -0
- package/backend/01-standards/caching-strategies-complete.md +390 -0
- package/backend/01-standards/config-and-observability.md +77 -0
- package/backend/01-standards/data-modeling-and-persistence.md +94 -0
- package/backend/01-standards/django-complete.md +1765 -0
- package/backend/01-standards/email-and-notifications.md +64 -0
- package/backend/01-standards/fastapi-complete.md +925 -0
- package/backend/01-standards/file-upload-and-storage.md +66 -0
- package/backend/01-standards/graphql-api-complete.md +416 -0
- package/backend/01-standards/llm-application-standard.md +78 -0
- package/backend/01-standards/message-queue-patterns.md +379 -0
- package/backend/01-standards/microservices-and-distributed.md +78 -0
- package/backend/01-standards/nestjs-complete.md +2167 -0
- package/backend/01-standards/payment-integration.md +80 -0
- package/backend/01-standards/rate-limiting-complete.md +451 -0
- package/backend/01-standards/realtime-and-websocket.md +65 -0
- package/backend/01-standards/search-and-filtering.md +64 -0
- package/backend/01-standards/spring-boot-complete.md +445 -0
- package/backend/02-playbooks/api-design-playbook.md +718 -0
- package/backend/02-playbooks/email-send-playbook.md +130 -0
- package/backend/02-playbooks/file-upload-s3-playbook.md +153 -0
- package/backend/02-playbooks/typescript-enterprise-playbook.md +133 -0
- package/backend/02-playbooks/websocket-realtime-playbook.md +154 -0
- package/backend/03-checklists/api-launch-checklist.md +189 -0
- package/backend/04-antipatterns/backend-antipatterns.md +1051 -0
- package/blockchain/01-standards/blockchain-basics.md +557 -0
- package/blockchain/01-standards/smart-contract-development.md +1315 -0
- package/cicd/01-standards/deployment-and-delivery-standard.md +96 -0
- package/cicd/01-standards/github-actions-complete.md +473 -0
- package/cicd/01-standards/release-and-store-submission.md +75 -0
- package/cicd/02-playbooks/cicd-pipeline-playbook.md +144 -0
- package/cicd/02-playbooks/release-management-playbook.md +605 -0
- package/cicd/03-checklists/pipeline-security-checklist.md +168 -0
- package/cicd/04-antipatterns/cicd-antipatterns.md +589 -0
- package/cicd/05-cases/case-deployment-automation.md +221 -0
- package/cicd/05-cases/case-gitops-transformation.md +212 -0
- package/cicd/06-glossary/cicd-glossary.md +114 -0
- package/cicd/cicd-blueprint-deep-dive.md +38 -0
- package/cicd/release-readiness-gate.md +37 -0
- package/cloud-native/01-standards/container-security.md +741 -0
- package/cloud-native/01-standards/kubernetes-complete.md +812 -0
- package/cloud-native/02-playbooks/api-gateway-playbook.md +155 -0
- package/cloud-native/02-playbooks/gitops-with-argocd.md +760 -0
- package/cloud-native/02-playbooks/k8s-troubleshooting-playbook.md +1942 -0
- package/cloud-native/02-playbooks/message-queue-playbook.md +129 -0
- package/cloud-native/02-playbooks/multicloud-governance.md +726 -0
- package/cloud-native/02-playbooks/serverless-patterns.md +788 -0
- package/cloud-native/02-playbooks/service-mesh-playbook.md +612 -0
- package/cloud-native/02-playbooks/terraform-iac-playbook.md +143 -0
- package/cloud-native/03-checklists/container-security-checklist.md +431 -0
- package/cloud-native/03-checklists/k8s-production-readiness-checklist.md +460 -0
- package/cloud-native/04-antipatterns/container-antipatterns.md +660 -0
- package/cloud-native/04-antipatterns/k8s-antipatterns.md +743 -0
- package/cloud-native/05-cases/case-k8s-migration.md +478 -0
- package/cloud-native/05-cases/case-k8s-scaling.md +642 -0
- package/cloud-native/05-cases/case-k8s-security-incident.md +397 -0
- package/cloud-native/06-glossary/cloud-native-glossary.md +337 -0
- package/cross-platform/01-standards/cross-platform-frameworks.md +83 -0
- package/cross-platform/01-standards/platform-selection-and-architecture.md +77 -0
- package/data/01-standards/elasticsearch-complete.md +2098 -0
- package/data/01-standards/postgresql-complete.md +1613 -0
- package/data/01-standards/redis-complete.md +1527 -0
- package/data/02-playbooks/database-optimization-playbook.md +403 -0
- package/data/02-playbooks/elasticsearch-production-playbook.md +132 -0
- package/data/03-checklists/database-launch-checklist.md +187 -0
- package/data/04-antipatterns/database-antipatterns.md +873 -0
- package/data/05-cases/case-database-migration.md +310 -0
- package/data/06-glossary/database-glossary.md +440 -0
- package/data/data-governance-and-modeling-deep-dive.md +39 -0
- package/data-engineering/01-standards/airflow-complete.md +523 -0
- package/data-engineering/01-standards/kafka-complete.md +1521 -0
- package/data-engineering/02-playbooks/spark-etl-playbook.md +496 -0
- package/data-engineering/03-checklists/pipeline-launch-checklist.md +194 -0
- package/data-engineering/04-antipatterns/data-pipeline-antipatterns.md +684 -0
- package/data-engineering/05-cases/case-real-time-pipeline.md +355 -0
- package/data-engineering/06-glossary/data-engineering-glossary.md +429 -0
- package/database/01-standards/database-schema-standards.md +147 -0
- package/database/02-playbooks/postgresql-optimization-quick.md +52 -0
- package/database/02-playbooks/postgresql-performance-optimization.md +58 -0
- package/database/02-playbooks/postgresql-production-playbook.md +146 -0
- package/database/02-playbooks/redis-caching-playbook.md +117 -0
- package/database/03-checklists/database-review-checklist.md +50 -0
- package/database/04-antipatterns/database-antipatterns.md +112 -0
- package/design/01-standards/ui-design-system-complete.md +423 -0
- package/design/02-playbooks/design-handoff-playbook.md +254 -0
- package/design/02-playbooks/design-review-playbook.md +388 -0
- package/design/03-checklists/design-review-checklist.md +246 -0
- package/design/04-antipatterns/design-antipatterns.md +378 -0
- package/design/05-cases/case-design-system-adoption.md +328 -0
- package/design/06-glossary/design-glossary.md +329 -0
- package/design/ui-full-lifecycle-cross-platform-playbook.md +571 -0
- package/design/ux-system-deep-dive.md +38 -0
- package/design-systems/00-craft-rules.md +71 -0
- package/design-systems/aesthetic-families.md +43 -0
- package/design-systems/anti-ai-slop.md +162 -0
- package/design-systems/bold-geometric.md +120 -0
- package/design-systems/brutalist-bold.md +103 -0
- package/design-systems/editorial-clean.md +109 -0
- package/design-systems/glass-aurora.md +108 -0
- package/design-systems/modern-minimal.md +145 -0
- package/design-systems/premium-luxury.md +106 -0
- package/design-systems/product-type-design-map.md +48 -0
- package/design-systems/soft-warm.md +123 -0
- package/design-systems/tech-utility.md +113 -0
- package/desktop/01-standards/desktop-app-standard.md +72 -0
- package/desktop/01-standards/desktop-design.md +71 -0
- package/development/00-governance/document-template.md +41 -0
- package/development/01-standards/api-versioning-strategies.md +432 -0
- package/development/01-standards/authentication-patterns-complete.md +479 -0
- package/development/01-standards/css-architecture-complete.md +550 -0
- package/development/01-standards/database-migration-strategies.md +484 -0
- package/development/01-standards/elasticsearch-complete.md +347 -0
- package/development/01-standards/git-complete.md +371 -0
- package/development/01-standards/golang-complete.md +1565 -0
- package/development/01-standards/graphql-complete.md +298 -0
- package/development/01-standards/javascript-bundlers-complete.md +469 -0
- package/development/01-standards/javascript-typescript-complete.md +528 -0
- package/development/01-standards/jest-complete.md +275 -0
- package/development/01-standards/linux-complete.md +234 -0
- package/development/01-standards/logging-observability-complete.md +526 -0
- package/development/01-standards/microservices-communication.md +502 -0
- package/development/01-standards/mongodb-complete.md +406 -0
- package/development/01-standards/oauth2-complete.md +285 -0
- package/development/01-standards/performance-optimization-complete.md +289 -0
- package/development/01-standards/playwright-complete.md +247 -0
- package/development/01-standards/postgresql-complete.md +456 -0
- package/development/01-standards/pytest-complete.md +340 -0
- package/development/01-standards/python-async-programming.md +902 -0
- package/development/01-standards/python-complete.md +956 -0
- package/development/01-standards/python-decorators-complete.md +799 -0
- package/development/01-standards/python-design-patterns.md +2854 -0
- package/development/01-standards/python-packaging-distribution.md +420 -0
- package/development/01-standards/python-testing-strategies.md +607 -0
- package/development/01-standards/python-web-frameworks-comparison.md +471 -0
- package/development/01-standards/redis-complete.md +317 -0
- package/development/01-standards/rest-api-complete.md +316 -0
- package/development/01-standards/rust-complete.md +578 -0
- package/development/01-standards/typescript-advanced-types.md +1513 -0
- package/development/01-standards/web-security-complete.md +292 -0
- package/development/02-playbooks/api-design-playbook.md +810 -0
- package/development/02-playbooks/database-migration-playbook.md +580 -0
- package/development/02-playbooks/debugging-playbook.md +692 -0
- package/development/02-playbooks/feature-delivery-playbook.md +430 -0
- package/development/02-playbooks/incident-hotfix-playbook.md +387 -0
- package/development/02-playbooks/performance-optimization-playbook.md +531 -0
- package/development/02-playbooks/performance-tuning-playbook.md +652 -0
- package/development/02-playbooks/refactor-playbook.md +403 -0
- package/development/02-playbooks/release-playbook.md +469 -0
- package/development/03-checklists/architecture-review-checklist.md +168 -0
- package/development/03-checklists/data-migration-checklist.md +157 -0
- package/development/03-checklists/oncall-handover-checklist.md +173 -0
- package/development/03-checklists/pr-checklist.md +158 -0
- package/development/03-checklists/production-readiness-checklist.md +190 -0
- package/development/03-checklists/release-readiness-checklist.md +154 -0
- package/development/03-checklists/security-review-checklist.md +182 -0
- package/development/04-antipatterns/api-antipatterns.md +657 -0
- package/development/04-antipatterns/architecture-antipatterns.md +686 -0
- package/development/04-antipatterns/backend-antipatterns.md +648 -0
- package/development/04-antipatterns/cicd-antipatterns.md +540 -0
- package/development/04-antipatterns/code-smell-antipatterns.md +571 -0
- package/development/04-antipatterns/data-antipatterns.md +658 -0
- package/development/04-antipatterns/database-antipatterns.md +578 -0
- package/development/04-antipatterns/frontend-antipatterns.md +635 -0
- package/development/04-antipatterns/reliability-antipatterns.md +700 -0
- package/development/04-antipatterns/security-antipatterns.md +747 -0
- package/development/05-cases/case-api-version-migration.md +428 -0
- package/development/05-cases/case-authorization-hardening.md +383 -0
- package/development/05-cases/case-bluegreen-rollback.md +466 -0
- package/development/05-cases/case-cache-snowball-protection.md +485 -0
- package/development/05-cases/case-ci-cd-pipeline.md +544 -0
- package/development/05-cases/case-database-scaling.md +500 -0
- package/development/05-cases/case-db-hotspot-optimization.md +487 -0
- package/development/05-cases/case-incident-mttr-reduction.md +563 -0
- package/development/05-cases/case-microservice-migration.md +375 -0
- package/development/05-cases/case-performance-optimization.md +406 -0
- package/development/05-cases/case-security-incident-response.md +345 -0
- package/development/06-glossary/full-stack-glossary.md +166 -0
- package/development/09-maturity/quarterly-audit-template.md +35 -0
- package/development/11-ui-excellence/ui-aesthetic-system.md +41 -0
- package/development/11-ui-excellence/ui-engineering-excellence.md +435 -0
- package/development/12-scenarios/development-scenarios-guide.md +565 -0
- package/development/13-implementation-assets/implementation-toolkit.md +282 -0
- package/development/13-implementation-assets/knowledge-gates-execution.md +43 -0
- package/development/14-full-lifecycle/software-lifecycle-gates.md +511 -0
- package/development/15-lifecycle-templates/project-templates-collection.md +791 -0
- package/development/api-contract-and-versioning-guide.md +36 -0
- package/development/api-governance-complete.md +43 -0
- package/development/backend-engineering-complete.md +43 -0
- package/development/code-review-quality-complete.md +43 -0
- package/development/concurrency-reliability-complete.md +43 -0
- package/development/database-engineering-complete.md +43 -0
- package/development/engineering-effectiveness-complete.md +43 -0
- package/development/engineering-standards-deep-dive.md +38 -0
- package/development/frontend-engineering-complete.md +43 -0
- package/development/performance-capacity-complete.md +43 -0
- package/development/refactor-migration-complete.md +42 -0
- package/development/refactoring-and-techdebt-playbook.md +37 -0
- package/development/security-in-development-complete.md +43 -0
- package/devops/01-standards/cicd-pipeline-complete.md +262 -0
- package/devops/01-standards/docker-complete.md +1490 -0
- package/devops/01-standards/github-actions-complete.md +337 -0
- package/devops/01-standards/kubernetes-complete.md +638 -0
- package/devops/01-standards/terraform-complete.md +2117 -0
- package/devops/02-playbooks/docker-compose-playbook.md +233 -0
- package/devops/02-playbooks/docker-k8s-production-playbook.md +186 -0
- package/devops/02-playbooks/docker-production-playbook.md +952 -0
- package/edge-iot/01-standards/edge-iot-complete.md +473 -0
- package/experts/architect/api-design.md +178 -0
- package/experts/architect/methodology.md +124 -0
- package/experts/architect/security.md +75 -0
- package/experts/backend-lead/methodology.md +216 -0
- package/experts/devops/methodology.md +160 -0
- package/experts/frontend-lead/methodology.md +178 -0
- package/experts/product-manager/industry/ecommerce.md +43 -0
- package/experts/product-manager/industry/saas.md +40 -0
- package/experts/product-manager/methodology.md +97 -0
- package/experts/qa-lead/methodology.md +123 -0
- package/experts/qa-lead/test-strategy.md +128 -0
- package/experts/uiux-designer/methodology.md +125 -0
- package/frontend/01-standards/accessibility-complete.md +532 -0
- package/frontend/01-standards/accessibility-standard.md +74 -0
- package/frontend/01-standards/admin-dashboard-and-crud.md +72 -0
- package/frontend/01-standards/design-tokens-complete.md +444 -0
- package/frontend/01-standards/forms-and-validation.md +77 -0
- package/frontend/01-standards/frontend-architecture-and-layering.md +119 -0
- package/frontend/01-standards/i18n-and-localization.md +65 -0
- package/frontend/01-standards/nextjs-complete.md +451 -0
- package/frontend/01-standards/react-complete.md +713 -0
- package/frontend/01-standards/react-hooks-complete-guide.md +1100 -0
- package/frontend/01-standards/react-hooks-complete.md +1171 -0
- package/frontend/01-standards/seo-and-web-vitals.md +77 -0
- package/frontend/01-standards/state-management-complete.md +444 -0
- package/frontend/01-standards/vue-complete.md +499 -0
- package/frontend/01-standards/vue3-complete.md +2002 -0
- package/frontend/01-standards/web-framework-best-practices.md +64 -0
- package/frontend/01-standards/web-performance-complete.md +495 -0
- package/frontend/02-playbooks/accessibility-a11y-playbook.md +161 -0
- package/frontend/02-playbooks/frontend-performance-playbook.md +707 -0
- package/frontend/02-playbooks/i18n-internationalization-playbook.md +120 -0
- package/frontend/02-playbooks/performance-optimization-playbook.md +163 -0
- package/frontend/02-playbooks/react-nextjs-production-playbook.md +167 -0
- package/frontend/02-playbooks/react-state-management-playbook.md +173 -0
- package/frontend/03-checklists/component-quality-checklist.md +166 -0
- package/frontend/03-checklists/frontend-launch-checklist.md +299 -0
- package/frontend/04-antipatterns/frontend-antipatterns.md +886 -0
- package/frontend/05-cases/case-performance-optimization.md +274 -0
- package/harmony/01-standards/harmonyos-arkts-standard.md +75 -0
- package/harmony/01-standards/harmonyos-design.md +65 -0
- package/high-quality-engineering-playbook.md +54 -0
- package/incident/01-standards/incident-response-complete.md +303 -0
- package/incident/02-playbooks/chaos-engineering-playbook.md +883 -0
- package/incident/02-playbooks/postmortem-playbook.md +398 -0
- package/incident/03-checklists/incident-readiness-checklist.md +181 -0
- package/incident/04-antipatterns/incident-antipatterns.md +490 -0
- package/incident/05-cases/case-cascade-failure.md +176 -0
- package/incident/06-glossary/incident-glossary.md +114 -0
- package/incident/postmortem-and-response-deep-dive.md +39 -0
- package/industries/ecommerce/ecommerce-complete.md +631 -0
- package/industries/education/education-complete.md +555 -0
- package/industries/fintech/fintech-complete.md +501 -0
- package/industries/gaming/gaming-complete.md +587 -0
- package/industries/healthcare/healthcare-complete.md +452 -0
- package/low-code/01-standards/low-code-complete.md +944 -0
- package/miniprogram/01-standards/ai-common-mistakes.md +61 -0
- package/miniprogram/01-standards/miniprogram-custom-navbar-capsule.md +77 -0
- package/miniprogram/01-standards/miniprogram-design.md +61 -0
- package/miniprogram/01-standards/miniprogram-standard.md +81 -0
- package/mobile/01-standards/android-material-design.md +70 -0
- package/mobile/01-standards/flutter-complete.md +384 -0
- package/mobile/01-standards/ios-design-hig.md +78 -0
- package/mobile/01-standards/mobile-app-standard.md +85 -0
- package/mobile/01-standards/react-native-complete.md +352 -0
- package/mobile/02-playbooks/mobile-cross-platform-playbook.md +175 -0
- package/mobile/02-playbooks/mobile-performance.md +473 -0
- package/mobile/03-checklists/mobile-release-checklist.md +234 -0
- package/mobile/04-antipatterns/mobile-antipatterns.md +798 -0
- package/mobile/05-cases/case-app-performance.md +500 -0
- package/mobile/05-cases/case-app-startup-optimization.md +218 -0
- package/mobile/06-glossary/mobile-glossary.md +484 -0
- package/observability/01-standards/observability-standards.md +103 -0
- package/observability/02-playbooks/prometheus-grafana-playbook.md +135 -0
- package/observability/02-playbooks/structured-logging-playbook.md +73 -0
- package/observability/03-checklists/observability-checklist.md +54 -0
- package/observability/04-antipatterns/observability-antipatterns.md +106 -0
- package/operations/01-standards/prometheus-monitoring-complete.md +1578 -0
- package/operations/02-playbooks/capacity-planning-playbook.md +620 -0
- package/operations/03-checklists/production-launch-checklist.md +365 -0
- package/operations/04-antipatterns/operations-antipatterns.md +664 -0
- package/operations/05-cases/case-sre-practices.md +581 -0
- package/operations/06-glossary/operations-glossary.md +120 -0
- package/operations/aiops-anomaly-detection.md +758 -0
- package/operations/capacity-planning.md +1061 -0
- package/operations/chaos-engineering.md +659 -0
- package/operations/incident-command-system.md +38 -0
- package/operations/observability-complete.md +442 -0
- package/operations/slo-sli-playbook.md +517 -0
- package/operations/sre-operations-deep-dive.md +39 -0
- package/package.json +8 -0
- package/performance/01-standards/performance-and-scalability.md +80 -0
- package/performance/01-standards/performance-standards.md +156 -0
- package/performance/02-playbooks/query-optimization-playbook.md +103 -0
- package/performance/03-checklists/performance-checklist.md +56 -0
- package/performance/04-antipatterns/performance-antipatterns.md +146 -0
- package/product/01-standards/product-management-complete.md +285 -0
- package/product/02-playbooks/feature-launch-playbook.md +207 -0
- package/product/02-playbooks/user-research-playbook.md +532 -0
- package/product/03-checklists/feature-launch-checklist.md +275 -0
- package/product/04-antipatterns/product-antipatterns.md +355 -0
- package/product/05-cases/case-mvp-to-scale.md +384 -0
- package/product/06-glossary/product-glossary.md +462 -0
- package/product/feature-prioritization-framework.md +40 -0
- package/product/kpi-and-metric-tree.md +37 -0
- package/product/product-discovery-and-prd-deep-dive.md +41 -0
- package/quantum/01-standards/quantum-complete.md +1186 -0
- package/security/01-standards/api-security-complete.md +511 -0
- package/security/01-standards/container-runtime-security.md +574 -0
- package/security/01-standards/data-protection-gdpr.md +543 -0
- package/security/01-standards/owasp-top10-complete.md +1890 -0
- package/security/01-standards/secure-coding-baseline.md +90 -0
- package/security/01-standards/supply-chain-security.md +441 -0
- package/security/01-standards/web-security-checklist.md +108 -0
- package/security/01-standards/zero-trust-architecture.md +521 -0
- package/security/02-playbooks/auth-sso-playbook.md +166 -0
- package/security/02-playbooks/incident-response-security-playbook.md +588 -0
- package/security/02-playbooks/owasp-api-security-playbook.md +129 -0
- package/security/02-playbooks/payment-integration-playbook.md +119 -0
- package/security/02-playbooks/penetration-testing-playbook.md +517 -0
- package/security/03-checklists/security-audit-checklist.md +356 -0
- package/security/04-antipatterns/security-coding-antipatterns.md +580 -0
- package/security/05-cases/case-log4shell-incident.md +537 -0
- package/security/05-cases/case-major-breaches.md +468 -0
- package/security/06-glossary/security-glossary.md +212 -0
- package/security/compliance-automation.md +993 -0
- package/security/container-security.md +680 -0
- package/security/devsecops-complete.md +426 -0
- package/security/sast-dast-sca.md +775 -0
- package/security/secrets-management.md +594 -0
- package/security/security-architecture-deep-dive.md +37 -0
- package/security/threat-modeling-stride-playbook.md +40 -0
- package/seed-templates/auth-system.md +59 -0
- package/seed-templates/blog-content.md +94 -0
- package/seed-templates/dashboard.md +89 -0
- package/seed-templates/docs-site.md +73 -0
- package/seed-templates/e-commerce.md +50 -0
- package/seed-templates/saas-landing.md +92 -0
- package/seed-templates/settings-page.md +51 -0
- package/testing/01-standards/test-strategy-and-layering.md +83 -0
- package/testing/01-standards/testing-strategy-complete.md +422 -0
- package/testing/01-standards/unit-testing-best-practices.md +118 -0
- package/testing/02-playbooks/e2e-testing-playbook.md +988 -0
- package/testing/02-playbooks/testing-strategy-playbook.md +126 -0
- package/testing/03-checklists/test-strategy-checklist.md +208 -0
- package/testing/04-antipatterns/testing-antipatterns.md +718 -0
- package/testing/05-cases/case-testing-transformation.md +300 -0
- package/testing/06-glossary/testing-glossary.md +110 -0
- package/testing/risk-based-test-matrix.md +36 -0
- package/testing/testing-strategy-deep-dive.md +37 -0
|
@@ -0,0 +1,1513 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: typescript-advanced-types
|
|
3
|
+
title: TypeScript 高级类型系统完整指南
|
|
4
|
+
domain: development
|
|
5
|
+
category: 01-standards
|
|
6
|
+
difficulty: intermediate
|
|
7
|
+
tags: [advanced, development, types, typescript, 与框架集成, 内置工具类型, 基础类型系统回顾, 完整指南]
|
|
8
|
+
quality_score: 70
|
|
9
|
+
last_updated: 2026-06-15
|
|
10
|
+
---
|
|
11
|
+
# TypeScript 高级类型系统完整指南
|
|
12
|
+
|
|
13
|
+
## 概述
|
|
14
|
+
TypeScript 的类型系统是图灵完备的,远超简单的类型注解。掌握高级类型能力可以在编译期捕获更多错误、提升代码可维护性、实现精准的 API 契约。本指南面向已有 TypeScript 基础的开发者,系统梳理泛型、工具类型、高级模式、装饰器、模块系统、项目配置、框架集成、常见陷阱与性能优化。
|
|
15
|
+
|
|
16
|
+
## 基础类型系统回顾
|
|
17
|
+
|
|
18
|
+
### 原始类型与字面量类型
|
|
19
|
+
|
|
20
|
+
```typescript
|
|
21
|
+
// 原始类型
|
|
22
|
+
const name: string = "Alice";
|
|
23
|
+
const age: number = 30;
|
|
24
|
+
const active: boolean = true;
|
|
25
|
+
const id: bigint = 9007199254740991n;
|
|
26
|
+
const key: symbol = Symbol("key");
|
|
27
|
+
|
|
28
|
+
// 字面量类型 — 将值本身作为类型
|
|
29
|
+
type Direction = "north" | "south" | "east" | "west";
|
|
30
|
+
type HttpStatus = 200 | 301 | 404 | 500;
|
|
31
|
+
type Toggle = true | false;
|
|
32
|
+
|
|
33
|
+
// as const 将值收窄为字面量类型
|
|
34
|
+
const config = {
|
|
35
|
+
endpoint: "https://api.example.com",
|
|
36
|
+
retries: 3,
|
|
37
|
+
debug: false,
|
|
38
|
+
} as const;
|
|
39
|
+
// typeof config.endpoint => "https://api.example.com"(字面量,非 string)
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### 联合类型与交叉类型
|
|
43
|
+
|
|
44
|
+
```typescript
|
|
45
|
+
// 联合类型: 或
|
|
46
|
+
type Result<T> = T | Error;
|
|
47
|
+
type StringOrNumber = string | number;
|
|
48
|
+
|
|
49
|
+
// 交叉类型: 且
|
|
50
|
+
type WithTimestamps = {
|
|
51
|
+
createdAt: Date;
|
|
52
|
+
updatedAt: Date;
|
|
53
|
+
};
|
|
54
|
+
type User = { id: string; name: string } & WithTimestamps;
|
|
55
|
+
|
|
56
|
+
// 可辨识联合(Discriminated Union)
|
|
57
|
+
type Shape =
|
|
58
|
+
| { kind: "circle"; radius: number }
|
|
59
|
+
| { kind: "rectangle"; width: number; height: number }
|
|
60
|
+
| { kind: "triangle"; base: number; height: number };
|
|
61
|
+
|
|
62
|
+
function area(shape: Shape): number {
|
|
63
|
+
switch (shape.kind) {
|
|
64
|
+
case "circle":
|
|
65
|
+
return Math.PI * shape.radius ** 2;
|
|
66
|
+
case "rectangle":
|
|
67
|
+
return shape.width * shape.height;
|
|
68
|
+
case "triangle":
|
|
69
|
+
return (shape.base * shape.height) / 2;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### 类型别名与接口
|
|
75
|
+
|
|
76
|
+
```typescript
|
|
77
|
+
// 接口 — 可声明合并,适合对外 API
|
|
78
|
+
interface ApiResponse<T> {
|
|
79
|
+
data: T;
|
|
80
|
+
status: number;
|
|
81
|
+
message: string;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// 类型别名 — 支持联合/交叉/映射/条件,适合内部建模
|
|
85
|
+
type Nullable<T> = T | null;
|
|
86
|
+
type ReadonlyDeep<T> = {
|
|
87
|
+
readonly [K in keyof T]: T[K] extends object ? ReadonlyDeep<T[K]> : T[K];
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
// 接口继承
|
|
91
|
+
interface BaseEntity {
|
|
92
|
+
id: string;
|
|
93
|
+
createdAt: Date;
|
|
94
|
+
}
|
|
95
|
+
interface UserEntity extends BaseEntity {
|
|
96
|
+
email: string;
|
|
97
|
+
role: "admin" | "user";
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// 接口声明合并(Declaration Merging)
|
|
101
|
+
interface Window {
|
|
102
|
+
__APP_CONFIG__: Record<string, unknown>;
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## 泛型(Generics)
|
|
107
|
+
|
|
108
|
+
### 基础泛型
|
|
109
|
+
|
|
110
|
+
```typescript
|
|
111
|
+
// 泛型函数
|
|
112
|
+
function identity<T>(value: T): T {
|
|
113
|
+
return value;
|
|
114
|
+
}
|
|
115
|
+
const str = identity("hello"); // 推导为 string
|
|
116
|
+
const num = identity(42); // 推导为 number
|
|
117
|
+
|
|
118
|
+
// 泛型接口
|
|
119
|
+
interface Repository<T> {
|
|
120
|
+
findById(id: string): Promise<T | null>;
|
|
121
|
+
findAll(filter?: Partial<T>): Promise<T[]>;
|
|
122
|
+
create(data: Omit<T, "id">): Promise<T>;
|
|
123
|
+
update(id: string, data: Partial<T>): Promise<T>;
|
|
124
|
+
delete(id: string): Promise<boolean>;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// 泛型类
|
|
128
|
+
class TypedEventEmitter<Events extends Record<string, unknown[]>> {
|
|
129
|
+
private listeners = new Map<keyof Events, Set<Function>>();
|
|
130
|
+
|
|
131
|
+
on<K extends keyof Events>(event: K, handler: (...args: Events[K]) => void) {
|
|
132
|
+
if (!this.listeners.has(event)) {
|
|
133
|
+
this.listeners.set(event, new Set());
|
|
134
|
+
}
|
|
135
|
+
this.listeners.get(event)!.add(handler);
|
|
136
|
+
return this;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
emit<K extends keyof Events>(event: K, ...args: Events[K]) {
|
|
140
|
+
this.listeners.get(event)?.forEach((handler) => handler(...args));
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// 使用
|
|
145
|
+
type AppEvents = {
|
|
146
|
+
login: [userId: string, timestamp: number];
|
|
147
|
+
logout: [userId: string];
|
|
148
|
+
error: [error: Error, context: string];
|
|
149
|
+
};
|
|
150
|
+
const emitter = new TypedEventEmitter<AppEvents>();
|
|
151
|
+
emitter.on("login", (userId, timestamp) => { /* 完全类型安全 */ });
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### 泛型约束(Constraints)
|
|
155
|
+
|
|
156
|
+
```typescript
|
|
157
|
+
// extends 约束
|
|
158
|
+
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
|
|
159
|
+
return obj[key];
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// 多重约束
|
|
163
|
+
interface Serializable {
|
|
164
|
+
serialize(): string;
|
|
165
|
+
}
|
|
166
|
+
interface Loggable {
|
|
167
|
+
log(): void;
|
|
168
|
+
}
|
|
169
|
+
function process<T extends Serializable & Loggable>(item: T): string {
|
|
170
|
+
item.log();
|
|
171
|
+
return item.serialize();
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// 构造函数约束
|
|
175
|
+
type Constructor<T = {}> = new (...args: any[]) => T;
|
|
176
|
+
|
|
177
|
+
function Timestamped<TBase extends Constructor>(Base: TBase) {
|
|
178
|
+
return class extends Base {
|
|
179
|
+
createdAt = new Date();
|
|
180
|
+
updatedAt = new Date();
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// 递归约束
|
|
185
|
+
type JSONValue =
|
|
186
|
+
| string
|
|
187
|
+
| number
|
|
188
|
+
| boolean
|
|
189
|
+
| null
|
|
190
|
+
| JSONValue[]
|
|
191
|
+
| { [key: string]: JSONValue };
|
|
192
|
+
|
|
193
|
+
function deepClone<T extends JSONValue>(value: T): T {
|
|
194
|
+
return JSON.parse(JSON.stringify(value));
|
|
195
|
+
}
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### 泛型默认值
|
|
199
|
+
|
|
200
|
+
```typescript
|
|
201
|
+
// 带默认类型参数的泛型
|
|
202
|
+
interface PaginatedResponse<T, M = { total: number; page: number }> {
|
|
203
|
+
items: T[];
|
|
204
|
+
meta: M;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// 使用默认值
|
|
208
|
+
type UserList = PaginatedResponse<User>;
|
|
209
|
+
// 覆盖默认值
|
|
210
|
+
type CursorUserList = PaginatedResponse<User, { cursor: string; hasMore: boolean }>;
|
|
211
|
+
|
|
212
|
+
// 带默认值的泛型工厂函数
|
|
213
|
+
function createStore<
|
|
214
|
+
State extends Record<string, unknown> = Record<string, unknown>,
|
|
215
|
+
Actions extends Record<string, Function> = Record<string, Function>
|
|
216
|
+
>(config: { state: State; actions: Actions }) {
|
|
217
|
+
return config;
|
|
218
|
+
}
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
### 条件类型(Conditional Types)
|
|
222
|
+
|
|
223
|
+
```typescript
|
|
224
|
+
// 基本条件类型
|
|
225
|
+
type IsString<T> = T extends string ? true : false;
|
|
226
|
+
type A = IsString<"hello">; // true
|
|
227
|
+
type B = IsString<42>; // false
|
|
228
|
+
|
|
229
|
+
// 分布式条件类型 — 联合类型自动分配
|
|
230
|
+
type ToArray<T> = T extends unknown ? T[] : never;
|
|
231
|
+
type C = ToArray<string | number>; // string[] | number[]
|
|
232
|
+
|
|
233
|
+
// 阻止分布式行为
|
|
234
|
+
type ToArrayNonDist<T> = [T] extends [unknown] ? T[] : never;
|
|
235
|
+
type D = ToArrayNonDist<string | number>; // (string | number)[]
|
|
236
|
+
|
|
237
|
+
// 条件类型嵌套
|
|
238
|
+
type TypeName<T> =
|
|
239
|
+
T extends string ? "string" :
|
|
240
|
+
T extends number ? "number" :
|
|
241
|
+
T extends boolean ? "boolean" :
|
|
242
|
+
T extends undefined ? "undefined" :
|
|
243
|
+
T extends Function ? "function" :
|
|
244
|
+
"object";
|
|
245
|
+
|
|
246
|
+
// infer 关键字 — 在条件类型中提取子类型
|
|
247
|
+
type UnpackPromise<T> = T extends Promise<infer U> ? U : T;
|
|
248
|
+
type E = UnpackPromise<Promise<string>>; // string
|
|
249
|
+
|
|
250
|
+
type FunctionParams<T> = T extends (...args: infer P) => any ? P : never;
|
|
251
|
+
type F = FunctionParams<(a: string, b: number) => void>; // [a: string, b: number]
|
|
252
|
+
|
|
253
|
+
type FirstElement<T> = T extends [infer First, ...unknown[]] ? First : never;
|
|
254
|
+
type G = FirstElement<[string, number, boolean]>; // string
|
|
255
|
+
|
|
256
|
+
// 复杂 infer 示例: 提取嵌套路径
|
|
257
|
+
type ExtractRouteParams<T extends string> =
|
|
258
|
+
T extends `${string}:${infer Param}/${infer Rest}`
|
|
259
|
+
? { [K in Param | keyof ExtractRouteParams<Rest>]: string }
|
|
260
|
+
: T extends `${string}:${infer Param}`
|
|
261
|
+
? { [K in Param]: string }
|
|
262
|
+
: {};
|
|
263
|
+
|
|
264
|
+
type Params = ExtractRouteParams<"/users/:userId/posts/:postId">;
|
|
265
|
+
// { userId: string; postId: string }
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
### 映射类型(Mapped Types)
|
|
269
|
+
|
|
270
|
+
```typescript
|
|
271
|
+
// 基本映射
|
|
272
|
+
type Optional<T> = {
|
|
273
|
+
[K in keyof T]?: T[K];
|
|
274
|
+
};
|
|
275
|
+
|
|
276
|
+
// 添加/移除修饰符
|
|
277
|
+
type Mutable<T> = {
|
|
278
|
+
-readonly [K in keyof T]: T[K];
|
|
279
|
+
};
|
|
280
|
+
type Required<T> = {
|
|
281
|
+
[K in keyof T]-?: T[K];
|
|
282
|
+
};
|
|
283
|
+
|
|
284
|
+
// 键重映射(as 子句, TypeScript 4.1+)
|
|
285
|
+
type Getters<T> = {
|
|
286
|
+
[K in keyof T as `get${Capitalize<string & K>}`]: () => T[K];
|
|
287
|
+
};
|
|
288
|
+
type Setters<T> = {
|
|
289
|
+
[K in keyof T as `set${Capitalize<string & K>}`]: (value: T[K]) => void;
|
|
290
|
+
};
|
|
291
|
+
|
|
292
|
+
interface Person {
|
|
293
|
+
name: string;
|
|
294
|
+
age: number;
|
|
295
|
+
}
|
|
296
|
+
type PersonGetters = Getters<Person>;
|
|
297
|
+
// { getName: () => string; getAge: () => number }
|
|
298
|
+
|
|
299
|
+
// 过滤键
|
|
300
|
+
type FilterByType<T, U> = {
|
|
301
|
+
[K in keyof T as T[K] extends U ? K : never]: T[K];
|
|
302
|
+
};
|
|
303
|
+
type StringProps = FilterByType<{ id: number; name: string; email: string }, string>;
|
|
304
|
+
// { name: string; email: string }
|
|
305
|
+
|
|
306
|
+
// 映射联合类型到对象
|
|
307
|
+
type EventHandlers<T extends string> = {
|
|
308
|
+
[K in T as `on${Capitalize<K>}`]: (event: K) => void;
|
|
309
|
+
};
|
|
310
|
+
type DomHandlers = EventHandlers<"click" | "focus" | "blur">;
|
|
311
|
+
// { onClick: (event: "click") => void; onFocus: ...; onBlur: ... }
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
### 模板字面量类型(Template Literal Types)
|
|
315
|
+
|
|
316
|
+
```typescript
|
|
317
|
+
// 基础模板字面量
|
|
318
|
+
type Greeting = `Hello, ${string}!`;
|
|
319
|
+
const g: Greeting = "Hello, TypeScript!"; // OK
|
|
320
|
+
|
|
321
|
+
// 联合类型组合
|
|
322
|
+
type Color = "red" | "green" | "blue";
|
|
323
|
+
type Size = "small" | "medium" | "large";
|
|
324
|
+
type ColorSize = `${Color}-${Size}`;
|
|
325
|
+
// "red-small" | "red-medium" | "red-large" | "green-small" | ...
|
|
326
|
+
|
|
327
|
+
// 内置字符串操作类型
|
|
328
|
+
type Upper = Uppercase<"hello">; // "HELLO"
|
|
329
|
+
type Lower = Lowercase<"HELLO">; // "hello"
|
|
330
|
+
type Cap = Capitalize<"hello">; // "Hello"
|
|
331
|
+
type Uncap = Uncapitalize<"Hello">; // "hello"
|
|
332
|
+
|
|
333
|
+
// CSS 单位类型
|
|
334
|
+
type CSSUnit = "px" | "em" | "rem" | "vh" | "vw" | "%";
|
|
335
|
+
type CSSValue = `${number}${CSSUnit}`;
|
|
336
|
+
const width: CSSValue = "100px"; // OK
|
|
337
|
+
const height: CSSValue = "50vh"; // OK
|
|
338
|
+
|
|
339
|
+
// 深度路径类型
|
|
340
|
+
type PathOf<T, Prefix extends string = ""> = T extends object
|
|
341
|
+
? {
|
|
342
|
+
[K in keyof T & string]: T[K] extends object
|
|
343
|
+
? `${Prefix}${K}` | PathOf<T[K], `${Prefix}${K}.`>
|
|
344
|
+
: `${Prefix}${K}`;
|
|
345
|
+
}[keyof T & string]
|
|
346
|
+
: never;
|
|
347
|
+
|
|
348
|
+
interface Config {
|
|
349
|
+
db: { host: string; port: number };
|
|
350
|
+
cache: { ttl: number };
|
|
351
|
+
}
|
|
352
|
+
type ConfigPath = PathOf<Config>;
|
|
353
|
+
// "db" | "db.host" | "db.port" | "cache" | "cache.ttl"
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
## 内置工具类型
|
|
357
|
+
|
|
358
|
+
### 对象操作类
|
|
359
|
+
|
|
360
|
+
```typescript
|
|
361
|
+
// Partial<T> — 所有属性可选
|
|
362
|
+
interface UserUpdate {
|
|
363
|
+
name: string;
|
|
364
|
+
email: string;
|
|
365
|
+
avatar: string;
|
|
366
|
+
}
|
|
367
|
+
function updateUser(id: string, updates: Partial<UserUpdate>) {
|
|
368
|
+
// updates 的每个字段都是可选的
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
// Required<T> — 所有属性必填
|
|
372
|
+
interface Config {
|
|
373
|
+
host?: string;
|
|
374
|
+
port?: number;
|
|
375
|
+
debug?: boolean;
|
|
376
|
+
}
|
|
377
|
+
function initServer(config: Required<Config>) {
|
|
378
|
+
// config.host, config.port, config.debug 都必填
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
// Readonly<T> — 所有属性只读
|
|
382
|
+
function freeze<T extends object>(obj: T): Readonly<T> {
|
|
383
|
+
return Object.freeze(obj);
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
// Record<K, V> — 构造键值对类型
|
|
387
|
+
type UserRoles = Record<string, "admin" | "editor" | "viewer">;
|
|
388
|
+
const roles: UserRoles = {
|
|
389
|
+
alice: "admin",
|
|
390
|
+
bob: "editor",
|
|
391
|
+
};
|
|
392
|
+
|
|
393
|
+
// 常见 Record 模式: 枚举键映射
|
|
394
|
+
type Status = "active" | "inactive" | "pending";
|
|
395
|
+
const statusLabels: Record<Status, string> = {
|
|
396
|
+
active: "活跃",
|
|
397
|
+
inactive: "未激活",
|
|
398
|
+
pending: "待审核",
|
|
399
|
+
};
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
### 属性筛选类
|
|
403
|
+
|
|
404
|
+
```typescript
|
|
405
|
+
// Pick<T, K> — 选取部分属性
|
|
406
|
+
interface User {
|
|
407
|
+
id: string;
|
|
408
|
+
name: string;
|
|
409
|
+
email: string;
|
|
410
|
+
password: string;
|
|
411
|
+
createdAt: Date;
|
|
412
|
+
}
|
|
413
|
+
type PublicUser = Pick<User, "id" | "name" | "email">;
|
|
414
|
+
|
|
415
|
+
// Omit<T, K> — 排除部分属性
|
|
416
|
+
type CreateUserDTO = Omit<User, "id" | "createdAt">;
|
|
417
|
+
|
|
418
|
+
// 组合使用
|
|
419
|
+
type UserProfile = Pick<User, "id" | "name"> & {
|
|
420
|
+
avatar: string;
|
|
421
|
+
bio?: string;
|
|
422
|
+
};
|
|
423
|
+
```
|
|
424
|
+
|
|
425
|
+
### 联合操作类
|
|
426
|
+
|
|
427
|
+
```typescript
|
|
428
|
+
// Exclude<T, U> — 从联合中排除
|
|
429
|
+
type AllEvents = "click" | "focus" | "blur" | "scroll" | "resize";
|
|
430
|
+
type UIEvents = Exclude<AllEvents, "scroll" | "resize">;
|
|
431
|
+
// "click" | "focus" | "blur"
|
|
432
|
+
|
|
433
|
+
// Extract<T, U> — 从联合中提取
|
|
434
|
+
type NumericTypes = Extract<string | number | boolean | bigint, number | bigint>;
|
|
435
|
+
// number | bigint
|
|
436
|
+
|
|
437
|
+
// NonNullable<T> — 排除 null 和 undefined
|
|
438
|
+
type MaybeString = string | null | undefined;
|
|
439
|
+
type DefiniteString = NonNullable<MaybeString>; // string
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
### 函数操作类
|
|
443
|
+
|
|
444
|
+
```typescript
|
|
445
|
+
// ReturnType<T> — 提取返回值类型
|
|
446
|
+
function createUser(name: string, email: string) {
|
|
447
|
+
return { id: crypto.randomUUID(), name, email, createdAt: new Date() };
|
|
448
|
+
}
|
|
449
|
+
type CreatedUser = ReturnType<typeof createUser>;
|
|
450
|
+
// { id: string; name: string; email: string; createdAt: Date }
|
|
451
|
+
|
|
452
|
+
// Parameters<T> — 提取参数类型
|
|
453
|
+
type CreateUserParams = Parameters<typeof createUser>;
|
|
454
|
+
// [name: string, email: string]
|
|
455
|
+
|
|
456
|
+
// ConstructorParameters<T> — 提取构造函数参数
|
|
457
|
+
class HttpClient {
|
|
458
|
+
constructor(baseURL: string, timeout: number, headers?: Record<string, string>) {}
|
|
459
|
+
}
|
|
460
|
+
type HttpClientArgs = ConstructorParameters<typeof HttpClient>;
|
|
461
|
+
// [baseURL: string, timeout: number, headers?: Record<string, string>]
|
|
462
|
+
|
|
463
|
+
// InstanceType<T> — 提取实例类型
|
|
464
|
+
type HttpClientInstance = InstanceType<typeof HttpClient>;
|
|
465
|
+
|
|
466
|
+
// Awaited<T> — 解包 Promise 类型(TypeScript 4.5+)
|
|
467
|
+
type ResolvedData = Awaited<Promise<Promise<string>>>; // string
|
|
468
|
+
|
|
469
|
+
async function fetchUsers(): Promise<User[]> {
|
|
470
|
+
return [];
|
|
471
|
+
}
|
|
472
|
+
type FetchResult = Awaited<ReturnType<typeof fetchUsers>>; // User[]
|
|
473
|
+
|
|
474
|
+
// ThisParameterType / OmitThisParameter
|
|
475
|
+
function greet(this: { name: string }, greeting: string) {
|
|
476
|
+
return `${greeting}, ${this.name}`;
|
|
477
|
+
}
|
|
478
|
+
type GreetThis = ThisParameterType<typeof greet>; // { name: string }
|
|
479
|
+
type GreetFn = OmitThisParameter<typeof greet>; // (greeting: string) => string
|
|
480
|
+
```
|
|
481
|
+
|
|
482
|
+
## 高级模式
|
|
483
|
+
|
|
484
|
+
### 类型守卫(Type Guards)
|
|
485
|
+
|
|
486
|
+
```typescript
|
|
487
|
+
// typeof 守卫
|
|
488
|
+
function formatValue(value: string | number): string {
|
|
489
|
+
if (typeof value === "string") {
|
|
490
|
+
return value.toUpperCase();
|
|
491
|
+
}
|
|
492
|
+
return value.toFixed(2);
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
// instanceof 守卫
|
|
496
|
+
class ApiError extends Error {
|
|
497
|
+
constructor(public statusCode: number, message: string) {
|
|
498
|
+
super(message);
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
function handleError(error: Error) {
|
|
502
|
+
if (error instanceof ApiError) {
|
|
503
|
+
console.log(`API Error ${error.statusCode}: ${error.message}`);
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
// 自定义类型守卫(type predicate)
|
|
508
|
+
interface Cat { meow(): void; }
|
|
509
|
+
interface Dog { bark(): void; }
|
|
510
|
+
type Pet = Cat | Dog;
|
|
511
|
+
|
|
512
|
+
function isCat(pet: Pet): pet is Cat {
|
|
513
|
+
return "meow" in pet;
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
function handlePet(pet: Pet) {
|
|
517
|
+
if (isCat(pet)) {
|
|
518
|
+
pet.meow(); // 类型收窄为 Cat
|
|
519
|
+
} else {
|
|
520
|
+
pet.bark(); // 类型收窄为 Dog
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
// 断言函数(Assertion Functions, TypeScript 3.7+)
|
|
525
|
+
function assertDefined<T>(value: T | null | undefined, msg?: string): asserts value is T {
|
|
526
|
+
if (value === null || value === undefined) {
|
|
527
|
+
throw new Error(msg ?? "Value is not defined");
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
function processUser(user: User | null) {
|
|
532
|
+
assertDefined(user, "User must exist");
|
|
533
|
+
console.log(user.name); // 此处 user 确定为 User
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
// 复合守卫
|
|
537
|
+
function isNonEmptyArray<T>(arr: T[]): arr is [T, ...T[]] {
|
|
538
|
+
return arr.length > 0;
|
|
539
|
+
}
|
|
540
|
+
```
|
|
541
|
+
|
|
542
|
+
### 类型断言(Type Assertions)
|
|
543
|
+
|
|
544
|
+
```typescript
|
|
545
|
+
// as 断言 — 告诉编译器"我比你更清楚"
|
|
546
|
+
const input = document.getElementById("email") as HTMLInputElement;
|
|
547
|
+
input.value = "test@example.com";
|
|
548
|
+
|
|
549
|
+
// 双重断言(慎用,绕过类型检查)
|
|
550
|
+
const value = "hello" as unknown as number; // 强制转换
|
|
551
|
+
|
|
552
|
+
// const 断言 — 收窄为最精确的字面量类型
|
|
553
|
+
const routes = ["home", "about", "contact"] as const;
|
|
554
|
+
type Route = (typeof routes)[number]; // "home" | "about" | "contact"
|
|
555
|
+
|
|
556
|
+
// satisfies 操作符(TypeScript 4.9+)— 校验而不拓宽
|
|
557
|
+
type Colors = Record<string, string | string[]>;
|
|
558
|
+
const palette = {
|
|
559
|
+
red: "#ff0000",
|
|
560
|
+
green: "#00ff00",
|
|
561
|
+
blue: ["#0000ff", "#0000cc"],
|
|
562
|
+
} satisfies Colors;
|
|
563
|
+
// palette.red 保持 string 类型(非 string | string[])
|
|
564
|
+
// palette.blue 保持 string[] 类型,可以调用 .map()
|
|
565
|
+
```
|
|
566
|
+
|
|
567
|
+
### 类型推导与 infer
|
|
568
|
+
|
|
569
|
+
```typescript
|
|
570
|
+
// 提取数组元素类型
|
|
571
|
+
type ElementOf<T> = T extends readonly (infer E)[] ? E : never;
|
|
572
|
+
type Nums = ElementOf<number[]>; // number
|
|
573
|
+
|
|
574
|
+
// 提取函数最后一个参数
|
|
575
|
+
type LastParam<T extends (...args: any[]) => any> =
|
|
576
|
+
T extends (...args: [...infer _, infer Last]) => any ? Last : never;
|
|
577
|
+
type Last = LastParam<(a: string, b: number, c: boolean) => void>; // boolean
|
|
578
|
+
|
|
579
|
+
// 提取 Promise 链
|
|
580
|
+
type DeepAwaited<T> = T extends Promise<infer U> ? DeepAwaited<U> : T;
|
|
581
|
+
|
|
582
|
+
// 提取对象值类型
|
|
583
|
+
type ValueOf<T> = T[keyof T];
|
|
584
|
+
type UserValues = ValueOf<User>; // string | Date
|
|
585
|
+
|
|
586
|
+
// 提取元组第一个和剩余
|
|
587
|
+
type Head<T extends readonly unknown[]> = T extends [infer H, ...unknown[]] ? H : never;
|
|
588
|
+
type Tail<T extends readonly unknown[]> = T extends [unknown, ...infer R] ? R : never;
|
|
589
|
+
```
|
|
590
|
+
|
|
591
|
+
### 递归类型
|
|
592
|
+
|
|
593
|
+
```typescript
|
|
594
|
+
// 深度只读
|
|
595
|
+
type DeepReadonly<T> = T extends Function
|
|
596
|
+
? T
|
|
597
|
+
: T extends object
|
|
598
|
+
? { readonly [K in keyof T]: DeepReadonly<T[K]> }
|
|
599
|
+
: T;
|
|
600
|
+
|
|
601
|
+
// 深度部分可选
|
|
602
|
+
type DeepPartial<T> = T extends Function
|
|
603
|
+
? T
|
|
604
|
+
: T extends object
|
|
605
|
+
? { [K in keyof T]?: DeepPartial<T[K]> }
|
|
606
|
+
: T;
|
|
607
|
+
|
|
608
|
+
// 递归展平数组
|
|
609
|
+
type Flatten<T extends readonly unknown[]> = T extends [infer First, ...infer Rest]
|
|
610
|
+
? First extends readonly unknown[]
|
|
611
|
+
? [...Flatten<First>, ...Flatten<Rest>]
|
|
612
|
+
: [First, ...Flatten<Rest>]
|
|
613
|
+
: [];
|
|
614
|
+
type Flat = Flatten<[1, [2, [3, 4]], 5]>; // [1, 2, 3, 4, 5]
|
|
615
|
+
|
|
616
|
+
// JSON 安全类型
|
|
617
|
+
type JSONSafe<T> = T extends Date
|
|
618
|
+
? string
|
|
619
|
+
: T extends Function
|
|
620
|
+
? never
|
|
621
|
+
: T extends object
|
|
622
|
+
? { [K in keyof T as JSONSafe<T[K]> extends never ? never : K]: JSONSafe<T[K]> }
|
|
623
|
+
: T;
|
|
624
|
+
```
|
|
625
|
+
|
|
626
|
+
### 变体类型(Variance)
|
|
627
|
+
|
|
628
|
+
```typescript
|
|
629
|
+
// 协变(Covariance)— 子类型可替代父类型,用于返回值
|
|
630
|
+
type Producer<out T> = () => T; // TypeScript 4.7+ 显式标注
|
|
631
|
+
|
|
632
|
+
// 逆变(Contravariance)— 父类型可替代子类型,用于参数
|
|
633
|
+
type Consumer<in T> = (value: T) => void;
|
|
634
|
+
|
|
635
|
+
// 不变(Invariance)— 既不协变也不逆变
|
|
636
|
+
type Processor<in out T> = (value: T) => T;
|
|
637
|
+
|
|
638
|
+
// 实际影响
|
|
639
|
+
interface Animal { name: string; }
|
|
640
|
+
interface Dog extends Animal { breed: string; }
|
|
641
|
+
|
|
642
|
+
type AnimalProducer = Producer<Animal>;
|
|
643
|
+
type DogProducer = Producer<Dog>;
|
|
644
|
+
|
|
645
|
+
// DogProducer 可赋值给 AnimalProducer(协变)
|
|
646
|
+
const dogFactory: DogProducer = () => ({ name: "Rex", breed: "Labrador" });
|
|
647
|
+
const animalFactory: AnimalProducer = dogFactory; // OK
|
|
648
|
+
|
|
649
|
+
type AnimalConsumer = Consumer<Animal>;
|
|
650
|
+
type DogConsumer = Consumer<Dog>;
|
|
651
|
+
|
|
652
|
+
// AnimalConsumer 可赋值给 DogConsumer(逆变)
|
|
653
|
+
const feedAnimal: AnimalConsumer = (animal) => console.log(animal.name);
|
|
654
|
+
const feedDog: DogConsumer = feedAnimal; // OK
|
|
655
|
+
```
|
|
656
|
+
|
|
657
|
+
## 装饰器与元数据
|
|
658
|
+
|
|
659
|
+
### TypeScript 5.x 标准装饰器
|
|
660
|
+
|
|
661
|
+
```typescript
|
|
662
|
+
// 类装饰器
|
|
663
|
+
function sealed(constructor: Function) {
|
|
664
|
+
Object.seal(constructor);
|
|
665
|
+
Object.seal(constructor.prototype);
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
// 方法装饰器(标准装饰器 API)
|
|
669
|
+
function log<This, Args extends any[], Return>(
|
|
670
|
+
target: (this: This, ...args: Args) => Return,
|
|
671
|
+
context: ClassMethodDecoratorContext<This, (this: This, ...args: Args) => Return>
|
|
672
|
+
) {
|
|
673
|
+
const methodName = String(context.name);
|
|
674
|
+
return function (this: This, ...args: Args): Return {
|
|
675
|
+
console.log(`Calling ${methodName} with`, args);
|
|
676
|
+
const result = target.call(this, ...args);
|
|
677
|
+
console.log(`${methodName} returned`, result);
|
|
678
|
+
return result;
|
|
679
|
+
};
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
class Calculator {
|
|
683
|
+
@log
|
|
684
|
+
add(a: number, b: number): number {
|
|
685
|
+
return a + b;
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
// 属性装饰器 — 注入默认值
|
|
690
|
+
function defaultValue<T>(value: T) {
|
|
691
|
+
return function <C>(
|
|
692
|
+
_target: undefined,
|
|
693
|
+
context: ClassFieldDecoratorContext<C, T>
|
|
694
|
+
) {
|
|
695
|
+
return function (this: C, initialValue: T): T {
|
|
696
|
+
return initialValue ?? value;
|
|
697
|
+
};
|
|
698
|
+
};
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
class Settings {
|
|
702
|
+
@defaultValue(3000)
|
|
703
|
+
accessor port: number = 0;
|
|
704
|
+
|
|
705
|
+
@defaultValue("localhost")
|
|
706
|
+
accessor host: string = "";
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
// 自动绑定装饰器
|
|
710
|
+
function bound<This, Args extends any[], Return>(
|
|
711
|
+
target: (this: This, ...args: Args) => Return,
|
|
712
|
+
context: ClassMethodDecoratorContext<This, (this: This, ...args: Args) => Return>
|
|
713
|
+
) {
|
|
714
|
+
const methodName = context.name;
|
|
715
|
+
context.addInitializer(function (this: This) {
|
|
716
|
+
(this as any)[methodName] = (this as any)[methodName].bind(this);
|
|
717
|
+
});
|
|
718
|
+
}
|
|
719
|
+
```
|
|
720
|
+
|
|
721
|
+
### 装饰器与依赖注入
|
|
722
|
+
|
|
723
|
+
```typescript
|
|
724
|
+
// 简易 DI 容器
|
|
725
|
+
const METADATA_KEY = Symbol("inject");
|
|
726
|
+
|
|
727
|
+
function Injectable() {
|
|
728
|
+
return function <T extends Constructor>(target: T) {
|
|
729
|
+
return target;
|
|
730
|
+
};
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
function Inject(token: string) {
|
|
734
|
+
return function (_target: undefined, context: ClassFieldDecoratorContext) {
|
|
735
|
+
// 在运行时解析依赖
|
|
736
|
+
};
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
@Injectable()
|
|
740
|
+
class UserService {
|
|
741
|
+
@Inject("UserRepository")
|
|
742
|
+
private repo!: UserRepository;
|
|
743
|
+
|
|
744
|
+
async getUser(id: string) {
|
|
745
|
+
return this.repo.findById(id);
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
```
|
|
749
|
+
|
|
750
|
+
## 模块系统
|
|
751
|
+
|
|
752
|
+
### 命名空间(Namespace)
|
|
753
|
+
|
|
754
|
+
```typescript
|
|
755
|
+
// 命名空间 — 仅在特殊场景使用(全局脚本、声明文件)
|
|
756
|
+
namespace Validation {
|
|
757
|
+
export interface Validator {
|
|
758
|
+
validate(value: string): boolean;
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
export class EmailValidator implements Validator {
|
|
762
|
+
validate(value: string): boolean {
|
|
763
|
+
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value);
|
|
764
|
+
}
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
export class PhoneValidator implements Validator {
|
|
768
|
+
validate(value: string): boolean {
|
|
769
|
+
return /^\+?[\d\s-]{10,}$/.test(value);
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
// 现代项目应优先使用 ES Module,而非命名空间
|
|
775
|
+
```
|
|
776
|
+
|
|
777
|
+
### 声明合并(Declaration Merging)
|
|
778
|
+
|
|
779
|
+
```typescript
|
|
780
|
+
// 接口合并
|
|
781
|
+
interface Box {
|
|
782
|
+
height: number;
|
|
783
|
+
width: number;
|
|
784
|
+
}
|
|
785
|
+
interface Box {
|
|
786
|
+
depth: number;
|
|
787
|
+
}
|
|
788
|
+
// 合并结果: { height: number; width: number; depth: number }
|
|
789
|
+
|
|
790
|
+
// 扩展第三方类型
|
|
791
|
+
declare module "express" {
|
|
792
|
+
interface Request {
|
|
793
|
+
user?: { id: string; role: string };
|
|
794
|
+
requestId: string;
|
|
795
|
+
}
|
|
796
|
+
}
|
|
797
|
+
|
|
798
|
+
// 扩展全局类型
|
|
799
|
+
declare global {
|
|
800
|
+
interface Window {
|
|
801
|
+
analytics: {
|
|
802
|
+
track(event: string, props?: Record<string, unknown>): void;
|
|
803
|
+
};
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
|
|
807
|
+
// 枚举合并
|
|
808
|
+
enum Color {
|
|
809
|
+
Red = 1,
|
|
810
|
+
Green = 2,
|
|
811
|
+
}
|
|
812
|
+
enum Color {
|
|
813
|
+
Blue = 3,
|
|
814
|
+
}
|
|
815
|
+
// Color.Red, Color.Green, Color.Blue 均可用
|
|
816
|
+
```
|
|
817
|
+
|
|
818
|
+
### 模块解析
|
|
819
|
+
|
|
820
|
+
```typescript
|
|
821
|
+
// 模块解析策略
|
|
822
|
+
// tsconfig.json 中 "moduleResolution": "bundler" | "node16" | "nodenext"
|
|
823
|
+
|
|
824
|
+
// 类型导入(Type-Only Imports, TypeScript 3.8+)
|
|
825
|
+
import type { User, UserRole } from "./types";
|
|
826
|
+
import { createUser, type CreateUserDTO } from "./user-service";
|
|
827
|
+
|
|
828
|
+
// 导入断言(Import Assertions)
|
|
829
|
+
import data from "./config.json" with { type: "json" };
|
|
830
|
+
|
|
831
|
+
// 动态导入
|
|
832
|
+
async function loadModule() {
|
|
833
|
+
const { default: Chart } = await import("chart.js");
|
|
834
|
+
return new Chart(/* ... */);
|
|
835
|
+
}
|
|
836
|
+
|
|
837
|
+
// 条件类型导出
|
|
838
|
+
export type { User } from "./user";
|
|
839
|
+
export { UserService } from "./user-service";
|
|
840
|
+
```
|
|
841
|
+
|
|
842
|
+
## 项目配置(tsconfig.json 完整指南)
|
|
843
|
+
|
|
844
|
+
### 编译选项核心配置
|
|
845
|
+
|
|
846
|
+
```jsonc
|
|
847
|
+
{
|
|
848
|
+
"compilerOptions": {
|
|
849
|
+
// ===== 语言与环境 =====
|
|
850
|
+
"target": "ES2022", // 编译目标
|
|
851
|
+
"lib": ["ES2022", "DOM", "DOM.Iterable"], // 可用库声明
|
|
852
|
+
"module": "ESNext", // 模块系统
|
|
853
|
+
"moduleResolution": "bundler", // 模块解析策略(推荐 bundler)
|
|
854
|
+
|
|
855
|
+
// ===== Strict 模式 =====
|
|
856
|
+
"strict": true, // 启用所有严格检查(推荐)
|
|
857
|
+
// strict 等价于以下全部开启:
|
|
858
|
+
// "strictNullChecks": true, // null/undefined 严格检查
|
|
859
|
+
// "strictFunctionTypes": true, // 函数参数逆变检查
|
|
860
|
+
// "strictBindCallApply": true, // bind/call/apply 严格类型
|
|
861
|
+
// "strictPropertyInitialization": true, // 类属性必须初始化
|
|
862
|
+
// "noImplicitAny": true, // 禁止隐式 any
|
|
863
|
+
// "noImplicitThis": true, // 禁止隐式 this
|
|
864
|
+
// "alwaysStrict": true, // 每个文件添加 "use strict"
|
|
865
|
+
// "useUnknownInCatchVariables": true, // catch(e) 中 e 为 unknown
|
|
866
|
+
|
|
867
|
+
// ===== 额外检查 =====
|
|
868
|
+
"noUncheckedIndexedAccess": true, // 索引签名返回 T | undefined
|
|
869
|
+
"noUnusedLocals": true, // 未使用的局部变量报错
|
|
870
|
+
"noUnusedParameters": true, // 未使用的参数报错
|
|
871
|
+
"exactOptionalPropertyTypes": true, // 可选属性不允许赋值 undefined
|
|
872
|
+
"noFallthroughCasesInSwitch": true, // switch 必须 break/return
|
|
873
|
+
|
|
874
|
+
// ===== 输出 =====
|
|
875
|
+
"outDir": "./dist",
|
|
876
|
+
"declaration": true, // 生成 .d.ts
|
|
877
|
+
"declarationMap": true, // 声明文件 source map
|
|
878
|
+
"sourceMap": true, // JS source map
|
|
879
|
+
"removeComments": false, // 保留注释
|
|
880
|
+
|
|
881
|
+
// ===== 互操作 =====
|
|
882
|
+
"esModuleInterop": true, // CommonJS/ESM 互操作
|
|
883
|
+
"allowSyntheticDefaultImports": true,
|
|
884
|
+
"forceConsistentCasingInFileNames": true,
|
|
885
|
+
"resolveJsonModule": true, // 允许导入 JSON
|
|
886
|
+
"isolatedModules": true, // 确保单文件可编译
|
|
887
|
+
|
|
888
|
+
// ===== 路径映射 =====
|
|
889
|
+
"baseUrl": ".",
|
|
890
|
+
"paths": {
|
|
891
|
+
"@/*": ["src/*"],
|
|
892
|
+
"@components/*": ["src/components/*"],
|
|
893
|
+
"@utils/*": ["src/utils/*"],
|
|
894
|
+
"@types/*": ["src/types/*"]
|
|
895
|
+
}
|
|
896
|
+
},
|
|
897
|
+
"include": ["src/**/*"],
|
|
898
|
+
"exclude": ["node_modules", "dist", "**/*.test.ts"]
|
|
899
|
+
}
|
|
900
|
+
```
|
|
901
|
+
|
|
902
|
+
### 项目引用(Project References)
|
|
903
|
+
|
|
904
|
+
```jsonc
|
|
905
|
+
// tsconfig.json (根目录)
|
|
906
|
+
{
|
|
907
|
+
"references": [
|
|
908
|
+
{ "path": "./packages/shared" },
|
|
909
|
+
{ "path": "./packages/client" },
|
|
910
|
+
{ "path": "./packages/server" }
|
|
911
|
+
],
|
|
912
|
+
"files": [] // 根配置不编译文件
|
|
913
|
+
}
|
|
914
|
+
|
|
915
|
+
// packages/shared/tsconfig.json
|
|
916
|
+
{
|
|
917
|
+
"compilerOptions": {
|
|
918
|
+
"composite": true, // 启用项目引用
|
|
919
|
+
"outDir": "./dist",
|
|
920
|
+
"declaration": true,
|
|
921
|
+
"declarationMap": true,
|
|
922
|
+
"rootDir": "./src"
|
|
923
|
+
},
|
|
924
|
+
"include": ["src/**/*"]
|
|
925
|
+
}
|
|
926
|
+
|
|
927
|
+
// packages/client/tsconfig.json
|
|
928
|
+
{
|
|
929
|
+
"compilerOptions": {
|
|
930
|
+
"composite": true,
|
|
931
|
+
"outDir": "./dist"
|
|
932
|
+
},
|
|
933
|
+
"references": [
|
|
934
|
+
{ "path": "../shared" } // 依赖 shared
|
|
935
|
+
]
|
|
936
|
+
}
|
|
937
|
+
```
|
|
938
|
+
|
|
939
|
+
### 不同场景的 tsconfig 模板
|
|
940
|
+
|
|
941
|
+
```jsonc
|
|
942
|
+
// React 项目 (Vite)
|
|
943
|
+
{
|
|
944
|
+
"compilerOptions": {
|
|
945
|
+
"target": "ES2022",
|
|
946
|
+
"lib": ["ES2022", "DOM", "DOM.Iterable"],
|
|
947
|
+
"module": "ESNext",
|
|
948
|
+
"moduleResolution": "bundler",
|
|
949
|
+
"jsx": "react-jsx",
|
|
950
|
+
"strict": true,
|
|
951
|
+
"noUncheckedIndexedAccess": true,
|
|
952
|
+
"noEmit": true, // Vite 处理编译
|
|
953
|
+
"isolatedModules": true,
|
|
954
|
+
"skipLibCheck": true
|
|
955
|
+
}
|
|
956
|
+
}
|
|
957
|
+
|
|
958
|
+
// Node.js 后端项目
|
|
959
|
+
{
|
|
960
|
+
"compilerOptions": {
|
|
961
|
+
"target": "ES2022",
|
|
962
|
+
"module": "NodeNext",
|
|
963
|
+
"moduleResolution": "NodeNext",
|
|
964
|
+
"strict": true,
|
|
965
|
+
"outDir": "./dist",
|
|
966
|
+
"declaration": true,
|
|
967
|
+
"sourceMap": true,
|
|
968
|
+
"esModuleInterop": true
|
|
969
|
+
}
|
|
970
|
+
}
|
|
971
|
+
|
|
972
|
+
// 库项目
|
|
973
|
+
{
|
|
974
|
+
"compilerOptions": {
|
|
975
|
+
"target": "ES2020",
|
|
976
|
+
"module": "ESNext",
|
|
977
|
+
"moduleResolution": "bundler",
|
|
978
|
+
"strict": true,
|
|
979
|
+
"declaration": true,
|
|
980
|
+
"declarationMap": true,
|
|
981
|
+
"outDir": "./dist",
|
|
982
|
+
"stripInternal": true // 移除 @internal 标记的导出
|
|
983
|
+
}
|
|
984
|
+
}
|
|
985
|
+
```
|
|
986
|
+
|
|
987
|
+
## 与框架集成
|
|
988
|
+
|
|
989
|
+
### React + TypeScript
|
|
990
|
+
|
|
991
|
+
```typescript
|
|
992
|
+
// 函数组件类型
|
|
993
|
+
interface ButtonProps {
|
|
994
|
+
variant: "primary" | "secondary" | "danger";
|
|
995
|
+
size?: "sm" | "md" | "lg";
|
|
996
|
+
disabled?: boolean;
|
|
997
|
+
onClick?: (event: React.MouseEvent<HTMLButtonElement>) => void;
|
|
998
|
+
children: React.ReactNode;
|
|
999
|
+
}
|
|
1000
|
+
|
|
1001
|
+
const Button: React.FC<ButtonProps> = ({ variant, size = "md", children, ...rest }) => {
|
|
1002
|
+
return <button className={`btn-${variant} btn-${size}`} {...rest}>{children}</button>;
|
|
1003
|
+
};
|
|
1004
|
+
|
|
1005
|
+
// 泛型组件
|
|
1006
|
+
interface ListProps<T> {
|
|
1007
|
+
items: T[];
|
|
1008
|
+
renderItem: (item: T, index: number) => React.ReactNode;
|
|
1009
|
+
keyExtractor: (item: T) => string;
|
|
1010
|
+
emptyState?: React.ReactNode;
|
|
1011
|
+
}
|
|
1012
|
+
|
|
1013
|
+
function List<T>({ items, renderItem, keyExtractor, emptyState }: ListProps<T>) {
|
|
1014
|
+
if (items.length === 0) return <>{emptyState}</>;
|
|
1015
|
+
return (
|
|
1016
|
+
<ul>
|
|
1017
|
+
{items.map((item, index) => (
|
|
1018
|
+
<li key={keyExtractor(item)}>{renderItem(item, index)}</li>
|
|
1019
|
+
))}
|
|
1020
|
+
</ul>
|
|
1021
|
+
);
|
|
1022
|
+
}
|
|
1023
|
+
|
|
1024
|
+
// Hook 类型
|
|
1025
|
+
function useLocalStorage<T>(key: string, initialValue: T) {
|
|
1026
|
+
const [stored, setStored] = React.useState<T>(() => {
|
|
1027
|
+
try {
|
|
1028
|
+
const item = window.localStorage.getItem(key);
|
|
1029
|
+
return item ? (JSON.parse(item) as T) : initialValue;
|
|
1030
|
+
} catch {
|
|
1031
|
+
return initialValue;
|
|
1032
|
+
}
|
|
1033
|
+
});
|
|
1034
|
+
|
|
1035
|
+
const setValue = React.useCallback(
|
|
1036
|
+
(value: T | ((prev: T) => T)) => {
|
|
1037
|
+
setStored((prev) => {
|
|
1038
|
+
const next = value instanceof Function ? value(prev) : value;
|
|
1039
|
+
window.localStorage.setItem(key, JSON.stringify(next));
|
|
1040
|
+
return next;
|
|
1041
|
+
});
|
|
1042
|
+
},
|
|
1043
|
+
[key]
|
|
1044
|
+
);
|
|
1045
|
+
|
|
1046
|
+
return [stored, setValue] as const;
|
|
1047
|
+
}
|
|
1048
|
+
|
|
1049
|
+
// Ref 类型
|
|
1050
|
+
const inputRef = React.useRef<HTMLInputElement>(null);
|
|
1051
|
+
const timerRef = React.useRef<ReturnType<typeof setInterval>>();
|
|
1052
|
+
|
|
1053
|
+
// Context 类型
|
|
1054
|
+
interface ThemeContextValue {
|
|
1055
|
+
theme: "light" | "dark";
|
|
1056
|
+
toggleTheme: () => void;
|
|
1057
|
+
}
|
|
1058
|
+
const ThemeContext = React.createContext<ThemeContextValue | null>(null);
|
|
1059
|
+
|
|
1060
|
+
function useTheme(): ThemeContextValue {
|
|
1061
|
+
const context = React.useContext(ThemeContext);
|
|
1062
|
+
if (!context) throw new Error("useTheme must be used within ThemeProvider");
|
|
1063
|
+
return context;
|
|
1064
|
+
}
|
|
1065
|
+
```
|
|
1066
|
+
|
|
1067
|
+
### Vue 3 + TypeScript
|
|
1068
|
+
|
|
1069
|
+
```typescript
|
|
1070
|
+
// Composition API with TypeScript
|
|
1071
|
+
import { defineComponent, ref, computed, PropType } from "vue";
|
|
1072
|
+
|
|
1073
|
+
interface Todo {
|
|
1074
|
+
id: number;
|
|
1075
|
+
text: string;
|
|
1076
|
+
done: boolean;
|
|
1077
|
+
}
|
|
1078
|
+
|
|
1079
|
+
export default defineComponent({
|
|
1080
|
+
props: {
|
|
1081
|
+
items: {
|
|
1082
|
+
type: Array as PropType<Todo[]>,
|
|
1083
|
+
required: true,
|
|
1084
|
+
},
|
|
1085
|
+
filter: {
|
|
1086
|
+
type: String as PropType<"all" | "active" | "done">,
|
|
1087
|
+
default: "all",
|
|
1088
|
+
},
|
|
1089
|
+
},
|
|
1090
|
+
emits: {
|
|
1091
|
+
toggle: (id: number) => typeof id === "number",
|
|
1092
|
+
delete: (id: number) => typeof id === "number",
|
|
1093
|
+
},
|
|
1094
|
+
setup(props, { emit }) {
|
|
1095
|
+
const searchQuery = ref("");
|
|
1096
|
+
|
|
1097
|
+
const filteredItems = computed(() => {
|
|
1098
|
+
let items = props.items;
|
|
1099
|
+
if (props.filter === "active") items = items.filter((t) => !t.done);
|
|
1100
|
+
if (props.filter === "done") items = items.filter((t) => t.done);
|
|
1101
|
+
if (searchQuery.value) {
|
|
1102
|
+
items = items.filter((t) =>
|
|
1103
|
+
t.text.toLowerCase().includes(searchQuery.value.toLowerCase())
|
|
1104
|
+
);
|
|
1105
|
+
}
|
|
1106
|
+
return items;
|
|
1107
|
+
});
|
|
1108
|
+
|
|
1109
|
+
return { searchQuery, filteredItems };
|
|
1110
|
+
},
|
|
1111
|
+
});
|
|
1112
|
+
|
|
1113
|
+
// <script setup> 写法(推荐)
|
|
1114
|
+
// <script setup lang="ts">
|
|
1115
|
+
// const props = defineProps<{ title: string; count?: number }>();
|
|
1116
|
+
// const emit = defineEmits<{ update: [value: string]; close: [] }>();
|
|
1117
|
+
// </script>
|
|
1118
|
+
```
|
|
1119
|
+
|
|
1120
|
+
### Express + TypeScript
|
|
1121
|
+
|
|
1122
|
+
```typescript
|
|
1123
|
+
import express, { Request, Response, NextFunction, RequestHandler } from "express";
|
|
1124
|
+
|
|
1125
|
+
// 类型安全的请求处理
|
|
1126
|
+
interface CreateUserBody {
|
|
1127
|
+
name: string;
|
|
1128
|
+
email: string;
|
|
1129
|
+
role: "admin" | "user";
|
|
1130
|
+
}
|
|
1131
|
+
|
|
1132
|
+
interface UserParams {
|
|
1133
|
+
id: string;
|
|
1134
|
+
}
|
|
1135
|
+
|
|
1136
|
+
interface UserQuery {
|
|
1137
|
+
include?: string;
|
|
1138
|
+
}
|
|
1139
|
+
|
|
1140
|
+
// 泛型请求处理器
|
|
1141
|
+
type TypedRequestHandler<
|
|
1142
|
+
Params = {},
|
|
1143
|
+
ResBody = unknown,
|
|
1144
|
+
ReqBody = unknown,
|
|
1145
|
+
Query = {}
|
|
1146
|
+
> = RequestHandler<Params, ResBody, ReqBody, Query>;
|
|
1147
|
+
|
|
1148
|
+
const createUser: TypedRequestHandler<{}, User, CreateUserBody> = async (req, res, next) => {
|
|
1149
|
+
try {
|
|
1150
|
+
const { name, email, role } = req.body; // 完全类型安全
|
|
1151
|
+
const user = await userService.create({ name, email, role });
|
|
1152
|
+
res.status(201).json(user);
|
|
1153
|
+
} catch (error) {
|
|
1154
|
+
next(error);
|
|
1155
|
+
}
|
|
1156
|
+
};
|
|
1157
|
+
|
|
1158
|
+
const getUser: TypedRequestHandler<UserParams, User, {}, UserQuery> = async (req, res, next) => {
|
|
1159
|
+
const { id } = req.params; // string 类型
|
|
1160
|
+
const { include } = req.query; // string | undefined
|
|
1161
|
+
// ...
|
|
1162
|
+
};
|
|
1163
|
+
|
|
1164
|
+
// 类型安全的中间件
|
|
1165
|
+
interface AuthenticatedRequest extends Request {
|
|
1166
|
+
user: { id: string; role: string };
|
|
1167
|
+
}
|
|
1168
|
+
|
|
1169
|
+
function requireAuth(req: Request, res: Response, next: NextFunction): void {
|
|
1170
|
+
const token = req.headers.authorization?.split(" ")[1];
|
|
1171
|
+
if (!token) {
|
|
1172
|
+
res.status(401).json({ error: "Unauthorized" });
|
|
1173
|
+
return;
|
|
1174
|
+
}
|
|
1175
|
+
(req as AuthenticatedRequest).user = verifyToken(token);
|
|
1176
|
+
next();
|
|
1177
|
+
}
|
|
1178
|
+
|
|
1179
|
+
// 错误处理中间件
|
|
1180
|
+
interface AppError extends Error {
|
|
1181
|
+
statusCode: number;
|
|
1182
|
+
code: string;
|
|
1183
|
+
}
|
|
1184
|
+
|
|
1185
|
+
const errorHandler = (err: AppError, req: Request, res: Response, _next: NextFunction) => {
|
|
1186
|
+
res.status(err.statusCode || 500).json({
|
|
1187
|
+
error: err.code || "INTERNAL_ERROR",
|
|
1188
|
+
message: err.message,
|
|
1189
|
+
});
|
|
1190
|
+
};
|
|
1191
|
+
```
|
|
1192
|
+
|
|
1193
|
+
### Prisma + TypeScript
|
|
1194
|
+
|
|
1195
|
+
```typescript
|
|
1196
|
+
import { PrismaClient, Prisma, User } from "@prisma/client";
|
|
1197
|
+
|
|
1198
|
+
const prisma = new PrismaClient();
|
|
1199
|
+
|
|
1200
|
+
// Prisma 自动生成的类型
|
|
1201
|
+
type UserWithPosts = Prisma.UserGetPayload<{
|
|
1202
|
+
include: { posts: true };
|
|
1203
|
+
}>;
|
|
1204
|
+
|
|
1205
|
+
type UserCreateInput = Prisma.UserCreateInput;
|
|
1206
|
+
|
|
1207
|
+
// 类型安全的查询构建
|
|
1208
|
+
async function findUsers(params: {
|
|
1209
|
+
where?: Prisma.UserWhereInput;
|
|
1210
|
+
orderBy?: Prisma.UserOrderByWithRelationInput;
|
|
1211
|
+
take?: number;
|
|
1212
|
+
skip?: number;
|
|
1213
|
+
}) {
|
|
1214
|
+
return prisma.user.findMany(params);
|
|
1215
|
+
}
|
|
1216
|
+
|
|
1217
|
+
// 带事务的类型安全操作
|
|
1218
|
+
async function transferCredits(fromId: string, toId: string, amount: number) {
|
|
1219
|
+
return prisma.$transaction(async (tx) => {
|
|
1220
|
+
const sender = await tx.user.update({
|
|
1221
|
+
where: { id: fromId },
|
|
1222
|
+
data: { credits: { decrement: amount } },
|
|
1223
|
+
});
|
|
1224
|
+
if (sender.credits < 0) {
|
|
1225
|
+
throw new Error("Insufficient credits");
|
|
1226
|
+
}
|
|
1227
|
+
const receiver = await tx.user.update({
|
|
1228
|
+
where: { id: toId },
|
|
1229
|
+
data: { credits: { increment: amount } },
|
|
1230
|
+
});
|
|
1231
|
+
return { sender, receiver };
|
|
1232
|
+
});
|
|
1233
|
+
}
|
|
1234
|
+
|
|
1235
|
+
// 动态选择字段
|
|
1236
|
+
function selectUserFields<T extends Prisma.UserSelect>(select: T) {
|
|
1237
|
+
return prisma.user.findMany({ select });
|
|
1238
|
+
}
|
|
1239
|
+
// 返回类型自动推导为选择的字段
|
|
1240
|
+
```
|
|
1241
|
+
|
|
1242
|
+
## 常见陷阱
|
|
1243
|
+
|
|
1244
|
+
### any 滥用
|
|
1245
|
+
|
|
1246
|
+
```typescript
|
|
1247
|
+
// 反模式: any 传染
|
|
1248
|
+
function parseData(raw: any): any {
|
|
1249
|
+
return JSON.parse(raw); // 所有类型信息丢失
|
|
1250
|
+
}
|
|
1251
|
+
|
|
1252
|
+
// 正确: 使用 unknown + 类型守卫
|
|
1253
|
+
function parseData(raw: string): unknown {
|
|
1254
|
+
return JSON.parse(raw);
|
|
1255
|
+
}
|
|
1256
|
+
|
|
1257
|
+
function isUser(data: unknown): data is User {
|
|
1258
|
+
return (
|
|
1259
|
+
typeof data === "object" &&
|
|
1260
|
+
data !== null &&
|
|
1261
|
+
"id" in data &&
|
|
1262
|
+
"name" in data &&
|
|
1263
|
+
typeof (data as User).id === "string"
|
|
1264
|
+
);
|
|
1265
|
+
}
|
|
1266
|
+
|
|
1267
|
+
// 需要灵活类型时的替代方案
|
|
1268
|
+
// 用 unknown 代替 any — 强制使用前检查
|
|
1269
|
+
// 用 Record<string, unknown> 代替 any — 至少约束为对象
|
|
1270
|
+
// 用泛型代替 any — 保留类型关联
|
|
1271
|
+
```
|
|
1272
|
+
|
|
1273
|
+
### 类型体操过度
|
|
1274
|
+
|
|
1275
|
+
```typescript
|
|
1276
|
+
// 反模式: 难以理解的深层类型嵌套
|
|
1277
|
+
type DeepMerge<A, B> = {
|
|
1278
|
+
[K in keyof A | keyof B]: K extends keyof B
|
|
1279
|
+
? K extends keyof A
|
|
1280
|
+
? A[K] extends object
|
|
1281
|
+
? B[K] extends object
|
|
1282
|
+
? DeepMerge<A[K], B[K]>
|
|
1283
|
+
: B[K]
|
|
1284
|
+
: B[K]
|
|
1285
|
+
: B[K]
|
|
1286
|
+
: K extends keyof A
|
|
1287
|
+
? A[K]
|
|
1288
|
+
: never;
|
|
1289
|
+
};
|
|
1290
|
+
|
|
1291
|
+
// 建议: 超过 3 层嵌套条件类型时,拆解或加注释
|
|
1292
|
+
// 如果团队无法理解类型定义,宁可放宽约束也不要写无人能维护的类型
|
|
1293
|
+
// 可以使用 // @ts-expect-error + 运行时校验作为折中方案
|
|
1294
|
+
```
|
|
1295
|
+
|
|
1296
|
+
### 枚举 vs 联合类型
|
|
1297
|
+
|
|
1298
|
+
```typescript
|
|
1299
|
+
// 反模式: 过度使用枚举
|
|
1300
|
+
enum Status {
|
|
1301
|
+
Active = "active",
|
|
1302
|
+
Inactive = "inactive",
|
|
1303
|
+
Pending = "pending",
|
|
1304
|
+
}
|
|
1305
|
+
// 枚举会生成运行时代码,tree-shaking 不友好
|
|
1306
|
+
|
|
1307
|
+
// 推荐: 字符串联合类型
|
|
1308
|
+
type Status = "active" | "inactive" | "pending";
|
|
1309
|
+
|
|
1310
|
+
// 如果需要枚举行为,使用 as const 对象
|
|
1311
|
+
const Status = {
|
|
1312
|
+
Active: "active",
|
|
1313
|
+
Inactive: "inactive",
|
|
1314
|
+
Pending: "pending",
|
|
1315
|
+
} as const;
|
|
1316
|
+
type Status = (typeof Status)[keyof typeof Status];
|
|
1317
|
+
// 零运行时开销,完全可 tree-shake
|
|
1318
|
+
|
|
1319
|
+
// 枚举的合理使用场景: 位标志
|
|
1320
|
+
enum Permission {
|
|
1321
|
+
Read = 1 << 0, // 1
|
|
1322
|
+
Write = 1 << 1, // 2
|
|
1323
|
+
Execute = 1 << 2, // 4
|
|
1324
|
+
Admin = Read | Write | Execute, // 7
|
|
1325
|
+
}
|
|
1326
|
+
```
|
|
1327
|
+
|
|
1328
|
+
### 类型窄化失败
|
|
1329
|
+
|
|
1330
|
+
```typescript
|
|
1331
|
+
// 陷阱 1: 回调中的类型窄化丢失
|
|
1332
|
+
function process(value: string | null) {
|
|
1333
|
+
if (value !== null) {
|
|
1334
|
+
// 此处 value 为 string
|
|
1335
|
+
setTimeout(() => {
|
|
1336
|
+
// 陷阱: TypeScript 无法保证回调执行时 value 仍非 null
|
|
1337
|
+
// 但实际上 const 变量在闭包中类型守卫仍然有效
|
|
1338
|
+
console.log(value.length); // OK — value 是 const
|
|
1339
|
+
}, 1000);
|
|
1340
|
+
}
|
|
1341
|
+
}
|
|
1342
|
+
|
|
1343
|
+
// 陷阱 2: 解构后的类型窄化
|
|
1344
|
+
type Response = { status: "ok"; data: string } | { status: "error"; message: string };
|
|
1345
|
+
|
|
1346
|
+
function handle(res: Response) {
|
|
1347
|
+
const { status } = res;
|
|
1348
|
+
if (status === "ok") {
|
|
1349
|
+
// 陷阱: res 已窄化,但 status 只是 string
|
|
1350
|
+
console.log(res.data); // OK — 通过 res 访问
|
|
1351
|
+
}
|
|
1352
|
+
}
|
|
1353
|
+
|
|
1354
|
+
// 陷阱 3: 属性赋值后类型窄化丢失
|
|
1355
|
+
interface Config {
|
|
1356
|
+
mode: "dev" | "prod";
|
|
1357
|
+
debug?: boolean;
|
|
1358
|
+
}
|
|
1359
|
+
|
|
1360
|
+
function setup(config: Config) {
|
|
1361
|
+
if (config.mode === "dev") {
|
|
1362
|
+
config.debug = true;
|
|
1363
|
+
// 赋值后 config.mode 的窄化可能丢失
|
|
1364
|
+
}
|
|
1365
|
+
}
|
|
1366
|
+
|
|
1367
|
+
// 解决: 用局部 const 变量保存窄化结果
|
|
1368
|
+
function handleSafe(res: Response) {
|
|
1369
|
+
if (res.status === "ok") {
|
|
1370
|
+
const { data } = res; // 在窄化的分支内解构
|
|
1371
|
+
console.log(data);
|
|
1372
|
+
}
|
|
1373
|
+
}
|
|
1374
|
+
```
|
|
1375
|
+
|
|
1376
|
+
### 其他常见陷阱
|
|
1377
|
+
|
|
1378
|
+
```typescript
|
|
1379
|
+
// 陷阱: 对象字面量的多余属性检查只在直接赋值时触发
|
|
1380
|
+
interface Options { timeout: number; }
|
|
1381
|
+
const opts = { timeout: 3000, retries: 5 };
|
|
1382
|
+
const config: Options = opts; // 不报错! 多余属性检查被绕过
|
|
1383
|
+
|
|
1384
|
+
// 陷阱: 可选链与 nullish coalescing 的优先级
|
|
1385
|
+
const value = obj?.nested?.value ?? "default"; // 正确
|
|
1386
|
+
const wrong = obj?.nested?.value || "default"; // 空字符串、0、false 都被替换!
|
|
1387
|
+
|
|
1388
|
+
// 陷阱: readonly 只是浅层
|
|
1389
|
+
interface Data {
|
|
1390
|
+
readonly items: string[];
|
|
1391
|
+
}
|
|
1392
|
+
const data: Data = { items: ["a"] };
|
|
1393
|
+
// data.items = []; // 报错: readonly
|
|
1394
|
+
data.items.push("b"); // 不报错! 数组内容可变
|
|
1395
|
+
// 解决: 使用 ReadonlyArray 或 readonly string[]
|
|
1396
|
+
```
|
|
1397
|
+
|
|
1398
|
+
## 性能优化
|
|
1399
|
+
|
|
1400
|
+
### 类型检查加速
|
|
1401
|
+
|
|
1402
|
+
```typescript
|
|
1403
|
+
// 1. 使用接口代替交叉类型(接口缓存更好)
|
|
1404
|
+
// 慢
|
|
1405
|
+
type SlowProps = BaseProps & StyleProps & EventProps;
|
|
1406
|
+
// 快
|
|
1407
|
+
interface FastProps extends BaseProps, StyleProps, EventProps {}
|
|
1408
|
+
|
|
1409
|
+
// 2. 避免深度条件类型递归
|
|
1410
|
+
// 设置递归深度限制
|
|
1411
|
+
type MaxDepth = 10;
|
|
1412
|
+
|
|
1413
|
+
// 3. 使用 type 而非 interface 做联合类型
|
|
1414
|
+
type Result = Success | Failure; // 联合类型只能用 type
|
|
1415
|
+
|
|
1416
|
+
// 4. 减少模板字面量类型的组合爆炸
|
|
1417
|
+
// 反模式: 排列组合导致类型数量爆炸
|
|
1418
|
+
type Variant = `${Color}-${Size}-${State}-${Theme}`;
|
|
1419
|
+
// 如果每个有 5 个值,结果有 625 个类型成员!
|
|
1420
|
+
|
|
1421
|
+
// 5. 善用 skipLibCheck 加速(不检查 node_modules 中的 .d.ts)
|
|
1422
|
+
// tsconfig.json: "skipLibCheck": true
|
|
1423
|
+
```
|
|
1424
|
+
|
|
1425
|
+
### 项目引用与增量编译
|
|
1426
|
+
|
|
1427
|
+
```bash
|
|
1428
|
+
# 增量编译
|
|
1429
|
+
# tsconfig.json 中添加:
|
|
1430
|
+
# "incremental": true
|
|
1431
|
+
# "tsBuildInfoFile": "./.tsbuildinfo"
|
|
1432
|
+
|
|
1433
|
+
# 项目引用构建
|
|
1434
|
+
tsc --build # 构建所有引用项目
|
|
1435
|
+
tsc --build --watch # 监听模式
|
|
1436
|
+
tsc --build --clean # 清理构建产物
|
|
1437
|
+
tsc --build --force # 强制重建
|
|
1438
|
+
|
|
1439
|
+
# 使用 --build 模式时:
|
|
1440
|
+
# - 只重新编译变更的项目
|
|
1441
|
+
# - 自动解析依赖顺序
|
|
1442
|
+
# - 生成 .tsbuildinfo 供增量使用
|
|
1443
|
+
```
|
|
1444
|
+
|
|
1445
|
+
### 大型项目优化策略
|
|
1446
|
+
|
|
1447
|
+
```typescript
|
|
1448
|
+
// 1. 拆分 tsconfig: 应用 / 测试 / 工具
|
|
1449
|
+
// tsconfig.app.json — 仅包含源码
|
|
1450
|
+
// tsconfig.test.json — 包含测试文件
|
|
1451
|
+
// tsconfig.json — 总配置(references)
|
|
1452
|
+
|
|
1453
|
+
// 2. 使用 paths 减少相对路径深度
|
|
1454
|
+
// 深层相对路径影响可读性,不影响编译性能
|
|
1455
|
+
// 但 paths 可减少因路径错误导致的类型解析失败
|
|
1456
|
+
|
|
1457
|
+
// 3. 类型导入隔离
|
|
1458
|
+
import type { HeavyType } from "./heavy-module";
|
|
1459
|
+
// type-only import 不会触发模块执行
|
|
1460
|
+
// 有助于 bundler 做 tree-shaking
|
|
1461
|
+
|
|
1462
|
+
// 4. 声明文件预编译
|
|
1463
|
+
// 对于不常变化的内部库,预编译 .d.ts 避免重复检查
|
|
1464
|
+
// 在 package.json 中设置 "types" 字段指向预编译的 .d.ts
|
|
1465
|
+
|
|
1466
|
+
// 5. 使用 @ts-check 渐进迁移
|
|
1467
|
+
// 在 JS 文件顶部添加 // @ts-check
|
|
1468
|
+
// 逐步享受类型检查,无需一次全量迁移
|
|
1469
|
+
```
|
|
1470
|
+
|
|
1471
|
+
## Agent Checklist
|
|
1472
|
+
|
|
1473
|
+
以下检查项供 AI Agent 在 TypeScript 项目中执行代码审查与生成时使用:
|
|
1474
|
+
|
|
1475
|
+
### 类型安全
|
|
1476
|
+
- [ ] 项目是否启用 `strict: true`
|
|
1477
|
+
- [ ] 是否存在 `any` 类型(排查并替换为 `unknown` 或具体类型)
|
|
1478
|
+
- [ ] 是否启用 `noUncheckedIndexedAccess`
|
|
1479
|
+
- [ ] catch 块中 error 是否为 `unknown` 类型并在使用前校验
|
|
1480
|
+
- [ ] 可选属性是否正确处理(不依赖 falsy 判断)
|
|
1481
|
+
|
|
1482
|
+
### 泛型与工具类型
|
|
1483
|
+
- [ ] 泛型是否有适当约束(避免无约束 `<T>`)
|
|
1484
|
+
- [ ] 是否优先使用内置工具类型而非手写等价物
|
|
1485
|
+
- [ ] 条件类型嵌套是否超过 3 层(超过需拆解或加注释)
|
|
1486
|
+
- [ ] 映射类型是否使用了 `as` 子句做键过滤/重映射
|
|
1487
|
+
|
|
1488
|
+
### 模式与实践
|
|
1489
|
+
- [ ] 联合类型是否使用了可辨识字段(discriminated union)
|
|
1490
|
+
- [ ] 类型守卫函数是否返回 `x is Type` 而非 `boolean`
|
|
1491
|
+
- [ ] 是否使用 `satisfies` 操作符避免类型拓宽
|
|
1492
|
+
- [ ] 是否使用 `as const` 代替手动字面量类型枚举
|
|
1493
|
+
- [ ] 枚举是否可以替换为联合类型或 `as const` 对象
|
|
1494
|
+
|
|
1495
|
+
### 项目配置
|
|
1496
|
+
- [ ] `moduleResolution` 是否与实际运行环境匹配
|
|
1497
|
+
- [ ] 是否配置了路径映射(`paths`)减少相对路径嵌套
|
|
1498
|
+
- [ ] 是否启用 `incremental` 编译加速构建
|
|
1499
|
+
- [ ] 大型 monorepo 是否使用了项目引用(`composite` + `references`)
|
|
1500
|
+
- [ ] 是否启用 `skipLibCheck` 加速类型检查
|
|
1501
|
+
|
|
1502
|
+
### 框架集成
|
|
1503
|
+
- [ ] React 组件 props 是否定义为独立接口
|
|
1504
|
+
- [ ] React Hook 返回值是否使用 `as const` 保留元组类型
|
|
1505
|
+
- [ ] Express 中间件是否正确扩展 Request 类型
|
|
1506
|
+
- [ ] Prisma 查询是否利用自动生成的类型而非手动定义
|
|
1507
|
+
|
|
1508
|
+
### 性能
|
|
1509
|
+
- [ ] 是否使用 `import type` 隔离类型导入
|
|
1510
|
+
- [ ] 模板字面量类型是否存在组合爆炸风险
|
|
1511
|
+
- [ ] 是否优先使用 `interface extends` 代替交叉类型
|
|
1512
|
+
- [ ] 递归类型是否设置了深度限制
|
|
1513
|
+
- [ ] `.tsbuildinfo` 文件是否被 `.gitignore` 忽略
|