Skip to main content

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 use not(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 use not(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 filter callbacks.
  • 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.
*
* @category Type guard
*
* @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
*/

Rule catalog ID: R025

Further readingโ€‹

Adoption resourcesโ€‹