Skip to content

Commit b989a86

Browse files
author
Elias Mulhall
committed
object decoder may validate dictionary with any values
1 parent d4326b5 commit b989a86

File tree

2 files changed

+23
-4
lines changed

2 files changed

+23
-4
lines changed

src/decoder.ts

+14-4
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,10 @@ export class Decoder<A> {
259259

260260
/**
261261
* An higher-order decoder that runs decoders on specified fields of an object,
262-
* and returns a new object with those fields.
262+
* and returns a new object with those fields. If `object` is called with no
263+
* arguments, then the outer object part of the json is validated but not the
264+
* contents, typing the result as a dictionary where all keys have a value of
265+
* type `any`.
263266
*
264267
* The `optional` and `constant` decoders are particularly useful for decoding
265268
* objects that match typescript interfaces.
@@ -270,11 +273,16 @@ export class Decoder<A> {
270273
* ```
271274
* object({x: number(), y: number()}).run({x: 5, y: 10})
272275
* // => {ok: true, result: {x: 5, y: 10}}
276+
*
277+
* object().map(Object.keys).run({n: 1, i: [], c: {}, e: 'e'})
278+
* // => {ok: true, result: ['n', 'i', 'c', 'e']}
273279
* ```
274280
*/
275-
static object<A>(decoders: DecoderObject<A>): Decoder<A> {
276-
return new Decoder<A>((json: any) => {
277-
if (isJsonObject(json)) {
281+
static object(): Decoder<{[key: string]: any}>;
282+
static object<A>(decoders: DecoderObject<A>): Decoder<A>;
283+
static object<A>(decoders?: DecoderObject<A>) {
284+
return new Decoder((json: any) => {
285+
if (isJsonObject(json) && decoders) {
278286
let obj: any = {};
279287
for (const key in decoders) {
280288
if (decoders.hasOwnProperty(key)) {
@@ -292,6 +300,8 @@ export class Decoder<A> {
292300
}
293301
}
294302
return Result.ok(obj);
303+
} else if (isJsonObject(json)) {
304+
return Result.ok(json);
295305
} else {
296306
return Result.err({message: expectedGot('an object', json)});
297307
}

test/json-decode.test.ts

+9
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,15 @@ describe('object', () => {
253253
expect(decoder.run({a: 12, b: 'hats'})).toEqual({ok: true, result: {a: 12, b: 'hats'}});
254254
expect(decoder.run({a: 12})).toEqual({ok: true, result: {a: 12}});
255255
});
256+
257+
it('decodes any object when the object shape is not specified', () => {
258+
const objectKeysDecoder: Decoder<string[]> = object().map(Object.keys);
259+
260+
expect(objectKeysDecoder.run({n: 1, i: [], c: {}, e: 'e'})).toEqual({
261+
ok: true,
262+
result: ['n', 'i', 'c', 'e']
263+
});
264+
});
256265
});
257266

258267
describe('array', () => {

0 commit comments

Comments
 (0)