Typescript — Как я могу динамически определять тип из массива возможных значений?

#typescript #typescript-generics

#typescript #typescript-generics

Вопрос:

Я хотел бы найти способ динамического определения типа из массива возможностей.

У меня есть карта, как показано ниже, где ключи — это имена типов, а соответствующие значения — это массивы того, каким может быть этот тип.

 export const typeOptions = {
  areaOfStudy: ["politics", "mathematics", "biology"],
  ageRange: ["1821", "2225", "26plus"],
  societyCategory: [
    "Debate Society",
    "Basketball Society",
    "Football Society",
    "3D Modelling Society",
  ],
}
  

Я хотел бы найти способ вывести из объекта выше следующее:

 export type AreaOfStudy = "politics" | "mathematics" | "biology";
export type AgeRange = "1821" | "2225" | "26plus";
export type SocietyCategory =
  | "Debate Society"
  | "Basketball Society"
  | "Football Society"
  | "3D Modelling Society"
  

Любые идеи или советы о том, как я мог бы это сделать?

Ответ №1:

Вы можете использовать typeof в сочетании с as const

typeof дает вам тип значения. as const говорит, что он должен использовать точные значения.

 export const typeOptions = {
  areaOfStudy: ["politics", "mathematics", "biology"] as const,
  ageRange: ["1821", "2225", "26plus"] as const,
  societyCategory: [
    "Debate Society",
    "Basketball Society",
    "Football Society",
    "3D Modelling Society",
  ] as const,
}

export type AreaOfStudy = typeof typeOptions.areaOfStudy[number]
export type AgeRange = typeof typeOptions.ageRange[number]
export type SocietyCategory = typeof typeOptions.societyCategory[number]
  

Комментарии:

1. Но это не сработает, если массив создается динамически (например, пользователем), поскольку Typescript не имеет возможности это проверить. Для этого значения массива должны быть известны во время компиляции

2. Я получаю: строка типа не может быть присвоена типу ‘только для чтения [….]’, если я попытаюсь инициализировать переменную

3. Мой плохой. Я исправил это, добавив [number] после определения типа (который может быть определенным индексом или числом для всех).

4. Это здорово, большое вам спасибо!! Что делают «как const» и «[number]»?

5. Я использовал утверждения const для использования точных значений ( politics, math, ... ) вместо string[] и [number] для выбора элементов вместо всего массива. Для последнего я не нашел документации, но я думаю, что это в основном то же самое, arr[0] что возвращает тип первого элемента, но вместо этого объединяет все элементы. Возможно, откройте новый вопрос, если этого ответа вам недостаточно 🙂