打字稿错误:类型'string'不能用于索引类型X

时间:2019-08-27 03:03:30

标签: typescript

我有一个简单的代码:

const allTypes = { jpg: true, gif: true, png: true, mp4: true };
const mediaType = url.substring(url.lastIndexOf('.') + 1).toLowerCase();
return Boolean(allTypes[mediaType]);

TypeScript抱怨:

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

我认为我需要将mediaType视为keyof typeof allTypes,但不知道如何。请帮助

为完整起见,完整的代码为:

// 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>
    );
};

2 个答案:

答案 0 :(得分:1)

您所需要做的就是定义索引签名

const allTypes: {[key: string]: boolean} = { jpg: true, gif: true, png: true, mp4: true };

Indexable Types

  

类似于我们如何使用接口来描述函数类型,我们也可以描述我们可以“索引”到的类型,例如a[10]ageMap["daniel"]。可索引类型具有一个 index签名,该索引描述了我们可以用来对对象建立索引的类型,以及建立索引时对应的返回类型。让我们举个例子:

interface StringArray {
    [index: number]: string;
}

let myArray: StringArray;
myArray = ["Bob", "Fred"];

let myStr: string = myArray[0];
  

上面,我们有一个带有索引签名的StringArray接口。该索引签名表明,将StringArray索引为number时,它将返回string

答案 1 :(得分:0)

您可以使用可索引的类型,但是当您要支持的键列表有限时,这会allTypes的类型扩展为包含任何(字符串)键。

一个更好的解决方案-允许您使用正确类型的allTypes-(如您在问题中已经指出的那样)告诉编译器您假设mediaType其中之一类型的 allTypes键和type assertion

return Boolean(allTypes[mediaType as keyof typeof allTypes]);

在这种情况下,此类型与联合类型等效 "jpg" | "gif" | "png" | "mp4",但它是自动计算的。

(当然,如何确保您的假设在运行时是正确的)