-
Notifications
You must be signed in to change notification settings - Fork 12.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Assertion functions cannot be used to narrow discriminated union types #37241
Comments
I'm having a similar problem. It's not totally clear to me if your example exposes the same behavior, but it seems very similar: the type is not narrowed by the assertion.
Works the same way when coded as a type guard. |
Note for a workaround in the first example, a more generic
|
It seems to be affecting other union types, as the code below demonstrates. Code type MyUnion = { [key: string]: any } | string[];
function assertObject(value: any): asserts value is Record<string, any> {
if (value === null || typeof value !== "object" || Array.isArray(value)) {
throw new Error("Assertion failed");
}
}
function getValue(): MyUnion {
return { foo: "bar" };
}
const value = getValue();
assertObject(value);
// Error as it does not know if it is a string[] or { [key: string]: any }
console.log(value["propName"]); Playground Link: here More detailsI've also observed that TypeScript is using the already known type at caller (i.e. I am not sure this part is expected. type MyType =
| {
[key: string]: {
[k: string]: number;
};
}
| string;
const a: MyType = { foo: { bar: 123 } };
function assertUndefined(value: any): asserts value is undefined {
if (value !== undefined) throw new Error();
}
assertUndefined(a.foo);
// `a.foo` is `never`
console.log(a.foo); |
Recently I tried to get creative with an assert function, but ran into a shortcoming. I think I understand why this is the behavior, but it would be nice if it wasn't the case.
TypeScript Version: 3.9.0-dev.20200304
Search Terms: assertion assert function discriminated union narrowing
Code
Expected behavior:
Calling
assertEqual(animal.type, 'cat')
would inferanimal
as aCat
.Actual behavior:
Only
animal.type
by itself is inferred; the type narrow does not "propagate" up to the union type.Playground Link: Provided
Related Issues: #11787 (most closely related, but that's for type guards, not the new assertion functions), #34596
The text was updated successfully, but these errors were encountered: