我有一些代碼,其中有幾個函式需要對物件進行空檢查,然后對其進行處理,或者如果為空則拋出錯誤,如下所示:
interface SomeObject {
doThingOne: () => string;
doThingTwo: () => string;
}
let object: SomeObject | null;
function doThingOne() {
if(!object) {
throw new Error('Object is null!');
}
// Typescript knows that object is not null, so it's fine with accessing its properties/methods
return object.doThingOne();
}
function doThingTwo() {
if(!object) {
throw new Error('Object is null!');
}
return object.doThingTwo();
}
我想將空檢查提取到一個函式中以減少重復代碼,如下所示:
interface SomeObject {
doThingOne: () => string;
doThingTwo: () => string;
}
let object: SomeObject | null;
function requireObject() {
if(!object) {
throw new Error('Object is null!');
}
}
function doThingOne() {
requireObject();
// Typescript no longer knows that object is defined, so it gets mad at the next line
return object.doThingOne();
}
function doThingTwo() {
requireObject();
return object.doThingTwo();
}
但是,當我這樣做時,打字稿不再意識到檢查后object肯定存在。有沒有干凈的方法來做到這一點?
這個問題看起來很相似,但實際上不會讓我節省很多代碼重復,因為我仍然需要設定一個if
uj5u.com熱心網友回復:
沒有辦法撰寫requireObject()并影響 的型別object,因為編譯器requireObject()認為與沒有object任何關系。(如果編譯器可以管理由于函式內部封閉變數的變異而導致的所有可能的狀態更改,那會很好,但它在計算上不可行。有關一般問題,請參閱microsoft/TypeScript#9998。)
你可以做的是通object入requireObject()和注釋這requireObject()是一個斷言功能。斷言函式必須實作為void-returning(因此它們不回傳任何內容),并且帶注釋的回傳型別是形式的“斷言謂詞” asserts x is Y(其中x是函式引數之一的名稱)或者只是asserts x如果您想要說的x是實話。
所以這給了我們:
function requireObject(x: any): asserts x {
if (!x) {
throw new Error('something is falsy here');
}
}
現在我們可以毫無錯誤地做到這一點:
let object: SomeObject | null;
function doThingOne() {
requireObject(object);
return object.doThingOne(); // okay
}
function doThingTwo() {
requireObject(object);
return object.doThingTwo(); // okay
}
Playground 鏈接到代碼
uj5u.com熱心網友回復:
您可以使用!運算子告訴編譯器object肯定會包含一個值。
return object!.doThingOne();
我盡量避免這種事情。以后很容易惹上麻煩。相反,我會將requireObject函式定義為始終回傳一個物件。
function requireObject(): object {
if (!object) {
throw new Error('Object is null!');
}
return object;
}
然后你可以這樣稱呼它:
object = requireObject();
由于requireObject總是回傳一個object型別,編譯器會知道此時object不是null。
現在唯一的問題是,因為object實際上是一個TypeScript型別,代碼有點混亂。它應該可以作業(我還沒有真正嘗試過),但是您可能需要考慮將變數命名為其他名稱。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/382665.html
