twoslashes v0.0.5
TwoSlashes
A fork and rewrite of @typescript/twoslash, with improvements:
!NOTE Working in progress, breaking changes are expected.
- Unified information interface, consistent and easier to manipulate
createTwoslasherfunction to create a twoslash instance with cached language servers (5-20 times faster!)- ESM-first, dual CJS/ESM builds
keepNotationsflag for better support of custom languages (seetwoslash-vueintegration)- Lighter, no longer deps on
lz-stringanddebug
Breaking Changes
Breaking changes from @typescript/twoslash:
- The returned items have different signatures, and different types of the items (
staticQuickInfo,queries,errors,tags) are now unified into a single arraynodes. Learn more at the Information Nodes section. - Main entry point
import "twoslashes"bundlestypescript, while a new sub-entryimport "twoslashes/core"is dependency-free and requires providing your own typescript instance. defaultOptionsis renamed tohandbookOptionsdefaultCompilerOptionsis renamed tocompilerOptions
Features
Information Nodes
TwoSlashes returns all types of information in the nodes array.
With some common properties:
type: the type of the node. Can behover,query,error,tag,highlightorcompletion(in some entries waskindin@typescript/twoslash)start: the 0-indexed start position of the node in the output codeline: a 0-indexed line number of the node in the output codecharacter: a 0-indexed character number of the node in the output code (in some entries it wasoffsetin@typescript/twoslash)length: length of the node
For different types of nodes, they have some extra properties:
hover
text: the text of the hover, usually the type information of the given nodedocs: the jsdoc of the given node, can beundefined
query
Same as hover
highlight
text: the extra annotation text of the highlight, can beundefined
completion
completion: the completion entriescompletionPrefix: the prefix of the completion
error
text: the error message (wasrenderedMessagein@typescript/twoslash)level: the error level (wascategoryin@typescript/twoslash)code: TypeScript error codeid: a generated based on the code and position of the error
tag
text: the text of the tag (wasannotationin@typescript/twoslash)
Getters
To make it easier to access, we also provide some getters shortcuts to each type of the nodes:
export interface TwoSlashReturn {
/** The output code */
code: string
/**
* Nodes containing various bits of information about the code
*/
nodes: TwoSlashNode[]
/** Getters */
get hovers(): NodeHover[] // was `staticQuickInfos`
get queries(): NodeQuery[] // was `queries` with `kind: 'query'`
get completions(): NodeCompletion[] // was `queries` with `kind: 'completion'`
get errors(): NodeError[]
get highlights(): NodeHighlight[]
get tags(): NodeTag[]
/**
* The meta information
*/
meta: TwoSlashReturnMeta
}createTwoSlasher
TwoSlash runs a TypeScript language server to get the information, which could be a heavy operation to load and parse all the files it needs. In repetitive usages, you may not want to initialize the language server every simple time. TwoSlashes provides a createTwoslasher factory function allows you to cache the language servers and reuse the already initialized files.
import { createTwoSlasher } from 'twoslashes'
const twoslasher = createTwoSlasher({
// you can have some default options here
})
const result1 = twoslasher('import { ref } from "vue"', 'ts')
// the second time will be much faster as the types from `vue` is already
const result2 = twoslasher('import { computed } from "vue"', 'ts')This would result in a 5-20 times faster performance in repetitive usage.
To avoid getting interference across runs, it will reuse the language server with the same compilerOptions. Internally it holds a map of hashed compilerOptions to the language server instances.
You can retrieve the cached map and clear it when necessary, to avoid memory leaks:
import { createTwoSlasher } from 'twoslashes'
const twoslasher = createTwoSlasher()
// do something
// Clear the cached language servers, free the memory
twoSlasher.getCacheMap()?.clear()Backward Compatibility Layer
To make it easier to migrate from @typescript/twoslash, TwoSlashes provides a backward compatibility layer that allows you to use the old interface with the new implementation.
import { twoslasherLegacy } from 'twoslashes'
const result = twoslasherLegacy('import { ref } from "vue"', 'ts')
console.log(result.staticQuickInfos) // the old interfaceYou can also compose it your own by only converting the return value:
import { convertLegacyReturn, twoslasher } from 'twoslashes'
const result = twoslasher('import { ref } from "vue"', 'ts') // new interface
const legacy = convertLegacyReturn(result) // <--
console.log(legacy.staticQuickInfos) // the old interfaceBenchmark
twoslashes - bench/compare.bench.ts > compiler_errors.ts
18.28x faster than @typescript/twoslash
twoslashes - bench/compare.bench.ts > compiler_flags.ts
20.41x faster than @typescript/twoslash
twoslashes - bench/compare.bench.ts > completions.ts
11.08x faster than @typescript/twoslash
twoslashes - bench/compare.bench.ts > cuts_out_unnecessary_code.ts
9.72x faster than @typescript/twoslash
twoslashes - bench/compare.bench.ts > errorsWithGenerics.ts
11.08x faster than @typescript/twoslash
twoslashes - bench/compare.bench.ts > highlighting.ts
10.90x faster than @typescript/twoslash
twoslashes - bench/compare.bench.ts > import_files.ts
6.62x faster than @typescript/twoslash
twoslashes - bench/compare.bench.ts > importsModules.ts
6.06x faster than @typescript/twoslash
twoslashes - bench/compare.bench.ts > multiFileErrors.ts
4.35x faster than @typescript/twoslash
twoslashes - bench/compare.bench.ts > query.ts
13.15x faster than @typescript/twoslash
twoslashes - bench/compare.bench.ts > arbitraryCommands.ts
10.98x faster than @typescript/twoslash
twoslashes - bench/compare.bench.ts > crossExports.ts
6.16x faster than @typescript/twoslash
twoslashes - bench/compare.bench.ts > cut_file_errors.ts
10.34x faster than @typescript/twoslash
twoslashes - bench/compare.bench.ts > cut_files.ts
13.73x faster than @typescript/twoslash
twoslashes - bench/compare.bench.ts > handlesJSON.ts
4.16x faster than @typescript/twoslash
twoslashes - bench/compare.bench.ts > inlineHighlights.ts
13.28x faster than @typescript/twoslash
twoslashes - bench/compare.bench.ts > large-cut.ts
10.23x faster than @typescript/twoslash
twoslashes - bench/compare.bench.ts > lib.ts
12.57x faster than @typescript/twoslash
twoslashes - bench/compare.bench.ts > multiLookups.ts
11.82x faster than @typescript/twoslash
twoslashes - bench/compare.bench.ts > queriesWithSpaceBefore.ts
12.51x faster than @typescript/twoslash
twoslashes - bench/compare.bench.ts > queryHandlesNoToken.ts
10.36x faster than @typescript/twoslash
twoslashes - bench/compare.bench.ts > twoliner.ts
6.58x faster than @typescript/twoslashLicense
MIT License © Microsoft Corporation MIT License © 2023-PRESENT Anthony Fu