【问题标题】:TypeScript custom type hintTypeScript 自定义类型提示
【发布时间】:2020-11-23 11:07:10
【问题描述】:

我想声明一些简单的类型,以区分“url”、“absolute url”、“json”等字符串。在提示中显示声明的类型就足够了,但类型检查会更好(即“url”不能传递给期望“绝对url”的函数)。

问题在于 TypeScript/VSC 可以理解,“url”是一个字符串,会跳过我声明的类型。有没有办法在提示中显示声明的类型?只要不破坏 TypeScript 功能,我不介意 hacky 解决方案。

示例代码 - 我想在提示中看到“const data: url”:

我想看到的(但这个解决方案很糟糕,因为 url 不应该是数字):

【问题讨论】:

    标签: typescript visual-studio-code typescript-generics


    【解决方案1】:

    解决方案

    将原始类型与空对象类型相交。

    type url = string & {};
    

    说明

    请注意,{} 并不像您想象的那样表示 空对象。它代表除null | undefined 之外的所有内容。在这里,将string{} 混合不会改变任何内容,但现在会保留名称。

    【讨论】:

    • 感谢您的解决方案和解释-我不知道。
    【解决方案2】:

    我没有找到实现您要求使用原始类型的方法的技巧。 但是你不介意使用enum吗?

    作为专业人士,您可以将您的网址放在一个地方。

    【讨论】:

    • 这是个好主意,但不幸的是不会涵盖我的所有情况,即从 API 获取数据。无论如何,谢谢你。
    【解决方案3】:

    无法保证您的类型别名会被保留,因为 typescript 并不关心某个东西是 string 还是 url,因为它们具有相同的基础类型。这是由于打字稿采用了structural (as opposed to nominal) 打字哲学,尽管有一些建议支持这种用例(https://github.com/microsoft/TypeScript/pull/33038https://github.com/microsoft/TypeScript/pull/33290)。

    与此同时,您最好的选择是使用具有如下返回类型的函数:

    至于您的其他问题 - 不同的 url 类型 - 您可以使用 discriminated unions 和向 string 对象添加属性:

    type url = string & { _subtype: 'absoluteUrl' | 'relativeUrl' | 'other' }
    type absoluteUrl = url & { _subtype: 'absoluteUrl' }
    type relativeUrl = url & { _subtype: 'relativeUrl' }
    
    const createAbsoluteUrl = (input: string) => {
      const createdAbsoluteUrl = input
      ;(createdAbsoluteUrl as any)._subtype = 'absoluteUrl'
      return createdAbsoluteUrl as absoluteUrl
    }
    
    const createRelativeUrl = (input: string) => {
      const createdRelativeUrl = input
      ;(createdRelativeUrl as any)._subtype = 'relativeUrl'
      return createdRelativeUrl as relativeUrl
    }
    
    const expectAbsoluteUrl = (input: absoluteUrl) => {
      // something
    }
    
    const expectRelativeUrl = (input: relativeUrl) => {
      // something
    }
    
    

    然后您应该会看到预期的类型错误:

    如果您采用这种方法,您可能还会发现 user defined type guards 很有用

    【讨论】:

    • 这个答案很棒,还包括类型检查,非常感谢您的帮助。对我来说有一个很大的缺点——函数会被编译成 JS,性能会受到一点影响,所以我会选择 Karol Majewski 的解决方案。
    猜你喜欢
    • 2021-01-22
    • 2020-11-11
    • 2017-06-18
    • 2016-02-23
    • 2021-11-16
    • 2015-05-01
    • 2020-08-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多