Description
Search Terms
template literal preserve
Suggestion
Now that we have template literal types, I would love to have the ability to apply them to string template literals.
Use Cases
This would be really useful in the ioBroker type declarations where we try to infer the object types returned by some methods from the given IDs. These IDs can be directly specified in the method calls, but are in reality often built from multiple parts.
A dumbed down example is shown in the following examples:
Examples
declare function takesLiteral<T extends string>(literal: T): T extends `foo.bar.${infer R}` ? R : unknown;
const t1 = takesLiteral("foo.bar.baz"); // "baz"
const id2 = "foo.bar.baz";
const t2 = takesLiteral(id2); // "baz"
declare const someString: string;
const t3 = takesLiteral(`foo.bar.${someString}`); // expected: string, actual: unknown
const id4 = `foo.bar.${someString}`;
const t4 = takesLiteral(id4); // expected: string, actual: unknown
Both id4
and the string passed to the third call of takesLiteral
are string constants that are created with a template literal. TypeScript should be able to preserve that literal-ness, since it already knows we're feeding a string into a template string.
This means we could work with literals of type foo.bar.${string}
, not string
like we currently do.
Checklist
My suggestion meets these guidelines:
- This wouldn't be a breaking change in existing TypeScript/JavaScript code
- This wouldn't change the runtime behavior of existing JavaScript code
- This could be implemented without emitting different JS based on the types of the expressions
- This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, etc.)
- This feature would agree with the rest of TypeScript's Design Goals.