網站搜尋

從介面轉換為遞迴型別時,Typescript 會拋出「索引簽名在型別中遺失」的錯誤


實例演示

我已經定義了一個遞歸的 SerializableRecord 介面,該介面是透過遞歸型別參考定義的。這個介面可以被更改。

type Serializable =
  | string
  | number
  | boolean
  | null
  | undefined
  | SerializableArray
  | SerializableRecord;

interface SerializableArray extends Array<Serializable> {}
interface SerializableRecord extends Record<string, Serializable> {}

我有另一個 匯入的 介面(這表示我無法更改它):

interface ExternalInterface {
   attr: string;
}

現在如果我嘗試做以下操作,我會收到一個錯誤:

const x: ExternalInterface = {attr: 'a'};
const y: SerializableRecord = x;
// Throws a TS error: "Index signature is missing in type 'ExternalInterface'"
   

有沒有辦法讓這兩個實體兼容,而不引入 any 或 unknown?

答案#1

根據這個 GitHub 問題,這種行為目前是設計如此。

我所知道的最佳解決方法是將介面「轉換」為一種類型:

type AsType<T> = { [P in keyof T]: T[P]; }

const x: ExternalInterface = {attr: 'a'};
const y: SerializableRecord = x as AsType<typeof x>;

另一個是使用物件展開語法,

const y: SerializableRecord = { ...x };

但那需要複製物件,而你可能不想這麼做。

答案#2

這應該可行,但不符合你不更改 ExternalInterface 的要求

type ExternalInterface = { attr: string };
const x: ExternalInterface = { attr: 'a' };
const y: SerializableRecord = x;