首页 > 解决方案 > 在打字稿中使用reduce,错误“元素隐式具有'any'类型,因为类型的表达式不能用于索引类型'{}'”

问题描述

我得到错误:

元素隐式具有“任何”类型,因为类型“POST_TYPE”的表达式不能用于索引类型“{}”属性“[POST_TYPE.POST]”在类型“{}”上不存在;

在具有如下接口的函数上使用 reduce 时出错:

// enum
export const enum POST_TYPE {
  POST = 'POST',
  BOARD = 'BOARD',
  ...
}

// interface
export interface Post {
  postType?: POST_TYPE[];
}

export interface PostType {
  POST?: boolean;
  BOARD?: boolean;
}

// function
const exec = (prevType: Post['postType'], type: PostType) => {
 const prevObject = prevType.reduce((prev, it) => {
    prev[it] = true; -->> ERROR in prev[it]
    return prev;
  }, {});
}

我犯了什么错误?

标签: typescript

解决方案


一个问题是你的论点prevType: Post['postType']可能是undefined,因为Post['postType']可能是undefined。不确定您要在那里做什么,但也许在. 上设置postType所需的属性Post,并在将对象传递给exec.

在您的代码中,传递给的第二个参数reduce缺少类型 - 它只是一个普通对象,并且您没有将类型参数传递给.reduce,因此 Typescript 不允许您向其中添加任意键值对。

如果将类型参数传递给reduce,这将表示初始值和累加器的类型。在这里,因为类型将是一个具有 的部分属性的对象POST_TYPE,所以创建这样一个对象类型并使用Partial。然后你可以断言返回值是一个完整的对象(不缺少属性):

export interface Post {
    postType: POST_TYPE[];
}
const exec = (prevType: Post['postType']) => {
    type PostObj = {
        [T in POST_TYPE]: boolean;
    };
    const prevObject = prevType.reduce<Partial<PostObj>>((prev, it) => {
        prev[it] = true;
        return prev;
    }, {}) as PostObj;
};

但是reduce有点冗长,并且可以说不是在创建单个对象时使用的正确工具。只声明对象并分配给它的属性可能更合适,或者使用Object.fromEntries

const postObj = Object.fromEntries(
    prevType.map(it => [it, true])
) as PostObj;

(不幸的是,TS 看起来还不能充分推断出返回值的类型fromEntries,因此需要类型断言)


推荐阅读