【问题标题】:Typescript tells me property 'padStart' does not exist on type 'string'. Why?打字稿告诉我“字符串”类型上不存在属性“padStart”。为什么?
【发布时间】:2019-02-16 23:12:39
【问题描述】:

当我输入 chrome 开发工具时:

"1".padStart(2,0)

我明白了

"01"

但是当我写的时候

"1".padStart(2,0)

在我的打字稿项目中

我明白了

Property 'padStart' does not exist on type 'string'.

Typescript 为什么会抱怨?我该如何解决这个问题?

【问题讨论】:

    标签: typescript


    【解决方案1】:

    padStartES2017 标准中定义。您需要告诉 typescript 使用适当的类型(ES2017 的类型)。如果您的运行时支持ES2017 所需的所有语言功能(在撰写本文时可能不是这种情况),您可以通过将目标设置为ES2017 来做到这一点。

    另一个选项是只设置libs 选项,以便根据ES2017 获取运行时对象的类型,但仍编译为您所针对的任何语言版本。(请注意,运行时本身需要支持padStart,typescript 不会提供任何 poly-fills)

    您可以在tsconfig 中使用lib 选项执行此操作:

    "compilerOptions": {
        "target": "es2016",
        "lib": [
            "es2017",
            "dom"
            "scripthost"
        ],
        // ...
    
    }
    

    您可以在answer 中阅读有关 lib 与目标的更多信息

    【讨论】:

    • 运行时是否需要支持 padStart,即使我将它添加到库中?
    • @user1283776 这些库只是告诉编译器该方法存在于运行时中。他们不添加任何代码。你需要使用 polyfill 是运行时不支持它,typescript 不提供 polifills
    【解决方案2】:

    要让 TypeScript 识别 String.prototype.padStart(),您需要在 tsconfig.json 的库列表中指定 es2017。如果你这样做,TypeScript 将假定所有 ES2017 特性都可以使用,这可能不是你想要的。

    像 Node.js 这样的平台并不总是实现新 ECMAScript 语言规范的完整功能集,因此只添加您确信存在的语言功能会更安全。如果您不确定目标平台支持哪些功能,您可以在 node.greenMDNs browser compatibility list 等页面上查找它们。

    padStart 函数是 String 原型的一部分,因此只需在 tsconfig.json 中添加 es2017.string 就足够了:

    {
      "compilerOptions": {
        "lib": ["es6", "es2017.string"],
        ...
      },
    }
    

    【讨论】:

    • 非常适合使用es2017.string 而不仅仅是es2017
    • 这是提取库特定部分的绝妙方法!
    【解决方案3】:

    TypeScript 假定默认情况下,您的转译代码将在最糟糕的环境中运行(现在,我希望,真的是最糟糕的),即在仅支持 ES5 的浏览器中。 String.prototype.padStart is an experimental feature 仅在 ES2017 中支持,因此 TypeScript 无法确定它在运行时是否会出现并准备就绪。

    如果您知道这种“最坏情况”不会出现(您不是针对旧浏览器,或者正在使用 polyfills),您可以对您的 tsconfig.json 进行以下更改之一:

    1. 更改您的转译目标。这迫使您的消费者拥有 ES2017(或更新的)运行时,但不需要您自己付出更多的努力。在这种情况下,设置target: "es2017"

    2. 更改可用库列表。在这种情况下,如果您不确定您的客户端是否足够现代,则必须为您正在使用的 ES2017 元素提供 polyfill。在这种情况下,将"es2017"添加到lib参数中的数组中(如果为空,则为lib: ["es2017"])。

    【讨论】:

    • 谢谢,很好的解释!即使将 es2017 添加到库中,打字稿也会抱怨。我需要做更多的事情吗,比如运行某种 npm 命令?
    • 我是否正确阅读了您的帖子,我将 es2017 添加到库中并以 es5 作为目标,padStart 也适用于旧浏览器?
    • 不,反之亦然。当您拥有target: "es2017" 时,您的代码可能根本无法在旧版浏览器上运行(因为语法错误)。当您拥有lib: ["es2017"] 时,您的代码将运行,但在 ES2017 中添加的任何功能都必须显式地填充。
    猜你喜欢
    • 2019-08-17
    • 2017-03-02
    • 2021-09-07
    • 1970-01-01
    • 2017-08-07
    • 2017-03-26
    • 2017-09-06
    • 2020-05-21
    • 1970-01-01
    相关资源
    最近更新 更多