5

There’s a typed module – 'markdown-it' – defining an interface that describes a class living in another (untyped) module – 'markdown-it/lib/token'

I would like to define typings for the latter, for which I created a .d.ts file:

declare module 'markdown-it/lib/token' {
    import * as MarkdownIt from 'markdown-it'

    class Token implements MarkdownIt.Token {}
    export = Token
}

Sadly, Typescript complains that Token doesn’t implement MarkdownIt.Token.

Optimally, I’d like to tell Typescript “the class and interface are identical”. But even if this isn’t possible, I can’t even copy the definition, as

Class Token incorrectly implements interface markdownit.Token.
Type Token provides no match for the signature new (type: string, tag: string, nesting: number): Token

no matter if I do

class Token implements MarkdownIt.Token {
    new (type: string, tag: string, nesting: number): Token
    // or
    new (type: string, tag: string, nesting: number): Token
    // or
    constructor(type: string, tag: string, nesting: number)
...
}

1 Answer 1

10

The trick is to merge the class declaration with an interface declaration that extends the original interface:

declare module 'markdown-it/lib/token' {
    import * as MarkdownIt from 'markdown-it'

    interface Token extends MarkdownIt.Token {}
    class Token {}
    export = Token
}

When you manually copied the interface methods, you found what appears to be a mistake in the original interface declaration, which won't stop the above technique from working but is nevertheless wrong:

interface Token {
    new (type: string, tag: string, nesting: number): Token;
    // ...
}

This is saying that a Token instance can be used with the new operator to create another Token instance, e.g.:

import Token = require("markdown-it/lib/token");
let a = new Token(...);
let b = new a(...);

That would be highly unusual design and I see no indication in the JavaScript implementation that it is actually supported. Please file an issue to have the construct signature removed. Or if you plan to contribute your enhancement to DefinitelyTyped, you could just make the change in the same pull request.

Sign up to request clarification or add additional context in comments.

1 Comment

Yes, the new declaration is indeed in the original (no constructor though). Thank you, this worked!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.