-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Optional Iterator parameter "incorrectly" accepts spread arguments #48575
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
@bschnurr thanks 😄 |
So from other discussions, this "works" because spreading a string produces another set of strings for each optional position. This is two slightly undesirable behaviors combined into one harder-to-explain one. declare function takeOptionals(x?: number, y?: number): void;
declare const nums: Iterable<number>;
takeOptionals(...nums); // fine, but suspicious
declare function eatStrings(strs: Iterable<string>): void;
eatStrings("hello"); // almost never desirable to begin with? |
In most cases this is gonna be a forward-compatibility hazard, like if
This on the other hand is something I have used in cases where any sequence of characters is valid. In general TypeScript is pretty weak here as it lacks any way to specify Mind you it is certainly somewhat of a hazard that someone passes non-char strings, which is why whenever I use it I just go straight to flattening it to counter this exact problem: for (const str in input) {
for (const char in string) {
// feed char into the parser or whatever
}
} |
I was under the impression that spread calls weren’t even allowed unless 1. You’re spreading into a rest parameter or 2. The spread source is a tuple type matching the function’s parameter list. When did that change? |
I don't quite get what the defect is supposed to be? We also let you write the equivalent badFoo(strs1[0]);
badFoo([...strs2][0]); The behavior we actually work hard to exhibit here is that a spread is valid if all its possible arities result in valid calls, including the generally-allowed pattern of dynamic excess arity. Strings being iterables of themselves means it's always going to be possible to be "off by one" in terms of the number of times you spreaded something. I don't know how we can detect that unless we somehow said that string iterations produced some special supertype of string that itself was not iterable by convention, but then we'd need some way to undo that despecialization once they combined with other chars. |
This came from a bug in pyright/pylance that came down to a the spread hiding the fact that |
Ultimately I think it's a case where |
Doesn't have to be Iterable, function with an optional parameter (of any type) incorrectly accepts spread arguments:
|
Playground Link
The text was updated successfully, but these errors were encountered: