Reputation: 14209
I have a container as follows:
lass BurgerBuilder extends React.Component {
state = {
ingredients: {
salad: 1,
bacon: 1,
cheese: 2,
meat: 2
}
}
render() {
return(
<>
<Burger ingredients={this.state.ingredients}/>
<div>Build Controls</div>
</>
);
}
}
My Burger functional component includes the following code
export interface IBurgerProps {
ingredients: {
salad?: number,
bacon?: number,
cheese?: number,
meat?: number
}
}
const burger = (props: IBurgerProps) =>{
const transformedIngredients = Object.keys(props.ingredients).map(igKey=> {
return [...Array(props.ingredients[igKey])].map((_, i) => {
<BurgerIngredient key={igKey + i} type={igKey}/>
})
});
Theoretically, if I add "chicken: 1" to the ingredient object in my container (BurgerBuilder), I should get an error. I.e, typescript should complain saying we can't assign { salad: number, bacon: number, cheese: number, meat: number, chicken: number } to type { salad: number | undefined, bacon: number | undefined, cheese: number | undefined, meat: number | undefined}
Why is it that I don't get this error when I add "chicken: 1" to the ingredients object in Burger Builder?
Just trying to understand typing and react more.
Upvotes: 1
Views: 691
Reputation: 25800
TypeScript uses what's called a substructural type system, which means as long as your object has everything you asked from it, the rest doesn't really matter.
There is an ongoing discussion around the topic of introducing exact types to the language. Today one needs to employ some questionable tricks to make it work.
In the meantime, I recommend describing the contract between your components with an interface. In this case, Ingredients
are the interface — it's what both components depend on.
Let's abstract it from your component. An example model could look like this:
type IngredientName =
| 'salad'
| 'bacon'
| 'cheese'
| 'meat';
type Ingredients = Record<IngredientName, number>
Usage:
interface Props {}
interface State {
ingredients: Ingredients;
}
export class BurgerBuilder extends React.Component<Props, State> {
state: State = {
ingredients: {
salad: 1,
bacon: 1,
cheese: 2,
meat: 2,
chicken: 2, // Error! Chicken is not on the list.
},
};
}
You can read more about type relationships in the specification.
Upvotes: 3