TypeScript Freshness
--
TypeScript concept Freshness (strict object literal checking) is a way to type check object literals that would otherwise be structurally type compatible.
Those are a lot of confusing words, let’s see some code:
This is the expected behavior, because as stated the people
list accepts only objects of type Person
.
However this only works with object literals!, see the following snippet for clarification:
So what is happening with TypeScript!!
Well the behavior observed while passing an object literal is intended. The reason behind it is that when one is passing an object literal as a method argument, TypeScript has to make sure that there is no excess properties on the passed object literal(EPC or Excess Property Checking), because that could only mean one of two things:
- a typo in the property name.
- a misunderstanding of the exploited api.
From the TypeScript Docs:
“…TypeScript takes the stance that there’s probably a bug in this code. Object literals get special treatment and undergo excess property checking when assigning them to other variables, or passing them as arguments. If an object literal has any properties that the “target type” doesn’t have, you’ll get an error”,
however, we can always get around this behavior using type assertion
:
Be mindful that this decision taken by the TypeScript team(IMHO) is a necessary one, and to demonstrate that I’ll leave you with this last snippet:
In the snippet above, we created a method that takes in an object which can have a property named info
, this property is optional, meaning that the absence of this property on an received object is permissible. However we still received a meaningful error message that would directly point us to the problem rather than failing silently while the developer thinks that he has provided the info
property.
So what can we conclude about Excess Property Checks in TypeScript?
Well TypeScript is a Structural Type System, meaning that TypeScript is fine with you providing extra properties in an object as long as you are also providing it with the necessary properties, one exception to that rule being object literals which are strictly checked.
This may seem like a bug, some may consider it a feature, it sure has sparked a lot of debate across multiple issues on the central TypeScript repository in Github ( #19775, #7547,…), one thing is for sure: types are open in TypeScript, this is a design decision. However, there is a proposal for exact types that can be found here #12936.