-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Support string literals as spread argument #51397
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
Comments
This is intentional. Duplicate of #39292 (comment). As mentioned in the other issue, intentionally wanting to spread a |
String spread is fine for ASCII stuff, but quickly goes off the rails for more complex characters. e.g. |
Well, that's a shame. Calling this feature "very rare" seems rather subjective, if not speculative. I was under the impression that TS tries to add type safety to JS, not remove features that might backfire when used carelessly. With that reasoning you might as well forbid half of JS's standard library. @RyanCavanaugh Emojis and other weird utf characters are always trouble when manipulating strings, this is not exclusive to spread syntax. You can shoot yourself in the same foot with pretty much any String method, or any other use case where strings are treated as Iterables (which TS does support!). And putting invisible whitespace in a string literal is pretty much exclusively useful for trolling coworkers… |
Every type error we issue is a subjective call of what is and isn't a good idea in JS. There's no bright line anywhere. |
Except that’s exactly what TS does, almost by definition. There is no undefined behavior in JS, but a lot of unintuitive behavior. See, e.g. #38471 |
@fatcerberus Anyway, I'm going to stop trying to argue my point here. I'm a bit disappointed with the offhanded dismissal of my proposal – it does not feel like there was any real attempt at objective consideration. Though of course I don't know all of TS's history and it is very possible that I'm biased. |
The relevant question is "if this feature is allowed by the type system, will it always do what most people expect it to?" In the case of At any rate, you can still cast the string literal (
Everything above having been said, what you're trying to do does, in fact, appear to work already: function fn(...args: string[]) { console.log(args); }
fn(..."abc"); // no error - prints a, b, c
const alphabet = [ ..."abcdefghijklmnopqrstuvwxyz" ]; // also no error
console.log(alphabet); // prints alphabet split by character |
We obviously put a lot of consideration into how this feature works when implementing it; re-enacting that design conversation with every user who disagrees is not scalable. We told you why the feature works the way it does, and that it was on purpose. You're welcome to offer a rebuttal and try to change our minds, but this is fundamentally a bug tracker, and if your suggestion boils down to "Your design outcome should have gone the other way" without raising novel points, there's not much else for me to say. |
This issue has been marked as a 'Duplicate' and has seen no recent activity. It has been automatically closed for house-keeping purposes. |
Suggestion
A tuple of characters can be concisely represented as a string literal – for example
"0123456789"
is a convenient representation of["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]
for many purposes. However when using the spread operator...
on a string literal, e.g. in a function call, TS2556 is raised with the message: "A spread argument must either have a tuple type or be passed to a rest parameter".My suggestion is therefor to allow string literals to be treated like string tuples in conjunction with the spread operator.
🔍 Search Terms
string literal, spread operator, spread string literal, spread characters, string as tuple
✅ Viability Checklist
My suggestion meets these guidelines:
⭐ Suggestion
When using the spread operator on a string literal it should work the same way as when it's used on a string tuple. E.g. the following expressions are equivalent in plain JS and thus should be supported the same way in TS:
📃 Motivating Example
I'm using
ts-pattern
to match keyboard events. For this example let's say I want to use it to control volume:For the +/- keys, this would increment/decrement the volume by 10%. When pressing a number key it should set the volume directly to the corresponding multiple of 10%.
Note that
ts-pattern
's.with
method takes any number of arguments for pattern matching and if any of the arguments matches the input calls the final argument as a function. Of the example above the fifth line does not work with current TS (4.8.4). I've tried the following variations, all of which fail type checking:However the following work:
You might call this a matter of convenience but I would argue that it improves readability in those cases where it comes in handy – and code readability could always be argued to be "just" a convenience.
💻 Use Cases
Whenever you want to hard code a tuple of characters it is easy to either use a string literal directly or spread it into an array, such as
This is quite universal and can be useful whenever you need a hard coded tuple of characters. Some examples:
"wasd"
(video game keyboard controls)RegExp
constructor).The text was updated successfully, but these errors were encountered: