0

I've been following this guide to create a custom angular library but I've hit a wall with an issue rather odd.

The idea behind exercise is simple, create a skeleton for a particular piece of functionality (in this case a staff directory) where a developer can npm install it and provide a custom data source that implements our interface.

This interface is as follows

export interface ISDDataService {
refiners: Subject<Refiner[]>;
search(queryTxt: string): Observable<Staff[]>;
refine(refiner: Refiner): Observable<Staff[]>;
}

In the library project, this skeleton is a module referenced by the root module which is set up to provide the data source which inherits the ISDDataService

@Injectable()
export class AppService implements ISDDataService {
  refiners: Subject<Refiner[]>;
  staff: Staff[] = [];
  constructor() {
    this.staff.push(<Staff>{name: 'John Doe', role: 'xyz', group: 'A Team', image: ''});
    this.staff.push(<Staff>{name: 'Jane Doe', role: 'xyz', group: 'B Team', image: ''});
  }

  search(queryTxt: string): Observable<Staff[]> {
    return Observable.of(this.staff).map(o => this.staff);
  }

  refine(refiner: Refiner): Observable<Staff[]> {
    return ;
  }
}

This is how the service is provided (app.module.ts)

providers: [
    {
      provide: 'ISDDataService',
      useClass: AppService
    }
  ],

The skeleton module also has the results component which uses the data source to query the data

@Component({
  selector: 'app-search-results',
  templateUrl: './search-results.component.html',
  styleUrls: ['./search-results.component.css']
})
export class SearchResultsComponent implements OnInit {
  private results: Observable<Staff[]>;
  private searchField: FormControl;
  constructor(@Inject('ISDDataService') private service: ISDDataService) { }

  ngOnInit() {
    this.searchField = new FormControl();
    this.results = this.searchField.valueChanges
      .debounceTime(400)
      .distinctUntilChanged()
      .switchMap( term => this.service.search(term));
  }
}

This set up works like a charm, so proceed to package up, create a tarball and create a new "test" app so I can import the module using npm install (all these steps as per the blog post). So far so good, no errors installing the module.

the test app is just an exact replica of what I used when building the library. Same AppServices inheriting the ISDDataService, same way of providing the service and etc. I try bulding it and it all goes to hell. The error couldn't be more bizarre

ERROR in src/app/app.service.ts(9,14): error TS2420: Class 'AppService' incorrectly implements interface 'ISDDataService'.
  Types of property 'refiners' are incompatible.
    Type 'Subject<Refiner[]>' is not assignable to type 'Subject<Refiner[]>'. Two different types with this name exist, but they are unrelated.
      Types of property 'lift' are incompatible.
        Type '<R>(operator: Operator<Refiner[], R>) => Observable<R>' is not assignable to type '<R>(operator: Operator<Refiner[], R>) => Observable<R>'. Two different types with this name exist, but they are unrelated.
          Types of parameters 'operator' and 'operator' are incompatible.
            Type 'Operator<Refiner[], R>' is not assignable to type 'Operator<Refiner[], R>'. Two different types with this name exist, but they are unrelated.
              Types of property 'call' are incompatible.
                Type '(subscriber: Subscriber<R>, source: any) => TeardownLogic' is not assignable to type '(subscriber: Subscriber<R>, source: any) => TeardownLogic'. Two different types with this name exist, but they are unrelated.
                  Types of parameters 'subscriber' and 'subscriber' are incompatible.
                    Type 'Subscriber<R>' is not assignable to type 'Subscriber<R>'. Two different types with this name exist,
but they are unrelated.
                      Property 'isStopped' is protected but type 'Subscriber<T>' is not a class derived from 'Subscriber<T>'. 

How's something like this "Subject<Refiner[]>' is not assignable to type 'Subject<Refiner[]>'" make sense!!??

I've made a couple of changes here and there but nothing works

Note, this issue is not for the refiner property only. If I remove that, it'll cascade down to the functions and so.

I'm starting to think that perhaps this approach isn't the right one... and here I thought it was pretty clean

anyhow, if anyone can give a hand would be greatly appreciated

agpc
  • 1
  • 2
  • It makes sense because, **as the error message goes on to tell you**, *"Two different types with this name exist,"*. You have multiple unconnected definitions of `Refiner` somewhere. – jonrsharpe Dec 14 '17 at 12:28
  • I must admit that was a poor choice of words, but your comment wasn't particularly helpful either. That said, I went on about making changes to the library by removing the Refiner and using strings to prove that it had nothing to do with with my objects, something I had already done previously and failed; however this time it worked with strings, so I changed it back to my original set up and now it freaking works. The code is the exact same as before, all I've done is re package and library, and re install it in my test app. This is actually pretty frustrating, but glad I can move on – agpc Dec 14 '17 at 20:26

0 Answers0