TypeScript verbatimModuleSyntax + import of ambient const enum missing error

l3zydbqr  于 6个月前  发布在  TypeScript
关注(0)|答案(5)|浏览(176)

Bug报告

preserveValueImports 在导入带有 isolatedModuleson 的 ambient const enum 时不会报错。相反,你会在运行时得到一个错误。

🩹 建议解决方案

如果命名导入是类型而不是 ambient const enum,你会得到编译时错误。
#47817 通过将其 predicate 更改为包括 ambient const enums 来引发该错误。

🔍 搜索关键词

preserveValueImports ambient const enum

🕗 版本与回归信息

4.5.0-dev.20210909 - 4.7.0-dev.20220225

⏯️ Playground 链接

Workbench Repro

🧑‍💻 代码

// @preserveValueImports
// @isolatedModules
import { RoundingMode } from "big.js";

// @filename: node_modules/big.js/index.d.ts
export const enum RoundingMode {}

🙁 实际行为

运行时错误:

import { RoundingMode } from "big.js";
         ^^^^^^^^^^^^
SyntaxError: Named export 'RoundingMode' not found. The requested module 'big.js' is a CommonJS module, which may not support all module.exports as named exports.
CommonJS modules can always be imported via the default export, for example using:

import pkg from 'big.js';
const { RoundingMode } = pkg;

🙂 预期行为

编译时错误(使用 #47817):

index.ts:1:10 - error TS1446: 'RoundingMode' resolves to a type-only declaration and must be imported using a type-only import when 'preserveValueImports' and 'isolatedModules' are both enabled.

1 import { RoundingMode } from "big.js";
           ~~~~~~~~~~~~
1dkrff03

1dkrff031#

@andrewbranch what's your take? The linked PR has some additional context

bis0qfac

bis0qfac2#

我认为在ambient上的区分是非常有问题的,尽管我理解为什么这样做是诱人的。如果我们不是在讨论const enums的谜题,那么将ambient视为非ambient声明的存在方式是非常错误的。Ambient声明假定与其他非ambient声明一样存在,只是编译器不知道它们的位置。类型检查行为通常不应受到ambient的影响;否则,您将在消费.ts文件和消费相同文件的.d.ts输出之间获得不同的行为。更令人困惑的是,在项目引用中,您将在CLI和编辑器之间获得不同的行为,因为前者使用.d.ts文件引用的项目,而后者默认使用.ts文件。
当谈论const enums时,故事略有不同,因为当您tsc -d一个const enum声明时,我们在.d.ts文件中发出一个(ambient)const enum声明,并且是否存在现有的运行时值可以根据其他编译器选项进行切换。因此,给定一个ambient const enum声明,我们真的不知道是否存在一个运行时等效项。(这是我提议为const enums引入某种语法标记以指示是否存在真正的运行时等效项的基础,但被拒绝了,因为它似乎使枚举变得更复杂。我认为这个问题表明这样的标记不会扩展我们关心的枚举信息的位数,而是编码了一个相当基本的问题——是否存在任何运行时表示——我们已经尝试考虑但未能准确地做到这一点。)另一方面,如果编译器看到一个非ambient const enum声明,它可以知道是否存在运行时等效项,因为当前的编译将负责生成它。所以我认为在这里的提案在许多方面是有意义的:

  • ambient const enum → 不知道是否有reified → 总是出错
  • non-ambient const enum → 检测是否有reified → 如果没有则出错

实际上是项目引用的情况让我对这个感到不安。在没有其他更改的情况下,您将无法使用--isolatedModules --preserveValueImports从引用的项目中消费自己的保留const enums,但这个错误不会出现在编辑器中。我们可以检查声明是否来自项目引用重定向,并检查引用项目的编译器选项(这将需要向TypeCheckerHost添加另一个API)以查看它是否会被保留。但这也可能不太正确,因为const enum声明可能是在输入文件中用declare手写的,通过这个复杂的逻辑,我们可以说应该出错(???),因为我们再次不确定是否存在运行时等效项。
总结:

  • 我同意当前状态过于宽容;它没有捕获我想捕获的一类有问题的导入。
  • 这个提案可能是我们在不向将来的const enums声明发出更多信息的情况下分类哪些导入将在运行时起作用或失败的最佳方法,但项目引用在CLI和编辑器中的行为不同似乎是我的障碍。
  • 项目引用CLI和编辑器之间的不一致可能可以通过一些额外的检查逻辑来缓解,但这种逻辑将是不完美的,并且检查器中不存在这种逻辑。
brjng4g3

brjng4g33#

感谢!

  • 我们不是已经在 ambient 上区分了吗,以便引发类似的错误?
error TS2748: Cannot access ambient const enums when the '--isolatedModules' flag is provided.

https://github.com/microsoft/TypeScript/blob/e4fe50cca477a3e46f9b629a6c5be0b0ed8b010f/src/compiler/checker.ts#L34251
所以在大多数情况下,你不能从引用的项目中使用 --isolatedModules 消耗自己的保留 const 枚举,而且这个错误不会出现在编辑器中?

  • 我猜 "deconstifying" preserved const enums 的问题是,如果 CLI 使用 .d.ts 文件来引用项目,它就不会内联这些枚举 ... 除非你使用一个“足够智能的捆绑器”:tm:?

关于删除 vs. 为保留 const 枚举的声明发出标记的设计会议记录:Design Meeting Notes,12/1/2021 #46983 (评论)
换句话说,这个提案不引入任何新问题吗?对于您提到的现有问题,有一个解决方案可以在 const enums 的声明发出中添加更多信息,但它在内联引用项目的枚举时有问题? ... 但也许可以解决这个问题?这是一个单独的问题吗?

rur96b6h

rur96b6h4#

这仍然是verbatimModuleSyntax的问题,但我在之前的信息中关心的项目引用差异最近在#57914中得到了处理。我认为我们应该继续为5.6这样做。在导入时出错没有太大意义,但在保留的导入中出错是有意义的。在verbatimModuleSyntax下,我们应该让错误仅出现在导入处,而不是使用站点。这样,我们可以使用单个ts-ignore来摆脱不知道 ambient const enum 是否与preserveConstEnums示例化的困境的情况。

von4xj4u

von4xj4u5#

你好,我是Repro bot。我可以协助缩小范围并跟踪不同版本的编译器错误!此评论反映了问题正文中运行的夜间TypeScript的当前重现状态。
问题正文代码块由@jablko提供
异常:错误 - TS5102错误:选项'preserveValueImports'已被移除。请从您的配置中删除它。请使用'verbatimModuleSyntax'代替。

Error: error TS5102: Option 'preserveValueImports' has been removed. Please remove it from your configuration.
  Use 'verbatimModuleSyntax' instead.

    at Object.createVirtualTypeScriptEnvironment (/home/runner/work/_actions/microsoft/TypeScript-Twoslash-Repro-Action/8680b5b290d48a7badbc7ba65971d526c61b86b8/dist/index.js:8128:11)
    at twoslasher (/home/runner/work/_actions/microsoft/TypeScript-Twoslash-Repro-Action/8680b5b290d48a7badbc7ba65971d526c61b86b8/dist/index.js:7618:17)
    at /home/runner/work/_actions/microsoft/TypeScript-Twoslash-Repro-Action/8680b5b290d48a7badbc7ba65971d526c61b86b8/dist/index.js:439:44
    at runTwoslashRequests (/home/runner/work/_actions/microsoft/TypeScript-Twoslash-Repro-Action/8680b5b290d48a7badbc7ba65971d526c61b86b8/dist/index.js:406:56)
    at run (/home/runner/work/_actions/microsoft/TypeScript-Twoslash-Repro-Action/8680b5b290d48a7badbc7ba65971d526c61b86b8/dist/index.js:20096:75)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)

