Skip to content

Try to preserve template-ness of string literal types where possible #41631

Closed
@AlCalzone

Description

@AlCalzone

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

Playground

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.

Metadata

Metadata

Assignees

Labels

FixedA PR has been merged for this issueSuggestionAn idea for TypeScript

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions