Recently updated a project from Angular v9 to v11. Opted for strict typing and got a bazillion errors of course, stumped on this one.
Using combineLatest to generate a publication from 3 observables (each is a firebase doc.valueChanges() or collection.valueChanges())
My code:
getEdition(editionId: string): AngularFirestoreDocument<Edition> {
return this.afs.collection('editions').doc(editionId);
}
const editionRef: Observable<Edition | undefined> = this.editionService.getEdition(ed.id).valueChanges();
combineLatest([editionRef, sectionsRef, articlesRef]).subscribe(([edition, sections, articles]: [Edition, Section[], Article[]]) => {
// do stuff, returns void
});
Edition.ts:
import { Moment } from 'moment';
export interface Edition {
id: string;
pubTypeId: string;
date: string | Moment;
imgCaption: string;
imgCredit: string;
imgLink: string;
imgSrc: string;
introText: string;
hasPreface: boolean;
preface: string;
printLink: string;
}
My error:
error TS2769: No overload matches this call.
Overload 1 of 5, '(observer?: NextObserver<[Edition | undefined, DocumentData, DocumentData]> | ErrorObserver<[Edition | undefined, DocumentData, DocumentData]> | CompletionObserver<...> | undefined): Subscription', gave the following error.
Argument of type '([edition, sections, articles]: [Edition, Section[], Article[]]) => void' is not assignable to parameter of type 'NextObserver<[Edition | undefined, DocumentData, DocumentData]> | ErrorObserver<[Edition | undefined, DocumentData, D
ocumentData]> | CompletionObserver<...> | undefined'.
Property 'complete' is missing in type '([edition, sections, articles]: [Edition, Section[], Article[]]) => void' but required in type 'CompletionObserver<[Edition | undefined, DocumentData, DocumentData]>'.
Overload 2 of 5, '(next?: ((value: [Edition | undefined, DocumentData, DocumentData]) => void) | undefined, error?: ((error: any) => void) | undefined, complete?: (() => void) | undefined): Subscription', gave the following error.
Argument of type '([edition, sections, articles]: [Edition, Section[], Article[]]) => void' is not assignable to parameter of type '(value: [Edition | undefined, DocumentData, DocumentData]) => void'.
Types of parameters '__0' and 'value' are incompatible.
Type '[Edition | undefined, DocumentData, DocumentData]' is not assignable to type '[Edition, Section[], Article[]]'.
Type 'Edition | undefined' is not assignable to type 'Edition'.
Type 'undefined' is not assignable to type 'Edition'.
I know I need to tweak my typings somehow, but not sure quite what to do given that I'm using combineLatest here...
My guess is that somewhere along the chain of editionRef -> edition -> Edition
you have an implicit any
type. from the docs:
Any variable, parameter or property that is initialized with null or undefined will have type any, even if strict null checks is turned on.
So I would start by trying to find an uninitialized, undefined
or null
variable within that chain.
The error
Type 'undefined' is not assignable to type 'Edition'.
indicates that this.editionService.getEdition(ed.id).valueChanges()
should never be allowed to return undefined
and the type of Observable should only be Edition
.
Finally, in your fix it is best to actually indicate the typing required to be enforced.
You could us as
to typecast the type, but you're changing something you are unsure of into something you need. This option will likely work, but doesn't "enforce" typing the way the typing does.
So the best solution, as you placed in your comment is:
subscribe(([edition, sections, articles]: [Edition | undefined, Section[], Article[]]) => { ... }