GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | |||||||||||||||||||||||||||||||||||||||
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | |||||||||||||||||||||||||||||||||||||||
GeezerVison is showing github.com — [ID-Prep] PR4 - Preserve types nodes from type assertions in declaration emit by dragomirtitian · Pull Request #57589 · microsoft/TypeScript Conversation
Contributor
Fixes #57587
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactions
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Changed this to preserve the original intent of the test (test what happens when huge type nodes need to be printed).
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactions
Titian Cernicova-Dragomir (dragomirtitian)
force-pushed
the
ts-verbatim-declrations-from-assertions
branch
from
f996402 to
9399b32
Compare
Uh oh!
There was an error while loading. Please reload this page.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Feels weird to have this detail in the transform; right now the only options that are used are ones explicitly related to declaration emit (noResolve/stripInternal). My impression is that isolatedDeclarations is not assumed to know the compiler options; is the case that we can treat strictNullChecks as true for emit with the assumption that
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactions
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is a bit of class X { // x?: 1 | 2 | undefined; with !strictNullChecks // x?: 1 | 2; // with !strictNullChecks x? = 1 as 1 | 2 }
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactions
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sure but if a user doesn't have strictNullChecks enabled, aren't the two equivalent? Since the way that strictNullChecks=false works is to effectively treat null/undefined as though they don't exist.
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactions
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. They are usually, but if you take the declaration from a project with
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactions
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thinking about it, it might actually be an improvement. Because a I can change this to always add Maybe this should be a different PR though? One that always adds
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactions
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I guess I see what you mean, in that this PR is only trying to touch assertions and therefore making this code unconditional would not change any other declarations?
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactions
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Exactly. Even it's final form,
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactions
Titian Cernicova-Dragomir (dragomirtitian)
force-pushed
the
ts-verbatim-declrations-from-assertions
branch
from
c47b97d to
4f63418
Compare
…eclrations-from-assertions
Ron Buckton (rbuckton)
suggested changes
Uh oh!
There was an error while loading. Please reload this page. Uh oh!
There was an error while loading. Please reload this page. Uh oh!
There was an error while loading. Please reload this page. Uh oh!
There was an error while loading. Please reload this page. Uh oh!
There was an error while loading. Please reload this page. Uh oh!
There was an error while loading. Please reload this page. Uh oh!
There was an error while loading. Please reload this page. Uh oh!
There was an error while loading. Please reload this page. Uh oh!
There was an error while loading. Please reload this page.
Titian Cernicova-Dragomir (dragomirtitian)
force-pushed
the
ts-verbatim-declrations-from-assertions
branch
from
4ffc67a to
5506934
Compare
Ron Buckton (rbuckton)
approved these changes
Jake Bailey (jakebailey)
previously approved these changes
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I still don't feel too great about declaration emit directly knowing about strictNullChecks as I'm not sure how we are expecting third party emitters to also know this, but, I guess it's fine.
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactions
Contributor
All reactions
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page.
Member
All reactions
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page.
Contributor
Author
All reactions
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page.
Contributor
All reactions
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page.
Contributor
All reactions
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page.
|
There was an error while loading. Please reload this page.
|
Starting jobs; this comment will be updated as builds start and complete.
|
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
|
Hey Ron Buckton (@rbuckton), I've packed this into an installable tgz. You can install it for testing by referencing it in your and then running There is also a playground for this build and an npm module you can use via |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
IMO, this is something we could/should have done even without isolated declarations, and we've done things like this in the past. We already have machinery for cloning/reusing input type nodes in new locations inside the emit resolver (usually for signatures copied from one location to another by structural inlining) - this logic should be moved into it, too, so all the guardrails around node copying are in one place (and there are a fair few). Over in createTypeOfDeclaration and createReturnTypeOfSignatureDeclaration they both defer to nodeBuilder.typeToTypeNode - within the node builder, we have a serializeExistingTypeNode (and parent function serializeTypeForDeclaration used extensively by the JS declaration emitter) function that adds a lot of guard rails onto this node copying process, because, well, there's a lot that needs to be checked for that currently isn't in this PR.
IMO, this logic should be exposed on the nodeBuilder and then used by the EmitResolver's createTypeOfDeclaration and createReturnTypeOfSignatureDeclaration instead of typeToTypeNode directly (rather than built directly into the declarations transformer). That way it's easy to leverage the existing caching and safe copying mechanisms we have, and to reuse the logic in the JS declaration emitter (which, I dunno if you wanna consider testing that out of scope or not).
Sorry, something went wrong.
There was an error while loading. Please reload this page.
Outdated; see Wesley's comment
There was an error while loading. Please reload this page.
|
The goal of the PRs to align emit is to extract more information directly from the initialisers of declarations that have them. To this end we will extract extract types from:
The general idea is that the types in these cases are trivial enough that by looking at the initialization expressions it is possible to derive the type node, without having to go through the type checker. This approach may yield a more readable type in some cases but not necessarily. The end goal is to allow external tools to perform the same transformations, and to be able to guarantee that these transformations are indeed just syntactical ones that don’t use any type information that is not local to the initialiser. Option 1: Transform initialisers to type nodes in the type checker (node builder)This approach will have all the logic for extracting the types in the same place as type nodes are synthesized from type checker types. Copying of existing type nodes already happens in Advantages
DisadvantagesThe declaration transform will not be runnable without the type checker. This creates several problems:
Option 2: Transform initialisers in the declaration emitThis is the approach in the current PR. This approach will have all the logic for extracting types from initialisers in the declaration transform. The declaration transform already does other purely syntactic transformation of original source to ensure the correct types in the declaration (ex: constructor class fields are transformed to parameters and fields, expressions in heritage clauses are moved to variables that are independently typed, default exports are moved to variables) Advantages
Disadvantages
Final thoughtsWhile for the current PR the extraction of the type happens from an assertion, for the other kinds of type from initializer transformations, there is no actual type node to extract from. But rather we go through the literal and create a new appropriate type if possible (reusing as much of the original AST). Putting this second way of getting the type in the typechecker does not really seem like a win. While in some cases the resulting types will be more faithful to the original source, the extra type information can also result in better types from the type checker. Just having the errors without actually extracting the type is also an option, but that makes the validation of external emitters much harder, as TypeScript may emit different declaration files (even if they are mostly semantically equivalent). Extraction from the initializer is needed for isolated declarations, but if it is always better for types to come from this source is not necessarily clear, and it’s a question that is out of scope for the current effort. Option 3: Factor out the shared logicIf we still want to reuse some of this logic in the type checker, maybe a better approach would be to factor out the type node from initializer logic into a separate component that can be reused in both |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
Closed in favor of #57772 |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
Successfully merging this pull request may close these issues.
[ID-Prep] Preserve type nodes from type assertions in declarations
There was an error while loading. Please reload this page.