Reputation: 824
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
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