Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Analyze control flow effects of lambdas passed as arguments #58729

Open
wants to merge 19 commits into
base: main
Choose a base branch
from

Conversation

ahejlsberg
Copy link
Member

@ahejlsberg ahejlsberg commented May 31, 2024

This PR changes control flow analysis to assume that function expressions or arrow functions (in the following called lambda expressions) passed as arguments in a function call may be invoked synchronously during that call. For example:

let x: string | number = "OK";
x;  // string
mystery(() => {
  x = 10;
});
x;  // string | number
if (x === 10) {  // Was error, now is ok
}

Previously, we wouldn't account for the possibility that the lambda expression might have been invoked during the call to mystery and thus we'd assume that the control flow type of x was still string following the call. Effectively, our assumption was that lambda expression arguments are never invoked synchronously, which is less sound than assuming they may have executed.

In some scenarios it is known that a callback parameter is never invoked synchronously (typical of many UI related callbacks), and therefore that possible effects of lambda expression arguments aren't immediate. To support those scenarios, this PR introduces a new deferred modifier that can be used to mark deferred callback parameters:

function setTimeout(deferred callback: (args: void) => void, ms?: number): NodeJS.Timeout;

When a lambda expression is passed as the argument for a deferred parameter, control flow analysis assumes that the lambda isn't called synchronously. (Effectively, deferred reverts control flow analysis to it's previous behavior.)

It an error to apply the deferred modifier to anything but a parameter with a type that permits functions.

In JavaScript files, a deferred callback parameter can be declared using a /** @deferred */ JSDoc annotation:

/**
 * @param {() => void} handler
 */
function onSomeEvent(/** @deferred */ handler) { ... }

Async arrow functions, async function expressions, and generator function expressions are always assumed to be deferred, regardless of whether their corresponding parameter includes a deferred modifier.

Fixes #11498.
Fixes #15380.
Fixes #57880.

@typescript-bot typescript-bot added Author: Team For Uncommitted Bug PR for untriaged, rejected, closed or missing bug labels May 31, 2024
@ahejlsberg
Copy link
Member Author

@typescript-bot test it

@typescript-bot
Copy link
Collaborator

typescript-bot commented May 31, 2024

Starting jobs; this comment will be updated as builds start and complete.

Command Status Results
test top400 ✅ Started 👀 Results
user test this ✅ Started 👀 Results
run dt ✅ Started ✅ Results
perf test this faster ✅ Started 👀 Results

@typescript-bot
Copy link
Collaborator

Hey @ahejlsberg, the results of running the DT tests are ready.

Everything looks the same!

You can check the log here.

@typescript-bot
Copy link
Collaborator

@ahejlsberg Here are the results of running the user tests with tsc comparing main and refs/pull/58729/merge:

Something interesting changed - please have a look.

Details

enhanced-resolve

/mnt/ts_downloads/_/m/enhanced-resolve/tsconfig.json

  • [MISSING] error TS2339: Property 'replace' does not exist on type 'never'.
    • /mnt/ts_downloads/_/m/enhanced-resolve/node_modules/enhanced-resolve/lib/concord.js(149,24)
    • /mnt/ts_downloads/_/m/enhanced-resolve/node_modules/enhanced-resolve/lib/concord.js(188,17)

pyright

/mnt/ts_downloads/_/m/pyright/build.sh

  • [NEW] error TS18048: 'cacheEntry' is possibly 'undefined'.
    • /mnt/ts_downloads/_/m/pyright/pyright: ../pyright-internal/src/analyzer/codeFlowEngine.ts(951,25)
    • /mnt/ts_downloads/_/m/pyright/pyright: ../pyright-internal/src/analyzer/codeFlowEngine.ts(1064,41)
    • /mnt/ts_downloads/_/m/pyright/pyright-internal: src/analyzer/codeFlowEngine.ts(951,25)
    • /mnt/ts_downloads/_/m/pyright/pyright-internal: src/analyzer/codeFlowEngine.ts(1064,41)
    • /mnt/ts_downloads/_/m/pyright/vscode-pyright: ../pyright-internal/src/analyzer/codeFlowEngine.ts(951,25)
    • /mnt/ts_downloads/_/m/pyright/vscode-pyright: ../pyright-internal/src/analyzer/codeFlowEngine.ts(1064,41)

uglify-js

/mnt/ts_downloads/_/m/uglify-js/tsconfig.json

  • [MISSING] error TS18048: 'ldef' is possibly 'undefined'.
    • /mnt/ts_downloads/_/m/uglify-js/node_modules/uglify-js/lib/compress.js(6753,56)

webpack

tsconfig.types.json

xterm.js

src/tsconfig-library-base.json

@typescript-bot
Copy link
Collaborator

@ahejlsberg
The results of the perf run you requested are in!

Here they are:

tsc

