typescript - Type 'string' is not assignable to type '"x" | "y" | "z"'. TS2345
问题描述
Here is the interface I'm working with:
export default interface BodyInterface {
cover : { name: string, element: JSX.Element },
portfolio : { name: string, element: JSX.Element },
aboutContact : { name: string, element: JSX.Element },
}
The error:
/home/owner/cp/portfolioSite/src/utilities.tsx
TypeScript error in /home/owner/cp/portfolioSite/src/utilities.tsx(19,53):
Argument of type '(keyName: "cover" | "portfolio" | "aboutContact") => JSX.Element' is not assignable to parameter of type '(value: string, index: number, array: string[]) => Element'.
Types of parameters 'keyName' and 'value' are incompatible.
Type 'string' is not assignable to type '"cover" | "portfolio" | "aboutContact"'. TS2345
17 | const allKeys: Array<string> = Object.keys(jsxData);
18 |
> 19 | const linkComponents: JSX.Element[] = allKeys.map((keyName: keyof BodyProps) => {
| ^
20 | const linkComponent: JSX.Element = makeLink(jsxData[keyName].name);
21 | return linkComponent;
22 | })
The surrounding context:
import BodyProps from './bodySection/BodyPropInterface';
export function makeLink(linkName: string): JSX.Element {
return (
<Link to={linkName}>{titleFirstCharacter(linkName)}</Link>
)
}
export function makeAllLinks(jsxData: BodyProps) {
const allKeys: Array<string> = Object.keys(jsxData);
const linkComponents: JSX.Element[] = allKeys.map((keyName: keyof BodyProps) => {
const linkComponent: JSX.Element = makeLink(jsxData[keyName].name);
return linkComponent;
})
return linkComponents;
}
But if I annotate keyName: string
I get this error instead:
/home/owner/cp/portfolioSite/src/utilities.tsx
TypeScript error in /home/owner/cp/portfolioSite/src/utilities.tsx(20,49):
Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'BodyInterface'.
No index signature with a parameter of type 'string' was found on type 'BodyInterface'. TS7053
18 |
19 | const linkComponents: JSX.Element[] = allKeys.map((keyName: string) => {
> 20 | const linkComponent: JSX.Element = makeLink(jsxData[keyName].name);
| ^
21 | return linkComponent;
22 | })
23 |
What is the correct way to solve this error?
解决方案
So it looks like your error is coming from the makeAllLinks
function.
export function makeAllLinks(jsxData: BodyProps) {
const allKeys: Array<string> = Object.keys(jsxData); /// <---- This piece
const linkComponents: JSX.Element[] = allKeys.map((keyName: keyof BodyProps) => {
const linkComponent: JSX.Element = makeLink(jsxData[keyName].name);
return linkComponent;
})
return linkComponents;
}
The right type should be:
Array<keyof BodyProps>
Something like:
const allKeys: Array<keyof BodyProps> = Object.keys(jsxData);
After that change I still get an issue. It looks like Object.keys will always just return an array of strings, and it doesn't take a generic you can pass in to change that. So you can typecast it, to look like:
const allKeys = Object.keys(jsxData) as Array<keyof BodyProps>;
Then you should be able to map over it, and have the right values come up.
推荐阅读
- swiftui - SwiftUI 嵌套 ForEach
- c++ - 在编译时根据一些枚举值添加额外的方法
- firebase - 在 Unity3D 中检查 Firebase 是否初始化成功?
- python - 如何动态构建函数并找到根python
- java - 反转类中的数组不会改变元素的顺序
- csv - 如何打开具有多列和多行的大型 CSV 文件
- socket.io - pixiJS 和 socket.io 如何一起工作?(一般问题)
- c - 无法理解 ip 结构的实现
- react-native - React Native & Amplify - 构建命令
- mysql - 如何在mysql中获取上周五过去7天的数据?