prefer-ts-extras-object-has-in
Require objectHasIn from ts-extras over Reflect.has().
Targeted pattern scopeโ
This rule only matches direct Reflect.has(object, key) calls where both arguments can be forwarded unchanged to objectHasIn(object, key).
Reflect.has(object, key)calls.
Syntactically similar alternatives are intentionally out of scope unless they preserve the same AST shape.
What this rule reportsโ
This rule reports Reflect.has(object, key) calls that can be replaced with objectHasIn(object, key).
Reflect.has(object, key)calls.
Why this rule existsโ
objectHasIn() provides stronger TypeScript narrowing for key-existence checks while preserving inherited-property semantics.
- Use this when inherited members should count as present.
- Reduces cast-heavy follow-up property access.
- Keeps prototype-aware checks consistent across modules.
โ Incorrectโ
if (Reflect.has(record, key)) {
console.log(record[key as keyof typeof record]);
}
โ Correctโ
if (objectHasIn(record, key)) {
console.log(record[key]);
}
Behavior and migration notesโ
- Runtime semantics align with
Reflect.hasandkey in object(prototype chain included). - Prefer
objectHasOwnif inherited members should be excluded. - For security-sensitive payload validation, confirm that inherited properties are acceptable.
Additional examplesโ
โ Incorrect โ Additional exampleโ
if (Reflect.has(input, "name")) {
console.log((input as { name: unknown }).name);
}
โ Correct โ Additional exampleโ
if (objectHasIn(input, "name")) {
console.log(input.name);
}
โ Correct โ Repository-wide usageโ
const canAccess = objectHasIn(candidate, key);
ESLint flat config exampleโ
import typefest from "eslint-plugin-typefest";
export default [
{
plugins: { typefest },
rules: {
"typefest/prefer-ts-extras-object-has-in": "error",
},
},
];
When not to use itโ
Disable this rule if checks must be own-property-only, or if runtime helper dependencies are disallowed in your environment.
Package documentationโ
ts-extras package documentation:
Source file: source/object-has-in.ts
/**
Check if an object has a property (including inherited) and narrow the object type.
This function performs __object narrowing__ - it adds the checked property to the object's type, allowing safe property access. Uses the `in` operator to check the entire prototype chain.
Unlike `objectHasOwn` (own properties only) and `keyIn` (key narrowing), this narrows the _object_ type to include inherited properties.
@example
```
import {objectHasIn} from 'ts-extras';
const data: unknown = {foo: 1};
if (objectHasIn(data, 'foo')) {
// `data` is now: unknown & {foo: unknown}
console.log(data.foo); // Safe access
}
// Also checks prototype chain
if (objectHasIn(data, 'toString')) {
// `data` is now: unknown & {toString: unknown}
console.log(data.toString); // Safe access to inherited method
}
```
@note This uses the `in` operator and checks the entire prototype chain, but blocks `__proto__` and `constructor` for security.
@category Type guard
*/
Rule catalog ID: R028