You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Monaco Editor与TypeScript:如何添加全局类型?

如何让Monaco Editor识别全局类型?

我需要让Monaco Editor识别一组全局类型,目前已能通过import type { Foo } from "my-lib";正常使用类型,但希望无需显式导入就能直接使用Foo这类类型。当前尝试的代码如下,但直接使用Foo会报错:

// setup compiler options
monaco.languages.typescript.typescriptDefaults.setCompilerOptions({
    target: monaco.languages.typescript.ScriptTarget.ES2016,
    allowNonTsExtensions: true,
    moduleResolution: monaco.languages.typescript.ModuleResolutionKind.NodeJs,
    module: monaco.languages.typescript.ModuleKind.CommonJS,
    noEmit: true,
    typeRoots: ["node_modules/@types"],
    types: ["my-lib"] // <=== NOTE THIS
});

// define my-lib
monaco.languages.typescript.typescriptDefaults.addExtraLib(
    "export interface Foo { foo: number; }",
    "file:///node_modules/@types/my-lib/index.d.ts"
);

// create model
const model = monaco.editor.createModel(
    "const o: Foo = { foo: 23 };", // <=== this code will have an error in the Monaco editor
    "typescript",
    monaco.Uri.parse(`file:///main.ts`)
);

// create the editor
const editor = monaco.editor.create(document.getElementById("container"), { model });

解决方案

要让类型全局可用,核心是把类型声明放在全局作用域中,而非作为模块导出。具体调整如下:

1. 修改全局类型声明

移除类型代码中的export关键字,改用declare直接声明全局类型;如果需要保留文件的模块结构,可使用declare global包裹类型。

2. 可选调整编译器配置

compilerOptions中的types配置可以保留,但并非必须——全局类型无需通过types列表引入也能被识别。

修正后的完整代码

// setup compiler options
monaco.languages.typescript.typescriptDefaults.setCompilerOptions({
    target: monaco.languages.typescript.ScriptTarget.ES2016,
    allowNonTsExtensions: true,
    moduleResolution: monaco.languages.typescript.ModuleResolutionKind.NodeJs,
    module: monaco.languages.typescript.ModuleKind.CommonJS,
    noEmit: true,
    typeRoots: ["node_modules/@types"]
});

// 定义全局类型的my-lib
monaco.languages.typescript.typescriptDefaults.addExtraLib(
    "declare interface Foo { foo: number; }", // 直接声明全局接口
    "file:///node_modules/@types/my-lib/index.d.ts"
);

// create model
const model = monaco.editor.createModel(
    "const o: Foo = { foo: 23 };", // 现在可正常识别Foo类型
    "typescript",
    monaco.Uri.parse(`file:///main.ts`)
);

// create the editor
const editor = monaco.editor.create(document.getElementById("container"), { model });

模块场景下的全局声明写法

如果你的类型文件本身需要作为模块(比如包含其他导出内容),可以用declare global注入全局类型:

declare global {
  interface Foo { foo: number; }
}
export {}; // 确保文件被TypeScript识别为模块

原因说明

原代码中Foo是通过export导出的模块类型,即使在types中配置了my-lib,TypeScript也只会将其视为可导入的模块成员,不会自动提升到全局作用域。只有当类型直接声明在全局作用域(或通过declare global注入),才能在无需导入的情况下直接使用。

内容的提问来源于stack exchange,提问作者Michael Gunter

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 17:30:34