Skip to main content

equality

Strict equality, shallow assignability, and key existence checks.

import type {
  Equal, NotEqual, ShallowEqual, ShallowNotEqual,
  HasKey, HasKeyWithType,
} from '@gentleduck/ttest/equality'

Equal

type Equal<X, Y> =
  (<T>() => T extends X ? 1 : 2) extends (<T>() => T extends Y ? 1 : 2) ? true : false

Bidirectional, variance-preserving equality. Distinguishes any from unknown and mutable from readonly.

type a = Equal<1, 1>            // true
type b = Equal<any, unknown>    // false
type c = Equal<{a:1}, {a:1}>    // true
type d = Equal<readonly [1], [1]>  // false

NotEqual

type NotEqual<X, Y>

Inverse of Equal. Use when negation reads cleaner.

ShallowEqual

type ShallowEqual<X, Y> = X extends Y ? true : false

One-way assignability — X extends Y.

type a = ShallowEqual<'admin', 'admin' | 'user'>  // true
type b = ShallowEqual<string,  'admin'>           // false

ShallowNotEqual

type ShallowNotEqual<X, Y> = X extends Y ? false : true

Inverse of ShallowEqual.

HasKey

type HasKey<K extends string, O> = K extends keyof O ? true : false
type a = HasKey<'id', { id: number }>  // true
type b = HasKey<'x',  { id: number }>  // false

HasKeyWithType

type HasKeyWithType<K extends string, T, O> = K extends keyof O ? Equal<T, O[K]> : false

true iff O[K] exists and equals T exactly.

type a = HasKeyWithType<'id', number, { id: number }>  // true
type b = HasKeyWithType<'id', string, { id: number }>  // false