2.3.3.7 release notes
2.3.3.7
- Removed support for JetBrains 2023.3 IDEs. Unfortunately that version has an increasing number of incompatibilities with recent big features including Agentforce for Developers and LWC TypeScript support described below.
- Issue 1921 - Added beta-level support for Lightning Web Components development in TypeScript. I've posted a video demonstration of the feature. It's rather lengthy, but I've provided direct links to key topics in the video description.
You can access the ported fork of theebikes-lwc
repository used in the video demonstration here, and similarly you can access the ported fork of thedreamhouse-lwc
repository here and the ported fork of thelwc-recipes
repository here . In each forked repository, themain
branch is effectively the same as the original but with a fully-configured IC project included, and theic_lwc_ts
branch includes the results of porting from JavaScript to TypeScript.
Again, this is still an early version of this feature, but I feel like it's in a solid enough state to make it available to end users for hands-on usage and feedback. There are several known issues and limitations that I'll enumerate clearly below. First, though, I'll describe the features and enhancements:Feature and Enhancements
- The LWC component creation dialog now lets you specify that the component's logic files should be in TypeScript instead of ES6. This preference is retained across invocations. Creation of other logic files — including Jest tests — for a TypeScript-based component are also assumed to be in TypeScript. When TypeScript is selected as the language for component logic, a clear warning is displayed about the beta-level state of this feature.
- The LWC tabbed editor UI now properly takes into consideration TypeScript-based components. JavaScript files generated by the TypeScript compiler are not included in the tabbed editor but can be opened explicitly in their own file editors or via the Navigate | Related Symbol... action from any LWC bundle file included in the tabbed editor.
- TypeScript source files are automatically compiled into the corresponding JavaScript on all deployment requests. Errors reported by the compiler cause deployment to fail fast and are integrated into the IDE. Deployment errors reported by the Salesforce org are attributed to the original TypeScript source files using inline source maps in the generated JavaScript files.
- TypeScript source files are also automatically compiled into JavaScript without deployment when the local development server is running and IC is configured not to deploy LWC source files so that the respective changes are reflected properly in the local development server.
- IC automatically helps configure the project for TypeScript development, creating and/or updating the required project configuration files as appropriate, installing/updating dependencies, etc. Note that some of these files should not be edited or changed as they are regenerated automatically based on standard templates, and any external changes will be discarded. Such files are clearly denoted with file header comments. Both source format and metadata format projects are supported. For metadata format projects, quite a few config files are added to the project including an
sfdx-project.json
pre-configured so that IC knows the project is metadata format.
NOTE:npm
(and thereforenode
) must be installed and available via the system execution path. - IC automatically maintains up-to-date TypeScript LWC modules under
projectRoot/.illuminatedCloud/lwc/types
for Salesforce-specific TypeScript modules including those based on project metadata, e.g.,@AuraEnabled
Apex declarations and translated representations of their input and output types as appropriate; static resources and content assets; SObject types and fields; custom permissions; message channels; custom labels; etc. TypeScript translations of all SObject types and their fields are also included. Note that these modules are also used for ES6 TypeScript development now. - I have included a number of code assistance features that help add strong data types to untyped expressions, both during the migration from ES6 to TypeScript and for ongoing development in TypeScript. These include:
- A code inspection/intention for functions and fields with the
@wire
decorator to add strong data types based on the respective wire adapters to the function parameters and fields respectively. These are added asWireResult<WiredDataType>
whereWireResult
is the type previously calledFetchResponseAndData
— a type alias is available for existing usages — and has the standard (strongly-typed)data
anderror
properties. - A code inspection/intention for event handler method parameters to add strong data types based on the component/element from which the event was raised based on the event handler attribute or component/element through which it was invoked, e.g.,
DragEvent
orCustomEvent<LightningInput>
. - A code intention for calls to
createElement()
,querySelector()
, andquerySelectorAll()
to add the inferred method type parameter when possible based on the provided element type or selector expression evaluated against the component's main HTML document. - A code intention for calls to the
publish()
andsubscribe()
functions of thelightning/messageService
module to add strong data types for the message payload when published as an object literal and received as a function expression respectively. - A code inspsection/intention for unresolvable mock method calls against imported wire adapters in Jest tests that casts the imported wire adapter name to the respective mock type, either
jest.MockInstance
or one of@salesforce/wire-service-jest-util.[Apex|Lds]TestWireAdapter
. - Alternatively, a new TypeScript LWC-specific live template,
lwc-wire-mock
, that helps to create a strongly-typed mock alias for an imported wire adapter in a Jest test. - I'm also considering adding a code intention to help restructure parameters of the destructured form
{data, error}
asresult: WireResult<WiredDataType>
using the correct inferredWiredDataType
and updating all references todata
anderror
to beresult.data
andresult.error
respectively. However, that's not included in this release. Definitely let me know if you have a broad application of this pattern and would like assistance with migrating to the more strongly-typed equivalent.
- A code inspection/intention for functions and fields with the
- Agentforce for Developers inline completion settings now includes a distinct option for TypeScript that is enabled by default.
Known Issues and Limitations
- While this feature technically works in JetBrains' free Community Edition IDEs, it is likely going to be of very limited value due to the lack of first-class support for TypeScript, Node/NPM, etc. in those IDEs. Additionally, TypeScript compilation in Community Edition IDEs is slower as it executes as a distinct external process per-compilation vs. being able to use the integrated compiler service. IC should be paired with a commercial JetBrains IDE to realize the full benefits of this integration.
- I have worked very hard to massage the bundled standard LWC modules into a solid state, but the truth is that due to the historical nature of LWC ES6 being quite loosely-typed, at least in terms of static data typing, the bundled standard LWC modules are often inaccurate, incorrect, or incomplete. In order to support strongly-typed LWC development in ES6, I've hand-maintained a set of modules based on a combination of Salesforce's own modules and the published API documentation. Because ES6 isn't an inherently strongly-typed language, many of the relevant data types are described but not clearly named, so while types may exist in IC's bundled modules and even be accurate (though not always), their names may not be "correct" (quoted because, in most cases, there hasn't been a concrete point-of-reference to establish "correctness"). I will continue to evolve the bundled modules based on the work that Salesforce is also doing on this front, closing existing gaps in completeness, consistency, accuracy, and fidelity. Whenever possible, I will try to retain backward-compatibility throughout these changes with type aliases, clearly denoting when a type name should be considered deprecated and how usages should be migrated. Because the TypeScript compiler strips all concrete type information, the main risk is that something that compiles from TypeScript to JavaScript successfully against IC's bundled modules may fail to compile against Salesforce's (or vice-versa) at present. It is always safe to use ambient types — inline or explicit as local types — in those cases as they will work properly in both environments. You will also likely find yourself needing to suppress errors reported by the IDE using preceding
@ts-ignore
or@ts-expect-error
comments. More on that below. - Closely-related, there appear to be some bugs/inconsistencies in LWC that are more evident in a strongly-typed environment. The most obvious example is with
CustomEvent
instances passed to HTML event handlers. When parameterized using the event source component type, e.g.,CustomEvent<LightningInput>
, one would typically want to use the event's strongly-typeddetails
property to extract component type-specific data instead of the untypedtarget
property. However, these two properties seem to be set by the LWC runtime inconsistently. I will raise this and other similar issues with Salesforce in hopes that they will be resolved in short order. In the interim, you can always use type casting/coercion on thetarget
property to interact with it in a strongly-typed manner, e.g.,(event.target as unknown as LightningInput).value.toLowerCase()
. - IC executes the TypeScript compiler using a transient, compiler-specific
tsconfig.json
file. During the (hopefully short) duration of TypeScript compilation, the IDE may briefly show errors in TypeScript editors, particularly around LWC-specific decorator usages. Without going into too much unnecessary detail, this is due to differences in the configuration required by the IDE's integrated TypeScript language services and that required to yield JavaScript source that's valid for deployment to Salesforce. I hope to address this at some point soon but wanted to mention why such temporary (and incorrect) errors might be displayed during compilation. - When IC compiles via the commercial JetBrains IDE's TypeScript compiler service, there may be a slight pause before the deployment proceeds (assuming compilation succeeds). This is due to a JetBrains bug that should hopefully be resolved in 2024.3.1. Also note that you may see occassional failures from service-based compilation due to a timeout. If/when you do, you can retry the operation or, if necessary, restart the TypeScript language/compiler service from the status bar. I apologize for these problems, but they're part of the same issue linked above, and I'm hoping to have a proper solution for it shortly. Worst case scenario, I could add a configuration option to force compilation to occur via the command-line which is slower but reliable. I'd prefer to avoid that unless absolutely necessary, though.
- The original TypeScript source files exist only in the local project and are never deployed to the Salesforce organization as part of the component bundles. The organization is only ever aware of the compiled JavaScript output files. As a result, only those will be included in subsequent metadata retrievals from the organization. It is therefore critical that the original TypeScript source files be mastered in a version control system.
- If TypeScript-based LWC components are to be used in automation environments such as with CI/CD systems, the compiled JavaScript output files should be included in version control even though they are generated artifacts. This ensures that the automation tools are not required to perform the TypeScript-to-JavaScript compilation step that itself requires all of the standard and project-specific modules. Hopefully as support for TypeScript-based LWC development matures, the Salesforce CLI itself will assist with this and only the TypeScript master source files will need to be included in version control.
Anecdotal Experience
While developing and testing this feature, I converted several projects from ES6 to TypeScript including my own hobby LWC side project and a few of Salesforce's open source LWC reference implementation projects. I applied the following process to these conversions:
- Renamed all LWC
*.js
files to*.ts
. - For each resulting TypeScript source file, migrated all type information conveyed via
@type
,@param
, and@return
comments to actual types in the respective declarations and addressed any other reported errors, warnings, and inspection-based suggestions until each file was reported as clean (green checkmark from the code inspector). Several reported errors were simply suppressed as they represented false positives due to the known issues described above. Note that Context Actions — including the data type inference code inspections and intentions described above — were critical in this process as they almost always included the appropriate (or at least a reasonable starting) remediation. - Confirmed that all Jest tests passed properly. I ran into a few situations where recommended actions — particularly those from the TypeScript Language Service as opposed to the JetBrains code inspections — resulted in breaking changes. The most specific example that comes to mind is a suggestion from TS for Jest test methods labeled
TS80006: This may be converted to an async function
that caused the corresponding test methods to fail after the conversion. So while I said above that the recommended context actions are exceptionally useful, at least some can cause problems. Always make sure that the resulting TypeScript code is behaviorally identical to the original JavaScript code. - Deployed the project to the org — in this case, specifically a dedicated scratch org and not any type of "sacred" org — and compared the compiled JavaScript output files to the original ES6 source files. The only differences I saw were due to:
- Minor white space changes from the TypeScript compiler, e.g., decorators being placed on their own lines vs. being inline with the declaration, and compound statements such as
if/else
being split across lines differently. - Applied code improvements/simplications suggested by the IDE for TypeScript that weren't recommended for ES6.
- Minor white space changes from the TypeScript compiler, e.g., decorators being placed on their own lines vs. being inline with the declaration, and compound statements such as
- Exercised and tested the resulting changes in the org itself.
- Committed all of the resulting changes — both source code and configuration files — to a separate branch in version control as I continued to work through the migration. Again, nothing was deployed to a "sacred" org or committed to a "sacred" version control branch.
Note that I do not recommend that users immediately migrate existing mission-critical (or even just somewhat important) LWC applications from ES6 to TypeScript while this feature is still in such an early state. I am doing so with my own hobby application as another channel for testing the changes, particularly as the aforementioned known issues and limitations are improved and/or addressed.
If you do decide to begin this migration, though, I strongly recommend that you carefully audit all generated JavaScript source files that are actually deployed to the Salesforce org to ensure that they are, for all intents and purposes, exactly what you would have written yourself in ES6.
- Issue 2678 - Fixed an issue with connection credentials verification in the IC2 connection manager due to a change in how the IDE processes modality states in 2024.3.