0.0.1-beta • Published 5 months ago

@typedly/check v0.0.1-beta

Weekly downloads
-
License
MIT
Repository
github
Last release
5 months ago

typedly/check

npm version GitHub issues GitHub license

A lightweight TypeScript type definitions library for type comparison.

Table of contents

Definitions

Boolean Ambiguity Prevention:

  • Ensures that type check returns a definite true or false result, instead of boolean especially seen in cases involving union types or complex conditions.
  • When we use conditional types, like A extends B ? (B extends A ? true : false) : false, it could lead to ambiguous results in certain scenarios, especially with unions.

Distributive Equality:

  • It can be seen by using union type as the type parameter.
  • Distributive equality occurs when a type equality check is performed across each member of a union type.
  • If either or both of the types being compared are union types, the comparison is distributed over each individual member of the union.

Example:

number | string being checked against string | number will check number against string, number against number, string against string, and string against number.

Structural Equality:

  • Ensures that two types have the exact same structure, including properties, types, and the order of those properties (in the case of objects).
  • Unlike subtype compatibility, where one type can be a more general form of another, structural equality requires that the types are identical in structure.

Example:

{ a: number; b: string } and { b: string; a: number } are structurally equal.

Strict Equality:

  • Enforced using the tuple [A] and [B].
  • Disallows subtype/supertype compatibility.
  • Both types need to have the same properties, the same number of properties, and the same order of properties.

Example:

[1, 2] is strictly equal to [1, 2], but not to [2, 1]. number | string is not strictly equal to string | number when using a non distributing equality check.

!NOTE It seems TypeScript's type system currently doesn't support full strict object equality (including key order) directly. If you're working with objects, you can check for strict structure, but not necessarily key order or exact value assignment without additional constraints or custom logic.

Installation

npm install @typedly/check --save-peer

Api

import {
  Assignable, DistributiveAssignable, Inclusion,
  Compatible, StrictAssignable, StructuralAssignable,
  Equal, DistributiveEqual,
  Mutual, BooleanDistributiveEqual,
  Same, StrictlySame,
  StrictEqual, StructuralEqual,
  StrictMutual, MutualAssignable,
} from '@typedly/check';

Assignable

Checks whether A can be assigned to B or vice versa, returning true if either condition is met, otherwise false.

  • Checks if one type includes another.
  • Checks if any member of A is assignable to B or vice versa.
  • Handles distribution over unions (distributive check).
  • Allows subtype/supertype compatibility.
  • Supports partial compatibility, not requiring exact structure alignment.
import { Assignable } from '@typedly/check';

// Union.
export type UnionExample1 = Assignable<"a" | "b", "a">;  // boolean
export type UnionExample2 = Assignable<'a' | 'b', 'b' | 'a'>; // true
export type UnionExample3 = Assignable<'a' | 'b', 'a' | 'b'>; // true
export type UnionExample4 = Assignable<string | number, number | string>; // true
export type UnionExample5 = Assignable<number | string, number | string>; // true

More examples

Equal

Determines if A and B are structurally identical by ensuring both A extends B and B extends A.

  • Ensures every member of A is assignable to B and vice versa.
  • Does not ensure full correctness due to potential boolean ambiguity with union types.
  • Disallows subtype/supertype compatibility by requiring exact structural equality.
import { Equal } from '@typedly/check';

// Union.
export type UnionExample1 = Equal<"a" | "b", "a">;  // boolean
export type UnionExample2 = Equal<'a' | 'b', 'b' | 'a'>; // boolean
export type UnionExample3 = Equal<'a' | 'b', 'a' | 'b'>; // boolean
export type UnionExample4 = Equal<string | number, number | string>; // boolean
export type UnionExample5 = Equal<number | string, number | string>; // boolean

More examples

ExactEqual

import { ExactEqual } from '@typedly/check';

// Union.
// The difference between `StrictEqual` / `Equal` / `ExactEqual`
export type UnionExample1 = ExactEqual<"a" | "b", "a">;  // false / boolean / false
export type UnionExample2 = ExactEqual<'a' | 'b', 'b' | 'a'>; // true / boolean / true
export type UnionExample3 = ExactEqual<'a' | 'b', 'a' | 'b'>; // true / boolean / true
export type UnionExample4 = ExactEqual<string | number, number | string>; // true / boolean / true
export type UnionExample5 = ExactEqual<number | string, number | string>; // true / boolean / true

More examples

Mutual

Determines if two types A and B are mutually equal preventing boolean ambiguity.

  • Checks if every member of A is assignable to B and vice versa.
  • Ensures a definite true or false result, avoiding boolean ambiguity in union types.
  • Handles distribution over unions, ensuring correctness in cases like A | B. (distributive check)
  • Structural equality check — requires the exact same structure, not just subtype compatibility.
import { Mutual } from '@typedly/check';

// Union.
export type UnionExample1 = Mutual<"a" | "b", "a">;  // false
export type UnionExample2 = Mutual<'a' | 'b', 'b' | 'a'>; // true
export type UnionExample3 = Mutual<'a' | 'b', 'a' | 'b'>; // true
export type UnionExample4 = Mutual<string | number, number | string>; // true
export type UnionExample5 = Mutual<number | string, number | string>; // true

