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
any, unknown, and attribution failure all collapse to the same JavaType.Unknown singleton
Component:rewrite-javascript Versions:rewrite-javascript 8.90.0, Moderne CLI 4.6.1, TypeScript 5.9.3, Node 26.7.0
What happens
Three semantically distinct situations produce the same payload-free interned value:
A parameter or expression declared any — a deliberate, resolved type.
A parameter or expression declared unknown — also deliberate and resolved.
A genuine type-attribution failure — the parser could not determine the type.
In type-mapping.ts, the single TypeFlags.Any branch matches only intrinsicName === 'error', so
declared any falls through to the terminal return Type.unknownType. Roughly a dozen other sites
return the same singleton for real failures. There is no TypeFlags.Unknown branch at all, so the unknown keyword lands there too. There is no any primitive (fromKeyword has no 'any' case).
The value carries no marker, flag, or provenance slot, and signs as <unknown>.
Both parameter types arrive as the same JavaType.Unknown instance that an unresolvable type
produces. Nothing distinguishes them from each other or from a failure.
Expected
A representable distinction — for example, separate kinds, or a payload on Unknown recording
whether it originated from declared any, declared unknown, or a failed resolution. Line 220
already reads intrinsicName to isolate 'error', so the discrimination point exists; what is
missing is somewhere to record the result.
Why this matters downstream (motivating case)
We build a code-property-graph frontend used for cross-repository code navigation. It must
distinguish "this parameter is deliberately untyped" from "we failed to type this parameter",
because the two demand opposite responses: the first is the author's decision and is final; the
second is a gap that better configuration or a fixed parser could close.
At 8.90.0 we cannot tell them apart. Concretely, on one repository 1,159 of our unresolved-callee
events are this value, while the source contains only 107 explicit any annotations and zero uses of
the unknown keyword — so most of them are probably genuine failures, but we cannot demonstrate
that, and we therefore cannot state an honest ceiling for TypeScript call resolution. The
measurement is blocked by the conflation, not by the rate.
Related
Do not treat missing type attribution as proof of semantic equality #8333 established the principle that missing type attribution must not be read as information
(the SemanticallyEqual/RemoveSelfAssignment incident). This is the same principle one layer
down: here, information (any was declared) is indistinguishable from its absence. Cited as an
analogous principle, not as the same defect.
Offer
The change looks small and well-scoped. We are willing to prepare a PR adding the any/unknown/error discrimination if the maintainers indicate which representation they would
accept — a distinct Kind, or a payload on Unknown.
any,unknown, and attribution failure all collapse to the sameJavaType.UnknownsingletonComponent:
rewrite-javascriptVersions:
rewrite-javascript8.90.0, Moderne CLI 4.6.1, TypeScript 5.9.3, Node 26.7.0What happens
Three semantically distinct situations produce the same payload-free interned value:
any— a deliberate, resolved type.unknown— also deliberate and resolved.In
type-mapping.ts, the singleTypeFlags.Anybranch matches onlyintrinsicName === 'error', sodeclared
anyfalls through to the terminalreturn Type.unknownType. Roughly a dozen other sitesreturn the same singleton for real failures. There is no
TypeFlags.Unknownbranch at all, so theunknownkeyword lands there too. There is noanyprimitive (fromKeywordhas no'any'case).The value carries no marker, flag, or provenance slot, and signs as
<unknown>.Minimal reproduction
Both parameter types arrive as the same
JavaType.Unknowninstance that an unresolvable typeproduces. Nothing distinguishes them from each other or from a failure.
Expected
A representable distinction — for example, separate kinds, or a payload on
Unknownrecordingwhether it originated from declared
any, declaredunknown, or a failed resolution. Line 220already reads
intrinsicNameto isolate'error', so the discrimination point exists; what ismissing is somewhere to record the result.
Why this matters downstream (motivating case)
We build a code-property-graph frontend used for cross-repository code navigation. It must
distinguish "this parameter is deliberately untyped" from "we failed to type this parameter",
because the two demand opposite responses: the first is the author's decision and is final; the
second is a gap that better configuration or a fixed parser could close.
At 8.90.0 we cannot tell them apart. Concretely, on one repository 1,159 of our unresolved-callee
events are this value, while the source contains only 107 explicit
anyannotations and zero uses ofthe
unknownkeyword — so most of them are probably genuine failures, but we cannot demonstratethat, and we therefore cannot state an honest ceiling for TypeScript call resolution. The
measurement is blocked by the conflation, not by the rate.
Related
(the
SemanticallyEqual/RemoveSelfAssignmentincident). This is the same principle one layerdown: here, information (
anywas declared) is indistinguishable from its absence. Cited as ananalogous principle, not as the same defect.
Offer
The change looks small and well-scoped. We are willing to prepare a PR adding the
any/unknown/errordiscrimination if the maintainers indicate which representation they wouldaccept — a distinct
Kind, or a payload onUnknown.