Skip to content

Assertion condition conflicts with know type #37493

Closed
@wmaca

Description

@wmaca

TypeScript Version: 3.9.0--dev.20200319

Search Terms: assertion condition, narrow assertion condition, assertion condition union

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"]); 

I've also observed that TypeScript is using the already known type at caller (i.e. MyType) to narrow after the assert function is called. This is resulting in never as a result.

I am not sure this part is behaving as expected, but seems to be related to the bug reported.

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);

Expected behavior: assert condition should narrow the type to one of the values in the union.

Actual behavior: it seems to be merging what is knows about the type at the caller with what the assertion returns.

Playground Link: https://www.typescriptlang.org/v2/en/play?ts=next#code/C4TwDgpgBAsiCqA7Alge0VAvFA3lA2gNYQgBcUAzsAE7KIDmAuuQIaIhQC+UAPpTXXr5GAbgBQYgGYBXRAGNgaDCwoUI1YAHkARgCsICgBQA3FgBtpEVuwCUrVeuAUopi9GTOASgdTUAJgA8VLQMADRQbCAAfLhiUPFQyJJQJuaWWJjYiNJmZrx8oJCoya7pAISZUABEqHoGwFX5UACC1NQsIAB0Hq3tIKluNjaxCaNQwAAW1KgA7lCIEHMAom2+hlXNDhpKUJIsyGYQflU24qOcYhdSsgo79BDAAGppEIZ2sAgo6CMJ1A-S1AweEkqFQ5Cq2hY1EanHEVzk6CoLheWCg9yeLze4jEKjUGh0+iMpQgpwkAHoyVAVtNqBFnMhgFA-KgIM5EKhGYR2XMkolGR4IvwQkJGFBfLgCMQyELBMwIuwuGIEYgKKhDp0zKh6ANLPgqmBpmAAHIsAC2ECqjFOUCAA

Related Issues: #37241

Metadata

Metadata

Assignees

No one assigned

    Labels

    Working as IntendedThe behavior described is the intended behavior; this is not a bug

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions