Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

is there a "is oneOf" in typescript?

I have the following code:

export type Environments = 'live' | 'test' | 'app' | 'localhost'
export const definedEnvironments: Environments[] = ['app', 'live', 'localhost', 'test']

and I have the following function:

export default function verifyEnvironment(env: Environments): boolean {
  return definedEnvironments.includes(env)
}

I am creating a command-line application with node and typescript, where the user has an input to write the environment, the user might input "live", "test", or even "ksvksdbvkjsdv".

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

So my role is to verify that the user input is correct, that’s why I created the function verifyEnvironment.

Now, when I use the function in my code as follows, typescript complains:

const environment = await waitForUserInput("enter the environment name: ")
if (!verifyEnvironment(environment)) {
  return console.error('Allowed options are: ' + definedEnvironments.join(', '))
}

it says:

Argument of type ‘string’ is not assignable to parameter of type
‘Environments’.

it happens in the line 2.

So typescript is correct, the user might input any string.

and I was reading the documentation, and I saw in the Using type predicates section that there’s a similar case to mine, they used the is operator to make a function which is used for validation.

Is there a way I can write something like this in typescript, or what is the solution?

export default function verifyEnvironment(env: Environments): env is oneOf Environments {
  return definedEnvironments.includes(env)
}

>Solution :

You’re trying to assert just env is Environments, but env shouldn’t be required to already be an Environments in that case.

You might also be interested in as const to avoid redundancy, and the singular Environment for consistency:

const definedEnvironments = ['live', 'test', 'app', 'localhost'] as const
type Environment = typeof definedEnvironments[number]

function verifyEnvironment(env: string): env is Environment {
  return (definedEnvironments as readonly string[]).includes(env)
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading