UNPKG

python-to-typescript-porting-mcp-server

Version:

Comprehensive MCP server providing systematic tools and references for Python-to-TypeScript porting with real-world examples

431 lines (348 loc) 10.8 kB
export const TYPING_EXAMPLES = { "python-typing-to-typescript": { title: "🏷️ Python Type System to TypeScript Mapping", content: `# Python Type System to TypeScript Mapping ## Overview Comprehensive mapping of Python's typing system to TypeScript equivalents, covering Python 3.9+ union operators, generics, and advanced typing patterns from real-world codebases. ## Core Type Mappings ### Python 3.9+ Union Syntax \`\`\`python # Python 3.9+ Union Operators → TypeScript from typing import Union, Optional, Literal, Final, TypeAlias from datetime import datetime from uuid import UUID # Union types (Python 3.9+) StringOrNumber = str | int OptionalString = str | None # Preferred over Optional[str] MultiUnion = str | int | float | None # Complex union patterns ResponseData = dict[str, str | int | list[str]] DatabaseId = int | str | UUID StatusCode = Literal[200, 404, 500] | int \`\`\` \`\`\`typescript // TypeScript equivalents - direct mapping type StringOrNumber = string | number; type OptionalString = string | null; type MultiUnion = string | number | number | null; // Complex union patterns type ResponseData = Record<string, string | number | string[]>; type DatabaseId = number | string; // UUID becomes string in TS type StatusCode = 200 | 404 | 500 | number; \`\`\` ### Generic Collections \`\`\`python # Python generics → TypeScript from typing import Dict, List, Set, Tuple, Any # Built-in generics (Python 3.9+) user_names: list[str] = ["alice", "bob"] user_scores: dict[str, int] = {"alice": 95, "bob": 87} unique_ids: set[int] = {1, 2, 3} coordinates: tuple[float, float] = (10.5, 20.3) # Nested generics user_groups: dict[str, list[str]] = { "admins": ["alice"], "users": ["bob", "charlie"] } # Complex nested structures api_responses: dict[str, dict[str, list[dict[str, str | int]]]] = {} \`\`\` \`\`\`typescript // TypeScript equivalents const userNames: string[] = ["alice", "bob"]; const userScores: Record<string, number> = { alice: 95, bob: 87 }; const uniqueIds: Set<number> = new Set([1, 2, 3]); const coordinates: [number, number] = [10.5, 20.3]; // Tuple // Nested generics const userGroups: Record<string, string[]> = { admins: ["alice"], users: ["bob", "charlie"] }; // Complex nested structures const apiResponses: Record<string, Record<string, Record<string, string | number>[]>> = {}; \`\`\` ### Literal Types and Enums \`\`\`python # Python Literal and Enum → TypeScript from typing import Literal from enum import Enum, StrEnum # Literal types HttpMethod = Literal["GET", "POST", "PUT", "DELETE"] LogLevel = Literal["DEBUG", "INFO", "WARNING", "ERROR"] BooleanLiteral = Literal[True, False] # Special case # String Enums (Python 3.11+) class UserRole(StrEnum): ADMIN = "admin" USER = "user" GUEST = "guest" # Regular Enums class StatusCode(Enum): SUCCESS = 200 NOT_FOUND = 404 SERVER_ERROR = 500 # Combining literals with unions Response = Literal["success"] | Literal["error"] | dict[str, str] \`\`\` \`\`\`typescript // TypeScript literal types - preferred approach type HttpMethod = "GET" | "POST" | "PUT" | "DELETE"; type LogLevel = "DEBUG" | "INFO" | "WARNING" | "ERROR"; type BooleanLiteral = true | false; // More explicit than boolean // Enum alternatives in TypeScript // Option 1: Union of literals (recommended) type UserRole = "admin" | "user" | "guest"; // Option 2: Const assertions const UserRole = { ADMIN: "admin", USER: "user", GUEST: "guest" } as const; type UserRole = typeof UserRole[keyof typeof UserRole]; // Option 3: Traditional enum (use sparingly) enum StatusCode { SUCCESS = 200, NOT_FOUND = 404, SERVER_ERROR = 500 } // Combining with unions type Response = "success" | "error" | Record<string, string>; \`\`\` ## Advanced Typing Patterns ### TypedDict to Interfaces \`\`\`python # Python TypedDict → TypeScript interface from typing import TypedDict, NotRequired, Required class User(TypedDict): id: int name: str email: str is_active: bool metadata: NotRequired[dict[str, str | int]] # Optional field class UserWithRequiredMeta(TypedDict): id: int name: str metadata: Required[dict[str, str]] # Explicitly required # Inheritance class AdminUser(User): permissions: list[str] access_level: Literal["admin", "superadmin"] # Total=False for all optional fields class PartialUser(TypedDict, total=False): name: str email: str phone: str \`\`\` \`\`\`typescript // TypeScript interface equivalents interface User { id: number; name: string; email: string; is_active: boolean; metadata?: Record<string, string | number>; // Optional with ? } interface UserWithRequiredMeta { id: number; name: string; metadata: Record<string, string>; // Required (no ?) } // Inheritance with extends interface AdminUser extends User { permissions: string[]; access_level: "admin" | "superadmin"; } // Partial utility type for all optional interface PartialUser { name?: string; email?: string; phone?: string; } // Or use built-in Partial<T> type PartialUserAlt = Partial<Pick<User, 'name' | 'email'>> & { phone?: string; }; \`\`\` ### Protocols and Structural Typing \`\`\`python # Python Protocols → TypeScript interfaces from typing import Protocol, runtime_checkable @runtime_checkable class Drawable(Protocol): def draw(self) -> None: ... def get_area(self) -> float: ... class Serializable(Protocol): def to_json(self) -> str: ... def from_json(self, data: str) -> None: ... # Generic protocols from typing import TypeVar T = TypeVar('T') class Repository(Protocol[T]): def save(self, entity: T) -> T: ... def find_by_id(self, id: int) -> T | None: ... def find_all(self) -> list[T]: ... # Using protocols def render_shape(shape: Drawable) -> None: shape.draw() print(f"Area: {shape.get_area()}") \`\`\` \`\`\`typescript // TypeScript structural interfaces (protocols equivalent) interface Drawable { draw(): void; getArea(): number; // snake_case → camelCase } interface Serializable { toJson(): string; fromJson(data: string): void; } // Generic interfaces interface Repository<T> { save(entity: T): T; findById(id: number): T | null; findAll(): T[]; } // Structural typing works automatically function renderShape(shape: Drawable): void { shape.draw(); console.log(\`Area: \${shape.getArea()}\`); } // Any object with the right shape works const circle = { draw: () => console.log("Drawing circle"), getArea: () => Math.PI * 5 * 5 }; renderShape(circle); // ✅ Works due to structural typing \`\`\` ## Modern Python → TypeScript Patterns ### dataclass to interface/type \`\`\`python # Python dataclass → TypeScript from dataclasses import dataclass, field from typing import ClassVar, InitVar @dataclass class Product: id: int name: str price: float category: str = "general" tags: list[str] = field(default_factory=list) # Class variables tax_rate: ClassVar[float] = 0.1 # Init-only variable currency: InitVar[str] = "USD" def __post_init__(self, currency: str) -> None: if currency == "EUR": self.price *= 1.1 # Convert from EUR @dataclass(frozen=True) # Immutable class ImmutableProduct: id: int name: str price: float \`\`\` \`\`\`typescript // TypeScript equivalent patterns interface Product { id: number; name: string; price: number; category: string; // Default handled in factory/constructor tags: string[]; // Default handled in factory/constructor } // Factory function for defaults (replacing __init__) function createProduct( id: number, name: string, price: number, options: { category?: string; tags?: string[]; currency?: string; } = {} ): Product { const { category = "general", tags = [], currency = "USD" } = options; // Post-init logic let adjustedPrice = price; if (currency === "EUR") { adjustedPrice *= 1.1; } return { id, name, price: adjustedPrice, category, tags: [...tags] // Defensive copy }; } // Class constants (ClassVar equivalent) const PRODUCT_TAX_RATE = 0.1; // Immutable type (frozen=True equivalent) type ImmutableProduct = Readonly<{ id: number; name: string; price: number; }>; // Or with readonly properties interface ImmutableProductInterface { readonly id: number; readonly name: string; readonly price: number; } \`\`\` ## Conversion Decision Matrix | Python Pattern | TypeScript Equivalent | When to Use | |----------------|----------------------|-------------| | \`str \| int\` | \`string \| number\` | Always prefer for Python 3.9+ | | \`Optional[T]\` | \`T \| null\` | Legacy code, use \`T \| null\` instead | | \`List[T]\` | \`T[]\` | Built-in arrays | | \`Dict[K, V]\` | \`Record<K, V>\` | Simple key-value mappings | | \`TypedDict\` | \`interface\` | Structured objects | | \`Protocol\` | \`interface\` | Structural typing | | \`Literal[...]\` | \`"..." \| ...\` | Exact value constraints | | \`Enum\` | Union of literals | Type safety over runtime behavior | | \`dataclass\` | \`interface + factory\` | Data structures with logic | | \`NamedTuple\` | \`type [..., ...]\` | Fixed-length tuples | ## Mypy to TypeScript Best Practices ### 1. Strict Mode Equivalence \`\`\`python # Python mypy strict mode # mypy: strict = True from typing import Any, Never def process_data(data: Any) -> Never: # Never for impossible returns raise NotImplementedError("Not implemented") \`\`\` \`\`\`typescript // TypeScript strict mode equivalent // tsconfig.json: "strict": true function processData(data: unknown): never { // unknown over any, never for impossible throw new Error("Not implemented"); } \`\`\` ### 2. Type Narrowing Patterns \`\`\`python # Python type narrowing from typing import Union, TypeGuard def is_string(value: Union[str, int]) -> TypeGuard[str]: return isinstance(value, str) def process_value(value: Union[str, int]) -> str: if is_string(value): return value.upper() # mypy knows this is str return str(value) \`\`\` \`\`\`typescript // TypeScript type narrowing function isString(value: string | number): value is string { return typeof value === "string"; } function processValue(value: string | number): string { if (isString(value)) { return value.toUpperCase(); // TS knows this is string } return String(value); } \`\`\` This mapping covers the essential patterns found in production Python codebases and their TypeScript equivalents, ensuring type safety is maintained across the conversion.`, tags: ["typing", "mypy", "type-safety", "type-system", "advanced"], language: "typescript" } }; //# sourceMappingURL=typing-examples.js.map