我在 TypeScript 上遇到了一個奇怪的問題。我最近了解了void ...operator 因為我需要應用它所以eslint不會報告no-floating-promises。然而,這個特定的片段不知何故導致了一個我無法在 TypeScript 操場上重現的問題:
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:缺少回傳型別注釋的函式運算式隱式具有“任何”回傳型別。
但是,該問題在
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));
}
}
uj5u.com熱心網友回復:
有關權威答案,請參閱microsoft/TypeScript#36651。
你的問題是,你已經啟用了--noImplicitAny編譯器選項,但你有沒有啟用的--strictNullChecks編譯器選項。您可以在 TypeScript Playground 中設定這些選項并重現您的問題。
旁白:請注意,--strictNullChecks是一部分的--strict家庭的編譯器功能,這是一般建議為型別安全的一個事實上的“標準”級別的一部分。您并沒有真正詢問您應該使用哪些編譯器選項,但請注意,如果您使用一組不常見的編譯器選項,您更有可能遇到一般 TypeScript 社區不為人知的編譯器行為。好了,差不多了。
所以我們知道如何重現,但還沒有明確回答這里為什么會出錯。現在讓我們這樣做。與--strictNullChecks啟用,所述voidopterator產生的值的undefined型別。但隨著--strictNullChecks 殘疾人,沒有一個真正的不同undefined型別和void運算子產生的值的any型別。除非你明確地注釋一個型別是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運算子的回傳型別被賦予背景關系型別,您也可以擺脫錯誤:
function foo(cb: () => any) { }
foo(() => void 0); // okay, void 0 is contextually typed as any
請注意,該Function介面有點奇怪,并且沒有真正的呼叫簽名,請參閱microsoft/TypeScript#20007,因此它無法提供背景關系型別:
function bar(cb: Function) { }
bar(() => void 0); // implicit any error!
Playground 代碼鏈接
uj5u.com熱心網友回復:
我可以重現您的問題,盡管我無法回答為什么會發生這種情況,但您可以通過省略voidoperator并將catch方法鏈接到滿足 ESLint 的承諾來修復編譯器錯誤:
// before
window.setTimeout(() => void this.onTickAsync(true), 200);
// after
window.setTimeout(() => this.onTickAsync(true).catch(() => {}), 200);
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/409636.html
標籤:
上一篇:如何為R包中的函式引數設定別名?
