Skip to main content Instalar con Codex o Claude Copia este prompt, pégalo en Codex, Claude u otro asistente, y deja que revise la página de la skill y la instale por ti.
Un comando directo omite el prompt de revisión. Revisa el origen antes de ejecutarlo.
npx skills add https://github.com/alinaqi/maggy --skill typescriptEl comando permanece en una sola línea. Desplázate horizontalmente para revisarlo antes de copiarlo.
¿Prefieres una copia local? Descarga los archivos que SkillsMP tiene disponibles ahora.
Ocupaciones relacionadasSOC
Basado en la clasificación ocupacional SOC
| name | typescript |
| description | TypeScript strict mode with eslint and jest |
| when-to-use | When working on TypeScript files |
| user-invocable | false |
| paths | ["**/*.ts","**/*.tsx","tsconfig*.json"] |
| effort | medium |
TypeScript Skill
Strict Mode (Non-Negotiable)
{
"compilerOptions": {
"strict": true,
"noImplicitAny": true,
"strictNullChecks"
:
true
,
"noUnusedLocals"
:
true
,
"noUnusedParameters"
:
true
,
"noImplicitReturns"
:
true
,
"esModuleInterop"
:
true
,
"skipLibCheck"
:
true
,
"forceConsistentCasingInFileNames"
:
true
}
}
Project Structure
project/
├── src/
│ ├── core/ # Pure business logic
│ │ ├── types.ts # Domain types/interfaces
│ │ ├── services/ # Pure functions
│ │ └── index.ts # Public API
│ ├── infra/ # Side effects
│ │ ├── api/ # HTTP handlers
│ │ ├── db/ # Database operations
│ │ └── external/ # Third-party integrations
│ └── utils/ # Shared utilities
├── tests/
│ ├── unit/
│ └── integration/
├── package.json
├── tsconfig.json
└── CLAUDE.md
Tooling (Required)
{
"scripts": {
"lint": "eslint src/ --ext .ts,.tsx",
"typecheck": "tsc --noEmit",
"test": "jest",
"test:coverage": "jest --coverage",
"format": "prettier --write 'src/**/*.ts'"
}
}
import eslint from '@eslint/js';
import tseslint from 'typescript-eslint';
export default tseslint.config(
eslint.configs.recommended,
...tseslint.configs.strictTypeChecked,
{
rules: {
'@typescript-eslint/no-explicit-any': 'error',
'@typescript-eslint/explicit-function-return-type': 'error',
'max-lines-per-function': ['error', 20],
'max-depth': ['error', 2],
'max-params': ['error', 3],
}
}
);
Testing with Jest
import { calculateTotal } from '../../../src/core/services/pricing';
describe('calculateTotal', () => {
it('returns sum of item prices', () => {
const items = [{ price: 10 }, { price: 20 }];
const result = calculateTotal(items);
expect(result).toBe(30);
});
it('returns zero for empty array', () => {
expect(calculateTotal([])).toBe(0);
});
it('throws on invalid item', () => {
expect(() => calculateTotal([{ invalid: 'item' }])).toThrow();
});
});
GitHub Actions
name: TypeScript Quality Gate
on: [push, pull_request]
jobs:
quality:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install dependencies
run: npm ci
- name: Lint
run: npm run lint
- name: Type Check
run: npm run typecheck
- name: Test with Coverage
run: npm run test:coverage
- name: Coverage Threshold (80%)
run: npm run test:coverage -- --coverageThreshold='{"global":{"branches":80,"functions":80,"lines":80,"statements":80}}'
Pre-Commit Hooks
Using Husky + lint-staged:
npm install -D husky lint-staged
npx husky init
{
"lint-staged": {
"*.{ts,tsx}": [
"eslint --fix",
"prettier --write"
]
}
}
npx lint-staged
npx tsc --noEmit
npm run test -- --onlyChanged --passWithNoTests
This runs on every commit:
- ESLint + Prettier on staged files
- Type check entire project
- Tests for changed files only
Type Patterns
Discriminated Unions for Results
type Result<T> =
| { ok: true; value: T }
| { ok: false; error: string };
function parseUser(data: unknown): Result<User> {
}
Branded Types for IDs
type UserId = string & { readonly brand: unique symbol };
type OrderId = string & { readonly brand: unique symbol };
function getOrder(orderId: OrderId): Order { ... }
Const Assertions for Literals
const STATUSES = ['pending', 'active', 'closed'] as const;
type Status = typeof STATUSES[number];
Zod for Runtime Validation
import { z } from 'zod';
const UserSchema = z.object({
email: z.string().email(),
name: z.string().min(1).max(100),
});
type User = z.infer<typeof UserSchema>;
TypeScript Anti-Patterns
- ❌
any type - use unknown and narrow
- ❌ Type assertions (
as) - use type guards
- ❌ Non-null assertions (
!) - handle null explicitly
- ❌
@ts-ignore without explanation
- ❌ Enums - use const objects or union types
- ❌ Classes for data - use interfaces/types
- ❌ Default exports - use named exports