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

Control flow analysis for element access with variable index #57847

Merged
merged 6 commits into from
Mar 26, 2024
Merged

Conversation

ahejlsberg
Copy link
Member

@ahejlsberg ahejlsberg commented Mar 19, 2024

With this PR we perform control flow analysis for element access expressions obj[key] where key is a const variable, or a let variable or parameter that is never targeted in an assignment. The intuition here is that even if the exact name of the property selected by key isn't known, any control flow analysis proof that involves obj[key] should hold in subsequent statements as long as obj and key aren't mutated,

Some examples:

function f1(obj: Record<string, unknown>, key: string) {
    if (typeof obj[key] === "string") {
        obj[key].toUpperCase();  // Now ok, previously was error
    }
}

type Thing = { a?: string, b?: number, c?: number };

function f2(obj: Thing, getKey: () => keyof Thing) {
    const key = getKey();
    if (obj[key] !== undefined) {
        if (typeof obj[key] === "string") {
            obj[key].toUpperCase();  // Now ok, previously was error
        }
        if (typeof obj[key] === "number") {
            obj[key].toFixed();  // Now ok, previously was error
        }
    }
}

function f3<K extends string>(obj: Record<K, string | undefined>, key: K) {
    if (obj[key]) {
        obj[key].toUpperCase();  // Now ok, previously was error
    }
}

Fixes #56389.

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

@typescript-bot test top200
@typescript-bot user test this
@typescript-bot run dt
@typescript-bot perf test this faster

@typescript-bot
Copy link
Collaborator

typescript-bot commented Mar 19, 2024

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

Command Status Results
test top200 ✅ 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 test suite comparing main and refs/pull/57847/merge:

Something interesting changed - please have a look.

Details

webpack

