ImF*_*nky 2 intellisense type-inference typescript visual-studio-code monaco-editor
我刚刚创建了一个复杂的函数,它有 3 个参数:名称、类型和方法。该函数将方法存储在存储中。它从第二个参数推断出第三个参数的返回类型。
addMethod.d.ts
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];
};
}
Run Code Online (Sandbox Code Playgroud)
感谢 Typescript 引擎,最后一个参数(方法)的返回类型是从第二个参数(类型)中的项推断出来的,并且 int 强制函数的用户编写具有特定返回类型的方法
添加方法.ts
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
);
Run Code Online (Sandbox Code Playgroud)
当我在 Visual-Studio Code 或 Codesandbox 上使用 addMethod 函数时,第三个参数的返回类型是众所周知的,但在 monaco-editor 上却不是:
=================================================== =======================
编辑 我发现是使用 noLib 编译器选项才导致这种情况发生。
reactMonaco.languages.typescript.typescriptDefaults.setCompilerOptions({
target: reactMonaco.languages.typescript.ScriptTarget.ES5,
noLib: true,
allowNonTsExtensions: true,
checkJs: true,
});
Run Code Online (Sandbox Code Playgroud)
有没有办法避免 es5 库自动完成,同时保持推理正常工作?
在 Monaco Editor 实现适当的解决方案之前,只需使用即可,根本monaco.languages.typescript.typescriptDefaults.addExtraLib(YOUR_CUSTOM_LIBRARY,"defaultLib:lib.es6.d.ts")
不用费心。您可以通过组合https://github.com/microsoft/TypeScript/tree/master/libsetCompilerOptions
中所需的部分来创建自己的自定义库。
我也在使用摩纳哥编辑器并遇到了同样的问题。在浏览了一下摩纳哥源代码后,我想我找到了一个不需要修改摩纳哥编辑器源代码的解决方案(解决方法?)。
首先,让我们看一下当前的行为。Monaco Editor 使用所谓的LanguageServiceHost来实现 TypeScript 相关功能,另请参阅使用语言服务 API :
它[语言宿主]抽象了语言服务与外部世界之间的所有交互。语言服务主机将管理、监视和维护输入文件推迟到主机。
Monaco 编辑器的 TypeScript 语言主机是microsoft/monaco-typescript存储库的一部分,可以在tsWorker.ts中找到。
现在,如果我们看一下源代码,我们发现Monaco Editor目前只支持两个库文件:
lib.d.ts
当编译器选项 目标设置为ES5时使用,否则lib.es6.d.ts
使用。更多调试表明,无论我们为lib选项设置什么,这两个文件之一都会用作库。正如您提到的,我们可以使用noLib选项,但这会导致其他副作用,例如类型推断不再正常工作。
所以现在我的想法是,大多数时候,你不需要没有图书馆,而是需要一个不同的图书馆。DOM 特定部分(我认为您不想要)位于 lib.dom.d.ts中,它包含在lib.d.ts中。通常,最好至少添加lib.es5.d.ts,其中包含 JavaScript 基础知识的类型,例如Object
,Function
或Number
; 或者也许是 lib.es2015.d.ts,其中包含Symbol
新的数组方法等等。所以问题就变成了:我们如何让 Monaco Editor 使用自定义的(可能是空的)库?
在 中monaco-typescript
,库源代码硬编码在文件lib.ts中。因此,如果我们使用诸如 webpack 之类的捆绑器,我们可以将该文件替换为我们自己的导出常量的版本lib_dts
或lib_es6_dts
我们想要使用的库。此选项可能并不总是可行,并且修改库的源代码无论如何都不是一个好主意。
但是,如果我们再看一下tsWorker.ts
它如何检索给定文件名的内容,就会出现另一种解决方案(解决方法?):如果我们添加具有特定名称的额外库,则将使用该额外库而不是内置库在图书馆。
lib.d.ts
,使用文件名defaultLib:lib.d.ts
lib.es6.d.ts
,使用文件名defaultLib:lib.es6.d.ts
总而言之,这里是一个可以在Monaco Editor Playground上运行的代码示例。请注意,这将目标设置为ES5
(如您的示例中所示),但我们也可以根本不修改编译器选项,而仅lib.es6.d.ts
在添加额外的库时使用。
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();
Run Code Online (Sandbox Code Playgroud)
另外,这里是代码沙盒示例的修改版本。
归档时间: |
|
查看次数: |
919 次 |
最近记录: |