API reference › @evolu/common › Type › excludes

function excludes<Substring extends string>(
  substring: ExcludesSubstring<Substring>,
): BrandFactory<`Excludes${Substring}`, string, ExcludesError<Substring>>;

Defined in: packages/common/src/Type.ts:8176

String Brand forbidding an exact, case-sensitive substring.

Use it, for example, to forbid a separator in values that will be joined. The string is rejected wherever the substring occurs, including across line breaks. A regular expression such as /^(?!.*,)/u is easy to get wrong, because its . does not match a line terminator, so it accepts "a\n,". Validation preserves the complete string.

The substring must be one concrete string literal so different substrings have distinct brands. Every string contains the empty string, so an empty substring would reject every string and is rejected at compile time.

Like String.prototype.includes, matching compares UTF-16 code units, so a forbidden precomposed é does not reject e followed by a combining accent. Use normalized to require one Unicode normalization form.

Example

import {
  assertEqual,
  assertErr,
  assertOk,
  assertType,
  excludes,
  String,
  type Brand,
} from "@evolu/common";

const Tag = excludes(",")(String);

const tag = Tag.fromUnknown("local-first");
assertOk(tag, "local-first");
assertType<typeof tag.value, string & Brand<"Excludes,">>();

const invalid = Tag.fromUnknown("local,first");
assertErr(invalid, {
  type: "Excludes,",
  value: "local,first",
  substring: ",",
});
assertEqual(
  Tag.formatError(invalid.error),
  'The value "local,first" must not contain ",".',
);

// @ts-expect-error Substring must not be empty because every string contains it.
excludes("");