Is there a way to invert the type of a template literal?

364 Views Asked by At

For example, we have a string that must start with /:

type StartsWithSlash = `/${string}`

How can we invert this type? Meaning that the type should accept any string as long as the first character is not /.

1

There are 1 best solutions below

0
T.J. Crowder On

I think it depends on where/how you want to use it. For instance, you can do it with a function parameter:

type StartsWithSlash = `/${string}`;

type OppositeOf<TypeToNarrow, TypeToNegate> = TypeToNarrow extends TypeToNegate ? never : TypeToNarrow;

function example<T extends string>(param: OppositeOf<T, StartsWithSlash>) {
    console.log(param);
}

example("works");
example("/fails");  // <== Error as desired

Caveat ─ this only works with arguments with literal types. The above have literal types because they're literals, but in the example below there is no error, because TypeScript infers str's type as string.

let str = "/should-fail-but-doesn't";
example(str); // <== No error

Playground link

This solution works when the type is for a function parameter, though that is a fairly special and restricted case. I don't think you can do it more generally.


This question asks for a similar (though different) thing, and its answer (use a branded type) may be a more reliable solution, depending on how you want to use this.