-
Couldn't load subscription status.
- Fork 13.1k
Description
π Search Terms
mutate array, covariance, covariant, invariance, invariant
π Version & Regression Information
- This is the behavior in every version I tried, and I reviewed the FAQ for entries about covariance and invariance
β― Playground Link
π» Code
I have a grid on which I want to create items by using a helper-function. This function should return a new version of the grid.
The type of the grid is as following:
type Grid = {
items: {
id: string;
name: string;
}[];
};In the create-item function, I thought generics would be a cool idea, so I went for this definition:
const createItem =
<
D extends {
id: string;
},
T extends {
items: D[];
},
>(
createNewItem: () => D,
) =>
(grid: T): T => {
return {
...grid,
items: [...grid.items, createNewItem()],
};
};But when invoking this function, I found a serious flaw in my types:
const createItemOnGrid = (): ((grid: Grid) => Grid) =>
createItem(() => ({
id: 'new_id',
}));π Actual behavior
No error, but data that does not comply with the type when running the code.
π Expected behavior
An error at compile time.
What gave me the expected result was to rewrite the function as following:
const createItem =
<
D extends {
id: string;
},
T extends {
items: D[];
},
>(
createNewItem: () => T["items"][number],
) =>
(grid: T): T => {
return {
...grid,
items: [...grid.items, createNewItem()],
};
};Note that I only changed the definition of createNewItem here.
But with the code provided first, I would like to get an error when adding the element to the array, because the types could be incompatible (as shown).
Additional information about the issue
Someone in discord pointed me to the terms "covariance" and "invariance", and I started reading https://stackoverflow.com/questions/8481301/covariance-invariance-and-contravariance-explained-in-plain-english.
When searching for something in this direction with regards to TypeScript, I came to https://stackoverflow.com/questions/60905518/why-are-typescript-arrays-covariant and further via #1394 to #48240, but I couldn't find a way of getting a helpful result.
I also saw this in the documentation https://www.typescriptlang.org/docs/handbook/2/generics.html#variance-annotations but couldn't see why my approach still should not error out.
Discord thread, where I raised this issue first: https://discord.com/channels/508357248330760243/1430830666865709096