20 ื›ืœื™ ื ื™ืชื•ื— ืกื˜ื˜ื™ ืฉื›ืœ ืฆื•ื•ืช TypeScript ืฆืจื™ืš

ื›ืœื™ ื ื™ืชื•ื— ืกื˜ื˜ื™ ืฉืœ TypeScript: ื”ืžื“ืจื™ืš ื”ืžืœื ืœืฆื•ื•ืชื™ ืคื™ืชื•ื—

ืžืขืจื›ืช ื”ื˜ื™ืคื•ืกื™ื ืฉืœ TypeScript ืœื•ื›ื“ืช ืžื—ืœืงื” ืžืฉืžืขื•ืชื™ืช ืฉืœ ื‘ืื’ื™ื ืœืคื ื™ ื”ืจืฆืช ืงื•ื“, ืื™ ื”ืชืืžื•ืช ื‘ื˜ื™ืคื•ืกื™ื, ืžืืคื™ื™ื ื™ื ื—ืกืจื™ื, ื—ืชื™ืžื•ืช ืคื•ื ืงืฆื™ื” ืฉื’ื•ื™ื•ืช. ืžื” ืฉื”ื™ื ืœื ื™ื›ื•ืœื” ืœืชืคื•ืก ื”ื•ื ื›ืœ ื”ืฉืืจ: ืคื’ื™ืขื•ื™ื•ืช ืื‘ื˜ื—ื” ืฉืชืœื•ื™ื•ืช ื‘ืื•ืคืŸ ืฉื‘ื• ื ืชื•ื ื™ื ื–ื•ืจืžื™ื ื“ืจืš ื”ืืคืœื™ืงืฆื™ื”, ื”ืคืจื•ืช ืืจื›ื™ื˜ืงื˜ื•ื ื™ื•ืช ืฉืžืฆื˜ื‘ืจื•ืช ืœืื•ืจืš ื–ืžืŸ ื›ื›ืœ ืฉื’ื‘ื•ืœื•ืช ื”ืฆื•ื•ืช ืžื™ื˜ืฉื˜ืฉื™ื, ื™ืฆื•ื ืžืช ืฉื ืฉืืจ ื‘ื‘ืกื™ืก ื”ืงื•ื“ ื–ืžืŸ ืจื‘ ืœืื—ืจ ืฉื”ืงื•ืจืื™ื ืœื”ื ื”ื•ืกืจื•, ื•ืฉื’ื™ืื•ืช ืชื›ื ื•ืช ืืกื™ื ื›ืจื•ื ื™ื•ืช ืฉืžืชืงืžืคืœื•ืช ื›ื”ืœื›ื” ืืš ื ื›ืฉืœื•ืช ื‘ืชื ืื™ ื–ืžืŸ ืจื™ืฆื” ืกืคืฆื™ืคื™ื™ื. ื›ืœื™ ื ื™ืชื•ื— ืกื˜ื˜ื™ื™ื ืžืžืœืื™ื ืืช ื”ืคืขืจื™ื ื”ืœืœื•, ื•ื‘ื—ื™ืจืช ื”ืฉื™ืœื•ื‘ ื”ื ื›ื•ืŸ ืชืœื•ื™ื” ื‘ืžื” ืฉืืชื ื‘ืืžืช ืžื ืกื™ื ืœืžืฆื•ื.

ืžื“ืจื™ืš ื–ื” ืžื›ืกื” ืืช ื”ื›ืœื™ื ื”ื—ืฉื•ื‘ื™ื ืœืฆื•ื•ืชื™ TypeScript ื‘ืฉื ืช 2026: ืฉื›ื‘ืช ื”-linting (ESLint ืขื typescript-eslint, Biome, OxcLint), ืฉื›ื‘ืช ื”ืื‘ื˜ื—ื” (Semgrep, Snyk Code, SonarQube), ืฉื›ื‘ืช ื”ืื“ืจื™ื›ืœื•ืช (Dependency-Cruiser, Deptrac, Nx), ืฉื›ื‘ืช ื”-dead code (Knip) ื•ืฉื›ื‘ืช ื”ื ื™ืชื•ื— ื”ืขืžื•ืง (ts-morph, ืžื”ื“ืจ TypeScript ืขืฆืžื•). ืขื‘ื•ืจ ื›ืœ ืื—ื“ ืžื”ื, ื”ื“ื’ืฉ ื”ื•ื ืขืœ ืžื” ืฉื”ื•ื ืขื•ืฉื” ื‘ืคื•ืขืœ, ื›ื™ืฆื“ ืœื”ื’ื“ื™ืจ ืื•ืชื•, ื•ืžืชื™ ื”ื•ื ืื™ื ื• ื”ื›ืœื™ ื”ืžืชืื™ื ืœืžืฉื™ืžื”.

ื ื‘ื ื” ืขื‘ื•ืจ ื‘ืกื™ืกื™ ืงื•ื“ ืฉืืฃ ืื—ื“ ืœื ืžื‘ื™ืŸ

SMART TS XL ืžืฆื™ื™ืจ ื‘ืื•ืคืŸ ืื•ื˜ื•ืžื˜ื™ ืฉื™ื ื•ื™ื™ื ืฉื‘ื™ืจื™ื ื‘ื›ืœ ื‘ืกื™ืก ื”ืงื•ื“ ืฉืœืš.

ืœืžื“ ืขื•ื“

ืชื•ื›ืŸ ื”ืขื ื™ื™ื ื™ื

ื›ืœื™ ื ื™ืชื•ื— ืกื˜ื˜ื™ ืฉืœ TypeScript: ื˜ื‘ืœืช ื”ืฉื•ื•ืื”

ืœืคื ื™ ืฉื ืฆืœื•ืœ ืœื›ืœื™ื ื‘ื•ื“ื“ื™ื, ื”ื˜ื‘ืœื” ืฉืœื”ืœืŸ ืžืžืคื” ื›ืœ ื›ืœื™ ืœืชืคืงื•ื“ื• ื”ืขื™ืงืจื™, ื”ืชืืžืชื• ืœ-CI ื•ืœืžืงืจื” ื”ืฉื™ืžื•ืฉ ื”ืื™ื“ื™ืืœื™ ืฉืœื•. ืื™ืŸ ื›ืœื™ ื‘ื•ื“ื“ ื”ืžื›ืกื” ืืช ื›ืœ ื”ืžืžื“ื™ื, ื ื™ืชื•ื— ืื™ื›ื•ืช ื™ืขื™ืœ ืฉืœ TypeScript ื“ื•ืจืฉ ืฉื›ื‘ื•ืช ืฉืœ ื›ืžื”.

