From 524ab52d32ef108ca0c09a63abc3ef96204eef38 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Thu, 24 Jul 2025 10:31:48 -0700 Subject: [PATCH 1/2] Update for TS7 I am testing Typescript 7's JS support, which I've largely rewritten during the switch to Go. The new code processes tags by converting them into synthetic nodes just after parsing their host node. For unified, that means that `@template` tags can't be shared between multiple `@overload` tags like before. This PR also has to convert function declarations with `@type` on them to variables initialised with a function expression. TS7 doesn't currently support this feature on function declarations--but both unified and svelte use this feature a lot, so I think we'll need to add it before TS7's JS features are ready. At that point the shuffling of functions in the test files won't be needed anymore. In addition, https://github.com/microsoft/typescript-go/pull/1444 makes it possible to have rest parameters in `@overload`, and is needed for this change to work in TS7, so it won't compile with the nightly until that PR is merged. Because TS7 is quite a way off, I don't know whether you'll want to take this PR. I created it to see how hard it would be to update popular JS code that uses TS for checking. --- lib/index.js | 44 ++++++++++++++++++++++---------------------- test/freeze.js | 32 ++++++++++++++++---------------- test/process-sync.js | 33 +++++++++++++++++---------------- 3 files changed, 55 insertions(+), 54 deletions(-) diff --git a/lib/index.js b/lib/index.js index 5e06134c..16cf2e55 100644 --- a/lib/index.js +++ b/lib/index.js @@ -538,7 +538,6 @@ export class Processor extends CallableInstance { * processor.data() // => {charlie: 'delta'} * ``` * - * @template {keyof Data} Key * * @overload * @returns {Data} @@ -547,15 +546,18 @@ export class Processor extends CallableInstance { * @param {Data} dataset * @returns {Processor} * + * @template {keyof Data} Key * @overload * @param {Key} key * @returns {Data[Key]} * + * @template {keyof Data} Key * @overload * @param {Key} key * @param {Data[Key]} value * @returns {Processor} * + * @template {keyof Data} Key * @param {Data | Key} [key] * Key to get or set, or entire dataset to set, or nothing to get the * entire dataset (optional). @@ -805,6 +807,14 @@ export class Processor extends CallableInstance { let complete = false /** @type {VFileWithOutput | undefined} */ let result + /** + * @type {ProcessCallback>} + */ + const realDone = (error, file) => { + complete = true + bail(error) + result = file + } this.freeze() assertParser('processSync', this.parser || this.Parser) @@ -815,15 +825,6 @@ export class Processor extends CallableInstance { assert(result, 'we either bailed on an error or have a tree') return result - - /** - * @type {ProcessCallback>} - */ - function realDone(error, file) { - complete = true - bail(error) - result = file - } } /** @@ -940,21 +941,21 @@ export class Processor extends CallableInstance { let complete = false /** @type {(TailTree extends undefined ? Node : TailTree) | undefined} */ let result - - this.run(tree, file, realDone) - - assertDone('runSync', 'run', complete) - assert(result, 'we either bailed on an error or have a tree') - return result - /** * @type {RunCallback} */ - function realDone(error, tree) { + const realDone = (error, tree) => { bail(error) result = tree complete = true } + + this.run(tree, file, realDone) + + assertDone('runSync', 'run', complete) + assert(result, 'we either bailed on an error or have a tree') + return result + } /** @@ -1029,10 +1030,6 @@ export class Processor extends CallableInstance { * .use({settings: {position: false}}) * ``` * - * @template {Array} [Parameters=[]] - * @template {Node | string | undefined} [Input=undefined] - * @template [Output=Input] - * * @overload * @param {Preset | null | undefined} [preset] * @returns {Processor} @@ -1041,6 +1038,9 @@ export class Processor extends CallableInstance { * @param {PluggableList} list * @returns {Processor} * + * @template {Array} [Parameters=[]] + * @template {Node | string | undefined} [Input=undefined] + * @template [Output=Input] * @overload * @param {Plugin} plugin * @param {...(Parameters | [boolean])} parameters diff --git a/test/freeze.js b/test/freeze.js index 56296c87..4153a8eb 100644 --- a/test/freeze.js +++ b/test/freeze.js @@ -8,6 +8,22 @@ import test from 'node:test' import {unified} from 'unified' import {simpleCompiler, simpleParser} from './util/simple.js' +// `this` in JS is buggy in TS. +/** + * @type {Plugin<[], string, Node>} + */ +const parse = function () { + this.parser = simpleParser +} + +// `this` in JS is buggy in TS. +/** + * @type {Plugin<[], Node, string>} + */ +const compile = function () { + this.compiler = simpleCompiler +} + test('`freeze`', async function (t) { const frozen = unified().use(parse).use(compile).freeze() @@ -219,19 +235,3 @@ test('`freeze`', async function (t) { }) }) }) - -// `this` in JS is buggy in TS. -/** - * @type {Plugin<[], string, Node>} - */ -function parse() { - this.parser = simpleParser -} - -// `this` in JS is buggy in TS. -/** - * @type {Plugin<[], Node, string>} - */ -function compile() { - this.compiler = simpleCompiler -} diff --git a/test/process-sync.js b/test/process-sync.js index 6fbdc9c8..1c599b8b 100644 --- a/test/process-sync.js +++ b/test/process-sync.js @@ -8,6 +8,23 @@ import test from 'node:test' import {unified} from 'unified' import {simpleCompiler, simpleParser} from './util/simple.js' + +// `this` in JS is buggy in TS. +/** + * @type {Plugin<[], string, Node>} + */ +const parse = function () { + this.parser = simpleParser +} + +// `this` in JS is buggy in TS. +/** + * @type {Plugin<[], Node, string>} + */ +const compile = function () { + this.compiler = simpleCompiler +} + test('`processSync`', async function (t) { await t.test('should throw w/o `parser`', async function () { assert.throws(function () { @@ -63,19 +80,3 @@ test('`processSync`', async function (t) { } ) }) - -// `this` in JS is buggy in TS. -/** - * @type {Plugin<[], string, Node>} - */ -function parse() { - this.parser = simpleParser -} - -// `this` in JS is buggy in TS. -/** - * @type {Plugin<[], Node, string>} - */ -function compile() { - this.compiler = simpleCompiler -} From c9b387004cff2cca4cef64ee258762ce88cae16f Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Thu, 24 Jul 2025 11:42:33 -0700 Subject: [PATCH 2/2] undo function->variable change --- lib/index.js | 34 ++++++++++++++++++---------------- test/freeze.js | 32 ++++++++++++++++---------------- test/process-sync.js | 33 ++++++++++++++++----------------- 3 files changed, 50 insertions(+), 49 deletions(-) diff --git a/lib/index.js b/lib/index.js index 16cf2e55..895e6f5b 100644 --- a/lib/index.js +++ b/lib/index.js @@ -807,14 +807,6 @@ export class Processor extends CallableInstance { let complete = false /** @type {VFileWithOutput | undefined} */ let result - /** - * @type {ProcessCallback>} - */ - const realDone = (error, file) => { - complete = true - bail(error) - result = file - } this.freeze() assertParser('processSync', this.parser || this.Parser) @@ -825,6 +817,16 @@ export class Processor extends CallableInstance { assert(result, 'we either bailed on an error or have a tree') return result + + /** + * @type {ProcessCallback>} + */ + function realDone(error, file) { + complete = true + bail(error) + result = file + } + } /** @@ -941,14 +943,6 @@ export class Processor extends CallableInstance { let complete = false /** @type {(TailTree extends undefined ? Node : TailTree) | undefined} */ let result - /** - * @type {RunCallback} - */ - const realDone = (error, tree) => { - bail(error) - result = tree - complete = true - } this.run(tree, file, realDone) @@ -956,6 +950,14 @@ export class Processor extends CallableInstance { assert(result, 'we either bailed on an error or have a tree') return result + /** + * @type {RunCallback} + */ + function realDone(error, tree) { + bail(error) + result = tree + complete = true + } } /** diff --git a/test/freeze.js b/test/freeze.js index 4153a8eb..56296c87 100644 --- a/test/freeze.js +++ b/test/freeze.js @@ -8,22 +8,6 @@ import test from 'node:test' import {unified} from 'unified' import {simpleCompiler, simpleParser} from './util/simple.js' -// `this` in JS is buggy in TS. -/** - * @type {Plugin<[], string, Node>} - */ -const parse = function () { - this.parser = simpleParser -} - -// `this` in JS is buggy in TS. -/** - * @type {Plugin<[], Node, string>} - */ -const compile = function () { - this.compiler = simpleCompiler -} - test('`freeze`', async function (t) { const frozen = unified().use(parse).use(compile).freeze() @@ -235,3 +219,19 @@ test('`freeze`', async function (t) { }) }) }) + +// `this` in JS is buggy in TS. +/** + * @type {Plugin<[], string, Node>} + */ +function parse() { + this.parser = simpleParser +} + +// `this` in JS is buggy in TS. +/** + * @type {Plugin<[], Node, string>} + */ +function compile() { + this.compiler = simpleCompiler +} diff --git a/test/process-sync.js b/test/process-sync.js index 1c599b8b..6fbdc9c8 100644 --- a/test/process-sync.js +++ b/test/process-sync.js @@ -8,23 +8,6 @@ import test from 'node:test' import {unified} from 'unified' import {simpleCompiler, simpleParser} from './util/simple.js' - -// `this` in JS is buggy in TS. -/** - * @type {Plugin<[], string, Node>} - */ -const parse = function () { - this.parser = simpleParser -} - -// `this` in JS is buggy in TS. -/** - * @type {Plugin<[], Node, string>} - */ -const compile = function () { - this.compiler = simpleCompiler -} - test('`processSync`', async function (t) { await t.test('should throw w/o `parser`', async function () { assert.throws(function () { @@ -80,3 +63,19 @@ test('`processSync`', async function (t) { } ) }) + +// `this` in JS is buggy in TS. +/** + * @type {Plugin<[], string, Node>} + */ +function parse() { + this.parser = simpleParser +} + +// `this` in JS is buggy in TS. +/** + * @type {Plugin<[], Node, string>} + */ +function compile() { + this.compiler = simpleCompiler +}