1

我似乎无法弄清楚如何在这里正确输入索引签名。我有一个枚举,需要遍历它以将一些 JSX 放在屏幕上。我可以猜到它在告诉我什么,但我无法在我的代码中解决它。这两种Category[el]说法都有问题。

export enum Category {
    All = 'ALL',
    Employee = 'EMPLOYEE',
    Gear = 'GEAR',
    Room = 'ROOM',
    Other = 'OTHER',
}

我渲染一些 JSX 的简化函数是:

    const renderCategories = (): ReactElement | ReactElement[] => {
        return Object.keys(Category).map(el => {
            return (
                <Option key={el} value={Category[el]}>
                    <span>{` (${someOtherData.filter((e) => e.type === Category[el].length})`}</span>
                </Option>
            );
        });
    };

TS告诉我:

Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'typeof Category'.
  No index signature with a parameter of type 'string' was found on type 'typeof Category'.
4

2 回答 2

1

您可以将以下索引签名添加到枚举:

export enum Category {
    All = 'ALL',
    Employee = 'EMPLOYEE',
    Gear = 'GEAR',
    Room = 'ROOM',
    Other = 'OTHER',
    [key: string]: string,
}
于 2020-12-21T15:52:42.110 回答
1

这个用例很常见,因为Object.keys它总是将每个键推断为string与类似的键enum或具有特定类型的对象不兼容。

但是 Typescript 仍然允许我们将每个键转换为一个类型,这意味着我们只是简单地转换回上述枚举的类型。

这是反映上述解释的片段:

export enum Category {
  All = 'ALL',
  Employee = 'EMPLOYEE',
  Gear = 'GEAR',
  Room = 'ROOM',
  Other = 'OTHER',
}

// A common type to detect the enum type

type EnumType = typeof Category;
type EnumKeyType = keyof EnumType;

// Then cast back to our desired type

someOtherData.filter((e) => e.type === Category[el as EnumKeyType].length) // cast `el as EnumKeyType`

于 2020-12-21T16:26:46.207 回答