ื›ืœื™ืคื•ื ืงืฆื™ื” ืจืืฉื™ืชืžืชืื™ื ืœ-CIืขืœื•ืชื”ื›ื™ ื˜ื•ื‘
ESLint + typescript-eslintืœื™ื ื˜ื™ื™ืฉืŸ, ืกื’ื ื•ืŸ, ื›ืœืœื™ ืžื•ื“ืขื•ืช ืœืกื•ื’ื™ืฉื—ื•ืคืฉื™ืžื•ืกื›ืžื•ืช ื›ืœืœ-ืฆื•ื•ืชื™ื•ืช, ื‘ื˜ื™ื—ื•ืช ืžืกื•ื’ ืืกื™ื ื›ืจื•ื ื™
ื‘ื™ื•ืžื”ืœื™ื ื˜ื™ื ื’ + ืขื™ืฆื•ื‘ื™ืฉื—ื•ืคืฉื™ESLint + ืชื—ืœื™ืฃ ื™ืคื” ื™ื•ืชืจ, ืžื”ื™ืจื•ืช
ืื•ืงืกืœื™ื ื˜ืœื™ื ื˜ื™ (ืชื•ืื ืœ-ESLint)ื™ืฉื—ื•ืคืฉื™ืžื•ื ื•ืจืคื•ืก ื–ืงื•ืง ืœื–ืžื ื™ ืกื™ื‘ื™ื ืžื”ื™ืจื™ื
ืžื”ื“ืจ TypeScript (tsc)ืกื•ื’ ื‘ื“ื™ืงื”ื™ืฉื—ื•ืคืฉื™ืฉื’ื™ืื•ืช ื”ืงืœื“ื”, ืื›ื™ืคื” ืงืคื“ื ื™ืช ืฉืœ ืžืฆื‘
SemgrepSAST, ืชื‘ื ื™ื•ืช ืžื•ืชืืžื•ืช ืื™ืฉื™ืชื™ืฉื—ื™ื ื + ื‘ืชืฉืœื•ืืกืจื™ืงืช ืื‘ื˜ื—ื”, ื›ืœืœื™ ืืจื’ื•ืŸ ืžื•ืชืืžื™ื ืื™ืฉื™ืช
ืงื•ื“ ืกื ื™ืงSAST, ืื‘ื˜ื—ืช ืชืœื•ืชื™ืฉื—ื™ื ื + ื‘ืชืฉืœื•ืืฆื•ื•ืชื™ ืื‘ื˜ื—ื” ื‘ืžืงื•ื ื”ืจืืฉื•ืŸ, ืฉื™ืœื•ื‘ IDE
ืกื•ื ืืจ ืงื™ื•ื‘ / ืกื•ื ืืจ ืงืœืื•ื“ืฉืขืจื™ ืื™ื›ื•ืช, ืžืขืงื‘ ืื—ืจ ืžื’ืžื•ืชื™ืฉื—ื™ื ื + ื‘ืชืฉืœื•ืืœื•ื—ื•ืช ืžื—ื•ื•ื ื™ื ืœืื™ื›ื•ืช ืืจื’ื•ื ื™ืช
ืกื•ื ืืจืœื™ื ื˜ืžืฉื•ื‘ ืื™ื›ื•ืชื™ ื‘ืจืžืช IDEIDE ื‘ืœื‘ื“ื—ื•ืคืฉื™ืจืžื–ื™ื ืžื•ื‘ื ื™ื ืœืื‘ื˜ื—ื” ื•ืื™ื›ื•ืช
ืกืคื™ื ืช ืชืœื•ื™ื•ืชืื›ื™ืคืช ื’ืจืฃ ืชืœื•ืชื™ืฉื—ื•ืคืฉื™ืื™ืžื•ืช ื›ืœืœื™ื ืื“ืจื™ื›ืœื™ื™ื
ื“ืคื˜ืจืงืื›ื™ืคืช ื’ื‘ื•ืœื•ืช ืฉื›ื‘ื•ืชื™ืฉื—ื•ืคืฉื™ืืจื›ื™ื˜ืงื˜ื•ืจื” ื ืงื™ื™ื”, ื’ื‘ื•ืœื•ืช DDD
Nxื ื™ื”ื•ืœ ืชืœื•ืช ืžื•ื ื•ืจืคื•ื™ืฉื—ื™ื ื + ื‘ืชืฉืœื•ืื’ื‘ื•ืœื•ืช ืžื•ื“ื•ืœ Monorepo
ื’ื–ื™ืจื”ืงื•ื“ ืžืช ื•ื™ืฆื•ื ืฉืื™ื ื• ื‘ืฉื™ืžื•ืฉื™ืฉื—ื•ืคืฉื™ืฆืžืฆื•ื ืงื•ื“ ืฉืื™ื ื• ื‘ืฉื™ืžื•ืฉ ื‘ืงื ื” ืžื™ื“ื” ื’ื“ื•ืœ
ts-ืžื•ืจืฃื ื™ืชื•ื— TS ืคืจื•ื’ืจืžื˜ื™ ASTืกืœืงื˜ื™ื‘ื™ื—ื•ืคืฉื™ื ื™ืชื•ื— ืžื•ืชืื ืื™ืฉื™ืช, ืงื•ื“ืžื•ื“ื™ื, ื›ืœื™ ืขื‘ื•ื“ื”

ืฉื›ื‘ื” 1: ืกื™ื‘ื™ื ื•ืกื’ื ื•ืŸ

ESLint ืขื typescript-eslint

ESLint ื ืฉืืจ ื”ื‘ืกื™ืก ืฉืœ ื™ืฆื™ืจืช ืคืชืจื•ื ื•ืช ืœื™ืฆื™ืจืช ืคืชืจื•ื ื•ืช ืœ-TypeScript. ืขื ื”- typescript-eslint ื‘ื—ื‘ื™ืœื”, ื”ื™ื ืžืงื‘ืœืช ื’ื™ืฉื” ืœืžื™ื“ืข ื”ืกื•ื’ ืฉืœ TypeScript ื•ื™ื›ื•ืœื” ืœืื›ื•ืฃ ื›ืœืœื™ื ื”ื“ื•ืจืฉื™ื ื”ืงืฉืจ ืกื•ื’ื™ื, ื›ืืฉืจ ื”ื—ืฉื•ื‘ื™ื ืฉื‘ื”ื ื”ื ื”ื›ืœืœื™ื ื”ืกืคืฆื™ืคื™ื™ื ืœืืกื™ื ื›ืจื•ื ื™ื™ื ืฉืชื•ืคืกื™ื ื˜ืขื•ื™ื•ืช ื ืคื•ืฆื•ืช ืฉืœ Promise.

ืœื—ื‘ื•ื˜

npm install --save-dev typescript-eslint

JavaScript

// eslint.config.js
import tseslint from "typescript-eslint";

export default tseslint.config(
  ...tseslint.configs.strictTypeChecked,
  {
    languageOptions: {
      parserOptions: {
        project: true,
        tsconfigRootDir: import.meta.dirname,
      },
    },
    rules: {
      // Async safety rules -- highest value TypeScript-specific rules
      "@typescript-eslint/no-floating-promises": "error",
      "@typescript-eslint/await-thenable": "error",
      "@typescript-eslint/no-misused-promises": "error",
      "@typescript-eslint/require-await": "warn",
      // Type safety
      "@typescript-eslint/no-explicit-any": "warn",
      "@typescript-eslint/no-unsafe-assignment": "error",
      "@typescript-eslint/no-unsafe-return": "error",
    },
  }
);

ืืจื‘ืขืช ื”ื›ืœืœื™ื ื”ืืกื™ื ื›ืจื•ื ื™ื™ื ืœืขื™ืœ ื”ื ื”ืชื•ืกืคืช ื‘ืขืœืช ื”ืขืจืš ื”ื’ื‘ื•ื” ื‘ื™ื•ืชืจ ืฉ-typescript-eslint ืžืกืคืง ืขืœ ืคื ื™ ESLint ืจื’ื™ืœ. ื”ื ืชื•ืคืกื™ื: ื”ื‘ื˜ื—ื•ืช ืœื ืžื˜ื•ืคืœื•ืช (ื”ื‘ื˜ื—ื•ืช ืฆืคื•ืช), await ืžื•ื—ืœ ืขืœ ืขืจื›ื™ื ืฉืื™ื ื Promise, Promises ื”ืžื•ืขื‘ืจื™ื ืœืงืจื™ืื•ืช ื—ื•ื–ืจื•ืช ื”ืžืฆืคื•ืช ืœืคื•ื ืงืฆื™ื•ืช ืกื™ื ื›ืจื•ื ื™ื•ืช, ื•ืคื•ื ืงืฆื™ื•ืช ืืกื™ื ื›ืจื•ื ื™ื•ืช ืฉืœืขื•ืœื ืœื ืžืฉืชืžืฉื•ืช awaitืืœื• ื”ืŸ ืชื‘ื ื™ื•ืช ืฉืžืชืงืžืคืœื•ืช ื‘ืฆื•ืจื” ื ืงื™ื™ื” ืืš ืžื™ื™ืฆืจื•ืช ื›ืฉืœื™ื ื‘ื–ืžืŸ ืจื™ืฆื” ื‘ืชื ืื™ื ืกืคืฆื™ืคื™ื™ื.