tsconfig.types.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
Angular - node (v18.15.0, x64)
Memory used 295,747k (± 0.00%) 295,762k (± 0.01%) ~ 295,722k 295,797k p=0.198 n=6
Parse Time 2.66s (± 0.28%) 2.67s (± 0.31%) ~ 2.65s 2.67s p=0.432 n=6
Bind Time 0.83s (± 0.62%) 0.83s (± 0.62%) ~ 0.82s 0.83s p=1.000 n=6
Check Time 8.21s (± 0.28%) 8.19s (± 0.16%) ~ 8.17s 8.21s p=0.089 n=6
Emit Time 7.14s (± 0.26%) 7.13s (± 0.33%) ~ 7.11s 7.17s p=0.518 n=6
Total Time 18.84s (± 0.15%) 18.81s (± 0.09%) ~ 18.79s 18.83s p=0.164 n=6
Compiler-Unions - node (v18.15.0, x64)
Memory used 192,638k (± 0.77%) 193,221k (± 0.91%) ~ 191,920k 195,508k p=0.378 n=6
Parse Time 1.36s (± 1.20%) 1.36s (± 0.40%) ~ 1.35s 1.36s p=0.360 n=6
Bind Time 0.72s (± 0.57%) 0.72s (± 0.00%) ~ 0.72s 0.72s p=0.405 n=6
Check Time 9.52s (± 0.74%) 9.48s (± 0.54%) ~ 9.42s 9.54s p=0.260 n=6
Emit Time 2.65s (± 0.41%) 2.66s (± 0.19%) +0.01s (+ 0.50%) 2.66s 2.67s p=0.020 n=6
Total Time 14.26s (± 0.52%) 14.22s (± 0.35%) ~ 14.16s 14.28s p=0.469 n=6
Monaco - node (v18.15.0, x64)
Memory used 347,377k (± 0.01%) 347,411k (± 0.00%) ~ 347,381k 347,434k p=0.065 n=6
Parse Time 2.47s (± 0.51%) 2.48s (± 0.54%) ~ 2.46s 2.50s p=0.139 n=6
Bind Time 0.93s (± 0.44%) 0.93s (± 0.56%) ~ 0.92s 0.93s p=0.595 n=6
Check Time 7.02s (± 0.40%) 7.02s (± 0.50%) ~ 6.98s 7.08s p=1.000 n=6
Emit Time 4.06s (± 0.67%) 4.08s (± 0.25%) ~ 4.06s 4.09s p=0.415 n=6
Total Time 14.47s (± 0.21%) 14.50s (± 0.27%) ~ 14.47s 14.57s p=0.334 n=6
TFS - node (v18.15.0, x64)
Memory used 302,758k (± 0.01%) 302,755k (± 0.01%) ~ 302,734k 302,782k p=0.936 n=6
Parse Time 2.01s (± 0.88%) 2.00s (± 0.68%) ~ 1.98s 2.02s p=0.805 n=6
Bind Time 1.01s (± 0.81%) 1.00s (± 0.82%) ~ 0.99s 1.01s p=0.077 n=6
Check Time 6.34s (± 0.36%) 6.32s (± 0.38%) ~ 6.29s 6.36s p=0.373 n=6
Emit Time 3.61s (± 0.21%) 3.60s (± 0.91%) ~ 3.56s 3.65s p=0.566 n=6
Total Time 12.96s (± 0.17%) 12.93s (± 0.38%) ~ 12.86s 13.01s p=0.225 n=6
material-ui - node (v18.15.0, x64)
Memory used 511,373k (± 0.00%) 511,377k (± 0.01%) ~ 511,349k 511,407k p=1.000 n=6
Parse Time 2.66s (± 0.46%) 2.67s (± 0.28%) ~ 2.66s 2.68s p=0.062 n=6
Bind Time 0.98s (± 1.19%) 0.98s (± 1.35%) ~ 0.96s 1.00s p=0.737 n=6
Check Time 17.34s (± 0.68%) 17.31s (± 0.44%) ~ 17.21s 17.41s p=0.936 n=6
Emit Time 0.00s (± 0.00%) 0.00s (± 0.00%) ~ 0.00s 0.00s p=1.000 n=6
Total Time 20.97s (± 0.53%) 20.96s (± 0.33%) ~ 20.88s 21.04s p=1.000 n=6
mui-docs - node (v18.15.0, x64)
Memory used 1,719,135k (± 0.00%) 1,719,188k (± 0.00%) +54k (+ 0.00%) 1,719,155k 1,719,222k p=0.020 n=6
Parse Time 6.54s (± 0.21%) 6.53s (± 0.51%) ~ 6.50s 6.59s p=0.373 n=6
Bind Time 2.35s (± 0.23%) 2.36s (± 0.69%) ~ 2.35s 2.39s p=0.342 n=6
Check Time 56.29s (± 0.65%) 56.21s (± 0.28%) ~ 56.01s 56.41s p=0.575 n=6
Emit Time 0.13s (± 0.00%) 0.13s (± 0.00%) ~ 0.13s 0.13s p=1.000 n=6
Total Time 65.31s (± 0.56%) 65.23s (± 0.25%) ~ 65.07s 65.49s p=0.689 n=6
self-build-src - node (v18.15.0, x64)
Memory used 2,395,587k (± 0.03%) 2,395,905k (± 0.03%) ~ 2,395,338k 2,397,348k p=0.298 n=6
Parse Time 4.99s (± 0.96%) 5.01s (± 1.19%) ~ 4.96s 5.12s p=0.936 n=6
Bind Time 1.90s (± 0.87%) 1.90s (± 1.20%) ~ 1.88s 1.93s p=0.933 n=6
Check Time 33.59s (± 0.22%) 33.59s (± 0.31%) ~ 33.41s 33.67s p=1.000 n=6
Emit Time 2.71s (± 1.81%) 2.70s (± 1.22%) ~ 2.67s 2.75s p=0.422 n=6
Total Time 43.21s (± 0.19%) 43.23s (± 0.29%) ~ 43.08s 43.39s p=0.810 n=6
self-compiler - node (v18.15.0, x64)
Memory used 416,099k (± 0.00%) 416,158k (± 0.01%) +59k (+ 0.01%) 416,114k 416,200k p=0.005 n=6
Parse Time 2.82s (± 1.20%) 2.81s (± 0.94%) ~ 2.76s 2.83s p=0.747 n=6
Bind Time 1.07s (± 0.70%) 1.07s (± 0.92%) ~ 1.06s 1.08s p=1.000 n=6
Check Time 15.28s (± 0.23%) 15.37s (± 0.22%) +0.08s (+ 0.55%) 15.32s 15.41s p=0.008 n=6
Emit Time 1.16s (± 1.01%) 1.14s (± 0.66%) -0.02s (- 1.44%) 1.13s 1.15s p=0.032 n=6
Total Time 20.34s (± 0.08%) 20.38s (± 0.19%) +0.05s (+ 0.23%) 20.34s 20.44s p=0.029 n=6
vscode - node (v18.15.0, x64)
Memory used 2,883,825k (± 0.00%) 2,884,003k (± 0.00%) +178k (+ 0.01%) 2,883,812k 2,884,096k p=0.031 n=6
Parse Time 10.82s (± 0.35%) 10.83s (± 0.57%) ~ 10.76s 10.91s p=1.000 n=6
Bind Time 3.46s (± 0.68%) 3.46s (± 0.30%) ~ 3.45s 3.48s p=0.494 n=6
Check Time 61.55s (± 0.41%) 61.79s (± 0.63%) ~ 61.47s 62.54s p=0.298 n=6
Emit Time 17.06s (± 7.90%) 16.99s (± 8.36%) ~ 16.30s 19.89s p=0.298 n=6
Total Time 92.88s (± 1.66%) 93.07s (± 1.97%) ~ 92.07s 96.80s p=0.575 n=6
webpack - node (v18.15.0, x64)
Memory used 408,036k (± 0.01%) 408,075k (± 0.01%) ~ 408,013k 408,146k p=0.378 n=6
Parse Time 3.23s (± 0.32%) 3.23s (± 0.25%) ~ 3.22s 3.24s p=0.270 n=6
Bind Time 1.38s (± 0.30%) 1.37s (± 0.75%) ~ 1.36s 1.38s p=0.461 n=6
Check Time 14.27s (± 0.41%) 14.31s (± 0.30%) ~ 14.27s 14.37s p=0.415 n=6
Emit Time 0.00s (± 0.00%) 0.00s (± 0.00%) ~ 0.00s 0.00s p=1.000 n=6
Total Time 18.88s (± 0.34%) 18.92s (± 0.28%) ~ 18.86s 18.99s p=0.521 n=6
xstate - node (v18.15.0, x64)
Memory used 513,118k (± 0.02%) 513,166k (± 0.02%) ~ 513,081k 513,316k p=0.689 n=6
Parse Time 3.28s (± 0.32%) 3.28s (± 0.31%) ~ 3.26s 3.29s p=0.933 n=6
Bind Time 1.54s (± 0.34%) 1.54s (± 0.41%) ~ 1.53s 1.55s p=0.386 n=6
Check Time 2.86s (± 0.68%) 2.85s (± 0.90%) ~ 2.83s 2.90s p=0.517 n=6
Emit Time 0.07s (± 0.00%) 0.07s (± 0.00%) ~ 0.07s 0.07s p=1.000 n=6
Total Time 7.75s (± 0.19%) 7.75s (± 0.29%) ~ 7.73s 7.79s p=0.420 n=6
System info unknown
Hosts
  • node (v18.15.0, x64)
