Skip to content

not_impl quick wins: generic defaults, Promise<T>, void callbacks, explicit type arguments - #718

Merged
ASDAlexander77 merged 4 commits into
mainfrom
not-impl-quick-wins
Oct 28, 2026
Merged

ASDAlexander77 merged 4 commits into
mainfrom
not-impl-quick-wins

Conversation

@ASDAlexander77

@ASDAlexander77 ASDAlexander77 commented Oct 28, 2026 •

Copy link
Copy Markdown
Owner

Quick wins from docs/not_impl (not_impl7, not_impl27).

A generic call with nothing to infer from takes the default, then the constraint

function noParams<T extends {}>() called as noParams(), and even function f<T = string>()
as f(), failed with "generic type arguments cannot be inferred". instantiateSpecializedFunction
now fills the type parameters from their defaults, then their constraints
(zipTypeParametersWithDefaultArguments, as the inference path already does), and reports only a
parameter with neither.

Test: 00generic_default_no_inference.

Promise<T> is T

An async function runs to completion and returns its value, but async function f(): Promise<number>
failed with "generic type Promise can't be found". Promise, PromiseLike and Awaited are now
embedded types that stand for their type argument, with and without builtins. A program's own
Promise<T> is still found first.

Test: 00promise_type.

A callback whose result is ignored may return one

TS lets an arrow given to a function type that returns nothing return a value:
each(a, s => bump(s)) with f: (s: string) => void, or (x) => null.

  • An arrow or function expression with no return type of its own, given to a function type whose
    result is a declared void, is generated as returning nothing
    (FunctionPrototypeDOM::discardsReturnValue, kept per function name). Its concise body and its
    return e statements evaluate the value as a statement does and drop it - no retain, so nothing
    leaks under rc. Only an explicit !ts.void result counts: a receiver with no result or a null one
    is one not resolved yet ((i: T) => R while R is inferred, builtin callbacks).
  • A variable's declared function type is the receiver of its initializer, as an assignment's left
    side already was.

Explicit type arguments type the arguments

A call to a generic function with every type argument given, none of them still generic, is
specialised before its arguments are generated, so produce<any>(() => undefined) meets
() => any, not () => T. It runs with the call's own (no) operands - the enclosing call's
operands broke DefaultLib's reduce through __is<V, T> - and a failure rolls its diagnostics
back and leaves the call to specialise as before.

Test (both): 00callback_result_ignored.

Not covered

  • () => 3 for (x: number) => void (fewer parameters) still fails: it needs an adapter thunk.
  • Under -mm=own, a generic returning a callback's any result is rejected - already so on main.

Verification

  • ctest Release: 6109/6109 passed.
  • DefaultLib tests.ps1 Release (with the companion DefaultLib PR): gc 176/176, rc 175/176
    (1 skipped), none 175/176 (1 skipped), own 165/176 (11 skipped) - all pass. Debug not run locally.

Companion: ASDAlexander77/TypeScriptCompilerDefaultLib#54 (String.substr).

🤖 Generated with Claude Code

ASDAlexander77 and others added 4 commits October 28, 2026 16:28
… constraint

`function noParams<T extends {}>()` called as `noParams()` (and even
`function f<T = string>()` as `f()`) failed with "generic type arguments
cannot be inferred": instantiateSpecializedFunction rejected a call with no
type arguments and no parameters outright. It now fills the type parameters
from their defaults, then their constraints (zipTypeParametersWithDefaultArguments,
as the inference path already does), and reports only a parameter with
neither.

Test: 00generic_default_no_inference (docs/not_impl/not_impl27.ts).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
An async function runs to completion and returns its value (an `await` waits
for the expression it awaits), but writing that type down failed: "generic
type Promise can't be found", so `async function f(): Promise<number>` - the
usual way to write one - did not compile. `Promise`, `PromiseLike` and
`Awaited` are now embedded types that stand for their type argument, with
and without builtins. A program's own `Promise<T>` is still found first.

Test: 00promise_type (docs/not_impl/not_impl7.ts).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ments type the arguments

TS lets an arrow given to a function type that returns nothing return a value:
`each(a, s => bump(s))` with `f: (s: string) => void`. Here it failed - "can't
find return variable" when the type came from a generic parameter, "one returns
a value and the other does not" when it came from a variable's type, and "can't
cast from 'null' to 'void'" for `() => null`.

- An arrow or function expression with no return type of its own, given to a
  function type that returns nothing, is generated as returning nothing
  (FunctionPrototypeDOM::discardsReturnValue, kept per function name so a
  later prototype of it keeps it). Its concise body and its `return e`
  statements evaluate the value as a statement does and drop it - no retain,
  so nothing leaks under rc.
- A variable's declared function type is the receiver of its initializer, as
  an assignment's left side already was.
- A call to a generic function with every type argument given specialises the
  callee before generating the arguments, so `produce<any>(() => undefined)`
  meets `() => any`, not `() => T` (which no arrow can take its return type from).

Test: 00callback_result_ignored (docs/not_impl/not_impl27.ts someGenerics2a/2b/3/4).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… with the call's own operands

The head start dee75f4 gives a call with every type argument given took the
GenContext of the expression around it, and with it the operands of the call
this one is an argument of: `__is<V, T>(this[0])` inside DefaultLib's
Array.reduce was specialised from reduce's own operands, which broke
`[].reduce((x, y) => x + y)` (array_reduce, array_reduce_empty,
array_reduce3, map_values_reduce). It now runs with no call operands, only
when no type argument is itself still generic, and a failure rolls its
diagnostics back and leaves the call to specialise the way it did before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ASDAlexander77
ASDAlexander77 merged commit bd08482 into main Oct 28, 2026
2 checks passed
@ASDAlexander77
ASDAlexander77 deleted the not-impl-quick-wins branch October 28, 2026 17:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant