diff --git a/CHANGELOG.md b/CHANGELOG.md index 640853e..1d59668 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ Note: I’m currently working on several breaking changes to tiny-decoders, but I’m trying out releasing them piece by piece. The idea is that you can either upgrade version by version only having to deal with one or a few breaking changes at a time, or wait and do a bunch of them at the same time. +### Version 21.0.0 (unreleased) + +This release renames `nullable` to `nullOr` to be consistent with `undefinedOr`. + ### Version 20.1.0 (2023-10-30) This release adds a `JSON` object with `parse` and `stringify` methods, similar to the standard global `JSON` object. The difference is that tiny-decoder’s versions also take a `Codec`, which makes them safer. Read more about it in the documentation. diff --git a/README.md b/README.md index 53e6b7a..c6ebb1e 100644 --- a/README.md +++ b/README.md @@ -121,7 +121,7 @@ Here’s a summary of all codecs (with slightly simplified type annotations) and - Of different types: [multi](#multi) - Of tagged objects: [fieldsUnion](#fieldsunion) with [tag](#tag) - With undefined: [undefinedOr](#undefinedor) - - With null: [nullable](#nullable) + - With null: [nullOr](#nullOr) - Other unions: [untagged union example](examples/untagged-union.test.ts) - Intersections: [intersection example](examples/fieldsUnion-with-common-fields.test.ts) - Transformation: [map](#map), [flatMap](#flatmap) @@ -320,7 +320,7 @@ Here’s a summary of all codecs (with slightly simplified type annotations) and T | undefined -nullable +nullOr
(codec: Codec<T>) =>
   Codec<T | null>
null or … @@ -842,7 +842,7 @@ Notes: - Using `undefinedOr` does _not_ make a field in an object optional. It only allows the field to be `undefined`. Similarly, using the [field](#field) function to mark a field as optional does not allow setting the field to `undefined`, only omitting it. - JSON does not have `undefined` (only `null`). So `undefinedOr` is more useful when you are decoding something that does not come from JSON. However, even when working with JSON `undefinedOr` still has a use: If you infer types from codecs, using `undefinedOr` on object fields results in `| undefined` for the type of the field, which allows you to assign `undefined` to it which is occasionally useful. -### nullable +### nullOr ```ts function nullOr( @@ -1011,7 +1011,7 @@ const myError: DecoderError = { }; ``` -`orExpected` exists so that `undefinedOr` and `nullable` can say that `undefined` and/or `null` also are expected values. +`orExpected` exists so that `undefinedOr` and `nullOr` can say that `undefined` and/or `null` also are expected values. ## format diff --git a/index.ts b/index.ts index f1a2280..6f86ce5 100644 --- a/index.ts +++ b/index.ts @@ -859,7 +859,7 @@ export function undefinedOr( }; } -export function nullable( +export function nullOr( codec: Codec, ): Codec { return { diff --git a/tests/codecs.test.ts b/tests/codecs.test.ts index 5281599..b0b7e37 100644 --- a/tests/codecs.test.ts +++ b/tests/codecs.test.ts @@ -15,7 +15,7 @@ import { InferEncoded, map, multi, - nullable, + nullOr, number, primitiveUnion, record, @@ -2432,9 +2432,9 @@ describe("undefinedOr", () => { }); }); -describe("nullable", () => { - test("nullable string", () => { - const codec = nullable(string); +describe("nullOr", () => { + test("nullOr string", () => { + const codec = nullOr(string); expectType, string | null>>(true); expectType, string | null>>(true); @@ -2457,7 +2457,7 @@ describe("nullable", () => { }); test("with default", () => { - const codec = map(nullable(string), { + const codec = map(nullOr(string), { decoder: (value) => value ?? "def", encoder: (value) => value, }); @@ -2475,7 +2475,7 @@ describe("nullable", () => { }); test("with undefined instead of null", () => { - const codec = map(nullable(string), { + const codec = map(nullOr(string), { decoder: (value) => value ?? undefined, encoder: (value) => value ?? null, }); @@ -2493,11 +2493,11 @@ describe("nullable", () => { expect(codec.encoder("a")).toBe("a"); }); - test("nullable field", () => { + test("nullOr field", () => { type Person = Infer; const Person = fieldsAuto({ name: string, - age: nullable(number), + age: nullOr(number), }); expectType>(true); @@ -2551,7 +2551,7 @@ describe("nullable", () => { void person; }); - test("nullable custom codec", () => { + test("nullOr custom codec", () => { const codec: Codec = { decoder: (value) => ({ tag: "DecoderError", @@ -2567,7 +2567,7 @@ describe("nullable", () => { }, }; - expect(run(nullable(codec), 1)).toMatchInlineSnapshot(` + expect(run(nullOr(codec), 1)).toMatchInlineSnapshot(` At root: fail Got: 1 @@ -2580,9 +2580,9 @@ describe("nullable", () => { ); }); - test("nullable higher up the chain makes no difference", () => { + test("nullOr higher up the chain makes no difference", () => { const codec = fieldsAuto({ - test: nullable(fieldsAuto({ inner: string })), + test: nullOr(fieldsAuto({ inner: string })), }); expect(run(codec, { test: 1 })).toMatchInlineSnapshot(` @@ -2600,8 +2600,8 @@ describe("nullable", () => { `); }); - test("undefinedOr and nullable", () => { - const codec = undefinedOr(nullable(nullable(undefinedOr(string)))); + test("undefinedOr and nullOr", () => { + const codec = undefinedOr(nullOr(nullOr(undefinedOr(string)))); expectType, string | null | undefined>>(true); expectType<