is there a "is oneOf" in typescript?

Advertisements

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".

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)
}

Leave a ReplyCancel reply