Scenarios
  • Angular - node (v18.15.0, x64)
  • Compiler-Unions - node (v18.15.0, x64)
  • Monaco - node (v18.15.0, x64)
  • TFS - node (v18.15.0, x64)
  • material-ui - node (v18.15.0, x64)
  • mui-docs - node (v18.15.0, x64)
  • self-build-src - node (v18.15.0, x64)
  • self-compiler - node (v18.15.0, x64)
  • vscode - node (v18.15.0, x64)
  • webpack - node (v18.15.0, x64)
  • xstate - 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 top-repos suite comparing main and refs/pull/57847/merge:

Something interesting changed - please have a look.

Details

microsoft/vscode

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

src/tsconfig.tsec.json

src/tsconfig.json

build/tsconfig.build.json

react-navigation/react-navigation

9 of 14 projects failed to build with the old tsc and were ignored

tsconfig.json

packages/core/tsconfig.build.json

Redocly/redoc

tsconfig.lib.json

tsconfig.json

ueberdosis/tiptap

3 of 8 projects failed to build with the old tsc and were ignored

tests/cypress/tsconfig.json

demos/tsconfig.vue-3.json

demos/tsconfig.vue-2.json

demos/tsconfig.react.json

demos/tsconfig.base.json

vercel/hyper

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

tsconfig.json

xyflow/xyflow

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

packages/system/tsconfig.json

  • error TS2339: Property 'handleBounds' does not exist on type '{ z?: number | undefined; handleBounds?: NodeHandleBounds | undefined; isParent?: boolean | undefined; userProvidedNode: NodeBase<Record<string, unknown>, string>; } | undefined'.

@jakebailey
Copy link
Member

Weird; reading some of the breaks, there seems to be a bug in this iteration of the PR where unrelated accesses are getting narrowed too.

declare const key: string;

declare const obj1: Record<string, number | undefined>;
declare const obj2: Record<string, number | undefined>;

if (obj1[key]) {
    const x = obj1[key];
    //    ^?

    const y = obj2[key];
    //    ^?
}

image

@ahejlsberg
Copy link
Member Author

Argh, I see what the issue is. Will fix.

@ahejlsberg
Copy link
Member Author

@typescript-bot test top200
@typescript-bot user test this
@typescript-bot run dt
@typescript-bot perf test this faster

@typescript-bot
Copy link
Collaborator

typescript-bot commented Mar 19, 2024

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

Command Status Results
test top200 ✅ 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 test suite comparing main and refs/pull/57847/merge:

Everything looks good!

