LGenzelis
LGenzelis

Reputation: 824

Typescript: type is any string except for a few exceptions

Is there a way in typescript to define a type which accepts anything except for a few things?

Consider this snippet:

type BagGuys = 'Voldemort' | 'Hitler';

type EveryoneElse = Exclude<string, BagGuys>; // this resolves to just string

function sayHi(name: EveryoneElse) {
  console.log(`Hi ${name}!`);
}

sayHi('Mark'); // Ok!

sayHi('Voldemort'); // Ok too, we'd like to have an error here  

I, of course, would like typescript to prevent me from saying hi to the bad guys.

Note: I understand why Exclude doesn't work here, I'm just using it to convey my intention

Upvotes: 2

Views: 2304

Answers (1)

LGenzelis
LGenzelis

Reputation: 824

This is a possible solution:

type BagGuys = 'Voldemort' | 'Hitler';


function sayHi<T extends string>(name: T extends BagGuys ? never : T) {
  console.log(`Hi ${name}!`);
}

sayHi('Mark'); // Ok
sayHi('Voldemort'); // Argument of type 'string' is not assignable to parameter of type 'never'.

Playground here.

I think this is as good as we can get until negated types is implemented. Feel free to upvote that PR btw :)

Note: I came up with this inspired by this similar question.

Note 2: for some reason, if I type the function with sayHi<T> instead of sayHi<T extends string>, this doesn't work. I guess it's a question for a different day.

Upvotes: 3

Related Questions