Home > database >  Variable type with objects having a different structure cause error Property 'propertyname'
Variable type with objects having a different structure cause error Property 'propertyname'

Time:06-25

I have this interface that i use as type for a variable inside a component

export interface IToolbarConfig 
{
    items:
    [
        {
            type?:string,
            label?:string,
            handler?:Function
        } ?,
        {
            type?:string,
            label?:string,
        } ?
    ] 
}

Into toolbar.component.ts:

@Input() config!: IToolbarConfig;

So, i try to cycle the items array into the toolbar.component.html:

<ng-container *ngFor="let item of config?.items">
    <ng-container *ngIf="item?.type == 'button'">
        <button (click)="item?.handler()">{{ item?.label }}</button> 
    </ng-container>
</ng-container>

Due the fact that property "handler" exists only when type="button", compiler give me error

Property 'handler' does not exist on type '{ type?: string | undefined; label?: string | undefined; handler?: Function | undefined; } | { type?: string | undefined; label?: string | undefined; }'.

I managed to solve modifing interface so

export interface IToolbarConfig 
{
    items:
    [
        {
            type?:string,
            label?:string,
            handler?:Function
        } ?,
        {
            type?:string,
            label?:string,
        } ?
    ] | any   <------added this
}

but i don't think this is the best practice. Any suggestions?

CodePudding user response:

Change your interface in:

// since handler can be undefined your interface was duplicating objects in the array
export interface IToolbarConfig {
  items: Array<{
    type?: string
    label?: string
    handler?: Function
  } | undefined>
}

And then, as said by Rabu call the method with the optional chaining:

<button (click)="item?.handler?.()">{{ item?.label }}</button>

CodePudding user response:

handler could be undefined so you need to add a check for it. You can use optional chaining on the function also.

<ng-container *ngFor="let item of config?.items">
    <ng-container *ngIf="item?.type == 'button'">
        <button (click)="item?.handler?.()">{{ item?.label }}</button> 
    </ng-container>
</ng-container>

CodePudding user response:

why not type items as

{ 
  type?:string,
  label?: string,
  handler?:Function,
}[]

The fact that your type uses ? on handler means that it doesn't need to be defined. That means even if you type is not button and you don't have any handler to define, you can leave it undefined, typescript won't complain

This declaration is now valid

let item: items = [{
  type: 'myType',
  label: 'myLabel',
}]
  • Related