GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Look for usable type nodes in associated expressions for declaration emit by weswigham · Pull Request #57772 · microsoft/TypeScript

Conversation

@weswigham

@weswigham Wesley Wigham (weswigham) commented Mar 14, 2024 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member

Per our design meeting notes (#57756), to expedite things a bit, this is a version of #57589 that (re)uses the machinery we already have for node reuse within the NodeBuilder in the checker.

Honestly, a worthwhile endeavor, since the test cases from the other PR let me find a bug in the existing node reuse code where we weren't reusing any nodes with a parameter or property in them (oops). The quick fix for that is responsible for most of the test whitespace changes in this PR (reused nodes don't get EmitFlags.SingleLine set, new nodes always do - and if that's a good thing or not is another discussion) - but I could split that short change out, if that was important for comparison (but it'd make two of the examples in tests\cases\compiler\declarationEmitCastReusesTypeNode5.ts not be copied - that's what made me notice the issue).

I've also normalized the new tests a bit, so all the similar ones test all the same variations, in addition to a couple extra variations. Notable differences from the original PR include this working for JS declaration emit, for set accessors, and for annotated required initialized parameters. I also took the opportunity to normalize all the callers of serializeExistingTypeNode (since I was adding another one or two) to perform the same sanity checking on the type (so all callers ensure the type node we're preserving actually resolves to the type we're looking at, and that if we're looking at a type reference, we don't try and reuse a type reference with less than the required number of type arguments (an error that is kind-of allowed in JS, but definitely results in an error if you copy it unmodified into TS)).

Fixes #57587

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@weswigham
Look for usable type nodes in associated expressions for declaration …
753a248
…emit
@weswigham
Wesley Wigham (weswigham) requested review from Ryan Cavanaugh (RyanCavanaugh) and Jake Bailey (jakebailey) March 14, 2024 03:39
@typescript-bot TypeScript Bot (typescript-bot) assigned Wesley Wigham (weswigham) Mar 14, 2024
@typescript-bot TypeScript Bot (typescript-bot) added Author: Team For Backlog Bug PRs that fix a backlog bug labels Mar 14, 2024
jakebailey
Jake Bailey (jakebailey) reviewed Mar 14, 2024
View reviewed changes
Comment thread tests/baselines/reference/optionalMethods.js Resolved

Uh oh!

There was an error while loading. Please reload this page.

weswigham
Wesley Wigham (weswigham) commented Mar 14, 2024
View reviewed changes

@weswigham Wesley Wigham (weswigham) left a comment

Copy link
Copy Markdown
Member Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

Neglected to post this last night, but I have some explanations for some of the smaller sub-changes here, that are a bit apart from the core change.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread src/compiler/checker.ts
if (sym) {
if (isSymbolAccessible(sym, context.enclosingDeclaration, SymbolFlags.All, /*shouldComputeAliasesToMakeVisible*/ false).accessibility !== SymbolAccessibility.Accessible) {
introducesError = true;
if (!isDeclarationName(node)) {

@weswigham Wesley Wigham (weswigham) Mar 14, 2024

Copy link
Copy Markdown
Member Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

This single line is the bugfix I mention in the OP - this is sufficient for most cases, but not complete. A (x: whatever) => typeof x node we try to reuse will no longer be rejected on the first x in the parameter list, so we'll use the parameters and signature, but the typeof x will still be rejected, since x isn't actually "in scope" in the scope we're considering. This could be fixed by invoking the same "fake scope" logic we already use in signatureToSignatureDeclarationHelper for wholly synthetic signatures to stack up the signature scopes we're trying to preserve as we descend, but since that doesn't seem to be relevant for any tests here, I've left that for future work for now, since it's a slight refactor to extract the "fake scope" helper functions into the outer scope.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread src/compiler/checker.ts
}
if (isParameter(node)) {
if (!node.type && !node.initializer) {
return factory.updateParameterDeclaration(node, /*modifiers*/ undefined, node.dotDotDotToken, visitEachChild(node.name, visitExistingNodeTreeSymbols, /*context*/ undefined), node.questionToken, factory.createKeywordTypeNode(SyntaxKind.AnyKeyword), /*initializer*/ undefined);

@weswigham Wesley Wigham (weswigham) Mar 14, 2024

Copy link
Copy Markdown
Member Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

This was kinda of just a drive-by fix - when looking at the whitespace changes, I noticed that some retained nodes in types baselines were missing : any because the input didn't have them. This probably never comes up in real code, since declaration emit doesn't trigger if the input code has errors, and basically everyone (our tests included) has noImplicitAny on. Still, .types baselines are made (and error messages!) - so this should (and does) help those cases look more complete (not that type portability across compiler settings matters for them).

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

DanielRosenwasser reacted with thumbs up emoji
All reactions
  • 👍 1 reaction
Comment thread src/compiler/checker.ts
}

if (file && isTupleTypeNode(node) && (getLineAndCharacterOfPosition(file, node.pos).line === getLineAndCharacterOfPosition(file, node.end).line)) {
if (file && isTupleTypeNode(node) && !nodeIsSynthesized(node) && (getLineAndCharacterOfPosition(file, node.pos).line === getLineAndCharacterOfPosition(file, node.end).line)) {

@weswigham Wesley Wigham (weswigham) Mar 14, 2024

Copy link
Copy Markdown
Member Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

I toyed with expanding this make-tuples-single-line-if-the-input-was-single-line to all object types, which works, but affects a lot of baselines. And it just made me notice the other cases where it wasn't retained even more, because the declaration emitter, when it keeps around an existing node, also doesn't set SingleLine. In the end, I decided messing with the whitespace was a bit too far out of scope, so left that for another day. But what I kept was this nodeIsSynthesized check - getLineAndCharacterOfPosition asserts if it gets a -1 for a position. When I was doing it for more nodes, I found this can crash, because the nodes may already have been transformed. I could put together a test for said crash, now that I know it's there, but I'm not sure what passes in a node with synthetic positions into this function - maybe something via a quickfix? The fix is just this, at least.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread src/compiler/checker.ts
// whose input is not type annotated (if the input symbol has an annotation we can reuse, we should prefer it)
const ctxSrc = getSourceFileOfNode(context.enclosingDeclaration);
return getObjectFlags(typeToSerialize) & (ObjectFlags.Anonymous | ObjectFlags.Mapped) &&
!some(typeToSerialize.symbol?.declarations, isTypeNode) && // If the type comes straight from a type node, we shouldn't try to break it up

@weswigham Wesley Wigham (weswigham) Mar 14, 2024

Copy link
Copy Markdown
Member Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

The JS declaration emit example is, apparently, the first time we've printed multiple variables of the same type where that type is defined in the current file in js declaration emit tests. It revealed that we tried to print them all as a namespace, but all the namespaces after the first would have no members, since they already got printed. That's silly. The namespace output mode for JS declaration emit is really supposed to be for things merged together across a lot of definitions - we can be pretty sure that if the type comes from a type node (as opposed to, say a binary expression or property access expression), we shouldn't convert it to a namespace (since, like, just writing a type node should be able to perfectly capture a type from a type node).

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread src/compiler/checker.ts
: !!(declaration as HasInitializer).initializer
? (declaration as HasInitializer & typeof declaration).initializer
: isParameter(declaration) && isSetAccessor(declaration.parent)
? getSingleReturnExpression(getAllAccessorDeclarations(getSymbolOfDeclaration(declaration.parent)?.declarations, declaration.parent).getAccessor)

@weswigham Wesley Wigham (weswigham) Mar 14, 2024

Copy link
Copy Markdown
Member Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

The accessor case in the original PR not working made me sad, so I added this line and made it work. We're smart and can look at multiple places for the potential annotation, after all.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread src/compiler/checker.ts
* so a `unique symbol` is returned when appropriate for the input symbol, rather than `typeof sym`
*/
function serializeTypeForDeclaration(context: NodeBuilderContext, type: Type, symbol: Symbol, enclosingDeclaration: Node | undefined, includePrivateSymbol?: (s: Symbol) => void, bundled?: boolean) {
function serializeTypeForDeclaration(context: NodeBuilderContext, type: Type, symbol: Symbol, enclosingDeclaration: Node | undefined, includePrivateSymbol?: (s: Symbol) => void, bundled?: boolean, addUndefined?: boolean) {

@weswigham Wesley Wigham (weswigham) Mar 14, 2024

Copy link
Copy Markdown
Member Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

Honestly, we can probably delete the addUndefined parameter with a bit more work - this function can rederive the same thing with the arguments it's given. Given that, since these functions do attempt top-level node reuse now, it'd also be nice to just ditch requiresAddingImplicitUndefined from the EmitResolver entirely, and let the resolver's internals figure it out when you call serializeTypeForDeclaration via createTypeOfDeclaration. I actually tried this for a second, and it seems like the only major blocker is that createReturnTypeOfSignatureDeclaration actually isn't what we want - we need it to return type predicate nodes, too! You can't notice the issue today, since all predicates have to be annotated, so they get preserved in the declaration emitter, but #57465 will change this! It's very likely the structure of that code will change a bit in response to that PR, and then maybe removing addUndefined and requiresAddingImplicitUndefined will feel more easily done.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

danvk reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

@DanielRosenwasser Daniel Rosenwasser (DanielRosenwasser) Mar 15, 2024

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

but #57465 will change this

Would it be good to proactively add a test case for that?

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@weswigham Wesley Wigham (weswigham) Mar 15, 2024

Copy link
Copy Markdown
Member Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

It adds its' own tests for it and since you can't cast into a type predicate like null! as x is number, I don't think this PR has much to add on top of that. But it should still make the refactor I mentioned above easier to do - though I don't really want to do it here, since it'll probably require fixing some more discrepancies between the declaration emitter's existing type node reuse logic and the node builder's inner type node reuse logic, as while the later is generalized to apply at the top level (using serializeTypeForDeclaration on the top-level type node if present), I've not yet done a comparison to see if the behaviors are identical (though it's already in use for JS declarations, ofc).

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread tests/baselines/reference/optionalMethods.js Resolved

Uh oh!

There was an error while loading. Please reload this page.

@DanielRosenwasser

Daniel Rosenwasser (DanielRosenwasser) commented Mar 14, 2024

Copy link
Copy Markdown
Member

TypeScript Bot (@typescript-bot) pack this
TypeScript Bot (@typescript-bot) user test tsserver
TypeScript Bot (@typescript-bot) test tsserver top200
TypeScript Bot (@typescript-bot) perf test this

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@typescript-bot

TypeScript Bot (typescript-bot) commented Mar 14, 2024 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor

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

Command Status Results
pack this ✅ Started ✅ Results
user test tsserver ✅ Started ✅ Results
test tsserver top200 ✅ Started 👀 Results
perf test this ✅ Started 👀 Results
All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@typescript-bot

TypeScript Bot (typescript-bot) commented Mar 14, 2024 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor

Hey Daniel Rosenwasser (@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/160375/artifacts?artifactName=tgz&fileId=8DC261A07C381925E09DAFD3EC14E5AB5D52A38F5F18CFF20E5CB0CBE9A6ABA202&fileName=/typescript-5.5.0-insiders.20240314.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]".;

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@typescript-bot

TypeScript Bot (typescript-bot) commented Mar 14, 2024

Copy link
Copy Markdown
Contributor

Daniel Rosenwasser (@DanielRosenwasser) Here are the results of running the user test suite comparing main and refs/pull/57772/merge:

Everything looks good!

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@typescript-bot

TypeScript Bot (typescript-bot) commented Mar 14, 2024

Copy link
Copy Markdown
Contributor

Daniel Rosenwasser (@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
Angular - node (v18.15.0, x64)
Memory used 295,636k (± 0.01%) 295,656k (± 0.01%) ~ 295,632k 295,703k p=0.149 n=6
Parse Time 2.66s (± 0.28%) 2.66s (± 0.44%) ~ 2.64s 2.67s p=0.933 n=6
Bind Time 0.82s (± 0.66%) 0.83s (± 0.62%) ~ 0.82s 0.83s p=0.640 n=6
Check Time 8.21s (± 0.38%) 8.21s (± 0.34%) ~ 8.17s 8.24s p=0.622 n=6
Emit Time 7.14s (± 0.41%) 7.17s (± 0.42%) ~ 7.13s 7.21s p=0.225 n=6
Total Time 18.83s (± 0.29%) 18.86s (± 0.18%) ~ 18.81s 18.91s p=0.171 n=6
Compiler-Unions - node (v18.15.0, x64)
Memory used 193,298k (± 0.94%) 192,676k (± 0.93%) ~ 191,378k 195,045k p=0.575 n=6
Parse Time 1.36s (± 1.95%) 1.35s (± 0.60%) ~ 1.34s 1.36s p=0.324 n=6
Bind Time 0.72s (± 0.00%) 0.72s (± 0.00%) ~ 0.72s 0.72s p=1.000 n=6
Check Time 9.29s (± 0.34%) 9.30s (± 0.37%) ~ 9.25s 9.34s p=0.809 n=6
Emit Time 2.59s (± 0.49%) 2.60s (± 0.47%) ~ 2.59s 2.62s p=0.103 n=6
Total Time 13.97s (± 0.30%) 13.97s (± 0.23%) ~ 13.94s 14.02s p=1.000 n=6
Monaco - node (v18.15.0, x64)
Memory used 347,368k (± 0.01%) 347,367k (± 0.01%) ~ 347,314k 347,391k p=1.000 n=6
Parse Time 2.48s (± 0.42%) 2.47s (± 0.65%) ~ 2.44s 2.48s p=0.082 n=6
Bind Time 0.93s (± 0.56%) 0.92s (± 0.56%) ~ 0.92s 0.93s p=0.311 n=6
Check Time 6.95s (± 0.26%) 6.93s (± 0.30%) ~ 6.90s 6.96s p=0.168 n=6
Emit Time 4.08s (± 0.35%) 4.07s (± 0.43%) ~ 4.04s 4.09s p=0.677 n=6
Total Time 14.44s (± 0.17%) 14.40s (± 0.34%) ~ 14.31s 14.45s p=0.120 n=6
TFS - node (v18.15.0, x64)
Memory used 302,797k (± 0.01%) 302,805k (± 0.01%) ~ 302,779k 302,856k p=0.336 n=6
Parse Time 2.00s (± 0.77%) 2.00s (± 1.12%) ~ 1.98s 2.04s p=0.807 n=6
Bind Time 1.01s (± 0.63%) 1.01s (± 1.32%) ~ 0.99s 1.02s p=1.000 n=6
Check Time 6.31s (± 0.33%) 6.34s (± 0.41%) ~ 6.32s 6.39s p=0.054 n=6
Emit Time 3.60s (± 0.38%) 3.61s (± 0.34%) ~ 3.60s 3.63s p=0.155 n=6
Total Time 12.93s (± 0.21%) 12.97s (± 0.39%) ~ 12.92s 13.06s p=0.108 n=6
material-ui - node (v18.15.0, x64)
Memory used 511,261k (± 0.00%) 511,251k (± 0.01%) ~ 511,223k 511,284k p=0.688 n=6
Parse Time 2.65s (± 0.46%) 2.65s (± 0.48%) ~ 2.63s 2.66s p=0.654 n=6
Bind Time 0.98s (± 1.00%) 0.98s (± 0.85%) ~ 0.97s 0.99s p=0.588 n=6
Check Time 17.30s (± 0.18%) 17.32s (± 0.31%) ~ 17.27s 17.40s p=0.574 n=6
Emit Time 0.00s (± 0.00%) 0.00s (± 0.00%) ~ 0.00s 0.00s p=1.000 n=6
Total Time 20.94s (± 0.19%) 20.96s (± 0.20%) ~ 20.91s 21.01s p=0.419 n=6
mui-docs - node (v18.15.0, x64)
Memory used 1,797,827k (± 0.00%) 1,797,831k (± 0.00%) ~ 1,797,806k 1,797,860k p=0.873 n=6
Parse Time 6.62s (± 0.35%) 6.61s (± 0.38%) ~ 6.59s 6.66s p=0.517 n=6
Bind Time 2.38s (± 0.59%) 2.38s (± 0.32%) ~ 2.37s 2.39s p=0.867 n=6
Check Time 59.14s (± 0.54%) 59.07s (± 0.41%) ~ 58.75s 59.46s p=0.873 n=6
Emit Time 0.16s (± 2.52%) 0.17s (± 3.32%) ~ 0.16s 0.17s p=0.282 n=6
Total Time 68.30s (± 0.47%) 68.23s (± 0.34%) ~ 67.93s 68.62s p=0.810 n=6
self-build-src - node (v18.15.0, x64)
Memory used 2,395,458k (± 0.04%) 2,396,659k (± 0.02%) +1,201k (+ 0.05%) 2,396,132k 2,397,329k p=0.045 n=6
Parse Time 5.01s (± 1.05%) 5.02s (± 0.78%) ~ 4.97s 5.08s p=0.810 n=6
Bind Time 1.90s (± 1.14%) 1.90s (± 0.87%) ~ 1.88s 1.92s p=1.000 n=6
Check Time 33.61s (± 0.34%) 33.61s (± 0.45%) ~ 33.38s 33.83s p=1.000 n=6
Emit Time 2.68s (± 1.43%) 2.70s (± 1.21%) ~ 2.66s 2.74s p=0.422 n=6
Total Time 43.23s (± 0.36%) 43.25s (± 0.42%) ~ 43.00s 43.54s p=0.689 n=6
self-compiler - node (v18.15.0, x64)
Memory used 414,789k (± 0.01%) 415,550k (± 0.01%) +761k (+ 0.18%) 415,489k 415,597k p=0.005 n=6
Parse Time 2.82s (± 1.13%) 2.81s (± 0.82%) ~ 2.77s 2.84s p=0.511 n=6
Bind Time 1.06s (± 0.84%) 1.07s (± 0.38%) ~ 1.06s 1.07s p=0.086 n=6
Check Time 15.17s (± 0.45%) 15.21s (± 0.37%) ~ 15.13s 15.26s p=0.376 n=6
Emit Time 1.10s (± 1.60%) 1.11s (± 0.95%) ~ 1.09s 1.12s p=0.413 n=6
Total Time 20.14s (± 0.38%) 20.19s (± 0.26%) ~ 20.12s 20.24s p=0.334 n=6
vscode - node (v18.15.0, x64)
Memory used 2,876,397k (± 0.00%) 2,876,397k (± 0.00%) ~ 2,876,202k 2,876,489k p=1.000 n=6
Parse Time 10.78s (± 0.23%) 10.78s (± 0.14%) ~ 10.76s 10.80s p=0.935 n=6
Bind Time 3.45s (± 0.35%) 3.45s (± 0.59%) ~ 3.42s 3.48s p=0.505 n=6
Check Time 61.19s (± 0.35%) 61.13s (± 0.40%) ~ 60.78s 61.51s p=0.471 n=6
Emit Time 16.45s (± 0.28%) 17.10s (± 8.08%) ~ 16.43s 19.92s p=0.090 n=6
Total Time 91.87s (± 0.23%) 92.46s (± 1.71%) ~ 91.47s 95.67s p=0.936 n=6
webpack - node (v18.15.0, x64)
Memory used 406,144k (± 0.01%) 406,154k (± 0.01%) ~ 406,075k 406,225k p=0.575 n=6
Parse Time 3.24s (± 1.49%) 3.21s (± 1.29%) ~ 3.16s 3.26s p=0.171 n=6
Bind Time 1.40s (± 1.25%) 1.39s (± 1.34%) ~ 1.37s 1.42s p=0.461 n=6
Check Time 14.05s (± 0.22%) 14.12s (± 0.22%) +0.07s (+ 0.52%) 14.08s 14.15s p=0.010 n=6
Emit Time 0.00s (± 0.00%) 0.00s (± 0.00%) ~ 0.00s 0.00s p=1.000 n=6
Total Time 18.70s (± 0.41%) 18.72s (± 0.36%) ~ 18.62s 18.80s p=0.689 n=6
xstate - node (v18.15.0, x64)
Memory used 513,185k (± 0.01%) 513,239k (± 0.01%) ~ 513,194k 513,291k p=0.128 n=6
Parse Time 3.27s (± 0.23%) 3.27s (± 0.19%) ~ 3.26s 3.28s p=0.718 n=6
Bind Time 1.54s (± 0.67%) 1.54s (± 0.34%) ~ 1.53s 1.54s p=0.242 n=6
Check Time 2.85s (± 0.36%) 2.86s (± 0.83%) ~ 2.84s 2.89s p=1.000 n=6
Emit Time 0.08s (± 0.00%) 0.08s (± 0.00%) ~ 0.08s 0.08s p=1.000 n=6
Total Time 7.75s (± 0.28%) 7.75s (± 0.39%) ~ 7.72s 7.79s 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

tsserver

Comparison Report - baseline..pr
Metric baseline pr Delta Best Worst p-value
Compiler-UnionsTSServer - node (v18.15.0, x64)
Req 1 - updateOpen 2,349ms (± 1.00%) 2,354ms (± 0.66%) ~ 2,335ms 2,372ms p=0.574 n=6
Req 2 - geterr 5,546ms (± 1.53%) 5,459ms (± 0.45%) ~ 5,427ms 5,487ms p=0.054 n=6
Req 3 - references 324ms (± 0.57%) 322ms (± 0.87%) ~ 319ms 326ms p=0.212 n=6
Req 4 - navto 275ms (± 0.82%) 277ms (± 0.62%) +3ms (+ 0.97%) 275ms 279ms p=0.035 n=6
Req 5 - completionInfo count 1,357 (± 0.00%) 1,357 (± 0.00%) ~ 1,357 1,357 p=1.000 n=6
Req 5 - completionInfo 89ms (± 6.00%) 82ms (± 3.60%) 🟩-7ms (- 7.72%) 79ms 85ms p=0.033 n=6
CompilerTSServer - node (v18.15.0, x64)
Req 1 - updateOpen 2,509ms (± 0.71%) 2,503ms (± 1.10%) ~ 2,458ms 2,530ms p=0.689 n=6
Req 2 - geterr 4,125ms (± 0.34%) 4,111ms (± 0.42%) ~ 4,087ms 4,128ms p=0.377 n=6
Req 3 - references 337ms (± 1.28%) 335ms (± 0.98%) ~ 332ms 341ms p=0.241 n=6
Req 4 - navto 286ms (± 0.18%) 286ms (± 0.26%) ~ 285ms 287ms p=0.241 n=6
Req 5 - completionInfo count 1,519 (± 0.00%) 1,519 (± 0.00%) ~ 1,519 1,519 p=1.000 n=6
Req 5 - completionInfo 89ms (± 0.84%) 89ms (± 0.00%) ~ 89ms 89ms p=0.598 n=6
xstateTSServer - node (v18.15.0, x64)
Req 1 - updateOpen 2,605ms (± 0.38%) 2,595ms (± 0.89%) ~ 2,559ms 2,617ms p=0.575 n=6
Req 2 - geterr 1,755ms (± 2.61%) 1,719ms (± 2.36%) ~ 1,668ms 1,779ms p=0.230 n=6
Req 3 - references 117ms (± 9.89%) 120ms (± 8.12%) ~ 107ms 128ms p=0.629 n=6
Req 4 - navto 369ms (± 0.68%) 369ms (± 1.17%) ~ 362ms 375ms p=0.870 n=6
Req 5 - completionInfo count 2,079 (± 0.00%) 2,079 (± 0.00%) ~ 2,079 2,079 p=1.000 n=6
Req 5 - completionInfo 307ms (± 1.53%) 309ms (± 1.23%) ~ 306ms 315ms p=0.195 n=6
System info unknown
Hosts
  • node (v18.15.0, x64)
Scenarios
  • CompilerTSServer - node (v18.15.0, x64)
  • Compiler-UnionsTSServer - node (v18.15.0, x64)
  • xstateTSServer - node (v18.15.0, x64)
Benchmark Name Iterations
Current pr 6
Baseline baseline 6

startup

Comparison Report - baseline..pr
Metric baseline pr Delta Best Worst p-value
tsc-startup - node (v18.15.0, x64)
Execution time 153.18ms (± 0.15%) 153.35ms (± 0.18%) +0.18ms (+ 0.11%) 152.17ms 155.22ms p=0.000 n=600
tsserver-startup - node (v18.15.0, x64)
Execution time 230.16ms (± 0.15%) 230.23ms (± 0.15%) ~ 228.67ms 233.20ms p=0.065 n=600
tsserverlibrary-startup - node (v18.15.0, x64)
Execution time 220.65ms (± 0.17%) 220.81ms (± 0.49%) +0.16ms (+ 0.07%) 219.21ms 269.23ms p=0.002 n=600
typescript-startup - node (v18.15.0, x64)
Execution time 221.60ms (± 0.15%) 221.53ms (± 0.14%) ~ 220.00ms 225.37ms p=0.068 n=600
System info unknown
Hosts
  • node (v18.15.0, x64)
Scenarios
  • tsc-startup - node (v18.15.0, x64)
  • tsserver-startup - node (v18.15.0, x64)
  • tsserverlibrary-startup - node (v18.15.0, x64)
  • typescript-startup - node (v18.15.0, x64)
Benchmark Name Iterations
Current pr 6
Baseline baseline 6

Developer Information:

Download Benchmarks

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@typescript-bot

TypeScript Bot (typescript-bot) commented Mar 14, 2024

Copy link
Copy Markdown
Contributor

Daniel Rosenwasser (@DanielRosenwasser) Here are the results of running the top-repos suite comparing main and refs/pull/57772/merge:

Something interesting changed - please have a look.

Details

Server exited prematurely with code unknown and signal SIGABRT

Server exited prematurely with code unknown and signal SIGABRT

Affected repos

calcom/cal.com Raw error text: RepoResults7/calcom.cal.com.rawError.txt in the artifact folder

Last few requests

{"seq":968,"type":"request","command":"getOutliningSpans","arguments":{"file":"@PROJECT_ROOT@/packages/app-store/utils.ts"}}
{"seq":969,"type":"request","command":"navtree","arguments":{"file":"@PROJECT_ROOT@/packages/app-store/utils.ts"}}
{"seq":970,"type":"request","command":"navbar","arguments":{"file":"@PROJECT_ROOT@/packages/app-store/utils.ts"}}
{"seq":971,"type":"request","command":"navto","arguments":{"searchValue":"a","maxResultCount":256}}

Repro steps

  1. git clone https://github.com/calcom/cal.com --recurse-submodules
  2. In dir cal.com, run git reset --hard 71b0dd2aa36095b19ee56c7c13589e21ed915ad7
  3. In dir cal.com, run yarn install --no-immutable --mode=skip-build
  4. Back in the initial folder, download RepoResults7/calcom.cal.com.replay.txt from the artifact folder
  5. npm install --no-save @typescript/server-replay
  6. npx tsreplay ./cal.com ./calcom.cal.com.replay.txt path/to/tsserver.js
  7. npx tsreplay --help to learn about helpful switches for debugging, logging, etc
All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

DanielRosenwasser
Daniel Rosenwasser (DanielRosenwasser) reviewed Mar 15, 2024
View reviewed changes

@DanielRosenwasser Daniel Rosenwasser (DanielRosenwasser) left a comment

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

Seems reasonable - the naming is a little interesting for expressionOrTypeToTypeNode, but we could rename in the future.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread src/compiler/checker.ts
* so a `unique symbol` is returned when appropriate for the input symbol, rather than `typeof sym`
*/
function serializeTypeForDeclaration(context: NodeBuilderContext, type: Type, symbol: Symbol, enclosingDeclaration: Node | undefined, includePrivateSymbol?: (s: Symbol) => void, bundled?: boolean) {
function serializeTypeForDeclaration(context: NodeBuilderContext, type: Type, symbol: Symbol, enclosingDeclaration: Node | undefined, includePrivateSymbol?: (s: Symbol) => void, bundled?: boolean, addUndefined?: boolean) {

@DanielRosenwasser Daniel Rosenwasser (DanielRosenwasser) Mar 15, 2024

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

but #57465 will change this

Would it be good to proactively add a test case for that?

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread src/compiler/checker.ts Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread src/compiler/checker.ts Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread src/compiler/checker.ts Resolved

Uh oh!

There was an error while loading. Please reload this page.

@DanielRosenwasser

Daniel Rosenwasser (DanielRosenwasser) commented Mar 15, 2024

Copy link
Copy Markdown
Member

Other than my comments (and the current merge conflict) I think this is good. Any other thoughts Ryan Cavanaugh (@RyanCavanaugh) Jake Bailey (@jakebailey) ?

weswigham reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

Wesley Wigham (weswigham) added 2 commits March 15, 2024 13:11
@weswigham
Merge branch 'main' into reuse-type-nodes-from-nearby-casts
69b6c63
@weswigham
PR feedback
018bef6
@jakebailey

Jake Bailey (jakebailey) commented Mar 15, 2024 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member

I think I still feel uneasy about the behavior of parameter properties. Take tests/cases/compiler/declarationEmitParameterProperty.ts, which has:

export class Foo {
  constructor(public bar?: string) {
  }
}

Our JS emit is:

var Foo = /** @class */ (function () {
    function Foo(bar) {
        this.bar = bar;
    }
    return Foo;
}());

bar is always assigned. Right now, the declaration file we emit is:

export declare class Foo {
    bar?: string | undefined;
    constructor(bar?: string | undefined);
}

But after this PR, it's:

export declare class Foo {
    bar?: string;
    constructor(bar?: string);
}

Consumers may read this as "the class will either have string, or the prop won't even exist".

I feel like maybe I'm not understanding #57772 (comment) or something, because this behavior really does look like a regression, and one of the ones that I pointed out in #53463.

RyanCavanaugh, DanielRosenwasser, and dragomirtitian reacted with thumbs up emoji
All reactions
  • 👍 3 reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@dragomirtitian Titian Cernicova-Dragomir (dragomirtitian) mentioned this pull request Mar 18, 2024
[ID-Prep] PR4 - Preserve types nodes from type assertions in declaration emit #57589
Closed
@weswigham
Make optional parameter property emit match old output
f2aee9b
@weswigham

Wesley Wigham (weswigham) commented Mar 18, 2024

Copy link
Copy Markdown
Member Author

Jake Bailey (@jakebailey) I've brought back the old emit for optional parameter properties - we can look into changing it later. It feels like they don't really play well with exactOptionalPropertyTypes as they are today.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@jakebailey

Jake Bailey (jakebailey) commented Mar 18, 2024

Copy link
Copy Markdown
Member

Jake Bailey (@jakebailey) I've brought back the old emit for optional parameter properties - we can look into changing it later. It feels like they don't really play well with exactOptionalPropertyTypes as they are today.

Thanks; I do wonder if we could simply preserve parameter properties in declaration emit, eliminating the need to rewrite the properties and making other emitters easier to write (just leave it as-is). But, not in this PR.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@jakebailey

Jake Bailey (jakebailey) commented Mar 18, 2024

Copy link
Copy Markdown
Member

(I am giving this PR one last pass now.)

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

jakebailey
Jake Bailey (jakebailey) reviewed Mar 18, 2024
View reviewed changes
Comment thread tests/cases/compiler/declarationEmitCastReusesTypeNode4.ts
/** @param {number} req */
methodWithRequiredDefault(p = /** @type {P} */(something), req) {}

constructor(ctorField = /** @type {P} */(something)) {}

@jakebailey Jake Bailey (jakebailey) Mar 18, 2024

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

This looks like a typo; should be public ctorField =..., right?

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@weswigham Wesley Wigham (weswigham) Mar 18, 2024

Copy link
Copy Markdown
Member Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

This is javascript, so no - since parameter properties are a syntax error in JS files.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@weswigham Wesley Wigham (weswigham) Mar 18, 2024

Copy link
Copy Markdown
Member Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

(And there's no jsdoc equivalent)

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@jakebailey Jake Bailey (jakebailey) Mar 18, 2024

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

Oh, whoops, didn't notice that.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
jakebailey
Jake Bailey (jakebailey) approved these changes Mar 18, 2024
View reviewed changes
@weswigham

Wesley Wigham (weswigham) commented Mar 18, 2024

Copy link
Copy Markdown
Member Author

I do wonder if we could simply preserve parameter properties in declaration emit, eliminating the need to rewrite the properties and making other emitters easier to write (just leave it as-is).

Unfortunately, we issue A parameter property is only allowed in a constructor implementation. when we read a parameter property from a constructor in a declaration file. So such a change would be a backwards incompatible change to declaration emit (though we admittedly still check it correctly, despite the error, so maybe not the worst break in emit in the world).

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@weswigham
Wesley Wigham (weswigham) merged commit 66047f7 into microsoft:main Mar 18, 2024
@weswigham Wesley Wigham (weswigham) mentioned this pull request Mar 22, 2024
Cherry pick PR #57887 into release-5.4 #57898
Merged
@jakebailey Jake Bailey (jakebailey) mentioned this pull request Apr 15, 2024
Add test for fixed declaration emit type parameter leak #58208
Closed
@Andarist Mateusz Burzyński (Andarist) mentioned this pull request May 1, 2024
typeof with identically named type and value causes invalid .d.ts output #58390
Closed
@microsoft Microsoft (microsoft) locked as resolved and limited conversation to collaborators Oct 16, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Reviewers

@DanielRosenwasser Daniel Rosenwasser (DanielRosenwasser) DanielRosenwasser left review comments
@jakebailey Jake Bailey (jakebailey) jakebailey approved these changes
@RyanCavanaugh Ryan Cavanaugh (RyanCavanaugh) Awaiting requested review from RyanCavanaugh

Uh oh!

There was an error while loading. Please reload this page.

Assignees

@weswigham Wesley Wigham (weswigham)

Labels

Author: Team For Backlog Bug PRs that fix a backlog bug

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

[ID-Prep] Preserve type nodes from type assertions in declarations

Uh oh!

There was an error while loading. Please reload this page.

4 participants

@weswigham @DanielRosenwasser @typescript-bot @jakebailey
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.