Comparison Report - baseline..pr
Metric baseline pr Delta Best Worst p-value
Compiler-Unions - node (v18.15.0, x64)
Errors 30 30 ~ ~ ~ p=1.000 n=6
Symbols 62,153 62,153 ~ ~ ~ p=1.000 n=6
Types 50,242 50,243 +1 (+ 0.00%) ~ ~ p=0.001 n=6
Memory used 192,920k (± 0.75%) 192,999k (± 0.75%) +79k (+ 0.04%) 192,402k 195,952k p=0.045 n=6
Parse Time 1.95s (± 0.96%) 1.95s (± 0.53%) ~ 1.94s 1.97s p=0.317 n=6
Bind Time 1.08s (± 0.70%) 1.10s (± 0.74%) +0.02s (+ 2.00%) 1.09s 1.11s p=0.007 n=6
Check Time 14.05s (± 0.46%) 14.15s (± 0.52%) +0.10s (+ 0.70%) 14.05s 14.27s p=0.037 n=6
Emit Time 4.07s (± 1.00%) 4.06s (± 0.53%) ~ 4.03s 4.09s p=0.223 n=6
Total Time 21.14s (± 0.18%) 21.26s (± 0.32%) +0.12s (+ 0.54%) 21.17s 21.37s p=0.010 n=6
angular-1 - node (v18.15.0, x64)
Errors 5 9 🔻+4 (+80.00%) ~ ~ p=0.001 n=6
Symbols 944,109 944,283 +174 (+ 0.02%) ~ ~ p=0.001 n=6
Types 407,049 407,127 +78 (+ 0.02%) ~ ~ p=0.001 n=6
Memory used 1,222,154k (± 0.00%) 1,223,819k (± 0.00%) +1,664k (+ 0.14%) 1,223,752k 1,223,903k p=0.005 n=6
Parse Time 8.05s (± 0.57%) 8.07s (± 0.67%) ~ 8.02s 8.16s p=0.809 n=6
Bind Time 2.23s (± 0.62%) 2.28s (± 0.72%) +0.05s (+ 2.32%) 2.26s 2.30s p=0.005 n=6
Check Time 36.28s (± 0.12%) 36.72s (± 0.27%) +0.43s (+ 1.19%) 36.62s 36.90s p=0.005 n=6
Emit Time 17.94s (± 0.68%) 18.11s (± 0.50%) +0.17s (+ 0.95%) 18.01s 18.25s p=0.030 n=6
Total Time 64.49s (± 0.28%) 65.18s (± 0.29%) +0.68s (+ 1.06%) 64.97s 65.46s p=0.005 n=6
mui-docs - node (v18.15.0, x64)
Errors 5 5 ~ ~ ~ p=1.000 n=6
Symbols 2,051,460 2,051,489 +29 (+ 0.00%) ~ ~ p=0.001 n=6
Types 899,446 899,469 +23 (+ 0.00%) ~ ~ p=0.001 n=6
Memory used 2,065,603k (± 0.01%) 2,065,874k (± 0.00%) +271k (+ 0.01%) 2,065,749k 2,065,985k p=0.013 n=6
Parse Time 8.10s (± 0.46%) 8.11s (± 0.21%) ~ 8.09s 8.13s p=1.000 n=6
Bind Time 2.75s (± 0.88%) 2.77s (± 0.84%) ~ 2.74s 2.80s p=0.124 n=6
Check Time 81.77s (± 0.36%) 82.13s (± 0.44%) ~ 81.76s 82.71s p=0.066 n=6
Emit Time 0.16s (± 3.16%) 0.17s (± 3.10%) ~ 0.16s 0.17s p=0.311 n=6
Total Time 92.78s (± 0.28%) 93.18s (± 0.40%) +0.39s (+ 0.43%) 92.82s 93.78s p=0.045 n=6
self-build-src - node (v18.15.0, x64)
Errors 0 0 ~ ~ ~ p=1.000 n=6
Symbols 1,229,708 1,229,781 +73 (+ 0.01%) ~ ~ p=0.001 n=6
Types 260,904 260,917 +13 (+ 0.00%) ~ ~ p=0.001 n=6
Memory used 2,351,266k (± 0.02%) 2,350,890k (± 0.06%) ~ 2,349,360k 2,353,094k p=0.575 n=6
Parse Time 4.98s (± 0.91%) 4.98s (± 0.85%) ~ 4.94s 5.05s p=0.936 n=6
Bind Time 1.91s (± 0.55%) 1.93s (± 0.39%) +0.03s (+ 1.40%) 1.92s 1.94s p=0.006 n=6
Check Time 34.12s (± 0.30%) 34.20s (± 0.17%) ~ 34.11s 34.27s p=0.109 n=6
Emit Time 2.56s (± 1.65%) 2.63s (± 2.41%) ~ 2.56s 2.72s p=0.066 n=6
Total Time 43.55s (± 0.21%) 43.78s (± 0.22%) +0.22s (+ 0.51%) 43.63s 43.89s p=0.013 n=6
self-build-src-public-api - node (v18.15.0, x64)
Errors 0 0 ~ ~ ~ p=1.000 n=6
Symbols 1,229,708 1,229,781 +73 (+ 0.01%) ~ ~ p=0.001 n=6
Types 260,904 260,917 +13 (+ 0.00%) ~ ~ p=0.001 n=6
Memory used 2,452,360k (± 2.48%) 2,428,222k (± 0.04%) ~ 2,427,090k 2,429,614k p=0.810 n=6
Parse Time 6.24s (± 0.45%) 6.26s (± 0.55%) ~ 6.22s 6.30s p=0.471 n=6
Bind Time 2.01s (± 0.96%) 2.20s (± 4.72%) 🔻+0.19s (+ 9.28%) 2.05s 2.27s p=0.005 n=6
Check Time 40.47s (± 0.33%) 40.48s (± 0.93%) ~ 40.18s 41.00s p=0.378 n=6
Emit Time 3.07s (± 2.70%) 3.05s (± 1.79%) ~ 2.99s 3.11s p=0.575 n=6
Total Time 51.82s (± 0.25%) 52.02s (± 0.49%) ~ 51.71s 52.35s p=0.230 n=6
self-compiler - node (v18.15.0, x64)
Errors 0 0 ~ ~ ~ p=1.000 n=6
Symbols 258,593 258,618 +25 (+ 0.01%) ~ ~ p=0.001 n=6
Types 105,011 105,024 +13 (+ 0.01%) ~ ~ p=0.001 n=6
Memory used 428,227k (± 0.01%) 428,434k (± 0.01%) +207k (+ 0.05%) 428,406k 428,469k p=0.005 n=6
Parse Time 4.06s (± 0.57%) 4.08s (± 0.38%) ~ 4.07s 4.10s p=0.210 n=6
Bind Time 1.63s (± 0.92%) 1.65s (± 1.31%) ~ 1.62s 1.68s p=0.124 n=6
Check Time 22.42s (± 0.40%) 22.43s (± 0.20%) ~ 22.37s 22.47s p=0.809 n=6
Emit Time 1.70s (± 1.93%) 1.71s (± 1.41%) ~ 1.68s 1.75s p=0.466 n=6
Total Time 29.81s (± 0.35%) 29.88s (± 0.21%) ~ 29.80s 29.95s p=0.295 n=6
ts-pre-modules - node (v18.15.0, x64)
Errors 35 35 ~ ~ ~ p=1.000 n=6
Symbols 224,565 224,565 ~ ~ ~ p=1.000 n=6
Types 93,734 93,736 +2 (+ 0.00%) ~ ~ p=0.001 n=6
Memory used 369,857k (± 0.03%) 369,994k (± 0.04%) ~ 369,826k 370,188k p=0.173 n=6
Parse Time 2.85s (± 0.79%) 2.85s (± 0.85%) ~ 2.82s 2.87s p=0.808 n=6
Bind Time 1.59s (± 0.97%) 1.60s (± 0.65%) ~ 1.59s 1.62s p=0.118 n=6
Check Time 15.73s (± 0.39%) 15.76s (± 0.27%) ~ 15.71s 15.82s p=0.746 n=6
Emit Time 0.00s 0.00s ~ ~ ~ p=1.000 n=6
Total Time 20.17s (± 0.36%) 20.21s (± 0.31%) ~ 20.12s 20.29s p=0.377 n=6
vscode - node (v18.15.0, x64)
Errors 10 90 🔻+80 (+800.00%) ~ ~ p=0.001 n=6
Symbols 2,842,991 2,847,064 +4,073 (+ 0.14%) ~ ~ p=0.001 n=6
Types 963,472 964,365 +893 (+ 0.09%) ~ ~ p=0.001 n=6
Memory used 3,015,847k (± 0.00%) 3,019,578k (± 0.00%) +3,732k (+ 0.12%) 3,019,506k 3,019,681k p=0.005 n=6
Parse Time 17.02s (± 0.26%) 17.07s (± 0.32%) ~ 17.02s 17.16s p=0.065 n=6
Bind Time 5.16s (± 2.45%) 5.21s (± 1.76%) ~ 5.17s 5.40s p=0.226 n=6
Check Time 89.08s (± 0.11%) 91.48s (± 1.87%) +2.41s (+ 2.70%) 90.25s 94.91s p=0.005 n=6
Emit Time 28.89s (± 0.78%) 28.10s (± 6.97%) ~ 24.11s 29.07s p=0.936 n=6
Total Time 140.15s (± 0.15%) 141.87s (± 0.36%) +1.72s (+ 1.23%) 141.29s 142.45s p=0.005 n=6
webpack - node (v18.15.0, x64)
Errors 0 0 ~ ~ ~ p=1.000 n=6
Symbols 266,361 266,362 +1 (+ 0.00%) ~ ~ p=0.001 n=6
Types 108,554 108,557 +3 (+ 0.00%) ~ ~ p=0.001 n=6
Memory used 411,503k (± 0.02%) 411,827k (± 0.04%) +324k (+ 0.08%) 411,629k 412,030k p=0.005 n=6
Parse Time 4.83s (± 0.54%) 4.78s (± 0.70%) -0.05s (- 1.04%) 4.73s 4.83s p=0.028 n=6
Bind Time 2.09s (± 0.58%) 2.12s (± 0.42%) +0.03s (+ 1.60%) 2.11s 2.13s p=0.005 n=6
Check Time 21.13s (± 0.16%) 21.29s (± 0.58%) ~ 21.07s 21.41s p=0.065 n=6
Emit Time 0.00s 0.00s ~ ~ ~ p=1.000 n=6
Total Time 28.05s (± 0.18%) 28.19s (± 0.38%) ~ 27.99s 28.28s p=0.066 n=6
xstate-main - node (v18.15.0, x64)
Errors 0 0 ~ ~ ~ p=1.000 n=6
Symbols 525,588 525,588 ~ ~ ~ p=1.000 n=6
Types 179,032 179,032 ~ ~ ~ p=1.000 n=6
Memory used 463,503k (± 0.07%) 463,672k (± 0.06%) ~ 463,176k 463,934k p=0.378 n=6
Parse Time 2.62s (± 0.45%) 2.62s (± 0.16%) ~ 2.62s 2.63s p=0.787 n=6
Bind Time 0.99s (± 0.41%) 1.00s (± 0.54%) +0.01s (+ 1.34%) 1.00s 1.01s p=0.006 n=6
Check Time 15.24s (± 0.62%) 15.33s (± 0.37%) ~ 15.27s 15.41s p=0.065 n=6
Emit Time 0.00s 0.00s ~ ~ ~ p=1.000 n=6
Total Time 18.85s (± 0.48%) 18.96s (± 0.30%) ~ 18.89s 19.03s p=0.054 n=6
System info unknown
Hosts
  • node (v18.15.0, x64)
