Typescript 일반 유형 테스트 파트 1
20787 단어 tutorialtypescriptprogrammingwebdev
그 중 일부는 유형 조작 논리의 큰 덩어리로 끝납니다.
그렇다면 우리의 유형이 작동하는지 어떻게 확신할 수 있으며 어떻게 우리의 유형을 테스트할 수 있습니까?
간단하면서도 어려운 것으로 밝혀졌지만 먼저 간단한 부분에 초점을 맞출 것입니다.
테스트 대상으로 삼자
type GetCountOfSubString<
String_ extends string,
SubString extends string,
Count extends unknown[] = []
> = String_ extends `${string}${SubString}${infer Tail}`
? GetCountOfSubString<Tail, SubString, [1, ...Count]>
: Count['length']
type NumberOfA = GetCountOfSubString<"a--a--aa--a","a"> // 5
우리는
GetCountOfSubString<"a--a--aa--a","a">
가 항상 5
가 되도록 하고 싶습니다.기본적으로 둘 다 서로를 확장해야합니다
다음으로 체커를 만듭니다. 체커는 두 부분으로 구성됩니다.
첫 번째는 Expect입니다. 두 유형이 서로 확장되는지 확인하고 싶습니다.
type Expect<T, U>= T extends U ? U extends T ? true : false : false
type r1 = Expect<GetCountOfSubString<"a--a--aa--a","a">,5> // true, success check
type r2 = Expect<GetCountOfSubString<"a--a--aa--a","a">,1> // false, fail check
playground
지금까지는 원하는 결과를 얻었습니다. 결과가 올바르면 유형이 true이고 결과가 올바르지 않으면 false입니다.
하지만 tsc로 유형 검사를 실행할 때 뭔가 빠져 있습니다.
아무 일도 일어나지 않습니다. 이것은 단순히 유형을 true와 false로 반환하고 그것에 대해 유효하지 않은 것이 없기 때문에 typescript는 불평하지 않습니다.
그래서 두 번째 부분인 어설션이 필요합니다.
type Assert<T extends true> = T // be anything after '=', doesn't matter
그들을 적용
type Expect<T, U>= T extends U ? U extends T ? true : false : false
type Assert<T extends true> = T // be anything after '=', doesn't matter
type r1 = Assert<Expect<GetCountOfSubString<"a--a--aa--a","a">,5>> // true, pass test
type r2 = Assert<Expect<GetCountOfSubString<"a--a--aa--a","a">,1>> // false, fail test
이제 실패 테스트가 실패했음을 알 수 있으며 tsc를 실행하면 콘솔에서 오류를 볼 수 있습니다.
하지만 아직 옳지 않은 것이 있습니다. 무엇입니까?
글쎄요, 실패 테스트는 실패해야 하며, 예상되는 대로 오류를 유발해서는 안 됩니다
그래서 우리는 원점으로 돌아왔습니까?
아니요, 더 가깝습니다.
@ts-expect-error
주석을 사용하여 해결하는 방법은 다음과 같습니다.type r1 = Assert<Expect<GetCountOfSubString<"a--a--aa--a","a">,5>> // true, pass test
// @ts-expect-error
type r2 = Assert<Expect<GetCountOfSubString<"a--a--aa--a","a">,1>> // false, fail test
playground
더 이상 유형 검사 오류가 없습니다.
@ts-expect-error
라인에 오류가 있는 경우에만 오류를 억제합니다. 그렇지 않고 완벽하게 괜찮은 라인에서 사용하면 TS가 대신 오류를 표시하며 이것이 우리가 원하는 동작입니다.GetCountOfSubString에 버그가 있는지 살펴보겠습니다. 예상대로 작동할까요?
통과 테스트에 실패하도록 합시다.
type GetCountOfSubString<
String_ extends string,
SubString extends string,
Count extends unknown[] = []
> = "BUG!!"
type Expect<T, U>= T extends U ? U extends T ? true : false : false
type Assert<T extends true> = T // be anything after '=', doesn't matter
type r1 = Assert<Expect<GetCountOfSubString<"a--a--aa--a","a">,5>> // true, pass test
// @ts-expect-error
type r2 = Assert<Expect<GetCountOfSubString<"a--a--aa--a","a">,1>> // false, fail test
playground
실패 테스트에 실패하도록 합시다.
type GetCountOfSubString<
String extends string,
SubString extends string,
Count extends unknown[] = []
> = 1
type Expect<T, U>= T extends U ? U extends T ? true : false : false
type Assert<T extends true> = T // be anything after '=', doesn't matter
type r1 = Assert<Expect<GetCountOfSubString<"a--a--aa--a","a">,5>> // true, pass test
// @ts-expect-error
type r2 = Assert<Expect<GetCountOfSubString<"a--a--aa--a","a">,1>> // false, fail test
playground
예, 작동합니다!
그러나 아직 끝나지 않았습니다. eslint와 같은 linter를 사용하는 경우 유형이 선언되었지만 사용되지 않는다고 불평합니다.
그것을 해결하는 두 가지 방법이 있습니다:
먼저 우리는 그들을 내보낼 수 있습니다
또는 대신 Assert를 함수로 바꿉니다.
// eslint-disable-next-line @typescript-eslint/no-unused-vars
export const assert = <T extends true>() => {
//
}
assert<Expect<GetCountOfSubString<'a--a--aa--a', 'a'>, 5>>() // true, pass test
// @ts-expect-error
assert<Expect<GetCountOfSubString<'a--a--aa--a', 'a'>, 1>>() // false, fail test
playground
두 번째 방법이 권장되며 모든 어설션에 대해 새 유형을 생성할 필요가 없기 때문에 더 짧습니다.
파트 1은 여기까지입니다. 어려운 부분인 몇 가지 엣지 케이스를 처리하겠습니다.
Reference
이 문제에 관하여(Typescript 일반 유형 테스트 파트 1), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/tylim88/typescript-test-your-generic-type-part-1-4jbc텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)