Agent skill
typescript-strict
TypeScript strict mode patterns with interfaces, type guards, generics, and utility types. Use when defining types, creating type-safe functions, handling nullable values, or implementing generic components.
Install this agent skill to your Project
npx add-skill https://github.com/canatufkansu/claude-skills/tree/main/typescript-strict
SKILL.md
TypeScript Strict Patterns
Strict Configuration
// tsconfig.json essentials
{
"compilerOptions": {
"strict": true,
"noUncheckedIndexedAccess": true,
"exactOptionalPropertyTypes": true
}
}
Interface vs Type
// Use interface for objects that may be extended
interface Service {
slug: string;
name: string;
price: number;
}
interface PremiumService extends Service {
benefits: string[];
}
// Use type for unions, primitives, tuples
type Locale = 'pt-PT' | 'en' | 'tr' | 'es' | 'fr' | 'de';
type DeliveryMode = 'in-person' | 'online' | 'both';
type Coordinates = [number, number];
Type Guards
// Custom type guard
function isService(value: unknown): value is Service {
return (
typeof value === 'object' &&
value !== null &&
'slug' in value &&
'name' in value
);
}
// Discriminated unions
type Result<T> =
| { success: true; data: T }
| { success: false; error: string };
function handleResult<T>(result: Result<T>) {
if (result.success) {
console.log(result.data); // TypeScript knows data exists
} else {
console.error(result.error); // TypeScript knows error exists
}
}
Generic Patterns
// Generic data fetcher
async function fetchData<T>(url: string): Promise<T> {
const res = await fetch(url);
if (!res.ok) throw new Error('Failed to fetch');
return res.json() as Promise<T>;
}
// Generic component props
interface ListProps<T> {
items: T[];
renderItem: (item: T, index: number) => React.ReactNode;
keyExtractor: (item: T) => string;
}
function List<T>({ items, renderItem, keyExtractor }: ListProps<T>) {
return (
<ul>
{items.map((item, i) => (
<li key={keyExtractor(item)}>{renderItem(item, i)}</li>
))}
</ul>
);
}
Utility Types
// Partial - all properties optional
type ServiceUpdate = Partial<Service>;
// Required - all properties required
type RequiredService = Required<Service>;
// Pick - select specific properties
type ServicePreview = Pick<Service, 'slug' | 'name'>;
// Omit - exclude properties
type ServiceWithoutPrice = Omit<Service, 'price'>;
// Record - key-value mapping
type LocaleMessages = Record<Locale, Record<string, string>>;
// Extract/Exclude for unions
type OnlineDelivery = Extract<DeliveryMode, 'online' | 'both'>;
Nullable Handling
// Non-null assertion (use sparingly)
const element = document.getElementById('root')!;
// Optional chaining + nullish coalescing
const name = user?.profile?.name ?? 'Anonymous';
// Type narrowing
function processValue(value: string | null | undefined) {
if (value == null) return; // Handles both null and undefined
console.log(value.toUpperCase()); // value is string
}
Component Props Patterns
// Props with children
interface ContainerProps {
children: React.ReactNode;
className?: string;
}
// Props extending HTML elements
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
variant?: 'primary' | 'secondary';
loading?: boolean;
}
// Polymorphic component
interface BoxProps<T extends React.ElementType> {
as?: T;
children: React.ReactNode;
}
type BoxPropsWithRef<T extends React.ElementType> = BoxProps<T> &
Omit<React.ComponentPropsWithoutRef<T>, keyof BoxProps<T>>;
Const Assertions
// Immutable arrays and objects
const LOCALES = ['pt-PT', 'en', 'tr', 'es', 'fr', 'de'] as const;
type Locale = typeof LOCALES[number]; // 'pt-PT' | 'en' | ...
const THEME_CONFIG = {
studio: { bg: '#ffffff', accent: '#000000' },
earth: { bg: '#faf9f6', accent: '#8b7355' },
} as const;
Zod Integration
import { z } from 'zod';
// Infer types from Zod schemas
const ServiceSchema = z.object({
slug: z.string(),
name: z.string(),
price: z.number().positive(),
});
type Service = z.infer<typeof ServiceSchema>;
Recommended Agent Skills
Expand your agent's capabilities with these related and highly-rated skills.
framer-motion-animations
Subtle animation patterns for hero sections, card reveals, page transitions, and scroll-triggered effects using Framer Motion. Use when adding animations to components, implementing scroll effects, or creating page transitions.
json-content-management
JSON-driven content architecture for services, programmes, FAQs, testimonials, and policies with TypeScript interfaces and locale-aware data fetching. Use when defining content schemas, creating data utilities, adding new content types, or fetching localized business data.
accessibility-a11y
Semantic HTML, keyboard navigation, focus states, ARIA labels, skip links, and WCAG contrast requirements. Use when ensuring accessibility compliance, implementing keyboard navigation, or adding screen reader support.
email-resend
Email sending via Resend API for contact forms and booking requests with locale-aware templates. Use when implementing email notifications, contact form submissions, or transactional emails.
nextjs-app-router
Next.js 15 App Router patterns for Server/Client Components, async params, layouts, route handlers, Server Actions, and data fetching. Use when creating routes, pages, layouts, API endpoints, or implementing form submissions with revalidation.
zod-react-hook-form
Form validation combining Zod schemas with React Hook Form, including localized error messages, Server Action integration, and shadcn/ui Form components. Use when building forms, validating user input, handling form submissions, or implementing Server Actions with validation.
Didn't find tool you were looking for?