# Typescript

> Write clear, predictable TypeScript and Vue TypeScript code with strong typing, maintainability, and consistent documentation conventions.

- Skill: `scalar/typescript` (Agent Skill)
- Install (CLI): `npx skillmds@latest add scalar/typescript`
- Raw SKILL.md: https://api.skillmd.com/api/skills/scalar/typescript/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Web & Frontend
- Author: scalar (https://skillmd.com/u/scalar)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/scalar/typescript

---


# Writing TypeScript

You write TypeScript code that is clear, predictable, and easy to maintain. The goal is to make the codebase safer, more understandable, and easier to refactor without over-engineering.

## Principles
* Type safety over flexibility.
* Clarity over cleverness.
* Type inference where it makes sense.

## General Guidelines
* Prefer type over interface.
* Explicit return types for functions.
* Avoid any. Use unknown when the type is unclear.
* Prefer primitive types over complex ones unless necessary.
* Use readonly when possible.
* Avoid enums. Use string literal unions instead.
* Always use const instead of let.
* Use satisfies instead of as
* Always use arrow functions when possible

## Naming Conventions
* Be descriptive.
* Use suffixes appropriately.

## Working with Vue + TypeScript
* Explicitly type defineProps and defineEmits.
* Explicit return types for composables.
* Explicitly type Ref and ComputedRef.

## Testing
* Write all tests using vitest.
* Ensure you cover all main cases as well as edge cases, try to break the code with the tests.
* Create the test file alongside the file being tested, call it `name.test.ts`.

# Great Comments for All Types
* Use comments to explain why, not what. Most of the time, the code explains what is happening. Comments should clarify why a type or function exists, why you made specific decisions, or why a workaround is necessary.
* Write friendly comments that sound human. Comments should be clear and helpful, not robotic or overly formal. Aim for a tone that's friendly and supportive, like you're helping a teammate understand the code later.

Good:

```ts
/**
 * We load the user here to make sure we have fresh data when the component mounts.
 * Without this, the user info could be stale.
 */
```

Bad:

```ts
/**
 * Load user.
 */
```

* Avoid contractions in comments. Use do not instead of don't, it is instead of it's, etc. This makes comments easier to read, especially for non-native speakers.

* If you use contractions, make sure they have proper apostrophes. Sometimes contractions can make a comment more approachable. If you choose to use them, use proper punctuation.

* Comment on types when their purpose isn't obvious. If a type models an external API, or has a non-obvious constraint, explain it.

* Explain relationships between types when they're not clear.

Example:

```ts
/**
 * Maps UserStatus to a badge color used in the UI.
 * Should stay in sync with the theme color palette.
 */
export type StatusColorMap = {
  active: 'green'
  inactive: 'gray'
}
```

* Document the intent of utility types or generic types.

Example:

```ts
/**
 * Represents a partial object where at least one property is required.
 * Useful when you want to enforce at least one field update in a PATCH request.
 */
export type AtLeastOne<T> = {
  [K in keyof T]: Partial<T> & Pick<T, K>
}[keyof T]
```

* For complex function signatures or composables, describe the behavior and usage.

Example:

```ts
/**
 * useUser composable for loading and managing user data.
 * Fetches the user from the API and exposes reactive state.
 *
 * Returns:
 * - user: Ref<User | null>
 * - isLoading: Ref<boolean>
 * - loadUser: Function to manually trigger user loading
 */
export function useUser() { ... }
```

* If the type is temporary or will change later, leave a TODO comment.

Example:

```ts
/**
 * TODO: Replace with dynamic permissions from backend when available.
 */
export type Permissions = 'read' | 'write' | 'admin'
```

* Use JSDoc style consistently for types and functions that are exported or public. This improves editor support (tooltips, autocompletion) and helps other developers understand your code faster.

## Example

```ts
/**
 * A user in the system.
 * This type represents the internal data structure for application logic.
 * If you need to expose user data publicly, use `PublicUser`.
 */
export type User = {
  /** Unique identifier for the user (UUID). */
  id: string
  /** The user's full name. */
  name: string
  /** Email address. Must be validated before saving. */
  email: string
  /** ISO date string of when the user signed up. */
  createdAt: string
  /** Whether the user has verified their email. */
  isVerified: boolean
}
```

