Reputation: 121
i got a working typescript code, see the snippet. Problem with TS is, that it states the code as falsy with the message:
Argument of type 'string' is not assignable to parameter of type 'SetStateAction<"vertical" | "horizontal" | "vertical-reverse" | "horizontal-reverse">'.
How can i write this code cleaner? I thought about using types or enums but then i get to many unecessary casts which then decrease readability and it turns into spaghetti code since i write way to much code for that.
Here the Code:
const directionItems = [
{ key: 0, label: "vertical" },
{ key: 1, label: "horizontal" },
{ key: 2, label: "vertical-reverse" },
{ key: 3, label: "horizontal-reverse" }
];
const [curDirection, setCurDirection] = React.useState<
"vertical" | "horizontal" | "vertical-reverse" | "horizontal-reverse"
>("vertical");
<DropDown
items={directionItems}
defaultSelectedIndex={3}
onSelectionChange={value =>
setCurDirection(directionItems[value].label) // <-- this is where the compiler gets angry even if it just works
}></DropDown>
Also here the approach using enum, but in my opinion way to much code or is this legit? (no errors from compiler with this approach):
enum position {
"top",
"bottom",
"left",
"right",
"in-between"
}
const buttonPositionItems = [
{ key: 0, label: position[0] },
{ key: 1, label: position[1] },
{ key: 2, label: position[2] },
{ key: 3, label: position[3] },
{ key: 4, label: position[4] }
];
const [curButtonPosition, setButtonPosition] = React.useState<position>(
position.right
);
<DropDown
items={buttonPositionItems}
defaultSelectedIndex={3}
onSelectionChange={value =>
setButtonPosition(
(buttonPositionItems[value].label as unknown) as position)
}
></DropDown>
My Solution now (i didnt use the interface though..)
export type DirectionType = | "vertical" | "horizontal" | "vertical-reverse" | "horizontal-reverse";
const directionItems = [
{ key: 0, label: "vertical" },
{ key: 1, label: "horizontal" },
{ key: 2, label: "vertical-reverse" },
{ key: 3, label: "horizontal-reverse" }
];
const [curDirection, setCurDirection] = React.useState<DirectionType>(
"vertical"
);
<DropDown
onSelectionChange={value =>
setCurDirection(directionItems[value].label as DirectionType )
}>/<DropDown>
Upvotes: 1
Views: 744
Reputation: 42536
You might want to work with interfaces to provide explicit typings, such that TypeScript will recognise that label
is of type "vertical" | "horizontal" | "vertical-reverse" | "horizontal-reverse"
. For instance, you could make use of type aliases.
export type LabelType = ("vertical" | "horizontal" | "vertical-reverse" | "horizontal-reverse");
export interface DirectionItem {
key: number;
label: LabelType;
}
Now, we can use the interfaces with your React Functional Component.
const directionItems: DirectionItem[] = [
{ key: 0, label: "vertical" },
{ key: 1, label: "horizontal" },
{ key: 2, label: "vertical-reverse" },
{ key: 3, label: "horizontal-reverse" }
];
const [curDirection, setCurDirection] = React.useState<LabelType>("vertical");
Upvotes: 1