| 118 | }) |
| 119 | |
| 120 | const makePredicate = (pattern: unknown): Predicate.Predicate<unknown> => { |
| 121 | if (typeof pattern === "function") { |
| 122 | return pattern as Predicate.Predicate<unknown> |
| 123 | } else if (Array.isArray(pattern)) { |
| 124 | const predicates = pattern.map(makePredicate) |
| 125 | const len = predicates.length |
| 126 | |
| 127 | return (u: unknown) => { |
| 128 | if (!Array.isArray(u)) { |
| 129 | return false |
| 130 | } |
| 131 | |
| 132 | for (let i = 0; i < len; i++) { |
| 133 | if (predicates[i](u[i]) === false) { |
| 134 | return false |
| 135 | } |
| 136 | } |
| 137 | |
| 138 | return true |
| 139 | } |
| 140 | } else if (pattern !== null && typeof pattern === "object") { |
| 141 | const keysAndPredicates = Object.entries(pattern).map( |
| 142 | ([k, p]) => [k, makePredicate(p)] as const |
| 143 | ) |
| 144 | const len = keysAndPredicates.length |
| 145 | |
| 146 | return (u: unknown) => { |
| 147 | if (typeof u !== "object" || u === null) { |
| 148 | return false |
| 149 | } |
| 150 | |
| 151 | for (let i = 0; i < len; i++) { |
| 152 | const [key, predicate] = keysAndPredicates[i] |
| 153 | if (!(key in u) || predicate((u as any)[key]) === false) { |
| 154 | return false |
| 155 | } |
| 156 | } |
| 157 | |
| 158 | return true |
| 159 | } |
| 160 | } |
| 161 | |
| 162 | return (u: unknown) => u === pattern |
| 163 | } |
| 164 | |
| 165 | const makeOrPredicate = ( |
| 166 | patterns: ReadonlyArray<unknown> |