// Feature 타입이 정의된 적이 없다.
// focusOnFeature 함수로 Feature 타입을 작성해 볼 수 있다.
// 하지만 공식 GeoJSON 명세가 있으니 명세를 사용하자.
function focusOnFeature(f: Feature) {
const bounds = calculateBoudingBox(f);
const camera = viewportForBounds(bounds);
setCamera(camera);
const {center: {lat, lng}, zoom} = camera;
zoom;
window.location.search = `?v=@${lat},${lng}z${zoom}`;
}
function calculateBoundingBox(f: Feature): BoundingBox | null {
let box: BoundingBox | null = null;
const helper = (coords: any[]) => {
// ...
};
const {geometry} = f;
if(geometry) {
helper(geometry.coordinates);
}
return box;
}
$ npm install --save-dev @types/geojson
import { Feature } from '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) {
// geometry가 GeometryCollection 타입이 될 수도 있는데
// GeometryCollection에는 coordinates 속성이 없기 때문에 에러 발생.
helper(geometry.coordinates); // 에러 발생.
}
return box;
}
/** DefinitelyTyped로 확인하는 Feature 타입 정의 */
// Feature 타입 정의
export interface Feature<G extends Geometry | null = Geometry, P = GeoJsonProperties> extends GeoJsonObject {
type: 'Feature';
geometry: G;
id?: string | number | undefined;
properties: P;
}
// Geometry 타입 정의
export type Geometry = Point | MultiPoint | LineString | MultiLineString | Polygon | MultiPolygon | GeometryCollection;
// Geometry에서 언급된 타입 정의
export interface Point extends GeoJsonObject {
type: 'Point';
coordinates: Position;
}
export interface MultiPoint extends GeoJsonObject {
type: 'MultiPoint';
coordinates: Position[];
}
export interface LineString extends GeoJsonObject {
type: 'LineString';
coordinates: Position[];
}
export interface MultiLineString extends GeoJsonObject {
type: 'MultiLineString';
coordinates: Position[][];
}
export interface Polygon extends GeoJsonObject {
type: 'Polygon';
coordinates: Position[][];
}
export interface MultiPolygon extends GeoJsonObject {
type: 'MultiPolygon';
coordinates: Position[][][];
}
export interface GeometryCollection<G extends Geometry = Geometry> extends GeoJsonObject {
type: 'GeometryCollection';
geometries: G[];
// GeometryCollection에서는 coordinates 속성이 없다.
}
에러를 해결해보자
// 타입을 체크하는 방법 이용
// 하지만 특정 타입 차단보다는 모든 타입을 지원하는 방법이 더 좋다.
const { geometry } = f;
if(geometry) {
if(geometry.type === 'GeometryCollection') {
throw new Error ('GeometryCollections are not supported');
}
helper(geometry.coordinates); // 정상
}
모든 타입을 지원하는 방법으로 수정해보자
const geometryHelper = (g: Geometry) => {
if(geometry.type === 'GeometryCollection') {
geometry.geometries.forEach(geometryHelper);
} else {
helper(geometry.coordinates); // 정상
}
}
const { geometry } = f;
if(geometry) {
geometryHelper(geometry); // 정상
}
GeometryCollection
같은 예외 상황이 포함되지 않았을 것.```tsx
$ apollo client:codegen \
--endpoint https://api.github.com/graphql \
--includes license.graphql \
--target typescript
```
quicktype
같은 도구가 있다.quicktype은 JSON 객체를 입력하면 그 객체의 interface를 자동으로 만들어준다. ( https://velog.io/@code-bebop/quicktype-TypeScript의-매우-유용한-도우미 )