Reputation: 8407
So i wanted to have all the icon names in the autocomplete from the react native icons module. Unfortunately the typings they provide do not include the names as an union type.
So my question is, importing an object (that typescript recognizes, with all its keys), how can I get all the keys as a union type.
Currently this is the only thing i came up with
import React from 'react';
import { MaterialCommunityIcons as Icon } from '@expo/vector-icons';
import { IconProps } from '@types/react-native-vector-icons/Icon'
import glyphmap from 'react-native-vector-icons/glyphmaps/MaterialCommunityIcons.json'
// create a type where I can do keyof
type MyMap<T> = {
[ P in keyof T ]: number
};
// unnecessary? function that maps any input
// to MyMap.
function something<T>(input: T) : MyMap<T> {
return (input as any) as MyMap<T>
}
const result = something(glyphmap);
// finally I get all keys from glyphmap as union of string literals
type MapKeys = keyof MyMap<typeof result>
interface Props extends IconProps {
name: MapKeys
}
const MyIcon = (props: Props) => (
<Icon {...props} />
)
// using here the name prop gives me all the keys as autocomplete
const Test = props => (
<MyIcon name="access-point" />
)
So as you can see, I couldn´t find any other way, how I could convert the glyphmap from a json file to something like this, without passing it through a senseless function
type MyMap<T> = {
[ P in keyof T ]: number
};
So one more time the question more precise:
How do I convert an untyped object into MyMap
without passing it through a function
Upvotes: 2
Views: 772
Reputation: 8407
UPDATE
So after looking into import types
(great thanks to Madara Uchiha) the whole thing can be transformed into one line of code... :D
type Glyphmap = typeof import('somemodule/.../file.json')
ORIGINAL
Oh, as soon as I sent the question, I looked over the code again and found that
the typeof result
could be also directly typeof glyphmap
. So I tried and it worked perfectly. So no need of this useless function.
import React from 'react';
import { MaterialCommunityIcons as Icon } from '@expo/vector-icons';
import { IconProps } from '@types/react-native-vector-icons/Icon'
import glyphmap from 'react-native-vector-icons/glyphmaps/MaterialCommunityIcons.json'
type MyMap<T> = {
[ P in keyof T ]: number
};
// spread keys after converting glyphmap into MyMap
type MapKeys = keyof MyMap<typeof glyphmap>
interface Props extends IconProps {
name: MapKeys
}
const MyIcon = (props: Props) => (
<Icon {...props} />
)
const Test = props => (
<MyIcon name="account" />
)
Upvotes: 2