Adrian Brand
Adrian Brand

Reputation: 21638

Type inference and inheritance in Angular templates

If I have a table component

TableComponent<T extends object, K extends keyof T> {
  ...

  Input()
  data!: T[];

  ContentChildren(ColumnComponent<K>)
  columns!: QueryList<ColumnComponent<K>>;

  ...
}

and a column component

ColumnComponent<K> {
  ...

  Input()
  property!: K;

  ...
}

and I use it like

<app-table [data]="someArray">
  <!-- Can I get a warning here to say some of the child components are not of type K -->
  <app-column property="validProperty" />
  <app-column property="anotherValidProperty" />
  <app-column property="invalidProperty" />
  <app-column [property]="'anotherInvalidProperty'" />
  <!-- I would like a warning here to show that some of the properties are not valid -->
<app-table>

Is it possible to get the column components to inherit the keys type from the parent table component so that they are strongly typed against the properties of the data array. Or maybe have the table show a warning that the some of the children are not of type K.

Here is a StackBlitz https://stackblitz.com/edit/stackblitz-starters-q3pgtp?file=src%2Fmain.html

Upvotes: 2

Views: 201

Answers (1)

Avraham Weinstein
Avraham Weinstein

Reputation: 894

I think that the only way you can achive this is if you'll pass the data of your table into each ColumnComponent as well, and make it also get the two generic types <T extends object, K extends keyof T> like in the parent TableComponent. In This way, typescript will be aware that the K type must be a keyof T.

Attached is your Stackblitz with the relevants additions, you will see that the desired warnings occurred.

Of course, if you got nothing to do with the data property in the ColumnComponent - consider if it worth it to add it there just for types handling. But I don't think you can achive your goal in a different way.

Upvotes: 0

Related Questions