prefer-ts-extras-not
Require not from ts-extras over inline negated predicate callbacks in filter calls.
Targeted pattern scopeโ
This rule focuses on direct .filter(...) callbacks that negate a predicate and can be migrated to not(predicate) with deterministic fixes.
- Inline negated predicate callbacks in
.filter(...)that can usenot(predicate). array.filter((value) => !predicate(value))
Alias indirection, wrapper helpers, and non-canonical call shapes are excluded to keep not(predicate) migrations safe.
What this rule reportsโ
This rule reports .filter(...) call sites when not(predicate) is the intended replacement.
- Inline negated predicate callbacks in
.filter(...)that can usenot(predicate). array.filter((value) => !predicate(value))
Why this rule existsโ
not(predicate) communicates intent directly and preserves predicate-based typing in a reusable helper.
โ Incorrectโ
const activeUsers = users.filter((user) => !isArchived(user));
โ Correctโ
const activeUsers = users.filter(not(isArchived));
Behavior and migration notesโ
not(predicate)preserves predicate inversion intent in one reusable helper.- This rule targets inline negation wrappers inside
filtercallbacks. - Callbacks that do extra work beyond predicate negation should be reviewed manually.
Additional examplesโ
โ Incorrect โ Additional exampleโ
const active = users.filter((user) => !isArchived(user));
โ Correct โ Additional exampleโ
const active = users.filter(not(isArchived));
โ Correct โ Repository-wide usageโ
const nonEmpty = values.filter(not(isEmptyValue));
ESLint flat config exampleโ
import typefest from "eslint-plugin-typefest";
export default [
{
plugins: { typefest },
rules: {
"typefest/prefer-ts-extras-not": "error",
},
},
];
When not to use itโ
Disable this rule if your codebase requires explicit inline callback bodies for readability.
Package documentationโ
ts-extras package documentation:
Source file: source/not.ts
/**
Invert a type predicate function.
This utility allows you to create the inverse of any type guard function, using TypeScript's `Exclude` utility type to properly narrow types.
@example
```
import {not} from 'ts-extras';
const isNullish = (value: unknown): value is null | undefined => value == null;
const isNotNullish = not(isNullish);
const values = [1, null, 2, undefined, 3];
const defined = values.filter(isNotNullish);
//=> [1, 2, 3]
// with type number[]
// Works with any type guard
const isString = (value: unknown): value is string => typeof value === 'string';
const isNotString = not(isString);
declare const mixedValue: string | number | boolean;
if (isNotString(mixedValue)) {
mixedValue;
//=> number | boolean
}
```
@note TypeScript may fail to narrow types in nested branches, with mutated variables, or when using `Exclude` with complex union types. See:
- https://github.com/microsoft/TypeScript/issues/44901
- https://github.com/microsoft/TypeScript/issues/43589
@category Type guard
*/
Rule catalog ID: R025