Optional parameter extended on generic class in TypeScript

Gheorghe Madalina Eleonora
2 min readFeb 13, 2024
Photo by Safar Safarov on Unsplash

Long story short, I have a component which is used in multiple pages.

<child-component [tableData]="tableData"></child-component>

Depending on the page, the input type is different.

const tableDataTypeFromOneParentComponent = [{name: '', surname: ''}];
const tableDataTypeFromOtherParentComponent = [{name: '', surname: '', whateverValue: ''}];

In child’s HTML I have a loop to iterate over those object in the array, and a check to show some data if object.whateverValue is present in the object.

<div *ngFor="let value of tableData; index as rowIndex">
<div *ngIf="tableData[rowIndex].whateverValue">
show something
</div>
</div>

The issue is that this whateverValue is present in 2 of 3 pages, which will require me to add/extend the generic type, so this leads to:

export class ChildComponent<T> {
@Input() public data: T[] = [];
}

Because this is a generic type, and this means we don’t know any of the keys of the object, we get the error: Property 'whateverValue' does not exist on type 'T' from child’s HTML.

The fix for it came as:

private _tableData: (T & {whateverValue: string})[];

public get tableData(): (T & {whateverValue: string})[] {
return this._tableData;
}

@Input() public set tableData(tableData: T[]) {
this._tableData = tableData.map((row: T) => {
return {
...row,
whateverValue:
typeof row['whateverValue' as keyof T] === 'string'
? row['whateverValue' as keyof T]
: 'default',
};
}) as (T & {whateverValue: string})[];
}

Now we are making sure that the property 'whateverValue' exists in every object and is known by the HTML as well, translating in here we have whatever type of object but with 'whateverValue' key in it.

Hope this helps everyone who’s searching to use generic interfaces in Angular but with optional properties used in the HTML of the component.

--

--

Gheorghe Madalina Eleonora

✨ Passionate photographer and FE Developer @Cognizant, former FE Developer at @Deloitte Digital and @IBM.