Используя process.env в TypeScript

Как читать переменные среды node в TypeScript?

Если я использую process.env.NODE_ENV, у меня есть эта ошибка:

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

Я установил @types/node, но это не помогло.

Ответ 1

Нет никакой гарантии того, что (если таковые имеются) переменные среды будут доступны в процессе Node - переменная NODE_ENV - это просто соглашение, которое было популяризировано Express, а не что-то встроенное в сам Node. Таким образом, не имеет смысла включать его в определения типов. Вместо этого они определяют process.env следующим образом:

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

Это означает, что process.env может быть проиндексирован строкой, чтобы вернуть строку (или undefined, если переменная не установлена). Чтобы исправить ошибку, вам нужно использовать синтаксис индекса:

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

В качестве альтернативы, как указал jcalz в комментариях, если вы используете TypeScript 2.2 или новее, вы можете получить доступ к индексируемым типам, подобным определенным выше, используя синтаксис точки - в этом случае ваш код должен просто работать как есть.

Ответ 2

Установив @types/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, а также использует преимущества строковых литералов.

Примечание: приведенный выше фрагмент является дополнением модуля. Файлы, содержащие расширение модулей, должны быть модулями (в отличие от скриптов). Разница между модулями и сценариями заключается в том, что модули имеют как минимум один оператор импорта/экспорта.

Чтобы TypeScript рассматривал ваш файл как модуль, просто добавьте в него одну инструкцию import. Это может быть что угодно. Даже import * as ts from 'typescript' подойдет.

Ответ 3

просто добавьте перед использованием process.env.NODE_ENV следующие строки:

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

Ответ 4

После выполнения с машинописью последней версии:

npm install --save @types/node

Вы можете использовать process.env напрямую.

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

вы увидите ожидаемый результат, если вы установили NODE_ENV.

Ответ 5

Для этого вы можете использовать утверждение типа for this

Иногда вы окажетесь в ситуации, когда вы узнаете больше о значение, чем TypeScript. Обычно это происходит, когда вы знаете Тип некоторого объекта может быть более конкретным, чем его текущий тип.

Утверждения типа - это способ сказать компилятору "поверь мне, я знаю, что" Я делаю.' Утверждение типа похоже на приведение типов в других языках, но не выполняет никакой специальной проверки или реструктуризации данных. Не имеет воздействие во время выполнения и используется исключительно компилятором. TypeScript предполагает что вы, программист, выполнили какие-либо специальные проверки, которые вы необходимо.

Пример

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

В качестве альтернативы вы можете найти библиотеку, например env-var, более подходящую для этой конкретной цели -

"решение для загрузки и очистки переменных среды в node.js с правильной типизацией"

Ответ 6

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 dotenv от среды. Создайте файл 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!')
}

Примечание. Этот файл необходимо импортировать в ваш самый верхний файл, скорее всего, в файл src/index.ts с помощью import './config' (помещается перед всеми остальными импортами).

3. Проверьте переменные ENV и определите IProcessEnv

После объединения нескольких методов, описанных выше, мы можем добавить некоторые проверки времени выполнения для проверки 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.

Ответ 8

Вот короткая функция, которая гарантированно извлекает значение 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 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');

Ответ 9

Если вы хотите использовать .env в TypeScrype, вот простой способ (работает в bash):

1- Создайте файл .env в своем приложении.

2- Настройте свои npm-скрипты в package.json.

3- создайте файл. /dev.sh в каталоге проекта. set -a; source.env; set +a; npm run dev

используйте файл. /dev.sh для запуска вашего проекта.

Таким образом, переменные среды устанавливаются. Если вы установили PORT = 3000 в файле, вы можете получить к нему доступ, используя: process.env.PORT