Scenarios
  • Compiler-Unions - node (v18.15.0, x64)
  • angular-1 - node (v18.15.0, x64)
  • mui-docs - node (v18.15.0, x64)
  • self-build-src - node (v18.15.0, x64)
  • self-build-src-public-api - node (v18.15.0, x64)
  • self-compiler - node (v18.15.0, x64)
  • ts-pre-modules - node (v18.15.0, x64)
  • vscode - node (v18.15.0, x64)
  • webpack - node (v18.15.0, x64)
  • xstate-main - node (v18.15.0, x64)
Benchmark Name Iterations
Current pr 6
Baseline baseline 6

Developer Information:

Download Benchmarks

@fatcerberus
Copy link

I feel like this is just going to flip the problem on its head in the end - instead of people complaining because their immediately-invoked callbacks didn't affect narrowing, an equal number of people will probably now complain instead that callbacks they know will be called out-of-band do affect narrowing. The goalposts don't even move really - the other team just gets possession is all 😄

@typescript-bot
Copy link
Collaborator

@ahejlsberg Here are the results of running the top 400 repos with tsc comparing main and refs/pull/58729/merge:

Something interesting changed - please have a look.

Details

apollographql/apollo-client

1 of 12 projects failed to build with the old tsc and were ignored

tsconfig.json

  • error TS7022: 'match' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.

src/tsconfig.json

  • error TS7022: 'match' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.

conwnet/github1s

extensions/github1s/tsconfig.json

electron-react-boilerplate/electron-react-boilerplate

tsconfig.json

highcharts/highcharts

25 of 26 projects failed to build with the old tsc and were ignored

test/ts-node-unit-tests/tsconfig.json

labring/FastGPT

projects/app/tsconfig.json

packages/service/tsconfig.json

lyswhut/lx-music-desktop

1 of 6 projects failed to build with the old tsc and were ignored

src/main/tsconfig.json

microsoft/vscode

7 of 54 projects failed to build with the old tsc and were ignored

extensions/vscode-test-resolver/tsconfig.json

extensions/vscode-api-tests/tsconfig.json

reduxjs/redux-toolkit

11 of 32 projects failed to build with the old tsc and were ignored

packages/toolkit/tsconfig.build.json

subquery/subql

2 of 6 projects failed to build with the old tsc and were ignored

tsconfig.json

tinacms/tinacms

12 of 24 projects failed to build with the old tsc and were ignored

packages/@tinacms/mdx/tsconfig.json

@ahejlsberg
Copy link
Member Author

I think it's clear that there's no one-size-fits-all answer to whether effects of executing lambda arguments should be reflected in CFA types. Our current assumption is that lambdas are never executed synchronously. This PR experiments with the assumption they're possibly executed, which, given no additional information about the function to which the lambda arguments are passed, is definitely a more sound assumption. Also, the PR validates an implementation strategy and gives us data on the performance cost of analyzing lambda effects.

I would nice to avoid modifiers (like sync, immediate, deferred) on callback parameters, but in the end it may be unavoidable. Modifiers come with the added complication that CFA will need to resolve the function's type, which may in turn lead to circularities.

@ahejlsberg
Copy link
Member Author

@typescript-bot test it

@typescript-bot
Copy link
Collaborator

typescript-bot commented Jun 3, 2024

Starting jobs; this comment will be updated as builds start and complete.

Command Status Results
test top400 ✅ Started 👀 Results
user test this ✅ Started 👀 Results
run dt ✅ Started ✅ Results
perf test this faster ✅ Started 👀 Results

@typescript-bot
Copy link
Collaborator

Hey @ahejlsberg, the results of running the DT tests are ready.

Everything looks the same!

You can check the log here.

@typescript-bot
Copy link
Collaborator

@ahejlsberg
The results of the perf run you requested are in!

Here they are:

tsc

