envalid icon indicating copy to clipboard operation
envalid copied to clipboard

fix: validator spec functions return their generic type

Open harrim91 opened this issue 4 years ago • 3 comments

I've been having an issue where the validator spec functions (str()etc.) don't return the correct type when passed a generic.

An example:

import { cleanEnv, str } from 'envalid';

type LogLevel = 'info' | 'error';

const env = cleanEnv(process.env, {
  LOG_LEVEL: str<LogLevel>(),
});

The return value of cleanEnv here is Readonly<{ LOG_LEVEL: string } & CleanedEnvAccessors>.

I would expect it to be Readonly<{ LOG_LEVEL: LogLevel } & CleanedEnvAccessors>.

If you add in a generic to cleanEnv, it highlights the problem further:

import { cleanEnv, str } from 'envalid';

type LogLevel = 'info' | 'error';

type Env = {
  LOG_LEVEL: LogLevel;
};

const env = cleanEnv<Env>(process.env, {
  LOG_LEVEL: str<LogLevel>(),
});

The line LOG_LEVEL: str<LogLevel>() gives a TypeScript error:

Type 'ValidatorSpec<string>' is not assignable to type 'ValidatorSpec<LogLevel>'.
  Type 'string' is not assignable to type 'LogLevel'.

So str<LogLevel>() is returning type ValidatorSpec<string> when I would expect it to return ValidatorSpec<LogLevel>.

This PR fixes the issue by just passing the generic type into the underlying makeValidator function so that the returned validator spec has the correct type.

harrim91 avatar Feb 02 '22 09:02 harrim91

Hi @harrim91 thanks for the PR! I can't figure out why the type T is not being inferred correctly by makeValidator()– when I tested #146 I'm quite sure it was working, but that was some months ago now. Which version of TS are you using?

I'll give this a spin on your same TS version and see if I can repro. Either way the diff looks sensible

af avatar Feb 04 '22 04:02 af

Hi @af

It's been happening for a while for me on various projects. I've been using type assertions to get around it, but thought I would take a deeper look. When I installed my local clone of the project with my changes, it fixed the issue.

The example I gave, I tested with 4.5.5.

tsconfig.json:

{
  "compilerOptions": {
    "target": "es2015",
    "module": "commonjs",
    "strict": true,
    "esModuleInterop": true
  }
}

harrim91 avatar Feb 04 '22 10:02 harrim91

Hey @harrim91 I was not able to repro the error you're seeing on latest main. Could you install 7.3.0-beta.1 (just published!) and let me know if that works better for you?

af avatar Feb 07 '22 03:02 af

I think https://github.com/af/envalid/pull/194 solves the same problem here, if you're still seeing the problem please open a new issue 🙏

af avatar Jan 10 '23 05:01 af