Search code examples
javascriptangulartypescriptangular17

Not sure why Angular is complaining about Type 'string' is not assignable to type 'MenuItem'


Angular is failing to compile because of the following error and I'm really confused as to why.

error TS2322: Type 'string' is not assignable to type 'MenuItem'.

4     <menu-item item={{item}}></menu-item>
                 ~~~~

  apps/angular-monorepo/src/app/app.component.ts:10:16
    10   templateUrl: './app.component.html',
                      ~~~~~~~~~~~~~~~~~~~~~~
    Error occurs in the template of component AppComponent.

Why is it complaining that item is of type 'string' when I specified that item is of type MenuItem or undefined

@Component({
  standalone: true,
  imports: [NxWelcomeComponent, RouterModule, MenuItemComponent],
  selector: 'angular-monorepo-root',
  templateUrl: './app.component.html',
  styleUrl: './app.component.scss',
})
export class AppComponent {
  title = 'angular-monorepo';
  menu: MenuItem[] = [
    {id: 101,category: 'appetizer', name:'french toast', price: 10.00},
    {id: 201,category: 'entree',sub_category:"rice",name:'pork', price: 10.00},
    {id: 301,category: 'drinks',name:'tea', price: 10.00},
    {id: 401,category: 'dessert',name:'affogato', price: 10.00},
  ]
}
//app.component.html
<router-outlet></router-outlet>
<h1>POS</h1>
@for (item of menu; track item.id) {
    <menu-item item={{item}}></menu-item>
}



@Component({
  selector: 'menu-item',
  standalone: true,
  imports: [CommonModule],
  templateUrl: './menu-item.component.html',
  styleUrl: './menu-item.component.scss',
})
export class MenuItemComponent {
  constructor() {

  }
  @Input({required: true}) item: MenuItem | undefined = undefined;
  
  @Output() itemSelectedEvent = new EventEmitter<number>();
}

//menu-item.component.html
@if (item) {
    <p>{{item.name}}</p>
}


//menu-item.type.ts
export type MenuItem = {
    id: number,
    category: ItemCategory,
    sub_category?: string,
    name: string,
    price: number
  }

I expect item would be of type MenuItem like I specified


Solution

  • The brackets, [], cause Angular to evaluate the right-hand side of the assignment as a dynamic expression.

    so like this, you will set item properly

      <menu-item [item]="item"></menu-item>
    

    Without the brackets, Angular treats the right-hand side as a string literal and sets the property to that static value.

    👉 https://angular.io/guide/property-binding#binding-to-a-property