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

Infer AssertsIdentifier type predicates #58495

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

Conversation

danvk
Copy link
Contributor

@danvk danvk commented May 10, 2024

This extends the type predicate inference from #57465 to cover "asserts identifier" predicates as well. For example:

// function isNumber(x: unknown): asserts x is number
function isNumber(x: unknown) {
  if (typeof x !== 'number') {
    throw new Error(`expected a number, got ${x}`);
  }
}

or:

// function assertNonNullish<T>(x: T): asserts x is NonNullable<T>
function assertNonNullish<T>(x: T) {
  if (x != null) {
    return;
  }
  throw new Error();
}

The constraints for inference are:

  • We're working with a function statement. Not a constructor, getter, setter, method, arrow function, or function expression. (This is significantly more restrictive than for "identifier" predicates, see Error when assertion function calls aren't CFA'd #33622 for why.)
  • The function does not have an explicit return type annotation, but is inferred to return void or undefined.
  • The function takes at least one parameter that it does not mutate.

The criterion winds up being a bit simpler than it was in #57465:

  • Check the type of the parameter at each return site (including an implicit return at the end of the function).
  • Union these types.
  • If this is different than the initial type of the parameter, then we've got an assertion function.

I wound up implementing "different than" with an assignability check since branching constructs can sometimes change the representation of a parameter's type in superficial ways, e.g. unknown can become {} | null | undefined.

There's no equivalent of the "false check" that we needed to infer identifier type predicates. Assertion predicates are inherently one-sided. If they fail, your code will throw. This means that we can infer assertions even when the negative type can't be represented. For example:

// function assertIsShortString(x: unknown): asserts x is string
function assertIsShortString(x: unknown) {
  if (typeof x !== 'string') {
    throw new Error('Expected string');
  } else if (x.length > 10) {
    throw new Error('Expected short string');
  }
}

This wouldn't work as a type predicate (x is string) because you can't represent "all types except short strings." But it's fine as an imprecise assertion, since there's no way to observe the negative case.

