ワンクリックで
typescript
TypeScript best practices and patterns. Use for type definitions, generics, utility types, and advanced TypeScript features.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
TypeScript best practices and patterns. Use for type definitions, generics, utility types, and advanced TypeScript features.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
RESTful API design best practices. Use when designing endpoints, request/response schemas, error handling, and API versioning.
Perform thorough code reviews with security, performance, and quality checks. Use when reviewing PRs, auditing code changes, or finding potential bugs.
Database design and optimization. Use for schema design, queries, migrations, indexing, and performance tuning.
Systematic debugging methodology for finding and fixing bugs. Use when investigating issues, tracing errors, or fixing production problems.
Docker and containerization best practices. Use for Dockerfile creation, docker-compose, multi-stage builds, and container optimization.
Technical documentation best practices. Use for writing READMEs, API docs, code comments, and project documentation.
| name | typescript |
| description | TypeScript best practices and patterns. Use for type definitions, generics, utility types, and advanced TypeScript features. |
TypeScript patterns, type safety, and best practices for frontend and backend development.
// Interface: Prefer for object shapes, can be extended
interface User {
id: string;
name: string;
email: string;
}
interface AdminUser extends User {
role: 'admin';
permissions: string[];
}
// Type: Prefer for unions, tuples, primitives
type Status = 'pending' | 'active' | 'inactive';
type Result<T> = { success: true; data: T } | { success: false; error: string };
type Coordinates = [number, number];
// ✅ Good: Explicit types
interface ApiResponse<T> {
success: boolean;
data: T;
meta: {
page: number;
total: number;
};
}
// ✅ Good: Const assertions for literals
const CONFIG = {
apiUrl: 'https://api.example.com',
timeout: 5000,
} as const;
// ❌ Bad: Using `any`
function processData(data: any) { }
// ✅ Good: Use `unknown` and type guards
function processData(data: unknown) {
if (isValidData(data)) {
// data is now typed
}
}
// Generic function
function first<T>(arr: T[]): T | undefined {
return arr[0];
}
// Generic interface
interface Repository<T> {
findById(id: string): Promise<T | null>;
findAll(): Promise<T[]>;
create(item: Omit<T, 'id'>): Promise<T>;
update(id: string, item: Partial<T>): Promise<T>;
delete(id: string): Promise<void>;
}
// Generic class
class ApiClient<T> {
constructor(private baseUrl: string) {}
async get(endpoint: string): Promise<T> {
const res = await fetch(`${this.baseUrl}${endpoint}`);
return res.json();
}
}
// Constrain to specific shape
interface HasId {
id: string;
}
function findById<T extends HasId>(items: T[], id: string): T | undefined {
return items.find(item => item.id === id);
}
// Multiple constraints
function merge<T extends object, U extends object>(a: T, b: U): T & U {
return { ...a, ...b };
}
// Pick specific keys
type UserPreview = Pick<User, 'id' | 'name'>;
// Omit specific keys
type CreateUserInput = Omit<User, 'id' | 'createdAt'>;
// Make all properties optional
type PartialUser = Partial<User>;
// Make all properties required
type RequiredUser = Required<User>;
// Make all properties readonly
type ReadonlyUser = Readonly<User>;
// Record type
type UserRoles = Record<string, 'admin' | 'user' | 'guest'>;
interface Cat {
type: 'cat';
meow(): void;
}
interface Dog {
type: 'dog';
bark(): void;
}
type Animal = Cat | Dog;
// Type predicate
function isCat(animal: Animal): animal is Cat {
return animal.type === 'cat';
}
function handleAnimal(animal: Animal) {
if (isCat(animal)) {
animal.meow(); // TypeScript knows it's Cat
} else {
animal.bark(); // TypeScript knows it's Dog
}
}
type Result<T, E = Error> =
| { success: true; data: T }
| { success: false; error: E };
function handleResult<T>(result: Result<T>) {
if (result.success) {
console.log(result.data); // T
} else {
console.error(result.error); // Error
}
}
function assertDefined<T>(value: T | null | undefined): asserts value is T {
if (value === null || value === undefined) {
throw new Error('Value must be defined');
}
}
function processUser(user: User | null) {
assertDefined(user);
// user is now User, not User | null
console.log(user.name);
}
// Make all properties nullable
type Nullable<T> = {
[K in keyof T]: T[K] | null;
};
// Make all properties promises
type Async<T> = {
[K in keyof T]: Promise<T[K]>;
};
// Prefix all keys
type Prefixed<T, P extends string> = {
[K in keyof T as `${P}${string & K}`]: T[K];
};
type PrefixedUser = Prefixed<User, 'user_'>;
// { user_id: string; user_name: string; user_email: string }
// Extract array element type
type ArrayElement<T> = T extends (infer E)[] ? E : never;
type StringArray = string[];
type Element = ArrayElement<StringArray>; // string
// Exclude null/undefined
type NonNullable<T> = T extends null | undefined ? never : T;
// Function return type
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : never;
type EventName = 'click' | 'focus' | 'blur';
type EventHandler = `on${Capitalize<EventName>}`;
// 'onClick' | 'onFocus' | 'onBlur'
type HttpMethod = 'get' | 'post' | 'put' | 'delete';
type Endpoint = `/${string}`;
type Route = `${Uppercase<HttpMethod>} ${Endpoint}`;
// 'GET /...' | 'POST /...' | ...
interface ButtonProps {
variant?: 'primary' | 'secondary' | 'ghost';
size?: 'sm' | 'md' | 'lg';
loading?: boolean;
disabled?: boolean;
onClick?: () => void;
children: React.ReactNode;
}
// With HTML attributes
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
variant?: 'primary' | 'secondary';
loading?: boolean;
}
export function Button({
variant = 'primary',
loading,
children,
...props
}: ButtonProps) {
return (
<button disabled={loading} {...props}>
{loading ? <Spinner /> : children}
</button>
);
}
interface ListProps<T> {
items: T[];
renderItem: (item: T) => React.ReactNode;
keyExtractor: (item: T) => string;
}
export function List<T>({ items, renderItem, keyExtractor }: ListProps<T>) {
return (
<ul>
{items.map(item => (
<li key={keyExtractor(item)}>{renderItem(item)}</li>
))}
</ul>
);
}
// Usage
<List
items={users}
renderItem={user => <span>{user.name}</span>}
keyExtractor={user => user.id}
/>
// useState with complex type
const [user, setUser] = useState<User | null>(null);
// useReducer
type Action =
| { type: 'SET_USER'; payload: User }
| { type: 'LOGOUT' };
function reducer(state: State, action: Action): State {
switch (action.type) {
case 'SET_USER':
return { ...state, user: action.payload };
case 'LOGOUT':
return { ...state, user: null };
}
}
// Custom hook return type
function useUser(): {
user: User | null;
loading: boolean;
login: (credentials: Credentials) => Promise<void>;
logout: () => void;
} {
// ...
}
// tsconfig.json
{
"compilerOptions": {
"strict": true,
"noImplicitAny": true,
"strictNullChecks": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedIndexedAccess": true,
"exactOptionalPropertyTypes": true
}
}