The Typo That TypeScript Hid From Me
I spent a good chunk of time debugging a silent failure in a React Native app. I was integrating the Google Routes API v2 to draw polylines and compute distance/duration between two coordinates. The API kept returning an empty object {} despite a 200 OK response.
After ruling out field mask issues, API key restrictions, and billing problems — all the usual suspects — I added granular logs directly inside the fetch function:
console.log("START COORDS:", JSON.stringify(start));
console.log("END COORDS:", JSON.stringify(end));
The output:
START COORDS: {"latitude":6.450904}
END COORDS: {"latitude":6.4696}
No longitude. The Routes API received an incomplete request body and returned {} silently.
But when I logged the raw data from the parent component:
console.log(schedule?.pickup_coord);
// {"latitude": 6.450904, "longitide": 3.390147}
There it was — longitide instead of longitude. A missing u.
Here’s where it gets interesting.
My custom hook accepted coordinates typed as LatLng:
type LatLng = {
latitude: number;
longitude: number;
};
When the object { latitude: 6.450904, longitide: 3.390147 } was cast with as LatLng, TypeScript didn’t complain. The cast silenced any structural mismatch. At runtime, accessing .longitude on that object returned undefined — and undefined serialized into the request body as a missing field entirely.
The Routes API received:
{
"origin": {
"location": {
"latLng": {
"latitude": 6.450904,
"longitude": undefined
}
}
}
}
Which JSON.stringify quietly drops, producing:
{
"origin": {
"location": {
"latLng": {
"latitude": 6.450904
}
}
}
}
A perfectly valid JSON object. No error thrown. No warning logged. Just a silent wrong request — and a silent empty response.
The real lesson here isn’t just “check your typos.”
It’s that as SomeType in TypeScript is an assertion, not a validation. You’re telling the compiler “trust me, this is the right shape” — and it does. Completely. If the runtime data doesn’t match, TypeScript has no way to know.
The safer pattern is a runtime validator or a mapping function that explicitly pulls the fields you need:
const toLatLng = (coord: any): LatLng => ({
latitude: coord?.latitude,
longitude: coord?.longitude,
});
This way, even if the upstream data has a typo, the mapping makes the missing field explicit — and you catch a { latitude: 6.450904, longitude: undefined } object before it ever reaches your API call, rather than getting a silent {} response from a server later.
Two layers failed here: a typo in the data source, and an unchecked as cast that let it through undetected.
Top comments (0)