首页 > 解决方案 > 通过打字稿中的动态键获取对象值

问题描述

我试图根据值仅导出配置对象的 1 个process.env.NODE_ENV值,因此我试图获取configEnvs变量的值,configEnvs['local']但尝试访问对象的一个​​键时出现错误。我尝试使用 anenum作为键来设置它的可能值,但它没有用。

我目前正在尝试获取键值,使用getKeyValue该键值获取对象并将键值限制为仅对象的键,但随后它说string我试图传递的键不可分配给可能的选项。

const getKeyValue = <T, K extends keyof T>(obj: T, key: K) => obj[key];

const { NODE_ENV, REACT_APP_ENV } = process.env;

interface IConfigEnv {
  DB_DNS: string;
}
interface IConfig {
  local: IConfigEnv;
  development: IConfigEnv;
  production: IConfigEnv;
}

let configEnvs: IConfig = {
  local: {
    DB_DNS: "https://localhost:4000",
  },

  development: {
    DB_DNS: "https://my-dev.web.com",
  },

  production: {
    DB_DNS: "https://api.web.com",
  },
};

const nodeEnv = REACT_APP_ENV || NODE_ENV || "development";
const config: IConfigEnv = getKeyValue(configEnvs, nodeEnv);

export default config; 

我收到此错误声明config

Argument of type 'string' is not assignable to parameter of type '"development" | "production" | "local"'.

标签: javascriptreactjstypescript

解决方案


更安全的方法是使用类型保护或类型断言函数,如下所示:

interface IConfigEnv {
  DB_DNS: string;
}
interface IConfig {
  local: IConfigEnv;
  development: IConfigEnv;
  production: IConfigEnv;
}

const acceptableEnvs = [ "local", "development", "production" ];
function assertEnv(k: any): asserts k is keyof IConfig {
  if (typeof k !== "string" || !acceptableEnvs.includes(k)) {
    throw new Error(
      `Environment must be one of '${acceptableEnvs.join("', '")}'. You passed '${k}'.`
    );
  }
}

const config: IConfig = {
  local: {
    DB_DNS: "https://localhost:4000",
  },

  development: {
    DB_DNS: "https://api-dev.web.com",
  },

  production: {
    DB_DNS: "https://api.web.com",
  },
};

const nodeEnv = process.env.REACT_APP_ENV || process.env.NODE_ENV || "development";

assertEnv(nodeEnv);

export default config[nodeEnv];

请注意,如果您只是简单地对错误的运行时值进行类型转换,此解决方案会明确说明您的应用程序会引发的错误,从而为您提供更多的控制和对流程的确定性。也就是说,如果/当它被抛出时,你仍然必须确保对该错误进行处理


推荐阅读