泛型被识别为any,如何优化Svelte下拉组件的TypeScript泛型?
Svelte下拉组件的TypeScript类型定义问题
编辑:已解决。答案已更新如下
我想要创建一个Svelte下拉组件<MySelect options={...},它可以接受多种格式的items选项,具体有以下几种实现方式:
- 最简形式:纯字符串值,下拉项的显示文本与值一致
options=["Item 1", "Item 2", "Item 3"] - 可自定义文本与值
options=[{text: string, value: anything}, {...}] - 分组+最简形式:分组下拉选择器
options=[ { text: "Group 1", options: ["Item 1", "Item 2", ...] } - 分组+可自定义
options=[ { text: "Group 1", options: [{text: string, value: anything}, {...}] }
当前的类型定义
/** * 列表中单个项的定义。 */ 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>> }; /** * 项数组的定义。 */ export type SimpleOptions<T> = Array<Option<T>>; export type GroupedSimpleOptions<T> = Array<GroupedOption<T>>; export type Options<T> = Option<T> | GroupedOption<T>;
我的期望
- 无需手动指定类型,希望能自动推断类型。
- 类型能自动推断,示例如下:
目前let options: Options<string> = [ { text: "Group 1", options: [ { value: "1", text: "One" }, // 合法 { value: "2", fsfsd: "Two" }, // 不合法 { value: "3", text: 3 }, // 不合法 ] } ]; let options: Options<string> = ["Item 1", "Item 2"] // 合法 let options: Options<number> = [1, 2] // 不合法 let options: Options<number> = [ { value: "1", text: 1 }, // 合法 { value: "2", fsfsd: 2 }, // 不合法 { value: "3", text: "3" }, // 不合法 ]let options: Options<string>的表现等同于类型为any,任何值都能被赋值。 - 需要能为返回值以及单个选项本身指定类型:
const items = [...]; // 假设items符合Options<T>的签名 <MySelect options={items} valueAsItem={false} // 表示选中值为Items[i].value itemSelect={(selectedItem) => ...} // selectedItem类型应为Items[i].value的类型 <MySelect options={items} valueAsItem={true} // 表示选中值为项本身:Items[i] itemSelect={(selectedItem) => ...} // selectedItem类型应为Items[i]的类型 - 后续希望能通过props动态设置标签/值的属性名,例如:
let items = [ { attr: "1", label: 1 }, ... ] <MySelect options={items} valueAsItem={true} labelField="label" valueField="attr" itemSelect={(selectedItem) => ...} // selectedItem应为"1"(string类型)
我想知道这些需求是否能通过TypeScript实现,还是只能依赖any类型。
编辑1
编辑:有人要求我提供可运行的演示代码。 我原本不想涉及Svelte/组件代码,因为这纯粹是TypeScript的问题。 我创建了一个Svelte演示沙箱。 类型定义:src/types/MySelect.d.ts 使用示例:src/routes/+page.svelte
内容的提问来源于stack exchange,提问作者James St-Pierre
相关产品推荐
相关产品推荐

