Luk*_* Vo 8 function void any typescript
我在 TypeScript 上遇到了一个奇怪的问题。我最近了解了void ...operator,因为我需要应用它所以eslint不会报告no-floating-promises。然而,这个特定的代码片段以某种方式导致了我无法在 TypeScript Playground 上重现的问题:
class A {
async a() {}
async onTickAsync(repeat: boolean) {
try {
await this.a();
} catch(e) {
console.error(e);
} finally {
if (repeat) {
window.setTimeout(() => void this.onTickAsync(true), 200);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
VS Code 会报这个错误:
TS7011:缺少返回类型注释的函数表达式隐式具有“any”返回类型。
但是,该问题在TS Playground上无法重现。VS Code 和 Playground 都使用 TypeScript 4.5.4。这是我的tsconfig.json:
class A {
async a() {}
async onTickAsync(repeat: boolean) {
try {
await this.a();
} catch(e) {
console.error(e);
} finally {
if (repeat) {
window.setTimeout(() => void this.onTickAsync(true), 200);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
我知道它可以通过添加: void返回类型或删除void操作或删除来修复noImplicitAny:
window.setTimeout((): void => void this.onTickAsync(true), 200);
Run Code Online (Sandbox Code Playgroud)
我想问一下:是什么原因导致这个错误呢?为什么它只发生在我的 IDE/本地而不是 Playground 上?
为了确保这不仅仅是 VS Code 造成的,我还在一个单独的终端上运行了tsc --version和:tsc
tsc --showConfig输出:
PS C:\Users\lukev\Downloads\Temp> tsc --showConfig
{
"compilerOptions": {
"noImplicitAny": true,
"noEmitOnError": true,
"sourceMap": true,
"target": "esnext",
"module": "esnext"
},
"files": [
"./test.ts"
],
"exclude": [
"node_modules"
],
"compileOnSave": true
}
Run Code Online (Sandbox Code Playgroud)
同样有趣的是,其他函数不会发生这种情况。例如,这不会产生任何错误。好像是有什么东西window.setTimeout。我发现Function类型之间有一些不同,() => void例如):
class A {
doSomething1(_: Function) { }
doSomething2(_: () => any) { }
doSomething3(_: () => void) { }
async a() { }
async onTickAsync(repeat: boolean) {
// Only this one produces error
this.doSomething1(() => void this.onTickAsync(true));
this.doSomething2(() => void this.onTickAsync(true));
this.doSomething3(() => void this.onTickAsync(true));
}
}
Run Code Online (Sandbox Code Playgroud)
请参阅microsoft/TypeScript#36651以获得权威答案。
您的问题是您已启用编译--noImplicitAny器选项,但尚未启用编译器--strictNullChecks选项。您可以在 TypeScript Playground 中设置这些选项并重现您的问题。
旁白:请注意,这--strictNullChecks是编译器功能系列的--strict一部分,通常建议将其作为事实上的“标准”类型安全级别的一部分。您并不是真正询问应该使用哪些编译器选项,但请注意,如果您使用一组不常见的编译器选项,您更有可能遇到一般 TypeScript 社区不太了解的编译器行为。好吧,就这些了。
所以我们知道如何重现,但还没有明确回答为什么这里会出现错误。我们现在就这样做吧。启用后--strictNullChecks,运算void符会生成类型undefined的值。但是对于--strictNullChecks disabled,实际上并没有明确的undefined类型,并且运算符会生成类型的void值。除非您明确注释类型为,否则您将在以下情况下收到错误:anyany--noImplicitAny
// with --strictNullChecks disabled
() => void 0; // error!
// Function expression, which lacks return-type annotation,
// implicitly has an 'any' return type.
(): undefined => void 0; // okay
//^^^^^^^^^^^ <-- arrow function return type annotation
Run Code Online (Sandbox Code Playgroud)
void正如您所看到的,如果给定运算符的返回类型为上下文类型,您也可以消除错误:
function foo(cb: () => any) { }
foo(() => void 0); // okay, void 0 is contextually typed as any
Run Code Online (Sandbox Code Playgroud)
请注意,该Function接口有点奇怪,没有真正的调用签名,请参阅microsoft/TypeScript#20007,因此它无法提供上下文类型:
function bar(cb: Function) { }
bar(() => void 0); // implicit any error!
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
27884 次 |
| 最近记录: |