mirror of
https://github.com/lit/lit.git
synced 2026-03-20 07:44:18 +00:00
Page:
Lit Development Resources
No results
This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
TypeScript Compiler API & Related Tools Notes
TypeScript Compiler API
- Resources:
- Symbols
- AST
Nodes can have an associatedSymbol, which is something that ultimately refers to aDeclaration(usechecker.getSymbolAtLocation(node)to retrieve it) Symbols can have multiple associatedDeclarations, because of the following:- Classes (the interface + the constructor)
- Namespace merging (e.g. lots of
declare global { interface HTMLElementTagNameMap {...} }contribute to the final value ofHTMLElementTagNameMap
- A
Symbol's Declaration may be ats.ImportSpecifierif it was imported (it will not necessarily be the original variable/class/function/… declaration that created the thing)- To get the original declaration of an imported symbol from its declaring source file, use
checker.getAliasedSymbol(symbol) - If the symbol was not imported, but rather its type came from an ambient .d.ts file (for example,
lib.dom.d.tsfor DOM globals), the declaration for the symbol retrieved from current source file will be its declaration in the .d.ts file (since there is nots.importSpecifierin the current source file)
- To get the original declaration of an imported symbol from its declaring source file, use
- AST
- Types
- Types can have representation in the AST when things are explicitly typed: e.g. in
let foo: number | Promise<number>, there will be syntax nodes for the type; those AST nodes extendts.TypeNode(which extend the AST node base classts.Node) - We can also get the inferred type of a syntax node using
checker.getTypeAtLocation(node). This returns ats.Type, which is not a tree of syntax nodes, but rather a tree of type nodes. - The compiler API does not have any built-in visitor support for Type trees, as far as I can tell. However, it is possible to convert a
ts.Typeto ats.TypeNodeusingchecker.typeToTypeNode(type)- This generates syntax nodes from type nodes (as if one had walked the type node and used the
ts.factoryAPI to create equivalent syntax nodes - The TypeNodes are then walkable using
ts.ForEachChild - The API docs note that these syntax nodes "are not checkable", so their use is limited.
- In particular,
ts.getSymbolForLocation(node)fails to return a symbol for node created usingtypeToTypeNode(). In order to find symbols forTypeReferences, we need to usechecker.getSymbolsInScope(node).filter(s => s.name === name)
- This generates syntax nodes from type nodes (as if one had walked the type node and used the
- Types can have representation in the AST when things are explicitly typed: e.g. in
- Literal Types
- The type inferred from a literal assignment/value will be a literal type (e.g.
const foo = 'hi'will have a type of"hi") - To turn a literal type into its wider base type (e.g.
string), usechecker.getBaseTypeOfLiteralType(type)
- The type inferred from a literal assignment/value will be a literal type (e.g.
Typescript-ESLint Plugin
- Resources:
- The conventional naming scheme used by ESLint is maddening. In general, it expects plugin npm module names to be prefixed with
eslint-plugin-, and then a shorthand used in e.g. rule names, plugin names, etc. is derived from the suffix, and gets wonky with npm orgs:- npm module
eslint-plugin-my-thing→ eslint plugin namemy-thing - npm module
@my-org/eslint-plugin→ eslint plugin name@my-org - npm module
@my-org/eslint-plugin-my-thing→ unclear;@my-org/my-thingdoesn't seem to work
- npm module
- To see loading errors or debug console.logs from the plugin in VSCode, go the "Output" tab in the terminals area and select "ESLint" in the dropdown
- In order to get a ts program/checker in a custom rule, the user's
.eslintrchas to point to atsconfig.jsonvia aparserOptions.projectsetting (in addition to theextends: [ 'plugin:@lit-labs/all']` to pull in a config- It doesn't seem like a single
.eslintrcconfig in a monorepo with multipletsconfig.jsons is well supported. "project": "**/tsconfig.json"does seem to work, but feels rather heavy
- It doesn't seem like a single
- Each time the rule runs, you get handed a new
ts.Program.ts.SourceFiles within the program that weren't changed are referentially equal to the last time the rule ran, which bodes well for caching keyed off the ts Node. - Since control is inverted from the current analyzer factoring (i.e., we don't control the serviceHost that creates the program), I don't see a good way to do the
/** Event {Type} */gambit, since we can't update files (to add the dummy declarations) and re-check them. So might need to re-think that, unfortunately.
Typescript Language Server Plugin
- Resources:
- You can put an npm package for a LSP in
tsconfig.jsoncompilerOptions.plugins.name, however vscode will try to resolve it from the bundled vscode TS installation location (and fail) unless you switch vscode to using the "workspace TS version" via cmd-P: "Typescript: Select Typescript Version"; in a monorepo where there might be lots of TS's, the plugin needs to be installed adjacent to the selected TS. - To see loading errors or debug messages (by using
info.project.projectService.logger.info, notconsole.log!), use cmd-P: "TypeScript: Open TS Server Log" (will ask to enable it once, apparently it's a perf thing since it logs so much). - To debug a plugin in VSCode:
- Start a separate VSCode using TSS_DEBUG env variable, e.g.:
TSS_DEBUG=5667 code --user-data-dir ~/.vscode-debug/ ./lit-next.code-workspace - Make sure to cmd-P "Typescript: Select Typescript Version" in the new VSCode window
- From VSCode used to develop plugin, cmd-P, "Debug: Attach to Node Process", and select instance with port 5667
- From there,
debuggers in plugin source should work
- Start a separate VSCode using TSS_DEBUG env variable, e.g.:
Ideal:
- Analyzer
- Generate CEM-like models from source
- Library for template type-checking
- Collect diagnostics, mappable by TS node
- Lit language service - Provides jump to definition, etc.
- Lit ESLit plugin - James's rules + Lit template type-checking
First steps
- Add eslint-plugin-lit folder to labs
- Add rule to detect @property type disagreement with TypeScript type