ืžื” ืฉ-ESLint ืœื ื™ื›ื•ืœ ืœืขืฉื•ืช : ื ื™ืชื•ื— ื–ืจื™ืžืช ื ืชื•ื ื™ื ื‘ื™ืŸ ืงื‘ืฆื™ื, ืื›ื™ืคืช ื’ื‘ื•ืœื•ืช ืื“ืจื™ื›ืœื™ื™ื, ืžืขืงื‘ ืื—ืจ ื›ืชืžื™ ืื‘ื˜ื—ื” ืื• ื–ื™ื”ื•ื™ ื™ื™ืฆื•ื ืžืช. ืขื‘ื•ืจ ืืœื”, ื ื“ืจืฉื•ืช ื”ืฉื›ื‘ื•ืช ื”ืื—ืจื•ืช ืฉืœื”ืœืŸ.

ื‘ื™ื•ืžื”: ESLint ื”ืžื•ื“ืจื ื™ + ืชื—ืœื™ืฃ ื™ืคื” ื™ื•ืชืจ

Biome ืžื—ืœื™ืฃ ื’ื ืืช ESLint ื•ื’ื ืืช Prettier ื‘ืงื•ื‘ืฅ ื‘ื™ื ืืจื™ ื™ื—ื™ื“ ืžื‘ื•ืกืก Rust ืฉืคื•ืขืœ ืžื”ืจ ื™ื•ืชืจ ืคื™ 25-35. ื”ื•ื ืชื•ืžืš ื‘-JavaScript, TypeScript, JSX ื•-JSON. ืขื‘ื•ืจ ืคืจื•ื™ืงื˜ื™ื ื—ื“ืฉื™ื ืื• ืฆื•ื•ืชื™ื ื”ืžืชื•ืกื›ืœื™ื ืžืžื•ืจื›ื‘ื•ืช ื”ืชื•ืกืคื™ื ืฉืœ ESLint ื•ื‘ื™ืฆื•ืขื™ื ืื™ื˜ื™ื™ื ื‘ื‘ืกื™ืกื™ ืงื•ื“ ื’ื“ื•ืœื™ื, Biome ื”ื™ื ื”ืืœื˜ืจื ื˜ื™ื‘ื” ื”ืžื•ื“ืจื ื™ืช ื”ื—ื–ืงื” ื‘ื™ื•ืชืจ.

ืœื—ื‘ื•ื˜

npm install --save-dev --save-exact @biomejs/biome
npx @biomejs/biome init

ืœื—ื‘ื•ื˜

# Check and format in one pass
npx @biomejs/biome check --write src/

# CI mode -- no modifications, exit non-zero on any finding
npx @biomejs/biome ci src/

ืžืขืจื›ืช ื”ืชื•ืกืคื™ื ืฉืœ Biome ืงื˜ื ื” ื™ื•ืชืจ ืžื–ื• ืฉืœ ESLint, ื“ื‘ืจ ืฉื—ืฉื•ื‘ ืœืฆื•ื•ืชื™ื ืขื ื›ืœืœื™ื ืžื•ืชืืžื™ื ืื™ืฉื™ืช ื ืจื—ื‘ื™ื ืื• ืชื•ืกืคื™ื ืกืคืฆื™ืคื™ื™ื ืœืžืกื’ืจืช. ืขื‘ื•ืจ ืฆื•ื•ืชื™ื ื”ืžืฉืชืžืฉื™ื ืจืง ื‘ื›ืœืœื™ ื”ืœื™ื‘ื” ืฉืœ ESLint ื•ื‘ืขื™ืฆื•ื‘ Prettier, Biome ืžืกืคืง ื›ื™ืกื•ื™ ืฉื•ื•ื” ืขืจืš ื‘ื—ืœืงื™ืง ืžื–ืžืŸ ื”ื‘ื™ืฆื•ืข.

OxcLint: ืชืื™ืžื•ืช ESLint ืขื ืžื”ื™ืจื•ืช ืจืืฉื•ื ื”

OxcLint (ื—ืœืง ืžืคืจื•ื™ืงื˜ Oxc) ืžืจื™ืฅ ื›ืœืœื™ื ืชื•ืืžื™ ESLint ื‘ืžื”ื™ืจื•ืช ื‘ื™ืฆื•ืข ืžื”ื™ืจื” ืคื™ 50-100. ื”ื•ื ืื™ื ื• ืžื—ืœื™ืฃ ืืช ื”ืžืขืจื›ืช ื”ืืงื•ืœื•ื’ื™ืช ื”ืžืœืื” ืฉืœ ESLint, ืืš ืžืฉืžืฉ ื›ืืคืฉืจื•ืช ื”ืžื”ื™ืจื” ื‘ื™ื•ืชืจ ืขื‘ื•ืจ ืฆื™ื ื•ืจื•ืช CI ืฉื‘ื”ื ื–ืžืŸ ื”-lint ื”ื•ื ืฆื•ื•ืืจ ื‘ืงื‘ื•ืง.

ืœื—ื‘ื•ื˜

npm install --save-dev oxlint
npx oxlint src/

OxcLint ื”ื™ื ื”ื‘ื—ื™ืจื” ื”ื ื›ื•ื ื” ืขื‘ื•ืจ ืžื•ื ื•ืจืคื• ื’ื“ื•ืœื™ื ืฉื‘ื”ื ESLint ืกื˜ื ื“ืจื˜ื™ ืœื•ืงื— ื“ืงื•ืช ืกืคื•ืจื•ืช ื•ื”ืฉื”ื™ื™ืช ืœื•ืœืืช ื”ืžืฉื•ื‘ ืžืคื—ื™ืชื” ืืช ืื™ื›ื•ืช ื‘ืงืฉืช ื”-pull. ื”ื•ื ืขื•ื‘ื“ ื‘ืฆื•ืจื” ื”ื˜ื•ื‘ื” ื‘ื™ื•ืชืจ ืœืฆื“ ESLint ื‘ืžืงื•ื ืœื”ื—ืœื™ืฃ ืื•ืชื•, ื”ืคืขืœ ืืช OxcLint ืขื‘ื•ืจ ื ืชื™ื‘ ื”ืžืฉื•ื‘ ื”ืžื”ื™ืจ ื•ืืช ESLint ืขื‘ื•ืจ ื›ื™ืกื•ื™ ืžืœื ืฉืœ ื”ื›ืœืœื™ื ื‘ืฉืขืจ ื˜ืจื•ื-ื”ืžื™ื–ื•ื’.

ืฉื›ื‘ื” 2: ื‘ื“ื™ืงืช ืกื•ื’ื™ื, ืžื”ื“ืจ TypeScript

ืžื”ื“ืจ TypeScript (tsc) ืื™ื ื• ืจืง ื›ืœื™ ื‘ื ื™ื™ื”, ื–ื”ื• ืžื ื•ืข ื”ื ื™ืชื•ื— ื”ืกื˜ื˜ื™ ื”ืขื™ืงืจื™ ืœืชืงื™ื ื•ืช ื‘ืจืžืช ื”ืกื•ื’. ื”ืคืขืœืช ืžืฆื‘ strict ืžืคืขื™ืœื” ืืช ื”ื”ื’ื“ืจื•ืช ืฉืชื•ืคืกื•ืช ืืช ืจื•ื‘ ื”ื‘ืื’ื™ื ื‘ืขื•ืœื ื”ืืžื™ืชื™:

ื’'ืกื•ืŸ

{
  "compilerOptions": {
    "strict": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true,
    "exactOptionalPropertyTypes": true,
    "useUnknownInCatchVariables": true
  }
}

ืœื—ื‘ื•ื˜

# Type-check only, no emit -- ideal for CI
npx tsc --noEmit

