prefer-ts-extras-is-property-defined
Require isPropertyDefined from ts-extras in Array.prototype.filter callbacks instead of inline property-undefined checks.
Targeted pattern scopeโ
This rule only inspects inline .filter(...) predicates that perform an explicit undefined check against a single object property.
- Inline property-undefined predicates inside
.filter(...), including:filter((item) => item.prop !== undefined)filter((item) => undefined !== item.prop)filter((item) => item.prop != undefined)filter((item) => typeof item.prop !== "undefined")
Named predicate references, multi-argument callbacks, and broader callback logic are not matched unless they preserve this property-undefined-check shape.
What this rule reportsโ
This rule reports inline filter predicates that check whether a single object property is not undefined and can be normalized with isPropertyDefined.
Why this rule existsโ
filter(isPropertyDefined('prop')) is the canonical ts-extras pattern for filtering out items where a specific property is undefined.
- Filtering logic is consistent and composable across collections.
- The property key is explicit in the function call, not hidden inside a callback.
- Repeated inline
!== undefinedcallback expressions are removed. isPropertyDefinedis a proper type predicate that narrows element types in the resulting array.
โ Incorrectโ
const named = users.filter((user) => user.name !== undefined);
โ Correctโ
import { isPropertyDefined } from "ts-extras";
const named = users.filter(isPropertyDefined("name"));
Behavior and migration notesโ
isPropertyDefined('prop')checksitem[prop] !== undefinedand narrows the result type accordingly.- The autofix preserves the property name as a string literal.
- Deep property access (e.g.,
user.address.street !== undefined) is intentionally excluded โ only single-level property checks are flagged. - Computed property access (e.g.,
user[key] !== undefined) is intentionally excluded.
Additional examplesโ
โ Incorrect โ typeof formโ
const named = users.filter((user) => typeof user.name !== "undefined");
โ Correct โ typeof form fixedโ
const named = users.filter(isPropertyDefined("name"));
ESLint flat config exampleโ
import typefest from "eslint-plugin-typefest";
export default [
{
plugins: { typefest },
rules: {
"typefest/prefer-ts-extras-is-property-defined": "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-defined.ts
/**
Returns a filter predicate that tests whether a given property key is defined (not `undefined`) on an object.
This is useful as a type guard in `Array.prototype.filter` to narrow the resulting array type.
@example
```
import {isPropertyDefined} from 'ts-extras';
interface User {
name: string | undefined;
}
const users: User[] = [{ name: 'Alice' }, { name: undefined }];
const namedUsers = users.filter(isPropertyDefined('name'));
//=> [{ name: 'Alice' }]
```
@category Type guard
*/
Rule catalog ID: R101