Home > OS >  When using Angular @Input decorator, Typescript Type 'string' is not assignable to type
When using Angular @Input decorator, Typescript Type 'string' is not assignable to type

Time:11-15

My problem is related to Angular @Input() decorator, as when I am using this decorator, typescript throwing error, not when using in regular code.

In my child.component.ts file I am declaring this decorator to get props from parent component :

@Input() customColumns: {
    name: string;
    index: number;
    type: 'icon' | 'image' | 'link' | 'button';
    icon?: any;
    url?: string;
  }[] = [];
  indexList: number[] = [];

And in my parent.component.ts file I am assigning the value for this variable like this :

customColumns = [
    { name: 'permissions', index: 7, type: 'icon', icon: faSave },
    { name: 'price list', index: 6, type: 'link', icon: faArrowDownWideShort },
    { name: 'details', index: 5, type: 'button', icon: faArrowUpWideShort },
  ];

Lastly, in my parent.component.html file I am calling that child component:

<app-child [customColumns]="customColumns">
</app-child>

But I'm getting this error:

Types of property 'type' are incompatible.
Type 'string' is not assignable to type '"button" | "link" | "image" | "icon"'.

But when I am doing same thing in normal typescript or ngOnInit() function it is working, can't figure out why it is happening, help me please, thanks in advance.

    let customColumns: {
      name: string;
      index: number;
      type: 'icon' | 'image' | 'link' | 'button';
      icon?: any;
      url?: string;
    }[] = [];

    customColumns = [
      { name: 'permissions', index: 7, type: 'link', icon: '' },
      {
        name: 'price list',
        index: 6,
        type: 'icon',
        icon: faArrowDownWideShort,
      },
      { name: 'details', index: 5, type: 'icon', icon: faArrowUpWideShort },
    ];

My project dependencies:

"@angular/cli": "~14.2.7",
"typescript": "~4.7.2"

CodePudding user response:

In order to replicate the same behavior in normal TypeScript you should use this scenario:

let customColumns: {
  name: string;
  index: number;
  type: 'icon' | 'image' | 'link' | 'button';
  icon?: any;
  url?: string;
}[] = [];

const anotherValue =  [
  { name: 'permissions', index: 7, type: 'link', icon: '' },
  {
    name: 'price list',
    index: 6,
    type: 'icon',
  },
  { name: 'details', index: 5, type: 'icon', icon: '' },
];
customColumns = anotherValue;

That's simular to Angular typecheck code.

In order to solve it you can use either predefined enum:

const enum ColumnType {
  icon = 'icon',
  image = 'image',
  link = 'link',
  button = 'button',
}

let customColumns: {
  name: string;
  index: number;
  type: ColumnType;
  icon?: any;
  url?: string;
}[] = [];


...
type: ColumnType.link,

or as const:

type: 'link' as const

CodePudding user response:

Please try this

1.create a class like this

export class CustomColumns {
constructor(
public name?: string,
public index?: number,
public type?: 'icon' | 'image' | 'link' | 'button',
public icon?: any,
public url?: string
){}
}

2.and in your child component use like this

@Input() customColumns: CustomColumns;
  • Related