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
Incorrect any displayed in type with noErrorTruncation: trueΒ #62032
typeT=[1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,'still good','now truncating']// type shows any in hover in place of 'still good' this is where the elision would be without noErrorTruncation
π Actual behavior
type shows any where the elision would have been without noErrorTruncation.
π Expected behavior
full type is shown.
Additional information about the issue
This is only in the display. type checking behaves correctly and indexing to that position shows the correct type.
But, truth to be told, noErrorTruncation is only documented to be, well, about error truncation - not about general type display in all sort of places (but I know it has, historically, been used by those too). The potential problem here is that this is somewhat at odds with the new expandable hovers (cc Gabriela Araujo Britto (@gabritto)) and I'd say it probably no longer should impact quick info (as it doesn't now).
This any gets a ... 4 more elided ... comment but that doesn't end up being printed and perhaps it should. That said, any being displayed in those truncating scenarios has always been slightly weird - and actually, IIRC, it can accidentally get leaked into generated .d.tswithout producing any errors about the inferred cyclic type not being fully serializable
Yes, the problem really is with the any. It is very confusing without the comment.
Agreed that noErrorTruncation having side effects outside of errors is weird and should be changed. That said, those side effects are often the difference between seeing what I need and having to create some indexed type just to figure out what is going on. From a user perspective it would be ideal if the expandable hovers could expand the elision. That seems like a fairly heavy lift on the implementation side.
Basically what Mateusz BurzyΕski (@Andarist) said above, but to reiterate, what I remember happening was that noErrorTruncation affecting hovers was a bit confusing for users and probably not intended. To add to that confusion, a long time ago I think we didn't truncate anything at all, and then we added truncation, and added noErrorTruncation, which was supposed to disable truncation in errors, but because the type printing code is shared, it ended up also disabling truncation in hovers (see #26238).
Now we have a setting specifically for truncation in hovers: #61662.
The elision comment on any shouldn't be missing, I agree that's a bug.
Do we know what the motivation for creating an any keyword node when noTruncation is true was? I'm waiting on the tests to finish after changing it always create the type reference node, hopefully that will provide more context
I took a closer look now, and I think producing the any is intentional.
The reason why the code exists as it does today is that, if we are printing a type for e.g. a codefix, we don't want to truncate the type, so in that context, we set the NodeBuilder.NoTruncation flag when printing a type. And if even with NodeBuilder.NoTruncation the type printer still hits its hard limit (of 100k characters I think), we don't want to produce the type node reference with an elision name (i.e. factory.createTypeReferenceNode(... ${types.length - i} more ..., /*typeArguments*/ undefined)), because then the code produced by the codefix will have a parsing error. So we instead produce an any with a comment, because that is a valid type.
Perhaps the root of the problem is that when a config has noErrorTruncation: true, we also set NodeBuilder.NoTruncation in typeToString, even if we're calling typeToString for hover or diagnostics, and in those cases we don't really need to produce an any because the type we print doesn't have to be valid. But then again, if we're printing a type for .d.ts emit, we do want to produce a valid type. So it's tricky.
Activity
typeholes commentedon Jul 10, 2025
This does not seem to happen in error messages
https://www.typescriptlang.org/play/?noErrorTruncation=true&ts=5.9.0-dev.20250709#code/C4TwDgpgBAKlC8UBOECGATA9gOwDYigG0AoAelKkoD0B+S4ygRgBoAmZgZmYBZmBWZgDZmAdmYAOZgE5mABmYMoLdl14DhYyTPmLlnHvyGiJ0uQqZt9ao5tM6LKg+uNazuy6sMaT280o9ONj5uDlZeLnZ+ep7Otr7ujtbervb+ieFxIWlhscGp0YHJkQk5QSlRAUkR8aExZcW1hdVZAOQAzsAAlri4UADmmJjoLcxQLdiYAO5QwEgArtgAxqhd2H0txAC6UMTEoJBQABYAtscAPHAQAB7AENjobchoWHgEhAB0n6jYIJsAfAhYIRGCJZJtdvtoDBWICTucYACyBRqDRdsRFjgOlArpRECRGlVMvlKhk8hV0rlyiU6kUatkac1iRT6nSCoSydSmkTyaVaVk2aSqQTBQ16VyOcLKaKBVLWSTZfz5SzFcy+al2l0elBBsNRuMpjN5ksVp01httqhHhjsB1dtasSAAFywQFXYhAA
Andarist commentedon Jul 10, 2025
This would likely address this "regression":
But, truth to be told,
noErrorTruncationis only documented to be, well, about error truncation - not about general type display in all sort of places (but I know it has, historically, been used by those too). The potential problem here is that this is somewhat at odds with the new expandable hovers (cc Gabriela Araujo Britto (@gabritto)) and I'd say it probably no longer should impact quick info (as it doesn't now).The extra problem is this weird
anythat gets displayed here. That's a product of those lines of code:https://github.com/microsoft/TypeScript/blob/9e20e032effad965567d4a1e1c30d5433b0a3332/src/compiler/checker.ts#L7833-L7839
This
anygets a... 4 more elided ...comment but that doesn't end up being printed and perhaps it should. That said,anybeing displayed in those truncating scenarios has always been slightly weird - and actually, IIRC, it can accidentally get leaked into generated.d.tswithout producing any errors about the inferred cyclic type not being fully serializabletypeholes commentedon Jul 10, 2025
Yes, the problem really is with the
any. It is very confusing without the comment.Agreed that noErrorTruncation having side effects outside of errors is weird and should be changed. That said, those side effects are often the difference between seeing what I need and having to create some indexed type just to figure out what is going on. From a user perspective it would be ideal if the expandable hovers could expand the elision. That seems like a fairly heavy lift on the implementation side.
gabritto commentedon Jul 10, 2025
Basically what Mateusz BurzyΕski (@Andarist) said above, but to reiterate, what I remember happening was that
noErrorTruncationaffecting hovers was a bit confusing for users and probably not intended. To add to that confusion, a long time ago I think we didn't truncate anything at all, and then we added truncation, and addednoErrorTruncation, which was supposed to disable truncation in errors, but because the type printing code is shared, it ended up also disabling truncation in hovers (see #26238).Now we have a setting specifically for truncation in hovers: #61662.
The elision comment on
anyshouldn't be missing, I agree that's a bug.typeholes commentedon Jul 11, 2025
Do we know what the motivation for creating an
anykeyword node when noTruncation is true was? I'm waiting on the tests to finish after changing it always create the type reference node, hopefully that will provide more contextgabritto commentedon Jul 11, 2025
I took a closer look now, and I think producing the
anyis intentional.The reason why the code exists as it does today is that, if we are printing a type for e.g. a codefix, we don't want to truncate the type, so in that context, we set the
NodeBuilder.NoTruncationflag when printing a type. And if even withNodeBuilder.NoTruncationthe type printer still hits its hard limit (of 100k characters I think), we don't want to produce the type node reference with an elision name (i.e.factory.createTypeReferenceNode(... ${types.length - i} more ..., /*typeArguments*/ undefined)), because then the code produced by the codefix will have a parsing error. So we instead produce ananywith a comment, because that is a valid type.Perhaps the root of the problem is that when a config has
noErrorTruncation: true, we also setNodeBuilder.NoTruncationintypeToString, even if we're callingtypeToStringfor hover or diagnostics, and in those cases we don't really need to produce ananybecause the type we print doesn't have to be valid. But then again, if we're printing a type for.d.tsemit, we do want to produce a valid type. So it's tricky.johtso commentedon Jul 19, 2025
This issue had me chasing my tail for a few hours today thinking that I had a problem with my types.. #62090