From harness-claude
Derives types programmatically in TypeScript using conditional types, infer keyword, and distributive logic. Useful for extracting nested types, building utility types, and type-level branching.
npx claudepluginhub intense-visions/harness-engineering --plugin harness-claudeThis skill uses the workspace's default tool permissions.
> Use conditional types, infer, and distributive logic to derive types programmatically
Masters TypeScript advanced types including generics, conditional types, mapped types, template literals, and utility types for type-safe applications. Use for complex type logic, reusable utilities, and compile-time safety in TS projects.
Explains and applies TypeScript utility types (Partial, Required, Pick, Omit, Readonly, Record) plus mapped and conditional types for flexible, type-safe code.
Provides examples of advanced TypeScript patterns: generics with constraints, conditional types, mapped types, discriminated unions, and type guards. Useful for complex typing scenarios.
Share bugs, ideas, or general feedback.
Use conditional types, infer, and distributive logic to derive types programmatically
T extends U ? TrueType : FalseType:type IsString<T> = T extends string ? true : false;
type A = IsString<'hello'>; // true
type B = IsString<42>; // false
infer:type UnwrapPromise<T> = T extends Promise<infer U> ? U : T;
type A = UnwrapPromise<Promise<string>>; // string
type B = UnwrapPromise<number>; // number
type ArrayElement<T> = T extends (infer E)[] ? E : never;
type C = ArrayElement<string[]>; // string
type DeepUnwrap<T> = T extends Promise<infer U> ? DeepUnwrap<U> : T;
type A = DeepUnwrap<Promise<Promise<string>>>; // string
type Parameters<T> = T extends (...args: infer P) => any ? P : never;
type ReturnType<T> = T extends (...args: any) => infer R ? R : never;
type Params = Parameters<(a: string, b: number) => void>; // [string, number]
T is a union, the condition distributes over each member:type NonNullable<T> = T extends null | undefined ? never : T;
type A = NonNullable<string | null | undefined>; // string
// Distributes as: (string extends null ? never : string) | (null extends null ? never : null) | ...
type IsUnion<T> = [T] extends [T] ? false : true; // Does not distribute
infer with extends:type FirstString<T> = T extends [infer F extends string, ...any[]] ? F : never;
type A = FirstString<['hello', 42]>; // 'hello'
type B = FirstString<[42, 'hello']>; // never
type OptionalByKey<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
type User = { id: string; name: string; email: string };
type CreateUser = OptionalByKey<User, 'id'>; // id is optional, rest required
type TypeName<T> = T extends string
? 'string'
: T extends number
? 'number'
: T extends boolean
? 'boolean'
: T extends Function
? 'function'
: 'object';
Conditional types are TypeScript's mechanism for type-level computation. They enable types that depend on other types, analogous to ternary expressions at the value level.
Distribution behavior: When a conditional type is applied to a naked type parameter that is a union, it distributes — the condition is applied to each union member separately, and the results form a new union. This is usually desirable but can be surprising.
infer keyword: Only valid inside the extends clause of a conditional type. It declares a type variable that TypeScript infers from the structure being matched. You can use multiple infer keywords in one condition.
never in conditionals: A conditional branch that returns never removes that member from a union (since T | never = T). This is the mechanism behind Exclude, Extract, and NonNullable.
Recursive conditional types: TypeScript supports recursive conditional types (up to a depth limit). Use them for deep unwrapping, recursive object transformation, or path-based type extraction.
Trade-offs:
infer can only capture types at specific structural positions — it cannot pattern-match arbitrary nested typesCommon mistakes:
T extends U checks assignability, not equality — string extends string | number is truenever input — never extends anything distributes to never (empty union)infer outside of a conditional type's extends clause — it is not a standalone keywordhttps://typescriptlang.org/docs/handbook/2/conditional-types.html