-
Notifications
You must be signed in to change notification settings - Fork 12.9k
Closed
Labels
Design LimitationConstraints of the existing architecture prevent this from being fixedConstraints of the existing architecture prevent this from being fixedDomain: Indexed Access TypesThe issue relates to accessing subtypes via index accessThe issue relates to accessing subtypes via index accessDuplicateAn existing issue was already createdAn existing issue was already created
Milestone
Description
TypeScript Version: 3.6.0-dev.20190720
Search Terms: type narrowing undefined generics early return
Code
type BaseEvents = {[event: string]: Array<any>};
type Cbs<A extends BaseEvents> = {
[P in keyof A]: Array<(...args: A[P]) => boolean | Promise<boolean>> | undefined;
}
export class Events<T extends BaseEvents> {
private cbs: Cbs<T> = {} as any;
async emit<P extends keyof T>(event: P, ...args: T[P]) {
const arr = this.cbs[event]; // typeof arr = ((...args: T[P]) => boolean | Promise<boolean>)[] | undefined
type NonNullArr = NonNullable<typeof arr>; // ((...args: T[P]) => boolean | Promise<boolean>)[]
if (typeof arr === 'undefined') {
return;
}
// typeof arr should now be ((...args: T[P]) => boolean | Promise<boolean>)[]
const nonNullArr: NonNullArr = arr; // TS2322: Type '((...args: T[P]) => boolean | Promise<boolean>)[] | undefined' is not assignable to type 'NonNullable<Cbs<T>[P]>'.
// Type 'undefined' is not assignable to type 'NonNullable<Cbs<T>[P]>'.
for (const cb of arr) { // TS2488: Type 'Cbs<T>[P]' must have a '[Symbol.iterator]()' method that returns an iterator.
}
for (const cb2 of nonNullArr) { // No error
}
}
}
Expected behavior: Compiles without errors.
Actual behavior: Several errors relating to arr not narrowing out the undefined
portion of the argument:
Error:(14, 15) TS2322: Type '((...args: T[P]) => boolean | Promise<boolean>)[] | undefined' is not assignable to type 'NonNullable<Cbs<T>[P]>'.
Type 'undefined' is not assignable to type 'NonNullable<Cbs<T>[P]>'.
Error:(16, 26) TS2488: Type 'Cbs<T>[P]' must have a '[Symbol.iterator]()' method that returns an iterator.
Related Issues:
#1726 (closed by design, this is different because we can assume any array is not undefined)
#31456 (this example has a constraint)
Metadata
Metadata
Assignees
Labels
Design LimitationConstraints of the existing architecture prevent this from being fixedConstraints of the existing architecture prevent this from being fixedDomain: Indexed Access TypesThe issue relates to accessing subtypes via index accessThe issue relates to accessing subtypes via index accessDuplicateAn existing issue was already createdAn existing issue was already created