最近在写接口类型时,希望一个类型的键值是联合类型中固定的几个
例如
const enum INFO_KEYS{
TEL = 'tel',
AGE = 'age',
}
// or
// type IInfoKeys = 'tel' | 'age';
export interface IPersonnalInfo = {
area_id: number;
area_name: string;
[key: INFO_KEYS]: number; // or [key: IInfoKeys]: number;
}
但是却得到错误提示
An index signature parameter type cannot be a union type. Consider using a mapped object type instead. ts(1337)
在github上找到了quick fix解决方法,先附上链接:https://github.com/Microsoft/TypeScript/issues/24220
下面是我对解决方法的总结
解决方案
解决该问题,我们只需要注意以下三个地方
-
使用
[key in INFO_KEYS]
,而不是[key: INFO_KEYS]
这也是很多回答给出的方案,但事实上?
export interface IPersonnalInfo = {
area_id: number;
area_name: string;
[key in INFO_KEYS]: number
}
在使用in
之后,仍然会得到错误提示
A computed property name in an interface must refer to an expression whose type is a literal type or a 'unique symbol' type. ts(1169)
A computed property name must be of type 'string', 'number', 'symbol', or 'any'. ts(2464)
因为接下来还有两点需要注意
- 如果类型是
interface
,使用type
类型别名替换
export type IPersonnalInfo = {
area_id: number;
area_name: string;
[key in INFO_KEYS]: number;
};
- 分离类型中的其他成员,使用相交类型来组织它们
type IAreaInfo = { //type or interface
area_id: number;
area_name: string;
}
export type IPersonnalInfo = {
[key in INFO_KEYS]: number;
} & IAreaInfo;
最后
如果注意了以上三点 ,我们最终得到的代码会是这样,并且没有错误提示
const enum INFO_KEYS{
TEL = 'tel',
AGE = 'age'
}
// or
// type IInfoKeys = 'tel' | 'age';
type IAreaInfo = {
area_id: number;
area_name: string;
}
export type IPersonnalInfo = {
[key in INFO_KEYS]: number; //or [key in IInfoKeys]: number;
} & IAreaInfo;