简体   繁体   中英

Typescript: Checking type of function passed as an argument

So, I have the following idea: I would like to describe a function which takes an RxJs Observable provided by some service as a first argument and OnNext function handler which will be passed to subscribe method.

import { Observable } from 'rxjs';

export interface OnNextHandler<T> {
  (value: T): void
}

export interface ServiceSubscriber<T> {
  (providedObservable: Observable<T>, onNext: OnNextHandler<T>): void
}

The code above seem to work, though TS doesn't give me an error in some cases(and I would like it to do so). For instance:

@Component({
  selector: 'app-notes-list',
  templateUrl: './notes-list.component.html',
  styleUrls: ['./notes-list.component.scss']
})
export class NotesListComponent implements OnInit, OnDestroy {
  activeNotes: Note[] = [];
  archivedNotes: Note[] = [];

  private destroy$: Subject<boolean> = new Subject<boolean>();

  constructor(
    private notesService: NotesService
  ) { }

  ngOnInit() {
    const { active, archived } = this.notesService; // pull our observables from the service
    this.subscribeTo(active, activeNotes => this.activeNotes = activeNotes);
    this.subscribeTo(archived, archivedNotes => this.archivedNotes = archivedNotes);
  }

  ngOnDestroy(): void {
    this.destroy$.next(true);
    this.destroy$.unsubscribe();
  }

  private subscribeTo: ServiceSubscriber<Note[]> = (providedObservable$, onNext) => {
    providedObservable$
      .pipe(takeUntil(this.destroy$))
      .subscribe(onNext)
  }
}

This is one of the Angular components where I'm trying to type the subscribeTo method with my ServiceSubscriber interface. The first argument gets checked: for example when we pass string instead of an expected Observable , but the second argument(onNext callback) can receive any function as its value(and I want it to be a function which takes argument of type T and return nothing ). To demonstrate, if I change the code inside ngOnInit to something like this:

  ngOnInit() {
    const { active, archived } = this.notesService;
    this.subscribeTo(active, activeNotes => activeNotes); // pay attention here on the 2nd arg
    this.subscribeTo(archived, archivedNotes => archivedNotes); // and here as well
  }

So now callbacks return something, instead of nothing as it was expected. What do I miss here and how can I receive an error when the callback function signature is wrong? Thanks.

You should type the return as never instead:

export interface ServiceSubscriber<T> {
  (providedObservable: Observable<T>, onNext: OnNextHandler<T>): never
}

I believe this should work.

There is an explanation for this in a different answer here .

The short answer is that the spec takes void to be

"don't care about the return type"

rather than

"strictly returns no value"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM