In general, you defined the columns based in your array like:
<ng-container *ngFor="let column of tableColumns;let first=first">
<ng-container [matColumnDef]="column.dataKey">
<th [style.width]="column.width" mat-header-cell *matHeaderCellDef>
{{column.name}}
</th>
<td [style.width]="column.width" mat-cell
*matCellDef="let element"> {{element[column.dataKey]}}
</td>
</ng-container>
</ng-container>
And your displayedColumns as
this.displayedColumns=this.tableColumns.map(x=>x.dataKey)
NOTE: I supose you defined the width as '50%' or '30px' if only use a number you can use, e.g.
[style.width]="column.width+'px'"
Update imagine you want to create a column with actions buttons, but this buttons can be one, two or three. We can asign to this last colum a width of "1%" and 'white-space: nowrap'
//we has two variables
btDelete:boolean=true;
btEdit:boolean:true;
<ng-container matColumnDef="action">
<th style="width:1%" mat-header-cell *matHeaderCellDef>
</th>
<td style="width:1%;white-space: nowrap;" mat-cell
*matCellDef="let element">
<button *ngIf="btEdit" mat-button (click)="edit(element)">Edit</button>
<button *ngIf="btDelete" mat-button (click)="delete(element)">Delete</button>
</td>
</ng-container>
NOTE: I'm not prety sure what happens with the width of columns because the % total is bigger that 100%
We can try using the mat-table in flex-mode
<ng-container *ngFor="let column of columns">
<ng-container [matColumnDef]="column.name">
<mat-header-cell [style.flex]="column.width" *matHeaderCellDef> {{column.width}}</mat-header-cell>
<mat-cell [style.flex]="column.width" *matCellDef="let element"> {{element[column.name]}} </mat-cell>
</ng-container>
</ng-container>
<ng-container matColumnDef="action">
<mat-header-cell style="flex:0 1 auto;visibility:hidden" *matHeaderCellDef>
<button *ngIf="btEdit" mat-button>Delete</button>
<button *ngIf="btDelete" mat-button>Delete</button>
</mat-header-cell>
<mat-cell style="flex:0 1 auto" *matCellDef="let element"> <button *ngIf="btEdit" mat-button>Edit</button>
<button *ngIf="btDelete" mat-button>Delete</button></mat-cell>
</ng-container>
See that the column "action" the "head" repeat the buttons -with visibility:hidden-
NOTE: In this case, the "with" -really the flex- is a number, not a %,