首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >vscode与摩纳哥编辑器的不同类型文本推理管理

vscode与摩纳哥编辑器的不同类型文本推理管理
EN

Stack Overflow用户
提问于 2019-11-13 09:53:42
回答 1查看 770关注 0票数 2

我刚刚创建了一个复杂的函数,它包含三个参数:名称、类型和方法。此函数将方法存储在存储区中。它从第二个纪念碑推断出第三个纪念碑的返回类型。

addMethod.d.ts

代码语言:javascript
运行
复制
interface SimplifiedTypeMap {
  string: string;
  number: number;
  boolean: boolean;
}

type GlobalMethodAdd = <T extends keyof SimplifiedTypeMap>(
  name: string,
  types: T[],
  method: () => SimplifiedTypeMap[T]
) => void;

interface MethodStore {
  [name: string]: {
    types: (keyof SimplifiedTypeMap)[];
    method: () => SimplifiedTypeMap[keyof SimplifiedTypeMap];
  };
}

由于类型记录引擎,最后一个参数(方法)的返回类型是从第二个参数(类型)中的项推断出来的,int强制函数的用户用特定的返回类型编写方法。

addMethod.ts

代码语言:javascript
运行
复制
import { random } from "lodash-es";

export const methodStorage: MethodStore = {};

const addMethod: GlobalMethodAdd = (name, types, method) => {
  methodStorage[name] = { types, method };
};

addMethod("test", ["string", "number"], () =>
  random(1, true) > 0.5 ? "abcd" : 1234
);

当我在Visual代码或Codesandbox上使用addMethod函数时,第三个参数的返回类型是众所周知的,但在摩纳哥编辑器上不是这样:

visual studio代码

码箱编辑器

(失败)摩纳哥编辑器

下面是我在代码框中的例子

=========================================================================

编辑我发现是noLib编译器选项的使用导致了这种情况的发生。

代码语言:javascript
运行
复制
reactMonaco.languages.typescript.typescriptDefaults.setCompilerOptions({
  target: reactMonaco.languages.typescript.ScriptTarget.ES5,
  noLib: true,
  allowNonTsExtensions: true,
  checkJs: true,
});

是否有办法在保持推理正常工作的同时避免es5库的自动完成?

EN

回答 1

Stack Overflow用户

发布于 2019-11-20 00:14:39

TL;DR

在摩纳哥编辑器实现正确的解决方案之前,只需使用monaco.languages.typescript.typescriptDefaults.addExtraLib(YOUR_CUSTOM_LIBRARY,"defaultLib:lib.es6.d.ts"),根本不用使用setCompilerOptions。您可以通过组合您希望从https://github.com/microsoft/TypeScript/tree/master/lib获得的部分来创建自己的自定义库。

长版

我也使用摩纳哥编辑,也有同样的问题。在浏览了一下摩纳哥的源代码之后,我想我找到了一个解决方案(解决办法?)这不需要修改摩纳哥编辑器的源代码。

首先,让我们来看看当前的行为。摩纳哥编辑器使用所谓的LanguageServiceHost实现与TypeScript相关的功能,另请参阅使用语言服务API

语言主机抽象语言服务和外部世界之间的所有交互。语言服务主机将管理、监视和维护输入文件延迟到主机。

摩纳哥编辑器的TypeScript语言主机是microsoft/摩纳哥-打字本存储库的一部分,可以在tsWorker.ts中找到。

现在,如果我们看一下源代码,我们发现摩纳哥编辑器中只有两个库文件目前支助

lib.d.ts编译器选项 目标设置为ES5时使用,否则使用lib.es6.d.ts。一些更多的调试显示,无论我们为选项设置了什么,这两个文件中的一个都被用作库。正如您提到的,我们可以使用noLib选项,但这会导致其他副作用,例如类型推断不再正确工作。

所以现在我有了一个想法,大多数情况下,你不想要库,而是想要一个不同的库。DOM特定的部分(我认为您不想要)在lib.dom.d.ts中,这是由lib.d.ts包含的。通常,添加至少lib.es5.d.ts是个好主意,它包含JavaScript基础元素的类型,如ObjectFunctionNumber;或者lib.es2015.d.ts,它包含Symbol、新数组方法等等。因此,问题是:我们如何使摩纳哥编辑器使用自定义-可能是空-库?

monaco-typescript中,库源代码是在文件lib.ts中硬编码的.因此,如果我们使用的是像webpack这样的绑定器,我们可以用我们自己的版本替换这个文件,该版本可以导出一个常量的lib_dtslib_es6_dts,并使用我们想要使用的库。这个选项可能并不总是可行的,修改库的源代码也不是一个好主意。

但是,如果我们再看一看tsWorker.ts如何检索给定文件名的内容,另一种解决方案(解决办法?)显示本身:如果我们使用特定名称的添加一个额外的库,那么将使用额外的lib来代替内置的库。

  • 对于lib.d.ts,使用文件名defaultLib:lib.d.ts
  • 对于lib.es6.d.ts,使用文件名defaultLib:lib.es6.d.ts

总之,下面是一个可以在摩纳哥编辑操场上运行的代码示例。请注意,这将目标设置为ES5 (如您的示例所示),但我们也不能修改编译器选项,只需在添加额外的lib时使用lib.es6.d.ts即可。

代码语言:javascript
运行
复制
const code = `
interface SimplifiedTypeMap {
    string: string;
    number: number;
    boolean: boolean;
}

type GlobalMethodAdd = <T extends keyof SimplifiedTypeMap>(
    name: string,
    types: T[],
    method: () => SimplifiedTypeMap[T]
) => void;

interface MethodStore {
    [name: string]: {
        types: (keyof SimplifiedTypeMap)[];
        method: () => SimplifiedTypeMap[keyof SimplifiedTypeMap];
    };
}

export const methodStorage: MethodStore = {};

const addMethod: GlobalMethodAdd = (name, types, method) => {
    methodStorage[name] = { types, method };
};

// Try hovering over addMethod, type inferrence works correctly
addMethod("test", ["string", "number"], () =>
    1 > 0.5 ? "abcd" : 1234
);

// No DOM library loaded, so this gives an error
new HTMLAnchorElement();    
`;

async function setup() {
    const response = await fetch("https://raw.githubusercontent.com/microsoft/TypeScript/master/lib/lib.es5.d.ts");
    const libes5 = await response.text();

    monaco.languages.typescript.typescriptDefaults.setCompilerOptions({
        allowNonTsExtensions: true,
        target: monaco.languages.typescript.ScriptTarget.ES5,
    });

    // Use "lib.custom.d.ts" for ES5, and "defaultLib:lib.es6.d.ts" for ESNext (the default)
    monaco.languages.typescript.typescriptDefaults.addExtraLib(
        libes5,
        "defaultLib:lib.d.ts"
    );

    monaco.editor.create(document.getElementById("container"), {
        value: code,
        language: "typescript"
    });
}

setup();

另外,这是一个代码沙箱示例的修改版本

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58834378

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档