網站搜尋

typescript - 如何禁止一個介面的鍵出現在另一個介面中


基本上,我想要達到的目標是防止現有對象的某些屬性被作為參數傳遞給介面。我相信這可以透過某種條件類型的組合來實現,但我很難找出正確的組合方式。

export interface Dictionary<T> {
  [index: string]: T;
}

type StandardContext = {
    myKeyOne?: string;
    myKeyTwo?: number;
}

type NonStandardContext = Exclude<Dictionary<any>, StandardContext>

const standard: StandardContext = {
    myKeyOne: '2', // ok!
}

const nonStandardError: NonStandardContext = {
    myKeyOne: '2' // should error (good so far)
}

const nonStandardGood: NonStandardContext = {
    foo: '2' // should not error, but it does!
}

遊樂場連結

答案#1

將 Dictionary<any> 與 {[P in keyof StandardContext]?: never} 聯合起來即可:

type NonStandardContext = Dictionary<any> & { [P in keyof StandardContext]?: never };

在操場上

在你的範例 StandardContext 裡,第二部分的那個 ? 其實不需要,但那只是因為你的範例 StandardContext 沒有任何必填屬性。如果它有一些必填屬性,沒有 ? 的話,上面的類型將無法滿足,因為這將要求你擁有一個類型為 never 的屬性!:-)(範例)

(感謝 kaya3 指出需要 ?!)

我必須承認並不完全明白為什麼Exclude<Dictionary<any>, StandardContext>不起作用。:-) 但我認為Exclude只適用於不使用索引簽名的類型。我可能對原因理解錯了。 我懷疑是從閱讀這個回答得出的結論,它說Exclude大致上如下(只是僅適用於字符串鍵,而不是字符串和數字鍵):

type Diff<T extends string, U extends string> = ({[P in T]: P } & {[P in U]: never } & { [x: string]: never })[T]
// −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−^^^^^^^^^^^^^^^^^^^^^^^^

注意最後一部分,不包括索引鍵。