Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Assertion functions cannot be used to narrow discriminated union types #37241

Copy link
Copy link
@oleg-codaio

Description

@oleg-codaio
Issue body actions

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

interface Cat {
  type: 'cat';
  canMeow: true;
}

interface Dog {
  type: 'dog';
  canBark: true;
}

type Animal = Cat | Dog;

function assertEqual<T>(value: any, type: T): asserts value is T {
  if (value !== type) {
    throw new Error('Not equal!');
  }
}

const animal = { type: 'cat', canMeow: true } as Animal;
assertEqual(animal.type, 'cat' as const);

// Error
animal.type; // "cat"
animal.canMeow; // Property 'canMeow' does not exist on type 'Dog'

// Works
if (animal.type !== 'cat') {
  throw new Error();
}
animal.canMeow; // true

Expected behavior:
Calling assertEqual(animal.type, 'cat') would infer animal as a Cat.

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

Reactions are currently unavailable

Metadata

Metadata

Assignees

Labels

BugA bug in TypeScriptA bug in TypeScript

Type

No type
No fields configured for issues without a type.

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions

    Morty Proxy This is a proxified and sanitized view of the page, visit original site.