import type {IsStringLiteral} from 'type-fest';
type A = IsStringLiteral<'foo'>;
//=> true
type B = IsStringLiteral<string>;
//=> false
// String types with infinite set of possible values return `false`
type C = IsStringLiteral<`on${string}`>;
//=> false
type D = IsStringLiteral<Uppercase<string>>;
//=> false
type E = IsStringLiteral<'foo' | 'bar' | 'baz'>;
//=> true
type F = IsStringLiteral<'sm' | 'md' | 'lg' | `${number}px`>;
//=> boolean
import type {IsStringLiteral} from 'type-fest';
type StringLength<S extends string, Counter extends never[] = []> =
IsStringLiteral<S> extends true
? S extends `${string}${infer Tail}`
? StringLength<Tail, [...Counter, never]>
: Counter['length']
: number; // return `number` for non-literal string types
type L1 = StringLength<'foobar'>;
//=> 6
type L2 = StringLength<Lowercase<string>>;
//=> number
type L3 = StringLength<`${number}`>;
//=> number
Returns a boolean for whether the given type is a
stringliteral type.The implementation of this type is inspired by the trick mentioned in this StackOverflow answer.