-
Notifications
You must be signed in to change notification settings - Fork 6.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(table): typescript/strong typing of cell templates #22290
Comments
Very simple repro: <table mat-table [dataSource]="[{ hello: 'world' }]">
<tr mat-cell *matCellDef="let element">
{{
element.test
}}
</tr>
</table> Generates the following typecheck block with Ivy: import * as i0 from 'some.component';
import * as i1 from '@angular/material/table';
const _ctor1: <T = any>(init: Pick<i1.MatTable<T>, "trackBy" | "dataSource"> & {
multiTemplateDataRows: typeof i1.MatTable.ngAcceptInputType_multiTemplateDataRows;
fixedLayout: typeof i1.MatTable.ngAcceptInputType_fixedLayout;
}) => i1.MatTable<T> = (null!);
/*tcb1*/
function _tcb1(ctx: i0.SomeComponent) { if (true) {
ctx. /*D:ignore*/ /*T:COMPCOMP*/;
var _t1 = document.createElement("table") /*96,149*/;
var _t2 /*T:DIR*/ /*96,149*/ = _ctor1({ "dataSource": ([{
"hello": "world" /*137,144*/
} /*128,146*/] /*127,147*/) /*113,148*/, "trackBy": (null as any), "multiTemplateDataRows": (null as any), "fixedLayout": (null as any) }) /*D:ignore*/;
_t2.dataSource /*114,124*/ = ([{
"hello": "world" /*137,144*/
} /*128,146*/] /*127,147*/) /*113,148*/;
var _t3: i1.MatCellDef /*T:DIR*/ /*152,191*/ = (null!);
var _t4: any = (null!);
{
var _t5 /*182,189*/ = _t4.$implicit /*178,189*/;
var _t6 = document.createElement("tr") /*152,191*/;
"" + (((_t5 /*205,212*/).test /*213,218*/) /*205,218*/);
}
} }
export const IS_A_MODULE = true; The correct type is available as part of the If |
Here's a working workaround for this. Most of the credits for it go to @nartc 🏆 , on the Angular Discord. import { CdkCellDef } from '@angular/cdk/table';
import { Directive, Input } from '@angular/core';
import { MatCellDef } from '@angular/material/table';
import { Observable } from 'rxjs';
@Directive({
selector: '[matCellDef]', // same selector as MatCellDef
providers: [{ provide: CdkCellDef, useExisting: TypeSafeMatCellDef }],
})
export class TypeSafeMatCellDef<T> extends MatCellDef {
@Input() matCellDefDataSource: T[] | Observable<T[]> | MatTableDataSource<T>;
static ngTemplateContextGuard<T>(
dir: TypeSafeMatCellDef<T>,
ctx: any,
): ctx is { $implicit: T; index: number } {
return true;
}
} You can add this directive to your <table mat-table [dataSource]="data">
...
<td mat-cell *matCellDef="let element; dataSource: data">
{{ element.hello }}
</td> And There's a bit of redundancy, with needing to specify the data source in every |
Do not forget to follow the steps at Under the hood of the language service to properly enable this workaround.
|
Is there a solution which would only require 1 change per table instead of 1 change per column? |
+1 |
I feel like this issue belongs under @angular/core instead of @angular/components. The fix should allow providing type through a parent directive. Maybe it would work if static ngTemplateContextGuard<T, P>(
thisdirective: ThisDirective<T>,
parentDirective: ParentDirective<P>
ctx: unknown
): ctx is { $implicit: T, parent: P } {
return true;
} |
Still waiting for this feature to be integrated in Angular as loosing types in table is still a big disadvantage. |
Would love to get this one as well... 🙏 |
For simply using the table reference version you can search-replace with following regex \*matCellDef="let (\w*)"
↓
*matCellDef="let $1; table: table" And Finds lots of real type errors. |
Feature Description
Currently,
*matCellDef
types the resulting variable asany
:This issue is an attempt to bring #16273 back in discussion, which has been closed as Ivy wasn't yet available.
There has been some progress on several fronts:
strictTemplates
mode.It appears that the approach described in this comment angular/angular#28731 (comment) might allow this to be implemented.
Use Case
As we've been converting more code to use Material Data Tables, the lack of strong typing has been really problematic, and it feels like a downgrade in developer experience compared to regular tables with
*ngFor
.Further motivation for this has been described in:
#16273
angular/angular#28731
The text was updated successfully, but these errors were encountered: