-
Notifications
You must be signed in to change notification settings - Fork 12.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Try to preserve template-ness of string literal types where possible #41631
Comments
@ahejlsberg thoughts? |
This is already covered by #40707 with the caveat that you need to include |
@ahejlsberg cool, that is good to know. Can you elaborate how that would be breaking? These literals should still be assignable to The mentioned PR only applies to TypeScript though, not JavaScript. Is there any way to get the desired behavior in JS? |
We'd end up giving more specific types to variables with types inferred from initializers, which would be breaking. However, we could consider introducing widening and non-widening template literals akin to what we do for regular literal types (see #10676 and #11126 for context). |
I don't quite grasp the implications of this change but this seems like it might cover most of the use cases I have in mind. |
Now implemented in #41891. |
We tried this and it turned out to be a bit too breaky and didn't really model user expectations. We can reconsider something that avoids the pain that the last one added, but it's unclear what that would be. In the meantime, you can use Please limit discussion to useful additions, thoughts, or insights - no |
I've raised #42884 to request support for the |
In #43376 (now merged) we fix this as much as possible without introducing breaking changes: 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}`); // string
const id4 = `foo.bar.${someString}` as const;
const t4 = takesLiteral(id4); // string Note the use of |
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
Both
id4
and the string passed to the third call oftakesLiteral
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}
, notstring
like we currently do.Checklist
My suggestion meets these guidelines:
The text was updated successfully, but these errors were encountered: