首页 > 解决方案 > 元素隐式具有“任何”类型,因为类型“xxx”没有索引签名

问题描述

当我尝试在 typescript 中重构一个 es6 项目时,我遇到了两个关于这个问题的案例,一个是 about Object.keys(),另一个是 about import * as xxx

情况1:

const SUPPORTED_VALUES = {
    min_s: 'Mininum similarity',
    max_rc: 'Maximum result count'
}
const UNSUPPORTED_MSG =
    'Configurable values:\n' +
    Object.keys(SUPPORTED_VALUES)
        .map(k => `${k}: ${SUPPORTED_VALUES[k]}`)
        .join('\n')

kin 保证是 in 的一个mapSUPPORTED_VALUES,但 typescript 编译器不知道这一点。我应该如何在不禁用的情况下解决这个问题noImplicitAny

案例二:

我有一个名为cmd.ts

export async function cmd1(args){}
export async function cmd2(args){}

它使用的是另一个像这样的文件:

import * as cmdHandlers from './cmd'
// some code...
if (cmd in cmdHandlers) {
    await cmdHandlers[cmd](bot, msg, ...args)
}

这也保证cmd存在于 中cmdHandlers,但打字稿编译器无法处理。

标签: javascripttypescriptecmascript-6

解决方案


在情况 1 中,您需要为SUPPORTED_VALUESlike定义准确的类型{[key: string]: string}

const SUPPORTED_VALUES: {[key: string]: string} = {
  min_s: 'Minimum similarity',
  max_rc: 'Maximum result count'
}
const UNSUPPORTED_MSG =
  'Configurable values:\n' +
  Object.keys(SUPPORTED_VALUES)
    .map(k => `${k}: ${SUPPORTED_VALUES[k]}`)
    .join('\n')

案例 2,同样的案例 1,cmd可以是任何东西,但cmdHandlers只包括cmd1cmd2。您可以为cmd.ts模块定义类型,使其cmdHandlers成为具有任何属性名称的对象。

我认为没关系,因为在调用函数之前你有一个条件

// cmd.ts

async function cmd1(...args: any) { }
async function cmd2(...args: any) { }

const myExport: { [key: string]: (...args: any) => void } = {
  cmd1,
  cmd2,
}

export default myExport;

//

import cmdHandlers from './cmd'
// some code...
if (cmd in cmdHandlers) {
    await cmdHandlers[cmd](bot, msg, ...args)
}

推荐阅读