首页 > 解决方案 > 获取元素隐式具有“任何”类型,因为“数字”类型的表达式不能用于索引类型错误

问题描述

我编写了以下代码,尽量避免使用 switch/case 或 if 语句:

function getReason(reasonNumber: number) {
    let fn;

    const reasons = {
        0: function() {
            return "Activation"
        },
        1: function() {
            return "Downgrade"
        },
        2: function() {
            return "Upgrade"
        },
        3: function() {
            return "Cancellation"
        },
        4: function() {
            return "Incompatibility"
        }
    }

    fn = reasons[reasonNumber]

    return fn();
}

问题是我收到一个 TypeScript 错误fn = reasons[reasonNumber],错误是:

Element implicitly has an 'any' type because expression of type 'number' can't be used to index type '{ 0: () => string; 1: () => string; 2: () => string; 3: () => string; 4: () => string; }'.

No index signature with a parameter of type 'number' was found on type '{ 0: () => string; 1: () => string; 2: () => string; 3: () => string; 4: () => string; }'.

我尝试阅读有关可索引类型的信息,但我不明白如何在这种情况下使用它们。希望可以有人帮帮我!提前致谢!

标签: typescript

解决方案


尽管错误本身并不完全清楚,但我相信这是因为您有可能getReason使用不受支持的号码(任何高于 4 的号码)拨打电话。如果这要运行,它会出错,因为 undefined 不是函数。

在此函数中处理它的最安全方法是只允许特定数字:

function getReason(reasonNumber: 0 | 1 | 2 | 3 | 4) {
    let fn;

    const reasons = {
        0: function() {
            return "Activation"
        },
        1: function() {
            return "Downgrade"
        },
        2: function() {
            return "Upgrade"
        },
        3: function() {
            return "Cancellation"
        },
        4: function() {
            return "Incompatibility"
        }
    }

    fn = reasons[reasonNumber]

    return fn();
}

getReason(1) // allowed
getReason(5) // not allowed

这可能只是将类型错误移动到getReason调用位置。如果您愿意,可以在内部处理错误或提供合理的后备值:

function getReason(reasonNumber: number): string {
    const reasons: Record<string, () => string> = {
        0: function() {
            return "Activation"
        },
        1: function() {
            return "Downgrade"
        },
        2: function() {
            return "Upgrade"
        },
        3: function() {
            return "Cancellation"
        },
        4: function() {
            return "Incompatibility"
        }
    }

    if (reasons[reasonNumber]) {
      const fn = reasons[reasonNumber]
      return fn()
    } else {
      // Either handle the error, or return a default...
      throw new Error('')
    }
}

推荐阅读