A few other things to note:

  • This allows assertions to flow (Type predicate assertion does not carry over when used in another function #51326). In particular, this lets CFA "see through" a function that calls a type predicate and throws if it fails (e.g. assertFoo calls isFoo).
  • This only infers assertions with a type: asserts x is T, not asserts x. The latter would also be interesting, but that feels like a different problem.
  • This only infers a non-returning code path via its effect on types. This feels a little strange/risky to me since it means this code runs on all sorts of functions that don't throw. But it does work, and this is a natural way to handle all the different patterns (early throw, early return).
  • One of the fourslash tests found a bug with unused parameters getting marked as used. This turns out to be an issue with inferred type predicates as well, see Regression in detecting unused parameters in 5.5.0-beta #58493.

It's possible that the "asserted type" really is the same as the parameter's declared type, but TS isn't able to figure that out. This happened for one of the baselines. In this case we'll infer a useless type predicate (function f(x: T): asserts x is T). This is noisy but won't produce spurious errors. There's one example of this in the baselines.

I didn't observe any slowdowns from this change locally and there's some reason to hope that's the case. For inferred type predicates, the expensive part was the "false" checks (see #57465 (comment)). There's no need to do that for assertion functions, though, so we won't pay that price. On the other hand, there might be more implicitly void-returning functions than implicitly boolean-returning functions, so we'll see!

@typescript-bot typescript-bot added the For Uncommitted Bug PR for untriaged, rejected, closed or missing bug label May 10, 2024
// An assignability check covers this, but a void initType can become an undefined type through control flow analysis.
// Since void is not assignable to undefined, we patch initType to handle this, too.
const assertedType = getUnionType(typesAtReturn, UnionReduction.Subtype);
const patchedInitType = mapType(initType, t => t.flags & TypeFlags.Void ? undefinedType : t);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is because void changes to undefined in this function, and undefined is not assignable to void:

function booleanOrVoid(a: boolean | void) {
  if (typeof a === "undefined") {
    a
  }
  a  // undefined
}

This feels like a hack, though, and I'd love to change it if there's a cleaner fix.

@@ -954,14 +954,17 @@ declare function foo({ value1, test1, test2, test3, test4, test5, test6, test7,
test8?: any;
test9?: any;
}): void;
declare function fa1(x: [true, number] | [false, string]): void;
declare function fa1(x: [true, number] | [false, string]): asserts x is [false, string];
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This one is a little weird (the function never returns), but it follows from the types: TS understands that for(;;) {} is an infinite loop, but not while(!!true) {}.

@@ -1192,8 +1192,8 @@ function unknownNarrowing(x: unknown) {
}

function keyofNarrowing<S extends { [K in keyof S]: string }>(k: keyof S) {
>keyofNarrowing : <S extends { [K in keyof S]: string; }>(k: keyof S) => void
> : ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^ ^^^^^^^^^
>keyofNarrowing : <S extends { [K in keyof S]: string; }>(k: keyof S) => asserts k is (keyof S & number) | (keyof S & symbol) | (keyof S & string)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is the one loss: the other changes are all valid predicates.

// asserts k is (keyof S & number) | (keyof S & symbol) | (keyof S & string)
function keyofNarrowing<S extends { [K in keyof S]: string }>(k: keyof S) { ... }

This should not be an assertion function because:

  (keyof S & number) | (keyof S & symbol) | (keyof S & string)
= keyof S & (number | symbol | string)
= keyof S & PropertyKey
= keyof S

TS isn't able to figure that out, however, so we get a meaningless assertion predicate.

@@ -68,7 +68,7 @@ import { x } from "foo";
import { x2, used2 } from "foo";
used1; used2;

function f() {
function f(a, b) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This diff is clearly wrong and a bug in my PR. There's a similar issue with the existing inferred type predicates change, see #58493. The fix for that should also apply here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I confirmed that @Andarist's PR #58514 also fixes this.

@fatcerberus
Copy link

If this is different than the initial type of the parameter, then we've got an assertion function.

This feels like it’s going to turn a lot of functions into assertions that were never intended to be, just because a parameter was narrowed somewhere in the function.

@danvk
Copy link
Contributor Author

danvk commented May 10, 2024

If this is different than the initial type of the parameter, then we've got an assertion function.

This feels like it’s going to turn a lot of functions into assertions that were never intended to be, just because a parameter was narrowed somewhere in the function.

It's not enough for the parameter to be narrowed somewhere in the function. The function has to throw in a way that's tied to that narrowing.

We could do an experiment similar to #58173 to see how often this triggers.

@fatcerberus
Copy link

Ah, okay - you didn’t mention that in the description in the OP, the algorithm you laid out was just that you check all the return points, not also the throwing points.

@danvk
Copy link
Contributor Author

danvk commented May 10, 2024

Ah, okay - you didn’t mention that in the description in the OP, the algorithm you laid out was just that you check all the return points, not also the throwing points.

The algorithm only looks at parameter types when you return, or (important!) at the implicit return at the end of a function. When you union those types, the only way I can think of that you'd get something distinct from the initial parameter type is by having a code path that throws or does the equivalent (calls another assertion function or never-returning function, or goes into an infinite loop).

Maybe an example would make it clearer how this works:

function assertABC(x: 'A' | 'B' | 'C' | 'D' | 'E') {
  if (x === 'A') {
    return;  // type of x here is 'A'
  } else if (x === 'B' || x === 'C') {
    throw new Error();
  }
  // implicit return; type of x here is 'D' | E'
}

Unioning the types of x gives 'A' | 'D' | 'E'. Since 'A' | D' | 'E' is distinct from 'A' | 'B' | 'C' | 'D' | 'E', we have a type assertion function.

If you take a look at the code for the algorithm, it's all about return. The association with throw is implied by the check on the types.

@fatcerberus
Copy link

fatcerberus commented May 10, 2024

Ah, so it’s based on how TS re-merges control-flow branches by unioning the narrowed types back together, that’s clever. However do note - that can sometimes create an observably different type on the other side (see: subtype reduction, introducing intersections, etc.)

@fatcerberus
Copy link

Forgive me if you’ve accounted for all this already - I’m just spouting the caveats that come to mind when I think about this.

@danvk
Copy link
Contributor Author

danvk commented May 10, 2024

Ah, so it’s based on how TS re-merges control-flow branches by unioning the narrowed types back together, that’s clever. However do note - that can sometimes create an observably different type on the other side (see: subtype reduction, introducing intersections, etc.)

I won't infer an assertion predicate so long as the initial parameter type is assignable to the asserted type, so superficial differences shouldn't matter. But there are some cases where TS can't figure out the relationship. There's one example of this in the baselines (see my comments on the code). There will probably be others in the wild.

This change would feel less aggressive if I could detect whether there was a code path that throws in the function, but I couldn't find anything that quite did what I wanted.

@jakebailey
Copy link
Member

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

for fun

@typescript-bot
Copy link
Collaborator

typescript-bot commented May 10, 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
pack this ✅ Started ✅ Results

@typescript-bot
Copy link
Collaborator

typescript-bot commented May 10, 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/161690/artifacts?artifactName=tgz&fileId=0BFA3D3A0A0BB0B903EE356283DCF9D638B724930087ECCE5D71B4C18A4DA8BB02&fileName=/typescript-5.5.0-insiders.20240510.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

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

Everything looks the same!

You can check the log here.

@typescript-bot
Copy link
Collaborator

@jakebailey Here are the results of running the user tests comparing main and refs/pull/58495/merge:

Everything looks good!

@typescript-bot
Copy link
Collaborator

@jakebailey
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,154 62,154 ~ ~ ~ p=1.000 n=6
Types 50,248 50,255 +7 (+ 0.01%) ~ ~ p=0.001 n=6
Memory used 192,824k (± 0.77%) 193,524k (± 0.95%) +700k (+ 0.36%) 192,296k 195,932k p=0.031 n=6
Parse Time 1.55s (± 1.08%) 1.54s (± 1.95%) ~ 1.51s 1.58s p=0.681 n=6
Bind Time 0.86s (± 1.40%) 0.86s (± 0.47%) ~ 0.86s 0.87s p=0.863 n=6
Check Time 11.29s (± 0.59%) 11.32s (± 0.63%) ~ 11.23s 11.40s p=0.748 n=6
Emit Time 3.15s (± 0.33%) 3.14s (± 0.82%) ~ 3.11s 3.19s p=0.112 n=6
Total Time 16.86s (± 0.49%) 16.86s (± 0.43%) ~ 16.74s 16.93s p=0.872 n=6
angular-1 - node (v18.15.0, x64)
Errors 5 5 ~ ~ ~ p=1.000 n=6
Symbols 944,110 944,107 -3 (- 0.00%) ~ ~ p=0.001 n=6
Types 407,140 407,147 +7 (+ 0.00%) ~ ~ p=0.001 n=6
Memory used 1,222,027k (± 0.00%) 1,222,174k (± 0.00%) +147k (+ 0.01%) 1,222,093k 1,222,232k p=0.008 n=6
Parse Time 8.07s (± 0.31%) 8.12s (± 0.64%) +0.05s (+ 0.66%) 8.05s 8.20s p=0.043 n=6
Bind Time 2.25s (± 0.67%) 2.25s (± 0.73%) ~ 2.22s 2.26s p=1.000 n=6
Check Time 36.49s (± 0.33%) 36.59s (± 0.44%) ~ 36.34s 36.81s p=0.229 n=6
Emit Time 17.53s (± 0.66%) 17.57s (± 0.40%) ~ 17.49s 17.69s p=0.423 n=6
Total Time 64.33s (± 0.30%) 64.53s (± 0.24%) ~ 64.28s 64.70s p=0.109 n=6
mui-docs - node (v18.15.0, x64)
Errors 5 5 ~ ~ ~ p=1.000 n=6
Symbols 1,961,283 1,961,283 ~ ~ ~ p=1.000 n=6
Types 696,900 696,939 +39 (+ 0.01%) ~ ~ p=0.001 n=6
Memory used 1,777,974k (± 0.00%) 1,778,082k (± 0.00%) +108k (+ 0.01%) 1,778,048k 1,778,110k p=0.005 n=6
Parse Time 9.86s (± 0.38%) 9.86s (± 0.31%) ~ 9.81s 9.90s p=0.686 n=6
Bind Time 3.36s (± 0.71%) 3.37s (± 0.82%) ~ 3.32s 3.40s p=0.370 n=6
Check Time 82.68s (± 0.18%) 82.72s (± 0.23%) ~ 82.45s 83.02s p=1.000 n=6
Emit Time 0.21s (± 3.95%) 0.20s (± 2.54%) ~ 0.20s 0.21s p=0.523 n=6
Total Time 96.12s (± 0.12%) 96.15s (± 0.22%) ~ 95.89s 96.49s p=1.000 n=6
self-build-src - node (v18.15.0, x64)
Errors 0 0 ~ ~ ~ p=1.000 n=6
Symbols 1,220,400 1,220,443 +43 (+ 0.00%) ~ ~ p=0.001 n=6
Types 258,967 258,989 +22 (+ 0.01%) ~ ~ p=0.001 n=6
Memory used 2,335,959k (± 0.03%) 2,336,372k (± 0.04%) ~ 2,335,223k 2,337,305k p=0.471 n=6
Parse Time 4.97s (± 1.31%) 4.95s (± 0.83%) ~ 4.91s 5.00s p=0.378 n=6
Bind Time 1.88s (± 0.73%) 1.88s (± 0.93%) ~ 1.85s 1.90s p=1.000 n=6
Check Time 33.77s (± 0.36%) 33.79s (± 0.32%) ~ 33.62s 33.91s p=0.936 n=6
Emit Time 2.65s (± 2.29%) 2.63s (± 2.95%) ~ 2.51s 2.74s p=0.521 n=6
Total Time 43.30s (± 0.24%) 43.25s (± 0.29%) ~ 43.02s 43.37s p=0.575 n=6
self-build-src-public-api - node (v18.15.0, x64)
Errors 0 0 ~ ~ ~ p=1.000 n=6
Symbols 1,220,400 1,220,443 +43 (+ 0.00%) ~ ~ p=0.001 n=6
Types 258,967 258,989 +22 (+ 0.01%) ~ ~ p=0.001 n=6
Memory used 2,411,497k (± 0.01%) 2,411,343k (± 0.02%) ~ 2,410,547k 2,412,209k p=0.575 n=6
Parse Time 6.31s (± 0.60%) 6.30s (± 0.90%) ~ 6.22s 6.38s p=0.810 n=6
Bind Time 2.05s (± 0.95%) 2.04s (± 1.13%) ~ 2.02s 2.07s p=0.808 n=6
Check Time 40.18s (± 0.36%) 40.26s (± 0.30%) ~ 40.09s 40.45s p=0.298 n=6
Emit Time 3.20s (± 2.60%) 3.19s (± 1.84%) ~ 3.08s 3.25s p=0.470 n=6
Total Time 51.75s (± 0.42%) 51.79s (± 0.29%) ~ 51.61s 52.01s p=0.689 n=6
self-compiler - node (v18.15.0, x64)
Errors 0 0 ~ ~ ~ p=1.000 n=6
Symbols 256,559 256,601 +42 (+ 0.02%) ~ ~ p=0.001 n=6
Types 104,270 104,285 +15 (+ 0.01%) ~ ~ p=0.001 n=6
Memory used 425,708k (± 0.03%) 425,822k (± 0.01%) ~ 425,752k 425,882k p=0.066 n=6
Parse Time 3.38s (± 0.63%) 3.37s (± 0.49%) ~ 3.34s 3.38s p=0.331 n=6
Bind Time 1.31s (± 0.89%) 1.31s (± 0.57%) ~ 1.30s 1.32s p=0.796 n=6
Check Time 17.93s (± 0.34%) 17.97s (± 0.38%) ~ 17.87s 18.03s p=0.335 n=6
Emit Time 1.37s (± 2.14%) 1.37s ~ ~ ~ p=0.655 n=6
Total Time 23.99s (± 0.22%) 24.02s (± 0.29%) ~ 23.92s 24.08s p=0.688 n=6
ts-pre-modules - node (v18.15.0, x64)
Errors 35 35 ~ ~ ~ p=1.000 n=6
Symbols 224,575 224,583 +8 (+ 0.00%) ~ ~ p=0.001 n=6
Types 93,785 93,792 +7 (+ 0.01%) ~ ~ p=0.001 n=6
Memory used 369,898k (± 0.03%) 369,935k (± 0.03%) ~ 369,870k 370,123k p=0.688 n=6
Parse Time 3.48s (± 0.47%) 3.51s (± 0.67%) ~ 3.48s 3.53s p=0.122 n=6
Bind Time 1.93s (± 0.53%) 1.93s (± 0.76%) ~ 1.92s 1.96s p=0.605 n=6
Check Time 19.36s (± 0.40%) 19.36s (± 0.42%) ~ 19.26s 19.49s p=0.872 n=6
Emit Time 0.00s 0.00s ~ ~ ~ p=1.000 n=6
Total Time 24.77s (± 0.35%) 24.80s (± 0.34%) ~ 24.69s 24.94s p=0.748 n=6
vscode - node (v18.15.0, x64)
Errors 0 2 🔻+2 (+ ∞%) ~ ~ p=0.001 n=6
Symbols 2,820,491 2,820,496 +5 (+ 0.00%) ~ ~ p=0.001 n=6
Types 956,787 956,831 +44 (+ 0.00%) ~ ~ p=0.001 n=6
Memory used 2,992,366k (± 0.00%) 2,992,554k (± 0.00%) +188k (+ 0.01%) 2,992,461k 2,992,599k p=0.005 n=6
Parse Time 13.84s (± 0.33%) 13.83s (± 0.36%) ~ 13.75s 13.88s p=0.936 n=6
Bind Time 4.16s (± 2.07%) 4.30s (± 2.20%) ~ 4.11s 4.37s p=0.063 n=6
Check Time 73.32s (± 0.29%) 73.45s (± 0.63%) ~ 72.95s 74.28s p=0.689 n=6
Emit Time 23.64s (± 0.62%) 23.40s (± 0.60%) -0.24s (- 1.00%) 23.25s 23.66s p=0.020 n=6
Total Time 114.95s (± 0.22%) 114.98s (± 0.52%) ~ 114.36s 116.12s p=0.689 n=6
webpack - node (v18.15.0, x64)
Errors 0 0 ~ ~ ~ p=1.000 n=6
Symbols 265,866 265,866 ~ ~ ~ p=1.000 n=6
Types 108,401 108,402 +1 (+ 0.00%) ~ ~ p=0.001 n=6
Memory used 410,604k (± 0.01%) 410,596k (± 0.01%) ~ 410,547k 410,639k p=1.000 n=6
Parse Time 4.77s (± 1.10%) 4.75s (± 0.54%) ~ 4.71s 4.79s p=0.169 n=6
Bind Time 2.08s (± 0.88%) 2.07s (± 1.22%) ~ 2.03s 2.10s p=0.622 n=6
Check Time 21.00s (± 0.26%) 21.07s (± 0.28%) ~ 20.99s 21.16s p=0.093 n=6
Emit Time 0.00s 0.00s ~ ~ ~ p=1.000 n=6
Total Time 27.85s (± 0.30%) 27.88s (± 0.31%) ~ 27.79s 28.03s p=0.689 n=6
xstate-main - node (v18.15.0, x64)
Errors 0 0 ~ ~ ~ p=1.000 n=6
Symbols 524,576 524,576 ~ ~ ~ p=1.000 n=6
Types 178,847 178,851 +4 (+ 0.00%) ~ ~ p=0.001 n=6
Memory used 462,623k (± 0.03%) 462,577k (± 0.00%) ~ 462,533k 462,600k p=1.000 n=6
Parse Time 3.12s (± 1.24%) 3.11s (± 0.86%) ~ 3.08s 3.16s p=0.570 n=6
Bind Time 1.17s (± 0.76%) 1.17s (± 0.76%) ~ 1.16s 1.18s p=1.000 n=6
Check Time 18.21s (± 0.64%) 18.21s (± 0.57%) ~ 18.08s 18.33s p=0.936 n=6
Emit Time 0.00s 0.00s ~ ~ ~ p=1.000 n=6
Total Time 22.49s (± 0.49%) 22.50s (± 0.42%) ~ 22.37s 22.62s p=0.873 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

@danvk
Copy link
Contributor Author

danvk commented May 10, 2024

Perf impact looks pretty minimal… but what are those two new errors in VS Code?

@typescript-bot
Copy link
Collaborator

@jakebailey Here are the results of running the top 400 repos comparing main and refs/pull/58495/merge:

Something interesting changed - please have a look.

Details

darkreader/darkreader

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

tests/inject/tsconfig.json

src/tsconfig.json

src/api/tsconfig.json

invoke-ai/InvokeAI

invokeai/frontend/web/tsconfig.json

microsoft/vscode

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

src/tsconfig.tsec.json

src/tsconfig.json

@fatcerberus
Copy link

Assertions require every name in the call target to be declared with an explicit type annotation.

Ouch. I forgot that was something the compiler checked for. The existence of that error means you have to be very careful about exactly what you infer as an assertion…

@danvk
Copy link
Contributor Author

danvk commented May 13, 2024

Summary of breaks (#58495 (comment)):

  • darkreader: we inferred that an arrow function was a type assertion predicate, which doesn't generally work.
  • InvokeAI: same; validateBaseCompatibility is an arrow function. This PR correctly infers that it returns a type assertion predicate, but this results in TS2775. If it were a function statement, the inferred type assertion predicate works fine.
  • vscode: In this case, we infer a type assertion predicate for a method. Again, this doesn't always work and can produce TS2776. But that's not what happens here. The ExtHostTreeView.validateTreeItem method becomes a type assertion predicate. This, in turn, exposes what I believe had been a latent TS bug: Narrowing by type predicate fails to produce intersection type with weak type #58518

The fix for all of these is to not infer type assertion predicates for methods or arrow functions because this can produce a confusing error at the call site. See #33622 for why. This definitely limits the scope of this PR: the latest version only runs on plain old function statements.

I think the nicest win from this PR is that it lets type predicates naturally flow through assertion wrappers:

declare function isFoo(x: any): x is Foo;

// function inferFromType(x: unknown): asserts x is Foo
function inferFromType(x: unknown) {
  if (!isFoo(x)) {
    throw new Error();
  }
}

@Andarist
Copy link
Contributor

I think the nicest win from this PR is that it lets type predicates naturally flow through assertion wrappers:

This is dope 🚀

@jakebailey
Copy link
Member

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

@typescript-bot
Copy link
Collaborator

typescript-bot commented May 13, 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
pack this ✅ Started ✅ Results

@typescript-bot
Copy link
Collaborator

typescript-bot commented May 13, 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/161715/artifacts?artifactName=tgz&fileId=33CA50AFB7B259ACD3FE936AA8261E8754CA2DEC5411359B7E3C7C6088AA876F02&fileName=/typescript-5.5.0-insiders.20240513.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

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

Everything looks the same!

You can check the log here.

@typescript-bot
Copy link
Collaborator

@jakebailey Here are the results of running the user tests comparing main and refs/pull/58495/merge:

Something interesting changed - please have a look.

Details

minimatch

/mnt/ts_downloads/_/m/minimatch/tsconfig.json

  • [NEW] error TS2775: Assertions require every name in the call target to be declared with an explicit type annotation.
    • /mnt/ts_downloads/_/m/minimatch/node_modules/minimatch/minimatch.js(116,3)
    • /mnt/ts_downloads/_/m/minimatch/node_modules/minimatch/minimatch.js(133,3)
    • /mnt/ts_downloads/_/m/minimatch/node_modules/minimatch/minimatch.js(260,3)
    • /mnt/ts_downloads/_/m/minimatch/node_modules/minimatch/minimatch.js(297,3)

@typescript-bot
Copy link
Collaborator

@jakebailey
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,154 62,154 ~ ~ ~ p=1.000 n=6
Types 50,248 50,252 +4 (+ 0.01%) ~ ~ p=0.001 n=6
Memory used 193,496k (± 0.95%) 195,371k (± 0.77%) +1,874k (+ 0.97%) 192,313k 196,084k p=0.020 n=6
Parse Time 1.55s (± 1.95%) 1.55s (± 1.49%) ~ 1.51s 1.58s p=1.000 n=6
Bind Time 0.86s (± 0.94%) 0.86s (± 0.47%) ~ 0.86s 0.87s p=0.584 n=6
Check Time 11.28s (± 0.34%) 11.32s (± 0.32%) ~ 11.30s 11.39s p=0.081 n=6
Emit Time 3.14s (± 0.55%) 3.13s (± 0.87%) ~ 3.09s 3.16s p=1.000 n=6
Total Time 16.83s (± 0.36%) 16.86s (± 0.26%) ~ 16.82s 16.94s p=0.295 n=6
angular-1 - node (v18.15.0, x64)
Errors 5 5 ~ ~ ~ p=1.000 n=6
Symbols 944,110 944,111 +1 (+ 0.00%) ~ ~ p=0.001 n=6
Types 407,140 407,144 +4 (+ 0.00%) ~ ~ p=0.001 n=6
Memory used 1,222,086k (± 0.00%) 1,222,194k (± 0.00%) +108k (+ 0.01%) 1,222,138k 1,222,260k p=0.020 n=6
Parse Time 6.78s (± 0.63%) 6.77s (± 0.28%) ~ 6.75s 6.80s p=0.810 n=6
Bind Time 1.88s (± 0.64%) 1.89s (± 0.40%) ~ 1.88s 1.90s p=0.111 n=6
Check Time 31.25s (± 0.53%) 31.34s (± 0.43%) ~ 31.13s 31.53s p=0.298 n=6
Emit Time 14.72s (± 0.54%) 14.77s (± 0.77%) ~ 14.64s 14.93s p=0.574 n=6
Total Time 54.62s (± 0.26%) 54.77s (± 0.39%) ~ 54.55s 55.03s p=0.128 n=6
mui-docs - node (v18.15.0, x64)
Errors 5 5 ~ ~ ~ p=1.000 n=6
Symbols 1,961,349 1,961,349 ~ ~ ~ p=1.000 n=6
Types 696,910 696,910 ~ ~ ~ p=1.000 n=6
Memory used 1,778,101k (± 0.00%) 1,778,109k (± 0.00%) ~ 1,778,068k 1,778,142k p=0.521 n=6
Parse Time 6.78s (± 0.31%) 6.79s (± 0.59%) ~ 6.77s 6.87s p=0.655 n=6
Bind Time 2.31s (± 0.33%) 2.31s (± 0.60%) ~ 2.29s 2.32s p=0.453 n=6
Check Time 57.05s (± 0.49%) 56.97s (± 0.64%) ~ 56.51s 57.51s p=0.689 n=6
Emit Time 0.14s 0.14s ~ ~ ~ p=1.000 n=6
Total Time 66.29s (± 0.43%) 66.20s (± 0.52%) ~ 65.73s 66.73s p=0.575 n=6
self-build-src - node (v18.15.0, x64)
Errors 0 0 ~ ~ ~ p=1.000 n=6
Symbols 1,221,120 1,221,163 +43 (+ 0.00%) ~ ~ p=0.001 n=6
Types 259,211 259,228 +17 (+ 0.01%) ~ ~ p=0.001 n=6
Memory used 2,337,130k (± 0.02%) 2,337,212k (± 0.03%) ~ 2,336,192k 2,338,326k p=1.000 n=6
Parse Time 4.98s (± 1.51%) 4.99s (± 0.83%) ~ 4.93s 5.03s p=1.000 n=6
Bind Time 1.87s (± 0.76%) 1.88s (± 0.78%) ~ 1.86s 1.90s p=0.222 n=6
Check Time 33.72s (± 0.33%) 33.81s (± 0.39%) ~ 33.64s 33.96s p=0.378 n=6
Emit Time 2.67s (± 1.96%) 2.62s (± 2.44%) ~ 2.55s 2.71s p=0.172 n=6
Total Time 43.26s (± 0.29%) 43.33s (± 0.23%) ~ 43.23s 43.48s p=0.378 n=6
self-build-src-public-api - node (v18.15.0, x64)
Errors 0 0 ~ ~ ~ p=1.000 n=6
Symbols 1,221,120 1,221,163 +43 (+ 0.00%) ~ ~ p=0.001 n=6
Types 259,211 259,228 +17 (+ 0.01%) ~ ~ p=0.001 n=6
Memory used 2,411,894k (± 0.02%) 2,412,608k (± 0.04%) ~ 2,411,592k 2,413,650k p=0.173 n=6
Parse Time 5.22s (± 0.95%) 5.23s (± 1.18%) ~ 5.16s 5.34s p=0.873 n=6
Bind Time 1.69s (± 0.24%) 1.69s (± 0.30%) ~ 1.69s 1.70s p=0.114 n=6
Check Time 34.31s (± 0.32%) 34.26s (± 0.38%) ~ 34.08s 34.45s p=0.378 n=6
Emit Time 2.69s (± 0.47%) 2.64s (± 3.18%) ~ 2.55s 2.75s p=0.378 n=6
Total Time 43.93s (± 0.30%) 43.84s (± 0.45%) ~ 43.53s 44.02s p=0.521 n=6
self-compiler - node (v18.15.0, x64)
Errors 0 0 ~ ~ ~ p=1.000 n=6
Symbols 256,716 256,758 +42 (+ 0.02%) ~ ~ p=0.001 n=6
Types 104,288 104,302 +14 (+ 0.01%) ~ ~ p=0.001 n=6
Memory used 425,755k (± 0.02%) 425,930k (± 0.01%) +175k (+ 0.04%) 425,883k 425,967k p=0.005 n=6
Parse Time 3.37s (± 0.41%) 3.38s (± 0.64%) ~ 3.35s 3.41s p=0.462 n=6
Bind Time 1.32s (± 0.68%) 1.32s (± 0.89%) ~ 1.31s 1.34s p=0.672 n=6
Check Time 17.89s (± 0.42%) 17.93s (± 0.29%) ~ 17.86s 17.99s p=0.297 n=6
Emit Time 1.35s (± 0.94%) 1.37s (± 1.07%) +0.02s (+ 1.60%) 1.36s 1.40s p=0.032 n=6
Total Time 23.93s (± 0.29%) 24.00s (± 0.21%) +0.07s (+ 0.31%) 23.94s 24.07s p=0.044 n=6
ts-pre-modules - node (v18.15.0, x64)
Errors 35 35 ~ ~ ~ p=1.000 n=6
Symbols 224,575 224,583 +8 (+ 0.00%) ~ ~ p=0.001 n=6
Types 93,785 93,791 +6 (+ 0.01%) ~ ~ p=0.001 n=6
Memory used 369,965k (± 0.04%) 369,917k (± 0.02%) ~ 369,837k 370,027k p=1.000 n=6
Parse Time 2.82s (± 0.92%) 2.83s (± 0.73%) ~ 2.81s 2.86s p=0.685 n=6
Bind Time 1.58s (± 0.84%) 1.59s (± 1.04%) ~ 1.57s 1.61s p=0.738 n=6
Check Time 15.68s (± 0.48%) 15.69s (± 0.22%) ~ 15.63s 15.72s p=0.809 n=6
Emit Time 0.00s 0.00s ~ ~ ~ p=1.000 n=6
Total Time 20.09s (± 0.42%) 20.11s (± 0.28%) ~ 20.03s 20.19s p=0.574 n=6
vscode - node (v18.15.0, x64)
Errors 0 0 ~ ~ ~ p=1.000 n=6
Symbols 2,821,517 2,821,518 +1 (+ 0.00%) ~ ~ p=0.001 n=6
Types 957,198 957,198 ~ ~ ~ p=1.000 n=6
Memory used 2,993,753k (± 0.00%) 2,993,703k (± 0.00%) ~ 2,993,596k 2,993,776k p=0.230 n=6
Parse Time 13.80s (± 0.26%) 13.82s (± 0.11%) ~ 13.80s 13.84s p=0.167 n=6
Bind Time 4.14s (± 0.52%) 4.14s (± 0.36%) ~ 4.13s 4.17s p=0.742 n=6
Check Time 73.44s (± 0.34%) 73.18s (± 0.19%) ~ 73.02s 73.37s p=0.066 n=6
Emit Time 23.48s (± 0.35%) 23.51s (± 0.67%) ~ 23.32s 23.73s p=0.873 n=6
Total Time 114.86s (± 0.23%) 114.65s (± 0.15%) ~ 114.44s 114.94s p=0.199 n=6
webpack - node (v18.15.0, x64)
Errors 0 0 ~ ~ ~ p=1.000 n=6
Symbols 265,866 265,866 ~ ~ ~ p=1.000 n=6
Types 108,401 108,401 ~ ~ ~ p=1.000 n=6
Memory used 410,651k (± 0.03%) 410,560k (± 0.02%) ~ 410,508k 410,651k p=0.128 n=6
Parse Time 4.76s (± 0.84%) 4.77s (± 1.23%) ~ 4.68s 4.85s p=0.936 n=6
Bind Time 2.07s (± 0.66%) 2.05s (± 0.95%) -0.02s (- 1.21%) 2.02s 2.07s p=0.033 n=6
Check Time 20.98s (± 0.36%) 20.96s (± 0.27%) ~ 20.89s 21.04s p=0.378 n=6
Emit Time 0.00s 0.00s ~ ~ ~ p=1.000 n=6
Total Time 27.82s (± 0.38%) 27.77s (± 0.30%) ~ 27.68s 27.87s p=0.295 n=6
xstate-main - node (v18.15.0, x64)
Errors 0 0 ~ ~ ~ p=1.000 n=6
Symbols 524,639 524,639 ~ ~ ~ p=1.000 n=6
Types 178,906 178,906 ~ ~ ~ p=1.000 n=6
Memory used 462,735k (± 0.01%) 462,750k (± 0.01%) ~ 462,650k 462,811k p=0.572 n=6
Parse Time 3.12s (± 0.81%) 3.12s (± 0.55%) ~ 3.09s 3.14s p=0.807 n=6
Bind Time 1.16s (± 0.35%) 1.16s (± 1.18%) ~ 1.15s 1.18s p=0.796 n=6
Check Time 18.34s (± 0.58%) 18.35s (± 0.54%) ~ 18.16s 18.44s p=1.000 n=6
Emit Time 0.00s 0.00s (±244.70%) ~ 0.00s 0.01s p=0.405 n=6
Total Time 22.63s (± 0.52%) 22.63s (± 0.44%) ~ 22.46s 22.73s p=1.000 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

@jakebailey Here are the results of running the top 400 repos comparing main and refs/pull/58495/merge:

Everything looks good!

@danvk
Copy link
Contributor Author

danvk commented May 15, 2024

At first I thought the minimatch break had something with old-fashioned JS constructor function statements that were inferred to be type predicates. But it turned out to be more straightforward. The relevant code is here and all the failures are calls to this function:

var MAX_PATTERN_LENGTH = 1024 * 64
var assertValidPattern = function (pattern) {
  if (typeof pattern !== 'string') {
    throw new TypeError('invalid pattern')
  }

  if (pattern.length > MAX_PATTERN_LENGTH) {
    throw new TypeError('pattern is too long')
  }
}

So I also need to exclude function expressions from inference, not just arrow functions.

@danvk danvk marked this pull request as ready for review May 15, 2024 13:38
@typescript-bot
Copy link
Collaborator

This PR doesn't have any linked issues. Please open an issue that references this PR. From there we can discuss and prioritise.

@fatcerberus
Copy link

Ironically, inferring assertValidPattern as an assertion predicate is actually correct! But unfortunately it hits the limitation that requires them to be explicitly annotated...

@danvk
Copy link
Contributor Author

danvk commented May 15, 2024

Ironically, inferring assertValidPattern as an assertion predicate is actually correct! But unfortunately it hits the limitation that requires them to be explicitly annotated...

Right. So far as I'm aware, the algorithm is correct: it will never infer a type assertion predicate that's inaccurate. But there are many situations (methods, arrow functions, function expressions) where it will push you right into TS2775 / TS2776.

@jakebailey
Copy link
Member

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

@typescript-bot
Copy link
Collaborator

typescript-bot commented May 15, 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
pack this ✅ Started ✅ Results

@typescript-bot
Copy link
Collaborator

typescript-bot commented May 15, 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/161774/artifacts?artifactName=tgz&fileId=93993D75141F9F8A88E91035A3BFD6BBFA39DEB63210D37972D1CB42488948E902&fileName=/typescript-5.5.0-insiders.20240515.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

@jakebailey Here are the results of running the user tests comparing main and refs/pull/58495/merge:

Everything looks good!

@typescript-bot
Copy link
Collaborator

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

Everything looks the same!

You can check the log here.

@typescript-bot
Copy link
Collaborator

@jakebailey
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,154 62,154 ~ ~ ~ p=1.000 n=6
Types 50,248 50,252 +4 (+ 0.01%) ~ ~ p=0.001 n=6
Memory used 194,089k (± 1.00%) 192,991k (± 0.76%) ~ 192,282k 195,989k p=0.936 n=6
Parse Time 1.30s (± 0.93%) 1.30s (± 0.31%) ~ 1.30s 1.31s p=0.863 n=6
Bind Time 0.72s 0.72s ~ ~ ~ p=1.000 n=6
Check Time 9.53s (± 0.47%) 9.59s (± 0.18%) ~ 9.57s 9.61s p=0.053 n=6
Emit Time 2.64s (± 0.62%) 2.62s (± 0.95%) ~ 2.59s 2.65s p=0.462 n=6
Total Time 14.19s (± 0.41%) 14.23s (± 0.29%) ~ 14.18s 14.27s p=0.332 n=6
angular-1 - node (v18.15.0, x64)
Errors 5 5 ~ ~ ~ p=1.000 n=6
Symbols 944,110 944,111 +1 (+ 0.00%) ~ ~ p=0.001 n=6
Types 407,140 407,144 +4 (+ 0.00%) ~ ~ p=0.001 n=6
Memory used 1,222,144k (± 0.00%) 1,222,202k (± 0.01%) ~ 1,222,065k 1,222,277k p=0.149 n=6
Parse Time 6.80s (± 0.54%) 6.79s (± 0.57%) ~ 6.76s 6.86s p=0.746 n=6
Bind Time 1.88s (± 0.27%) 1.88s (± 0.52%) ~ 1.87s 1.89s p=0.348 n=6
Check Time 31.36s (± 0.50%) 31.28s (± 0.36%) ~ 31.17s 31.48s p=0.470 n=6
Emit Time 14.80s (± 0.37%) 14.78s (± 0.33%) ~ 14.72s 14.85s p=0.630 n=6
Total Time 54.84s (± 0.34%) 54.72s (± 0.25%) ~ 54.56s 54.87s p=0.173 n=6
mui-docs - node (v18.15.0, x64)
Errors 5 5 ~ ~ ~ p=1.000 n=6
Symbols 1,964,176 1,964,176 ~ ~ ~ p=1.000 n=6
Types 819,283 819,283 ~ ~ ~ p=1.000 n=6
Memory used 1,849,631k (± 0.00%) 1,849,667k (± 0.00%) ~ 1,849,599k 1,849,710k p=0.128 n=6
Parse Time 6.78s (± 0.27%) 6.77s (± 0.45%) ~ 6.74s 6.83s p=0.677 n=6
Bind Time 2.30s (± 0.84%) 2.28s (± 0.46%) ~ 2.27s 2.30s p=0.218 n=6
Check Time 58.72s (± 0.36%) 58.76s (± 0.16%) ~ 58.64s 58.91s p=0.689 n=6
Emit Time 0.14s (± 2.88%) 0.14s (± 5.69%) ~ 0.14s 0.16s p=1.000 n=6
Total Time 67.93s (± 0.31%) 67.96s (± 0.12%) ~ 67.85s 68.09s p=0.936 n=6
self-build-src - node (v18.15.0, x64)
Errors 0 0 ~ ~ ~ p=1.000 n=6
Symbols 1,221,221 1,221,264 +43 (+ 0.00%) ~ ~ p=0.001 n=6
Types 259,523 259,540 +17 (+ 0.01%) ~ ~ p=0.001 n=6
Memory used 2,362,550k (± 2.61%) 2,362,575k (± 2.60%) ~ 2,336,165k 2,488,304k p=0.936 n=6
Parse Time 5.02s (± 0.73%) 4.97s (± 1.22%) ~ 4.91s 5.04s p=0.336 n=6
Bind Time 1.87s (± 0.48%) 1.90s (± 0.97%) +0.03s (+ 1.52%) 1.88s 1.93s p=0.007 n=6
Check Time 33.82s (± 0.62%) 33.94s (± 0.29%) ~ 33.80s 34.04s p=0.336 n=6
Emit Time 2.64s (± 3.02%) 2.65s (± 3.84%) ~ 2.58s 2.84s p=0.936 n=6
Total Time 43.37s (± 0.69%) 43.48s (± 0.26%) ~ 43.31s 43.61s p=0.297 n=6
self-build-src-public-api - node (v18.15.0, x64)
Errors 0 0 ~ ~ ~ p=1.000 n=6
Symbols 1,221,221 1,221,264 +43 (+ 0.00%) ~ ~ p=0.001 n=6
Types 259,523 259,540 +17 (+ 0.01%) ~ ~ p=0.001 n=6
Memory used 2,414,011k (± 0.03%) 2,413,361k (± 0.02%) ~ 2,412,776k 2,413,868k p=0.128 n=6
Parse Time 6.26s (± 0.82%) 6.28s (± 1.55%) ~ 6.15s 6.42s p=0.936 n=6
Bind Time 2.04s (± 1.30%) 2.04s (± 0.62%) ~ 2.02s 2.05s p=1.000 n=6
Check Time 40.27s (± 0.21%) 40.31s (± 0.15%) ~ 40.20s 40.37s p=0.518 n=6
Emit Time 3.11s (± 2.72%) 3.16s (± 3.29%) ~ 3.04s 3.27s p=0.423 n=6
Total Time 51.71s (± 0.23%) 51.80s (± 0.32%) ~ 51.54s 51.96s p=0.378 n=6
self-compiler - node (v18.15.0, x64)
Errors 0 0 ~ ~ ~ p=1.000 n=6
Symbols 256,767 256,809 +42 (+ 0.02%) ~ ~ p=0.001 n=6
Types 104,587 104,601 +14 (+ 0.01%) ~ ~ p=0.001 n=6
Memory used 426,112k (± 0.01%) 426,185k (± 0.01%) +73k (+ 0.02%) 426,109k 426,238k p=0.045 n=6
Parse Time 3.36s (± 0.62%) 3.35s (± 0.48%) ~ 3.33s 3.37s p=0.465 n=6
Bind Time 1.31s (± 0.62%) 1.32s (± 0.62%) ~ 1.31s 1.33s p=0.666 n=6
Check Time 17.84s (± 0.31%) 17.89s (± 0.34%) ~ 17.82s 17.98s p=0.147 n=6
Emit Time 1.38s (± 1.61%) 1.36s (± 1.57%) ~ 1.33s 1.38s p=0.072 n=6
Total Time 23.89s (± 0.19%) 23.91s (± 0.29%) ~ 23.81s 23.99s p=0.687 n=6
ts-pre-modules - node (v18.15.0, x64)
Errors 35 35 ~ ~ ~ p=1.000 n=6
Symbols 224,575 224,583 +8 (+ 0.00%) ~ ~ p=0.001 n=6
Types 93,785 93,791 +6 (+ 0.01%) ~ ~ p=0.001 n=6
Memory used 369,897k (± 0.03%) 369,921k (± 0.02%) ~ 369,780k 370,041k p=1.000 n=6
Parse Time 3.52s (± 0.66%) 3.50s (± 1.12%) ~ 3.44s 3.56s p=0.376 n=6
Bind Time 1.93s (± 0.89%) 1.95s (± 1.10%) ~ 1.93s 1.98s p=0.163 n=6
Check Time 19.40s (± 0.29%) 19.36s (± 0.41%) ~ 19.25s 19.47s p=0.688 n=6
Emit Time 0.00s 0.00s ~ ~ ~ p=1.000 n=6
Total Time 24.85s (± 0.26%) 24.81s (± 0.39%) ~ 24.66s 24.92s p=0.518 n=6
vscode - node (v18.15.0, x64)
Errors 0 0 ~ ~ ~ p=1.000 n=6
Symbols 2,823,941 2,823,942 +1 (+ 0.00%) ~ ~ p=0.001 n=6
Types 957,912 957,912 ~ ~ ~ p=1.000 n=6
Memory used 2,996,285k (± 0.00%) 2,996,309k (± 0.00%) ~ 2,996,200k 2,996,378k p=0.298 n=6
Parse Time 17.02s (± 0.39%) 16.98s (± 0.22%) ~ 16.93s 17.04s p=0.223 n=6
Bind Time 5.04s (± 0.29%) 5.04s (± 0.27%) ~ 5.02s 5.05s p=0.933 n=6
Check Time 89.44s (± 0.22%) 89.28s (± 0.35%) ~ 88.92s 89.84s p=0.229 n=6
Emit Time 28.83s (± 0.59%) 28.77s (± 0.40%) ~ 28.59s 28.88s p=0.810 n=6
Total Time 140.33s (± 0.25%) 140.06s (± 0.22%) ~ 139.76s 140.66s p=0.128 n=6
webpack - node (v18.15.0, x64)
Errors 0 0 ~ ~ ~ p=1.000 n=6
Symbols 265,866 265,866 ~ ~ ~ p=1.000 n=6
Types 108,401 108,401 ~ ~ ~ p=1.000 n=6
Memory used 410,516k (± 0.01%) 410,529k (± 0.02%) ~ 410,484k 410,672k p=0.810 n=6
Parse Time 3.84s (± 1.36%) 3.82s (± 0.85%) ~ 3.79s 3.87s p=0.870 n=6
Bind Time 1.67s (± 0.83%) 1.66s (± 0.31%) ~ 1.66s 1.67s p=0.928 n=6
Check Time 16.93s (± 0.20%) 16.95s (± 0.29%) ~ 16.90s 17.01s p=0.572 n=6
Emit Time 0.00s 0.00s ~ ~ ~ p=1.000 n=6
Total Time 22.44s (± 0.35%) 22.44s (± 0.30%) ~ 22.34s 22.54s p=0.936 n=6
xstate-main - node (v18.15.0, x64)
Errors 0 0 ~ ~ ~ p=1.000 n=6
Symbols 524,639 524,639 ~ ~ ~ p=1.000 n=6
Types 178,906 178,906 ~ ~ ~ p=1.000 n=6
Memory used 462,680k (± 0.03%) 462,702k (± 0.01%) ~ 462,612k 462,808k p=0.423 n=6
Parse Time 3.12s (± 0.24%) 3.11s (± 0.55%) ~ 3.08s 3.13s p=0.280 n=6
Bind Time 1.17s (± 0.76%) 1.16s (± 0.54%) ~ 1.15s 1.17s p=0.070 n=6
Check Time 18.21s (± 0.85%) 18.33s (± 0.21%) ~ 18.29s 18.40s p=0.296 n=6
Emit Time 0.00s (±154.76%) 0.00s ~ ~ ~ p=0.174 n=6
Total Time 22.50s (± 0.68%) 22.60s (± 0.21%) ~ 22.54s 22.67s p=0.419 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

@jakebailey Here are the results of running the top 400 repos comparing main and refs/pull/58495/merge:

Everything looks good!

@dgreensp
Copy link

This is incredible work! Hope to see it land :)

Am I correct that this allows a function to assert things about multiple parameters?

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

Successfully merging this pull request may close these issues.

6 participants