prefer-type-fest-conditional-except
Prefer ConditionalExcept from type-fest over Except<Base, ConditionalKeys<Base, Condition>> compositions.
This rule lives only in the experimental preset and reports without autofixing.
Targeted pattern scopeโ
This rule focuses on direct type-fest compositions that already use both Except and ConditionalKeys together.
Except<Base, ConditionalKeys<Base, Condition>>- the same shape when
ExceptandConditionalKeysare imported under local aliases fromtype-fest
It intentionally skips builtin Omit<Base, ConditionalKeys<Base, Condition>> shapes to avoid overlapping with the stable prefer-type-fest-except rule.
What this rule reportsโ
This rule reports type-fest compositions when all of the following are true:
- the outer type reference resolves to
Except - the second type argument resolves to
ConditionalKeys - the base type passed to
Exceptmatches the base type passed toConditionalKeys
The rule is currently report-only. It does not autofix or suggest a replacement yet.
Why this rule existsโ
ConditionalExcept<Base, Condition> expresses the intent of conditional omission directly.
- Readers do not need to mentally expand two helper types to understand the result.
- The single helper form is shorter and easier to scan in large type aliases.
- The intent stays aligned with the upstream Type-Fest utility that already models this exact composition.
โ Incorrectโ
import type {ConditionalKeys, Except} from "type-fest";
type Example = {
count: number;
enabled: boolean;
name: string;
};
type NonStrings = Except<Example, ConditionalKeys<Example, string>>;
โ Correctโ
import type {ConditionalExcept} from "type-fest";
type Example = {
count: number;
enabled: boolean;
name: string;
};
type NonStrings = ConditionalExcept<Example, string>;
Behavior and migration notesโ
- This rule only reports the direct
Except<..., ConditionalKeys<...>>composition. - It ignores builtin
Omitforms on purpose to avoid duplicate reporting withprefer-type-fest-except. - It ignores compositions where the
ConditionalKeysbase type does not exactly match theExceptbase type.
Additional examplesโ
โ Incorrect โ Additional exampleโ
import type {ConditionalKeys as MatchingKeys, Except as StrictExcept} from "type-fest";
type Example = {
count: number;
enabled: boolean;
name: string;
};
type NonStrings = StrictExcept<Example, MatchingKeys<Example, string>>;
โ Correct โ Additional exampleโ
import type {ConditionalExcept} from "type-fest";
type Example = {
count: number;
enabled: boolean;
name: string;
};
type NonStrings = ConditionalExcept<Example, string>;
ESLint flat config exampleโ
import typefest from "eslint-plugin-typefest";
export default [typefest.configs.experimental];
When not to use itโ
Disable this rule if your team prefers explicit helper-type composition over the shorter canonical alias, or if you want Except and ConditionalKeys to stay visible for teaching purposes.
Package documentationโ
TypeFest package documentation:
Source file: source/conditional-except.d.ts
import type {ConditionalExcept} from "type-fest";
type Example = {
a: string;
b: string | number;
c: () => void;
};
type NonStringKeysOnly = ConditionalExcept<Example, string>;
//=> {b: string | number; c: () => void}
Rule catalog ID: R087