format

deno land deno doc GitHub release (latest by date) codecov GitHub

test NPM

Formatting and printing string utilities.

Features

  • No parsing
  • No runtime error
  • Type safety
  • Single responsibility
  • Minimum

Why

The purpose of this project is to provide minimum replacement formatting function.

Existing formatting solutions offer multiple features.

The Deno community already has std/fmt::sprintf. There are also various other 3rd party libraries.

These could accomplish a lot of work. On the other hand, they are somewhat over-specified. You have to pay more cost than you need to. (cost here refers to code size and execution speed).

We decompose formatting into replacement and serialization. Then, focus on replacement.

Usage

Type inference works well for template literal.

import { format } from "https://deno.land/x/format@$VERSION/mod.ts";
import { assertEquals } from "https://deno.land/std/testing/asserts.ts";

assertEquals(format("{0} {name}!", { 0: "Hello", name: "Tom" }), "Hello Tom!");

//@ts-expect-error it should provide args.0 and args.name
format("{0} {name}!", {});

If the specifier is numeric only, you can specify an array as an argument.

import { format } from "https://deno.land/x/format@$VERSION/mod.ts";
import { assertEquals } from "https://deno.land/std/testing/asserts.ts";

assertEquals(format("{0} world!", ["Hello"]), "Hello world!");

//@ts-expect-error it should provide args.0
format("{0} world!", []);

Placeholder

Placeholder is a pair of prefix and suffix.

Name Default
prefix {
suffix }

This can be changed.

Template literal style:

import { format } from "https://deno.land/x/format@$VERSION/mod.ts";
import { assertEquals } from "https://deno.land/std/testing/asserts.ts";

const result = format("should be ${expected}, actual ${actual}", {
  expected: "string",
  actual: "number",
}, { placeholders: [{ prefix: "${", suffix: "}" }] });
assertEquals(result, "should be string, actual number");

//@ts-expect-error it should be error
format("should be ${expected}, actual ${actual}", {}, {
  placeholders: [{ prefix: "${", suffix: "}" }],
});

Percent style:

import { format } from "https://deno.land/x/format@$VERSION/mod.ts";
import { assertEquals } from "https://deno.land/std/testing/asserts.ts";

const result = format("Hello %s!!!", { "": "world" }, {
  placeholders: [{ prefix: "%", suffix: "s" }],
});
assertEquals(result, "Hello world!!!");

Multiple placeholders:

import { format } from "https://deno.land/x/format@$VERSION/mod.ts";
import { assertEquals } from "https://deno.land/std/testing/asserts.ts";

const result = format("[0] {name}: {title}", {
  0: new Date("2038/1/1"),
  name: "",
  title: "",
}, {
  placeholders: [
    { prefix: "{", suffix: "}" },
    { prefix: "[", suffix: "]" },
  ],
});
assertEquals(result, "abcde{fg}ijk]a}");

The computational complexity of placeholder is O(n) compared to argument. It is recommended to reduce the number of placeholders as much as possible.

Custom serialization

Argument serialization uses the String constructor by default.

To change this, specify the stringify option.

import { format } from "https://deno.land/x/format@$VERSION/mod.ts";
import { assertEquals } from "https://deno.land/std/testing/asserts.ts";

const result = format("{0}{1}{2}", ["1", 1, true], {
  stringify: (arg) => {
    if (typeof arg === "string") return `"${arg}"`;

    return String(arg);
  },
});
assertEquals(result, `"1"1true`);

Override type inference

In certain circumstances, template literal types cannot be provided. In such cases, generics can be specified.

import { format } from "https://deno.land/x/format@$VERSION/mod.ts";
import { assertEquals } from "https://deno.land/std/testing/asserts.ts";

declare const string: string;
//@ts-expect-error it should provide args.name and args.title
format<"name" | "title">(string, {});

API

See deno doc for all APIs.

License

Copyright © 2023-present Tomoki Miyauci.

Released under the MIT license