TypeScript 变量声明列表中的注解从异步函数中移除

vq8itlhq  于 4个月前  发布在  TypeScript
关注(0)|答案(6)|浏览(134)

TypeScript版本: 2.2.1
代码

async function example() {
    // result.value will be promise
    const promise = Promise.resolve("foo");
    await promise;

    // result.value will be "foo"
    return "foo";
}

预期行为:

忽略 __awaiter__generator ,输出应包括 // result.value will be promise

实际行为:

function example() {
    return __awaiter(this, void 0, void 0, function () {
        var promise;
        return __generator(this, function (_a) {
            switch (_a.label) {
                case 0:
                    promise = Promise.resolve("foo");
                    return [4 /*yield*/, promise];
                case 1:
                    _a.sent();
                    // result.value will be "foo"
                    return [2 /*return*/, "foo"];
            }
        });
    });
}
8e2ybdfx

8e2ybdfx1#

经过进一步探索,发现这种情况只发生在变量声明列表前出现注解时。

async function example() {
    // test abc
    let abc;

    // test def
    let def,
        // ghi
        ghi;

    // result.value will be promise
    const promise = Promise.resolve("foo");
    await promise;

    // result.value will be "foo"
    return "foo";
}

...变成:

function example() {
    return __awaiter(this, void 0, void 0, function () {
        var abc, def, 
        // ghi
        ghi, promise;
        return __generator(this, function (_a) {
            switch (_a.label) {
                case 0:
                    promise = Promise.resolve("foo");
                    return [4 /*yield*/, promise];
                case 1:
                    _a.sent();
                    // result.value will be "foo"
                    return [2 /*return*/, "foo"];
            }
        });
    });
}
js81xvg6

js81xvg62#

与@rbuckton讨论后发现这个问题比看起来要难...我们需要解决以下几个问题

  • 当有两个独立的变量声明注解时,应该把注解放在哪里?
async function example() {
    // test abc
    let abc;

    // test def
    let def,
    ....
}
function example() {
    return __awaiter(this, void 0, void 0, function () {
     --- what should this comment be -----
        var abc, def, 
    ....
}
  • 当前我们如何转换变量声明并提升它?声明提升并不容易让我们传入关于原始变量声明的信息(我们需要获取注解)
xqkwcwgp

xqkwcwgp3#

当有两个独立的变量声明注解时,应该在哪里放置注解?
按照目前的方式将变量声明通过注解分开似乎是合理的。

async function example() {
    // test abc
    let abc;

    // test def, ghi
    let def, ghi;

    // test jkl
    let jkl,
        // test mno
        mno;
    ...
}

默认输出:

function example() {
    return __awaiter(this, void 0, void 0, function () {
        // test abc
        var abc;
        // test def, ghi
        var def, ghi;
        // test jkl
        var jkl,
        // test mno
        mno;
        ...
}

使用 --removeComments 输出:

function example() {
    return __awaiter(this, void 0, void 0, function () {
        var abc, def, ghi, jkl, mno;
        ...
}
gwbalxhn

gwbalxhn4#

@JoshuaKGoldberg,我认为这里的示例不够清晰。请考虑以下情况:

async function example() {
  // comment1
  let a = 1;
  // comment2
  let b;
}

变为:

function example() {
  return __awaiter(this, void 0, void 0, function () {
    var a, b;
    return __generator(this, function (_a) {
      switch (_a.label) {
        case 0:
          a = 1;
          return [2 /*return*/];
      }
    });
  });
}

由于转换,a的声明已与其初始化器分离,而b的声明已被提升,不再与源位置的相关代码关联。
对于a,我们可以选择提升的声明或初始化器作为放置注解的位置。对于b,我们可以选择提升的声明或为该位置合成一个NotEmittedStatement,以便我们可以关联其注解。开发者可以选择任何一种选择,所以情况并不是那么明确。
如果我们确实选择将注解与声明关联,那么在生成器转换中模拟您的建议中的注解发射将需要一些非平凡的更改。

s1ag04yj

s1ag04yj5#

在我看来,变量声明之前的注解应该始终紧跟在声明变量的地方:
语义上:

  • 将注解放在变量声明上方的动机是为了为该变量的目的提供描述,就像任何已记录的结构(成员属性、函数等)一样。与声明相关的注解应该与声明保持一致。

实际上:
有时我们确实需要在调试器中打开编译后的JS文件。假设这个需求是合理的:

  • 在VS Code和其他地方,Intellisense可以识别JSDoc风格的注解,位于变量声明上方。具有JSDoc注解的变量可能很有用。
  • 注解通常包含用于查找所有内容的搜索词。删除原本打算被找到的注解是很令人沮丧的。

@rbuckton 使用您的示例并应用保留注解的原则:

function example() {
  return __awaiter(this, void 0, void 0, function () {
    // comment1
    var a;
    // comment2
    var b;
    return __generator(this, function (_a) {
      switch (_a.label) {
        case 0:
          a = 1;
          return [2 /*return*/];
      }
    });
  });
}

如果用 /** ... */ 风格的注解编写,Intellisense仍然有效:

async function example() {
  /** comment1 */
  let a = 1;
  /** comment2 */
  let b;
}
function example() {
  return __awaiter(this, void 0, void 0, function () {
    /** comment1 */
    var a;
    /** comment2 */
    var b;
    return __generator(this, function (_a) {
      switch (_a.label) {
        case 0:
          a = 1;
          return [2 /*return*/];
      }
    });
  });
}

@yuit 我不同意“按预期工作”的标签。如果这比值得的努力还要多,那么这是可以理解的,但我认为现在可以删除注解的方式不是很好。

ndasle7k

ndasle7k6#

我同意work as intended不是一个好选择。我会重新打开并看看我们能做什么。

相关问题