noUnusedLocals ื• noUnusedParameters ื‘ืจืžืช ื”ืžื”ื“ืจ, ืœืชืคื•ืก ืžืฉืชื ื™ื ื•ืคืจืžื˜ืจื™ ืคื•ื ืงืฆื™ื” ืฉืื™ื ื ื‘ืฉื™ืžื•ืฉ. useUnknownInCatchVariables (ืกื•ื’ื™ TypeScript 4.4+) ื ืชืคืกื• ื—ืจื™ื’ื™ื ื› unknown ื•ืœื any, ื›ื•ืคื” ืฆืžืฆื•ื ืกื•ื’ื™ื ืžืคื•ืจืฉ ืœืคื ื™ ื”ืฉื™ืžื•ืฉ.

ื ื™ืชื•ื— ื–ืจื™ืžืช ื‘ืงืจื” ืฉืœ TypeScript ื”ื™ื ื™ื›ื•ืœืช ืžื•ื‘ื ื™ืช ืฉื”ืžื”ื“ืจ ืžืกืคืง ืœืฆืžืฆื•ื ืกื•ื’ื™ื ื‘ืชื•ืš ืขื ืคื™ื ืžื•ืชื ื™ื. ื–ื” ืœื ื›ืœื™ ื ืคืจื“, ื”ืžืืคืฉืจ strict ืžืฆื‘ ืžื‘ื˜ื™ื— ืฉื”ื•ื ืžื™ื•ืฉื ื‘ืงืคื“ื ื•ืช ืžืœืื”. ื ื™ืชื•ื— ื–ืจื™ืžืช ื”ื‘ืงืจื” ืฉืœ ื”ืžื”ื“ืจ ืžื‘ื™ืŸ ืกื•ื’ื™ื ืžื’ื ื™ื, typeof ืฆ'ืงื™ื, instanceof, ื•ื“ืคื•ืกื™ ืื™ื’ื•ื“ื™ื ืžืงืฆื•ืขื™ื™ื ืžืคืœื™ื.

ืžื’ื‘ืœืช tsc : ืžื”ื“ืจ TypeScript ืื™ื ื• ืžื•ืฆื ืคื’ื™ืขื•ื™ื•ืช ืื‘ื˜ื—ื”, ื”ืคืจื•ืช ื’ื‘ื•ืœื•ืช ืืจื›ื™ื˜ืงื˜ื•ื ื™ื•ืช ืื• ื™ื™ืฆื•ื ืžืช. ื”ื•ื ืžื•ืฆื ืฉื’ื™ืื•ืช ื”ืงืœื“ื”, ื•ื”ื•ื ืขื•ืฉื” ื–ืืช ื‘ืื•ืคืŸ ื—ื“ ืžืฉืžืขื™.

ืฉื›ื‘ื” 3: ืื‘ื˜ื—ื”, SAST ืขื‘ื•ืจ TypeScript

Semgrep: ืกืจื™ืงืช ืื‘ื˜ื—ื” ืžื‘ื•ืกืกืช ืชื‘ื ื™ื•ืช

Semgrep ืžื•ืฆืืช ืคื’ื™ืขื•ื™ื•ืช ืื‘ื˜ื—ื” ื‘ืืžืฆืขื•ืช ื”ืชืืžืช ืชื‘ื ื™ื•ืช ืงื•ื“. ืขื‘ื•ืจ TypeScript, ื”ื•ื ื™ื›ื•ืœ ืœื–ื”ื•ืช ื”ื–ืจืงืช SQL, XSS, ืื™ืฉื•ืจื™ื ืžืงื•ื“ื“ื™ื, ืื•ื‘ื™ื™ืงื˜ื™ื ืœื ื‘ื˜ื•ื—ื™ื. eval ืฉื™ืžื•ืฉ, ื–ื™ื”ื•ื ืื‘ ื˜ื™ืคื•ืก ื•ืชืฆื•ืจื•ืช Express.js ืœื ืžืื•ื‘ื˜ื—ื•ืช, ืชื‘ื ื™ื•ืช ืฉืžืชืงืžืคืœื•ืช ื›ื”ืœื›ื” ืืš ืžืฆื™ื’ื•ืช ืคื’ื™ืขื•ื™ื•ืช ื”ื ื™ืชื ื•ืช ืœื ื™ืฆื•ืœ.

ื™ืืžืœ

# Custom rule: flag user input in SQL queries (TypeScript)
rules:
  - id: ts-sql-injection-risk
    patterns:
      - pattern: |
          const query = `SELECT ... ${$USER_INPUT} ...`;
    message: "User input directly interpolated into SQL -- use parameterized queries"
    languages: [typescript]
    severity: ERROR

ืœื—ื‘ื•ื˜

# Run with the community TypeScript security rules
semgrep scan --config=p/typescript --config=p/owasp-top-ten src/

Semgrep ืžืฉืœื™ื ืืช ESLint, ืœื ืžืชื—ืจื” ืื™ืชื•. ESLint ืื•ื›ืฃ ืžื•ืกื›ืžื•ืช; Semgrep ืžื•ืฆื ืชื‘ื ื™ื•ืช ืื ื˜ื™-ืื‘ื˜ื—ื”. ืจื•ื‘ ืฆื•ื•ืชื™ TypeScript ืฉืื›ืคืช ืœื”ื ืžืื‘ื˜ื—ื” ืฆืจื™ื›ื™ื ืœื”ืจื™ืฅ ืืช ืฉื ื™ื”ื.

ืงื•ื“ Snyk: SAST ืžื‘ื•ืกืก ML ืขื ืฉื™ืœื•ื‘ IDE

Snyk Code ืžื‘ืฆืขืช SAST ืขื ืžื ื•ืข ื ื™ืชื•ื— ืžื‘ื•ืกืก ืœืžื™ื“ืช ืžื›ื•ื ื” ืฉืขื•ืงื‘ ืื—ืจ ื–ืจื™ืžื•ืช ื–ื™ื”ื•ื ื‘ื™ืŸ ืงื‘ืฆื™ื. ื”ื™ื ืžืฉืชืœื‘ืช ื‘-VS Code ื•ื‘-JetBrains IDEs, ื•ื—ื•ืฉืคืช ืžืžืฆืื™ื ื‘ืื•ืคืŸ ืžืงื•ื•ืŸ ื›ืืฉืจ ืžืคืชื—ื™ื ื›ื•ืชื‘ื™ื ืงื•ื“ ื‘ืžืงื•ื ืœื”ืžืชื™ืŸ ืœื”ืจืฆืช CI.

ืœื—ื‘ื•ื˜

npm install --save-dev snyk
npx snyk auth
npx snyk code test

ื”ืžื™ืงื•ื“ ืฉืœ Snyk Code ื‘ื—ื•ื•ื™ื™ืช ื”ืžืคืชื—ื™ื, ืžืฉื•ื‘ ืžื•ื‘ื ื” ืขืœ IDE, ื”ืฆืขื•ืช ืชื™ืงื•ื ื™ื ืœืฆื“ ื›ืœ ืžืžืฆื ื•ื“ื•ื’ืžืื•ืช ืœืชื™ืงื•ืŸ, ื”ื•ืคื›ื™ื ืื•ืชื• ืœื‘ื—ื™ืจื” ื˜ื•ื‘ื” ื™ื•ืชืจ ื›ืืฉืจ ื—ื™ื ื•ืš ืœืื‘ื˜ื—ื” ื—ืฉื•ื‘ ืœื ืคื—ื•ืช ืžื’ื™ืœื•ื™ ืื‘ื˜ื—ื”.

SonarQube ื•-SonarLint: ืฉืขืจื™ ืื™ื›ื•ืช ื•ืžืขืงื‘ ืื—ืจ ืžื’ืžื•ืช

