| 13 | * Object type |
| 14 | */ |
| 15 | export class ObjectType<T extends AnyObject> implements Type<T> { |
| 16 | name = 'object'; |
| 17 | |
| 18 | constructor(public type: Class<T>) {} |
| 19 | |
| 20 | isInstance(value: any) { |
| 21 | return value == null || value instanceof this.type; |
| 22 | } |
| 23 | |
| 24 | isCoercible(value: any): boolean { |
| 25 | return ( |
| 26 | value == null || (typeof value === 'object' && !Array.isArray(value)) |
| 27 | ); |
| 28 | } |
| 29 | |
| 30 | defaultValue() { |
| 31 | return new this.type(); |
| 32 | } |
| 33 | |
| 34 | coerce(value: any) { |
| 35 | if (value == null) return value; |
| 36 | if (value instanceof this.type) { |
| 37 | return value; |
| 38 | } |
| 39 | if (typeof value !== 'object' || Array.isArray(value)) { |
| 40 | const msg = util.format('Invalid %s: %j', this.name, value); |
| 41 | throw new TypeError(msg); |
| 42 | } |
| 43 | return new this.type(value); |
| 44 | } |
| 45 | |
| 46 | serialize(value: T | null | undefined) { |
| 47 | if (value == null) return value; |
| 48 | if (typeof value.toJSON === 'function') { |
| 49 | return value.toJSON(); |
| 50 | } |
| 51 | return value; |
| 52 | } |
| 53 | } |