Skip to content

Generic parameter implicitly broadens object key to string. #55110

Closed as not planned
@cefn

Description

@cefn

Bug Report

Const object having typed string keys should not be broadened to string when key is an inferred const function parameter and type is a const object.

In the example below SingleEntryCreated is the type at fault and it has [x:string] where it should have "iamanentry".

In the createMapWithCast factory function below, there should not be a need to cast with as Readonly<{[k in N]:V}> as it is already known to be exactly that. All three types of singleEntryCreated, singleEntryCreatedWithCast, singleEntryInline should have identical type.

🔎 Search Terms

Object key type broadened narrowed.

🕗 Version & Regression Information

⏯ Playground Link

Playground link with relevant code

💻 Code

function createMap<const N extends string, const V extends unknown>(
  entryName: N,
  value: V
) {
  return {
    [entryName]: value,
  } as const;
}

function createMapWithCast<const N extends string, const V extends unknown>(
  entryName: N,
  value: V
) {
  return {
    [entryName]: value,
  } as const as Readonly<{ [k in N]: V }>;
}


const entryName = "iamanentry";
const singleEntryCreated = createMap(entryName, 3);
const singleEntryCreatedWithCast = createMapWithCast(entryName, 3);
const singleEntryInline = {
  [entryName]: 3,
} as const;

type SingleEntryCreated = typeof singleEntryCreated;
//  ^? type SingleEntryCreated = { readonly [x:string]: 3; }
type SingleEntryCreatedWithCast = typeof singleEntryCreatedWithCast;
//  ^?  type SingleEntryCreatedWithCast =  { readonly "iamanentry": 3; }
type SingleEntryInline = typeof singleEntryInline;
//  ^?  type SingleEntryInline = { readonly "iamanentry": 3; }

🙁 Actual behavior

Embedding the construction of an object inside a factory (passing a string key for inference) has the key broadened to string.

🙂 Expected behavior

The key should not be broadened to string as it is known to be exactly the inferred generic value.

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