未考慮到陣列元素可能傳回undefined的情況的Typescript程式碼
P粉824889650
2023-08-24 12:15:44
<p>以下程式碼在Typescript類型檢查器(v2.9.1)中通過,但在執行時拋出<code>TypeError</code>。 </p>
<pre class="brush:php;toolbar:false;">interface Item { id: string }
const list: Item[] = [{ id: 'a' }, { id: 'b' }];
const item = list[3]; // 類型: Item
const itemId = item.id; // 型別: string</pre>
<p>考慮到訪問類型化數組中的元素可能始終返回<code>undefined</code>,<code>item</code>應該是<code>item: Item | undefined</code> ,這將強制你進行空值檢查,難道不應該嗎? </p>
<p>更令我驚訝的是,以下程式碼也透過型別檢查:</p>
<pre class="brush:php;toolbar:false;">const item2: Item | undefined = list[3];
const item2Id = item2.id;</pre>
<p>儘管將回傳值強制轉換確實會導致類型檢查失敗:</p>
<pre class="brush:php;toolbar:false;">const item3 = list[3] as Item | undefined;
const item3Id = item3.id; // [ts] Object is possibly 'undefined'.</pre>
<p>創建一個明確類型的訪問器函數也可以捕獲到<code>undefined</code>的情況,但會增加不必要的開銷:</p>
<pre class="brush:php;toolbar:false;">const getItem1 = (index: number, items: Item[]): Item | undefined => items[index];
const item3 = getItem1(3, list);
const item3Id = item3 && item3.id;</pre>
<p>這是Typescript的已知限制嗎?有沒有推薦的模式或函式庫來處理這種情況? </p>
這是有意的行為。 在TypeScript GitHub儲存庫上查看此問題的長時間討論
#你的
strictNullChecks
關閉了;試著打開它。TS 4.1更新:
TypeScript 4.1引入了一個
--noUncheckedIndexedAccess
編譯器標誌,實現了在microsoft/TypeScript#13778中提出的建議,以考慮這種情況下的undefined
。請注意,該功能不會作為--strict
編譯選項集的一部分啟用,並且被稱為“嚴格的索引簽名”,因為它會在程式設計師可能不希望或期望的情況下發出關於undefined
的警告。TS4.1之前的回答:
您已經發現索引簽名不會像可選屬性那樣將
| undefined
新增到元素類型中。在microsoft/TypeScript#13778上提出了建立一個編譯器選項來實現這一點的建議。您可以閱讀該建議中的評論;它們連結到其他問題,但共識是高錯誤率幾乎使其無用。也提到您可以手動將
| undefined
新增至元素類型:這將按您的預期工作,而不會影響整個語言。