Comparison Report - baseline..pr
Metric baseline pr Delta Best Worst p-value
Compiler-Unions - node (v18.15.0, x64)
Errors 30 30 ~ ~ ~ p=1.000 n=6
Symbols 62,153 62,153 ~ ~ ~ p=1.000 n=6
Types 50,242 50,243 +1 (+ 0.00%) ~ ~ p=0.001 n=6
Memory used 193,572k (± 1.01%) 193,028k (± 0.73%) ~ 192,339k 195,911k p=0.378 n=6
Parse Time 1.29s (± 0.94%) 1.29s (± 0.81%) ~ 1.28s 1.31s p=0.868 n=6
Bind Time 0.72s 0.74s +0.02s (+ 2.78%) ~ ~ p=0.001 n=6
Check Time 9.57s (± 0.23%) 9.59s (± 0.70%) ~ 9.48s 9.66s p=0.468 n=6
Emit Time 2.76s (± 0.20%) 2.75s (± 0.74%) ~ 2.72s 2.78s p=0.100 n=6
Total Time 14.35s (± 0.16%) 14.37s (± 0.48%) ~ 14.25s 14.44s p=0.195 n=6
angular-1 - node (v18.15.0, x64)
Errors 5 9 🔻+4 (+80.00%) ~ ~ p=0.001 n=6
Symbols 944,109 944,283 +174 (+ 0.02%) ~ ~ p=0.001 n=6
Types 407,049 407,096 +47 (+ 0.01%) ~ ~ p=0.001 n=6
Memory used 1,222,193k (± 0.00%) 1,223,909k (± 0.00%) +1,717k (+ 0.14%) 1,223,856k 1,223,966k p=0.005 n=6
Parse Time 6.80s (± 0.47%) 6.79s (± 0.50%) ~ 6.74s 6.84s p=0.420 n=6
Bind Time 1.88s (± 0.29%) 1.91s (± 0.57%) +0.03s (+ 1.87%) 1.89s 1.92s p=0.004 n=6
Check Time 31.38s (± 0.34%) 31.71s (± 0.56%) +0.34s (+ 1.07%) 31.49s 31.98s p=0.006 n=6
Emit Time 15.21s (± 0.97%) 15.20s (± 0.32%) ~ 15.12s 15.24s p=0.575 n=6
Total Time 55.26s (± 0.23%) 55.60s (± 0.41%) +0.34s (+ 0.62%) 55.33s 55.97s p=0.013 n=6
mui-docs - node (v18.15.0, x64)
Errors 5 5 ~ ~ ~ p=1.000 n=6
Symbols 2,054,061 2,054,090 +29 (+ 0.00%) ~ ~ p=0.001 n=6
Types 899,813 899,836 +23 (+ 0.00%) ~ ~ p=0.001 n=6
Memory used 2,067,140k (± 0.01%) 2,067,295k (± 0.01%) ~ 2,067,100k 2,067,509k p=0.336 n=6
Parse Time 8.10s (± 0.18%) 8.13s (± 0.34%) ~ 8.10s 8.17s p=0.120 n=6
Bind Time 2.75s (± 0.90%) 2.78s (± 0.87%) ~ 2.74s 2.80s p=0.145 n=6
Check Time 82.19s (± 0.36%) 82.05s (± 0.55%) ~ 81.46s 82.49s p=0.689 n=6
Emit Time 0.16s 0.17s (± 4.89%) ~ 0.16s 0.18s p=0.073 n=6
Total Time 93.21s (± 0.31%) 93.12s (± 0.51%) ~ 92.53s 93.57s p=1.000 n=6
self-build-src - node (v18.15.0, x64)
Errors 0 0 ~ ~ ~ p=1.000 n=6
Symbols 1,229,585 1,229,658 +73 (+ 0.01%) ~ ~ p=0.001 n=6
Types 260,899 260,912 +13 (+ 0.00%) ~ ~ p=0.001 n=6
Memory used 2,350,738k (± 0.02%) 2,350,985k (± 0.04%) ~ 2,350,160k 2,352,793k p=0.810 n=6
Parse Time 4.99s (± 1.00%) 4.99s (± 0.76%) ~ 4.95s 5.05s p=1.000 n=6
Bind Time 1.91s (± 0.51%) 1.94s (± 0.51%) +0.03s (+ 1.39%) 1.92s 1.95s p=0.008 n=6
Check Time 33.99s (± 0.36%) 34.19s (± 0.34%) +0.20s (+ 0.59%) 33.98s 34.28s p=0.031 n=6
Emit Time 2.58s (± 1.35%) 2.65s (± 3.33%) ~ 2.52s 2.73s p=0.230 n=6
Total Time 43.50s (± 0.31%) 43.78s (± 0.47%) +0.27s (+ 0.63%) 43.41s 43.94s p=0.045 n=6
self-build-src-public-api - node (v18.15.0, x64)
Errors 0 0 ~ ~ ~ p=1.000 n=6
Symbols 1,229,585 1,229,658 +73 (+ 0.01%) ~ ~ p=0.001 n=6
Types 260,899 260,912 +13 (+ 0.00%) ~ ~ p=0.001 n=6
Memory used 2,451,724k (± 2.52%) 2,426,666k (± 0.04%) ~ 2,426,036k 2,428,177k p=0.810 n=6
Parse Time 5.20s (± 0.51%) 5.16s (± 0.65%) -0.04s (- 0.83%) 5.12s 5.21s p=0.037 n=6
Bind Time 1.68s (± 0.58%) 1.89s (± 4.74%) 🔻+0.21s (+12.29%) 1.71s 1.95s p=0.004 n=6
Check Time 34.45s (± 0.15%) 34.35s (± 0.58%) ~ 34.13s 34.70s p=0.092 n=6
Emit Time 2.64s (± 3.81%) 2.64s (± 2.98%) ~ 2.56s 2.77s p=0.936 n=6
Total Time 43.99s (± 0.19%) 44.07s (± 0.39%) ~ 43.78s 44.31s p=0.230 n=6
self-compiler - node (v18.15.0, x64)
Errors 0 0 ~ ~ ~ p=1.000 n=6
Symbols 258,592 258,617 +25 (+ 0.01%) ~ ~ p=0.001 n=6
Types 105,012 105,025 +13 (+ 0.01%) ~ ~ p=0.001 n=6
Memory used 428,264k (± 0.01%) 428,428k (± 0.01%) +165k (+ 0.04%) 428,359k 428,468k p=0.005 n=6
Parse Time 4.08s (± 0.22%) 4.07s (± 0.57%) ~ 4.05s 4.10s p=0.685 n=6
Bind Time 1.64s (± 1.89%) 1.67s (± 0.99%) ~ 1.64s 1.69s p=0.103 n=6
Check Time 22.39s (± 0.10%) 22.40s (± 0.38%) ~ 22.32s 22.52s p=1.000 n=6
Emit Time 1.72s (± 0.61%) 1.72s (± 0.70%) ~ 1.71s 1.74s p=0.868 n=6
Total Time 29.84s (± 0.20%) 29.87s (± 0.31%) ~ 29.76s 30.02s p=1.000 n=6
ts-pre-modules - node (v18.15.0, x64)
Errors 35 35 ~ ~ ~ p=1.000 n=6
Symbols 224,565 224,565 ~ ~ ~ p=1.000 n=6
Types 93,734 93,736 +2 (+ 0.00%) ~ ~ p=0.001 n=6
Memory used 369,775k (± 0.01%) 369,980k (± 0.02%) +206k (+ 0.06%) 369,875k 370,097k p=0.005 n=6
Parse Time 2.84s (± 0.87%) 2.84s (± 1.03%) ~ 2.80s 2.87s p=1.000 n=6
Bind Time 1.58s (± 0.84%) 1.61s (± 0.64%) +0.03s (+ 1.80%) 1.59s 1.62s p=0.011 n=6
Check Time 15.72s (± 0.48%) 15.74s (± 0.38%) ~ 15.65s 15.82s p=0.376 n=6
Emit Time 0.00s 0.00s ~ ~ ~ p=1.000 n=6
Total Time 20.14s (± 0.33%) 20.18s (± 0.40%) ~ 20.06s 20.30s p=0.226 n=6
vscode - node (v18.15.0, x64)
Errors 0 79 🔻+79 (+ ∞%) ~ ~ p=0.001 n=6
Symbols 2,845,596 2,849,669 +4,073 (+ 0.14%) ~ ~ p=0.001 n=6
Types 964,085 964,978 +893 (+ 0.09%) ~ ~ p=0.001 n=6
Memory used 3,017,140k (± 0.00%) 3,021,037k (± 0.00%) +3,897k (+ 0.13%) 3,020,987k 3,021,138k p=0.005 n=6
Parse Time 13.90s (± 0.17%) 13.88s (± 0.23%) ~ 13.83s 13.93s p=0.326 n=6
Bind Time 4.23s (± 2.59%) 4.27s (± 1.80%) ~ 4.20s 4.42s p=0.230 n=6
Check Time 73.40s (± 0.42%) 75.35s (± 2.27%) +1.95s (+ 2.66%) 74.38s 78.83s p=0.005 n=6
Emit Time 23.70s (± 0.61%) 23.06s (± 7.06%) ~ 19.75s 23.90s p=0.810 n=6
Total Time 115.23s (± 0.26%) 116.57s (± 0.11%) +1.34s (+ 1.17%) 116.36s 116.75s p=0.005 n=6
webpack - node (v18.15.0, x64)
Errors 0 0 ~ ~ ~ p=1.000 n=6
Symbols 266,361 266,362 +1 (+ 0.00%) ~ ~ p=0.001 n=6
Types 108,554 108,557 +3 (+ 0.00%) ~ ~ p=0.001 n=6
Memory used 411,328k (± 0.03%) 411,647k (± 0.02%) +320k (+ 0.08%) 411,571k 411,847k p=0.005 n=6
Parse Time 3.84s (± 0.39%) 3.84s (± 0.50%) ~ 3.82s 3.87s p=0.677 n=6
Bind Time 1.66s (± 0.82%) 1.70s (± 0.69%) +0.04s (+ 2.30%) 1.69s 1.72s p=0.005 n=6
Check Time 17.02s (± 0.27%) 17.12s (± 0.29%) +0.10s (+ 0.59%) 17.05s 17.19s p=0.008 n=6
Emit Time 0.00s 0.00s ~ ~ ~ p=1.000 n=6
Total Time 22.52s (± 0.23%) 22.66s (± 0.22%) +0.14s (+ 0.61%) 22.62s 22.72s p=0.005 n=6
xstate-main - node (v18.15.0, x64)
Errors 0 0 ~ ~ ~ p=1.000 n=6
Symbols 526,436 526,436 ~ ~ ~ p=1.000 n=6
Types 179,425 179,425 ~ ~ ~ p=1.000 n=6
Memory used 464,088k (± 0.06%) 464,116k (± 0.08%) ~ 463,817k 464,702k p=0.936 n=6
Parse Time 3.15s (± 0.56%) 3.16s (± 0.68%) ~ 3.13s 3.18s p=0.870 n=6
Bind Time 1.19s (± 0.43%) 1.20s (± 0.53%) +0.01s (+ 1.12%) 1.19s 1.21s p=0.009 n=6
Check Time 18.20s (± 0.30%) 18.12s (± 0.26%) -0.08s (- 0.47%) 18.05s 18.18s p=0.037 n=6
Emit Time 0.00s 0.00s ~ ~ ~ p=1.000 n=6
Total Time 22.54s (± 0.30%) 22.48s (± 0.25%) ~ 22.37s 22.53s p=0.148 n=6
System info unknown
Hosts
  • node (v18.15.0, x64)
Scenarios
  • Compiler-Unions - node (v18.15.0, x64)
  • angular-1 - node (v18.15.0, x64)
  • mui-docs - node (v18.15.0, x64)
  • self-build-src - node (v18.15.0, x64)
  • self-build-src-public-api - node (v18.15.0, x64)
  • self-compiler - node (v18.15.0, x64)
  • ts-pre-modules - node (v18.15.0, x64)
  • vscode - node (v18.15.0, x64)
  • webpack - node (v18.15.0, x64)
  • xstate-main - node (v18.15.0, x64)
Benchmark Name Iterations
Current pr 6
Baseline baseline 6

Developer Information:

Download Benchmarks

@typescript-bot
Copy link
Collaborator

@ahejlsberg Here are the results of running the user tests with tsc comparing main and refs/pull/58729/merge:

Something interesting changed - please have a look.

Details

enhanced-resolve

/mnt/ts_downloads/_/m/enhanced-resolve/tsconfig.json

  • [MISSING] error TS2339: Property 'replace' does not exist on type 'never'.
    • /mnt/ts_downloads/_/m/enhanced-resolve/node_modules/enhanced-resolve/lib/concord.js(149,24)
    • /mnt/ts_downloads/_/m/enhanced-resolve/node_modules/enhanced-resolve/lib/concord.js(188,17)

pyright

/mnt/ts_downloads/_/m/pyright/build.sh

  • [NEW] error TS18048: 'cacheEntry' is possibly 'undefined'.
    • /mnt/ts_downloads/_/m/pyright/pyright: ../pyright-internal/src/analyzer/codeFlowEngine.ts(951,25)
    • /mnt/ts_downloads/_/m/pyright/pyright: ../pyright-internal/src/analyzer/codeFlowEngine.ts(1064,41)
    • /mnt/ts_downloads/_/m/pyright/pyright-internal: src/analyzer/codeFlowEngine.ts(951,25)
    • /mnt/ts_downloads/_/m/pyright/pyright-internal: src/analyzer/codeFlowEngine.ts(1064,41)
    • /mnt/ts_downloads/_/m/pyright/vscode-pyright: ../pyright-internal/src/analyzer/codeFlowEngine.ts(951,25)
    • /mnt/ts_downloads/_/m/pyright/vscode-pyright: ../pyright-internal/src/analyzer/codeFlowEngine.ts(1064,41)

uglify-js

/mnt/ts_downloads/_/m/uglify-js/tsconfig.json

  • [MISSING] error TS18048: 'ldef' is possibly 'undefined'.
    • /mnt/ts_downloads/_/m/uglify-js/node_modules/uglify-js/lib/compress.js(6753,56)

xterm.js

src/tsconfig-library-base.json

@typescript-bot
Copy link
Collaborator

@ahejlsberg Here are the results of running the top 400 repos with tsc comparing main and refs/pull/58729/merge:

Something interesting changed - please have a look.

Details

apollographql/apollo-client

1 of 12 projects failed to build with the old tsc and were ignored

tsconfig.json

  • error TS7022: 'match' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.

src/tsconfig.json

  • error TS7022: 'match' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.

conwnet/github1s

extensions/github1s/tsconfig.json

electron-react-boilerplate/electron-react-boilerplate

tsconfig.json

labring/FastGPT

projects/app/tsconfig.json

packages/service/tsconfig.json

lyswhut/lx-music-desktop

1 of 6 projects failed to build with the old tsc and were ignored

src/main/tsconfig.json

microsoft/vscode

4 of 54 projects failed to build with the old tsc and were ignored

src/tsconfig.tsec.json

src/tsconfig.monaco.json

src/tsconfig.json

extensions/vscode-test-resolver/tsconfig.json

extensions/vscode-api-tests/tsconfig.json

tinacms/tinacms

12 of 24 projects failed to build with the old tsc and were ignored

packages/@tinacms/mdx/tsconfig.json

@ethanresnick
Copy link
Contributor

ethanresnick commented Jun 5, 2024

@ahejlsberg If I'm understanding correctly, this would apply to arguments that are declared as arrow functions or function expressions, but not function declarations. Is that right? If so, why exclude function declarations?

(FWIW, I do like this experiment and the attempt at added strictness, if it ends up not being too breaking.)

@ahejlsberg
Copy link
Member Author

@ethanresnick It only applies to arrow functions and function expressions passed directly as arguments. It does not apply to functions referenced through identifiers or other indirect expression constructs.

@typescript-bot
Copy link
Collaborator

Looks like you're introducing a change to the public API surface area. If this includes breaking changes, please document them on our wiki's API Breaking Changes page.

Also, please make sure @DanielRosenwasser and @RyanCavanaugh are aware of the changes, just as a heads up.

@ahejlsberg
Copy link
Member Author

@typescript-bot test it

@g-plane
Copy link
Contributor

g-plane commented Jun 20, 2024

Are there any reasons about using deferred keyword instead of Deferred<T>? Also, what about move the deferred before function type but after parameter name like this:

function setTimeout(callback: deferred (args: void) => void, ms?: number): NodeJS.Timeout;
function setTimeout(callback: deferred Function, ms?: number): NodeJS.Timeout;

@magic-akari
Copy link
Contributor

magic-akari commented Jun 20, 2024

class Foo {
    constructor(deferred public a: () => void) { }
}

class Bar {
    constructor(public deferred a: () => void) { }
}

It seems that both orders are acceptable, is this expected?

https://www.typescriptlang.org/play/?ts=5.6.0-pr-58729-66#code/MYGwhgzhAEBiD29oG8BQ0PWPAdhALgE4Cuw+8hAFACYCmAZrYYbddAA7EBGIAlsNDAAuaJQCU0ALwA+aADd4vahOTQAvqg2pQkGACEwhFOkzY8RUuSqce-aHUbNWgkeKmyFSles1A

@ahejlsberg
Copy link
Member Author

Are there any reasons about using deferred keyword instead of Deferred<T>?

One reason is that the "deferred" nature of a parameter is an attribute of the parameter itself, not the parameter's type. Another reason is that a Deferred<T> marker type could appear in a number of situations where it would have no effect (for example as the type of a local variable or property), which would be confusing.

Also, what about move the deferred before function type but after parameter

That would make deferred an attribute of the type, which we want to avoid for the same reasons as Deferred<T> above.

@ahejlsberg
Copy link
Member Author

It seems that both orders are acceptable, is this expected?

No, we should verify that deferred appears as the first modifier.

# Conflicts:
#	src/compiler/diagnosticMessages.json
#	tests/baselines/reference/asyncYieldStarContextualType.types
#	tests/baselines/reference/awaitedType.types
#	tests/baselines/reference/contextuallyTypeAsyncFunctionReturnTypeFromUnion.types
#	tests/baselines/reference/declarationEmitExportAliasVisibiilityMarking.types
#	tests/baselines/reference/declarationEmitUsingAlternativeContainingModules1.types
#	tests/baselines/reference/declarationEmitUsingAlternativeContainingModules2.types
#	tests/baselines/reference/destructureOfVariableSameAsShorthand.types
#	tests/baselines/reference/esModuleInteropImportCall.types
#	tests/baselines/reference/genericFunctionInference1.types
#	tests/baselines/reference/importCallExpression1ES2020.types
#	tests/baselines/reference/importCallExpression2ES2020.types
#	tests/baselines/reference/importCallExpression4ES2020.types
#	tests/baselines/reference/importCallExpressionES5AMD.types
#	tests/baselines/reference/importCallExpressionES5CJS.types
#	tests/baselines/reference/importCallExpressionES5System.types
#	tests/baselines/reference/importCallExpressionES5UMD.types
#	tests/baselines/reference/importCallExpressionES6AMD.types
#	tests/baselines/reference/importCallExpressionES6CJS.types
#	tests/baselines/reference/importCallExpressionES6System.types
#	tests/baselines/reference/importCallExpressionES6UMD.types
#	tests/baselines/reference/importCallExpressionErrorInES2015.types
#	tests/baselines/reference/importCallExpressionInAMD1.types
#	tests/baselines/reference/importCallExpressionInAMD2.types
#	tests/baselines/reference/importCallExpressionInAMD4.types
#	tests/baselines/reference/importCallExpressionInCJS1.types
#	tests/baselines/reference/importCallExpressionInCJS3.types
#	tests/baselines/reference/importCallExpressionInCJS5.types
#	tests/baselines/reference/importCallExpressionInSystem1.types
#	tests/baselines/reference/importCallExpressionInSystem2.types
#	tests/baselines/reference/importCallExpressionInSystem4.types
#	tests/baselines/reference/importCallExpressionInUMD1.types
#	tests/baselines/reference/importCallExpressionInUMD2.types
#	tests/baselines/reference/importCallExpressionInUMD4.types
#	tests/baselines/reference/importCallExpressionNoModuleKindSpecified.types
#	tests/baselines/reference/importCallExpressionReturnPromiseOfAny.types
#	tests/baselines/reference/importCallExpressionShouldNotGetParen.types
#	tests/baselines/reference/importCallExpressionSpecifierNotStringTypeError.types
#	tests/baselines/reference/inferenceLimit.types
#	tests/baselines/reference/instantiateContextualTypes.types
#	tests/baselines/reference/mappedTypesGenericTuples2.types
#	tests/baselines/reference/modularizeLibrary_Dom.asynciterable.types
#	tests/baselines/reference/modularizeLibrary_NoErrorDuplicateLibOptions1.types
#	tests/baselines/reference/modularizeLibrary_NoErrorDuplicateLibOptions2.types
#	tests/baselines/reference/modularizeLibrary_TargetES5UsingES6Lib.types
#	tests/baselines/reference/modularizeLibrary_Worker.asynciterable.types
#	tests/baselines/reference/moduleResolutionWithoutExtension5.types
#	tests/baselines/reference/moduleResolutionWithoutExtension8.types
#	tests/baselines/reference/privateNameMethodAsync.types
#	tests/baselines/reference/promisePermutations.types
#	tests/baselines/reference/promisePermutations2.types
#	tests/baselines/reference/promisePermutations3.types
#	tests/baselines/reference/promiseTest.types
#	tests/baselines/reference/promiseType.types
#	tests/baselines/reference/promiseTypeStrictNull.types
#	tests/baselines/reference/promiseVoidErrorCallback.types
#	tests/baselines/reference/promises.types
#	tests/baselines/reference/specializationError.types
#	tests/baselines/reference/syntheticDefaultExportsWithDynamicImports.types
#	tests/baselines/reference/truthinessPromiseCoercion.types
#	tests/baselines/reference/unionAndIntersectionInference1.types
#	tests/baselines/reference/unionOfClassCalls.types
@yume-chan
Copy link
Contributor

yume-chan commented Jun 20, 2024

Function parameters can also be declared using tuples, would the deferred modifier be allowed there?

function a(...args: [deferred () => void]): void {} // The tuple element can have no name, so this looks very differently
function b(...args: [deferred callback: () => void]): void {}
function c(...args: Parameters<typeof a>): void {} // Still deferred?

EDIT: mentioned by @codehz , function parameter can also be an object with function properties:

function d(props: { a: () => void, b: () => void }) {
    props.a();
    props.b();
}

Would the deferred modifier allowed before property keys?


Would TypeScript check the function body to ensure a non-deferred callback parameter is actually (or at least might) synchronously called?

function a(callback: () => void) { } // Error: `callback` is marked as synchronous but not synchronously invoked

function b(callback: () => void) { // Error: `callback` is marked as synchronous but not synchronously invoked
    setTimeout(callback, 1000);
}

function c(callback: () => void) { // OK
    if (Math.random() > 0.5) {
        callback();
    }
}

I think the Deferred<T> approach supports the tuple case with minimal change.

It might also be beneficial to allow the call site to specify whether an argument will be invoked synchronously or not, especially when library authors has not adopted the change into their typings, so there will be many callbacks mistakenly considered synchronous.

// library.d.ts
declare function doThingsAsync(callback: () => void): void; // Not updated

// src/index.ts
let x: string | undefined;
doThingsAsync((() => { x = "foo" }) as Deferred<() => void>);
x; // Still `string | undefined`

@ahejlsberg
Copy link
Member Author

Function parameters can also be declared using tuples, would the deferred modifier be allowed there?

