-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Confusing type error message in concat
#6594
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
Agreed. The interface Array<T> {
// ...
concat<U extends T[]>(...items: U[]): T[];
concat(...items: T[]): T[];
} Those declarations were written before we permitted union types and used a generic constraint to work around some other historical issues. We need to update the declaration to this instead: interface Array<T> {
// ...
concat(...items: (T | T[])[]): T[];
} This will also allow us to correctly check an argument list that mixes single elements and arrays, such as |
This is a good/simple correction that needs to happen (I figured I must have had a head cold Friday when the playground kept complaining to me about How about just "deprecating" const x = [1];
x.push(2, ...[3, 4]); Clear. Now, as for: var x = [1];
x = x.concat(2, [3, 4]); -OR- (my historical, personal problem with var x = [1];
x.concat(2, [3, 4]); // forgot that I have to assign the expression result back over x Ick. ... I don't like >
> [1].concat(2, [3])
[ 1, 2, 3 ]
>
> [1].concat(2, [3], [[4]])
[ 1, 2, 3, [ 4 ] ]
> |
@ahejlsberg, there is a subtle point there with what
should be a type error because JS would add just @SlurpTheo: I don't know how things are done in JS VMs, but a spread that gets translated to |
I'll take a crack at this issue! |
@ahejlsberg would removing the generic variant of |
So, the issue isn't simply that TypeScript isn't accepting enough input scenarios; it's that TypeScript as-is today is already type-incorrect when calling const x: number[][] = [[1]];
const y: number[][] = x.concat([2]); Execution-result in JavaScript (from Node.js v4.2.6 REPL): >
> x = [[1]]
[ [ 1 ] ]
> x.concat([2])
[ [ 1 ], 2 ]
> |
Hmm, the proposed fix doesn't actually address that either. |
Is there a solution to that problem that wouldn't introduce extra typing complexity? JS's handling of |
I discussed something with @RyanCavanaugh offline. I was wondering whether @sandersn's |
What would concat's this be if not Array? My first guess would be |
I had something like interface Array<T> {
concat<U, ArrayElement extends Array<U>>(this: ArrayElement[], ...args: (ArrayElement | ArrayElement[])[]): ArrayElement[];
} which partially almost works kinda-sorta. |
I don't think that buys us anything beyond Ander's first proposal. It just binds U locally instead of inheriting it from the containing class. |
Update Array.concat type signature to fix #6594
Thanks @LPGhatguy! |
If Why not be more restrictive/"limiting"/safe? interface Array<T> {
// ...
concat(...items: T[][]): T[];
} Has there been talk of creating a ~ let testStr = "ABCDEFG";
testStr[1] = "6"; // Ick, the 2nd character isn't updated
const testNumber = 1234;
testNumber[2]; // Ick, this returns undefined
let myNum = 1;
let myAnyString: any = "hi";
myNum += myAnyString; // Ick, my "number" variable contains "1hi" Not really sure how any such directive/flag would effect a definition file change like this, but seems similarish in my mind. |
@SlurpTheo I feel that would be the job of a linter like |
@SlurpTheo I prefer |
Typechecking this code:
will throw up with
This happens even without the
x =
assignment, and that shows that it would make more sense if the error was either of:or
The text was updated successfully, but these errors were encountered: