prefer-ts-extras-is-property-present
Require isPropertyPresent from ts-extras in Array.prototype.filter callbacks instead of inline property-nullish checks.
Targeted pattern scopeโ
This rule only inspects inline .filter(...) predicates that perform an explicit loose-null check against a single object property.
- Inline property-nullish predicates inside
.filter(...), including:filter((item) => item.prop != null)filter((item) => null != item.prop)
Named predicate references, multi-argument callbacks, and stricter equality checks are not matched.
What this rule reportsโ
This rule reports inline filter predicates that check whether a single object property is not null (using loose equality, which also catches undefined) and can be normalized with isPropertyPresent.
Why this rule existsโ
filter(isPropertyPresent('prop')) is the canonical ts-extras pattern for filtering out items where a specific property is null or undefined.
- Filtering logic is consistent and composable across collections.
- The property key is explicit in the function call, not embedded inside a callback expression.
- Repeated inline
!= nullcallback expressions are removed. isPropertyPresentis a proper type predicate that narrows element types in the resulting array to exclude bothnullandundefined.
โ Incorrectโ
const titled = posts.filter((post) => post.title != null);
โ Correctโ
import { isPropertyPresent } from "ts-extras";
const titled = posts.filter(isPropertyPresent("title"));
Behavior and migration notesโ
isPropertyPresent('prop')checksitem[prop] != null, which istruewhen the value is neithernullnorundefined.- The autofix preserves the property name as a string literal.
- Strict null checks (e.g.,
post.title !== null) are intentionally excluded โ those do not narrow awayundefined. - Deep property access (e.g.,
post.meta.title != null) is intentionally excluded โ only single-level property checks are flagged. - Computed property access (e.g.,
post[key] != null) is intentionally excluded.
Additional examplesโ
โ Incorrect โ reversed operandsโ
const titled = posts.filter((post) => null != post.title);
โ Correct โ reversed operands fixedโ
const titled = posts.filter(isPropertyPresent("title"));
ESLint flat config exampleโ
import typefest from "eslint-plugin-typefest";
export default [
{
plugins: { typefest },
rules: {
"typefest/prefer-ts-extras-is-property-present": "error",
},
},
];
When not to use itโ
Disable this rule if your filter callbacks intentionally combine property checks with additional logic, or if the property name is dynamic.
Package documentationโ
ts-extras package documentation:
Source file: source/is-property-present.ts
/**
Returns a filter predicate that tests whether a given property key is present (non-nullable) on an object.
This is useful as a type guard in `Array.prototype.filter` to narrow the resulting array type by removing `null` and `undefined` property values.
@example
```
import {isPropertyPresent} from 'ts-extras';
interface Post {
title: string | null | undefined;
}
const posts: Post[] = [{ title: 'Hello' }, { title: null }];
const titledPosts = posts.filter(isPropertyPresent('title'));
//=> [{ title: 'Hello' }]
```
@category Type guard
*/
Rule catalog ID: R102