"Function expression, which lacks return-type annotation, implicitly has an 'any' return type" 添加void操作时
"Function expression, which lacks return-type annotation, implicitly has an 'any' return type" when adding void operation
我在 TypeScript 上遇到了一个 st运行ge 问题。我最近了解了 void ...
运算符,因为我需要应用它,这样 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);
}
}
}
}
VS Code 会报告这个错误:
TS7011: Function expression, which lacks return-type annotation, implicitly has an 'any' return type.
但是,该问题无法在 TS Playground 上重现。 VS Code 和 Playground 都使用 TypeScript 4.5.4。这是我的 tsconfig.json
:
{
"compileOnSave": true,
"compilerOptions": {
"noImplicitAny": true,
"noEmitOnError": true,
"sourceMap": true,
"target": "ESNext",
"module": "ESNext"
},
"exclude": [
"node_modules"
]
}
我知道可以通过添加 : void
return 类型或删除 void
操作或删除 noImplicitAny
:
来修复它
window.setTimeout((): void => void this.onTickAsync(true), 200);
请问:错误原因是什么?为什么它只发生在我的 IDE/local 而不是操场上?
为了确定这不仅仅是因为 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
}
同样有趣的是,它不会发生在其他函数上。例如,这不会产生任何错误。好像是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));
}
}
我可以重现你的问题,虽然我无法回答为什么会发生这种情况,但你可以通过省略 void
operator 和链接来修复编译器错误承诺满足 ESLint 的 catch
方法:
// before
window.setTimeout(() => void this.onTickAsync(true), 200);
// after
window.setTimeout(() => this.onTickAsync(true).catch(() => {}), 200);
请参阅 microsoft/TypeScript#36651 以获得权威答案。
您的问题是您启用了 the --noImplicitAny
compiler option but you have not enabled the --strictNullChecks
compiler option. You can set these options in the TypeScript Playground and reproduce your issue。
旁注:请注意 --strictNullChecks
是 the --strict
family of compiler features 的一部分,通常建议将其作为事实上的“标准”类型安全级别的一部分。你并不是真的在问你应该使用哪些编译器选项,但请注意,如果你使用一组不常见的编译器选项,你更有可能 运行 进入一般 TypeScript 社区并不了解的编译器行为.好了,说完了。
所以我们知道如何重现,但还没有明确回答为什么这里有错误。让我们现在就这样做。启用 --strictNullChecks
后,the void
opterator produces a value of the undefined
type. But with --strictNullChecks
disabled, there isn't really a distinct undefined
type, and the void
operator produces a value of the any
type. And unless you explicitly annotate 类型为 any
,您将在 --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
如您所见,如果 void
运算符的 return 类型被赋予 contextual type:
,您也可以消除错误
function foo(cb: () => any) { }
foo(() => void 0); // okay, void 0 is contextually typed as any
注意 Function
接口有点奇怪,没有真正的 call signature, see microsoft/TypeScript#20007,所以它不能提供上下文类型:
function bar(cb: Function) { }
bar(() => void 0); // implicit any error!
我在 TypeScript 上遇到了一个 st运行ge 问题。我最近了解了 void ...
运算符,因为我需要应用它,这样 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);
}
}
}
}
VS Code 会报告这个错误:
TS7011: Function expression, which lacks return-type annotation, implicitly has an 'any' return type.
但是,该问题无法在 TS Playground 上重现。 VS Code 和 Playground 都使用 TypeScript 4.5.4。这是我的 tsconfig.json
:
{
"compileOnSave": true,
"compilerOptions": {
"noImplicitAny": true,
"noEmitOnError": true,
"sourceMap": true,
"target": "ESNext",
"module": "ESNext"
},
"exclude": [
"node_modules"
]
}
我知道可以通过添加 : void
return 类型或删除 void
操作或删除 noImplicitAny
:
window.setTimeout((): void => void this.onTickAsync(true), 200);
请问:错误原因是什么?为什么它只发生在我的 IDE/local 而不是操场上?
为了确定这不仅仅是因为 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
}
同样有趣的是,它不会发生在其他函数上。例如,这不会产生任何错误。好像是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));
}
}
我可以重现你的问题,虽然我无法回答为什么会发生这种情况,但你可以通过省略 void
operator 和链接来修复编译器错误承诺满足 ESLint 的 catch
方法:
// before
window.setTimeout(() => void this.onTickAsync(true), 200);
// after
window.setTimeout(() => this.onTickAsync(true).catch(() => {}), 200);
请参阅 microsoft/TypeScript#36651 以获得权威答案。
您的问题是您启用了 the --noImplicitAny
compiler option but you have not enabled the --strictNullChecks
compiler option. You can set these options in the TypeScript Playground and reproduce your issue。
旁注:请注意 --strictNullChecks
是 the --strict
family of compiler features 的一部分,通常建议将其作为事实上的“标准”类型安全级别的一部分。你并不是真的在问你应该使用哪些编译器选项,但请注意,如果你使用一组不常见的编译器选项,你更有可能 运行 进入一般 TypeScript 社区并不了解的编译器行为.好了,说完了。
所以我们知道如何重现,但还没有明确回答为什么这里有错误。让我们现在就这样做。启用 --strictNullChecks
后,the void
opterator produces a value of the undefined
type. But with --strictNullChecks
disabled, there isn't really a distinct undefined
type, and the void
operator produces a value of the any
type. And unless you explicitly annotate 类型为 any
,您将在 --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
如您所见,如果 void
运算符的 return 类型被赋予 contextual type:
function foo(cb: () => any) { }
foo(() => void 0); // okay, void 0 is contextually typed as any
注意 Function
接口有点奇怪,没有真正的 call signature, see microsoft/TypeScript#20007,所以它不能提供上下文类型:
function bar(cb: Function) { }
bar(() => void 0); // implicit any error!