Skip to content

Instantly share code, notes, and snippets.

@azu
Last active July 1, 2024 01:20
Show Gist options
  • Save azu/b728c411b43e405757004fe1e5d9e777 to your computer and use it in GitHub Desktop.
Save azu/b728c411b43e405757004fe1e5d9e777 to your computer and use it in GitHub Desktop.
Type Safe env.ts
export type BaseEnvRecord = Record<
string,
{
value: string | undefined;
required: boolean;
defaultValue?: string;
}
>;
export type ReturnTypeOfCreateEnv<T extends BaseEnvRecord> = {
// If the value is required, it should be a string, otherwise it should be a string or undefined
[K in keyof T]: T[K]["required"] extends true ? string : string | undefined;
};
export const createEnv = <T extends BaseEnvRecord>(
envs: T,
): ReturnTypeOfCreateEnv<T> => {
const result = new Map<string, string | undefined>();
Object.entries(envs).forEach(([key, { value, required, defaultValue }]) => {
if (required && !value && !defaultValue) {
throw new Error(
`Missing required environment variable: ${key}, value: ${value === undefined ? "undefined" : `"${value}"`}`,
);
}
result.set(key, value || defaultValue);
});
return Object.fromEntries(result) as ReturnTypeOfCreateEnv<T>;
};
import { createEnv } from "./createEnv.ts":
export const env = createEnv({
/**
* Next.jsサーバ自体のローカルホストURL
*/
NEXT_PUBLIC_LOCALHOST_URL: {
value: process.env["NEXT_PUBLIC_LOCALHOST_URL"],
required: true,
defaultValue: "http://localhost:3000",
},
/**
* GraphQL APIのエンドポイントのURL
*/
NEXT_PUBLIC_GRAPHQL_API_ENDPOINT: {
value: process.env["NEXT_PUBLIC_GRAPHQL_API_ENDPOINT"],
required: true,
defaultValue: "http://localhost:4000/query",
},
/**
* ローカルの開発モードかどうか
*/
IS_DEVELOPMENT: {
value: process.env["IS_DEVELOPMENT"],
required: false,
defaultValue: "false",
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment