Heim  >  Fragen und Antworten  >  Hauptteil

Eine umgeschriebene Version dieses Titels könnte lauten: Ist das ein Fehler in TypeScript (Interpoliertes Esliteral wird nicht als String-Typ erkannt)

TS scheint zu glauben, dass die Art des interpolierten Prop-Werts wie folgt ist:

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

Keine Zeichenfolgen (wenn sie in unterscheidbaren Vereinigungen verwendet werden)?

Typinferenz für das dritte p3 实例会丢失 ev Feld unten, aber nur, wenn href eine interpolierte Esliteralzeichenfolge ist.

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-Komplettreproduktion

P粉015402013P粉015402013226 Tage vor479

Antworte allen(1)Ich werde antworten

  • P粉617597173

    P粉6175971732024-03-31 00:33:04

    更新 TS5.2+

    此错误已在 microsoft/TypeScript#53907 中修复,因此从TypeScript 5.2,问题中的代码将按需要工作,无需任何更改。

    使用 TS 5.2.0-dev.20230516 的 Playground 链接


    TS5.1 的原始答案-

    事实证明是的,这是 TypeScript 中的一个错误,如 microsoft/TypeScript#53888,这是我为了回答 Stack Overflow 问题而提交的。编译器似乎认识到 判别 属性 hrefstring 类型,而不是 undefined,但这发生得太晚了 根据上下文输入 onClick 回调参数。据推测,模板文字插值足以延迟事情导致问题。

    GitHub 问题位于 Backlog 中,这意味着 TS 团队不计划尽快修复它......但因此它也被标记为需要帮助,这意味着他们将接受社区成员的拉取请求;因此,任何希望尽快解决此问题的人都应该考虑自己贡献修复程序。

    同时,我在这里建议的解决方法是提前进行字符串插值并将其存储在 const 中,以便提前知道其类型:

    const theHref = `2${undefined}332132`;
    
    const p4: ClickableDiscriminatedUnion = {
      href: theHref,
      onClick: (ev) => ev.toUpperCase()  // okay
    }

    这很烦人(对于 JSX 来说可能更烦人),但至少它有效!

    0
  • StornierenAntwort