@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
Angular - node (v18.15.0, x64)
Memory used 295,750k (± 0.01%) 295,777k (± 0.00%) ~ 295,765k 295,788k p=0.066 n=6
Parse Time 2.66s (± 0.37%) 2.66s (± 0.50%) ~ 2.64s 2.68s p=0.654 n=6
Bind Time 0.83s (± 0.62%) 0.83s (± 0.00%) ~ 0.83s 0.83s p=0.174 n=6
Check Time 8.20s (± 0.26%) 8.19s (± 0.15%) ~ 8.17s 8.20s p=0.220 n=6
Emit Time 7.14s (± 0.23%) 7.11s (± 0.23%) -0.03s (- 0.40%) 7.09s 7.13s p=0.028 n=6
Total Time 18.83s (± 0.21%) 18.79s (± 0.14%) ~ 18.76s 18.82s p=0.075 n=6
Compiler-Unions - node (v18.15.0, x64)
Memory used 193,151k (± 0.97%) 192,675k (± 0.75%) ~ 191,914k 195,612k p=0.936 n=6
Parse Time 1.36s (± 0.40%) 1.36s (± 1.02%) ~ 1.33s 1.37s p=0.663 n=6
Bind Time 0.72s (± 0.00%) 0.72s (± 0.00%) ~ 0.72s 0.72s p=1.000 n=6
Check Time 9.49s (± 0.56%) 9.48s (± 0.58%) ~ 9.41s 9.58s p=1.000 n=6
Emit Time 2.66s (± 0.66%) 2.65s (± 0.34%) ~ 2.64s 2.66s p=0.198 n=6
Total Time 14.22s (± 0.32%) 14.21s (± 0.35%) ~ 14.15s 14.30s p=0.936 n=6
Monaco - node (v18.15.0, x64)
Memory used 347,386k (± 0.01%) 347,403k (± 0.01%) ~ 347,380k 347,435k p=0.173 n=6
Parse Time 2.47s (± 0.98%) 2.49s (± 0.00%) ~ 2.49s 2.49s p=0.128 n=6
Bind Time 0.94s (± 2.40%) 0.93s (± 0.44%) ~ 0.92s 0.93s p=0.787 n=6
Check Time 7.02s (± 0.32%) 7.00s (± 0.33%) ~ 6.98s 7.04s p=0.106 n=6
Emit Time 4.07s (± 0.41%) 4.07s (± 0.30%) ~ 4.06s 4.09s p=0.616 n=6
Total Time 14.50s (± 0.13%) 14.49s (± 0.26%) ~ 14.45s 14.55s p=0.332 n=6
TFS - node (v18.15.0, x64)
Memory used 302,745k (± 0.01%) 302,751k (± 0.01%) ~ 302,722k 302,771k p=0.378 n=6
Parse Time 2.00s (± 0.81%) 2.01s (± 0.75%) ~ 2.00s 2.04s p=0.462 n=6
Bind Time 1.00s (± 0.98%) 1.00s (± 1.03%) ~ 0.99s 1.02s p=0.452 n=6
Check Time 6.33s (± 0.60%) 6.30s (± 0.21%) ~ 6.28s 6.32s p=0.221 n=6
Emit Time 3.60s (± 0.55%) 3.60s (± 0.23%) ~ 3.59s 3.61s p=1.000 n=6
Total Time 12.93s (± 0.30%) 12.92s (± 0.22%) ~ 12.89s 12.97s p=0.685 n=6
material-ui - node (v18.15.0, x64)
Memory used 511,362k (± 0.00%) 511,389k (± 0.00%) +27k (+ 0.01%) 511,377k 511,417k p=0.030 n=6
Parse Time 2.66s (± 0.58%) 2.66s (± 0.31%) ~ 2.64s 2.66s p=0.242 n=6
Bind Time 0.99s (± 1.23%) 0.99s (± 1.05%) ~ 0.97s 1.00s p=1.000 n=6
Check Time 17.33s (± 0.33%) 17.29s (± 0.25%) ~ 17.23s 17.36s p=0.226 n=6
Emit Time 0.00s (± 0.00%) 0.00s (± 0.00%) ~ 0.00s 0.00s p=1.000 n=6
Total Time 20.98s (± 0.26%) 20.93s (± 0.23%) ~ 20.86s 21.01s p=0.125 n=6
mui-docs - node (v18.15.0, x64)
Memory used 1,719,162k (± 0.00%) 1,719,198k (± 0.00%) ~ 1,719,144k 1,719,243k p=0.066 n=6
Parse Time 6.52s (± 0.49%) 6.53s (± 0.43%) ~ 6.50s 6.57s p=0.747 n=6
Bind Time 2.37s (± 0.56%) 2.35s (± 0.35%) ~ 2.35s 2.37s p=0.052 n=6
Check Time 56.10s (± 0.42%) 56.40s (± 0.42%) +0.30s (+ 0.54%) 56.12s 56.75s p=0.045 n=6
Emit Time 0.14s (± 4.05%) 0.13s (± 0.00%) ~ 0.13s 0.13s p=0.071 n=6
Total Time 65.12s (± 0.36%) 65.41s (± 0.39%) ~ 65.10s 65.79s p=0.093 n=6
self-build-src - node (v18.15.0, x64)
Memory used 2,395,113k (± 0.03%) 2,395,863k (± 0.02%) ~ 2,395,219k 2,396,651k p=0.128 n=6
Parse Time 4.98s (± 0.73%) 4.98s (± 1.12%) ~ 4.94s 5.08s p=0.809 n=6
Bind Time 1.89s (± 0.72%) 1.91s (± 0.63%) +0.02s (+ 1.06%) 1.90s 1.93s p=0.042 n=6
Check Time 33.64s (± 0.55%) 33.64s (± 0.29%) ~ 33.49s 33.79s p=0.689 n=6
Emit Time 2.70s (± 2.05%) 2.71s (± 1.18%) ~ 2.68s 2.77s p=1.000 n=6
Total Time 43.22s (± 0.55%) 43.26s (± 0.21%) ~ 43.13s 43.36s p=0.378 n=6
self-compiler - node (v18.15.0, x64)
Memory used 416,056k (± 0.00%) 416,145k (± 0.01%) +89k (+ 0.02%) 416,120k 416,178k p=0.005 n=6
Parse Time 2.82s (± 0.66%) 2.81s (± 0.52%) ~ 2.79s 2.83s p=0.368 n=6
Bind Time 1.07s (± 0.51%) 1.07s (± 0.51%) ~ 1.06s 1.07s p=1.000 n=6
Check Time 15.27s (± 0.39%) 15.37s (± 0.45%) +0.10s (+ 0.64%) 15.30s 15.48s p=0.029 n=6
Emit Time 1.14s (± 1.51%) 1.15s (± 0.90%) ~ 1.13s 1.16s p=0.459 n=6
Total Time 20.30s (± 0.38%) 20.39s (± 0.37%) ~ 20.30s 20.52s p=0.109 n=6
vscode - node (v18.15.0, x64)
Memory used 2,884,099k (± 0.00%) 2,884,245k (± 0.00%) +147k (+ 0.01%) 2,884,114k 2,884,293k p=0.013 n=6
Parse Time 10.81s (± 0.27%) 10.81s (± 0.23%) ~ 10.77s 10.84s p=0.871 n=6
Bind Time 3.46s (± 0.47%) 3.46s (± 0.24%) ~ 3.45s 3.47s p=0.458 n=6
Check Time 61.53s (± 0.21%) 61.65s (± 0.39%) ~ 61.37s 62.08s p=0.297 n=6
Emit Time 16.44s (± 0.24%) 17.12s (± 8.96%) ~ 16.41s 20.25s p=0.126 n=6
Total Time 92.24s (± 0.19%) 93.05s (± 1.87%) ~ 92.13s 96.60s p=0.149 n=6
webpack - node (v18.15.0, x64)
Memory used 408,093k (± 0.03%) 408,112k (± 0.02%) ~ 408,031k 408,214k p=0.689 n=6
Parse Time 3.22s (± 0.46%) 3.24s (± 0.50%) ~ 3.21s 3.25s p=0.139 n=6
Bind Time 1.38s (± 0.71%) 1.38s (± 0.99%) ~ 1.36s 1.40s p=0.607 n=6
Check Time 14.31s (± 0.50%) 14.31s (± 0.30%) ~ 14.23s 14.34s p=1.000 n=6
Emit Time 0.00s (± 0.00%) 0.00s (± 0.00%) ~ 0.00s 0.00s p=1.000 n=6
Total Time 18.91s (± 0.40%) 18.93s (± 0.19%) ~ 18.88s 18.97s p=0.688 n=6
xstate - node (v18.15.0, x64)
Memory used 513,109k (± 0.01%) 513,091k (± 0.01%) ~ 513,035k 513,147k p=0.810 n=6
Parse Time 3.28s (± 0.23%) 3.27s (± 0.23%) ~ 3.26s 3.28s p=0.195 n=6
Bind Time 1.54s (± 0.41%) 1.54s (± 0.49%) ~ 1.53s 1.55s p=0.718 n=6
Check Time 2.86s (± 0.64%) 2.84s (± 1.02%) ~ 2.79s 2.87s p=0.145 n=6
Emit Time 0.07s (± 0.00%) 0.07s (± 5.69%) ~ 0.07s 0.08s p=0.405 n=6
Total Time 7.76s (± 0.27%) 7.73s (± 0.34%) ~ 7.69s 7.76s p=0.198 n=6
System info unknown
Hosts
  • node (v18.15.0, x64)
