我有兩個描述幾乎相同事物的型別定義:
// compilation fails with `Type alias 'StringOrRecordOfStrings' circularly references itself.ts(2456)`
type StringOrRecordOfStrings = string | string[] | Record<string, StringOrRecordOfStrings>;
// compiles without problems
type StringOrRecordOfStrings = string | string[] | { [property: string]: StringOrRecordOfStrings };
有誰能夠解釋為什么第一個型別定義不能編譯?
- 遞回型別別名已在 3.7 版中引入https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html#more-recursive-type-aliases
- 這個 SO 答案解釋了如何在 TypeScript 中使用遞回型別別名 Recursive Types
- 為簡潔起見,我從記錄中省略了其余的鍵型別,但即使我們設定了
[property: string | number | symbol].
uj5u.com熱心網友回復:
Record<string, StringOrRecordOfStrings>不允許的原因Record是泛型型別,而不是類或介面。
沒有很多明確的檔案,但是物件、索引簽名和映射型別中的屬性的遞回型別參考已經存在了很長一段時間。以下內容早在 TypeScript 3.3 中就可以使用:
type Recursive = {p: Recursive} | {[p: string]: Recursive} | {[Key in 'a']: Recursive}
TypeScript 3.3 游樂場
這就是您的第二個示例型別(帶有索引簽名)檢查的原因。
TypeScript 3.7 擴展了對遞回參考的支持,如本PR中所述:
- 泛型類和介面型別的實體化(例如
Array<Foo>)。 - 陣列型別(例如
Foo[])。 - 元組型別(例如
[string, Foo?])。
所以現在,這三個例子也是有效的:
type RecursiveCI = Promise<RecursiveCI>
type RecursiveT = [number, boolean, RecursiveT]
type RecursiveA = RecursiveA[]
我假設該示例只是測驗代碼,但您可以使用這樣的輔助介面對其進行型別檢查:
type StringOrRecordOfStrings = string | string[] | Record<string, RecordInterface>
interface RecordInterface extends Record<string, StringOrRecordOfStrings> {}
TypeScript 游樂場
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/460211.html
