-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpredicates.ts
More file actions
138 lines (132 loc) · 3.68 KB
/
predicates.ts
File metadata and controls
138 lines (132 loc) · 3.68 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/**
* @file Object type guards: `hasKeys`, `hasOwn`, `isObject`, `isPlainObject`.
* All four narrow `unknown` to a typed shape and tolerate `null` /
* `undefined` without throwing.
*/
import { isArray } from '../arrays/predicates'
import {
ObjectGetPrototypeOf,
ObjectHasOwn,
ObjectPrototype,
} from '../primordials/object'
import type { PropertyBag } from './types'
/**
* Check if an object has any enumerable own properties.
*
* Returns `true` if the object has at least one enumerable own property,
* `false` otherwise. Also returns `false` for null/undefined.
*
* @example
* ;```ts
* hasKeys({ a: 1 }) // true
* hasKeys({}) // false
* hasKeys([]) // false
* hasKeys([1, 2]) // true
* hasKeys(null) // false
* hasKeys(undefined) // false
* hasKeys(Object.create({ inherited: true })) // false
* ```
*
* @param obj - The value to check.
*
* @returns `true` if obj has enumerable own properties, `false` otherwise
*/
/*@__NO_SIDE_EFFECTS__*/
export function hasKeys(obj: unknown): obj is PropertyBag {
if (obj === null || obj === undefined) {
return false
}
for (const key in obj as object) {
if (ObjectHasOwn(obj as object, key)) {
return true
}
}
return false
}
/**
* Check if an object has an own property.
*
* Type-safe wrapper around `Object.hasOwn()` that returns `false` for
* null/undefined instead of throwing. Only checks own properties, not inherited
* ones from the prototype chain.
*
* @example
* ;```ts
* const obj = { name: 'Alice' }
* hasOwn(obj, 'name') // true
* hasOwn(obj, 'age') // false
* hasOwn(obj, 'toString') // false (inherited)
* hasOwn(null, 'name') // false
* ```
*
* @param obj - The value to check.
* @param propKey - The property key to look for.
*
* @returns `true` if obj has the property as an own property, `false` otherwise
*/
/*@__NO_SIDE_EFFECTS__*/
export function hasOwn(
obj: unknown,
propKey: PropertyKey,
): obj is object & PropertyBag {
if (obj === null || obj === undefined) {
return false
}
return ObjectHasOwn(obj as object, propKey)
}
/**
* Check if a value is an object (including arrays).
*
* Returns `true` for any object type including arrays, dates, etc. Returns
* `false` for primitives and `null`. Functions are not considered objects here
* (typeof functions === 'function').
*
* @example
* ;```ts
* isObject({}) // true
* isObject([]) // true
* isObject(new Date()) // true
* isObject(() => {}) // false
* isObject(null) // false
* ```
*
* @param value - The value to check.
*
* @returns `true` if value is an object (including arrays), `false` otherwise
*/
/*@__NO_SIDE_EFFECTS__*/
export function isObject(
value: unknown,
): value is { [key: PropertyKey]: unknown } {
return value !== null && typeof value === 'object'
}
/**
* Check if a value is a plain object (not an array, not a built-in).
*
* Returns `true` only for plain objects created with `{}` or
* `Object.create(null)`. Returns `false` for arrays, built-in objects (Date,
* RegExp, etc.), and primitives.
*
* @example
* ;```ts
* isPlainObject({}) // true
* isPlainObject({ a: 1 }) // true
* isPlainObject(Object.create(null)) // true
* isPlainObject([]) // false
* isPlainObject(new Date()) // false
* ```
*
* @param value - The value to check.
*
* @returns `true` if value is a plain object, `false` otherwise
*/
/*@__NO_SIDE_EFFECTS__*/
export function isPlainObject(
value: unknown,
): value is { [key: PropertyKey]: unknown } {
if (value === null || typeof value !== 'object' || isArray(value)) {
return false
}
const proto: object | null = ObjectGetPrototypeOf(value)
return proto === null || proto === ObjectPrototype
}