Scenarios
  • Angular - node (v18.15.0, x64)
  • Compiler-Unions - node (v18.15.0, x64)
  • Monaco - node (v18.15.0, x64)
  • TFS - node (v18.15.0, x64)
  • material-ui - node (v18.15.0, x64)
  • mui-docs - node (v18.15.0, x64)
  • self-build-src - node (v18.15.0, x64)
  • self-compiler - node (v18.15.0, x64)
  • vscode - node (v18.15.0, x64)
  • webpack - node (v18.15.0, x64)
  • xstate - node (v18.15.0, x64)
Benchmark Name Iterations
Current pr 6
Baseline baseline 6

Developer Information:

Download Benchmarks

@ahejlsberg
Copy link
Member Author

@typescript-bot perf test this faster

@typescript-bot
Copy link
Collaborator

typescript-bot commented Mar 19, 2024

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

Command Status Results
perf test this faster ✅ Started 👀 Results

@typescript-bot
Copy link
Collaborator

@ahejlsberg Here are the results of running the top-repos suite comparing main and refs/pull/57847/merge:

Something interesting changed - please have a look.

Details

xyflow/xyflow

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

packages/system/tsconfig.json

  • error TS2339: Property 'handleBounds' does not exist on type '{ z?: number | undefined; handleBounds?: NodeHandleBounds | undefined; isParent?: boolean | undefined; userProvidedNode: NodeBase<Record<string, unknown>, string>; } | undefined'.

@jakebailey
Copy link
Member

@typescript-bot pack this

@typescript-bot
Copy link
Collaborator

typescript-bot commented Mar 19, 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 Mar 19, 2024

Hey @jakebailey, 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/160607/artifacts?artifactName=tgz&fileId=FCCE8FB0B7250696E9C38855366CC2296FF63CC26FF4295ECFB451B5CF87FE3B02&fileName=/typescript-5.5.0-insiders.20240319.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]".;

@ahejlsberg
Copy link
Member Author

@typescript-bot test top200

@typescript-bot
Copy link
Collaborator

typescript-bot commented Mar 19, 2024

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

Command Status Results
test top200 ✅ Started ✅ Results

@jakebailey
Copy link
Member

@typescript-bot pack this

@typescript-bot
Copy link
Collaborator

