Item 42: Avoid Types Based on Anecdotal Data
May 10, 2024 ยท View on GitHub
Things to Remember
- Avoid writing types by hand based on data that you've seen. It's easy to misunderstand a schema or get nullability wrong.
- Prefer types sourced from official clients or the community. If these don't exist, generate TypeScript types from schemas.## Code Samples
function calculateBoundingBox(f: GeoJSONFeature): BoundingBox | null {
let box: BoundingBox | null = null;
const helper = (coords: any[]) => {
// ...
};
const {geometry} = f;
if (geometry) {
helper(geometry.coordinates);
}
return box;
}
interface GeoJSONFeature {
type: 'Feature';
geometry: GeoJSONGeometry | null;
properties: unknown;
}
interface GeoJSONGeometry {
type: 'Point' | 'LineString' | 'Polygon' | 'MultiPolygon';
coordinates: number[] | number[][] | number[][][] | number[][][][];
}
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);
// ~~~~~~~~~~~
// Property 'coordinates' does not exist on type 'Geometry'
// Property 'coordinates' does not exist on type 'GeometryCollection'
}
return box;
}
const {geometry} = f;
if (geometry) {
if (geometry.type === 'GeometryCollection') {
throw new Error('GeometryCollections are not supported.');
}
helper(geometry.coordinates); // OK
}
const geometryHelper = (g: Geometry) => {
if (g.type === 'GeometryCollection') {
g.geometries.forEach(geometryHelper);
} else {
helper(g.coordinates); // OK
}
}
const {geometry} = f;
if (geometry) {
geometryHelper(geometry);
}