It's unlikely that you're going to get this syntax to work in a template (there are many valid typescript constructs that don't work in templates).
You could write a helper method in the component instead, that takes the item as an argument, and then makes the appropriate call, as in, for example:
public doCommand(item: ToolbarItem): void {
item.command(...item.commandParams);
}
and then change your template to:
<button (click)="doCommand(item)"...
Answer from GreyBeardedGeek on Stack OverflowIt's unlikely that you're going to get this syntax to work in a template (there are many valid typescript constructs that don't work in templates).
You could write a helper method in the component instead, that takes the item as an argument, and then makes the appropriate call, as in, for example:
public doCommand(item: ToolbarItem): void {
item.command(...item.commandParams);
}
and then change your template to:
<button (click)="doCommand(item)"...
The spread syntax is now available in Angular 22.
For the function calls (your usecase):
<button
mat-mini-fab
[style.color]="item.color"
(click)="item.command(...item.commandParams)"
>
<mat-icon>{{ item.icon }}</mat-icon>
</button>
For lists:
<div [class]="[...otherClassList, 'foo', 'bar']">
Some content
</div>
For objects:
<div [class]="{
...otherClassMapping,
'foo': isFoo,
'bar': isBar
}">
Some content
</div>
See: https://blog.angular.dev/announcing-angular-v22-c52bb83a4664
Support spread operator (`...`) in Angular templates (e.g., for `[class]` binding)
Angular-How to use spread operator in angular html template
angular - RxJS : how to understand the spread operator here? - Stack Overflow
typescript - Can you use spread operator in the template in angular - Stack Overflow
No, you cannot use the spread in a template (even less like you're trying).
To achieve that, you will need a reference to your template.
<input #myInput (input)="isTruthy()" />
@ViewChild('myInput', { static: true }) myInput: ElementRef<HTMLInputElement>;
ngOnInit() {
Object.assign(this.myInput.nativeElement, this.val);
}
One way to do this could be create a directive like
import { Directive, ElementRef, HostListener, Input } from '@angular/core';
@Directive({
selector: '[setAttr]'
})
export class AttrDirective {
constructor(private el: ElementRef) { }
@Input() attr: any;
ngOnInit(){
if(this.attr){
console.log(this.el.nativeElement)
Object.keys(this.attr).forEach(k=>{
this.el.nativeElement.setAttribute(k,this.attr[k])
console.log(this.el.nativeElement)
})
}
}
}
then apply on input like
<input type="text" setAttr [attr]="val">
demo
From what I understand the spread operator works both to add new keys to an object and to overwrite the keys it already has.
I imagine a product object like this:
product = {
price: 0,
category: a
};
Now we copy the object with the spread operator:
const product2 = {...product};
Now you have another object (in another memory location) with the same content as product.
Now we create a new object with other values with the spread operator:
const produc3 = { ...product, price: 1, category: b };
Now you have an object that has the same keys as the original but with other values.
Now we add a new key to the object:
const product4 = { ...product, name: 'car'};
Now you have an object that has the same keys as the original object, plus the name key.
You will never have an object with 2 keys the same.

Tested in the chrome console, if you try to define an object with two equal keys only the last key of the definition prevails.
It is a JavaScript feature not RxJS specific per say. I think this snippet of code (or similar) is part of RxJS examples slides of Deborah Kurata conference or something like this. If you are interested, there is a record on youtube on a similar usage of this syntax with RxJS by Deborah Kurata.
As mentioned on MDN:
Spread syntax can be used when all elements from an object or array need to be included in a new array or object, or should be applied one-by-one in a function call's arguments list. There are three distinct places that accept the spread syntax:
Function arguments list (myFunction(a, ...iterableObj, b)) Array literals ([1, ...iterableObj, '4', 'five', 6]) Object literals ({ ...obj, key: 'value' })
In our case above it is called shallow cloning with Object literals. Read more here
As you mentioned in the question, and as can be seen in this stackblitz, the spread syntax doesn't appear to be allowed in Angular templates at the present time. A feature request has been opened in issue 11850 to support that syntax.
As stated before, Angular dosen't allow you use spread operator in template BUT you can use my pipe to do it!
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'addPropsToObj'
})
export class AddPropsToObjPipe implements PipeTransform {
transform(prevObj: { [key: string]: any }, propsToBeAdded: { [key: string]: any }): { [key: string]: any } {
return { ...prevObj, ...propsToBeAdded };
}
}
This will allow to do this:
.. [user]="{}|addPropsToObj:member" ..
and get exaclty what you wanted:
{ ...member }
I want to build a component on top of a existing one from Angular Material. Ex: A Custom Button built on top of Material Button. In React the straightforward solution is wrapping the material component and spread the props in the wrapped component
<CustomComponent /> = (props) => <MaterialComponent {...props} />
Is there a way to do something similar with Angular? Thanks in advance (:
(non english speaker here, I tried my best to express my idea)