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
Types that select one of two possible types based on a condition:
type IsString<T> = T extends string ? true : false;
type A = IsString<string>; // true
type B = IsString<number>; // false
// Useful for filtering
type NonNullable<T> = T extends null | undefined ? never : T;infer KeywordExtract types from other types:
// Extract return type from function
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : never;
type Fn = () => string;
type Result = ReturnType<Fn>; // string
// Extract array element type
type ElementType<T> = T extends (infer E)[] ? E : never;
type Items = ElementType<string[]>; // string
// Extract Promise result type
type Awaited<T> = T extends Promise<infer U> ? U : T;
type P = Awaited<Promise<string>>; // stringConditional types distribute over union types:
type ToArray<T> = T extends any ? T[] : never;
type Result = ToArray<string | number>;
// Distributes to: ToArray<string> | ToArray<number>
// Results in: string[] | number[]
// Prevent distribution with tuple wrapper
type ToArrayNonDist<T> = [T] extends [any] ? T[] : never;
type Result2 = ToArrayNonDist<string | number>;
// Results in: (string | number)[]Chain multiple conditions:
type TypeName<T> =
T extends string ? "string" :
T extends number ? "number" :
T extends boolean ? "boolean" :
T extends undefined ? "undefined" :
T extends Function ? "function" :
"object";
type A = TypeName<string>; // "string"
type B = TypeName<() => void>; // "function"// Extract function parameter types
type Parameters<T> = T extends (...args: infer P) => any ? P : never;
type Fn = (a: string, b: number) => void;
type Params = Parameters<Fn>; // [string, number]
// Extract constructor parameters
type ConstructorParameters<T> = T extends new (...args: infer P) => any
? P
: never;
class User {
constructor(name: string, age: number) {}
}
type UserParams = ConstructorParameters<typeof User>; // [string, number]type Exclude<T, U> = T extends U ? never : T;
type Extract<T, U> = T extends U ? T : never;
type Numbers = Exclude<string | number | boolean, string>; // number | boolean
type Strings = Extract<string | number | boolean, string>; // stringtype DeepReadonly<T> = {
readonly [P in keyof T]: T[P] extends object
? DeepReadonly<T[P]>
: T[P];
};
interface Config {
database: {
host: string;
port: number;
};
}
type ReadonlyConfig = DeepReadonly<Config>;
// All properties (including nested) are readonlytype Flatten<T> = T extends Array<infer U> ? U : T;
type Flat = Flatten<string[]>; // string
type NotFlat = Flatten<string>; // string// Make all parameters optional
type PartialParameters<T extends (...args: any[]) => any> =
T extends (...args: infer P) => infer R
? (...args: Partial<P>) => R
: never;
// Add error parameter to function
type WithError<T extends (...args: any[]) => any> =
T extends (...args: infer P) => infer R
? (...args: [...P, Error?]) => R
: never;type RouteParams<T extends string> =
T extends `${infer _Start}:${infer Param}/${infer Rest}`
? { [K in Param | keyof RouteParams<Rest>]: string }
: T extends `${infer _Start}:${infer Param}`
? { [K in Param]: string }
: {};
type Params = RouteParams<'/users/:userId/posts/:postId'>;
// { userId: string; postId: string }type JSONValue =
| string
| number
| boolean
| null
| JSONValue[]
| { [key: string]: JSONValue };
type JSONCompatible<T> =
T extends JSONValue ? T :
T extends { toJSON(): infer U } ? U :
never;infer to extract type informationnever in conditional typesinfer placement in different contextsInstall with Tessl CLI
npx tessl i pantheon-ai/typescript-advancedreferences