🔎 搜索词
私有元素,计算键,超类调用
🕗 版本与回归信息
- 这是一场崩溃
- 在版本______和______之间发生了变化
- 在提交或PR______中发生了变化
- 这是我尝试的每个版本的行为,我查阅了关于类的FAQ条目
- 由于______,我无法在之前的版本上测试这个
⏯ Playground链接
https://www.typescriptlang.org/play?target=9#code/DYUwLgBAxghgDmArgJxAEwGIHssEEpQgDORANBKkYsGANwBQUwMJEAQhAN70TRYB2RMMkRQwWZAAoAbgEouPXtHhJUmHPkKsAvBGmKAvvSP1+IAO7RmrAMIQQADzAh+aIuwW8oAoSLETJeW4lKxZ3XE8QiCEYMABLKAgAYgAzHAhdABYAJgYo6LBYhIgAbSo4EClJMHltAD4IMAA6VJxZAF08pQMu3kpqSF1YBBR0bDwCYiJJXFlaXkNjekYfLFAm4CwAc0lOCmIBiAM5oA
💻 代码
let capturedFooAccess, result;
class B {
constructor(v) {
capturedFooAccess = v
}
}
new class C extends B {
constructor() {
class A {
static #foo = 42;
static [super((t) => t.#foo)];
};
result = capturedFooAccess(A);
}
}
console.log({ result });
🙁 实际行为
转换后的代码抛出 "Private field '#foo' must be declared in an enclosing class" 错误,因为私有的IIFE在类 A
之前被提升。
🙂 预期行为
它应该打印 { result: 42 }
输入已经是ES2022,TS可以保持原样。
关于问题的附加信息
我们可以在ES2022目标中避免这个问题,但我还没有弄清楚如何处理装饰器表达式。要么我们失去了 #foo
的访问权限,要么 super()
被移动到了未派生类 A
的范围。
6条答案
按热度按时间bvhaajcl1#
翻译结果为:它应该打印$x^1m0n^1x$
输入已经是ES2022,TS可以保持原样。
这就是我观察到的行为:
https://www.typescriptlang.org/play?target=9&filetype=js#code/DYUwLgBAxghgDmArgJxAEwGIHssEEpQgDORANBKkYsGANwBQUwMJEAQhAN70TRYB2RMMkRQwWZAAoAbgEouPXtHhJUmHPkKsAvBGmKAvvSP1+IAO7RmrAMIQQADzAh+aIuwW8oAoSLETJeW4lKxZ3XE8QiCEYMABLKAgAYgAzHAhdABYAJgYo6LBYhIgAbSo4EClJMHltAD4IMAA6VJxZAF08pQMu3kpqSF1YBBR0bDwCYiJJXFlaXkNjekYfLFAm4CwAc0lOCmIBiAM5oA
cu6pst1q2#
这是我观察到的行为:https://www.typescriptlang.org/play?target=9&filetype=js#code/DYUwLgBAxghgDmArgJxAEwGIHssEEpQgDORANBKkYsGANwBQUwMJEAQhAN70TRYB2RMMkRQwWZAAoAbgEouPXtHhJUmHPkKsAvBGmKAvvSP1+IAO7RmrAMIQQADzAh+aIuwW8oAoSLETJeW4lKxZ3XE8QiCEYMABLKAgAYgAzHAhdABYAJgYo6LBYhIgAbSo4EClJMHltAD4IMAA6VJxZAF08pQMu3kpqSF1YBBR0bDwCYiJJXFlaXkNjekYfLFAm4CwAc0lOCmIBiAM5oA
哦,我没想到复制粘贴还有一个要求:语言选项应该设置为“TypeScript”,(你的是JavaScript)。
cig3rfwq3#
我注意到,选择TS会改变emit。这几乎肯定是一个bug。
ffdz8vbo4#
哦,这是一个仅限于TS的问题,因为当我启用
useDefineForClassFields
选项时,输出是好的。tez616oj5#
它(
uDFCF
)应该在tsc
中默认启用,以便目标为es2022+(我记得是这样的),但是不幸的是,playground中没有这个标志的"默认"开关,需要在playground中手动设置。z9ju0rcb6#
我们目前报告一个错误,如果你在类元素计算属性名称中使用
this
,因为它可能被认为是模糊的,不知道你指的是哪个this
。出于同样的原因,我们也应该将其视为错误来引用super
。当
useDefineForClassFields
是false
时,我们必须移动一些东西以确保保留评估顺序。这意味着在尝试避免将逻辑注入到计算属性名称中时,在static {}
块中评估一些东西,因为这会产生不可读的代码。虽然这里的 emit 绝对是个 bug ,但使用static {}
在这里生成期望的输出有点复杂,因为将捕获super
的箭头移动到static {}
块中会改变其含义。为了保留作用域和评估顺序,我们需要发出的东西类似于这样:
这似乎是一个多余且不必要的转换;然而,如果你修改示例以包含具有计算名称的静态字段的初始化器(例如,
static [super(...)] = 1
),就会更明显地了解为什么我们会进行这种转换: