網站搜尋

typescript2.0 - 在 TypeScript 類型中,有可能同時擁有混合的特定類型鍵和通用鍵類型嗎?


我正在嘗試創建一種類型來描述一個 ES6 Proxy 對象,其中我會知道幾個鍵的類型,其餘的鍵將是通用的,值是一個回調函數,而且我在運行時才會知道它們的名稱。

然而,如果我嘗試這樣的方式:

interface MyCallback {
  (): void;
}

interface MyType {
    myKey1: number;
    [key: string]: MyCallBack;
}

我收到類似以下的錯誤:

[ts] Property 'myKey1' of type 'number' is not assignable to string index type 'MyCallback'.

如果我添加 [key: string]: number,我會得到錯誤 Duplicate string index signature。

如果我對它進行重載,使其類似於 number | MyCallback,那麼如果我嘗試對 MyType 實例調用回調,會出現這個錯誤:

[ts] Cannot invoke an expression whose type lacks a call signature. Type 'number | MyCallback' has no compatible call signatures.

在 TypeScript 中有可能創建我正在嘗試創建的類型嗎?

答案#1

被接受的答案對我不起作用,這段程式碼有效:Playground 連結

interface MyType {
    myKey1: number;
}

interface GenericCallbackType {
    [key: string]: () => void;
}

type CombinedType = MyType | GenericCallbackType;

const obj: CombinedType = {
    myKey1: 8,
    anyString: () => {}
}

答案#2

如評論中所指出的,已接受的答案在賦值操作中無法使用,會導致 Property 'myKey1' is incompatible with index signature 錯誤。要在賦值操作中使用,我們可以利用 @jcalz 在這裡的答案:

interface MyCallback {
  (): void
}

interface MyType {
  myKey1: number
}

const asCombinedType = <C>(
  res: C & MyType & Record<Exclude<keyof C, keyof MyType>, MyCallback>
): C => res

const obj = asCombinedType({
  anyKey: () => { /* ...*/ },
  myKey1: 12
})

不可否認有點複雜,但它能完成工作。