How do I find element in object typescript code

落爺英雄遲暮 提交于 2020-06-26 06:27:50

问题


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: '&#xe800;',
    star: '&#xe801;',
};

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: '&#xe800;',
    star: '&#xe801;',
    like: '&#xe800;',
    dislike: '&#xe802;',
    flash: '&#xe803;',
    marker: '&#xf031;',
    filter: '&#xf0b0;',
    user: '&#xf061;',
    circle: '&#xf039;',
    hashtag: '&#xf029;',
    calendar: '&#xf4c5;',
    chevronLeft: '&#xf004;',
    optionsV: '&#xf142;',
    optionsH: '&#xf141;',
    chat: '&#xf4ac;',
    explore: '&#xf50d;'
};

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: '&#xe800;',
    star: '&#xe801;',
    like: '&#xe800;',
    dislike: '&#xe802;',
    flash: '&#xe803;',
    marker: '&#xf031;',
    filter: '&#xf0b0;',
    user: '&#xf061;',
    circle: '&#xf039;',
    hashtag: '&#xf029;',
    calendar: '&#xf4c5;',
    chevronLeft: '&#xf004;',
    optionsV: '&#xf142;',
    optionsH: '&#xf141;',
    chat: '&#xf4ac;',
    explore: '&#xf50d;'
};

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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!