[英]Make a String Literal Types from an Array in TypeScript
我的定義文件中有這個 object
export const properties = {
name: '',
level: ['a', 'b', 'c'],
uri: '',
active: true
}
(注意:它不是一個接口它實際上是一個真正的 object,我需要一個 object 的原因是因為我需要它作為運行時的參考)
現在我嘗試用這個 object 制作一個類型,所以這就是我需要的
export type Properties = {
name: string;
level: 'a'|'b'|'c';
uri: string;
active: boolean
}
我嘗試使用
export type Properties = typeof properties
但是level
被翻譯為string[]
這是正常的,但是我如何使用 TypeScript 到 map ['a', 'b', 'c']
到'a'|'b'|'c'
? 如果可能的話,在將一種類型映射到另一種類型的過程中,我該如何做到這一點?
謝謝
如果您完全按照上面所做的那樣定義properties
,那么它將不起作用。 當您開始編寫type Properties =
時,編譯器已經將level
屬性擴展為string[]
,並且忘記了所有關於其元素的字符串文字類型,正如您所見。
為了甚至有機會得到"a" | "b" | "c"
"a" | "b" | "c"
"a" | "b" | "c"
out of properties
,因此,您將需要更改properties
的定義。 最簡單的方法是使用const
斷言向編譯器提示您想要它可以推斷的最窄類型。 例如:
const properties = {
name: '',
level: ['a', 'b', 'c'] as const,
uri: '',
active: true
}
我們將level
聲明為const
,現在typeof properties
如下所示:
/* const properties: {
name: string;
level: readonly ["a", "b", "c"];
uri: string;
active: boolean;
} */
那么,我們如何轉換它以獲得Properties
呢? 假設問題“在將一種類型映射到另一種類型的過程中如何做到這一點?” 意味着您希望將每個類似數組的東西都轉換為其元素類型,並假設您只需要執行此一級深度(而不是遞歸),那么您可以定義此類型 function:
type Transform<T> = { [K in keyof T]:
T[K] extends readonly any[] ? T[K][number] : T[K]
}
這是一個映射類型,我們采用輸入類型T
,並且對於每個屬性鍵K
,我們對其進行索引以獲取其屬性類型( T[K]
)。 如果該屬性類型不是數組( readonly any[]
實際上比any[]
更通用),我們不理會它。 如果它是一個數組,那么我們通過使用number
對其進行索引來獲取它的元素類型(如果你有一個數組arr
和一個數字n
,那么arr[n]
將是一個元素)。
對於typeof properties
,這會導致:
type Properties = Transform<typeof properties>
/* type Properties = {
name: string;
level: "a" | "b" | "c";
uri: string;
active: boolean;
} */
如預期的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.