Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions src/validators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,12 @@ export function bool<T extends boolean = boolean>(spec?: Spec<T>) {
case 'true':
case 't':
case '1':
return true
return true as T
case false:
case 'false':
case 'f':
case '0':
return false
return false as T
default:
throw new EnvError(`Invalid bool input: "${input}"`)
}
Expand All @@ -58,20 +58,20 @@ export function num<T extends number = number>(spec?: Spec<T>) {
return makeValidator((input: string) => {
const coerced = +input
if (Number.isNaN(coerced)) throw new EnvError(`Invalid number input: "${input}"`)
return coerced
return coerced as T
})(spec)
}

export function str<T extends string = string>(spec?: Spec<T>) {
return makeValidator((input: string) => {
if (typeof input === 'string') return input
if (typeof input === 'string') return input as T
throw new EnvError(`Not a string: "${input}"`)
})(spec)
}

export function email<T extends string = string>(spec?: Spec<T>) {
return makeValidator((x: string) => {
if (EMAIL_REGEX.test(x)) return x
if (EMAIL_REGEX.test(x)) return x as T
throw new EnvError(`Invalid email address: "${x}"`)
})(spec)
}
Expand All @@ -81,7 +81,7 @@ export function host<T extends string = string>(spec?: Spec<T>) {
if (!isFQDN(input) && !isIP(input)) {
throw new EnvError(`Invalid host (domain or ip): "${input}"`)
}
return input
return input as T
})(spec)
}

Expand All @@ -97,15 +97,15 @@ export function port<T extends number = number>(spec?: Spec<T>) {
) {
throw new EnvError(`Invalid port input: "${input}"`)
}
return coerced
return coerced as T
})(spec)
}

export function url<T extends string = string>(spec?: Spec<T>) {
return makeValidator((x: string) => {
try {
new URL(x)
return x
return x as T
} catch (e) {
throw new EnvError(`Invalid url: "${x}"`)
}
Expand All @@ -121,7 +121,7 @@ export function url<T extends string = string>(spec?: Spec<T>) {
export function json<T = any>(spec?: Spec<T>) {
return makeValidator<T>((x: string) => {
try {
return JSON.parse(x)
return JSON.parse(x) as T
} catch (e) {
throw new EnvError(`Invalid json: "${x}"`)
}
Expand Down
18 changes: 18 additions & 0 deletions tests/basics.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,24 @@ test('choices field', () => {
expect(() => cleanEnv({ FOO: 'hi' }, { FOO: str({ choices: 123 }) }, makeSilent)).toThrow()
})

test('choices typed', () => {
type Spec = {
NODE_ENV: 'production' | 'test' | 'development'
}

const environment = {
NODE_ENV: 'test',
}

const spec: Spec = cleanEnv(environment, {
NODE_ENV: str({
choices: ['production', 'test', 'development'],
}),
})

expect(spec.NODE_ENV).toEqual('test')
})

test('misconfigured spec', () => {
// Validation throws with different error if spec is invalid
// @ts-expect-error This misuse should be a type error
Expand Down