Typescript 일반 유형 테스트 파트 2

1부 읽기

이제 우리는 유형에 대한 테스트를 만드는 방법을 알고 있지만 아직 완료되지 않았습니다. 처리해야 하는 극단적인 경우가 있으며 문제를 해결하기 전에 몇 가지 이론을 이해해야 합니다.

이제 우리의 Expect 유형을 다시 살펴보십시오.

type Expect<T, U>= T extends U ? U extends T ? true : false : false

TU에 주목하십시오.

네이키드 유형 매개변수라고 합니다.

일종의 변수라고 생각하시면 됩니다.

네이키드 형식 매개변수가 있는 경우 네이키드 형식이 아닌 매개변수도 있으며 예를 들면 다음과 같습니다.
  • 키오브 T
  • 유[]
  • [유]
  • SomeGeneric< T >

  • naked 매개 변수는 공용체에 배포되지만 non-naked 및 유형은 공용체에 배포되지 않습니다(일반 유형과 동일). 이를 이해하려면 아래 코드를 살펴보겠습니다.

    정상:

    type A = "a" | "b" extends "a" ? true : false // false 
    type B = "a" extends "a" | "b" ? true : false // true 
    


    꽤 직설적 인
    "a" | "b""a"에서 좁혀질 수 없습니다.

    네이키드 매개변수:

    type C<T,U> = T extends U ? true : false
    type r1 = C<"a" | "b", "a"> // boolean
    type r2 = C<"a", "a" | "b"> // true
    


    r1의 경우, "a" | "b" "a" | "b"에 분배 시도 : "a""a" | "b" extends "a" is ("a" extends "a"? true : false) | ("b" extends "a"? true : false) , "a" extends "a" is true , 결국 우리는 "b"를 얻습니다.

    r2의 경우 "a"는 합집합이 아니므로 분포가 없고 falsetrue | false에서 좁혀질 수 있으므로 boolean가 된다.

    이 시점에서 우리는 Expect에 무엇이 잘못될 수 있는지 알고 있습니다. 이번에는 테스트 대상으로 사용하겠습니다.

    type OddNumber<
        X extends number,
        Y extends unknown[] = [1],
        Z extends number = never
    > = Y['length'] extends X
        ? Z | Y['length']
        : OddNumber<X, [1, 1, ...Y], Z | Y['length']>
    
    type Expect<T, U> = T extends U ? (U extends T ? true : false) : false
    
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    export const assert = <T extends true>() => {
        //
    }
    
    assert<Expect<OddNumber<5>,1 | 3 | 5>>() // true, pass test
    // @ts-expect-error
    assert<Expect<OddNumber<5>,1>>() // false, fail test
    




    playground

    예상대로 작동하지 않습니다.

    그래서 우리는 그것을 어떻게 고칠 수 있습니까?

    실제로 힌트는 이미 나와 있습니다. 알몸이 아닌 유형 매개변수입니다.

    솔루션은 기본 유형 매개변수를 기본 유형 매개변수가 아닌 유형 매개변수로 변환하는 것이며 가장 안전한 방법은 이를 배열로 바꾸는 것입니다.

    type Expect<T, U>= T[] extends U[] ? U[] extends T[] ? true : false : false
    


    order of union cannot be guaranteed yet

    type Expect<T, U>= [T] extends [U] ? [U] extends [T] ? true : false : false
    
    // don't do this
    


    다시 해보자:


    playground

    파트 1의 예를 통해 다시 확인



    playground

    둘 다 일하고 있습니다!

    파트 2의 끝입니다. 파트 3(아직 준비되지 않음)에서 더 많은 엣지 케이스를 살펴보고 예상 유형을 더 다듬을 것입니다.

    좋은 웹페이지 즐겨찾기