SonarQube ืžืกืคืง ื ื™ืชื•ื— ืจืฆื™ืฃ ืฉืœ ืื™ื›ื•ืช ื”ืงื•ื“ ื‘ืืžืฆืขื•ืช ืœื•ื— ืžื—ื•ื•ื ื™ื, ืžืขืงื‘ ืื—ืจ ืžื’ืžื•ืช ื•ืงื™ืฉื•ื˜ ื‘ืงืฉื•ืช ืžืฉื™ื›ื”. ืขื‘ื•ืจ TypeScript, ื”ื•ื ืžื–ื”ื” ื‘ืื’ื™ื, ืจื™ื—ื•ืช ืงื•ื“, ื ืงื•ื“ื•ืช ื—ืžื•ืช ืฉืœ ืื‘ื˜ื—ื” ื•ื›ืคื™ืœื•ื™ื•ืช. SonarLint ื”ื™ื ื”ืจื—ื‘ืช IDE ืฉื—ื•ืฉืคืช ืืช ื›ืœืœื™ SonarQube ื‘ืื•ืคืŸ ืžืงื•ืžื™.

ืขื‘ื•ืจ ืฆื•ื•ืชื™ TypeScript, SonarCloud (ื”ื’ืจืกื” ื”ืžืื•ื—ืกื ืช ื‘ืขื ืŸ) ื”ื™ื ื”ื ืชื™ื‘ ื”ืคืฉื•ื˜ ื™ื•ืชืจ: ื—ื™ื ืžื™ ืขื‘ื•ืจ ืžืื’ืจื™ื ืฆื™ื‘ื•ืจื™ื™ื, ืขื ืฉื™ืœื•ื‘ CI ื“ืจืš GitHub Actions ืื• GitLab CI ืชื•ืš ื“ืงื•ืช.

ื™ืืžืœ

# .github/workflows/sonar.yml
- name: SonarCloud Scan
  uses: SonarSource/sonarcloud-github-action@master
  env:
    GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
    SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}

ื”ืขืจืš ื”ืขื™ืงืจื™ ืฉืœ SonarQube ืขืœ ืคื ื™ ืขื™ื‘ื•ื“ ืฉื‘ื‘ื™ ื’ื•ืœืžื™ื™ื (raw linting) ื”ื•ื ืžื•ื“ืœ ื”ืžื’ืžื” ืฉืœื•: ื›ื™ืฆื“ ืื™ื›ื•ืช ื”ืงื•ื“ ืžืชืคืชื—ืช ืœืื•ืจืš ื–ืžืŸ, ืื™ืœื• ืจื›ื™ื‘ื™ื ืžืชื“ืจื“ืจื™ื, ื•ืžื”ื• ืฆื™ื•ืŸ ืฉืขืจ ื”ืื™ื›ื•ืช ืฉืœ ืงื•ื“ ื—ื“ืฉ ืขื‘ื•ืจ ื›ืœ ื‘ืงืฉืช ืžืฉื™ื›ื”. ืžื“ื“ื™ื ืืœื” ื”ืคื•ื ื™ื ืœื ื™ื”ื•ืœ ื”ื ืžื” ืฉ-SonarQube ืขื•ืฉื” ืฉ-ESLint ื•-Semgrep ืœื ื™ื›ื•ืœื™ื ืœืขืฉื•ืช.

ืฉื›ื‘ื” 4: ื ื™ืชื•ื— ืื“ืจื™ื›ืœื™

Dependency-Cruiser: ืื›ื™ืคืช ื›ืœืœื™ ื’ื‘ื•ืœ ืžื•ื“ื•ืœ

Dependency-Cruiser ืžืืžืช ืฉื”ื’ืจืฃ ื”ืžื™ื•ื‘ืื™ ืฉืœืš ืขื•ืžื“ ื‘ื›ืœืœื™ื ืืจื›ื™ื˜ืงื˜ื•ื ื™ื™ื ืžื•ื’ื“ืจื™ื. ื”ื•ื ืžื™ื™ืฆืจ ื’ืจืคื™ ืชืœื•ืช ื—ื–ื•ืชื™ื™ื ื•ืžื›ืฉืœ ื‘-CI ื›ืืฉืจ ื”ืงื•ื“ ืžืคืจ ืืช ืื™ืœื•ืฆื™ ื’ื‘ื•ืœื•ืช ื”ืžื•ื“ื•ืœ.

JavaScript

// .dependency-cruiser.cjs
module.exports = {
  forbidden: [
    {
      name: "no-circular",
      severity: "error",
      comment: "Circular dependencies make code hard to test and maintain",
      from: {},
      to: { circular: true },
    },
    {
      name: "no-ui-in-domain",
      severity: "error",
      comment: "Domain modules must not import from UI layer",
      from: { path: "^src/domain" },
      to: { path: "^src/ui" },
    },
    {
      name: "no-external-in-shared",
      severity: "warn",
      comment: "Shared utilities should minimize external dependencies",
      from: { path: "^src/shared" },
      to: { pathNot: "^(src|node_modules/(lodash|date-fns))" },
    },
  ],
};

ืœื—ื‘ื•ื˜

npx depcruise --validate .dependency-cruiser.cjs src/

Dependency-Cruiser ืžื˜ืคืœ ื™ืฉื™ืจื•ืช ื‘ืฉืื™ืœืชื•ืช "react dependency analysis cli tool" ื‘ื ืชื•ื ื™ Search Console, ื–ื”ื• ื”ื›ืœื™ ื”ืกื˜ื ื“ืจื˜ื™ ืœื™ืฆื™ืจื” ื•ืื™ืžื•ืช ืฉืœ ื’ืจืคื™ ืชืœื•ืช ื‘ืคืจื•ื™ืงื˜ื™ื ืฉืœ TypeScript/React.

ื“ืคื˜ืจืง: ืื›ื™ืคืช ื’ื‘ื•ืœื•ืช ืžื‘ื•ืกืกืช ืฉื›ื‘ื•ืช

Deptrac ืื•ื›ืฃ ืฉื›ื‘ื•ืช ืื“ืจื™ื›ืœื™ื•ืช, ื•ืžื‘ื˜ื™ื— ืฉืงื•ื“ persistence ืœื ื™ื•ื›ืœ ืœื™ื™ื‘ื ืžื”ืžืฆื’ืช, ืฉืื•ื‘ื™ื™ืงื˜ื™ ืชื—ื•ื ืื™ื ื ืชืœื•ื™ื™ื ื‘ืชืฉืชื™ืช, ื•ืฉื’ื‘ื•ืœื•ืช ื”ืžื•ื“ื•ืœื™ื ืžื›ื•ื‘ื“ื™ื ืœืื•ืจืš ื›ืœ ื‘ืกื™ืก ื”ืงื•ื“.

ื™ืืžืœ

# deptrac.yaml
parameters:
  layers:
    - name: Domain
      collectors:
        - type: directory
          value: src/domain
    - name: Application
      collectors:
        - type: directory
          value: src/application
    - name: Infrastructure
      collectors:
        - type: directory
          value: src/infrastructure
  ruleset:
    Domain:
      - ~Infrastructure  # Domain must not depend on Infrastructure
    Application:
      - Domain
    Infrastructure:
      - Application
      - Domain

Deptrac ื”ื•ื ื‘ืขืœ ืขืจืš ืจื‘ ื‘ื™ื•ืชืจ ื‘ืคืจื•ื™ืงื˜ื™ื ื”ืขื•ืงื‘ื™ื ืื—ืจ ืชื‘ื ื™ื•ืช ืฉืœ ืืจื›ื™ื˜ืงื˜ื•ืจื” ื ืงื™ื™ื”, DDD ืื• ืืจื›ื™ื˜ืงื˜ื•ืจื” ืžืฉื•ืฉื”, ืฉื‘ื”ืŸ ื‘ื™ื“ื•ื“ ืฉื›ื‘ื•ืช ื”ื•ื ืื™ืœื•ืฅ ืขื™ืฆื•ื‘ื™, ืœื ืจืง ื”ืขื“ืคื”.

Nx: ื ื™ื”ื•ืœ ืชืœื•ืช ื‘ืจืžืช Monorepo

