[英]Typescript Error: type 'string' can't be used to index type X
I have a simple code:我有一个简单的代码:
const allTypes = { jpg: true, gif: true, png: true, mp4: true };
const mediaType = url.substring(url.lastIndexOf('.') + 1).toLowerCase();
return Boolean(allTypes[mediaType]);
TypeScript is complaining:打字稿抱怨:
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
I think I need to treat mediaType
as keyof typeof allTypes
, but don know how.我想我需要将
mediaType
视为keyof typeof allTypes
,但不知道如何。 Please help请帮忙
For sake of completion, the complete code is:为了完成,完整的代码是:
// 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>
);
};
All you need is to define the index signature :您只需要定义索引签名:
const allTypes: {[key: string]: boolean} = { jpg: true, gif: true, png: true, mp4: true };
Similarly to how we can use interfaces to describe function types, we can also describe types that we can “index into” like
a[10]
, orageMap["daniel"]
.类似于我们如何使用接口来描述函数类型,我们也可以描述我们可以“索引”的类型,如
a[10]
或ageMap["daniel"]
。 Indexable types have an index signature that describes the types we can use to index into the object, along with the corresponding return types when indexing.可索引类型有一个索引签名,它描述了我们可以用来索引对象的类型,以及索引时相应的返回类型。 Let's take an example:
让我们举个例子:
interface StringArray { [index: number]: string; } let myArray: StringArray; myArray = ["Bob", "Fred"]; let myStr: string = myArray[0];
Above, we have a
StringArray
interface that has an index signature.上面,我们有一个带有索引签名的
StringArray
接口。 This index signature states that when aStringArray
is indexed with anumber
, it will return astring
.此索引签名指出,当
StringArray
用number
索引时,它将返回一个string
。
You can use indexable types, but this widens the type of allTypes
to contain any (string) key, when it looks like you have a limited list of keys that you want to support.您可以使用可索引类型,但是当您想要支持的键列表有限时,这会扩大
allTypes
的类型以包含任何(字符串)键。
A better solution - allowing you to use the proper type of allTypes
- is (as you already indicated in your question) to tell the compiler your assumption that mediaType
is one of the keys of the type of allTypes
with a type assertion :一个更好的解决方案 - 允许您使用
allTypes
的正确类型 - 是(正如您在问题中已经指出的那样)告诉编译器您的假设mediaType
是具有类型断言的allTypes
类型的键之一:
return Boolean(allTypes[mediaType as keyof typeof allTypes]);
This type is in this case equivalent to the union type "jpg" | "gif" | "png" | "mp4"
在这种情况下,此类型等效于联合类型
"jpg" | "gif" | "png" | "mp4"
"jpg" | "gif" | "png" | "mp4"
"jpg" | "gif" | "png" | "mp4"
, but it is computed automatically. "jpg" | "gif" | "png" | "mp4"
,但它是自动计算的。
(How you ensure that your assumption is correct at runtime is a separate concern, of course.) (当然,如何确保您的假设在运行时正确是一个单独的问题。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.