Skip to content

Variable loses type narrowing when passed as object literalΒ #57013

Closed as not planned
@jasonaden

Description

@jasonaden

πŸ”Ž Search Terms

object literal type inference
enum type narrowing

πŸ•— Version & Regression Information

  • This changed between versions 5.0.4 and 5.1.6

⏯ Playground Link

https://www.typescriptlang.org/play?ts=5.3.3#code/FAUwdgrgtgBAogN3AFwM4wN7BvAanAOQBUBGGAXhgHJEUYSqAabPQogJgutrGRnabAAvsGABLXiABOAMwCGAYxAwA4uGliFPPlhwgkvAnKggAXPANoA3CwAOUgPa3pyMSFQB+c2H3SbI8UlZRWVtEm1MFl9DYzMLFFQAOjh8YhIbHHsnFzdUc10cGAATOWQ5c1RkKQkAcxYhf1EJZGl5JXjedgiC6OQjE3NtJJS2dgyYLOcpV3d8lhwSsoqq2vrG4GQAT2cO5CJt9y5gAB9VdWqtSxPd8KvT7S6r4AUHMEqYSFhKAFlSgAtEjIADYOBxSAAUv2QAKkcjARQcUHBAEoYAAqegABlRAGp6DZnq93r1+spKJ8YAA+GAAVhgHl2w1SpBgg0sTNGBIA9FyYEQ-mJ0EgpKgxK8YPIxEDUMAskpUKhtOCepZScxMo4pjM8pFCsVSuUYAAib6bXYwAAiBqN9WEyO5vP5gpgwtF4oA7mCANYyl5vPiLORcFUoNV2TU5Wa6wqB8wms0RK1lG04EQNWWOeWKyzgwP20QyCBgBSucVy9zZlDg3pslD7ZyoVEFP2oBxAkCJEE1auWfMiIA

πŸ’» Code

enum Events {
  EVENT1 = 'Event 1',
  EVENT2 = 'Event 2',
}

interface GenericEvent {
  eventName: Events;
  properties?: never;
}

interface Event1Event {
  eventName: Events.EVENT1;
  properties: {
    data: string
  };
}

interface Event2Event {
  eventName: Events.EVENT2;
  properties: {
    data: string
  };
}

type EventTypes = 
| GenericEvent
| Event1Event
| Event2Event

const num = Math.floor(Math.random() * 10) + 1;

const eventName = num > 5 ? Events.EVENT1 : Events.EVENT2;

// This version fails on properties: Type '{ data: string; }' is not assignable to type 'undefined'
processEvent({
  eventName,
  properties: {
    data: "My Event Data"
  }
});

// This version works
const data = {
  eventName,
  properties: {
    data: "My Event Data"
  }
};
processEvent(data);

function processEvent(event: EventTypes) {
  console.log(event);
}

πŸ™ Actual behavior

The event passed to processEvent behaves differently if assigned to a const prior to being passed in.

πŸ™‚ Expected behavior

Both should be the same result. It's also worth noting that in the repro provided assignment to a const data = ... works to resolve the problem. But in my code this doesn't end up working and instead I need to explicitly state that eventName can only be one of the two Events values in the ternary.

Additional information about the issue

No response

Metadata

Metadata

Assignees

Labels

Design LimitationConstraints of the existing architecture prevent this from being fixed

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions