Some context: I would like to build a Dropdown svelte component that accepts multiple kind of possible items
<MySelect options={...}
Possibility 1: Simplest: Raw string value. The "text" of the dropdown item is the same as the valueoptions=["Item 1", "Item 2", "Item 3"]
Possibility 2: Customizable text vs labeloptions=[{text: string, value: anything}, {...}]
Possibility 3: Grouped + Simplest. Grouped select
options=[ { text: "Group 1", options: ["Item 1", "Item 2", ...]}
Possibility 4: Grouped + Customizable
options=[ { text: "Group 1", options: [{text: string, value: anything}, {...}]}
What I have come up with
/** * Definitions for a single item in the list. */export type SimpleOption = string;export type LabeledSimpleOption<T> = { text: string; value: T };export type Option<T> = SimpleOption | LabeledSimpleOption<T>;export type GroupedOption<T> = { text: string; options: Array<Option<T>> };/** * Definitions for an array of items. */export type SimpleOptions<T> = Array<Option<T>>;export type GroupedSimpleOptions<T> = Array<GroupedOption<T>>;export type Options<T> = Option<T> | GroupedOption<T>;
Expectation
// Would be great to not have to specify the type.// Would be great if it could be infered automaticallylet options: Options<string> = [ { text: "Group 1", options: [ { value: "1", text: "One" }, // OK { value: "2", fsfsd: "Two" }, // Not OK { value: "3", text: 3 }, // Not OK ] }];let options: Options<string> = ["Item 1", "Item 2"] // OKlet options: Options<number> = [1, 2] // NOT OKlet options: Options<number> = [ { value: "1", text: 1 }, // OK { value: "2", fsfsd: 2 }, // Not OK { value: "3", text: "3" }, // Not OK]
Current behaviorlet options: Options<string>
acts as if options had "any" as a type. I can assign anything and it's going to be accepted.
Special needsI need to be able to type the value returned as well as a single option itself.Demonstration:
const items: Items = [...]; // Assuming Items signature is compatible with Options<T><MySelect options={items} valueAsItem={false} // Meaning item value is Items[i].value itemSelect={(selectedItem) => ...} // selectedItem must be of type Items[i].value<MySelect options={items} valueAsItem={true} // Meaning item value is the item itself: Items[i] itemSelect={(selectedItem) => ...} // selectedItem must be of type Items[i]
Thanks in advance ! :)