awais nawaz
awais nawaz

Reputation: 19

error TS2322: Type 'string | string[]' is not assignable to type 'string'

enter image description here

I have an @Input() property with the data type string | string[]. Before upgrading to Angular 16, it was working fine, but after I upgraded to Angular 16, I started getting this error. I'm not sure where I went wrong. I have a component that has an input property as shown below:

let call this MyComponent 
@Input() info: string | string[];

Somewhere in my app, I am using this component and passing the info value:

// Case #1
// value = 'something in ts file'
<my-component [info]="value">
// Case #2
// arrayValue = ['a', 'b', 'c']
<my-component [info]="arrayValue">

I'm not sure what is wrong. I have already tried changing the type like this:

export type stringOrArray = string | string[];

However, I got the same error.

Upvotes: 0

Views: 1058

Answers (2)

rozsazoltan
rozsazoltan

Reputation: 6892

Type checking must be performed to determine whether our variable is of type string or string[]. Once we're certain it's a string with typeof this.info === 'string', we can then pass its value to another variable that accepts ONLY strings.

@NarenMurali already mentioned it in answer, but I think he overthought the example and didn't focus on the essence, so I'm leaving this here:

let message: string | string[] = 'Example'
let result: string = ''

if (typeof message === 'string') {
  // the 'message' variable is a string, so I can pass it as a string
  result = message // it safely receives a string
}
else {
  // the 'message' variable is not a string, so I concatenated the elements of the array into a string
  result = message.split(' ') // message is definitely an array, so split() will work
}

Upvotes: 1

Naren Murali
Naren Murali

Reputation: 56002

Since there are two possible types string and string[] we need to explicitly tell typescript that the value you are assigning is of which type

this.test = <string>this.info;

Full code:

import { Component, Input } from '@angular/core';

@Component({
  selector: 'app-child',
  standalone: true,
  imports: [],
  templateUrl: './child.component.html',
  styleUrl: './child.component.css',
})
export class ChildComponent {
  @Input() info!: string | string[];
  test: string = '';
  ngOnInit() {
    if(typeof this.info === 'string') {
        this.test = this.info;
    }
  }
}

Stackblitz Demo

Upvotes: 3

Related Questions