typescript-bot commented Mar 19, 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 Mar 19, 2024

Hey @jakebailey, 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/160610/artifacts?artifactName=tgz&fileId=6DA0FDC478A78981951C02D8A521617538C50A7BA6615392B110355013145BBE02&fileName=/typescript-5.5.0-insiders.20240319.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]".;

@typescript-bot
Copy link
Collaborator

@ahejlsberg Here are the results of running the top-repos suite comparing main and refs/pull/57847/merge:

Everything looks good!

@ahejlsberg
Copy link
Member Author

Tests and performance look good. This is ready for a review.

}
if (isElementAccessExpression(source) && isElementAccessExpression(target) && isIdentifier(source.argumentExpression) && isIdentifier(target.argumentExpression)) {
const symbol = getResolvedSymbol(source.argumentExpression);
if (symbol === getResolvedSymbol(target.argumentExpression) && (isConstantVariable(symbol) || isParameterOrMutableLocalVariable(symbol) && !isSymbolAssigned(symbol))) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it make more sense to do isPastLastAssignment using a more specific location? How does this PR interact with #56908?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately not that simple. We would need to know that all narrowing operations for obj[key] occur past the last assignment to key which would require an additional CFA graph walk. We don't have that issue in #56908 because the only location we care about is the location where the arrow function is created.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense; I really need to prototype the idea I had to make that efficient enough for us to do, but I've lost that brainwave ☹️

Can you add a test in the vein of #56908 in terms of what closures do? Something like: Playground Link (which does behave properly I think)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add a test in the vein of...

Such a test wouldn't show anything. The new analysis in #56908 only affects references to local variables, not references to properties, so there are no changes across closure boundaries with this PR.

@ahejlsberg
Copy link
Member Author

@typescript-bot perf test this faster

@typescript-bot
Copy link
Collaborator

typescript-bot commented Mar 20, 2024

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

Command Status Results
perf test this faster ✅ Started 👀 Results

@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
Angular - node (v18.15.0, x64)
Memory used 295,752k (± 0.00%) 295,764k (± 0.01%) ~ 295,727k 295,787k p=0.199 n=6
Parse Time 2.67s (± 0.28%) 2.66s (± 0.39%) ~ 2.65s 2.68s p=0.351 n=6
Bind Time 0.83s (± 0.76%) 0.83s (± 0.76%) ~ 0.82s 0.84s p=1.000 n=6
Check Time 8.20s (± 0.28%) 8.21s (± 0.29%) ~ 8.17s 8.24s p=0.459 n=6
Emit Time 7.11s (± 0.19%) 7.11s (± 0.43%) ~ 7.07s 7.15s p=0.745 n=6
Total Time 18.81s (± 0.21%) 18.82s (± 0.21%) ~ 18.78s 18.88s p=0.686 n=6
Compiler-Unions - node (v18.15.0, x64)
Memory used 192,684k (± 0.79%) 193,228k (± 0.93%) ~ 191,955k 195,545k p=0.689 n=6
Parse Time 1.36s (± 1.29%) 1.36s (± 1.10%) ~ 1.34s 1.38s p=0.932 n=6
Bind Time 0.72s (± 0.57%) 0.72s (± 0.00%) ~ 0.72s 0.72s p=0.405 n=6
Check Time 9.54s (± 0.59%) 9.53s (± 0.69%) ~ 9.45s 9.60s p=1.000 n=6
Emit Time 2.66s (± 0.39%) 2.66s (± 0.19%) ~ 2.65s 2.66s p=0.794 n=6
Total Time 14.28s (± 0.44%) 14.27s (± 0.43%) ~ 14.19s 14.33s p=0.935 n=6
Monaco - node (v18.15.0, x64)
Memory used 347,381k (± 0.01%) 347,410k (± 0.00%) +29k (+ 0.01%) 347,396k 347,428k p=0.020 n=6
Parse Time 2.48s (± 0.59%) 2.48s (± 0.49%) ~ 2.46s 2.49s p=0.867 n=6
Bind Time 0.93s (± 0.44%) 0.92s (± 0.59%) ~ 0.92s 0.93s p=0.282 n=6
Check Time 7.02s (± 0.43%) 7.03s (± 0.11%) ~ 7.02s 7.04s p=0.368 n=6
Emit Time 4.07s (± 0.63%) 4.07s (± 0.55%) ~ 4.05s 4.11s p=0.800 n=6
Total Time 14.50s (± 0.42%) 14.50s (± 0.18%) ~ 14.48s 14.55s p=1.000 n=6
TFS - node (v18.15.0, x64)
Memory used 302,745k (± 0.01%) 302,759k (± 0.01%) ~ 302,715k 302,814k p=0.575 n=6
Parse Time 2.01s (± 0.70%) 2.00s (± 1.41%) ~ 1.97s 2.05s p=0.293 n=6
Bind Time 1.01s (± 1.02%) 1.00s (± 0.52%) ~ 0.99s 1.00s p=0.069 n=6
Check Time 6.33s (± 0.45%) 6.33s (± 0.60%) ~ 6.28s 6.39s p=0.630 n=6
Emit Time 3.61s (± 0.29%) 3.60s (± 0.46%) ~ 3.58s 3.62s p=0.559 n=6
Total Time 12.96s (± 0.26%) 12.93s (± 0.41%) ~ 12.87s 13.01s p=0.261 n=6
material-ui - node (v18.15.0, x64)
Memory used 509,905k (± 0.00%) 509,929k (± 0.00%) +24k (+ 0.00%) 509,910k 509,954k p=0.020 n=6
Parse Time 2.66s (± 0.73%) 2.66s (± 0.44%) ~ 2.64s 2.67s p=0.869 n=6
Bind Time 0.99s (± 1.18%) 0.98s (± 1.23%) ~ 0.97s 1.00s p=0.323 n=6
Check Time 17.23s (± 0.24%) 17.27s (± 0.33%) ~ 17.19s 17.33s p=0.296 n=6
Emit Time 0.00s (± 0.00%) 0.00s (± 0.00%) ~ 0.00s 0.00s p=1.000 n=6
Total Time 20.89s (± 0.23%) 20.91s (± 0.28%) ~ 20.84s 20.98s p=0.372 n=6
mui-docs - node (v18.15.0, x64)
Memory used 1,719,252k (± 0.00%) 1,719,223k (± 0.00%) ~ 1,719,141k 1,719,297k p=0.575 n=6
Parse Time 6.54s (± 0.43%) 6.55s (± 0.74%) ~ 6.50s 6.64s p=0.872 n=6
Bind Time 2.36s (± 0.38%) 2.38s (± 0.52%) +0.02s (+ 0.64%) 2.37s 2.40s p=0.025 n=6
Check Time 56.41s (± 0.23%) 56.32s (± 0.47%) ~ 55.88s 56.58s p=0.810 n=6
Emit Time 0.13s (± 0.00%) 0.13s (± 3.87%) ~ 0.13s 0.14s p=0.174 n=6
Total Time 65.45s (± 0.21%) 65.38s (± 0.34%) ~ 65.03s 65.58s p=0.630 n=6
self-build-src - node (v18.15.0, x64)
Memory used 2,395,320k (± 0.04%) 2,394,952k (± 0.04%) ~ 2,393,869k 2,395,740k p=0.575 n=6
Parse Time 4.99s (± 0.58%) 5.04s (± 1.02%) ~ 4.96s 5.10s p=0.077 n=6
Bind Time 1.91s (± 0.88%) 1.90s (± 0.98%) ~ 1.88s 1.93s p=0.516 n=6
Check Time 33.69s (± 0.48%) 33.71s (± 0.24%) ~ 33.60s 33.80s p=0.689 n=6
Emit Time 2.72s (± 1.49%) 2.69s (± 1.32%) ~ 2.65s 2.74s p=0.375 n=6
Total Time 43.33s (± 0.40%) 43.35s (± 0.17%) ~ 43.26s 43.44s p=0.810 n=6
self-compiler - node (v18.15.0, x64)
Memory used 416,071k (± 0.01%) 416,145k (± 0.01%) +75k (+ 0.02%) 416,120k 416,177k p=0.005 n=6
Parse Time 2.82s (± 0.65%) 2.84s (± 0.66%) ~ 2.82s 2.87s p=0.122 n=6
Bind Time 1.07s (± 0.59%) 1.07s (± 0.51%) ~ 1.06s 1.07s p=0.201 n=6
Check Time 15.28s (± 0.22%) 15.33s (± 0.18%) +0.04s (+ 0.27%) 15.30s 15.36s p=0.043 n=6
Emit Time 1.14s (± 1.43%) 1.14s (± 1.11%) ~ 1.13s 1.16s p=0.567 n=6
Total Time 20.32s (± 0.16%) 20.36s (± 0.18%) +0.05s (+ 0.23%) 20.32s 20.42s p=0.034 n=6
vscode - node (v18.15.0, x64)
Memory used 2,886,074k (± 0.00%) 2,886,262k (± 0.00%) +189k (+ 0.01%) 2,886,173k 2,886,342k p=0.005 n=6
Parse Time 10.86s (± 0.46%) 10.84s (± 0.37%) ~ 10.80s 10.91s p=0.808 n=6
Bind Time 3.47s (± 0.42%) 3.46s (± 0.22%) ~ 3.45s 3.47s p=0.102 n=6
Check Time 61.33s (± 0.32%) 61.46s (± 0.32%) ~ 61.25s 61.67s p=0.378 n=6
Emit Time 16.50s (± 0.79%) 16.42s (± 0.26%) ~ 16.35s 16.47s p=0.148 n=6
Total Time 92.16s (± 0.33%) 92.19s (± 0.24%) ~ 91.91s 92.45s p=0.936 n=6
webpack - node (v18.15.0, x64)
Memory used 408,070k (± 0.02%) 408,120k (± 0.02%) ~ 408,023k 408,217k p=0.378 n=6
Parse Time 3.23s (± 0.51%) 3.23s (± 0.46%) ~ 3.21s 3.24s p=0.684 n=6
Bind Time 1.38s (± 0.00%) 1.38s (± 0.75%) ~ 1.36s 1.39s p=0.599 n=6
Check Time 14.29s (± 0.17%) 14.29s (± 0.22%) ~ 14.23s 14.32s p=0.935 n=6
Emit Time 0.00s (± 0.00%) 0.00s (± 0.00%) ~ 0.00s 0.00s p=1.000 n=6
Total Time 18.90s (± 0.18%) 18.90s (± 0.17%) ~ 18.86s 18.94s p=1.000 n=6
xstate - node (v18.15.0, x64)
Memory used 513,109k (± 0.01%) 513,102k (± 0.01%) ~ 512,985k 513,143k p=0.810 n=6
Parse Time 3.27s (± 0.27%) 3.27s (± 0.41%) ~ 3.25s 3.29s p=0.801 n=6
Bind Time 1.54s (± 0.54%) 1.54s (± 0.26%) ~ 1.54s 1.55s p=0.527 n=6
Check Time 2.85s (± 0.63%) 2.85s (± 0.65%) ~ 2.83s 2.88s p=0.628 n=6
Emit Time 0.07s (± 0.00%) 0.07s (± 0.00%) ~ 0.07s 0.07s p=1.000 n=6
Total Time 7.75s (± 0.21%) 7.74s (± 0.18%) ~ 7.73s 7.76s p=1.000 n=6
System info unknown
Hosts
  • node (v18.15.0, x64)
Scenarios
  • Angular - node (v18.15.0, x64)
  • Compiler-Unions - node (v18.15.0, x64)
  • Monaco - node (v18.15.0, x64)
  • TFS - node (v18.15.0, x64)
  • material-ui - node (v18.15.0, x64)
  • mui-docs - node (v18.15.0, x64)
  • self-build-src - node (v18.15.0, x64)
  • self-compiler - node (v18.15.0, x64)
  • vscode - node (v18.15.0, x64)
  • webpack - node (v18.15.0, x64)
  • xstate - node (v18.15.0, x64)
Benchmark Name Iterations
Current pr 6
Baseline baseline 6

Developer Information:

Download Benchmarks

@ipanasenko
Copy link

Hi. I'm not sure if it's okay to ask here or I should rather open new discussion, so sorry in advance.

Do you think the following type narrowing using in should work as well?
I have a Record with predefined keys in it, and I expected that if in returns true, then animal can only be of Animal type.
https://www.typescriptlang.org/play/?#code/C4TwDgpgBAggdgSwLYEMA2UC8UDkBjFYHKAH1wBMB7Ac2LJwCMEAncnAbgCg9K4BnYFBSJUaAAooA7nwCyKMAC4oAJQg9WAHnjJ0AGihwArkgYRmAPixQA3pyhQCwBQBZddqFWou39pqyUATG4AvlzcvAJQABaUknJwIBLSVgAUwjpoSgLMCHDUAJRKRiZmWJa29ggAZlBpIuhQuUL14lKy8vk27vbMEMCGzHDNGUntYADa6aIAulz2wZzuvf2DUACScFW5CKBcwUA

I think this might be related to this feature.

@JoostK
Copy link
Contributor

JoostK commented Jun 11, 2024

Hi. I'm not sure if it's okay to ask here or I should rather open new discussion, so sorry in advance.

Do you think the following type narrowing using in should work as well? I have a Record with predefined keys in it, and I expected that if in returns true, then animal can only be of Animal type. https://www.typescriptlang.org/play/?#code/C4TwDgpgBAggdgSwLYEMA2UC8UDkBjFYHKAH1wBMB7Ac2LJwCMEAncnAbgCg9K4BnYFBSJUaAAooA7nwCyKMAC4oAJQg9WAHnjJ0AGihwArkgYRmAPixQA3pyhQCwBQBZddqFWou39pqyUATG4AvlzcvAJQABaUknJwIBLSVgAUwjpoSgLMCHDUAJRKRiZmWJa29ggAZlBpIuhQuUL14lKy8vk27vbMEMCGzHDNGUntYADa6aIAulz2wZzuvf2DUACScFW5CKBcwUA

I think this might be related to this feature.

That error is correct and desirable: the index signature only specifies that properties in Animal (i.e. 'cat' | 'dog' | 'bird') have a number value, it does not specify a type for any other properties. Since TypeScript does not have strict types it's fine for a Record<Animal, number> to also have other properties, as demonstrated in this playground. If the animal parameter is changed from type string to Animal then TypeScript no longer reports an error for the implementation of howManyPaws, while correctly preventing the monkey from requesting its number of paws.

@ipanasenko
Copy link

I see. Big thank you for an explanation

@geakstr
Copy link

geakstr commented Jun 24, 2024

Hi and thank you for your work! Trying to clarify for myself this statement "The intuition here is that even if the exact name of the property selected by key isn't known, any control flow analysis proof that involves obj[key] should hold in subsequent statements as long as obj and key aren't mutated" from the PR description.

Here I mutate obj and TS 5.5.2 doesn't throw errors:

function f1(obj: Record<string, unknown>, key: string) {
  if (typeof obj[key] === "string") {
    delete obj[key];
    obj[key].toUpperCase(); // ok
  }
}

Is this "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
Development

Successfully merging this pull request may close these issues.

Narrow object property when key is a variable
7 participants