잘 설계된 타입은 타입스크립트 사용을 유용하게 해주지만, 그렇지 않은 타입은 우리를 힘들게 한다.
앞서 31장에서 사용했던 boudningBox를 계산하는 함수에서 아래와 같이 쓰였을때 문제 없으나 실제로 해당 geoJson의 타입을 넣게되는 순간 문제가 생긴다.
import {Feature} from "geojson" ;
function calculateBoundingBox(f:Feature):BoundingBox|null{
let box:BoundingBox|null =null;
const helper = (coords:any[]){
}
const {geometry} =f;
if(geometry){
helper(geometry.coordinates)
//geometry에 coordinates가 없음 -> GeometryCollection에서 coordinates 프로퍼티가 없음
}
return box
}
그래서 이를 차단하기 위해 GeometryCollection일때 예외를 던지는 방법으로 해결할 수 있다.
const {geometry} =f;
if(geometry){
if(geometry.type==="GeometryCollection"){
throw new Error("GeometryCollection are not supported")
}
helper(geometry.coordinates)
//geometry에 coordinates가 없음 -> GeometryCollection에서 coordinates 프로퍼티가 없음
}
하지만 부분적으로 에러를 띄워주는거보다 모든 타입을 받아서 해결할 수 있도록 만들어주면 좋다
const geometryHelper = (g:Geometry)=>{
if(geometry.type==="GeometryCollection"){
geometry.geometries.forEach(geometryHelper)
}else{
helper(geometry.coordinates)
}
}
const {geometry} =f;
if(geometry){
geometryHelper(geometry)
}
이와 같은 문제가 생긴이유는 Geojson이라는 데이터에 의존해서 타입을 만들어서 야기된 문제이다.
GraphQL 처럼 자체적인 타입이 정의된 API에서 잘 동작한다. 쿼리에서 타입을 생성하기 위해 GraphQL 스키마가 필요하고 Apollo를 통해 스키마를 얻는다. 이를 통해 명세로부터 타입을 가져올 수 있고, 타입과 실제 값이 항상 일치하여 좋다!
우리가 프론트엔드 개발자로서 실제로 프론트엔드 개발하기 위해 책의 내용처럼 인터페이스를 보고 타입을 지정해서 개발해야하며, 실제로 작업하기전에 백엔드 개발자와 미리 스키마에 대한 협의를 하고 개발하면 좋을것 같다.
snakeCase, cammelCase 혹은 idx, index 등등 실제로 작업하다보면 똑같은 값임에도 idx, index로 이름이 달라 혼동을 야기할 수 있기에 백엔드랑 미리 협의해서 데이터에 대한 명세를 미리 맞추면 좋다.
그래서 위와 같이 생성했다면 앞서 설명했던 Swagger나 Postman 같은 어플리케이션을 사용해서 인터페이스에 대한 소통을 진행한다.