簡體   English   中英

從 TypeScript 中的數組創建字符串文字類型

[英]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;
} */

如預期的。

Playground 代碼鏈接

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM