19. Parse, don’t validate
https://lexi-lambda.github.io/blog/2019/11/05/parse-don-t-validate/
- 검증만 하지 말고, 타입으로 증명을 보존할 것.
// ❌ 나쁜 예: 검증 (Validation)
function validateNonEmpty(list: string[]): void {
if (list.length === 0) throw new Error("Empty!");
// 정보를 버림 - 타입이 여전히 string[]
}
// ✅ 좋은 예: 파싱 (Parsing)
type NonEmptyArray<T> = [T, ...T[]];
function parseNonEmpty<T>(list: T[]): NonEmptyArray<T> {
if (list.length === 0) throw new Error("Empty!");
return list as NonEmptyArray<T>;
// 정보를 타입에 보존 - 이제 NonEmptyArray<T>
}
shotgun parsing 방지
- 검증 로직이 코드 곳곳에 흩어지면 -> 어디서 검증했는지 추적 불가
- 일부만 검증된 데이터를 사용 -> 런타임 에러 폭탄
타입 시스템의 힘 활용 & 코드의 신뢰도 향상
- 컴파일 타임에 불가능한 상태를 차단
- 한 번 파싱하면 → 이후 재검증 불필요
// 이 함수는 안전한가?
function processData(data: any[]) {
// data가 비어있을 수도...?
// 중복이 있을 수도...?
// null이 섞여있을 수도...?
}
// vs
function processData(data: NonEmptyArray<ValidUser>) {
// 타입만 봐도 안전함을 알 수 있음
}
즉, 아예 불가능한 상태를 타입으로 검증해놓을 것.
단순히 error throw 만 하지말고, 타입시스템을 사용하여 런타임 에러 방지.
넘나리 당연한 얘기 같지만 typescript 사용하면서도 잘 활용못하는 경우가 많은듯.