Scenario
The “doStuff” team at your company created a function for you to use
function doStuff({ x, y, z }: { x: number; y: number; z?: number }) {
console.log({ x, y, z })
}
Then, you diligently call it in your code like this
const obj = { x: 1, y: 2, z: 3 }
doStuff(obj)
all fine and good
Later on, the optional “prop” is renamed
The doStuff team says, well, it’s not really a true “z coordinate”…it’s more
of a “z-index” so they change the function definition to be
function doStuff({ x, y, zIndex }: { x: number; y: number; zIndex?: number }) {
console.log({ x, y, zIndex })
}
Now you might have a bug
Since zIndex is optional, TypeScript will not warn you about zIndex not
being supplied by your existing code. Typescript is also not bothered that you
have this “rider” variable z that “does nothing” in this case.
const obj = { x: 1, y: 2, z: 3 }
doStuff(obj) // no typescript error, z is no longer used, zIndex is optional, and you don't get the behavior you want
But wait, why didn’t TypeScript catch it?
Here is the funny thing:
-
TypeScript DOES NOT catch this issue when you pass it via this separately created “obj” variable.
-
TypeScript DOES(!!!) catch this issue when you pass it directly to the function (as an “object literal”)
doStuff({ x: 1, y: 2, z: 3 }) // ERROR!
// Object literal may only specify known properties, and 'z' does not exist in type '{ x: number; y: number; zIndex?: number | undefined; }'.
Demo playground
Footnote
I am certainly not the only person to come across this “topic/issue”, and people often come across it in different contexts.
My particular take away is to “be careful when you rename optional props”. Of course, changing any API comes with risks, but this one particularly :)
More resources
Typescript Deep Dive - “Freshness”
https://basarat.gitbook.io/typescript/type-system/freshness
Follow up
This post was given lots of downvotes in /r/typescript and sarcasm that “no duh, breaking changes are breaking”.
However, some helpful comments were made. Read on https://www.reddit.com/r/typescript/comments/1fk1rqe/be_careful_when_you_rename_an_optional_prop_in/
I think maybe people are distracted that I posited this as the “doStuff team” vs “you”, but keep in mind this could just be your left brain vs right brain in an actively developed codebase