TS 似乎认为插值 prop 值的类型如下:
{ href: `#234${undefined}2213` }
不是字符串(当它们在可区分联合中使用时)?
下面的第三个 p3
实例会丢失 ev
字段的类型推断,但仅当 href 是内插的 esliteral 字符串时。
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沙盒完整重现
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 问题而提交的。编译器似乎认识到 判别 属性 href
是 string
类型,而不是 undefined
,但这发生得太晚了 根据上下文输入 onClick
回调参数。据推测,模板文字插值足以延迟事情导致问题。
GitHub 问题位于 Backlog 中,这意味着 TS 团队不计划尽快修复它......但因此它也被标记为需要帮助 a>,这意味着他们将接受社区成员的拉取请求;因此,任何希望尽快解决此问题的人都应该考虑自己贡献修复程序。
同时,我在这里建议的解决方法是提前进行字符串插值并将其存储在 const
中,以便提前知道其类型:
const theHref = `2${undefined}332132`; const p4: ClickableDiscriminatedUnion = { href: theHref, onClick: (ev) => ev.toUpperCase() // okay }
这很烦人(对于 JSX 来说可能更烦人),但至少它有效!