¿Cómo construir un tipo de Typescript a partir de un arreglo de cadenas?
Hasta ahora tengo esto.
export const PacerThemes = ['Default', 'Dark Muted', 'Neon'] as const;
export type PacerTheme = typeof PacerThemes[number];
type ThemeProperties = {
exhaleHoldBorderColor: string;
exhaleHoldColor: string;
inhaleHoldBorderColor: string;
inhaleHoldColor: string;
};
type Themes = {
Default: ThemeProperties;
'Dark Muted': ThemeProperties;
Neon: ThemeProperties;
};
¿Hay una manera de generar el tipo Themes a partir del arreglo PacerThemes?
Respuesta #1
Podrías usar un tipo mapeado, como se sugiere en los comentarios.
type ThemeNames = "Default" | "Dark Muted" | "Neon";
type ThemeProperties = {
exhaleHoldBorderColor: string;
exhaleHoldColor: string;
inhaleHoldBorderColor: string;
inhaleHoldColor: string;
};
type Themes = {
[T in ThemeNames]: ThemeProperties;
};
O podrías usar un tipo de utilidad Record
type ThemeNames = "Default" | "Dark Muted" | "Neon";
type ThemeProperties = {
exhaleHoldBorderColor: string;
exhaleHoldColor: string;
inhaleHoldBorderColor: string;
inhaleHoldColor: string;
}
type Themes = Record<ThemeNames, ThemeProperties>
Campo de Juegos TS
Respuesta #2
Aquí hay una solución (enlace a Playground):
const PacerThemes = ['Default', 'Dark Muted', 'Neon'] as const
type ThemePropertiesVersion = {
[k in (typeof PacerThemes)[keyof typeof PacerThemes & number]]: "YourType"
}
Si quieres hacer esto más genérico introduciendo algunos tipos auxiliares reutilizables, podrías encontrarte con el problema de que readonly any[] no se extiende a any[].
Por ejemplo, esto no funcionaría, ya que typeof PacerThemes es readonly:
type Items<A extends any[]> = A[keyof A & number]
Para manejar esto podrías hacer algo como esto (enlace de Playground):
const PacerThemes = ['Default', 'Dark Muted', 'Neon'] as const
// Version 1 -- allow only readonly arrays
type ReadonlyItems<P extends readonly any[]> = P[keyof P & number]
type TestVersion1 = NonRestrictiveItems<typeof PacerThemes>
type ThemePropertiesVersion1 = {
[k in ReadonlyItems<typeof PacerThemes>]: "YourType"
}
// Version 2 -- allow both
type NonRestrictiveItems<P extends (readonly any[]) | any[]> = P[keyof P & number]
type TestVersion2 = NonRestrictiveItems<typeof PacerThemes>
type ThemePropertiesVersion2 = {
[k in NonRestrictiveItems<typeof PacerThemes>]: "YourType"
}
