A rewritten version of this title could be: Is this a bug in TypeScript? (Interpolated esliteral not being recognized as a string type)
P粉015402013
P粉015402013 2024-03-30 08:37:56
0
1
499

TS seems to think that the type of the interpolated prop value is as follows:

{ href: `#234${undefined}2213` }

are not strings (when they are used in distinguishable unions)?

The third p3 instance below loses type inference for the ev field, but only if the href is an interpolated esliteral string.

type BiomePlainLinkProps = {
  href: string;
  onClick?: (event: string) => void;
}

type BiomeButtonProps = {
  href?: never;
  onClick?: (event: number) => void;
}

export type ClickableDiscriminatedUnion =
  | BiomePlainLinkProps
  | BiomeButtonProps;

const p1: ClickableDiscriminatedUnion = {
  href: '2332132',
  onClick: (ev) => console.log('@@@@', ev), // ev is string here
}

const p2: ClickableDiscriminatedUnion = {
  onClick: (ev) => console.log('@@@@', ev), // ev is number here
}

const p3: ClickableDiscriminatedUnion = {
  href: `2${undefined}332132`,
  onClick: (ev) => console.log('@@@@', ev), // ev is any (not string) here
}

TS sandbox complete reproduction

P粉015402013
P粉015402013

reply all(1)
P粉617597173

Update TS5.2

This bug has been fixed in microsoft/TypeScript#53907, so as of TypeScript 5.2, the code in the question will work as expected without any changes.

Use the Playground link of TS 5.2.0-dev.20230516


Original answer for TS5.1-

It turns outYes, this is a bug in TypeScript, as microsoft/TypeScript#53888, which I submitted in response to a Stack Overflow question. The compiler seems to recognize that the discrimination attribute href is of type string rather than undefined, but this happens too late Enter onClick callback parameters based on context. Presumably template literal interpolation is enough to delay things causing problems.

The

GitHub issue is in the Backlog, which means the TS team doesn't plan to fix it anytime soon... but therefore it's also marked as Needs Help a>, which means They will accept pull requests from community members; therefore, anyone looking to resolve this issue as soon as possible should consider contributing the fix themselves.

Meanwhile, the workaround I suggest here is to do the string interpolation ahead of time and store it in const so that its type is known ahead of time:

const theHref = `2${undefined}332132`;

const p4: ClickableDiscriminatedUnion = {
  href: theHref,
  onClick: (ev) => ev.toUpperCase()  // okay
}

It's annoying (probably even more annoying for JSX), but at least it works!

Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template