ืขื‘ื•ืจ ืžื•ื ื•-ืจืคื•ืื™ื ืฉืœ TypeScript, Nx ืžืกืคืงืช ืื›ื™ืคืช ื’ื‘ื•ืœื•ืช ืžื•ื“ื•ืœื™ื, ื–ื™ื”ื•ื™ ื‘ื ื™ื™ื” ืžื•ืฉืคืขืช, ื•ื”ื“ืžื™ื” ืฉืœ ื’ืจืฃ ืชืœื•ื™ื•ืช ื‘ื›ืœ ื”ืคืจื•ื™ืงื˜ื™ื ื‘ืžืื’ืจ.

ื’'ืกื•ืŸ

// .eslintrc.json -- Nx module boundary rules
{
  "rules": {
    "@nx/enforce-module-boundaries": [
      "error",
      {
        "allow": [],
        "depConstraints": [
          { "sourceTag": "scope:shared", "onlyDependOnLibsWithTags": ["scope:shared"] },
          { "sourceTag": "scope:feature", "onlyDependOnLibsWithTags": ["scope:shared", "scope:feature"] },
          { "sourceTag": "scope:app", "onlyDependOnLibsWithTags": ["scope:shared", "scope:feature"] }
        ]
      }
    ]
  }
}

Nx's affected ืคืงื•ื“ื•ืช ืžืจื™ืฆื•ืช ืจืง ืืช ื”ื‘ื“ื™ืงื•ืช ื•ื”-linting ื”ืจืœื•ื•ื ื˜ื™ื™ื ืœืžื•ื“ื•ืœื™ื ืฉื”ืฉืชื ื•, ืžื” ืฉืžืคื—ื™ืช ืžืฉืžืขื•ืชื™ืช ืืช ื–ืžืŸ ื”-CI ื‘ืžื•ื ื•ืจืคื• ื’ื“ื•ืœื™ื.

ืฉื›ื‘ื” 5: ื–ื™ื”ื•ื™ ืงื•ื“ ืžืช

Knip: ืžืฆื ืงื‘ืฆื™ ื™ื™ืฆื•ื, ืงื‘ืฆื™ื ื•ืชืœื•ื™ื•ืช ืฉืื™ื ื ื‘ืฉื™ืžื•ืฉ

Knip ืžื ืชื— ืืช ื’ืจืฃ ื”ืžื•ื“ื•ืœ ื”ืžืœื ื›ื“ื™ ืœื–ื”ื•ืช ื™ื™ืฆื•ื ืฉืื™ื ื• ื‘ืฉื™ืžื•ืฉ, ืงื‘ืฆื™ื ืฉืื™ื ื ื‘ืฉื™ืžื•ืฉ ื•ืงื‘ืฆื™ื ืฉืื™ื ื ื‘ืฉื™ืžื•ืฉ package.json ืชืœื•ื™ื•ืช, ืกื•ื’ ืฆื‘ื™ืจืช ื”ืงื•ื“ ืฉ-ESLint no-unused-vars ืœื ื™ื›ื•ืœ ืœืชืคื•ืก ื›ื™ ื–ื” ืžื—ืคืฉ ืจืง ื‘ืชื•ืš ืงื•ื‘ืฅ.

ืœื—ื‘ื•ื˜

npm install --save-dev knip
npx knip

ื’'ืกื•ืŸ

// knip.json
{
  "entry": ["src/index.ts", "src/**/*.test.ts"],
  "project": ["src/**/*.ts"],
  "ignore": ["src/generated/**"],
  "ignoreDependencies": ["vitest"]
}

Knip ืžืชื‘ืฆืข ื™ืฉื™ืจื•ืช ื‘ื ืชื•ื ื™ SC ื‘ืชื•ืจ "dead code detection unused exports javascript typescript". ื–ื”ื• ื”ื›ืœื™ ื”ื™ืขื™ืœ ื‘ื™ื•ืชืจ ื›ื™ื•ื ืœื–ื™ื”ื•ื™ ืงื•ื“ ืžืช ื‘ืจืžืช ื”ืžื•ื“ื•ืœ ื‘ืคืจื•ื™ืงื˜ื™ื ืฉืœ TypeScript.

ืฉื›ื‘ื” 6: ื ื™ืชื•ื— ืคืจื•ื’ืจืžื˜ื™, ts-morph

ts-morph ื”ื•ื ืขื˜ื™ืคืช API ืฉืœ ืžื”ื“ืจ TypeScript ื”ืžืืคืฉืจืช ื›ืชื™ื‘ืช ื ื™ืชื•ื—ื™ื ืžื•ืชืืžื™ื ืื™ืฉื™ืช, ืงื•ื“ืžื•ื“ื™ื ื•ื›ืœื™ื ื›ื ื’ื“ AST ืฉืœ TypeScript. ื”ื•ื ืžื—ืคืฉ ื™ืฉื™ืจื•ืช ื‘ื ืชื•ื ื™ SC ื›-"ts-morph" ื•-"ts morph".

ื›ืชื‘ ื›ืชื™ื‘ื”

import { Project } from "ts-morph";

const project = new Project({ tsConfigFilePath: "tsconfig.json" });

// Find all async functions that never await anything
const suspiciousAsyncFns: string[] = [];

for (const sourceFile of project.getSourceFiles()) {
  for (const fn of sourceFile.getFunctions()) {
    if (fn.isAsync()) {
      const hasAwait = fn.getDescendantsOfKind(
        SyntaxKind.AwaitExpression
      ).length > 0;
      if (!hasAwait) {
        suspiciousAsyncFns.push(
          `${sourceFile.getFilePath()}:${fn.getName() ?? "anonymous"}`
        );
      }
    }
  }
}

console.log("Async functions with no await:", suspiciousAsyncFns);

ts-morph ืื™ื ื• ื›ืœื™ ื ื™ืชื•ื— ืžื•ื›ืŸ ืœื”ืคืขืœื”, ืืœื ื”ืกืคืจื™ื™ื” ืฉื‘ื” ืžืฉืชืžืฉื™ื ื›ื“ื™ ืœื‘ื ื•ืช ืื—ื“. ื”ื•ื ืžืชืื™ื ืœืฆื•ื•ืชื™ื ื”ื–ืงื•ืงื™ื ืœื ื™ืชื•ื— ืžื•ืชืื ืื™ืฉื™ืช ืžืขื‘ืจ ืœืžื” ืฉื”ื›ืœื™ื ื”ืงื™ื™ืžื™ื ืชื•ืžื›ื™ื ื‘ื•: ืกืงืจื™ืคื˜ื™ื ืฉืœ ื”ื’ื™ืจื”, ืžืืžืชื™ื ืืจื›ื™ื˜ืงื˜ื•ื ื™ื™ื ืžื•ืชืืžื™ื ืื™ืฉื™ืช, ืฉื™ืคื•ืฅ ืื•ื˜ื•ืžื˜ื™ ืื• ืฆื™ื ื•ืจื•ืช ื™ืฆื™ืจืช ืงื•ื“.

ื ื™ืชื•ื— ืกื˜ื˜ื™ ืืกื™ื ื›ืจื•ื ื™/ื”ืžืชื ื” ืฉืœ TypeScript

ื ืชื•ื ื™ Search Console ืžืฆื™ื’ื™ื ืืฉื›ื•ืœ ืกืคืฆื™ืคื™ ืฉืœ ืฉืื™ืœืชื•ืช ืกื‘ื™ื‘ "typescript static analysis async await paper tool" ื•-"typescript static analysis async await vulnerability paper tool". ืืœื” ืžืฉืงืคื™ื ืžื•ืžื—ื™ื ื”ืžื—ืคืฉื™ื ื›ืœื™ื ืฉืžื‘ื™ื ื™ื ืฉื’ื™ืื•ืช ืชื›ื ื•ืช ืืกื™ื ื›ืจื•ื ื™ื•ืช ื‘ืจืžืช ื”ืกื•ื’.

