Rule proposal: prevent an explicit `: boolean` return type annotation if a predicate return type could be inferred

Author: bradzacherCreated Aug 9, 2024Updated Sep 16, 2026
Labelspackage: eslint-pluginenhancement: new plugin ruleaccepting prs

Before You File a Proposal Please Confirm You Have Done The Following...

My proposal is suitable for this project

  • My proposal specifically checks TypeScript syntax, or it proposes a check that requires type information to be accurate.
  • My proposal is not a "formatting rule"; meaning it does not just enforce how code is formatted (whitespace, brace placement, etc).
  • I believe my proposal would be useful to the broader TypeScript community (meaning it is not a niche proposal).

Description

TS 5.5 introduced Inferred Type Predicates. TS will try to infer a predicate return type if:

  • The function does not have an explicit return type or type predicate annotation.
  • The function has a single return statement and no implicit returns.
  • The function does not mutate its parameter.
  • The function returns a boolean expression that’s tied to a refinement on the parameter.

The first point is the kicker -- a lot of people (us included) annotate return types explicitly. Or they'll annotate their own predicates.

We should introduce a rule that warns if:

  • the function matches the other 3 conditions
  • the function has an explicit return type

This would allow people to lean on TS's inference for much safer code -- explicit type predicates are horridly unsound! TS only enforces that the predicate is assignable to the variable's original type -- not that the predicate is correct.

For example this code is TS valid but it is WILDLY incorrect and will crash at runtime:

typescript
const x = [1, 2, null].filter((x): x is number => x == null);

Fail Cases

typescript
const x = [1, 2, null].filter((x): boolean => x != null);

Pass Cases

typescript
const x = [1, 2, null].filter(x => x != null);

// perhaps configurable to allow this?
// by default inferring the predicate would probably be better as it's more type safe
const x = [1, 2, null].filter((x): x is NonNullable<typeof x> => x != null);

Additional Info

No response

Source: typescript-eslint/typescript-eslint