历史信息
| 版本 | 重现输出 | 时间 |
| ------------ | ------------ | ------------ |
| 5.0.2, 5.1.3, 5.2.2, 5.3.2, 5.4.2 | !!️异常:错误 - TS5101错误:选项'preserveValueImports'已弃用,将在TypeScript 5.5中停止工作。指定编译器选项'ignoreDeprecations': '5.0'以静默此错误。请使用'verbatimModuleSyntax'代替。

Error: error TS5101: Option 'preserveValueImports' is deprecated and will stop functioning in TypeScript 5.5. Specify compilerOption '"ignoreDeprecations": "5.0"' to silence this error.
  Use 'verbatimModuleSyntax' instead.

    at Object.createVirtualTypeScriptEnvironment (/home/runner/work/_actions/microsoft/TypeScript-Twoslash-Repro-Action/8680b5b290d48a7badbc7ba65971d526c61b86b8/dist/index.js:8128:11)
    at twoslasher (/home/runner/work/_actions/microsoft/TypeScript-Twoslash-Repro-Action/8680b5b290d48a7badbc7ba65971d526c61b86b8/dist/index.js:7618:17)
    at /home/runner/work/_actions/microsoft/TypeScript-Twoslash-Repro-Action/8680b5b290d48a7badbc7ba65971d526c61b86b8/dist/index.js:439:44
    at /home/runner/work/_actions/microsoft/TypeScript-Twoslash-Repro-Action/8680b5b290d48a7badbc7ba65971d526c61b86b8/dist/index.js:427:51
    at Array.map (<anonymous>)
    at runTwoSlashOnOlderVersions (/home/runner/work/_actions/microsoft/TypeScript-Twoslash-Repro-Action/8680b5b290d48a7badbc7ba65971d526c61b86b8/dist/index.js:425:23)
    at runTwoslashRequests (/home/runner/work/_actions/microsoft/TypeScript-Twoslash-Repro-Action/8680b5b290d48a7badbc7ba65971d526c61b86b8/dist/index.js:408:66)
    at run (/home/runner/work/_actions/microsoft/TypeScript-Twoslash-Repro-Action/8680b5b290d48a7badbc7ba65971d526c61b86b8/dist/index.js:20096:75)
    at runMicrotasks (<anonymous>)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)

| ⚠️速度慢得多 |

相关问题