Rename optional and undefinable functions for clarity; update related schemas to use optionalOrNull

This commit is contained in:
Mario Campos
2026-06-19 13:55:56 -05:00
parent c8e32e423d
commit defcf1bff6
5 changed files with 53 additions and 53 deletions

View File

@@ -10,8 +10,8 @@ const testSchema = {
requiredKey: json.string,
};
const optionalSchema = {
optionalKey: json.optional(json.string),
const optionalOrNullSchema = {
optionalKey: json.optionalOrNull(json.string),
};
test("validateSchema - required properties are required", async (t) => {
@@ -30,11 +30,34 @@ test("validateSchema - required properties are required", async (t) => {
test("validateSchema - optional properties are optional", async (t) => {
// Optional fields may be absent
t.true(json.validateSchema(optionalSchema, {}));
t.true(json.validateSchema(optionalSchema, { optionalKey: undefined }));
t.true(json.validateSchema(optionalSchema, { optionalKey: null }));
t.true(json.validateSchema(optionalOrNullSchema, {}));
t.true(json.validateSchema(optionalOrNullSchema, { optionalKey: undefined }));
t.true(json.validateSchema(optionalOrNullSchema, { optionalKey: null }));
// But, if present, should have the expected type
t.false(json.validateSchema(optionalOrNullSchema, { optionalKey: 0 }));
t.false(json.validateSchema(optionalOrNullSchema, { optionalKey: 123 }));
t.false(json.validateSchema(optionalOrNullSchema, { optionalKey: false }));
t.false(json.validateSchema(optionalOrNullSchema, { optionalKey: true }));
t.false(json.validateSchema(optionalOrNullSchema, { optionalKey: [] }));
t.false(json.validateSchema(optionalOrNullSchema, { optionalKey: {} }));
t.true(json.validateSchema(optionalOrNullSchema, { optionalKey: "" }));
t.true(json.validateSchema(optionalOrNullSchema, { optionalKey: "foo" }));
});
const optionalSchema = {
optionalKey: json.optional(json.string),
};
test("validateSchema - optional properties may be absent or undefined, but reject null", async (t) => {
// Optional fields may be absent or explicitly undefined
t.true(json.validateSchema(optionalSchema, {}));
t.true(json.validateSchema(optionalSchema, { optionalKey: undefined }));
// But should reject null
t.false(json.validateSchema(optionalSchema, { optionalKey: null }));
// And, if present, should have the expected type
t.false(json.validateSchema(optionalSchema, { optionalKey: 0 }));
t.false(json.validateSchema(optionalSchema, { optionalKey: 123 }));
t.false(json.validateSchema(optionalSchema, { optionalKey: false }));
@@ -44,26 +67,3 @@ test("validateSchema - optional properties are optional", async (t) => {
t.true(json.validateSchema(optionalSchema, { optionalKey: "" }));
t.true(json.validateSchema(optionalSchema, { optionalKey: "foo" }));
});
const undefinableSchema = {
optionalKey: json.undefinable(json.string),
};
test("validateSchema - undefinable properties are optional but reject null", async (t) => {
// Optional fields may be absent or explicitly undefined
t.true(json.validateSchema(undefinableSchema, {}));
t.true(json.validateSchema(undefinableSchema, { optionalKey: undefined }));
// But, unlike `optional`, `null` is rejected
t.false(json.validateSchema(undefinableSchema, { optionalKey: null }));
// And, if present, should have the expected type
t.false(json.validateSchema(undefinableSchema, { optionalKey: 0 }));
t.false(json.validateSchema(undefinableSchema, { optionalKey: 123 }));
t.false(json.validateSchema(undefinableSchema, { optionalKey: false }));
t.false(json.validateSchema(undefinableSchema, { optionalKey: true }));
t.false(json.validateSchema(undefinableSchema, { optionalKey: [] }));
t.false(json.validateSchema(undefinableSchema, { optionalKey: {} }));
t.true(json.validateSchema(undefinableSchema, { optionalKey: "" }));
t.true(json.validateSchema(undefinableSchema, { optionalKey: "foo" }));
});

View File

@@ -76,7 +76,7 @@ export const object = {
* Transforms a validator to be optional, accepting `undefined` or `null` for an
* absent value.
*/
export function optional<T>(validator: Validator<T>) {
export function optionalOrNull<T>(validator: Validator<T>) {
return {
validate: (val: unknown) => {
return val === undefined || val === null || validator.validate(val);
@@ -87,9 +87,9 @@ export function optional<T>(validator: Validator<T>) {
/**
* Transforms a validator to be optional, accepting `undefined` for an absent
* value but, unlike `optional`, rejecting `null`.
* value but, unlike `optionalOrNull`, rejecting `null`.
*/
export function undefinable<T>(validator: Validator<T>) {
export function optional<T>(validator: Validator<T>) {
return {
validate: (val: unknown): val is T | undefined => {
return val === undefined || validator.validate(val);