简体   繁体   English

节点 Typescript:使用括号表示法时未定义 JSON

[英]Node Typescript: JSON undefined when using bracket notation

I have a node project with typescript and I'm trying to read the right url from a json object.我有一个带有 typescript 的节点项目,我正在尝试从 json ZA8CFDE6331BD59EB26ACZF96 读取正确的 url。 However when using square bracket notation I get undefined.但是,当使用方括号表示法时,我得到未定义。

{
    "env":"dev",
    "dev":{
        "url": "url1"
    },
    "aws":{
        "url": "url2"
    }
}

For some reason this does not work:由于某种原因,这不起作用:

const url = config[config.env].url;

The code below accomplishes what I need, but it is not as flexible as the above and I want to understand why it does not work the other way.下面的代码完成了我所需要的,但它不像上面那样灵活,我想了解为什么它不能以其他方式工作。

const cenv:string = config.env;
    let url=null;
    if( cenv === "dev")
        url = config["dev"].url;
    else
        url = config["aws"].url;

This is my tsconfig file:这是我的 tsconfig 文件:

{
  "compilerOptions": {
    "lib": [
      "es2017"
    ],
    "moduleResolution": "node",
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "sourceMap": true,
    "target": "es2017",
    "outDir": "lib",
    "resolveJsonModule": true
  },
  "exclude": [
    "node_modules"
  ]
}

The json is imported to the project like so: json 被导入到项目中,如下所示:

import * as config from './config.json';

The reason this doesn't work is because Typescript infers the value for env to be of type string , which means it can be any string value.这不起作用的原因是因为 Typescript 将env的值推断为string类型,这意味着它可以是任何字符串值。 You can see this when you inspect typeof config :当您检查typeof config时,您可以看到这一点:

在此处输入图像描述

Because Typescript thinks that env can be any string value, it throws an error.因为 Typescript 认为env可以是任意字符串值,所以会抛出错误。 What would happen for example if you compiled this code, but then changed the env value to be "foobar"?例如,如果您编译了此代码,但随后将env值更改为“foobar”,会发生什么? The code would throw, and Typescript guards you from this.代码会抛出,并且 Typescript 会保护您免受此影响。

I'd suggest creating config folder我建议创建config文件夹

config/
  settings.dev.json
  settings.prod.json
  index.js

// index.js
module.exports = function(){
    switch(process.env.NODE_ENV){
        case 'development':
            return require('./settings.dev.json');

        case 'production':
            return require('./settings.prod.json');

        default:
            return {error or other settings};
    }
};

If you want to use approach you can do it this way:如果你想使用方法,你可以这样做:

enum Enivornment {
  Dev = "dev",
  Aws = "aws"
}

type Config = {
  "env": Enivornment,
} & {
  [key in Enivornment]: ConfigItem
}

// this will help you have all environments in sync
type ConfigItem = {
  "url": string
} 

const config: Config = {
    "env": Enivornment.Dev,
    [Enivornment.Dev]: {
        "url": "url1"
    },
    [Enivornment.Aws]:{
        "url": "url2"
    }
}

You can test it here .你可以在这里测试它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM