從介面轉換為遞迴型別時,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;
