@toomuchdesign/json-schema-fns
is a type-safe immutable utility library for transforming JSON Schemas.
It ensures that schema transformations not only update the runtime schema correctly but also preserve accurate TypeScript type inference. This makes it especially useful when paired with tools like json-schema-to-ts.
import { omitProps } from '@toomuchdesign/json-schema-fns';
import type { FromSchema } from 'json-schema-to-ts';
const userSchema = {
type: 'object',
properties: {
id: { type: 'string' },
password: { type: 'string' },
},
required: ['id', 'password'],
} as const;
const publicUserSchema = omitProps(userSchema, ['password']);
type PublicUser = FromSchema<typeof publicUserSchema>;
// { id: string }
Manipulating JSON Schemas directly can be verbose and error-prone.
This library provides small, focused utilities that keep runtime schemas and TypeScript types in sync — especially when paired with json-schema-to-ts.
npm install @toomuchdesign/json-schema-fns
omitProps
– Omit specificproperties
from an object JSON schemapickProps
– Pick only specificproperties
from an object JSON schemamergeProps
– Merge two object JSON schemasproperties
andpatternProperties
props into one. If the same property key exists in both schemas, the property fromschema2
takes precedencerequireProps
– Mark specific properties in a object JSON schema as required. If no keys provided, all properties become requiredoptionalProps
– Make specific properties of a object JSON schema optional. If no keys provided, all properties become optionalsealSchemaDeep
– Recursively setadditionalProperties: false
on all object JSON schema schemasunsealSchemaDeep
– Recursively removeadditionalProperties
from all object JSON schema schemas
Omit specific properties
from an object JSON schema.
import { omitProps } from '@toomuchdesign/json-schema-fns';
const schema = {
type: 'object',
properties: {
a: { type: 'string' },
b: { type: 'number' },
},
required: ['a', 'b'],
} as const;
const result = omitProps(schema, ['b']);
Pick only specific properties
from an object JSON schema.
import { pickProps } from '@toomuchdesign/json-schema-fns';
const schema = {
type: 'object',
properties: {
a: { type: 'string' },
b: { type: 'number' },
},
required: ['a', 'b'],
} as const;
const result = pickProps(schema, ['b']);
Merge two object JSON schemas properties
and patternProperties
props into one. If the same property key exists in both schemas, the property from schema2
takes precedence.
import { mergeProps } from '@toomuchdesign/json-schema-fns';
const schema1 = {
type: 'object',
properties: {
a: { type: 'string' },
},
required: ['a'],
} as const;
const schema2 = {
type: 'object',
properties: {
b: { type: 'number' },
},
required: ['b'],
} as const;
const result = mergeProps(schema1, schema2);
Mark specific properties in a object JSON schema as required. If no keys provided, all properties become required.
import { requireProps } from '@toomuchdesign/json-schema-fns';
const schema = {
type: 'object',
properties: {
a: { type: 'string' },
b: { type: 'string' },
c: { type: 'string' },
},
required: ['b'],
} as const;
const result = requireProps(schema, ['a', 'c']);
Make specific properties of a object JSON schema optional. If no keys provided, all properties become optional.
import { optionalProps } from '@toomuchdesign/json-schema-fns';
const schema = {
type: 'object',
properties: {
a: { type: 'string' },
b: { type: 'string' },
c: { type: 'string' },
},
required: ['a', 'b', 'c'],
} as const;
const result = optionalProps(schema, ['b', 'c']);
Recursively set additionalProperties: false
on all object JSON schema schemas.
import { sealSchemaDeep } from '@toomuchdesign/json-schema-fns';
const schema = {
type: 'object',
required: ['name'],
properties: {
name: { type: 'string' },
address: {
type: 'object',
properties: {
street: { type: 'string' },
},
},
},
} as const;
const result = sealSchemaDeep(schema);
Recursively remove additionalProperties
from all object JSON schema schemas.
import { unsealSchemaDeep } from '@toomuchdesign/json-schema-fns';
const schema = {
type: 'object',
additionalProperties: false,
required: ['name'],
properties: {
name: { type: 'string' },
address: {
type: 'object',
additionalProperties: false,
properties: {
street: { type: 'string' },
},
},
},
} as const;
const result = unsealSchemaDeep(schema);
In addition to the standard functional API, json-schema-fns
also offers a composition-friendly counterpart that enables schema transformations through a pipeable interface.
Note: The library does not include its own pipe utility. You are free to use any composition library you prefer, such as pipe-ts, ts-functional-pipe or even bigger libraries like effect or remeda. See composition tests.
import {
mergeProps,
omitProps,
requireProps,
sealSchemaDeep,
} from '@toomuchdesign/json-schema-fns';
const schema = {
type: 'object',
properties: {
a: { type: 'string' },
b: { type: 'string' },
},
required: ['a'],
} as const;
const result = sealSchemaDeep(
requireProps(
omitProps(
mergeProps(schema, {
type: 'object',
properties: {
c: { type: 'string' },
},
}),
['a'],
),
['b'],
),
);
import {
pipeMergeProps,
pipeOmitProps,
pipeRequireProps,
pipeSealSchemaDeep,
} from '@toomuchdesign/json-schema-fns';
import { pipeWith } from 'pipe-ts';
const schema = {
type: 'object',
properties: {
a: { type: 'string' },
b: { type: 'string' },
},
required: ['a'],
} as const;
const result = pipeWith(
schema,
pipeMergeProps({
type: 'object',
properties: {
c: { type: 'string' },
},
}),
pipeOmitProps(['a']),
pipeRequireProps(['b']),
pipeSealSchemaDeep(),
);
Contributions are welcome! Before opening a PR, please run:
npx changeset