Microsoft/TypeScript

Generic type gets widened in an unexpected way

Open

#52,249 opened on Jan 15, 2023

View on GitHub
ย (7 comments)ย (0 reactions)ย (0 assignees)TypeScriptย (48,455 stars)ย (6,726 forks)batch import
BugDomain: Mapped TypesHelp Wanted

Description

Bug Report

๐Ÿ”Ž Search Terms

widen

๐Ÿ•— Version & Regression Information

4.9.4

โฏ Playground Link

Playground link with relevant code

๐Ÿ’ป Code

enum One {
  A = 'a',
  B = 'b',
  C = 'c'
}

const isOneSomethingMap = {
  [One.A]: true,
  [One.B]: false,
  [One.C]: true
} as const satisfies Record<One, boolean>;

type BooleanMapToUnion<T extends Record<string, boolean>> = {
  [P in keyof T]: T[P] extends true ? P : never;
}[keyof T];

type SomethingOne = BooleanMapToUnion<typeof isOneSomethingMap>;

const a = <T>(value: T) => value;
const b = <T>(fn: (value: T) => T, v: T): T => fn(v);

const v: SomethingOne = One.A as SomethingOne;
const v2: One.A | One.C = One.A as One.A | One.C;

const r1 = b(a, v); // One and not SomethingOne - not expected
const r2 = a(v); // SomethingOne as expected
const r3 = b(a, v2); // Union as expected

const r4 = b(a, One.A as One.A | One.C); // Works
const r5 = b(a, One.A as SomethingOne); // Still doesn't work...

๐Ÿ™ Actual behavior

The type gets widened when using BooleanMapToUnion... I guess it is the culprit.

๐Ÿ™‚ Expected behavior

Both union and using BooleanMapToUnion should work equally.

Contributor guide

Generic type gets widened in an unexpected way ยท Microsoft/TypeScript#52249 | Good First Issue