Skip to content

Commit

Permalink
Fix issue af#139, validator return type is too broad (af#146)
Browse files Browse the repository at this point in the history
  • Loading branch information
jkomyno authored and tuannm151 committed Jul 1, 2024
1 parent 5ee1a11 commit 6341614
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 9 deletions.
18 changes: 9 additions & 9 deletions src/validators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,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 @@ -59,20 +59,20 @@ export function num<T extends number = number>(spec?: Spec<T>) {
return makeValidator((input: string) => {
const coerced = parseFloat(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 @@ -82,7 +82,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 @@ -98,7 +98,7 @@ export function port<T extends number = number>(spec?: Spec<T>) {
) {
throw new EnvError(`Invalid port input: "${input}"`)
}
return coerced
return coerced as T
})(spec)
}

Expand All @@ -107,7 +107,7 @@ export function url<T extends string = string>(spec?: Spec<T>) {
try {
// @ts-expect-error TS doesn't acknowledge this API by default yet
new URL(x)
return x
return x as T
} catch (e) {
throw new EnvError(`Invalid url: "${x}"`)
}
Expand All @@ -123,7 +123,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

0 comments on commit 6341614

Please sign in to comment.