我具有以下类型结构:
export type Method1 = (id: string, param: string) => Promise<any>
export enum ValuesList {
VALUE1 = 'VALUE1',
VALUE2 = 'VALUE2'
}
export type ValuesMap = {
[key in ValuesList]: {
callMethod: Method1
}
}
export const methodsMap: ValuesMap = {
[ValuesList.VALUE1]: {
callMethod: lib.method
},
[ValuesList.VALUE2]: {
callMethod: lib2.method
}
}
在应用程序的某些部分,我想映射一些列表以动态调用此方法:
methodsMap[target].callMethod(data.id, data.param)
通过打字稿返回以下问题:
Element implicitly has an 'any' type because type 'ValuesMap' has no index signature.ts(7017)
打字稿无法将ValuesMap
识别为带有索引的元素。如果我将ValuesMap
改为使用[key: string]
而不是[key in ValuesList]
,则可以使用,但是我想保留[key in ValuesList]
答案 0 :(得分:1)
首先,让我们回顾一些术语。在TypeScript中,索引签名可以是字符串或数字,但不能更窄。如果您不只是使用string
类型,而是通过文字(即属性,而不是索引签名)显式指定类型。这就是为什么枚举从不具有类型签名,而是具有属性的原因。
type A = {
[key: string]: number // this is index signature
};
type B = {
[key in 'foo' | 'bar']: number // this is a property
}
现在是实际代码。您发布的代码片段似乎运行良好。当您将鼠标悬停在名称ValuesMap
上时,工具提示会显示为:
type ValuesMap = { VALUE1: { callMethod: Method1; }; VALUE2: { callMethod: Method1; }; }
因此,实际上,它包含枚举中的两个值。因此,问题必须是您用作索引的target
。因为TypeScript抱怨没有索引签名,所以我最好的猜测是您使用的target
的类型为string
,因此可能不是该枚举的值。 (您可以将鼠标悬停在其上方以查看其类型。)由于TypeScript希望防止您在未定义的情况下调用callMethod
,因此它开始对您大吼大叫,直到将target
限制为正确的值为止。 / p>
答案 1 :(得分:1)
如果您想使用 enum
作为变量来检查值:
如果你有
export enum ValuesList {
VALUE1 = 'VALUE1',
VALUE2 = 'VALUE2'
}
然后使用:
someVariable: { [key: string]: ValuesList } = ValuesList
代替:
someVariable: ValuesList = ValuesList