【问题标题】:Typescript: Access values from a nested global object | Typ "string" cannot be used as index type打字稿:从嵌套的全局对象访问值 |类型“字符串”不能用作索引类型
【发布时间】:2021-09-10 21:39:19
【问题描述】:

我有一个包含全局参数的对象。这些参数是我的组件使用的列表(数组或带有键的对象)。

某些参数由 2 个或更多组件共享。这些参数存储在GLOBALS.global[parameter-name] 中。 其他参数与组件相关,存放在GLOBALS.related[component-name][parameter-name]中。

const GLOBALS = {
    // Used by 2 or more components
    'global': {
        'colors': ['red', 'blue', 'green', 'yellow'],
        'icons': {
            'home': 'icon-home',
            'power': 'icon-power',
            'server': 'icon-server',
        }
    },
    // Related to components
    'related': {
        'component-1': {
            'direction': ['left', 'right', 'up', 'down'],
        },
        'component-2': {
            'direction': ['up', 'down'],
            'icon-set': {
                'arrow': { 'up': 'icon-arrow-up-1', 'down': 'icon-arrow-down-1' },
                'arrow-simple': { 'up': 'icon-arrow-up-2', 'down': 'icon-arrow-down-2' },
                'arrow-circle': { 'up': 'icon-arrow-up-3', 'down': 'icon-arrow-down-3' },
            }
        },
    }
};

对于某些用户输入检查,我需要获取这些参数列表并检查用户输入是否有效。

例如:

getGlobalParamList('color') // => returns ['red', 'blue', 'green', 'yellow']

getGlobalParamList('icons') // => returns ['home', 'power', 'server']

getGlobalParamList('isNotDefined') // => error message

我写了这个函数:

const getGlobalParamList = (paramName: string): string[] => {
    // Check if key paramName exist in GLOBALS
    if (GLOBALS.global.hasOwnProperty(paramName)) {
        const paramList = GLOBALS.global[paramName];
        if (Array.isArray(paramList)) return paramList;
        if (typeof paramList === 'object') return Object.keys(paramList);
        console.error(`Global parameter name ${paramName} is neither an array nor an object.`);
        return [];
    }.
    console.error(`Undefined global parameter name ${paramName}.`);
    return [];
}

然后我得到打字稿错误: 该元素隐式属于“any”类型,因为该类型的表达式不能用于索引类型。

我尝试向对象声明类型Global,但这不起作用:

type Globals = {
    [key: string]: string | object | string[] | object[]
}

当我将类型更改为 any 时,它可以工作,但是在 Visual Studio Code 中我的 GLOBALS 对象不再自动完成。

type Globals = {
    [key: string]: any
}

有人猜怎么处理吗?在下一步中,我想创建一个函数来访问与组件相关的参数,例如getComponentParamList(componentName: string, paramName: string) :string[]

【问题讨论】:

    标签: typescript


    【解决方案1】:

    我会说这是一种非常“javascript 方式”的做事方式。有一些方法可以让您的代码按原样工作,但它可能会变得不必要地复杂。

    您的问题的一个简单答案是在您的 tsconfig 文件中将 noImplicitAny 设置为 false。

    但是打字稿给你的部分安全性将会消失。

    另一种方式(我认为更好),一种更打字的方式,就是定义您正在使用的类型:

    type Icons = {
        [name: string]: string
    }
    type IconsSet = {
        [name: string]: {
            [category: string]: string
        }
    }
    type GlobalParameters = {
        colors?: string[];
        icons?: Icons;
    }
    type ComponentParameters = {
        direction?: string[];
        iconsSet?: IconsSet;
    }
    type GlobalVariables = {
        global?: GlobalParameters;
        related?: ComponentParameters;
    }
    
    const GLOBALS: GlobalVariables = {
        //...
    }
    

    编写代码可能需要更多时间,但从长远来看会好得多,而且实际上维护和更新速度更快。

    【讨论】:

    • 谢谢!我必须阅读一些关于自定义类型的东西,但我还没有找到一个很好的文档和一些例子。说[name: string]: string 而不是[key: string]: string 有什么区别吗?
    • 真的没有区别。 « 名称 » 或 « 键 » 只是您为便于阅读而为键指定的名称。声明后不会使用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-11-30
    • 2021-08-31
    • 1970-01-01
    • 2021-12-06
    • 2021-09-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多