Skip to content

Commit

Permalink
fix: handle never case
Browse files Browse the repository at this point in the history
  • Loading branch information
unional committed Sep 12, 2022
1 parent 4ad548a commit f8376ff
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 8 deletions.
2 changes: 1 addition & 1 deletion ts/array/Concat.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ test('concat tuples', () => {

test('concat array to tuple', () => {
type A = Concat<string[], [1, 2, 3]>
isType.t<Equal<Array<string | 1 | 2 | 3>, A>>()
isType.t<Equal<[...string[], 1, 2, 3], A>>()
})

test('concat tuple to array', () => {
Expand Down
1 change: 1 addition & 0 deletions ts/object/ValueOf.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@

export type ValueOf<T> = T[keyof T]
13 changes: 12 additions & 1 deletion ts/predicates/Equal.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { assertType, Equal, NotEqual } from '../index.js'
import { assertType, Equal, NotEqual, ValueOf } from '../index.js'

describe('Equal<A, B>', () => {
test('match', () => {
Expand Down Expand Up @@ -59,6 +59,12 @@ describe('Equal<A, B>', () => {
assertType.isTrue(true as Equal<{ a: number, b: string }, { a: number } & { b: string }>)
assertType.isTrue(true as Equal<{ a: number, b?: string }, { a: number } & { b?: string }>)
})

it('works with never type', () => {
assertType.isTrue(true as Equal<never, never>)
assertType.isFalse(false as Equal<never, 1>)
assertType.isFalse(false as Equal<1, never>)
})
})

describe('NotEqual<A, B>', () => {
Expand All @@ -77,4 +83,9 @@ describe('NotEqual<A, B>', () => {
assertType.isFalse(false as NotEqual<{ a: number, b: string }, { a: number } & { b: string }>)
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>)
assertType.isTrue(true as NotEqual<never, 1>)
assertType.isFalse(false as Equal<never, NotEqual<never, ValueOf<string>>>)
})
})
16 changes: 10 additions & 6 deletions ts/predicates/Equal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,17 @@
* Checks if two types are equal.
*/
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
[A, B] extends [boolean | string | number, boolean | string | number]
? (<T>() => T extends A ? 1 : 2) extends (<T>() => T extends B ? 1 : 2) ? Then : Else
: ([A] extends [never]
? ([B] extends [never] ? Then : Else)
: (A extends B ? B extends A ? Then : Else : 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
[A, B] extends [boolean | string | number, boolean | string | number]
? (<T>() => T extends A ? 1 : 2) extends (<T>() => T extends B ? 1 : 2) ? Else : Then
: ([A] extends [never]
? ([B] extends [never] ? Then : Else)
: (A extends B ? B extends A ? Else : Then : Then))
export type IsNotEqual<A, B> = NotEqual<A, B>

0 comments on commit f8376ff

Please sign in to comment.