Search code examples
typescript

Type for "every possible string value except ..."


Is it possible to define a type that may have every string-value assigned except a few specified ones? I would like to express something along the lines of this (non-compiling) example:

type ReservedNames = "this" | "that"
type FooName = string - ReservedNames;
const f1 : FooName = "This" // Works
const f2 : FooName = "this" // Should error

Solution

  • This isn't currently possible in TypeScript, however you can create a generic type that can handle many of the practical use cases if you add the concrete string value as a parameter of FooName.

    type ReservedNames = "this" | "that"
    type NotA<T> = T extends ReservedNames ? never : T
    type NotB<T> = ReservedNames extends T ? never : T
    type FooName<T> = NotA<T> & NotB<T>
    
    const f1: FooName<'This'> = 'This' // works
    const f2: FooName<'this'> = 'this' // error
    
    const f3: FooName<string> = 'this' //error
    const f4: FooName<any> = 'this' // error
    const f5: FooName<unknown> = 'this' // error
    

    And in a function it works as expected if you make the function generic on the string value:

    function foo<T extends string> (v: FooName<T>) {
      ...
    }
    
    foo('this') // error
    foo('This') // works