You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Confusing 'never' return type when appending an empty array #9976
Expected behavior:
Accept this, and have the type inferencer postulate x:number[]. Alternatively, an error message along the lines of "cannot assign number to parameter {}" (because type inferencer could also assume x:undefined[]).
Actual behavior:
(with strictNullCheck)
error TS2345: Argument of type 'string' is not assignable to parameter of type 'never'.
This might be because of how never is documented as the "bottom" type (for functions that never return), but since the code isn't using the result expression, this is pretty confusing. Is this because the assumed type of x is never[]?
I tried looking for related issues, I feel like it's slightly related to empty tuple discussions, but not 100% sure.
Maybe there Is there something like noImplicitAny that will make sense for any[] instead? 🌹
Reacted by igorrmotta, Ankit Singhaniya, Seven, ekoneko, Aditya Chouhan, Christian Loyd Larazo, r-ndom-developer, Daniel Ferreira, meadowstream, Jay Tarwe and 7 more
Reacted by Rick Lancee, Vincent Cantin and Christian Loyd Larazo
Basarat Ali Syed (@basarat) it is called not setting --strictNullCheck 😉. I would say it is desirable behaviour that if you have said that you want to make sure you don't have null values, that the type system becomes more strict. You can of course be explicit about it (x: any[] = []) and it works.
Reacted by Ahmed, Marlon Barcarol, Telmo "Trooper", Prasanna Raj, darkantares, Francesco Bancalari, Ján Vorčák, Junhyuk Lee, sunitakarle23, Ryan Pfister and 14 more
Reacted by Alexandre Correa and Semo
Reacted by Basarat Ali Syed, Kien Pham, omarnemer, Ryan Pfister, Alexandre Correa and Guruprasad J Rao
Ryan Cavanaugh (@RyanCavanaugh) I've read through the related discussions and now I get the logic of why let a = [] is inferred as never[]. But prior to that, the compiler error message is not very helpful; it's quite difficult to understand what is going on and how to resolve the error.
Reacted by Trent, Zheeeng, Joe Lapp, Babak, Arjan, Marian Kleineberg, Wilhelm Klopp, Or Duan, Jason Axelson, Jamison Dance and 27 more
Reacted by Mathijs Segers, Conor Rice, Mike Lentini, Kevin Ross, Mark Robson, Leo Y. Li, Andrey Zenkov, the-unbearable-lightness-of-being, Yangzi Chen, Abdel and 2 more
Adam Kucharczyk (@108adams) - Your code example doesn't actually concat the rows. As concat returns a new array. By doing rows.concat(generateElements()); you aren't actually updating rows to contain generateElements(). Might be why this doesn't throw the error?
You'd need to say:
let rows: Element[] = [];
rows = rows.concat(generateElements());
I love how Typescript is still giving me an error:
"TS2345: Argument of type '{ style: { position: string; x: number; y: number; height: any; width: any; }; }' is not assignable to parameter of type 'never'."
Robert Penner (@robertpenner) I think it's because that was in a Vue file. I've found out that there's a few issues in integrating Vue with TypeScript.
Edit: scratch that, it's unlikely that was in a Vue component file, since I don't need to export functions in those. Although I was probably consuming that function within a Vue component and maybe that's what caused the issue.
[].concat(a,b);// <- not goodArray().concat(a,b)// <- okay
I have a use case that a, b are in the same type but one of them are also possible to be undefined. I want to merge them into an array without mutation... The firs expressional approach failed but the second functional approach not give me any error?!
I'm using this workaround since .concat is not happy to be undefined which is fine (it won't extend the array but just return a copy).
Reacted by 寸头哥, Sai Perchard, Mohit Tilwani, Yangzi Chen, Sebastian, Matt Chowning, Carlos Marte and sabercc
Here is a short list of every way I can think of writing this...
letfoo: string[]=['one','two','three'];// Bad - this will throw a compile error.letone: string[]=[].concat(...foo);// Goodlettwo: string[]=Array().concat(...foo);// Goodletthree: string[]=[];three.concat(...foo);// Goodletfour: string[]=([]asstring[]).concat(...foo);// Good - but throws an error in the playground because it thinks this the type annotation is JSX.// You must set JSX to "none" to remove the error.letfour: string[]=(<string[]>[]).concat(...foo);
Activity
Arnavion commentedon Jul 27, 2016
#8944
basarat commentedon Aug 5, 2016
Maybe there Is there something like
noImplicitAnythat will make sense forany[]instead? 🌹kitsonk commentedon Aug 5, 2016
Basarat Ali Syed (@basarat) it is called not setting
--strictNullCheck😉. I would say it is desirable behaviour that if you have said that you want to make sure you don't have null values, that the type system becomes more strict. You can of course be explicit about it (x: any[] = []) and it works.RyanCavanaugh commentedon Aug 5, 2016
#8944 covers why this is done
robertpenner commentedon May 25, 2017
Ryan Cavanaugh (@RyanCavanaugh) I've read through the related discussions and now I get the logic of why
let a = []is inferred asnever[]. But prior to that, the compiler error message is not very helpful; it's quite difficult to understand what is going on and how to resolve the error.108adams commentedon Aug 10, 2017
My question: why never in this:
but not in this:
EliRobinson commentedon Mar 28, 2018
Adam Kucharczyk (@108adams) - Your code example doesn't actually concat the rows. As concat returns a new array. By doing
rows.concat(generateElements());you aren't actually updating rows to containgenerateElements(). Might be why this doesn't throw the error?You'd need to say:
TAGC commentedon May 18, 2018
I love how Typescript is still giving me an error:
When I've clearly annotated the type:
I don't see anything wrong with that, and no errors display in VS Code, yet it won't compile. 😕
robertpenner commentedon Jun 20, 2018
David Fallah (@TAGC) I tried your code in TypeScript 2.9.1 and don't hit the
nevererror:https://agentcooper.github.io/typescript-play/?noImplicitAny=false&target=5#code/JYOwLgpgTgZghgYwgAgOJWAEwCrADYQDCA9uHKNAN4C+AUDAK4gJjCnIC2DerADgQGcAkiABKcEAHMIAClYEAysABeEAFzIQDDgCNoAGmRwNW3QeQ6T2vVACUVs1ADaAXWSVkUCGAZQQyVwBuZDpaCAAPXmIoMGRGZlZ2aTBcQREFCBY2EBlaZGRwhxt9POQATyKDUoFMxJAAdSwwAAtKqBL8mqzSAAkIYElmsDaO5HkIJVU22ns0DBx8IlIwchBoV3dShFIBWOa4PBgM7oam5uQAXmQuusbMFuQAemQAJkCtnb2Do9rsvoGhpdrr9ev1BrFnm8PiBdsh9odUhMVCgruNJihIe98tsYbFwgBGIHhZAAWjh32OtzOWOQONh4ReROQAGpyYdKdk7i0aXTYmVCVcyqS2T8Tv9wTzPuVGYKWSKOaCAWB3tD6QBZLBRUBgARArg8YD8CDCMQSaRyRbowwE60vWyS3HlDWYLXgXVXfV8NKmqSyNHIwz8wN2lX5AixHErChQAQadBYREkMjRjZXIK0UowaLIGS8grIYgwArO1062ybfL5LNQHN5oWFp2a4jagTlyilSu05araACAB0vAYAmaMnbnc7uzKBA0Y-HnaiAmAdQ0ACI4DoBMQ8AxICvRnP8oV82T4TBEVaOweKuVhafzwHL3PmmChhp-ap9weAO5nN+W5GPpWdBztQ9qXsBIQZvkXg+H4XbJmsMbvNQQA
TAGC commentedon Jun 20, 2018
Robert Penner (@robertpenner) I think it's because that was in a Vue file. I've found out that there's a few issues in integrating Vue with TypeScript.
Edit: scratch that, it's unlikely that was in a Vue component file, since I don't need to export functions in those. Although I was probably consuming that function within a Vue component and maybe that's what caused the issue.
leoyli commentedon Apr 4, 2019
I still have question on this:
I have a use case that
a,bare in the same type but one of them are also possible to beundefined. I want to merge them into an array without mutation... The firs expressional approach failed but the second functional approach not give me any error?!I'm using this workaround since
.concatis not happy to beundefinedwhich is fine (it won't extend the array but just return a copy).s-ong-c commentedon Aug 6, 2019
why type error const nextList = list.concat(parseInt(number));
danielmorell commentedon Mar 24, 2021
Here is a short list of every way I can think of writing this...