I'm currently working on developing a class called Map
that will store mappings set by other classes, such as CharacterManager
.
I want the content of the map to be determined by other classes, so I have designed the Map
class to accept a generic type that will always extend from object
.
For instance:
// Map.ts
interface MapCellData {
collides: boolean;
}
class Map<CellData extends object = {}> {
map!: Array<Array<CellData & MapCellData>>;
}
// CharacterManager.ts
interface CharacterManagerCellData {
character: null | Character;
}
// Other interfaces...
When examining the type
Array<Array<CellData & MapCellData>>
, the intention is for each cell of the 2D array to contain multiple properties defined by various classes.
However, the problem arises when I have to provide those properties during the initial population of the map.
This does not align with my approach: I prefer the Map
class to remain unaware of what other classes intend to add. Each class should be responsible for supplying its own data, with the Map
class handling the initialization of the map initially so it is accessible to others.
The straightforward solution, in my mind, is to make the CellData
properties optional since they are not set when populating the map for the first time. Any class wanting to utilize it should confirm whether it is set.
Following this logic, I updated
Array<Array<CellData & MapCellData>>
to Array<Array<Partial<CellData & MapCellData>>>
(by adding the Partial
keyword).
Now, the actual issue arises: despite this adjustment, the code does not function as expected, and I am not getting any error details to pinpoint my mistake.
TypeScript simply indicates
Type '{ collides: true; }' is not assignable to type 'Partial<CellData & MapCellData>'.
Below is a complete example that triggers the error:
interface CharacterManagerCellData {
character: null | string;
}
interface CollisionCellData {
collides: boolean;
}
// Using partial without a generic works correctly
type BasicCellData = Partial<CharacterManagerCellData & CollisionCellData>;
const myCell: BasicCellData = {
collides: true
}
// Applying the same pattern with a generic results in a TypeScript error
function myFunc<CellData extends object = {}>() {
type RealCellData = Partial<CellData & CollisionCellData>;
const cell: RealCellData = {
collides: true
}
}
I am using the latest version of TypeScript (3.6.3), and this error persists in the playground