More examples

Same

Ensures exact equality by strictly comparing function return types.

import { Same } from '@typedly/check';

// Union.
export type UnionExample1 = Same<"a" | "b", "a">;  // false
export type UnionExample2 = Same<'a' | 'b', 'b' | 'a'>; // true
export type UnionExample3 = Same<'a' | 'b', 'a' | 'b'>; // true
export type UnionExample4 = Same<string | number, number | string>; // true
export type UnionExample5 = Same<number | string, number | string>; // true

More examples

StrictAssignable

Checks whether A can be strictly(by using tuple wrapping) assigned to B or vice versa, returning true if either condition is met, otherwise false.

import { StrictAssignable } from '@typedly/check';

// Union.
export type UnionExample1 = StrictAssignable<"a" | "b", "a">;  // true
export type UnionExample2 = StrictAssignable<'a' | 'b', 'b' | 'a'>; // true
export type UnionExample3 = StrictAssignable<'a' | 'b', 'a' | 'b'>; // true
export type UnionExample4 = StrictAssignable<string | number, number | string>; // true
export type UnionExample5 = StrictAssignable<number | string, number | string>; // true

More examples

StrictEqual

Determines if two types A and B are strictly equal.

  • Ensures both types mutually extend each other: it checks if every member of A is assignable to B and every member of B is assignable to A.
  • Ensures a definite true or false result, avoiding boolean ambiguity.
  • Prevents distribution behavior: no distribution over unions.
  • Strict(by using tuple) structural(both direction): Ensures exact structural equality in both directions.
import { StrictEqual } from '@typedly/check';

// Union.
// The difference between Equal and StrictEqual
export type UnionExample1 = StrictEqual<"a" | "b", "a">;  // false instead of boolean
export type UnionExample2 = StrictEqual<'a' | 'b', 'b' | 'a'>; // true instead of boolean
export type UnionExample3 = StrictEqual<'a' | 'b', 'a' | 'b'>; // true instead of boolean
export type UnionExample4 = StrictEqual<string | number, number | string>; // true instead of boolean
export type UnionExample5 = StrictEqual<number | string, number | string>; // true instead of boolean

More examples

StrictMutual

Determines if two types A and B are strictly and mutually equal.

  • Ensures that both types mutually extend each other: Checks if every member of A is assignable to B and every member of B is assignable to A.
  • Guarantees a definite true or false result, avoiding boolean ambiguity.
  • Prevents distribution behavior: no distribution over unions.
  • Strict(by using tuple) structural(both direction): Ensures exact structural equality in both directions.
import { StrictMutual } from '@typedly/check';

// Union.
export type UnionExample1 = StrictMutual<"a" | "b", "a">;  // false
export type UnionExample2 = StrictMutual<'a' | 'b', 'b' | 'a'>; // true
export type UnionExample3 = StrictMutual<'a' | 'b', 'a' | 'b'>; // true
export type UnionExample4 = StrictMutual<string | number, number | string>; // true
export type UnionExample5 = StrictMutual<number | string, number | string>; // true

More examples

Contributing

Your contributions are valued! If you'd like to contribute, please feel free to submit a pull request. Help is always appreciated.

Support

If you find this package useful and would like to support its and general development, you can contribute through one of the following payment methods. Your support helps maintain the packages and continue adding new.

Support via:

Thanks for your support!

Code of Conduct

By participating in this project, you agree to follow Code of Conduct.

GIT

Commit

Versioning

Semantic Versioning 2.0.0

Given a version number MAJOR.MINOR.PATCH, increment the:

  • MAJOR version when you make incompatible API changes,
  • MINOR version when you add functionality in a backwards-compatible manner, and
  • PATCH version when you make backwards-compatible bug fixes.

Additional labels for pre-release and build metadata are available as extensions to the MAJOR.MINOR.PATCH format.

FAQ How should I deal with revisions in the 0.y.z initial development phase?

The simplest thing to do is start your initial development release at 0.1.0 and then increment the minor version for each subsequent release.

How do I know when to release 1.0.0?

If your software is being used in production, it should probably already be 1.0.0. If you have a stable API on which users have come to depend, you should be 1.0.0. If you’re worrying a lot about backwards compatibility, you should probably already be 1.0.0.

License

MIT © typedly (license)

Packages

  • @typedly/array: A TypeScript type definitions package to handle array-related operations.
  • @typedly/character: A TypeScript type definitions package for various character types.
  • @typedly/context: A TypeScript type definitions package for context data structures.
  • @typedly/descriptor: A TypeScript type definitions package for property descriptor.
  • @typedly/digit: A TypeScript type definitions package for digit types.
  • @typedly/letter: A TypeScript type definitions package for handling letter types.
  • @typedly/object: A TypeScript type definitions package to handle object-related operations.
  • @typedly/payload: A TypeScript type definitions package for payload data structures.
  • @typedly/property: A TypeScript type definitions package to handle object property-related operations.
  • @typedly/regexp: A TypeScript type definitions package for RegExp.
  • @typedly/symbol: A TypeScript type definitions package for various symbols.