Skip to content

Commit

Permalink
fix: update isType implemention
Browse files Browse the repository at this point in the history
Based on older algorithm using `[object, object]`.
This avoid the need to use extra types such as `bigint`.
  • Loading branch information
unional committed Oct 30, 2022
1 parent ca885b9 commit 5aaf0f5
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 22 deletions.
29 changes: 26 additions & 3 deletions ts/predicates/Equal.spec.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,30 @@
import { assertType, Equal, NotEqual, ValueOf } from '../index.js'
import { AnyFunction, assertType, Equal, NotEqual, ValueOf } from '../index.js'

describe('Equal<A, B>', () => {
test('match', () => {
it('compares among booleans', () => {
assertType.isTrue(true as Equal<true, true>)
assertType.isTrue(true as Equal<false, false>)
assertType.isTrue(true as Equal<boolean, boolean>)

assertType.isFalse(false as Equal<true, false>)
assertType.isFalse(false as Equal<false, true>)
})
it('compares boolean with others', () => {
assertType.isFalse(false as Equal<true, undefined>)
assertType.isFalse(false as Equal<true, null>)
assertType.isFalse(false as Equal<true, number>)
assertType.isFalse(false as Equal<true, string>)
assertType.isFalse(false as Equal<true, symbol>)
assertType.isFalse(false as Equal<true, object>)
assertType.isFalse(false as Equal<true, AnyFunction>)

assertType.isFalse(false as Equal<false, undefined>)
assertType.isFalse(false as Equal<false, null>)
assertType.isFalse(false as Equal<false, number>)
assertType.isFalse(false as Equal<false, string>)
assertType.isFalse(false as Equal<false, symbol>)
assertType.isFalse(false as Equal<false, object>)
assertType.isFalse(false as Equal<false, AnyFunction>)
})

test('not match', () => {
Expand Down Expand Up @@ -94,7 +116,8 @@ describe('NotEqual<A, B>', () => {
assertType.isTrue(true as NotEqual<{ a: number, b: string }, { a: number } & { b?: string }>)
})
it('works with never type', () => {
assertType.isFalse(false as NotEqual<never, never>)
type A = NotEqual<never, never>
assertType.isFalse(false as A)
assertType.isTrue(true as NotEqual<never, 1>)
assertType.isFalse(false as Equal<never, NotEqual<never, ValueOf<string>>>)
})
Expand Down
27 changes: 8 additions & 19 deletions ts/predicates/Equal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,29 +13,18 @@ import { IsNever } from '../PrimitiveTypes.js'
* Checks if two types are equal.
*/
export type Equal<A, B, Then = true, Else = false> =
[A, B] extends [boolean | string | number | undefined | symbol, boolean | string | number | undefined | symbol]
? (<T>() => T extends A ? 1 : 2) extends (<T>() => T extends B ? 1 : 2) ? Then : Else
: (IsNever<A> extends true
[A, B] extends [object, object]
? (IsNever<A> extends true
? (IsNever<B> extends true ? Then : Else)
: (A extends B ? B extends A ? Then : Else : Else))
: (<T>() => T extends A ? 1 : 2) extends (<T>() => T extends B ? 1 : 2) ? Then : Else
export type IsEqual<A, B> = Equal<A, B>

export type NotEqual<A, B, Then = true, Else = false> =
[A, B] extends [boolean | string | number | undefined | symbol, boolean | string | number | undefined | symbol]
? (<T>() => T extends A ? 1 : 2) extends (<T>() => T extends B ? 1 : 2) ? Else : Then
: (IsNever<A> extends true
? (IsNever<B> extends true ? Then : Else)
[A, B] extends [object, object]
? (IsNever<A> extends true
? (IsNever<B> extends true ? Else : Then)
: (A extends B ? B extends A ? Else : Then : Then))
export type IsNotEqual<A, B> = NotEqual<A, B>
: (<T>() => T extends A ? 1 : 2) extends (<T>() => T extends B ? 1 : 2) ? Else : Then

// export type Equal<A, B, Then = true, Else = false> =
// [A, B] extends [object, object]
// ? (A extends B ? B extends A ? Then : Else : Else)
// : (<T>() => T extends A ? 1 : 2) extends (<T>() => T extends B ? 1 : 2) ? Then : Else
// export type IsEqual<A, B> = Equal<A, B>

// export type NotEqual<A, B, Then = true, Else = false> =
// [A, B] extends [object, object]
// ? (A extends B ? B extends A ? Else : Then : Then)
// : (<T>() => T extends A ? 1 : 2) extends (<T>() => T extends B ? 1 : 2) ? Else : Then
// export type IsNotEqual<A, B> = NotEqual<A, B>
export type IsNotEqual<A, B> = NotEqual<A, B>

0 comments on commit 5aaf0f5

Please sign in to comment.