首页 > 解决方案 > 打字稿:声明类实现接口

问题描述

有一个类型化模块——'markdown-it'定义一个接口来描述一个存在于另一个(非类型化)模块中的类——'markdown-it/lib/token'

我想为后者定义类型,为此我创建了一个.d.ts文件:

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

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

可悲的是,Typescript 抱怨说Token没有实现MarkdownIt.Token.

最理想的情况是,我想告诉 Typescript “类和接口是相同的”。但即使这是不可能的,我什至不能复制定义,因为

Token错误地实现了接口markdownit.Token
类型Token不匹配签名new (type: string, tag: string, nesting: number): Token

不管我是否这样做

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)
...
}

标签: typescripttypescript-typings

解决方案


诀窍是将类声明与扩展原始接口的接口声明合并:

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

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

当您手动复制接口方法时,您发现原始接口声明中似乎有一个错误,这不会阻止上述技术的工作,但仍然是错误的:

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

这就是说一个Token实例可以与new操作符一起使用来创建另一个Token实例,例如:

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

那将是非常不寻常的设计,我在 JavaScript 实现中看不到它实际上受支持的迹象。请提交问题以删除构造签名。或者,如果您打算将您的增强功能贡献给 DefinitiveTyped,您可以在同一个拉取请求中进行更改。


推荐阅读