在TypeScript中使用process.env

时间:2017-07-19 15:11:23

标签: node.js typescript

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

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

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

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

17 个答案:

答案 0 :(得分:9)

无法保证Node流程中可用的环境变量(如果有的话) - NODE_ENV变量只是Express推广的一种约定,而不是内置的内容到节点本身。因此,将它包含在类型定义中是不合理的。相反,they define process.env like this

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

这意味着process.env可以使用字符串编制索引以获取字符串(如果变量未设置,则为undefined)。要修复错误,您必须使用索引语法:

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

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

答案 1 :(得分:6)

在使用之前添加process.env.NODE_ENV后续行:

declare var process : {
  env: {
    NODE_ENV: string
  }
}

答案 2 :(得分:4)

使用打字稿最新版本执行后:

npm install --save @types/node

您可以直接使用process.env

console.log(process.env["NODE_ENV"])

如果您设置了NODE_ENV,将会看到预期的结果。

答案 3 :(得分:4)

您可以为此使用Type Assertion

  

有时候,您最终会遇到以下情况:   比TypeScript更有价值。通常,当您知道   某些实体的类型可能比其当前类型更具体。

     

类型断言是一种告诉编译器“相信我的方法,我知道   我在做。”类型断言就像其他语言中的类型转换一样,   但不执行数据的特殊检查或重组。它没有   对运行时的影响,仅由编译器使用。 TypeScript假定   您,程序员,已经对您执行了任何特殊检查   需要。

示例

const nodeEnv: string = (process.env.NODE_ENV as string);
console.log(nodeEnv);

或者,您可能会发现诸如env-var之类的库更适合于此特定目的-

“使用正确的类型在node.js中加载和清理环境变量的解决方案”

答案 4 :(得分:4)

在项目中安装@type/node后,您可以准确地告诉TypeScript process.env中存在哪些变量:

environment.d.ts

declare global {
  namespace NodeJS {
    interface ProcessEnv {
      GITHUB_AUTH_TOKEN: string;
      NODE_ENV: 'development' | 'production';
      PORT?: string;
      PWD: string;
    }
  }
}

此方法将为您提供IntelliSense,并且还利用了字符串文字类型。

  

注意:上面的代码段是模块增强。包含模块扩展的文件必须是 modules (与 scripts 相对)。模块和脚本之间的区别在于,模块至少具有一个import / export语句。

     

为了使TypeScript将文件视为模块,只需向其中添加一个import语句。可以是任何东西。甚至import * as ts from 'typescript'都可以。

答案 5 :(得分:3)

对我有用的是,在我想使用process.env的任何地方,我首先导入dotenv并在其上调用config()。另外,请记住在末尾附加!,并确保在.env文件中定义了属性

import dotenv from 'dotenv';

dotenv.config();

export const YOUR_ATTRIBUTE = process.env.YOUR_ATTRIBUTE!;

答案 6 :(得分:1)

这是一个简短的函数,可以保证将process.env值作为字符串提取-否则引发错误。

对于更强大(但也更大)的功能,这里的其他人建议使用env-var

/**
 * Returns value stored in environment variable with the given `name`.
 * Throws Error if no such variable or if variable undefined; thus ensuring type-safety.
 * @param name - name of variable to fetch from this process's environment.
 */
export function env(name: string): string {
  const value = process.env[name];

  if (!value) {
    throw new Error(`Missing: process.env['${name}'].`);
  }

  return value;
}

然后您应该可以编写如下代码:

let currentEnvironment: string;
currentEnvironment = env('NODE_ENV');

答案 7 :(得分:1)

  1. 通过运行 npm i @types/node 安装 @types/node
  2. "types": [ "node" ] 添加到 compilerSection 部分的 tsconfig.json 文件中。

答案 8 :(得分:1)

对于任何来这里专门为React项目寻求答案的人,您的变量名应以REACT_APP_

开头

在此处了解更多信息:https://facebook.github.io/create-react-app/docs/adding-custom-environment-variables

答案 9 :(得分:1)

1。创建一个.env文件

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

2。使用.env

process.env文件加载到dotenv

我们可以利用dotenv来设置特定于环境的process.env变量。在config.ts目录中创建一个名为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!`)
}

注意: 该文件需要导入到您最顶层的文件中,可能是通过 import './config'(放在在所有其他进口商品之前

3。检查ENV变量并定义IProcessEnv

在结合了上述几种方法之后,我们可以添加一些运行时检查是否完整,以确保声明的IProcessEnv接口反映出.env.*文件中设置的ENV变量。以下内容也可以位于src/config.ts

// More content in config.ts
const throwIfNot = <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 { }
  }
}

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

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

答案 10 :(得分:0)

您还可以使用类型保护功能。这样的东西,返回类型为

parameterName is string

例如

function isEnvVarSpecified(envVar: string | undefined): envVar is string {
  if(envVar === undefined || envVar === null) {
    return false;
  }
  if(typeof envVar !== 'string'){
    return false;
  }
  return true;
}

然后可以将其称为类型防护:

function myFunc() {
  if(!isEnvVarSpecified(process.env.SOME_ENV_VAR')){
      throw new Error('process.env.SOME_ENV_VAR not found')
  }
  // From this point on the ts compiler won't complain about 
  // process.env.SOME_ENV_VAR being potentially undefined
}

答案 11 :(得分:0)

对先前的回答进行补充,并在一段时间后解决了这个问题,甚至安装了@ types / node,我发现了这个answer。简而言之,只需运行一个重新加载窗口即可:

“ ...尽管,如果打字稿语言服务器仍使用tsconfig的先前版本,则可能必须重新启动它。要在VS Code中执行此操作,请执行Ctrl+Shift+PReload WindowTypeScript: Restart TS server(如果有)...“

答案 12 :(得分:0)

在您的打字稿项目中使用节点process.env的最佳和最简单的方法是,首先使用tsc进行编译,然后使用提供您的ENV变量的节点运行已编译的JavaScript文件。示例(首先确保tsconfig.ts是输出目录所需的,也是编译文件的名称,我以dist作为输出目录,以index.js作为示例):

cd my-typescriptproject
tsc
NODE_ENV=test node ./dist/index.js

答案 13 :(得分:0)

如果要在TypeScrype中使用.env,这是一种简单的方法(在bash中有效):

1-在您的应用程序中创建一个.env文件。

2-在package.json中设置您的npm脚本。

3-在项目目录中创建一个./dev.sh文件。 set -a; source .env; set +a; npm run dev

使用./dev.sh文件运行您的项目。

通过这种方式设置环境变量。如果在文件中设置PORT = 3000,则可以使用以下命令访问它: process.env.PORT

答案 14 :(得分:0)

这是我使用 envalid 的解决方案(在 Node.js 中验证和访问环境变量)

import { str, cleanEnv } from 'envalid'

const env = cleanEnv(process.env, {
  clientId: str(),
  clientSecret: str(),
})

// and now the env is validated and no longer undefined
const clientId = env.clientId

答案 15 :(得分:0)

重要提示:如果您有一个网络应用程序并且您正在使用 webpack.DefinePlugin 在您的窗口上定义 process.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.
    }
}

答案 16 :(得分:-1)

只需键入过程即可。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));