Skip to content

Union type breaks type safety of dynamic object keysΒ #58054

Closed as not planned
Closed as not planned
@aelgn

Description

@aelgn

πŸ”Ž Search Terms

"union type as dynamic object key"

πŸ•— Version & Regression Information

  • This is the behavior in every version I tried, and I reviewed the FAQ for entries about Union types

⏯ Playground Link

https://www.typescriptlang.org/play?ts=5.4.3#code/FAguE8AcFMAIEVYF5YG9i1gQwPwC5YBnUAJwEsA7AcwG5gBfOgMwFcKBjUMgewtgEcA7t0gAKUAQDkWSbAA+sSRRHRJASgKJ0mEtFAsSfbZlgBtUAF0CANlsAaWAHpHsUAAsyhWO24BbSGQANtCEGLCMDMCsHFy8AsKQAEziUjIaCGhhuvqGmSZmljb2Ti7unrBUZABuIa5QcNAkJNwk2F7QAB4wnNAAJmER9GD1CInIeWYA0rCUijLyigBGkhb4RKSUtAzMbJw8fEIiAMwpc+qaY8bZBkZhmOZWsLbWDs6uHl6VNV4QMLCNzVaWHaXWgPX6mEGUV2sQOCQALKdpLIFJJlul4JcsnobhN7oUnsU3mUvD5-EEQg5FiwqDgBnQhsBfnB4EdxsZcARiORqHRMIs1tzNgydjF9vERABWJHzVHozRsq443LGfGPZ6vUofbx+ALBQhUml0yEMoA

πŸ’» Code

type Q = {
  a?: string;
};
function qwop(t: 'a' | 'nope'): Q {
  return {
    [t]: 666, // this compiles
  };
}
function qwop2(t: 'a'): Q {
  return {
    [t]: 666, // this gives type error as expected
  };
}

type Q2 = {
  [K in 'a' | 'b']?: string;
};
function qwop3(t: 'a'): Q2 {
  return {
    [t]: 666, // this gives type error as expected
  };
}
function qwop4(t: 'a' | 'b'): Q2 {
  return {
    [t]: 666, // this compiles, bug?
  };
}

type Q3 = {
  a?: string;
  b?: string;
};
function qwop5(t: 'a' | 'b'): Q3 {
  return {
    [t]: 666, // this compiles, bug?
  };
}

πŸ™ Actual behavior

Type check stops working when using a string union type as dynamic key to an object.

πŸ™‚ Expected behavior

First I expected 'a' | 'nope' to not be a valid type for key of { a?: string } but I guess extraneous keys are just fine in a duck eat duck world.

What seems to be a bug to me is that the type declaration is ignored when the key type is a union - even when the full union is properly declared in the type. Ie. the type of properties 'a' | 'b' is clearly string and I expected a number to produce a type error.

Additional information about the issue

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    DuplicateAn existing issue was already created

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions