2017-07-27 65 views

回答

7

用戶定義的鍵盤鎖只能返回一個x is T。幸運的是,你可以在你選擇的T中使用聯合和交叉點。因此,例如:

function everythingIsDefined(o: Maybe<Obj>): o is Obj & {jbo: Jbo} { 
    return typeof o !== 'undefined' && typeof o.jbo !== 'undefined'; 
} 

everythingIsDefined功能斷言輸入是一個Obj(相對於未定義),一個對象,其jbo屬性是一個Jbo(相對於未定義)。所以,你可以使用它像這樣:

if (everythingIsDefined(obj)) { 
    console.log(obj.jbo.toString()) // no error 
} 
+1

很好的交點 –

+0

這真棒,謝謝! – gen

0

呀,你可以拉其關閉:

type Maybe<T> = T | undefined; 
type DeepMaybe<T> = { [K in keyof T]: Maybe<T[K]> }; 

class Obj { 
    jbo: Jbo; 
} 

function everythingIsDefined<T>(o: DeepMaybe<T>): o is T { 
    return false; 
} 

然後:

let obj: DeepMaybe<Obj> = {} as Obj; 
if (everythingIsDefined(obj)) { 
    // type of obj.jbo is Jbo 
} else { 
    // type of obj.jbo is Maybe<Jbo> 
} 

code in playground

說明:
根據您提供的類型(即Obj.jbo: Maybe<Jbo>),可能沒有辦法實現這一點。
相反,類Obj需要將其屬性定義爲實際類型,但如果您將變量鍵入爲DeepMaybe<Obj>(或其他任何內容而不是Obj),那麼您會得到同樣的結果。

現在的區別是,因爲DeepMaybe是一種映射類型,您可以更好地控制如何創建類型警衛。

+0

你從'也許'改變Obj.jbo'的'類型'Jbo'。爲什麼? – jcalz

+0

@jcalz我編輯了我的答案。這是否解釋了它? –

+0

是的,我明白你現在說的話。這是一個處理更普遍情況的簡便方式,但我認爲OP的問題可以更直接地回答。 – jcalz

相關問題