【问题标题】:Typescript type assertions in parameters参数中的打字稿类型断言
【发布时间】:2017-11-08 08:41:55
【问题描述】:

到目前为止,我很喜欢 typescript,但发现我需要做很多类型断言。例如,将 EventTarget 转换为 HTMLAnchorElement 对我来说是一个常见的用例。但是要做到这一点,我需要使用以下内容:

getTabID(eventTarget: EventTarget) : string {
    // without the following variable, the compiler tells me that .hash 
    // is not a property of EventTarget, which according to the interface, it isn't.
    // So thats fine, i'll cast it to an Element
    let mEventTarget: HTMLAnchorElement = <HTMLAnchorElement>eventTarget
    let mTabID: string
    if(mEventTarget.hash){
        mTabID = mEventTarget.hash.split('#')[1]
    } 
    return mTabID
}

然而,这意味着如果我不希望编译器抛出错误,我需要在我的函数中创建变量来进行类型断言。我不介意额外的输入,但这些最终也会出现在 JS 中,最终会在我的 js 文件中浪费字节。

我希望能够做到以下几点:

getTabID(eventTarget: EventTarget) : string {
    let mTabID: string
    // Do the type assertion in the parameter 
    if(<HTMLAnchorElement> eventTarget.hash){
        mTabID = mEventTarget.hash.split('#')[1]
    } else {
        mTabID = mEventTarget.dataset.tabId
    }
    return mTabID
}

我已经很好地查看了文档和 SO,但似乎找不到任何方法来做到这一点。有人有什么想法吗?

【问题讨论】:

  • 如果你确定eventTarget永远是HTMLAnchorElement,为什么不在参数中声明eventTarget: HTMLAnchorElement并强制getTabID的调用者确保它是HTMLAnchorElement
  • 您可以使用eventTarget: EventTarget | HTMLAnchorElement 作为类型,这样可以同时启用 EventTarget 和 HTMLAnchorElement 作为类型。
  • @Saravana 因为当我调用该函数时,调用者会抛出一个错误,指出您无法将EventTarget 传递给需要HTMLAnchorElement 的函数。 @Wernerson 我想这会阻止错误,但似乎是个 hack。
  • @C02Equinox 关键是您可以在调用者端进行断言。喜欢getTabID(target as HTMLAnchorElement)。如果这一切感觉很麻烦,我只需键入参数any:(eventTarget: any) 即可关闭类型检查。
  • 哦,太棒了!我曾尝试使用as 语法,但不知道在哪里使用它。完美的!谢谢!

标签: typescript parameters type-assertion


【解决方案1】:

您可以使用类型保护来实现这一点。

一个例子是:

function isAnchor(eventTarget: EventTarget): eventTarget is HTMLAnchorElement {
  return (<HTMLAnchorElement>eventTarget).hash != undefined;
}


function getTabID(eventTarget: EventTarget): string {
  let mTabID: string
  // Do the type assertion in the parameter 
  if (isAnchor(eventTarget)) {
    mTabID = eventTarget.hash.split('#')[1]
  } else {
    mTabID = eventTarget.dataset.tabId
  }
  return mTabID
}

注意:我不知道 dataset 是哪个接口的一部分,但您也可以为它制作类型保护。

您可以在手册here 中了解有关类型保护的更多信息。

【讨论】:

  • 感谢您的建议!这确实满足了编译器,但是它实现了一个全新的函数来进行类型断言。这可能会减少代码错误的可能性,但不会减少文件大小。
【解决方案2】:

您可以执行内联类型断言,方法是将断言用括号括起来:

if((<HTMLAnchorElement>eventTarget).hash) {

您可能还会看到可以采取哪些措施来避免需要类型断言,例如:

getTabID(eventTarget: HTMLAnchorElement) : string {
    let mTabID: string;

    if(eventTarget.hash){
        mTabID = eventTarget.hash.split('#')[1]
    } 

    return mTabID
}

最后,当您在其中一个示例中混合 EventTargeteventTarget 时,请注意大小写。

【讨论】:

  • 您的第一个解决方案正是我所希望的,而且似乎效果很好。谢谢!但是,您的第二个解决方案只会将问题从该函数转移到调用者。调用 this.getTabID(event.target) 只会抛出一个错误,提示您无法将 EventTarget 分配给类型 HTMLAnchorElement
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-03-22
  • 1970-01-01
  • 2020-03-22
  • 1970-01-01
  • 1970-01-01
  • 2018-08-12
  • 2018-05-02
相关资源
最近更新 更多