0

在打字稿中

const func = (str: string) => {
  const strToNumber = {
    account: 0,
    goals: 1,
    metrics: 2,
  };

  const number = strToNumber?.[str] || 0;
};

给出以下错误:

元素隐式具有“任何”类型,因为“字符串”类型的表达式不能用于索引类型“{ account: number; 目标:数量;指标:数字;}'。在“{ account: number;”类型上找不到带有“string”类型参数的索引签名;目标:数量;指标:数字;}'。

我有点理解为什么它会给出这个错误,但同时我没有看到代码有任何问题,因为我使用的是可选链接,任何错误的值都会回退到 0。

我应该怎么做才能不出现此错误?有没有不涉及使用“as”或“@ts-ignore”的方法?

tsconfig.json

{
  "compilerOptions": {
    "target": "es5",
    "lib": [
      "dom",
      "dom.iterable",
      "esnext"
    ],
    "allowJs": true,
    "skipLibCheck": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noEmit": true,
    "esModuleInterop": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "jsx": "preserve",
    "baseUrl": "./",
    "paths": {
      "@components/*": [
        "components/*"
      ],
      "@lib/*": [
        "lib/*"
      ],
      "@utils/*": [
        "utils/*"
      ],
      "@public/*": [
        "public/*"
      ],
      "@types/*": [
        "types/*"
      ]
    }
  },
  "include": [
    "next-env.d.ts",
    "**/*.ts",
    "**/*.tsx",
    "tailwind.config.js"
  ],
  "exclude": [
    "node_modules"
  ]
}
4

2 回答 2

2

你可以给strToNumber对象一个像这样的类型:

const func = (str: string) => {
  const strToNumber : { [key:string]:number } = { // <--
    account: 0,
    goals: 1,
    metrics: 2,
  };

  const number = strToNumber?.[str] || 0;
};

这是一个示例Typescript 游乐场

于 2021-09-27T13:50:36.660 回答
0

您可能需要使用保护子句来断言str确实是 的键strToNumber,以便访问strToNumber?.[str]不会引发错误。保护子句可以是非常通用的东西,例如:

function isKeyInShallowObject<T = Record<string, any>>(key: any, obj: T): key is keyof typeof obj {
    return Object.keys(obj).includes(key);
}

然后你可以这样使用它:

const number = isKeyInShallowObject(str, strToNumber) ? strToNumber[str] || 0;

请参阅此处的概念证明。这样做的一个优点是,在这种情况下,您不再需要依赖可选链接,即strToNumber[str]可以工作,因为您的保护子句将处理str不是对象键的情况。


或者,您可以让 typescript 知道这strToNumber只是一个通用字典,其键是任何string值:

const func = (str: string) => {
  const strToNumber: Record<string, number> = { ... };

  // Rest of your code here
};

请参阅概念验证


一个肮脏但可行的 hack 是一个单行的,你只需强制 TypeScript 认为这str是一个关键strToNumber

const number = strToNumber?.[str as keyof typeof strToNumber] || 0;

请参阅概念验证

于 2021-09-27T13:48:52.627 回答