I have a union of a bunch of different strings, which represent all the translation keys supported by the application. They are written in a standardized form, with '.''s as separators. For example:
type Keys = 'foo.bar' | 'baz.bar' | 'fail.error';
I would like to derive from that union another union, which contains all the root strings that end in .bar. So for this example, the desired output is 'foo' | 'baz'
My best solution so far is as follows, but it requires me to always explicitly state the string as a parameter to the generic:
type Namespace<T extends string = string> = `${T}.bar` extends Keys ? T : never;
const example0: Namespace<'foo'> = 'foo'; // Allowed, but i had to explicitly give the type
const example1: Namespace<'notFound'> = 'notFound'; // Correctly gives an error
I would like to be able to do the following, but my current version results in an error on each line:
const example2: Namespace = 'foo'; // Should be allowed, but isn't
const example3: Namespace = 'baz'; // Should be allowed, but isn't
const example4: Namespace = 'fail'; // Should be an error
const example5: Namespace = 'notFound'; // Should be an error
Is there a better way i can do this type?