我有一个简单的代码:
const allTypes = { jpg: true, gif: true, png: true, mp4: true };
const mediaType = url.substring(url.lastIndexOf('.') + 1).toLowerCase();
return Boolean(allTypes[mediaType]);
TypeScript抱怨:
Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ jpg: boolean; gif: boolean; png: boolean; mp4: boolean; }'.
No index signature with a parameter of type 'string' was found on type '{ jpg: boolean; gif: boolean; png: boolean; mp4: boolean; }'. TS7
我认为我需要将mediaType
视为keyof typeof allTypes
,但不知道如何。请帮助
为完整起见,完整的代码为:
// these are all the types of media we support
const allTypes = { jpg: true, gif: true, png: true, mp4: true };
const MediaGallery = () => {
const classes = useStyles();
const [ filters, setFilters ] = useState(allTypes);
return (
<div className={classes.root}>
{mediaList
.filter(({ url }) => {
const type = url.substring(url.lastIndexOf('.') + 1).toLowerCase();
return Boolean(filters[type]);
})
.map(({ url, caption, hash }) => <Media url={url} caption={caption} key={hash} />)}
<FiltersPanel onFiltersChanged={(newFilters: any) => setFilters(newFilters)} />
</div>
);
};
答案 0 :(得分:1)
您所需要做的就是定义索引签名:
const allTypes: {[key: string]: boolean} = { jpg: true, gif: true, png: true, mp4: true };
类似于我们如何使用接口来描述函数类型,我们也可以描述我们可以“索引”到的类型,例如
a[10]
或ageMap["daniel"]
。可索引类型具有一个 index签名,该索引描述了我们可以用来对对象建立索引的类型,以及建立索引时对应的返回类型。让我们举个例子:
interface StringArray {
[index: number]: string;
}
let myArray: StringArray;
myArray = ["Bob", "Fred"];
let myStr: string = myArray[0];
上面,我们有一个带有索引签名的
StringArray
接口。该索引签名表明,将StringArray
索引为number
时,它将返回string
。
答案 1 :(得分:0)
您可以使用可索引的类型,但是当您要支持的键列表有限时,这会allTypes
的类型扩展为包含任何(字符串)键。
一个更好的解决方案-允许您使用正确类型的allTypes
-(如您在问题中已经指出的那样)告诉编译器您假设mediaType
是其中之一的类型的 allTypes
键和type assertion:
return Boolean(allTypes[mediaType as keyof typeof allTypes]);
在这种情况下,此类型与联合类型等效
"jpg" | "gif" | "png" | "mp4"
,但它是自动计算的。
(当然,如何确保您的假设在运行时是正确的)