bh2980.dev

XXX - Equal

  • #TypeScript
  • #Type Challenges

질문

두 타입이 완전히 동일한지 비교하는 Equal<A, B> 타입을 구현하세요.

type A = Equal<1, 1>            // true
type B = Equal<1, number>       // false
type C = Equal<true, boolean>   // false
type D = Equal<{ a: number }, { a: number }> // true
type E = Equal<{ a: number }, { readonly a: number }> // false

// !collapse(1:30) collapsed
/* _____________ 테스트 케이스 _____________ */
import type { Expect } from '@type-challenges/utils'

type cases = [
  // primitive & literal
  Expect<Equal<Equal<1, 1>, true>>,
  Expect<Equal<Equal<1, number>, false>>,

  // union
  Expect<Equal<Equal<1 | 2, 2 | 1>, true>>,
  Expect<Equal<Equal<1 | 2, 1>, false>>,

  // object (structural vs modifier)
  Expect<Equal<Equal<{ a: number }, { a: number }>, true>>,
  Expect<Equal<Equal<{ a: number }, { readonly a: number }>, false>>,

  // special case: any
  Expect<Equal<Equal<any, any>, true>>,
  Expect<Equal<Equal<any, number>, false>>,
]

선행 지식

  1. extends할당(대입) 가능성을 검사한다.
any extends string ? true : false // true
string extends any ? true : false // true

흔히 TypeScript의 타입 시스템은 집합에 비유되곤 하지만, (*에 대하여) any라는 특수 케이스 때문에 완벽히 동일하지는 않다. 따라서 A extends Btrue이고 B extends Atrue라고 이 둘이 동일하다는 동등성을 보장하지는 못한다.

풀이