TypeScript Best Practices
SkillDev toolsTypeScript strict patterns and best practices. Trigger: When writing TypeScript code - types, interfaces, generics.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the TypeScript Best Practices skill
What this skill tells your AI
The instructions your AI receives, as published by yacosta738/yacosta738.github.io in .agents/skills/typescript/SKILL.md and read by ahel’s review.
This document outlines best practices for using TypeScript in Astro and Vue projects, focusing on types, interfaces, generics, and utility types.
Const Types Pattern (REQUIRED)
// ✅ ALWAYS: Create const object first, then extract type
const STATUS = {
ACTIVE: "active",
INACTIVE: "inactive",
PENDING: "pending",
} as const;
type Status = (typeof STATUS)[keyof typeof STATUS];
// ❌ NEVER: Direct union types
type Status = "active" | "inactive" | "pending";
Why? Single source of truth, runtime values, autocomplete, easier refactoring.
Flat Interfaces (REQUIRED)
// ✅ ALWAYS: One level depth, nested objects → dedicated interface
interface UserAddress {
street: string;
city: string;
}
interface User {
id: string;
name: string;
address: UserAddress; // Reference, not inline
}
interface Admin extends User {
permissions: string[];
}
// ❌ NEVER: Inline nested objects
interface User {
address: { street: string; city: string }; // NO!
}
Never Use any
// ✅ Use unknown for truly unknown types
function parse(input: unknown): User {
if (isUser(input)) return input;
throw new Error("Invalid input");
}
// ✅ Use generics for flexible types
function first<T>(arr: T[]): T | undefined {
return arr[0];
}
// ❌ NEVER
function parse(input: any): any {
}
Utility Types
Pick<User, "id" | "name"> // Select fields
Omit<User, "id"> // Exclude fields
Partial<User> // All optional
Required<User> // All required
Readonly<User> // All readonly
Record<string, User> // Object type
Extract<Union, "a" | "b"> // Extract from union
Exclude<Union, "a"> // Exclude from union
NonNullable<T | null> // Remove null/undefined
ReturnType<typeof fn> // Function return type
Parameters<typeof fn> // Function params tuple
Examples
// Pick: select only specific fields (e.g. for form payloads, previews)
type UserPreview = Pick<User, "id" | "name">;
// { id: string; name: string }
// Omit: remove fields (e.g. hide sensitive data for public types)
type PublicUser = Omit<User, "password">;
// { id: string; name: string; ... }
// Partial: make all fields optional (e.g. update forms, patch payloads)
type UserUpdate = Partial<User>;
// { id?: string; name?: string; ... }
// Required: make all fields required (e.g. validation, strict objects)
type StrictUser = Required<User>;
// { id: string; name: string; ... }
// Readonly: prevent mutation (e.g. config, constants)
type ImmutableUser = Readonly<User>;
// { readonly id: string; ... }
// Record: dictionary/map with known value type (e.g. id → user lookup)
type UserMap = Record<string, User>;
// { [id: string]: User }
// Extract: filter union to allowed members (e.g. only certain values)
type Allowed = Extract<"a" | "b" | "c", "a" | "b">;
// "a" | "b"
// Exclude: remove members from union (e.g. blacklist values)
type NotA = Exclude<"a" | "b" | "c", "a">;
// "b" | "c"
// NonNullable: remove null/undefined (e.g. for strict values)
type Name = NonNullable<string | null | undefined>;
// string
// ReturnType: get function return type (e.g. for API responses)
function getUser(): Promise<User> { /* ... */
}
type UserPromise = ReturnType<typeof getUser>;
// Promise<User>
// Parameters: get function parameter tuple (e.g. for wrappers)
function setUser(id: string, user: User) {
}
type SetUserParams = Parameters<typeof setUser>;
// [id: string, user: User]
Type Guards
function isUser(value: unknown): value is User {
return (
typeof value === "object" &&
value !== null &&
"id" in value &&
"name" in value
);
}
Import Types
import type {User} from "./types";
import {createUser, type Config} from "./utils";
Signals
- GitHub stars
- 48
- Forks
- 7
- Last commit
- Sep 2026
- Hacker News mentions
- 20
Advanced
- Catalog kind
- skill
- Gateway key
typescript-yacosta738- Source
- github.com/yacosta738/yacosta738.github.io