如何为getFieldsBySlug函数添加类型以返回特定类型对象?
为getFieldsBySlug添加精确类型标注方案
要实现调用getFieldsBySlug('price')时返回精确字面量类型而非通用string结构,需要结合as const字面量断言和泛型映射来实现,具体步骤如下:
1. 为Fields数组添加as const断言
首先给Fields加上as const,让TypeScript将数组中每个对象的属性值识别为字面量类型(而非宽泛的string):
const Fields = [ { label: "Price, $", slug: "price", type: "checkbox", }, { label: "Area", slug: "area", type: "number", }, { label: "Floor", slug: "floor", type: "grop", }, { label: "Finishing", slug: "finishing", type: "radio", }, ] as const;
2. 定义基础类型与映射类型
基于Fields的字面量类型,提取单个字段类型,并创建slug到对应字段类型的映射:
// 单个字段的字面量类型 type Field = typeof Fields[number]; // 建立slug与对应字段类型的映射 type FieldMap = { [F in Field as F['slug']]: F };
3. 为getFieldsBySlug添加泛型类型标注
使用泛型约束传入的slug参数,让函数返回与slug对应的精确字段类型数组,同时处理find可能返回undefined的情况:
const getFieldsBySlug = <Slug extends keyof FieldMap>(...slugs: Slug[]): FieldMap[Slug][] => { return slugs .map((slug) => Fields.find((field) => field.slug === slug)) .filter((field): field is FieldMap[Slug] => field !== undefined); };
效果验证
现在调用函数时,传入不同slug会得到精确的返回类型:
// 返回类型:[{ label: "Price, $", slug: "price", type: "checkbox" }] const priceField = getFieldsBySlug('price'); // 返回类型:[{ label: "Area", slug: "area", type: "number" }, { label: "Finishing", slug: "finishing", type: "radio" }] const mixedFields = getFieldsBySlug('area', 'finishing');
关键说明
as const确保Fields的属性值被TypeScript视为不可变的字面量,而非宽泛的string类型。FieldMap映射类型将每个slug与对应的字段类型绑定,让泛型可以精准匹配。- 类型守卫
filter((field): field is FieldMap[Slug] => field !== undefined)过滤掉undefined,确保返回数组中没有空值,同时让TypeScript识别返回的是精确类型。
内容的提问来源于stack exchange,提问作者Alex Pavlov
相关产品推荐
相关产品推荐

