Skip to main content

typescript

TypeScript best practices for this monorepo. Use this skill when: (1) writing new TypeScript code, (2) reviewing TypeScript code, (3) working with API responses, fetch calls, or JSON parsing, (4) adding or modifying types and interfaces.

소스 정보

저장소
microsoft/scope
최근 소스 활동
2026년 5월 26일 22:19
감지된 SKILL.md 언어
영어
스타
54
포크
26

설치 방법

기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.

소스 파일 검토

설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.

SKILL.md 표시 중

SKILL.md
소스 지침 · 읽기 전용 미리보기
name
typescript
description
TypeScript best practices for this monorepo. Use this skill when: (1) writing new TypeScript code, (2) reviewing TypeScript code, (3) working with API responses, fetch calls, or JSON parsing, (4) adding or modifying types and interfaces.
metadata
{"version":"1.0.0"}
# TypeScript Best Practices ## Never Leave Values Untyped at `any` Boundaries Whenever data crosses a boundary that erases type information (`response.json()`, `JSON.parse()`, external library returns, database query results, queue message payloads), **immediately annotate or narrow the type**: ```typescript // ❌ BAD — `any` leaks through, wrong property access compiles silently const data = await response.json(); data.turns; // no error even if turns lives at data.run.turns const parsed = JSON.parse(rawMessage); parsed.requestId; // unverified assumption // ✅ GOOD — type boundary is explicit, TypeScript verifies all access import type { RequestDocument } from "shared"; const data: RequestDocument = await response.json(); data.run?.turns; // correct path, verified at compile time const parsed: QueueMessagePayload = JSON.parse(rawMessage); parsed.requestId; // known to exist ``` ### Why This Matters - `any` propagates silently — one untyped value infects everything it touches - Bugs from wrong property paths are invisible at compile time - Tests may share the same wrong assumption as the code (mocks mirror the bug) - Adding a type annotation is zero-cost at runtime but catches entire classes of bugs ### Guidelines 1. **Import the shared type** from `packages/shared` when one exists (e.g., `RequestDocument`, `RunState`, `ReportDocument`) 2. **Create a local interface** if no shared type exists and the response shape is known 3. **Use Zod `.parse()`** when you need runtime validation (e.g., external APIs you don't control) 4. **Use optional chaining** (`?.`) instead of `|| {}` fallbacks — it preserves type narrowing ## Prefer Optional Chaining Over Fallback Objects ```typescript // ❌ BAD — `|| {}` erases type information, downstream access is untyped const run = request.run || {}; run.turns; // type is `{}`, no autocomplete, no error checking // ✅ GOOD — preserves the original type, TypeScript tracks nullability const run = request.run; run?.turns; // type is `ConversationTurn[] | undefined` ``` ## Use Shared Types from `packages/shared` This monorepo defines canonical types in `packages/shared/src/types/`. Always import from there rather than redeclaring shapes: | Type | Use For | | --- | --- | | `RequestDocument` | Full request document (includes `run?: RunState`) | | `RunState` | Per-attempt run state (status, turns, outcome) | | `ConversationTurn` | Individual iteration within a run | | `ReportDocument` | Report job state | | `ReportTemplateDocument` | Report template configuration | | `LogEvent` | Structured log entry | | `Scenario` | Task + criteria definition | ## Avoid `any` in New Code - Use `unknown` when the type is genuinely not known, then narrow with type guards - Use generics when writing reusable utilities - If you must use `any` (e.g., third-party library boundaries), contain it — cast to a typed variable immediately ```typescript // ❌ BAD — any spreads and defeats type checking function process(data: any) { return data.items.map((i: any) => i.name); } // ✅ GOOD — typed boundary, any is contained interface ApiResponse { items: Array<{ name: string }> } function process(data: unknown): string[] { const typed = data as ApiResponse; return typed.items.map(i => i.name); } ```
GitHub에서 보기