-
Notifications
You must be signed in to change notification settings - Fork 13.1k
Closed
Closed
Copy link
Labels
DuplicateAn existing issue was already createdAn existing issue was already created
Description
TypeScript Version: 4.0.0-dev.20200531
Search Terms: type narrow discriminant generic
Code
interface A<T, K extends keyof T> {
t: true;
v: T[K];
}
interface B {
t: false;
e: Error;
}
type X<T> = A<T, keyof T> | B;
type Some = { y: number; z: string };
declare function assertIsX(x: unknown): asserts x is X<Some>;
// CASE 1: narrowing unknown (works)
declare const some: unknown;
assertIsX(some);
// Ok, `r1` is `string | number | Error` as expected
const r1 = some.t ? some.v : some.e;
// CASE 2: before narrowing (works)
declare const some2: X<{ [k: string]: unknown }>;
// Ok, `r2` is `unknown` as expected
const r2 = some2.t ? some2.v : some2.e;
// CASE 3: narrowing again (does not work)
assertIsX(some2);
// ERROR: `some2` narrowed to `B`, not `X<Some>`,
// so `v` isn't accesible
some2.t ? some2.v : some2.e;
// CASE 4: narrowing `A<any, any> | B` (does not work)
declare function onlyASomeHere(x: A<Some, keyof Some>): void;
declare const a: A<any, any>;
// `A<any, any>` is assignable to `A<Some, keyof Some>`
onlyASomeHere(a);
declare const some3: A<any, any> | B;
assertIsX(some3);
// ERROR: `some3` narrowed to `B`, not `X<Some>`
some3.t ? some3.v : some3.e;
I'm using a type assertion, but a type predicate makes no difference. The same happens starting with X<any>
or X<unknown>
.
Expected behavior: some2
is narrowed to the union A<Some> | B
so .v
can be accessed when t === true
.
Actual behavior: some2
narrows only to B
, so when t === true
some2
is never
.
Playground Link: playground
Related Issues: Maybe #30557 but that case works on last nightly and this does not.
Metadata
Metadata
Assignees
Labels
DuplicateAn existing issue was already createdAn existing issue was already created