在決議 JSON 時,我錯了還是 TypeScript 中的型別安全被丟棄了?
我應該在這里得到一個錯誤,但我沒有:
interface Person {
name: string
}
const person: Person = somePossibleFalsey ? JSON.parse(db.person) : undefined
當我認為應該時,上述內容不會通過型別檢查。該db.person變數可以不存在,這可能呈現person為undefined。但Person不應該undefined。據我所知,這是因為我正在使用JSON.parse.
只是為了確認我應該得到一個錯誤,這里是另一個片段,它正確地給了我一個錯誤:
const person: Person = Math.random() > .5 ? { name: 'Arthur' } : undefined
上面的代碼會產生相應的 TypsScript 錯誤:
Type '{ name: string; } | undefined' is not assignable to type 'Person'.
Type 'undefined' is not assignable to type 'Person'.ts(2322)
為什么JSON.parse允許型別安全失敗?或者這里還有其他東西在起作用嗎?
uj5u.com熱心網友回復:
JSON.parse回傳一個any. 并且由于any包含任何型別(包括未定義),any | undefined因此與any.
使用as鍵入JSON.parse結果,您將獲得預期的輸出:
const person: Person = db.person ? JSON.parse(db.person) as Person : undefined;
// Error: Type 'Person | undefined' is not assignable to type 'Person'. Type 'undefined' is not assignable to type 'Person'
編輯:您似乎不清楚any型別。這基本上關閉了所有型別安全。每個型別都可以分配給any并且any可以分配給每個型別。當你做
const myAnyFunc = (): any => {return undefined;};
const myPerson: Person = myAnyFunc();
這不會創建 TypeError。沒什么特別的JSON.parse(),只是任何回傳的“問題” any。看看這本優秀的 TS 書,了解更多關于any.
uj5u.com熱心網友回復:
我認為問題的核心是為什么undefined允許三元運算式的第二項, 是分配給 的替代項之一Person。這個 Github 問題將其描述為按預期作業。整個三元運算式獲得第一個回傳型別和第二個回傳型別的并集,即any | undefined,折疊為any,這反過來又使其成為有效的賦值。(any是所有型別中最弱的型別)。相反,如果將其包裝在 if-else 塊中,則會出現錯誤:
let n: number;
let x: any = {}
n = x.z ? x.z : undefined // no error
let y: any = {}
if (y.z) {
n = y.z
} else {
n = undefined // error
}
(來源)
我認為這里的不一致在于,在第一種情況下,整個三元運算式被推斷為 any | undefined 可折疊為任意;因此,編譯器會看到一個回傳 any 并且一切正常(即使它不是)。在第二種情況下,有兩個回傳站點:一個是 return any ,這再次很好,一個是 return undefined ,這不是。
我認為挑戰在于三元實際上不是一個陳述句,而是一個運算式。運算式必須具有單一型別;在這種情況下,該型別恰好是 any | undefined 僅憑 any 的性質就顯得不合理。我懷疑改變這一點會非常困難:當你在陳述句中間有一個三元時會發生什么,例如作為函式的引數?當同一陳述句中有多個三元組時會發生什么 [...]
為了按照您建議的方式對上述內容進行型別檢查,編譯器基本上必須復制該陳述句,并對陳述句中的每個三元組的真/假的每個組合進行單獨的型別檢查。你會有一個組合爆炸。
我懷疑,目前的行為是我們將要得到的最好的結果。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/334135.html
標籤:javascript json 打字稿 类型安全
