When working with TypeScript, there isn't a specific type that corresponds to "all strings except for 'options'". This concept would require the use of negated types, which have been suggested in issues like microsoft/TypeScript#4196. However, TypeScript currently does not support negated types, so achieving this specific requirement is not possible at the moment.
To work around this limitation, you can utilize generic types and constraints. By defining a generic type like Options<T>
and then using it as a constraint on another type, you can emulate the desired behavior. Additionally, creating a helper function to infer the generic type argument T
can simplify the process. Although directly assigning values like const o: Options = {...}
may not work as intended, options({...}) could provide a similar effect with minor differences.
The solution involves utilizing conditional types to filter out "options" from any string literal type in T
. For example, the
Exclude<T, "options">
utility type can be used for this purpose:
interface Options<T extends string> {
configNames: Exclude<T, "options">
}
You can further refine the definition to exclude the base type string
, preventing scenarios where {configNames: someRandomString}
might inadvertently include "options":
interface Options<T extends string> {
configNames: string extends T ? never : Exclude<T, "options">
}
A helper function like this can streamline the implementation:
const options = <T extends string>(o: Options<T>) => o;
By testing the function using examples like
const bad = options({ configNames: 'options' })
and
const good = options({ configNames: 'somethingElse' })
, you can verify the validation logic in place. While this method differs slightly from the original approach, it offers a feasible way to achieve the desired functionality.
Link to code playground