在try 为emBind编写类型定义时,特别是extend特性,我遇到了一个我自己无法解决的问题.到目前为止,我所掌握的是:

export declare class Deletable {
    public delete(): void;
}

type Constructor<T> = new (...args: any[]) => T;

export declare class Extendable extends Deletable {
    public static extend<T extends Constructor<T>>(name: string, o: unknown): new (...args: ConstructorParameters<T>) => T;
    public static implement<T>(o: object): T;
}

class Lexer extends Extendable {
    public constructor(i?: number) { super(); }
}

const WhiteboxLexerTrampoline = Lexer.extend<Lexer>("Lexer", {
});

操场代码是here.错误在Lexer.extend<Lexer>()的行上:

类型‘lexer’不满足约束‘Constructor’. 类型‘lexer’不提供签名‘new(...args:any[]):lexer’的匹配项.(2344)

显然,我遗漏了一些与构造函数参数相关的内容.这要怎么写才能正确呢?

更多信息:从extend返回的类用于从我的应用程序派生类,并在应用程序中使用,如:

export default class WhiteboxLexer extends WhiteboxLexerTrampoline {
    // actual implementation of the lexer.
}

推荐答案

通常情况下,简单的提问例子并不能完全代表手头的真实问题.在本例中,Lexer类是一个环境声明,用于emind生成的WASM模块.

要使用这样的类,它必须从模块(这是一个接口)中导出,并且只有在加载模块后才能使用.在此之后,可以导出WASM模块中的类型.

要使用像Lexer这样的类,您需要两个声明:

let antlr4: ANTLR4Wasm;
try {
    antlr4 = await Module();
} catch (e) {
    throw new Error("Could not initialize the ANTLR4 runtime:\n" + e);
}

type Lexer = InstanceType<typeof antlr4.Lexer>;
const Lexer = antlr4.Lexer;

这可用于导出单个标识符:

export { Lexer }:

有了这一点,您可以只使用Lexer作为类型或值.TS会自动照顾好的.通过这种方式,您可以同时执行以下两项操作:

const WhiteboxLexerTrampoline = Lexer.extend<Lexer>("Lexer", {
});

(WhiteboxLexerTrampolineLexer类型,不是typeof Lexer() => Lexer)

const lexer = new Lexer();

为了完整性:为了更好的类型安全性,已经更改了Extendable类:

export declare class Extendable extends Deletable {
    public static extend<T>(name: string, o: { [key in keyof T]?: T[key]; }): Constructor<T>;
}

这又允许从WhiteboxLexerTrampoline派生或创建它的一个实例.

Typescript相关问答推荐

Typescript对每个属性具有约束的通用类型

TypScript在对象上强制执行值类型时推断对象文字类型?

使用带有RxJS主题的服务在Angular中的组件之间传递数据

TypeScript类型不匹配:在返回类型中处理已经声明的Promise Wrapper

如何判断输入是否是TypeScript中的品牌类型?

如何按不能保证的功能过滤按键?

TypeScrip原始字符串没有方法

如何重构长联合类型?

TypeScrip错误:为循环中的对象属性赋值

为什么上下文类型在`fn|curred(Fn)`的联合中不起作用?

创建一个TypeScrip对象并基于来自输入对象的约束定义其类型

使用Type脚本更新对象属性

VITEST警告:当前的测试运行器不支持After Each/teardown挂钩

如何在TypeScrip中使用数组作为字符串的封闭列表?

两个子组件共享控制权

我应该使用服务方法(依赖于可观察的)在组件中进行计算吗?

React-Router V6 中的递归好友路由

如何判断路由或其嵌套路由是否处于活动状态?

node_modules/@newrelic/native-metrics:命令失败. node_modules/couchbase:命令失败.退出代码:127

NgRx 效果在 10 次错误后消失