问题
So, am trying to assign colours to my icons dynamically ... but this line of code keeps complaining,
let icon = iconsList[name];
When I hover of it .. This is the explanation "
Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ heart: string; star: string; like: string; dislike: string; flash: string; marker: string; filter: string; user: string; circle: string; hashtag: string; calendar: string; chevronLeft: string; optionsV: string; optionsH: string; chat: string; explore: string; }'. No index signature with a parameter of type 'string' was found on type '{ heart: string; star: string; like: string; dislike: string; flash: string; marker: string; filter: string; user: string; circle: string; hashtag: string; calendar: string; chevronLeft: string; optionsV: string; optionsH: string; chat: string; explore: string; }'.ts(7053)
interface Props{
name:string,
}
const Icon = ({ name }:Props) => {
const iconsList = {
heart: '',
star: '',
like: '',
dislike: '',
flash: '',
marker: '',
filter: '',
user: '',
circle: '',
hashtag: '',
calendar: '',
chevronLeft: '',
optionsV: '',
optionsH: '',
chat: '',
explore: ''
};
let icon = iconsList[name];
icon = icon.substr(3);
icon = String.fromCharCode(parseInt(icon, 16));
return icon;
};
export default Icon;
ScreenShot of the code in Vscode On line 25, am trying to pick the specific icon color but it complains
回答1:
It's worth breaking this down a little bit because it's quite educational. Getting a property string
from an object
is something of a partial function; some combinations of properties and objects can return values, but not all.
In your example, getting a property which has type string
(name
) from the type of iconsList
is not guaranteed to give a value; what if the string
is "xyz"
? What ought the value be in that case? It's hard to give a really concrete answer to that.
If we look at a condensed example, we see the same error:
const getIcon = (iconName: string) => {
const iconsList = {
heart: '',
star: '',
};
return iconsList[iconName];
};
Gives us the same error on the line return iconsList[iconName];
We can do better though, in order to make this work. If what we want to say is that the iconName
we pass in will always be a property of the iconsList
object, we can do that via. a type:
const iconsList = {
heart: '',
star: '',
};
const getIcon = (iconName: keyof typeof iconsList) => {
return iconsList[iconName];
}
const x = getIcon('heart'); // works
const y = getIcon('xyz'); // type error
...and we can get more generic with this:
const path = <T>(o: T) => (k: keyof T) => o[k];
const iconsList = {
heart: '',
star: '',
};
const getIcon = path(iconsList);
const x = getIcon('heart'); // works
const y = getIcon('xyz'); // type error
If you'd like to always return a usable value no matter what the input, consider looking into a Maybe return type; that way, you can always return a Maybe
, which will be a Nothing
if you can't get the key on the object.
Hopefully that gives an insight into why you're getting the error and how you can fix it. If you have any questions, please ask away.
Update as per comment:
You'd want to make sure that you're also setting the type in Props
in order that we can use it to access iconTypes
:
const iconsList = {
heart: '',
star: '',
like: '',
dislike: '',
flash: '',
marker: '',
filter: '',
user: '',
circle: '',
hashtag: '',
calendar: '',
chevronLeft: '',
optionsV: '',
optionsH: '',
chat: '',
explore: ''
};
interface Props{
name: keyof typeof iconsList;
}
etc.
回答2:
You can make indexable type for this type of object
type KeyValues = {
[index: string]: string
}
const iconsList: KeyValues = {
...values...
}
回答3:
So according to OliverRadini this how you can implement it if am following him in the correct way.
Icon.ts file
const iconsList = {
heart: '',
star: '',
like: '',
dislike: '',
flash: '',
marker: '',
filter: '',
user: '',
circle: '',
hashtag: '',
calendar: '',
chevronLeft: '',
optionsV: '',
optionsH: '',
chat: '',
explore: ''
};
interface Props{
name: keyof typeof iconsList;
}
const Icon = ({ name }:Props) => {
const path = <T>(o: T) => (k: keyof T) => o[k];
const getIcon = path(iconsList);
const x = getIcon(name); // works
return x;
};
export default Icon;
Then how to reuse the icon on the
test.tsx file
import React from 'react';
import { Text, View } from 'react-native';
import Icon from './Icon';
interface Props {
}
const TestComponent = ({}: Props) => {
return (
<View style={styles.containerTest}>
<View style={styles.testView}>
<Text style={styles.testText}>
<Icon name="heart" /> Test icon
</Text>
</View>
</View>
);
};
export default TestComponent;
来源:https://stackoverflow.com/questions/62068664/how-do-i-find-element-in-object-typescript-code