I am working on a typescript project and struggle a bit with defining a fitting type. Context:
I got the following constant inside my project:
export const PROPERTYOPTIONS = [
{ value: "tag", label: "Tag" },
{ value: "composition", label: "Composition" },
{ value: "solvent", label: "Solvent" },
{ value: "allergen", label: "Allergen" },
{ value: "category", label: "Category" },
{ value: "other", label: "Other" },
];
Now I want to define an interface:
interface CreatePropertyModalState {
type: { value: string; label: string };
}
How can I define that the type of the type field is a member of PROPERTYOPTIONS?
I want to dodge a type definition like:
type: { value: "tag" | "composition" | .....
CodePudding user response:
If you're not planning to change the contents of PROPERTYOPTIONS
at runtime, you can mark it as immutable (as const
) and define a type alias for it using typeof
:
export const PROPERTYOPTIONS = [
{ value: 'tag', label: 'Tag' },
{ value: 'composition', label: 'Composition' },
{ value: 'solvent', label: 'Solvent' },
{ value: 'allergen', label: 'Allergen' },
{ value: 'category', label: 'Category' },
{ value: 'other', label: 'Other' },
] as const
type PropertyOptions = typeof PROPERTYOPTIONS
type PropertyOption = PropertyOption[number]
interface CreatePropertyModalState {
// if the type should be exactly one of the options
type: PropertyOption,
// if you want to combine an allowed value with an arbitrary label
type: { value: PropertyOption['value'], label: string },
}
CodePudding user response:
You can use a generic identity function to constrain the type of the array, and then typeof
with an indexed access type to extract the type you want.
function checkArray<T extends string>(arr: {value: T, label: string}[]) {
return arr;
}
export const PROPERTY_OPTIONS = checkArray([
{ value: "tag", label: "Tag" },
{ value: "composition", label: "Composition" },
{ value: "solvent", label: "Solvent" },
{ value: "allergen", label: "Allergen" },
{ value: "category", label: "Category" },
{ value: "other", label: "Other" },
]);
type PropertyOption = typeof PROPERTY_OPTIONS[number]
// type PropertyOption = {
// value: "tag" | "composition" | "solvent" | "allergen" | "category" | "other";
// label: string;
// }
interface CreatePropertyModalState {
type: PropertyOption
}