lib.es5.d.ts: accept array-likes (arguments, typed arrays, DOM collections) as the second argument of Function.prototype.apply#63654
Closed
KAMRONBEK wants to merge 1 commit into
Closed
Conversation
Function.prototype.apply accepts any array-like as its second argument per the ECMAScript spec (CreateListFromArrayLike), so cases like String.fromCharCode.apply(null, uint8Array) and console.log.apply(null, arguments) work at runtime but were rejected under strictBindCallApply. Add an array-like apply overload to CallableFunction that routes real arrays/tuples back to the arity-checked tuple overload (Args extends readonly any[] ? A : Args), so strictBindCallApply's arity and element-type checks are fully preserved while non-array array-likes (arguments, typed arrays, DOM collections) are now accepted. Adds conformance fixture applyArrayLike.ts. Full test battery: 106377 passing, 0 failing. No JS emit baselines changed. Fixes microsoft#61835
Contributor
There was a problem hiding this comment.
Pull request overview
This PR updates the CallableFunction.apply typing in lib.es5.d.ts to accept non-array array-like objects (e.g. arguments, typed arrays, DOM collections) as the args parameter under strictBindCallApply, aligning the lib definition with ECMAScript’s CreateListFromArrayLike behavior and fixing #61835.
Changes:
- Add an additional
CallableFunction.applyoverload that acceptsArrayLikeinputs without regressing tuple/array arity checking. - Add a new conformance test covering accepted array-likes and guarding against
strictBindCallApplyarity/type regressions. - Accept baseline updates reflecting the new overload in type/symbol output and the expected diagnostic shape changes.
Reviewed changes
Copilot reviewed 52 out of 53 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| src/lib/es5.d.ts | Adds an apply overload to accept non-array array-like arguments under CallableFunction. |
| tests/cases/conformance/functions/applyArrayLike.ts | New conformance coverage for array-like apply usage and regression guards. |
| tests/baselines/reference/tsxReactEmitSpreadAttribute(target=es2018).types | Baseline update reflecting signature/printing changes. |
| tests/baselines/reference/truthinessCallExpressionCoercion2.types | Baseline update reflecting added overload in type display. |
| tests/baselines/reference/truthinessCallExpressionCoercion2.symbols | Baseline update reflecting added overload symbol declaration count. |
| tests/baselines/reference/strictBindCallApply1.types | Baseline update reflecting added overload in type display. |
| tests/baselines/reference/strictBindCallApply1.symbols | Baseline update reflecting added overload symbol declaration count. |
| tests/baselines/reference/strictBindCallApply1.errors.txt | Baseline update reflecting TS2769 “no overload matches” shape due to added overload. |
| tests/baselines/reference/objectTypeWithCallSignatureAppearsToBeFunctionType.types | Baseline update reflecting added overload in type display. |
| tests/baselines/reference/objectTypeWithCallSignatureAppearsToBeFunctionType.symbols | Baseline update reflecting added overload symbol declaration count. |
| tests/baselines/reference/noParameterReassignmentJSIIFE.types | Baseline update reflecting added overload in type display. |
| tests/baselines/reference/noParameterReassignmentJSIIFE.symbols | Baseline update reflecting added overload symbol declaration count. |
| tests/baselines/reference/noParameterReassignmentJSIIFE.errors.txt | Baseline deletion because arguments is now accepted as array-like for .apply. |
| tests/baselines/reference/noParameterReassignmentIIFEAnnotated.types | Baseline update reflecting added overload in type display. |
| tests/baselines/reference/noParameterReassignmentIIFEAnnotated.symbols | Baseline update reflecting added overload symbol declaration count. |
| tests/baselines/reference/noParameterReassignmentIIFEAnnotated.errors.txt | Baseline update reflecting removal of the previous .apply(arguments) error. |
| tests/baselines/reference/functionType.types | Baseline update reflecting added overload in type display. |
| tests/baselines/reference/functionType.symbols | Baseline update reflecting added overload symbol declaration count. |
| tests/baselines/reference/esDecorators-contextualTypes.2.types | Baseline update reflecting added overload in type display. |
| tests/baselines/reference/esDecorators-contextualTypes.2.symbols | Baseline update reflecting added overload symbol declaration count. |
| tests/baselines/reference/emitSkipsThisWithRestParameter.types | Baseline update reflecting added overload in type display. |
| tests/baselines/reference/emitSkipsThisWithRestParameter.symbols | Baseline update reflecting added overload symbol declaration count. |
| tests/baselines/reference/emitSkipsThisWithRestParameter.errors.txt | Baseline update reflecting TS2769 diagnostic shape due to added overload. |
| tests/baselines/reference/declarationEmitPromise.types | Baseline update reflecting added overload in type display. |
| tests/baselines/reference/declarationEmitPromise.symbols | Baseline update reflecting added overload symbol declaration count. |
| tests/baselines/reference/completionsCommitCharactersAfterDot.baseline | Baseline update reflecting overload count displayed in completion details. |
| tests/baselines/reference/coAndContraVariantInferences6.types | Baseline update reflecting added overload in type display. |
| tests/baselines/reference/coAndContraVariantInferences6.symbols | Baseline update reflecting added overload symbol declaration count. |
| tests/baselines/reference/asyncFunctionDeclarationCapturesArguments_es5(target=es5).types | Baseline update reflecting added overload in type display. |
| tests/baselines/reference/asyncFunctionDeclarationCapturesArguments_es5(target=es5).symbols | Baseline update reflecting added overload symbol declaration count. |
| tests/baselines/reference/asyncFunctionDeclarationCapturesArguments_es5(target=es5).errors.txt | Baseline update reflecting TS2769 diagnostic shape due to added overload. |
| tests/baselines/reference/asyncFunctionDeclarationCapturesArguments_es5(target=es2015).types | Baseline update reflecting added overload in type display. |
| tests/baselines/reference/asyncFunctionDeclarationCapturesArguments_es5(target=es2015).symbols | Baseline update reflecting added overload symbol declaration count. |
| tests/baselines/reference/asyncFunctionDeclarationCapturesArguments_es5(target=es2015).errors.txt | Baseline update reflecting TS2769 diagnostic shape due to added overload. |
| tests/baselines/reference/asyncArrowFunctionCapturesArguments_es6.types | Baseline update reflecting added overload in type display. |
| tests/baselines/reference/asyncArrowFunctionCapturesArguments_es6.symbols | Baseline update reflecting added overload symbol declaration count. |
| tests/baselines/reference/asyncArrowFunctionCapturesArguments_es6.errors.txt | Baseline update reflecting TS2769 diagnostic shape due to added overload. |
| tests/baselines/reference/asyncArrowFunctionCapturesArguments_es5(target=es5).types | Baseline update reflecting added overload in type display. |
| tests/baselines/reference/asyncArrowFunctionCapturesArguments_es5(target=es5).symbols | Baseline update reflecting added overload symbol declaration count. |
| tests/baselines/reference/asyncArrowFunctionCapturesArguments_es5(target=es5).errors.txt | Baseline update reflecting TS2769 diagnostic shape due to added overload. |
| tests/baselines/reference/asyncArrowFunctionCapturesArguments_es5(target=es2015).types | Baseline update reflecting added overload in type display. |
| tests/baselines/reference/asyncArrowFunctionCapturesArguments_es5(target=es2015).symbols | Baseline update reflecting added overload symbol declaration count. |
| tests/baselines/reference/asyncArrowFunctionCapturesArguments_es5(target=es2015).errors.txt | Baseline update reflecting TS2769 diagnostic shape due to added overload. |
| tests/baselines/reference/asyncArrowFunctionCapturesArguments_es2017.types | Baseline update reflecting added overload in type display. |
| tests/baselines/reference/asyncArrowFunctionCapturesArguments_es2017.symbols | Baseline update reflecting added overload symbol declaration count. |
| tests/baselines/reference/asyncArrowFunctionCapturesArguments_es2017.errors.txt | Baseline update reflecting TS2769 diagnostic shape due to added overload. |
| tests/baselines/reference/argumentsReferenceInFunction1_Js.types | Baseline update reflecting added overload in type display. |
| tests/baselines/reference/argumentsReferenceInFunction1_Js.symbols | Baseline update reflecting added overload symbol declaration count. |
| tests/baselines/reference/argumentsReferenceInFunction1_Js.errors.txt | Baseline update reflecting removal of the previous .apply(arguments) error. |
| tests/baselines/reference/applyArrayLike.types | New baseline for the added conformance test. |
| tests/baselines/reference/applyArrayLike.symbols | New baseline for the added conformance test. |
| tests/baselines/reference/applyArrayLike.js | New emit baseline for the added conformance test. |
| tests/baselines/reference/applyArrayLike.errors.txt | New error baseline for the added conformance test’s intentional negative cases. |
Member
|
Undisclosed AI |
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.
Fixes #61835
Summary
Function.prototype.applyaccepts any array-like object as its secondargument, not just a real
Array. This is normative in the ECMAScript spec:Function.prototype.applybuilds its argument list with the abstract operation
CreateListFromArrayLike,which reads the
lengthproperty and the indexed properties0 .. length-1off an ordinary object — it never requires a genuine
Array. MDN documents thesame: "You can also use any kind of object which is array-like as the second
parameter. In practice, this means that it needs to have a
lengthproperty,and integer ("index") properties … You can also use
arguments."Under
strictBindCallApply(implied bystrict), calls resolve toCallableFunction.apply, whose second parameter is currently typed as the exacttuple/array
A extends any[]. That rejects perfectly valid array-likes that workat runtime:
The only workaround today is
Array.from(...), which the reporter correctlynotes imposes a needless runtime copy.
The fix
Add one overload to
CallableFunction.applyinsrc/lib/es5.d.ts— theexisting tuple overload is left untouched:
Why an added overload and not a mutation of the existing one
Naively widening the existing overload's
args: Atoargs: ArrayLike<A[number]>regresses
strictBindCallApply. That machinery relies on inferring theargument tuple
Aand checking its arity and element types against theparameter list.
ArrayLike<T>has no length/arity, so cases that must error stoperroring — verified empirically:
Keeping the tuple overload first preserves precise arity checking for
arrays/tuples. But a plain
ArrayLikefallback overload placed after itre-introduces the same regression, because a tuple like
[10]is assignable toArrayLike<number>and the fallback swallows it.The discriminator
The added overload therefore routes on whether the supplied argument is a real
array/tuple:
Args extends readonly any[]— the input is an array or tuple (this holdsfor tuples and arrays, but not for
Uint8Array,IArguments, or DOMcollections, none of which are assignable to
readonly any[]). The parametertype collapses to
A, so the strict tuple check still applies and wrong-arity/ wrong-type array literals still error exactly as before.
Args(constrained toArrayLike<A[number]>), soUint8Array,arguments,NodeList, etc. are accepted while an array-like of the wrong element type(e.g.
ArrayLike<string>for anumberparameter) is still rejected via theArgs extends ArrayLike<A[number]>constraint.This is why
foo.apply(undefined, [10, 20])still errors whileString.fromCharCode.apply(null, u8)type-checks.Scope:
CallableFunctiononlyNewableFunction.applyis deliberately left unchanged. Calling a constructor's.applyinvokes it as a plain function (not withnew), which throws for realclasses at runtime, and no reported case targets it. The issue and all of its
examples (
String.fromCharCode,console.log,arguments) areCallableFunctioncalls. Keeping the change to
CallableFunction.applymatches the reported surfaceand avoids gratuitous churn. The non-strict
Function.applyoverload alreadytakes
argArray?: any, so it was never affected.Verification
Built the compiler (
npx hereby local) and ran the full test battery withthe modified lib:
The lib change shifts a number of recorded baselines; each was reviewed and
hereby baseline-accepted. They fall into three buckets, all expected:IArguments/array-like errors on.applyremoved, e.g.
noParameterReassignmentJSIIFE(its.errors.txtis deletedbecause
importScripts.apply(this, arguments)no longer errors),noParameterReassignmentIIFEAnnotated,argumentsReferenceInFunction1_Js.via the "No overload matches this call" (TS2769) form because
applynow has anextra overload (
strictBindCallApply1,asyncArrowFunctionCapturesArguments_*,asyncFunctionDeclarationCapturesArguments_*,emitSkipsThisWithRestParameter).No error changed line or root cause; a zero-parameter target still rejects
argumentsbecauseIArgumentsis not assignable toArrayLike<never>..types/.symbolsbaselines that print theapplysignaturenow show the added overload. No
.jsemit baseline changed (a lib typechange cannot affect emit, and none did).
A dedicated conformance fixture is added at
tests/cases/conformance/functions/applyArrayLike.tsproving both directions:the array-like cases (
Uint8Array,arguments,ArrayLike<number>) type-check,and the arity / wrong-element-type cases still error.
Known trade-off (for maintainer review)
The one real downside is diagnostic verbosity: because
applynow carries anextra overload, a genuinely wrong
applycall reports the multi-lineTS2769: No overload matches this call.form instead of the previous crispsingle
TS2345/TS2322. Correctness of type-checking is unchanged — only theerror presentation is noisier. If the team prefers to preserve the terse
diagnostics, an alternative is to gate the array-like acceptance behind a compiler
change rather than a purely-declarative overload, but that is a larger change; the
declarative overload here is the minimal fix that resolves the reported cases with
no semantic regression.
Files changed
src/lib/es5.d.ts— add the array-likeapplyoverload toCallableFunction.tests/cases/conformance/functions/applyArrayLike.ts— new conformance fixture.tests/baselines/reference/*— accepted baseline updates (categorized above);no
.jsemit baselines changed.