|
1 | 1 | /* eslint-disable @typescript-eslint/ban-types */ |
| 2 | +import { hasAdditionalProperties } from '../../hasAdditionalProperties.js'; |
2 | 3 | import { isAnyObject } from '../isAnyObject.js'; |
3 | 4 |
|
4 | 5 | import { literal } from './literal.js'; |
@@ -40,24 +41,26 @@ export type InferTypeFromShape<Shape extends ObjectShapeRecord<object>> = { |
40 | 41 |
|
41 | 42 | export const shape = <Type extends object, Shape extends ObjectShapeRecord<Type> = ObjectShapeRecord<Type>>( |
42 | 43 | objectShape: Shape, |
| 44 | + additionalProperties = true, |
43 | 45 | ): TypePredicateFn<Pretty<Type & InferTypeFromShape<Shape>>> => { |
44 | | - const entries: [key: string | symbol, predicate: TypePredicateFn<unknown>][] = Reflect.ownKeys(objectShape).map( |
45 | | - (key) => { |
46 | | - const value = Reflect.get(objectShape, key); |
47 | | - |
48 | | - const predicate = |
49 | | - typeof value === 'function' |
50 | | - ? (value as TypePredicateFn<unknown>) |
51 | | - : value instanceof RegExp |
52 | | - ? matching(value) |
53 | | - : isAnyObject(value) |
54 | | - ? shape(value) |
55 | | - : literal(value); |
56 | | - |
57 | | - return [key, predicate]; |
58 | | - }, |
59 | | - ); |
| 46 | + const knownProperties = Reflect.ownKeys(objectShape); |
| 47 | + const entries: [key: string | symbol, predicate: TypePredicateFn<unknown>][] = knownProperties.map((key) => { |
| 48 | + const value = Reflect.get(objectShape, key); |
| 49 | + |
| 50 | + const predicate = |
| 51 | + typeof value === 'function' |
| 52 | + ? (value as TypePredicateFn<unknown>) |
| 53 | + : value instanceof RegExp |
| 54 | + ? matching(value) |
| 55 | + : isAnyObject(value) |
| 56 | + ? shape(value) |
| 57 | + : literal(value); |
| 58 | + |
| 59 | + return [key, predicate]; |
| 60 | + }); |
60 | 61 |
|
61 | 62 | return (input: unknown): input is Pretty<Type & InferTypeFromShape<Shape>> => |
62 | | - isAnyObject(input) && entries.every(([key, predicate]) => predicate(Reflect.get(input, key))); |
| 63 | + isAnyObject(input) && |
| 64 | + entries.every(([key, predicate]) => predicate(Reflect.get(input, key))) && |
| 65 | + (additionalProperties || !hasAdditionalProperties(input, knownProperties)); |
63 | 66 | }; |
0 commit comments