I am facing an issue with a component that requires a `labels` attribute.
<Component
defaultValue={FURNITURE.BED}
labels={[
{
value: FURNITURE.BED,
text: 'Bed',
},
{
value: FURNITURE.COUCH,
text: 'Couch',
},
{
value: FURNITURE.CHAIR,
text: 'Chair',
},
]}
onSubmit={onSubmit}
...otherAttributes
/>
Here is the enum and type declaration:
export enum FURNITURE {
BED = 'bed',
COUCH = 'couch',
CHAIR = 'chair'
}
type FurnitureOptions = `${FURNITURE}` // FURNITURE.BED | FURNITURE.COUCH | FURNITURE.CHAIR
const onSubmit = (value: FurnitureOptions} => processFurniture(value)
The issue lies in the fact that the value
prop within my Component
is set as a string. I would like the Component
to infer the type automatically based on the values within the labels, such as FurnitureOptions
.
This is how my component is structured:
interface ILabel {
readonly label: string;
readonly value: string | number;
}
interface IComponentProps {
readonly labels: ILabel[];
readonly defaultValue: string | number | null;
readonly onSubmit: (value: ILabel) => void;
...otherAttributes
const Component = ({
labels, default, onSubmit, ...otherAttributes
}: IComponentProps => { ...function code }
My desired outcome is to replace string | number
with any type parameter, like FurnitureOptions
.
I have attempted using a type parameter T
, calling the component with
<Component<FurnitureOptions> ... />
, but this solution feels messy and goes against coding standards. I am looking for a way to achieve this inference automatically.
One approach I have tried involves extracting possible values like so:
type PossibleValues = Extract<typeof labels[number], { readonly [v in 'value']: unknown }>['value'] // FURNITURE.BED | FURNITURE.COUCH | FURNITURE.CHAIR
Unfortunately, I cannot pass this into the Component
parameters without encountering a circular error.
'labels' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer. ts(7022)
Are there any other techniques available for me to accomplish this?