Issue
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't know how.
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>
);
};
Solution
All you need is to define the index signature:
const allTypes: {[key: string]: boolean} = { jpg: true, gif: true, png: true, mp4: true };
Indexable Types
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"]
. 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. This index signature states that when aStringArray
is indexed with anumber
, it will return astring
.
Utility type: Record<Keys, Type>
Another solution is to use the TypeScript utility type Record<Keys, Type>
:
Constructs an object type whose property keys are
Keys
and whose property values areType
. This utility can be used to map the properties of a type to another type.
const allTypes: Record<string, boolean> = { jpg: true, gif: true, png: true, mp4: true };
for (const key of Object.keys(allTypes)) {
console.log(`${key}: ${allTypes[key]}`);
}
Answered By - Christopher Peisert
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.