Comprehensive TypeScript guidance covering compiler configuration, advanced types, utility types, type guards, strict mode workflows, and documentation patterns; use when configuring tsconfig, designing complex generics, making illegal states unrepresentable, fixing type errors, or writing testable and maintainable type-safe APIs.
Overall
score
99%
Does it follow best practices?
Validation for skill structure
Branded types (nominal types) create distinct types from primitives using unique symbols or phantom types, preventing accidental mixing of semantically different values with the same underlying type.
type Brand<K, T> = K & { __brand: T };
type UserId = Brand<number, "UserId">;
type ProductId = Brand<number, "ProductId">;
function createUserId(id: number): UserId {
return id as UserId;
}
function createProductId(id: number): ProductId {
return id as ProductId;
}
function getUser(id: UserId) { /* ... */ }
function getProduct(id: ProductId) { /* ... */ }
const userId = createUserId(42);
const productId = createProductId(42);
getUser(userId); // ✓ OK
getUser(productId); // ✗ Error: ProductId not assignable to UserIdtype Email = Brand<string, "Email">;
function isValidEmail(value: string): value is Email {
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value);
}
function createEmail(value: string): Email {
if (!isValidEmail(value)) {
throw new Error("Invalid email format");
}
return value;
}
function sendEmail(to: Email, subject: string, body: string) {
// Guaranteed to be valid email
console.log(`Sending to ${to}: ${subject}`);
}
const email = createEmail("alice@example.com");
sendEmail(email, "Hello", "...");
// sendEmail("invalid", "Hello", "..."); // ✗ Error: string not assignable to Emailtype URL = Brand<string, "URL">;
type SecureURL = Brand<URL, "Secure">;
function createURL(value: string): URL {
try {
new globalThis.URL(value);
return value as URL;
} catch {
throw new Error("Invalid URL");
}
}
function createSecureURL(value: URL): SecureURL {
if (!value.startsWith("https://")) {
throw new Error("URL must be secure (https)");
}
return value as SecureURL;
}
function fetchSecure(url: SecureURL) {
// Guaranteed to be valid and secure
return fetch(url);
}
const url = createURL("https://example.com");
const secureUrl = createSecureURL(url);
fetchSecure(secureUrl);type PositiveNumber = Brand<number, "Positive">;
type Integer = Brand<number, "Integer">;
type PositiveInteger = Brand<PositiveNumber, "Integer">;
function isPositive(n: number): n is PositiveNumber {
return n > 0;
}
function isInteger(n: number): n is Integer {
return Number.isInteger(n);
}
function createPositiveInteger(n: number): PositiveInteger {
if (!isPositive(n) || !isInteger(n)) {
throw new Error("Must be a positive integer");
}
return n as PositiveInteger;
}
function repeat<T>(item: T, times: PositiveInteger): T[] {
return Array.from({ length: times }, () => item);
}
const count = createPositiveInteger(5);
repeat("hello", count); // ✓ OK
// repeat("hello", 3.5); // ✗ Error: number not assignable to PositiveIntegerconst UserIdSymbol = Symbol("UserId");
const ProductIdSymbol = Symbol("ProductId");
type UserId = number & { [UserIdSymbol]: true };
type ProductId = number & { [ProductIdSymbol]: true };
function createUserId(id: number): UserId {
return id as UserId;
}
function createProductId(id: number): ProductId {
return id as ProductId;
}
// Symbols ensure brands are truly unique
const userId = createUserId(42);
const productId = createProductId(42);
function getUserName(id: UserId): string {
return `User ${id}`;
}
getUserName(userId); // ✓ OK
// getUserName(productId); // ✗ Error: ProductId not assignable to UserIdtype Brand<K, T> = K & { __brand: T };
type Unbrand<T> = T extends Brand<infer K, any> ? K : T;
type UserId = Brand<number, "UserId">;
type UnbrandedUserId = Unbrand<UserId>; // number
function unwrap<T>(value: Brand<T, any>): T {
return value as T;
}
const userId = 42 as UserId;
const rawId: number = unwrap(userId);type CustomerId = Brand<string, "CustomerId">;
type OrderId = Brand<string, "OrderId">;
type Money = Brand<number, "Money">;
interface Order {
id: OrderId;
customerId: CustomerId;
total: Money;
}
function createOrder(
customerId: CustomerId,
total: Money
): Order {
return {
id: crypto.randomUUID() as OrderId,
customerId,
total
};
}
function chargeCust omer(id: CustomerId, amount: Money) {
// Type safety ensures correct IDs and amounts
console.log(`Charging customer ${id}: $${amount}`);
}
const customerId = "cust_123" as CustomerId;
const total = 99.99 as Money;
const order = createOrder(customerId, total);
chargeCustomer(order.customerId, order.total); // ✓ OK
// chargeCustomer(order.id, order.total); // ✗ Error: OrderId not assignable to CustomerIdtype NonEmptyString = Brand<string, "NonEmpty">;
function isNonEmpty(value: string): value is NonEmptyString {
return value.trim().length > 0;
}
function assertNonEmpty(value: string): asserts value is NonEmptyString {
if (!isNonEmpty(value)) {
throw new Error("String must not be empty");
}
}
function greet(name: NonEmptyString) {
console.log(`Hello, ${name}!`);
}
const input = "Alice";
if (isNonEmpty(input)) {
greet(input); // ✓ OK - narrowed to NonEmptyString
}
const input2 = "Bob";
assertNonEmpty(input2);
greet(input2); // ✓ OK - asserted as NonEmptyStringInstall with Tessl CLI
npx tessl i pantheon-ai/typescript-advancedreferences