ื”ืชืฉื•ื‘ื” ื”ืžืขืฉื™ืช ืขื‘ื•ืจ ืฆื•ื•ืชื™ TypeScript ื‘ื™ื™ืฆื•ืจ ื”ื™ื ืืจื‘ืขืช ื”ื›ืœืœื™ื ื”ืกืคืฆื™ืคื™ื™ื ืœืืกื™ื ื›ืจื•ื ื™ื™ื ืฉืœ typescript-eslint (no-floating-promises, await-thenable, no-misused-promises, require-await) ื‘ืฉื™ืœื•ื‘ ืขื strictNullChecks ื• useUnknownInCatchVariablesื™ื—ื“, ืืœื” ืœื•ื›ื“ื™ื ืืช ืฉื’ื™ืื•ืช ื”ืืกื™ื ื›ืจื•ื ื™ื•ืช ื”ื ืคื•ืฆื•ืช ื‘ื™ื•ืชืจ ืžื‘ืœื™ ืœื”ื–ื“ืงืง ืœื›ืœื™ ืžื—ืงืจ ืืงื“ืžื™ื™ื.

ืขื‘ื•ืจ ืฆื•ื•ืชื™ื ืฉืขื•ืกืงื™ื ื‘ืžื—ืงืจ ืื‘ื˜ื—ื” ืขืœ ื“ืคื•ืกื™ ืคื’ื™ืขื•ื™ื•ืช ืืกื™ื ื›ืจื•ื ื™ื•ืช, TAJS ื•-Jelly ื”ื ืžื ืชื—ื™ื ืกื˜ื˜ื™ื™ื ืืงื“ืžื™ื™ื ื”ืžื“ื’ืžื™ื ืืช ื”ืกืžื ื˜ื™ืงื” ืฉืœ ื‘ื™ืฆื•ืข ืืกื™ื ื›ืจื•ื ื™ ืฉืœ JavaScript, ืืš ื”ื ื›ืœื™ ืžื—ืงืจ, ืœื ื›ืœื™ ืคื™ืชื•ื— ื™ื™ืฆื•ืจ.

Angular ื•-React: ื ื™ืชื•ื— ืกื˜ื˜ื™ ืกืคืฆื™ืคื™ ืœืžืกื’ืจืช

ืขื‘ื•ืจ ืฆื•ื•ืชื™ ืื ื’ื•ืœืจ, @angular-eslint ืžืกืคืง ื›ืœืœื™ linting ืกืคืฆื™ืคื™ื™ื ืœ-Angular ื”ืžื›ืกื™ื ืชื‘ื ื™ื•ืช ืจื›ื™ื‘ื™ื, ื ื™ืชื•ื— ืชื‘ื ื™ื•ืช ื•ื”ื–ืจืงืช ืฉื™ืจื•ืชื™ื. ื”ื•ื ืžืฉืชืœื‘ ืขื ืชืฆื•ืจืช ESLint + typescript-eslint ืœืขื™ืœ.

ืขื‘ื•ืจ ืฆื•ื•ืชื™ ืจื™ืืงื˜, ื” eslint-plugin-react, eslint-plugin-react-hooks, ื• eslint-plugin-jsx-a11y ืชื•ืกืคื™ื ืžื›ืกื™ื ืชื‘ื ื™ื•ืช ืกืคืฆื™ืคื™ื•ืช ืœ-React. Dependency-Cruiser ืžื˜ืคืœ ื‘ื ื™ืชื•ื— ื’ืจืคื™ ืชืœื•ื™ื•ืช ืกืคืฆื™ืคื™ื™ื ืœ-React ื•ื”ื•ื ื”ื›ืœื™ ืฉืขื•ืžื“ ืžืื—ื•ืจื™ ืฉืื™ืœืชื•ืช "react dependency analysis cli tool" ื‘ื ืชื•ื ื™ SC.

ืฉื™ืœื•ื‘ IDE: ื›ืœื™ื ืขื‘ื•ืจ VS Code ื•-JetBrains

ื”ืฉืื™ืœืชื•ืช "ื›ืœื™ ืงื•ื“ ืื™ื›ื•ืชื™ื™ื ืœืฉื™ืœื•ื‘ VS Code" ื•"ื›ืœื™ ืงื•ื“ ืื™ื›ื•ืชื™ื™ื ืœืฉื™ืœื•ื‘ IDE" ืžืฉืงืคื•ืช ืฆื•ืจืš ืืžื™ืชื™: ืžืฉื•ื‘ CI ืžื’ื™ืข ืžืื•ื—ืจ ืžื“ื™ ื›ื“ื™ ืœืฉื ื•ืช ื”ืชื ื”ื’ื•ืช. ื ื™ืชื•ื— ืžืฉื•ืœื‘ IDE ืžืกืคืง ืืช ืœื•ืœืืช ื”ืžืฉื•ื‘ ื”ื”ื“ื•ืงื” ื‘ื™ื•ืชืจ.

ืงื•ื“ VS : ื”ืจื—ื‘ืช ESLint ืขื ืžื ืชื— ื—ืœื•ื“ื” Clippy parity, ื”ืจื—ื‘ืช SonarLint ืขื‘ื•ืจ ื›ืœืœื™ SonarQube ืžื•ื˜ื‘ืขื™ื, ื”ืจื—ื‘ืช Snyk ืขื‘ื•ืจ ืžืžืฆืื™ ืื‘ื˜ื—ื”, ื•ืฉื™ืจื•ืช ืฉืคืช TypeScript ืžื•ื‘ื ื” ืขื‘ื•ืจ ืžืฉื•ื‘ ื‘ืจืžืช ื”ืกื•ื’.

JetBrains (WebStorm/IntelliJ) : WebStorm ืžื’ื™ืข ืขื ืชืžื™ื›ื” ืžื•ื‘ื ื™ืช ื‘-TypeScript ืฉื—ื•ืฉืคืช ืฉื’ื™ืื•ืช ื”ืงืœื“ื” ื‘ืื•ืคืŸ ืžืงื•ื•ืŸ, ื‘ื ื•ืกืฃ ืœืื™ื ื˜ื’ืจืฆื™ื” ืขื ESLint, Prettier ื•-SonarLint. ืžืขืจื›ืช ื”ื‘ื“ื™ืงื” ื”ืžื•ื‘ื ื™ืช ืžื›ืกื” ืจื‘ื•ืช ืžืื•ืชืŸ ืชื‘ื ื™ื•ืช ื›ืžื• ื›ืœืœื™ ESLint.

ืชืฆื•ืจืช VS Code ืœื›ื™ืกื•ื™ ื ื™ืชื•ื— ืกื˜ื˜ื™ ืžืงืกื™ืžืœื™ ืฉืœ TypeScript :

ื’'ืกื•ืŸ

// .vscode/settings.json
{
  "typescript.tsdk": "node_modules/typescript/lib",
  "typescript.enablePromptUseWorkspaceTsdk": true,
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": "explicit"
  },
  "eslint.validate": ["javascript", "typescript", "typescriptreact"],
  "sonarlint.connectedMode.project": {
    "connectionId": "my-sonarcloud",
    "projectKey": "my-org_my-project"
  }
}

ืื™ืš SMART TS XL ืžืจื—ื™ื‘ ืืช ื ื™ืชื•ื— TypeScript ื‘ืจื—ื‘ื™ ื”ืืจื’ื•ืŸ

ื”ื›ืœื™ื ื”ื "ืœ ืžื›ืกื™ื ืืช TypeScript ื‘ืชื•ืš ืคืจื•ื™ืงื˜ TypeScript. ื‘ืืจื’ื•ื ื™ื ืฉื‘ื”ื ืฉื™ืจื•ืชื™ TypeScript ืžืงื™ื™ืžื™ื ืื™ื ื˜ืจืืงืฆื™ื” ืขื ืชื•ื›ื ื™ื•ืช ืืฆื•ื•ื” ืฉืœ COBOL, ืžืžืฉืงื™ API ืฉืœ Java, ืฆื™ื ื•ืจื•ืช ื ืชื•ื ื™ื ืฉืœ Python ืื• ืžืขืจื›ื•ืช ืžื™ื™ื ืคืจื™ื™ื ืžื“ื•ืจ ืงื•ื“ื, ื›ืœื™ื ื‘ืฉืคื” ืื—ืช ืื™ื ื ื™ื›ื•ืœื™ื ืœืจืื•ืช ืืช ื”ืชืœื•ื™ื•ืช ื”ื—ื•ืฆื•ืช ื’ื‘ื•ืœื•ืช ืฉืคื”.

