Angular2/TypeScript: error TS2345: Argument of type 'String' is not assignable to parameter of type 'string'

17,070
private searchTerms = new Subject<String>();

change it to

private searchTerms = new Subject<string>();

String is a class and string is a datatype.

Share:
17,070
Admin
Author by

Admin

Updated on June 04, 2022

Comments

  • Admin
    Admin almost 2 years

    I have the following code, which I am using to create a Casino Management System:

    import { Component, OnInit } from '@angular/core';
    import { Router }            from '@angular/router';
    import { Observable }        from 'rxjs/Observable';
    import { Subject }           from 'rxjs/Subject';
    
    import { SearchService } from './search.service';
    import { Data } from './datatypings';
    
    @Component({
      moduleId: module.id,
      selector: 'casino-search',
      templateUrl: 'search.component.html',
      styleUrls: [ 'search.component.css' ],
      providers: [SearchService]
    })
    
    export class SearchComponent implements OnInit {
    
      data: Observable<Data[]>;
    
      private searchTerms = new Subject<String>();
    
      constructor(
        private searchService: SearchService,
        private router: Router) {}
      // Push a search term into the observable stream
      search(term: string): void {
        this.searchTerms.next(term);
      }
    
      ngOnInit(): void {
        this.data = this.searchTerms
          .debounceTime(150)        // wait for 150ms pause in events
          .distinctUntilChanged()   // ignore if next search term is same as previous
          .switchMap(term => term   // switch to new observable each time
            // return the http search observable
            ? this.searchService.search(term)
            // or the observable of empty data if no search term
            : Observable.of<Data[]>([]))
              .catch(error => {
            // TODO: real error handling
            console.log(error);
            return Observable.of<Data[]>([]);
          });
      }
    
      gotoDetail(data: Data): void {
        let link = ['/detail', data.id];
        this.router.navigate(link);
      }
    }
    

    However, when I attempt to transpile this code from TypeScript to JavaScript I get this error:

    app/data/search.component.ts(37,37): error TS2345: Argument of type 'String' is not assignable to parameter of type 'string'.
      'string' is a primitive, but 'String' is a wrapper object. Prefer using 'string' when possible.
    

    Now, I've fixed the error simply by changing String to string within the angle braces but I want to be able to proceed in future without creating similar errors, and also to write the best code I can... So I'm wondering if someone could clear this up for me:

    I think I understand that a parameter with a wrapper class is something which encapsulates a primitive class and provides some sort of additional, usually interfacing related, behaviour (correct me if I'm wrong here), and I see why it might then not be possible to assign the contents of what is essentially a broader declared variable type to the more simple primitive, there is another aspect of the error message which interests me, that is:

    Why would it be preferable to use type 'string' over type 'String' in Angular2/Typescript in such a general sense as the error seems to imply? What is it which makes this preferential?

  • Admin
    Admin over 7 years
    Yeah, I know. What is the difference between the Typescript library class String and the TypeScript datatype string which should cause me to use the datatype over the class in all instances where such a thing is possible (as per the error message), though, was my question.
  • micronyks
    micronyks over 7 years
    Subject method/API will emit data later on. Subject<string>() so it tells which type of data will be emited. Generally subject can emit string type data and obviously not String class type data. So...
  • Admin
    Admin over 7 years
    So it's preferable use the String wrapper class in general because the extra data in the wrapper class does not interface cleanly (or perhaps at all? I wonder if the wrapper class can be 'made' to interface, but that's seperate...) Subject API? Perhaps there is a more general rule about not adding additional complexity by using a wrapper class unless absolutely required and the Subject method issue is just one example of one wrapper class (I assume Subject is also a wrapper class?) interfacing poorly or not at all because of the additional complexity added by the wrapper?
  • micronyks
    micronyks over 7 years
    its hard to say until looking inside of subject's definition.