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...
- I have searched for related issues and found none that match my proposal.
- I have searched the current rule list and found no rules that match my proposal.
- I have read the FAQ and my problem is not listed.
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:
const x = [1, 2, null].filter((x): x is number => x == null);Fail Cases
const x = [1, 2, null].filter((x): boolean => x != null);Pass Cases
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