No. The deferred modifier can only be applied to parameters (and not tuple elements), which reflects the reality of how control flow analysis analyzes deferred callback parameters: It just looks at the modifiers associated with the particular position of the parameter in the parameter list, avoiding the numerous circularities that full type resolution of the call signature would otherwise cause (another reason Deferred<T> isn't really an option).

Would TypeScript check the function body to ensure a non-deferred callback parameter is actually (or at least might) synchronously called?

We discussed doing this, but it's not clear how useful it would be, and there are several complex issues. We could potentially check that no calls are made directly through the deferred parameter in the body of the function, but that is quickly defeated by us not analyzing aliasing and calls made to other functions. And attempting to track it in types such as Deferred<T> is even more daunting. It's not enough to know that a function reference is deferred, you'd also need to know with respect to what and somehow track that.

It might also be beneficial to allow the call site to specify whether an argument will be invoked synchronously or not

The recommendation here is to use a simple wrapper function that just returns its argument:

function deferred<T extends (...args: any) => any>(deferred cb: T) { return cb }

declare function doThingsAsync(callback: () => void): void; // Not updated

let xx: string | undefined = undefined;
doThingsAsync(deferred(() => { xx = "foo" }));
xx; // Still undefined

@DanielRosenwasser
Copy link
Member

DanielRosenwasser commented Jun 24, 2024

@typescript-bot test this
@typescript-bot pack this

@typescript-bot
Copy link
Collaborator

typescript-bot commented Jun 24, 2024

Starting jobs; this comment will be updated as builds start and complete.

Command Status Results
pack this ✅ Started ✅ Results

@typescript-bot
Copy link
Collaborator

typescript-bot commented Jun 24, 2024

Hey @DanielRosenwasser, I've packed this into an installable tgz. You can install it for testing by referencing it in your package.json like so:

{
    "devDependencies": {
        "typescript": "https://typescript.visualstudio.com/cf7ac146-d525-443c-b23c-0d58337efebc/_apis/build/builds/162379/artifacts?artifactName=tgz&fileId=8E028D13A8759944922C675AFC58931ADDB828C74FA4502ABB10508C8F5CC06F02&fileName=/typescript-5.6.0-insiders.20240624.tgz"
    }
}

and then running npm install.


There is also a playground for this build and an npm module you can use via "typescript": "npm:@typescript-deploys/[email protected]".;

@DanielRosenwasser
Copy link
Member

@typescript-bot test it

@typescript-bot
Copy link
Collaborator

typescript-bot commented Jun 24, 2024

Starting jobs; this comment will be updated as builds start and complete.

Command Status Results
test top400 ✅ Started 👀 Results
user test this ✅ Started 👀 Results
run dt ✅ Started ✅ Results
perf test this faster ✅ Started 👀 Results

@typescript-bot
Copy link
Collaborator

Hey @DanielRosenwasser, the results of running the DT tests are ready.

Everything looks the same!

You can check the log here.

@typescript-bot
Copy link
Collaborator

@DanielRosenwasser Here are the results of running the user tests with tsc comparing main and refs/pull/58729/merge:

Something interesting changed - please have a look.

Details

enhanced-resolve

/mnt/ts_downloads/_/m/enhanced-resolve/tsconfig.json

  • [MISSING] error TS2339: Property 'replace' does not exist on type 'never'.
    • /mnt/ts_downloads/_/m/enhanced-resolve/node_modules/enhanced-resolve/lib/concord.js(149,24)
    • /mnt/ts_downloads/_/m/enhanced-resolve/node_modules/enhanced-resolve/lib/concord.js(188,17)

pyright

/mnt/ts_downloads/_/m/pyright/build.sh

  • [NEW] error TS18048: 'cacheEntry' is possibly 'undefined'.
    • /mnt/ts_downloads/_/m/pyright/pyright: ../pyright-internal/src/analyzer/codeFlowEngine.ts(943,25)
    • /mnt/ts_downloads/_/m/pyright/pyright: ../pyright-internal/src/analyzer/codeFlowEngine.ts(1056,41)
    • /mnt/ts_downloads/_/m/pyright/pyright-internal: src/analyzer/codeFlowEngine.ts(943,25)
    • /mnt/ts_downloads/_/m/pyright/pyright-internal: src/analyzer/codeFlowEngine.ts(1056,41)
    • /mnt/ts_downloads/_/m/pyright/vscode-pyright: ../pyright-internal/src/analyzer/codeFlowEngine.ts(943,25)
    • /mnt/ts_downloads/_/m/pyright/vscode-pyright: ../pyright-internal/src/analyzer/codeFlowEngine.ts(1056,41)

uglify-js

/mnt/ts_downloads/_/m/uglify-js/tsconfig.json

  • [MISSING] error TS18048: 'ldef' is possibly 'undefined'.
    • /mnt/ts_downloads/_/m/uglify-js/node_modules/uglify-js/lib/compress.js(6896,56)

xterm.js

src/tsconfig-library-base.json

@typescript-bot
Copy link
Collaborator

@DanielRosenwasser
The results of the perf run you requested are in!

Here they are:

tsc

Comparison Report - baseline..pr
Metric baseline pr Delta Best Worst p-value
Compiler-Unions - node (v18.15.0, x64)
Errors 30 30 ~ ~ ~ p=1.000 n=6
Symbols 62,153 62,153 ~ ~ ~ p=1.000 n=6
Types 50,242 50,243 +1 (+ 0.00%) ~ ~ p=0.001 n=6
Memory used 193,384k (± 0.94%) 192,835k (± 0.76%) ~ 192,149k 195,833k p=0.689 n=6
Parse Time 1.31s (± 0.64%) 1.31s (± 0.42%) ~ 1.30s 1.31s p=0.855 n=6
Bind Time 0.71s 0.75s 🔻+0.04s (+ 5.63%) ~ ~ p=0.001 n=6
Check Time 9.42s (± 0.38%) 9.45s (± 0.28%) ~ 9.42s 9.49s p=0.226 n=6
Emit Time 2.74s (± 0.64%) 2.74s (± 0.71%) ~ 2.71s 2.77s p=0.805 n=6
Total Time 14.18s (± 0.17%) 14.24s (± 0.21%) +0.06s (+ 0.46%) 14.21s 14.28s p=0.010 n=6
angular-1 - node (v18.15.0, x64)
Errors 5 6 🔻+1 (+20.00%) ~ ~ p=0.001 n=6
Symbols 944,114 944,287 +173 (+ 0.02%) ~ ~ p=0.001 n=6
Types 407,051 407,101 +50 (+ 0.01%) ~ ~ p=0.001 n=6
Memory used 1,218,334k (± 0.00%) 1,218,920k (± 0.00%) +586k (+ 0.05%) 1,218,880k 1,219,006k p=0.005 n=6
Parse Time 6.67s (± 0.44%) 6.64s (± 0.66%) ~ 6.59s 6.68s p=0.466 n=6
Bind Time 1.88s (± 1.06%) 1.91s (± 0.43%) +0.03s (+ 1.42%) 1.90s 1.92s p=0.048 n=6
Check Time 30.68s (± 0.38%) 30.63s (± 0.39%) ~ 30.50s 30.85s p=0.376 n=6
Emit Time 13.58s (± 0.26%) 13.56s (± 0.36%) ~ 13.49s 13.62s p=0.418 n=6
Total Time 52.80s (± 0.24%) 52.73s (± 0.16%) ~ 52.63s 52.87s p=0.377 n=6
mui-docs - node (v18.15.0, x64)
Errors 0 0 ~ ~ ~ p=1.000 n=6
Symbols 2,135,096 2,135,123 +27 (+ 0.00%) ~ ~ p=0.001 n=6
Types 927,167 927,187 +20 (+ 0.00%) ~ ~ p=0.001 n=6
Memory used 2,117,449k (± 0.01%) 2,117,649k (± 0.01%) ~ 2,117,448k 2,117,756k p=0.092 n=6
Parse Time 7.91s (± 0.30%) 7.87s (± 0.33%) -0.03s (- 0.44%) 7.85s 7.92s p=0.043 n=6
Bind Time 2.77s (± 0.99%) 2.79s (± 2.45%) ~ 2.73s 2.92s p=1.000 n=6
Check Time 83.66s (± 1.10%) 83.88s (± 0.56%) ~ 83.18s 84.57s p=0.936 n=6
Emit Time 0.16s (± 3.16%) 0.16s (± 4.65%) ~ 0.15s 0.17s p=0.784 n=6
Total Time 94.50s (± 0.93%) 94.70s (± 0.49%) ~ 93.95s 95.33s p=0.936 n=6
self-build-src - node (v18.15.0, x64)
Errors 0 0 ~ ~ ~ p=1.000 n=6
Symbols 1,230,971 1,231,474 +503 (+ 0.04%) ~ ~ p=0.001 n=6
Types 261,249 261,366 +117 (+ 0.04%) ~ ~ p=0.001 n=6
Memory used 2,345,459k (± 0.05%) 2,347,952k (± 0.05%) +2,494k (+ 0.11%) 2,346,754k 2,349,641k p=0.008 n=6
Parse Time 5.01s (± 0.95%) 5.05s (± 0.92%) ~ 4.96s 5.09s p=0.261 n=6
Bind Time 1.91s (± 1.30%) 1.97s (± 1.16%) +0.06s (+ 3.05%) 1.94s 1.99s p=0.004 n=6
Check Time 33.82s (± 0.26%) 33.87s (± 0.29%) ~ 33.69s 33.96s p=0.298 n=6
Emit Time 2.72s (± 3.40%) 2.71s (± 3.76%) ~ 2.59s 2.86s p=0.936 n=6
Total Time 43.49s (± 0.36%) 43.62s (± 0.31%) ~ 43.48s 43.87s p=0.229 n=6
self-build-src-public-api - node (v18.15.0, x64)
Errors 0 0 ~ ~ ~ p=1.000 n=6
Symbols 1,230,971 1,231,474 +503 (+ 0.04%) ~ ~ p=0.001 n=6
Types 261,249 261,366 +117 (+ 0.04%) ~ ~ p=0.001 n=6
Memory used 2,421,595k (± 0.04%) 2,423,495k (± 0.04%) +1,900k (+ 0.08%) 2,422,009k 2,424,310k p=0.031 n=6
Parse Time 5.15s (± 1.00%) 5.12s (± 0.87%) ~ 5.06s 5.18s p=0.378 n=6
Bind Time 1.69s (± 0.44%) 1.75s (± 0.60%) +0.05s (+ 3.15%) 1.73s 1.76s p=0.005 n=6
Check Time 34.13s (± 0.22%) 34.30s (± 0.28%) +0.18s (+ 0.51%) 34.18s 34.42s p=0.013 n=6
Emit Time 2.72s (± 3.00%) 2.71s (± 3.48%) ~ 2.61s 2.81s p=0.873 n=6
Total Time 43.71s (± 0.33%) 43.92s (± 0.37%) +0.21s (+ 0.48%) 43.69s 44.09s p=0.045 n=6
self-compiler - node (v18.15.0, x64)
Errors 0 0 ~ ~ ~ p=1.000 n=6
Symbols 258,575 258,711 +136 (+ 0.05%) ~ ~ p=0.001 n=6
Types 104,825 104,891 +66 (+ 0.06%) ~ ~ p=0.001 n=6
Memory used 428,213k (± 0.01%) 428,737k (± 0.01%) +525k (+ 0.12%) 428,705k 428,776k p=0.005 n=6
Parse Time 3.30s (± 0.92%) 3.34s (± 0.52%) +0.04s (+ 1.16%) 3.32s 3.36s p=0.029 n=6
Bind Time 1.32s (± 1.72%) 1.35s (± 1.21%) +0.04s (+ 2.92%) 1.33s 1.37s p=0.015 n=6
Check Time 17.77s (± 0.41%) 17.85s (± 0.58%) ~ 17.76s 18.02s p=0.229 n=6
Emit Time 1.37s (± 1.34%) 1.37s (± 0.85%) ~ 1.35s 1.38s p=0.805 n=6
Total Time 23.76s (± 0.29%) 23.92s (± 0.41%) +0.16s (+ 0.65%) 23.81s 24.07s p=0.008 n=6
ts-pre-modules - node (v18.15.0, x64)
Errors 35 35 ~ ~ ~ p=1.000 n=6
Symbols 224,565 224,565 ~ ~ ~ p=1.000 n=6
Types 93,734 93,736 +2 (+ 0.00%) ~ ~ p=0.001 n=6
Memory used 369,495k (± 0.03%) 369,531k (± 0.02%) ~ 369,464k 369,663k p=0.630 n=6
Parse Time 2.75s (± 0.91%) 2.78s (± 1.10%) ~ 2.73s 2.80s p=0.071 n=6
Bind Time 1.59s (± 1.28%) 1.63s (± 0.74%) +0.04s (+ 2.20%) 1.62s 1.65s p=0.031 n=6
Check Time 15.48s (± 0.27%) 15.53s (± 0.27%) ~ 15.49s 15.61s p=0.145 n=6
Emit Time 0.00s 0.00s ~ ~ ~ p=1.000 n=6
Total Time 19.82s (± 0.19%) 19.94s (± 0.24%) +0.12s (+ 0.60%) 19.89s 20.02s p=0.005 n=6
vscode - node (v18.15.0, x64)
Errors 0 17 🔻+17 (+ ∞%) ~ ~ p=0.001 n=6
Symbols 2,880,823 2,880,829 +6 (+ 0.00%) ~ ~ p=0.001 n=6
Types 975,524 975,543 +19 (+ 0.00%) ~ ~ p=0.001 n=6
Memory used 3,042,366k (± 0.00%) 3,042,862k (± 0.00%) +496k (+ 0.02%) 3,042,815k 3,042,885k p=0.005 n=6
Parse Time 13.56s (± 0.46%) 13.53s (± 0.42%) ~ 13.45s 13.61s p=0.418 n=6
Bind Time 4.22s (± 1.85%) 4.25s (± 1.90%) ~ 4.19s 4.41s p=0.124 n=6
Check Time 73.35s (± 0.28%) 73.92s (± 0.31%) +0.58s (+ 0.78%) 73.67s 74.20s p=0.005 n=6
Emit Time 24.05s (± 0.92%) 23.92s (± 0.82%) ~ 23.77s 24.27s p=0.173 n=6
Total Time 115.18s (± 0.38%) 115.61s (± 0.20%) ~ 115.38s 115.99s p=0.078 n=6
webpack - node (v18.15.0, x64)
Errors 0 0 ~ ~ ~ p=1.000 n=6
Symbols 267,117 267,117 ~ ~ ~ p=1.000 n=6
Types 108,775 108,775 ~ ~ ~ p=1.000 n=6
Memory used 411,548k (± 0.03%) 411,716k (± 0.01%) +168k (+ 0.04%) 411,641k 411,812k p=0.037 n=6
Parse Time 4.70s (± 0.13%) 4.70s (± 0.22%) ~ 4.68s 4.71s p=0.654 n=6
Bind Time 2.09s (± 0.49%) 2.16s (± 0.61%) +0.07s (+ 3.26%) 2.14s 2.17s p=0.004 n=6
Check Time 20.73s (± 0.67%) 20.75s (± 0.44%) ~ 20.65s 20.86s p=0.575 n=6
Emit Time 0.00s 0.00s ~ ~ ~ p=1.000 n=6
Total Time 27.52s (± 0.50%) 27.61s (± 0.38%) ~ 27.46s 27.71s p=0.229 n=6
xstate-main - node (v18.15.0, x64)
Errors 0 0 ~ ~ ~ p=1.000 n=6
Symbols 525,251 525,251 ~ ~ ~ p=1.000 n=6
Types 178,574 178,574 ~ ~ ~ p=1.000 n=6
Memory used 462,752k (± 0.05%) 462,682k (± 0.07%) ~ 462,436k 463,109k p=1.000 n=6
Parse Time 3.16s (± 0.74%) 3.19s (± 0.67%) ~ 3.17s 3.23s p=0.118 n=6
Bind Time 1.17s (± 0.35%) 1.20s (± 0.82%) +0.03s (+ 2.85%) 1.19s 1.22s p=0.003 n=6
Check Time 17.91s (± 0.47%) 17.97s (± 0.27%) ~ 17.93s 18.05s p=0.128 n=6
Emit Time 0.00s 0.00s (±244.70%) ~ 0.00s 0.02s p=0.405 n=6
Total Time 22.24s (± 0.35%) 22.36s (± 0.28%) +0.13s (+ 0.58%) 22.30s 22.44s p=0.025 n=6
System info unknown
Hosts
  • node (v18.15.0, x64)
Scenarios
  • Compiler-Unions - node (v18.15.0, x64)
  • angular-1 - node (v18.15.0, x64)
  • mui-docs - node (v18.15.0, x64)
  • self-build-src - node (v18.15.0, x64)
  • self-build-src-public-api - node (v18.15.0, x64)
  • self-compiler - node (v18.15.0, x64)
  • ts-pre-modules - node (v18.15.0, x64)
  • vscode - node (v18.15.0, x64)
  • webpack - node (v18.15.0, x64)
  • xstate-main - node (v18.15.0, x64)
Benchmark Name Iterations
Current pr 6
Baseline baseline 6

Developer Information:

Download Benchmarks

@typescript-bot
Copy link
Collaborator

@DanielRosenwasser Here are the results of running the top 400 repos with tsc comparing main and refs/pull/58729/merge:

Something interesting changed - please have a look.

Details

conwnet/github1s

extensions/github1s/tsconfig.json

electron-react-boilerplate/electron-react-boilerplate

tsconfig.json

lyswhut/lx-music-desktop

1 of 6 projects failed to build with the old tsc and were ignored

src/main/tsconfig.json

microsoft/vscode

4 of 54 projects failed to build with the old tsc and were ignored

src/tsconfig.tsec.json

src/tsconfig.monaco.json

src/tsconfig.json

extensions/vscode-test-resolver/tsconfig.json

tinacms/tinacms

12 of 24 projects failed to build with the old tsc and were ignored

packages/@tinacms/mdx/tsconfig.json

@DanielRosenwasser
Copy link
Member

DanielRosenwasser commented Jun 24, 2024

I'm having a hard time constructing a simple use case for where this might come up, but I have a slight concern around how the deferred modifier doesn't travel along in any sort of higher order - for example, when inferring the parameter list of a signature that uses deferred (playground link).

export declare function doStuff(deferred f: () => void): void;

declare function recreate<Args extends unknown[], Return>(f: (...args: Args) => Return): (...args: Args) => Return;

declare function recreateDeferred<Args extends unknown[], Return>(f: (deferred ...args: Args) => Return): (...args: Args) => Return;

{
    let x: string | number;
    x = 123;

    doStuff(() => {
        x = "hi";
    });

    x;
//  ^? let x: number
}


{
    let y: string | number;
    y = 123;

    recreate(doStuff)(() => {
        y = "hi";
    });

    y;
//  ^? let y: string | number
}


{
    let z: string | number;
    z = 123;

    recreateDeferred(doStuff)(() => {
        z = "hi";
    });

    z;
//  ^? let z: string | number
}

At the very least, this would be a good test case to add.

@ahejlsberg
Copy link
Member Author

Not sure what your intent is, but did you mean to have recreateDeferred reintroduce the deferred modifier?

declare function recreateDeferred<Args extends unknown[], Return>(f: (...args: Args) => Return): (deferred ...args: Args) => Return;

Certainly that works as expected.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Author: Team For Uncommitted Bug PR for untriaged, rejected, closed or missing bug
Projects
None yet