Repository navigation
typescript: a destructured parameter typed by its context, and a literal nested in a typed literal - #2010
Open
swapnilpaliwal-sd wants to merge 1 commit into
Open
typescript: a destructured parameter typed by its context, and a literal nested in a typed literal#2010swapnilpaliwal-sd wants to merge 1 commit into
swapnilpaliwal-sd wants to merge 1 commit into
Conversation
…ral nested in a typed literal
`const poll: (ctx: Ctx) => R = async ({ data, utils }) => utils.http(..)` and
`define({ lifecycle: { start: async ({ utils }) => utils.http(..) } })` left every call
on `utils` unresolved, while `ctx.utils.http(..)` on the same arrow resolved.
Two causes:
- a bound name reads its pattern's type through param_type, which only an annotation
fills; contextual typing (lambda_param_type) typed references to the parameter and
never the names destructured from it. The bound name now takes the type (and shape)
of the field it names from the contextual type, typed at its uses beside the plain
parameter's, not through param_type, which overload rejection reads under negation.
- an object literal written as a property of a typed literal had no scope, so functions
in a nested slot took no parameter types. It now takes the type of the field it fills.
Case 99 pins both, with controls: an `any` pattern and a parameter typed by an object
type literal stay unresolved. Every other TypeScript case is unchanged (109/109).
On a Deno connector repository (~750 endpoint definitions): known_edge rows 7,410 -> 8,923,
ambiguous_unknown 35,820 -> 34,300, multi_inferred 63 -> 77, no edge lost; 194 of 198
hook calls of the framework's HTTP helper now resolve.
Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com>
swapnilpaliwal-sd
requested review from
JaredHLZhang,
Whua689 and
suyashpaliwal26
as code owners
November 3, 2026 10:19
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What was wrong
An arrow whose parameter type comes from its context, not an annotation, lost every call on a name destructured from that parameter:
Causes and fix (
contextual-params.dl)param_type(binding_pattern_type), which only an annotation fills. Contextual typing (lambda_param_type) types references to the parameter, never the names destructured from it. Now each bound name takes the type and shape of the field it names on the contextual type. Its uses are typed next to the plain parameter's uses (expr_type/expr_shape), not throughparam_type, because overload rejection readsparam_typeunder negation.objlit_ctx_refcovered a literal that is a variable initializer, a field initializer, a returned value or a call argument, but not a literal that is the property value of a typed literal. A nested literal now takes the type of the field it fills, which also works through intersections (Omit<..> & { lifecycle?: Slots }).Tests
99-contextual-destructured-paramcovers the const-annotated arrow, a nested slot under an intersection-typed parameter, and arrows written both destructured and plain. Controls: ananypattern and a parameter typed by an object type literal both stay unresolved.(?,?,?)where the compiler writes(?). The pre-existingannotatedfunction has the same artifact. One real gap is recorded: the type-literal parameter.run-tests.sh: the other 109 cases are unchanged.On a real repository (a Deno connector monorepo, ~750 endpoint definitions)
known_edgeambiguous_unknownmulti_inferredThe new edges are the expected interface members (
JsonUtil.*495+347+…,HookLogger.*325, the HTTP helper 209). 7 sites now also reach a class whoseownedmethod has the same shape as the interface member. That comes from the existing structural dispatch, which these sites now reach; it is not a new rule.Not covered
A parameter typed by an alias to an object type literal (
type Ctx = { utils: Utils }): the bound name reads only a declaration's fields.