如何在TypeScript中读取节点环境变量?

如果我使用process.env。NODE_ENV我有这个错误:

Property 'NODE_ENV' does not exist on type 'ProcessEnv'

我已经安装了@types/node,但它没有帮助。


当前回答

1. 创建一个.env文件

# Contents of .env file
AUTHENTICATION_API_URL="http://localhost:4000/login"
GRAPHQL_API_URL="http://localhost:4000/graphql"

2. 将.env文件加载到进程中。Env和dotenv

我们可以利用dotenv来设置特定于环境的过程。env变量。创建一个名为config的文件。t在你的src/目录中,并按如下方式填充:

// Contents of src/config.ts

import {config as configDotenv} from 'dotenv'
import {resolve} from 'path'

switch(process.env.NODE_ENV) {
  case "development":
    console.log("Environment is 'development'")
    configDotenv({
      path: resolve(__dirname, "../.env.development")
    })
    break
  case "test":
    configDotenv({
      path: resolve(__dirname, "../.env.test")
    })
    break
  // Add 'staging' and 'production' cases here as well!
  default:
    throw new Error(`'NODE_ENV' ${process.env.NODE_ENV} is not handled!`)
}

注意:这个文件需要导入到最顶层的文件中,可能是src/index文件。Ts通过import '。/config'(放置在所有其他导入之前)

3.检查ENV变量并定义IProcessEnv

在组合了上面的几个方法之后,我们可以添加一些运行时检查,以确保我们声明的IProcessEnv接口反映了在. ENV中设置的ENV变量。*文件。下面的内容也可以保存在src/config.ts中

// More content in config.ts
const throwIfNot = function<T, K extends keyof T>(obj: Partial<T>, prop: K, msg?: string): T[K] {
  if(obj[prop] === undefined || obj[prop] === null){
    throw new Error(msg || `Environment is missing variable ${prop}`)
  } else {
    return obj[prop] as T[K]
  }
}
// Validate that we have our expected ENV variables defined!
['AUTHENTICATION_API_URL', 'GRAPHQL_API_URL'].forEach(v => {
  throwIfNot(process.env, v)
})

export interface IProcessEnv {
  AUTHENTICATION_API_URL: string
  GRAPHQL_API_URL: string
}

declare global {
  namespace NodeJS {
    interface ProcessEnv extends IProcessEnv { }
  }
}
   

这将为我们提供适当的智能感知/tslint类型检查,以及部署到各种环境时的一些理智。

注意,这也适用于ReactJS应用程序(而不是NodeJS服务器应用程序)。你可以省略步骤(2),因为这是由create-react-app处理的。

其他回答

只需对process.env.YOUR_VAR进行类型转换

例子:

mongoose
  .connect(String(process.env.MONGO_URL), {
    useNewUrlParser: true,
    useFindAndModify: false
  })
  .then(() => console.log('DB connected'))
  .catch((err: any) => console.error(err));

重要提示:如果你有一个web应用程序,你正在使用webpack。定义流程。Env在你的窗户上,那么这些就是你要找的类型:

declare namespace process {
    let env: {
        // this is optional, if you want to allow also
        // other values than the ones listed below, they will have type 
        // string | undefined, which is the default
        [key: string]: string
        commit_hash: string
        build_time: string
        stage: string
        version: string
        // ... etc.
    }
}

对我有用的是,无论我想在哪里使用过程。我首先导入dotenv并在它上面调用config()。另外,记得附加!最后,确保在.env文件中定义了该属性

从'dotenv'导入dotenv; dotenv.config (); export const YOUR_ATTRIBUTE = process.env.YOUR_ATTRIBUTE!;

我写了一个模块来简化它。它没有依赖关系,所以是相当轻量级的。它也适用于dotenv,您可以传递一个自定义进程。Env到Env .from函数,如果需要的话。

在一些回答中已经提到了它,但这里有一个例子:

使用yarn/npm安装:

npm install env-var --save

然后读取变量:

import * as env from 'env-var'

// Read NODE_ENV and verify that:
// 1) it is set using the required() function
// 2) it is either 'dev' or 'prod'
// 3) throw a runtime exception if conditions #1 or #2 fail
const environment = env.get('NODE_ENV').required().asEnum(['dev', 'prod'])

// Intellisense will suggest 'dev' or 'prod'
if (environment === 'dev') {
  console.log('yep, this is dev')
} else {
  console.log('looks like this is prod')
}

或另一个:

import { get } from 'env-var'

// Read the GitHub token. It could be undefined
const githubToken = get('GITHUB_TOKEN').asString()

// Read MAX_CONCURRENCY, or default to 5. Throw an error if it's
// not set to a positive integer value
const concurrencyLimit = get('MAX_CONCURRENCY').default(5).asIntPositive()

function callGitApi (token: string, concurrency: number) { /* implementation */ }

// TS Error: Argument of type 'string | undefined' is not assignable to
// parameter of type 'string'.
callGitApi(githubToken, concurrencyLimit)

并不能保证在Node进程中可用的环境变量是什么(如果有的话)——NODE_ENV变量只是一个由Express推广的约定,而不是Node本身内置的东西。因此,将它包含在类型定义中实际上没有意义。相反,他们定义过程。这样的环境:

export interface ProcessEnv {
    [key: string]: string | undefined
}

这意味着这个过程。Env可以用字符串进行索引,以便返回字符串(如果没有设置变量,则为undefined)。要修复你的错误,你必须使用索引语法:

let env = process.env["NODE_ENV"];

或者,正如jcalz在评论中指出的那样,如果你使用的是TypeScript 2.2或更新版本,你可以使用点语法访问上面定义的可索引类型——在这种情况下,你的代码应该可以正常工作。