TypeScript如何让字典的指定特殊键对应值可省略特定属性
问题原因
你之前的写法不生效是因为交叉类型要求值同时满足所有子类型的约束。Partial<Record<string, Bar>>的索引签名覆盖了所有字符串类型的键,包含你指定的特殊键foo1、foo2,相当于要求这两个特殊键的值必须同时符合Foo和Bar两个类型,自然会提示缺少必填属性y。
解决方案
可以直接在通用索引签名中排除掉已经定义的特殊键,再和特殊键的类型定义交叉即可,实现代码如下:
// 泛型说明: // SpecialKeys:指定的特殊键联合类型 // SpecialVal:特殊键对应的值类型 // CommonVal:普通字符串键对应的值类型 type MixedDict<SpecialKeys extends string, SpecialVal, CommonVal> = // 普通键部分:排除特殊键后的所有字符串键,值为CommonVal,保持可选 Omit<Partial<Record<string, CommonVal>>, SpecialKeys> // 特殊键部分:指定的特殊键对应值为SpecialVal,保持可选 & Partial<Record<SpecialKeys, SpecialVal>>
使用示例
interface Foo { x: string } interface Bar { x: string, y: number } type FooKeys = 'foo1' | 'foo2' // 构造你需要的混合字典类型 type MixedDictionary = MixedDict<FooKeys, Foo, Bar> // 赋值完全符合预期,不会报错 const mixedDictionary: MixedDictionary = { "foo1": { x: "some string" }, "sfdds": { x: "some string", y: 23 } }
如果你的特殊键允许可选传入y属性,可以直接从Bar派生特殊值类型,不用单独定义:
// 特殊键值类型:x必选,y可选 type Foo = Omit<Bar, 'y'> & Partial<Pick<Bar, 'y'>>
内容的提问来源于stack exchange,提问作者Michal Kurz
相关产品推荐
相关产品推荐

