我的應用程式收到“訊息”。我首先驗證未知輸入以確保它遵循預期的訊息格式:
const isMessage = x =>
typeof x === 'object' &&
x !== null &&
typeof x['data'] === 'string';
我希望在 TypeScript 中輸入它。這是我所擁有的:
type Message = { data: string };
const isMessage = (x: unknown): x is Message =>
typeof x === 'object' &&
x !== null &&
typeof x['data'] === 'string';
但是,這無法進行型別檢查,因為:
Element implicitly has an 'any' type because expression of type '"data"' can't be used to index type '{}'.
Property 'data' does not exist on type '{}'.
在型別保護之后typeof x === 'object' && x !== null,TypeScript 給出了型別x : object。這似乎與x : {}. 但是這種型別不允許我檢查物件的任何屬性。
而不是x: object,我想我想要一個像x: { [key: string | number | symbol]: unknown }. 但這不是 TypeScript 從 type guard 中給我的型別typeof x === 'object'。
我可以使用as強制x轉換為字典型別:
const isMessage = (x: unknown): x is Message =>
typeof x === 'object' &&
x !== null &&
typeof (x as { [key: string | number | symbol]: unknown })['data'] === 'string';
這種型別檢查,但它真的很長而且笨拙,而且我不確定as型別轉換是否真的是型別安全的。
我閱讀了有關in運算子縮小的內容,并基于此,我預計添加'data' in x會起作用:
const isMessage = (x: unknown): x is Message =>
typeof x === 'object' &&
x !== null &&
'data' in x &&
typeof x['data'] === 'string';
然而,這沒有區別;TypeScript 仍然抱怨我無法索引到x,即使在'data' in x. 為什么這個in運算子不允許我索引到x?
uj5u.com熱心網友回復:
你應該可以這樣做:
type Message = { data: string };
const isMessage = (x: unknown): x is Message =>
typeof x === 'object' &&
x !== null &&
typeof (x as Message).data === 'string';
這種技術顯示在 TypeScript 的檔案中:https : //www.typescriptlang.org/docs/handbook/2/narrowing.html#using-type-predicates
由于typeof也是運行時檢查,因此as斷言不會消除任何型別安全性。
你可以這樣想:在最后一行之前,我們已經檢查過 thatx是一個物件而不是null。因此,x.data不能在運行時失敗,即使x是{}or{bar: 'bar'}或{data: null}。我們只需要使用斷言讓編譯器允許我們進行運行時typeof檢查。
uj5u.com熱心網友回復:
您可以使用通用hasProperty助手進行屬性檢查:
type Message = { data: string };
const hasProperty = <Obj, Prop extends string>(obj: Obj, prop: Prop)
: obj is Obj & Record<Prop, unknown> =>
Object.prototype.hasOwnProperty.call(obj, prop);
const isMessage = (x: unknown): x is Message =>
typeof x === 'object' &&
x !== null &&
hasProperty(x, 'data') &&
typeof x['data'] === 'string'
操場
請在此處查看我的回答以獲取有關in操作員和此問題的更多背景資訊/43284
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/330858.html
標籤:打字稿
