Skip to main content

prefer-type-fest-union-member

Require TypeFest UnionMember<T> over custom union-member extraction helpers based on UnionToIntersection.

Targeted pattern scopeโ€‹

This rule targets exact custom helper definitions that reproduce TypeFest UnionMember<T> semantics with UnionToIntersection, distributive function wrappers, and the optional IsNever<T> guard.

What this rule reportsโ€‹

  • UnionToIntersection<T extends any ? () => T : never> extends () => infer R ? R : never
  • The guarded variant IsNever<T> extends true ? never : ...

Why this rule existsโ€‹

UnionMember<T> is the canonical TypeFest helper for extracting an arbitrary union member. Using it avoids re-declaring a brittle conditional-type helper and standardizes on the TypeFest utility name.

โŒ Incorrectโ€‹

type LastOfUnion<Union> = IsNever<Union> extends true
? never
: UnionToIntersection<Union extends any ? () => Union : never> extends () => infer Last
? Last
: never;

โœ… Correctโ€‹

import type { UnionMember } from "type-fest";

type LastOfUnion<Union> = UnionMember<Union>;

Behavior and migration notesโ€‹

  • This rule intentionally matches only exact, high-confidence helper shapes.
  • Similar custom helpers that differ structurally are ignored.
  • It will not autofix when UnionMember is shadowed in the local type scope.

Additional examplesโ€‹

โŒ Incorrect โ€” Additional exampleโ€‹

type MemberOfUnion<Union> = UnionToIntersection<Union extends any ? () => Union : never> extends () => infer Member
? Member
: never;

โœ… Correct โ€” Additional exampleโ€‹

import type { UnionMember } from "type-fest";

type MemberOfUnion<Union> = UnionMember<Union>;

โœ… Correct โ€” Non-targeted usageโ€‹

type LastOfUnion<Union> = UnionToIntersection<Union extends unknown ? () => Union : never> extends () => infer Last
? Last
: never;

ESLint flat config exampleโ€‹

import typefest from "eslint-plugin-typefest";

export default [
{
plugins: { typefest },
rules: {
"typefest/prefer-type-fest-union-member": "error",
},
},
];

When not to use itโ€‹

Disable this rule if your project intentionally keeps local helper names for compatibility or if your custom helper intentionally differs from TypeFest UnionMember<T> semantics.

Package documentationโ€‹

TypeFest package documentation:

Source file: source/union-member.d.ts

/**
Returns an arbitrary member of a union type.

Use-cases:
- Implementing recursive type functions that accept a union type.
*/
export type UnionMember<T> =
IsNever<T> extends true
? never
: UnionToIntersection<T extends any ? () => T : never> extends () => (infer R)
? R
: never;

Rule catalog ID: R081

Further readingโ€‹

Adoption resourcesโ€‹