Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor to improve types #7

Merged
merged 2 commits into from
Jul 1, 2021
Merged

Refactor to improve types #7

merged 2 commits into from
Jul 1, 2021

Conversation

wooorm
Copy link
Member

@wooorm wooorm commented Jun 30, 2021

I improved the types a bit, namely:

  • Add missing dependencies
  • Test types of test.js too, to see if they work, which leaves one bug we should fix
  • Some refactoring

/cc @cbush

@codecov-commenter

This comment has been minimized.

index.js Show resolved Hide resolved
index.js Show resolved Hide resolved
package.json Show resolved Hide resolved
test.js Outdated
@@ -22,6 +29,7 @@ test('rehype2remark()', function (t) {
t.equal(
unified()
.use(parse, {fragment: true})
// @ts-expect-error: todo open issue.
.use(rehype2remark, unified())
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ChristianMurphy Any idea on how this can be fixed?

My hunch is that it could be solved by doing this: https://github.com/remarkjs/remark-rehype/blob/2b460d889893bf96324fa0ffa72b772b1e25c1b2/types/index.d.ts#L5, but in JSDoc. Any idea how to do that?

Might be something else tho

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the specific TS error thrown?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

test.js:32:27 - error TS2559: Type 'Processor<Settings>' has no properties in common with type 'Options'.

32       .use(rehype2remark, unified())
                             ~~~~~~~~~

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It did pass when I removed & ((options?: Options) => Transformer), leaving only ((destination: Processor, options?: Options) => Transformer), although of course some other things failed.
I don’t think it should be | between the two instead of & (I tried and it didn’t work). 🤔

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI I do think this is the first JSDoc-style thing accepting maybe multiple arguments? Or at least accepting an (optional) processor as the first argument?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The overloads in unified can be misleading, they'll report on the last overload that falls through.
To get a clearer trace try

interface ExamplePluginSettings {
  example: string
}

function overloadedPlugin(processorOrOptions?: ExamplePluginSettings): void
function overloadedPlugin(processorOrOptions: Processor, options?: ExamplePluginSettings): void
function overloadedPlugin(processorOrOptions?: Processor | ExamplePluginSettings, options?: ExamplePluginSettings): void {}

const testingPluginType: Plugin<[ExamplePluginSettings?] | [Processor, ExamplePluginSettings?]> = overloadedPlugin

which reports back:

Type '{ (processorOrOptions?: ExamplePluginSettings | undefined): void; (processorOrOptions: Processor<Settings>, options?: ExamplePluginSettings | undefined): void; }' is not assignable to type 'Plugin<[(ExamplePluginSettings | undefined)?] | [Processor<Settings>, (ExamplePluginSettings | undefined)?], Settings>'.
  Types of parameters 'processorOrOptions' and 'settings' are incompatible.
    Type '[(ExamplePluginSettings | undefined)?] | [Processor<Settings>, (ExamplePluginSettings | undefined)?]' is not assignable to type '[processorOrOptions?: ExamplePluginSettings | undefined]'.
      Type '[Processor<Settings>, (ExamplePluginSettings | undefined)?]' is not assignable to type '[processorOrOptions?: ExamplePluginSettings | undefined]'.
        Type at position 0 in source is not compatible with type at position 0 in target.
          Property 'example' is missing in type 'Processor<Settings>' but required in type 'ExamplePluginSettings'

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ChristianMurphy Figured it out, see next push.

But, what’s the reason unified.Settings is passed as a type param to plugins? https://github.com/unifiedjs/unified/blob/45eb72e7e7bb4745b94677c5f5681ac0c433d704/types/index.d.ts#L21

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That was a compromise to get untyped plugins kinda working in typescript.
If no type is provided for a plugin's settings, it assumes a single interface with something object like.

I wouldn't mind walking that back out, either requiring an options interface, or defaulting to no options, now that more of the ecosystem has types.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm also not sure the error has to do with the default, some examples from testing locally

function overloadedPlugin(processorOrOptions?: ExamplePluginSettings): Transformer
function overloadedPlugin(processorOrOptions: Processor, options?: ExamplePluginSettings): Transformer
function overloadedPlugin(processorOrOptions?: Processor | ExamplePluginSettings, options?: ExamplePluginSettings): Transformer {return () =>{}}

// error on next line, TS doesn't see the overload as compatible with plugin
const testing123: Plugin<[ExamplePluginSettings?]|[Processor, ExamplePluginSettings?]> = overloadedPlugin

processor.use(testing123)
function overloadedPlugin(processorOrOptions?: ExamplePluginSettings): Transformer
function overloadedPlugin(processorOrOptions: Processor, options?: ExamplePluginSettings): Transformer
function overloadedPlugin(processorOrOptions?: Processor | ExamplePluginSettings, options?: ExamplePluginSettings): Transformer {return () =>{}}

const testing123: Plugin<[ExamplePluginSettings?]> | Plugin<[Processor, ExamplePluginSettings?]> = overloadedPlugin

// error on next line, TS does consider a union of Plugins to be compatible with Plugin
processor.use(testing123)

@wooorm wooorm merged commit 1e3e7d5 into main Jul 1, 2021
@wooorm wooorm deleted the improve-types branch July 1, 2021 07:37
@wooorm
Copy link
Member Author

wooorm commented Jul 1, 2021

Released in 8.1.0!

@cbush
Copy link
Contributor

cbush commented Jul 1, 2021

Nice! Is the index.d.ts file supposed to be included in the release, though? 😅

@ChristianMurphy
Copy link
Member

It is #8

@cbush
Copy link
Contributor

cbush commented Jul 1, 2021

Ah! Good to know where to update package.json for next time. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants