如何在对象打字稿代码中找到元素

How do I find element in object typescript code

所以,我正在尝试动态地为我的图标分配颜色...但是这行代码一直在抱怨,

let icon = iconsList[name];

当我悬停在它上面时..这就是解释“

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;
  

VscodeOn line 25, am trying to pick the specific icon color but it complains

中代码的截图

你可以为这种类型的对象制作indexable type

type KeyValues = {
  [index: string]: string
}

const iconsList: KeyValues = {
   ...values...
}

值得把它分解一点,因为它很有教育意义。从 object 得到 属性 string 是部分函数;某些属性和对象的组合可以 return 值,但不是全部。

在您的示例中,不能保证从 iconsList 类型中获取类型为 string (name) 的 属性 会给出一个值;如果 string"xyz" 怎么办?在那种情况下,应该值是多少?很难给出一个真正具体的答案。

如果我们看一个浓缩的例子,我们会看到同样的错误:

const getIcon = (iconName: string) => {
  const iconsList = {
      heart: '',
      star: '',
  };

  return iconsList[iconName];
};

在行 return iconsList[iconName];

上给我们同样的错误

不过,为了完成这项工作,我们可以做得更好。如果我们想说的是我们传入的 iconName 永远是 iconsList 对象的 属性 ,我们可以通过。类型:

const iconsList = {
    heart: '',
    star: '',
};

const getIcon = (iconName: keyof typeof iconsList) => {
  return iconsList[iconName];
}

const x = getIcon('heart'); // works
const y = getIcon('xyz');   // type error

...我们可以得到更通用的:

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

如果您希望无论输入什么都总是 return 可用值,请考虑研究 Maybe return 类型;那样的话,你总是可以 return 一个 Maybe,如果你不能得到对象上的键,这将是一个 Nothing

希望这能让您深入了解为什么会收到错误以及如何修复它。有什么问题请留言。


根据评论更新:

您需要确保也在 Props 中设置类型,以便我们可以使用它来访问 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.

根据 OliverRadini 的说法,如果以正确的方式跟随他,您将如何实施。

Icon.ts 文件

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;

那么如何复用

上的图标

test.tsx 文件

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;