// your answers
// type Length<T> = T extends Array<any> ? T['length'] : Error // 내가 생각한 답
type Length<T extends readonly any[]> = T['length'] // 정답
type Length의 두 가지 버전 중 첫 번째가 답이 될 수 없고, 두 번째가 정답인 이유는 TypeScript의 타입 시스템이 엄격한 제약 조건을 요구하기 때문입니다. 각각의 차이점을 분석해보겠습니다.
1. type Length = T extends Array ? T['length'] : Error
이 버전은 타입 T가 배열인지 아닌지를 검사하기 위해 T extends Array 조건을 사용합니다. 여기서 문제가 되는 이유는 다음과 같습니다:
1-1. 타입의 유효성 문제
- T['length']는 T가 배열 타입임을 보장받은 경우에만 사용할 수 있습니다.
- 하지만 T extends Array 조건을 사용하더라도 TypeScript는 타입 내에서 타입 안전성을 완전히 보장하지 않습니다.
- 즉, 조건이 참인 경우(T extends Array일 때)라도 TypeScript는 T['length']가 항상 유효하다고 추론하지 않을 수 있습니다.
1-2. 반환값이 Error인 문제
- 조건에 의해 T가 배열이 아닌 경우, 반환 타입은 Error가 됩니다.
- 그러나 문제에서 요구된 제약 사항은 **배열(튜플)**에 대해서만 동작해야 한다는 것이지, 배열이 아닌 경우 특별한 에러 타입을 반환하라는 요구는 없습니다.
- Error 타입은 실제로 타입 체커에 의해 사용되지 않으며, 이는 의도와 맞지 않습니다.
2. type Length<T extends readonly any[]> = T['length']
이 버전은 정답입니다. 이유는 다음과 같습니다:
2-1. 제네릭 제약을 사용한 강제 조건
- T extends readonly any[]는 T가 읽기 전용 배열 또는 튜플임을 강제합니다.
- 이로 인해 T가 배열이 아닌 경우(예: number, string) 타입 체커 단계에서 컴파일 에러를 발생시킵니다.
- 이 제약은 TypeScript의 타입 시스템 강제 조건을 활용한 가장 안전한 방식입니다.
- 예를 들어, 다음과 같은 경우 컴파일 에러가 발생합니다:
type Test = Length<5>; // Error
type Test2 = Length<'hello world'>; // Error
2-2. T['length']의 타입 안전성
- T['length']는 배열이나 튜플 타입에서만 유효합니다.
- T extends readonly any[] 조건을 통해 T가 배열임을 이미 보장받았으므로, T['length']는 항상 안전하게 사용할 수 있습니다.
- 예:
const tesla = ['tesla', 'model 3', 'model X', 'model Y'] as const;
type TeslaLength = Length<typeof tesla>; // 4
2-3. 더 간결하고 명확한 타입
- type Length<T extends readonly any[]> = T['length']는 조건문을 생략하여 더 간결하며, 불필요한 타입 분기를 제거합니다.
- 타입 시스템에서 처리할 논리가 단순해지고, 타입 추론 및 검증도 효율적으로 작동합니다.
결론
- type Length = T extends Array ? T['length'] : Error는 컴파일러가 타입 안전성을 충분히 보장하지 못하며, 문제에서 요구된 범위(배열 또는 튜플)에 대해 정확히 동작하지 않습니다.
- 반면 type Length<T extends readonly any[]> = T['length']는 강제적인 제약을 통해 문제의 요구 사항을 정확히 만족시키고, 컴파일 단계에서 잘못된 입력을 차단할 수 있습니다.
type Length의 두 가지 버전 중 첫 번째가 답이 될 수 없고, 두 번째가 정답인 이유는 TypeScript의 타입 시스템이 엄격한 제약 조건을 요구하기 때문입니다. 각각의 차이점을 분석해보겠습니다.
1. type Length = T extends Array ? T['length'] : Error
이 버전은 타입 T가 배열인지 아닌지를 검사하기 위해 T extends Array 조건을 사용합니다. 여기서 문제가 되는 이유는 다음과 같습니다:
1-1. 타입의 유효성 문제
1-2. 반환값이 Error인 문제
2. type Length<T extends readonly any[]> = T['length']
이 버전은 정답입니다. 이유는 다음과 같습니다:
2-1. 제네릭 제약을 사용한 강제 조건
2-2. T['length']의 타입 안전성
2-3. 더 간결하고 명확한 타입
결론