Im working on an Angular 17 app where I have to apply specific interface according to a type in a generic interface.
First, I have the enum with all my block types
export enum BlockTypes {
text = 'TEXT',
check = 'CHECKBOX',
header1 = 'HEADER1',
table = 'TABLE',
container = 'CONTAINER',
};
And it could be added more. So every block type has it's own configuration that I want to have in a separate interface.
// interface for block type Text
export interface BlockText {
content: string;
}
// interface for block type Text
export interface BlockChecklist {
list: {
label: string;
checked: boolean
}[];
}
// interface for block type Header
export interface BlockHeader {
content: string;
level: number;
}
// interface for block type table
export interface BlockTable {
fullWidth: boolean;
columns: string[];
data: { selected: boolean, data: BlockItem<BlockTypes>[] }[];
}
// interface for block type container
export interface BlockContainer{
columns: { order: number, data: BlockItem<BlockTypes>[] }[];
}
So now I want a generic interface named BlockItem to apply the specific interface according to the type I want to create.
So I was trying to create that generic model and send the type as a type parameter, but I'm having an error.
export interface BlockItem<T extends BlockTypes> {
blockType: T;
// Here I'm having the error 'Type 'T' cannot be used to index type 'BlockModel'.'
data: BlockModel[T];
}
export interface BlockModel {
[BlockTypes.text]: BlockText;
[BlockTypes.check]: BlockChecklist;
[BlockTypes.header1]: BlockHeader;
[BlockTypes.table]: BlockTable;
[BlockTypes.container]: BlockContainer;
}
The result that I expect is to create variables like this examples:
const exampleBlockText: BlockItem<BlockTypes.text> = {
blockType: BlockTypes.text,
data: { content: 'Hello, World!' },
};
const exampleBlockCheck: BlockItem<BlockTypes.check> = {
blockType: BlockTypes.check,
data: { list: [ { label: 'Option 1', checked: false }, { label: 'Option 2', checked: false } ] },
};
I'm avoiding to use the "any"type because what I want is to have specific interfaces to each one.
How can I create a generic model with specific interface according to the type sended?
UPDATE:
I am using Angular 17 and this is the tsconfig.json
{
"compileOnSave": false,
"compilerOptions": {
"baseUrl": "./",
"outDir": "./dist/out-tsc",
"forceConsistentCasingInFileNames": true,
"strict": false,
"noImplicitOverride": true,
"noPropertyAccessFromIndexSignature": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"sourceMap": true,
"declaration": false,
"downlevelIteration": true,
"experimentalDecorators": true,
"moduleResolution": "node",
"importHelpers": true,
"target": "ES2022",
"module": "ES2022",
"useDefineForClassFields": false,
"lib": [
"ES2022",
"dom"
]
},
"angularCompilerOptions": {
"enableI18nLegacyMessageIdFormat": false,
"strictInjectionParameters": true,
"strictInputAccessModifiers": true,
"strictTemplates": true
}
}