SMART TS XL"S ื ื™ืชื•ื— ืงื•ื“ ืกื˜ื˜ื™ ืžื›ืกื” ืืช TypeScript ืœืฆื“ ื›ืœ ืฉืคื” ืื—ืจืช ื‘ืกื‘ื™ื‘ืช ื”ืืจื’ื•ืŸ, COBOL, JCL, Java, Python, RPG, SQL, ื•ื‘ื•ื ื” ืžื•ื“ืœ ืชืœื•ืช ืžืื•ื—ื“ ืขืœ ืคื ื™ ื›ื•ืœืŸ. ื›ืืฉืจ ืฉื™ืจื•ืช TypeScript ืงื•ืจื ืœ-API ื”ืžื’ื•ื‘ื” ืขืœ ื™ื“ื™ ืชื•ื›ื ื™ืช COBOL, SMART TS XL ื™ื›ื•ืœ ืœืขืงื•ื‘ ืื—ืจ ื”ืงืฉืจ ื”ื–ื” ื•ืœื›ืœื•ืœ ืื•ืชื• ื‘ ื ื™ืชื•ื— ื”ืฉืคืขื•ืช ืœืคื ื™ ื‘ื™ืฆื•ืข ื›ืœ ืฉื™ื ื•ื™ ื‘ืื—ื“ ื”ืจื›ื™ื‘ื™ื.

ื™ื›ื•ืœืช ื”ื—ื™ืคื•ืฉ ื”ืืจื’ื•ื ื™ ื”ื•ืคื›ืช ืืช ื›ืœ ื‘ืกื™ืก ื”ืงื•ื“ ื”ืจื‘-ืœืฉื•ื ื™ ืœื ื™ืชืŸ ืœืฉืื™ืœืชื”: ืžืฆื ื›ืœ ื™ื™ื‘ื•ื โ€‹โ€‹TypeScript ืฉืœ ืžื•ื“ื•ืœ ืกืคืฆื™ืคื™, ื›ืœ ืฉื™ื˜ืช Java ืฉืฉื™ืจื•ืช TypeScript ืงื•ืจื ืœื”, ื›ืœ ืกืคืจ ืขื•ืชืงื™ื ืฉืœ COBOL ืฉืžื–ื™ืŸ ื ืชื•ื ื™ื ืœ-API ื”ื ืฆืจืš ืขืœ ื™ื“ื™ TypeScript, ืชื•ืš ืฉื ื™ื•ืช, ืขืœ ืคื ื™ ืžื™ืœื™ื•ื ื™ ืฉื•ืจื•ืช ืงื•ื“ ื‘ื›ืœ ืฉื™ืœื•ื‘ ืฉืœ ืฉืคื•ืช.

ืขื‘ื•ืจ ืฆื•ื•ืชื™ ืืจื’ื•ืŸ ื”ืžืคืขื™ืœื™ื ืืช TypeScript ื›ืฉืคื” ืื—ืช ื‘ืชื•ืš ืชื™ืง ืขื‘ื•ื“ื•ืช ื’ื“ื•ืœ ื™ื•ืชืจ, SMART TS XL ืžืกืคืง ืืช ื”ื ืจืื•ืช ื”ืื“ืจื™ื›ืœื™ืช ื•ืืช ื”ื’ื™ืฉื” ื”ื—ื•ืฆื” ืœืฉื•ื ื™ืช ืžื™ืคื•ื™ ืชืœื•ืช ืฉื’ื•ืจื ืœื›ืœื™ TypeScript ืกืคืฆื™ืคื™ื™ื ืœื”ืกืชื›ืœ ืขืœ ื”ื—ืœืง ืฉืœื”ื ื‘ืžืขืจื›ืช ื‘ื–ืžืŸ SMART TS XL ืจื•ืื” ืืช ื”ืฉืœื.

ื‘ื ื™ื™ืช ื”ืขืจื™ืžื” ื”ื ื›ื•ื ื”

ืื™ืŸ ื›ืœื™ ื™ื—ื™ื“ ื”ืžื›ืกื” ืืช ื›ืœ ืžืžื“ื™ ื”ืื™ื›ื•ืช ืขื‘ื•ืจ TypeScript. ื”ื’ื™ืฉื” ื”ื ื›ื•ื ื” ื”ื™ื ื’ื™ืฉื” ืจื‘-ืฉื›ื‘ืชื™ืช, ื›ืืฉืจ ื›ืœ ืฉื›ื‘ื” ืžื›ื•ื•ื ืช ืœืกื•ื’ ื‘ืขื™ื” ื ืคืจื“:

ืขืจื™ืžื” ืžื™ื ื™ืžืœื™ืช ืืคืฉืจื™ืช (ืคืจื•ื™ืงื˜ ื—ื“ืฉ, ืฆื•ื•ืช ืงื˜ืŸ):

  • ืžืฆื‘ ืงืคื“ื ื™ ืฉืœ TypeScript
  • ESLint ืขื ื›ืœืœื™ ืืกื™ื ื›ืจื•ืŸ ืฉืœ typescript-eslint
  • npm audit ืขื‘ื•ืจ ืคื’ื™ืขื•ื™ื•ืช ืชืœื•ืช

ืžื—ืกื ื™ืช ื™ื™ืฉื•ืžื™ ื™ื™ืฆื•ืจ (ืฆื•ื•ืช ื‘ื™ื ื•ื ื™, ืžื•ื“ืข ืœืื‘ื˜ื—ื”):

  • ื”ื›ืœ ืœืžืขืœื”, ืคืœื•ืก:
  • ื‘ื™ื•ืžื” ืื• ื™ืคื” ื™ื•ืชืจ ืœืขื™ืฆื•ื‘
  • Semgrep ืขื‘ื•ืจ SAST ืื‘ื˜ื—ื”
  • ืกื›ื™ืŸ ืœืงื•ื“ ืžืช
  • SonarCloud ืœื ืจืื•ืช ืžื’ืžื•ืช ืื™ื›ื•ืชื™ืช

ืžื—ืกื ื™ืช ืืจื’ื•ื ื™ืช / ืžื•ื ื•ืจืคื• (ืฆื•ื•ืช ื’ื“ื•ืœ, ืื™ืœื•ืฆื™ื ืืจื›ื™ื˜ืงื˜ื•ื ื™ื™ื):

  • ื”ื›ืœ ืœืžืขืœื”, ืคืœื•ืก:
  • Dependency-Cruiser ืœืื›ื™ืคืช ื’ื‘ื•ืœื•ืช ืžื•ื“ื•ืœื™ื
  • Nx ืขื‘ื•ืจ ืื•ืคื˜ื™ืžื™ื–ืฆื™ื” ืฉืœ ื‘ื ื™ื™ืช ืžื•ืฉืคืขืช ืžืžื•ื ื•-ืจืคื•
  • Deptrac ืœืื™ืžื•ืช ื’ื‘ื•ืœื•ืช ืฉื›ื‘ื”
  • SonarQube (ืื—ืกื•ืŸ ืขืฆืžื™) ืœืฉืขืจื™ื ืื™ื›ื•ืชื™ื™ื ื‘ืืชืจ

ืžื—ืกื ื™ืช ืืจื’ื•ื ื™ืช ืฉืœ Polyglot (TypeScript ืœืฆื“ ืžืขืจื›ื•ืช ืžื“ื•ืจ ืงื•ื“ื):

  • ื”ื›ืœ ืœืžืขืœื”, ืคืœื•ืก:
  • SMART TS XL ืœื ื™ืชื•ื— ื”ืฉืคืขื•ืช ื—ื•ืฆื•ืช-ืœืฉื•ื ื•ืช ื•ืžื™ืคื•ื™ ืชืœื•ืช