如何在TypeScript中表示键为foo/bar/baz之一的对象类型?
正确定义API返回类型的方法
你的需求是:类型必须包含id和name字段,同时必须且只能存在foo/bar/baz中的一个字段,对应的值结构固定为{ address: string }。下面是两种可行的写法:
写法一:直接联合类型
最直观的方式是列出所有可能的组合,通过联合类型确保只能存在其中一个指定键:
type ItemResponse = { id: string; name: string; foo: { address: string } } | { id: string; name: string; bar: { address: string } } | { id: string; name: string; baz: { address: string } };
写法二:提取公共部分优化
如果字段较多,可先提取公共属性,再通过泛型生成每个变体的联合类型,减少重复代码:
// 公共基础属性 type BaseItem = { id: string; name: string }; // 生成包含指定键的类型 type WithSingleKey<K extends 'foo' | 'bar' | 'baz'> = BaseItem & { [key in K]: { address: string } }; // 联合所有可能的类型 type ItemResponse = WithSingleKey<'foo'> | WithSingleKey<'bar'> | WithSingleKey<'baz'>;
为什么你的两种写法无效?
第一种写法的问题
你尝试直接在对象键位置写联合类型'foo' | 'bar' | 'baz'?: ...,这是TypeScript语法不允许的。对象键名不能直接用联合类型这样定义,这种写法会被解析为语法错误,无法生效。
第二种写法的问题
你在映射类型中写了[K in ['foo' | 'bar' | 'baz']],这里的['foo' | 'bar' | 'baz']是数组字面量,对应的类型是('foo'|'bar'|'baz')[],而非联合类型。映射类型会把数组的索引(number)作为键,而非你期望的foo/bar/baz。
即使你改成[K in 'foo' | 'bar' | 'baz']?: ...,这种写法会让三个键都变成可选的,允许同时存在多个或都不存在,不符合你“只会存在其中一个”的要求。
内容的提问来源于stack exchange,提问作者synic
相关产品推荐
相关产品推荐

