Skip to content

Commit

Permalink
Add Jsonifiable type (#492)
Browse files Browse the repository at this point in the history
Co-authored-by: Sindre Sorhus <sindresorhus@gmail.com>
  • Loading branch information
itsjohncs and sindresorhus authored Nov 5, 2022
1 parent b11f017 commit e11ab80
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 0 deletions.
1 change: 1 addition & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ export type {SetReturnType} from './source/set-return-type';
export type {Asyncify} from './source/asyncify';
export type {Simplify} from './source/simplify';
export type {Jsonify} from './source/jsonify';
export type {Jsonifiable} from './source/jsonifiable';
export type {Schema} from './source/schema';
export type {LiteralToPrimitive} from './source/literal-to-primitive';
export type {
Expand Down
1 change: 1 addition & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,7 @@ Click the type names for complete docs.
### JSON

- [`Jsonify`](source/jsonify.d.ts) - Transform a type to one that is assignable to the `JsonValue` type.
- [`Jsonifiable`](source/jsonifiable.d.ts) - Matches a value that can be losslessly converted to JSON.
- [`JsonPrimitive`](source/basic.d.ts) - Matches a JSON primitive.
- [`JsonObject`](source/basic.d.ts) - Matches a JSON object.
- [`JsonArray`](source/basic.d.ts) - Matches a JSON array.
Expand Down
37 changes: 37 additions & 0 deletions source/jsonifiable.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import type {JsonPrimitive, JsonValue} from './basic';

type JsonifiableObject = {[Key in string]?: Jsonifiable} | {toJSON: () => Jsonifiable};
type JsonifiableArray = readonly Jsonifiable[];

/**
Matches a value that can be losslessly converted to JSON.
Can be used to type values that you expect to pass to `JSON.stringify`.
`undefined` is allowed in object fields (for example, `{a?: number}`) as a special case even though `JSON.stringify({a: undefined})` is `{}` because it makes this class more widely useful and checking for undefined-but-present values is likely an anti-pattern.
@example
```
import type {Jsonifiable} from 'type-fest';
// @ts-expect-error
const error: Jsonifiable = {
map: new Map([['a', 1]]),
};
JSON.stringify(error);
//=> {"map": {}}
const good: Jsonifiable = {
number: 3,
date: new Date(),
missing: undefined,
}
JSON.stringify(good);
//=> {"number": 3, "date": "2022-10-17T22:22:35.920Z"}
```
@category JSON
*/
export type Jsonifiable = JsonPrimitive | JsonifiableObject | JsonifiableArray;
30 changes: 30 additions & 0 deletions test-d/jsonifiable.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import {expectAssignable, expectNotAssignable} from 'tsd';
import type {Jsonifiable} from '..';

expectAssignable<Jsonifiable>(1);
expectAssignable<Jsonifiable>('');
expectAssignable<Jsonifiable>(null);
expectAssignable<Jsonifiable>(new Date());
expectAssignable<Jsonifiable>({a: new Date()});
expectAssignable<Jsonifiable>([new Date()]);
expectAssignable<Jsonifiable>({a: undefined});
expectAssignable<Jsonifiable>([1, 2, 3] as const);
expectAssignable<Jsonifiable>({a: new Date()} as const);
expectAssignable<Jsonifiable>({a: {deeply: {nested: {toJsonObject: new Date()}}}});
expectAssignable<Jsonifiable>({toJSON: () => new Date()});
expectAssignable<Jsonifiable>({
toJSON() {
return {
foo: {
toJSON() {
return {bar: 'bar'};
},
},
};
},
});

expectNotAssignable<Jsonifiable>(undefined);
expectNotAssignable<Jsonifiable>(new Map());
expectNotAssignable<Jsonifiable>({a: new Map()});
expectNotAssignable<Jsonifiable>([new Map()]);

0 comments on commit e11ab80

Please sign in to comment.