Skip to content

Difference between the Equal Type implemented in the Type Challenge Repository and the Equal Type in this issue. #34874

@iamkanguk97

Description

@iamkanguk97

I have a question while solving the Merge problem of the medium level.
Here is the source code I implemented the Merge type.

type Merge<F, S> = Omit<F, keyof S> & S

/* _____________ Test Cases _____________ */
import type { Equal, Expect } from '@type-challenges/utils'

type Foo = {
  a: number
  b: string
}
type Bar = {
  b: number
  c: boolean
}

type cases = [
  Expect<Equal<Merge<Foo, Bar>, {
    a: number
    b: number
    c: boolean
  }>>
]

I don't understand why my solution is wrong. So I looked to see if the Equal type was incorrect.

I checked the two links above. The Equal Type source code provided in the link is as follows.

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

So, I tried changing the Equal Type.
(This Equal Type was referenced from another repository)

// My custom equal type
type Expression<X> = <T>() => T extends X ? 1 : 2;
export type Equal<X, Y> = Expression<X> extends Expression<Y> ? true : false;

Afterwards, I checked the answers and the results were printed correctly, saying they were the same.
Below is the source code for the two cases I organized myself.

/**
 * CASE3
 */
namespace case3 {
  type Foo = {
    a: number;
    b: string;
  };
  type Coo = {
    b: number;
    c: boolean;
  };
  type Expected = {
    a: number;
    b: number;
    c: boolean;
  }

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

  type CompareExpected = Omit<Foo, keyof Coo> & Coo;

  type TC1 = Equal3<Expected, CompareExpected>;   // false
  type TC2 = Equal3<{ a: 3, b: 5 }, { a: 3 } & { b: 5 }>;   // false
  type TC3 = Equal3<{ a: 3, b: 5 }, { a: 3, b: 5 }>;   // true
}

/**
 * CASE4
 */
namespace case4 {
  type Foo = {
    a: number;
    b: string;
  };
  type Coo = {
    b: number;
    c: boolean;
  };
  type Expected = {
    a: number;
    b: number;
    c: boolean;
  }

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

  type CompareExpected = Omit<Foo, keyof Coo> & Coo;

  type TC1 = Equal4<Expected, CompareExpected>;   // true
  type TC2 = Equal4<{ a: 3, b: 5 }, { a: 3 } & { b: 5 }>;   // true
  type TC3 = Equal4<{ a: 3, b: 5 }, { a: 3, b: 5 }>;   // true
}

What I'm ultimately curious about is what's different between the Equal Type I wrote and the Equal type that implemented in the Type Challenge Util Type.

Also, if the Equal Type implemented in the Type Challenge is correct, I don't understand why my answer to the Merge problem is wrong.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions