在 JavaScript VSCode 项目中添加自定义类型文件
Add custom typings file in a JavaScript VSCode project
问题
我正在使用 VSCode 进行 JavaScript 项目。我正在使用 UMD
设计模式并且 vscode 智能感知无法识别从另一个文件导出的模块。我在名为 globals.d.ts
的文件中添加了所有声明。不幸的是,我找不到从我的 JavaScript 文件中加载 globals.d.ts
声明的方法。
示例模块声明
export namespace ModuleName {
export interface Item {
toString(): string;
property: string;
name: string;
}
}
示例JavaScript文件
(function (global, factory) {
"use strict";
if (typeof ModuleName === "undefined" && typeof require === "function") global.ModuleName = require("./mymodule.js");
if (typeof exports !== "undefined" && typeof module !== "undefined") factory(exports);
else factory(global.OtherModule = global.OtherModule || {});
})(this, (function (exports) {
"use strict";
function myMethod() {
}
exports.myMethod = myMethod;
return exports;
}));
我试过的
我尝试使用 typings install "globals.d.ts"
创建了 typings
文件夹,typings.json
等。只有在 VSCode 中打开 typings 文件然后关闭并重新打开应用程序。这仅在我保持 typings
文件打开时有效。这不是添加我的接口声明的非常方便的方法。
大约 VSCode(8 个月前)
Version: 1.17.0
Shell: 1.7.7
Node: 7.9.0
Architecture: x64
大约VSCode(现在)
Version: 1.24.1
Shell: 1.7.12
Node: 7.9.0
Architecture: x64
行为没有变化。
正在使用babel的ES6导入语法解决方案
创建下一个文件(名称应该相同):
lib.js
lib.d.ts
在lib.js里面写一些代码,比如说这个:
export const testMethod = (name, params) => params && params.age ? `hello ${name} with age: ${params.age}` : `hello ${name}`;
export const myConst = {
name: 'test',
age: 5
};
里面lib.d.ts这样写:
declare namespace MyModule {
interface IParams { age: number; }
function testMethod(name: string, params: IParams): string;
const myConst: {
name: string,
age: number
}
}
export = MyModule;
然后,创建某个文件来使用新创建的函数并放入此代码:
import { testMethod } from "./lib/lib";
const name = 'drag13';
const r = testMethod(name, { age: 5 });
console.log(r);
现在,智能感知应该可以很好地处理参数和结果。
但是。这种方法要求您使用 babel to friend node.js 和导入。如果您尝试将代码从 import 样式更改为 require 样式,您仍然会看到类型和参数,但 intelisence 将失败。
简单的 babel 检查:
npm i babel-preset-env babel-cli
./node_modules/.bin/babel-node index.js --presets env
我的VsCode版本是1.24.1
普通Node.JS解决方案
创建下一个文件(名称应该相同):
lib.js
lib.d.ts
在lib.js里面写一些代码,比如说这个:
function whenDo(params) {
return params;
}
module.exports = whenDo;
里面lib.d.ts这样写:
declare function wd(params: wd.Params): wd.Params;
declare namespace wd {
interface Params {
name: string;
}
}
export = wd;
然后,在某个地方创建文件来使用新创建的函数并放入此代码:
const wd = require('./lib/lib');
const opt = wd({name:'drag13'});
console.log(opt.name);
魔法就在这里,一切正常。
代码从这里被盗:https://github.com/Drag13/WhenDo/blob/master/dts/index.d.ts
描述的方法here
致谢
这个答案主要是 copied/inspired,但由于必须对其进行一些修改,以便与我的项目一起使用,我也添加了这个答案。
解决方案
在我使用外部代码的每个文件顶部,我添加了:
if (undefined) var { -List of Namespaces used- } = require("./globals");
Undefined 是在不触发 eslint
或 jshint
的情况下拥有恒定假值的最短且最简单的方法(我想到的)。这确保代码永远不会是 运行,同时仍然是 "requiring" jsdoc。
我使用 var
而不是 let
或 const
因为它不会留在 if 范围内,而是在全局文件范围内。
这实际上会在{}
中声明变量(如undefined
),但是typeof undeclared
和typeof undefined
都是"undefined"
,因此有代码没有区别。
通过将所有声明放在一个文件中,我可以通过在一行中解构一个 require 语句来获取所有名称空间。
但请记住,为了使其正常工作,您需要在打字文件中使用 export
而不是 declare
。
解决方案有问题
我无法从 JavaScript 个文件中查看 globals.d.ts
中的接口。
export namespace Namespace {
export interface Interface {
property: string;
}
}
我通过将带有接口的命名空间重命名为 Interfaces
(还修复了 globals.d.ts
中的所有引用)暂时解决了这个问题,并创建了另一个带有实现接口的常量的命名空间,如下所示:
export namespace Interfaces {
export interface Interface {
property: string;
}
}
export namespace Namespace {
export const Interface: Interfaces.Interface;
}
我在 JavaScript 评论中使用来自 globals.d.ts
的命名空间时也遇到了问题。为了解决这个问题,我在类型前面添加了 typeof
,如下所示: /** @param {typeof Namespace.Interface} */
更新
我现在找到了将接口从 .d.ts
文件导出到 .js
文件的方法,你可以找到答案 .
问题
我正在使用 VSCode 进行 JavaScript 项目。我正在使用 UMD
设计模式并且 vscode 智能感知无法识别从另一个文件导出的模块。我在名为 globals.d.ts
的文件中添加了所有声明。不幸的是,我找不到从我的 JavaScript 文件中加载 globals.d.ts
声明的方法。
示例模块声明
export namespace ModuleName {
export interface Item {
toString(): string;
property: string;
name: string;
}
}
示例JavaScript文件
(function (global, factory) {
"use strict";
if (typeof ModuleName === "undefined" && typeof require === "function") global.ModuleName = require("./mymodule.js");
if (typeof exports !== "undefined" && typeof module !== "undefined") factory(exports);
else factory(global.OtherModule = global.OtherModule || {});
})(this, (function (exports) {
"use strict";
function myMethod() {
}
exports.myMethod = myMethod;
return exports;
}));
我试过的
我尝试使用 typings install "globals.d.ts"
创建了 typings
文件夹,typings.json
等。只有在 VSCode 中打开 typings 文件然后关闭并重新打开应用程序。这仅在我保持 typings
文件打开时有效。这不是添加我的接口声明的非常方便的方法。
大约 VSCode(8 个月前)
Version: 1.17.0
Shell: 1.7.7
Node: 7.9.0
Architecture: x64
大约VSCode(现在)
Version: 1.24.1
Shell: 1.7.12
Node: 7.9.0
Architecture: x64
行为没有变化。
正在使用babel的ES6导入语法解决方案
创建下一个文件(名称应该相同):
lib.js
lib.d.ts
在lib.js里面写一些代码,比如说这个:
export const testMethod = (name, params) => params && params.age ? `hello ${name} with age: ${params.age}` : `hello ${name}`;
export const myConst = {
name: 'test',
age: 5
};
里面lib.d.ts这样写:
declare namespace MyModule {
interface IParams { age: number; }
function testMethod(name: string, params: IParams): string;
const myConst: {
name: string,
age: number
}
}
export = MyModule;
然后,创建某个文件来使用新创建的函数并放入此代码:
import { testMethod } from "./lib/lib";
const name = 'drag13';
const r = testMethod(name, { age: 5 });
console.log(r);
现在,智能感知应该可以很好地处理参数和结果。
但是。这种方法要求您使用 babel to friend node.js 和导入。如果您尝试将代码从 import 样式更改为 require 样式,您仍然会看到类型和参数,但 intelisence 将失败。
简单的 babel 检查:
npm i babel-preset-env babel-cli
./node_modules/.bin/babel-node index.js --presets env
我的VsCode版本是1.24.1
普通Node.JS解决方案
创建下一个文件(名称应该相同):
lib.js
lib.d.ts
在lib.js里面写一些代码,比如说这个:
function whenDo(params) {
return params;
}
module.exports = whenDo;
里面lib.d.ts这样写:
declare function wd(params: wd.Params): wd.Params;
declare namespace wd {
interface Params {
name: string;
}
}
export = wd;
然后,在某个地方创建文件来使用新创建的函数并放入此代码:
const wd = require('./lib/lib');
const opt = wd({name:'drag13'});
console.log(opt.name);
魔法就在这里,一切正常。
代码从这里被盗:https://github.com/Drag13/WhenDo/blob/master/dts/index.d.ts
描述的方法here
致谢
这个答案主要是
解决方案
在我使用外部代码的每个文件顶部,我添加了:
if (undefined) var { -List of Namespaces used- } = require("./globals");
Undefined 是在不触发 eslint
或 jshint
的情况下拥有恒定假值的最短且最简单的方法(我想到的)。这确保代码永远不会是 运行,同时仍然是 "requiring" jsdoc。
我使用 var
而不是 let
或 const
因为它不会留在 if 范围内,而是在全局文件范围内。
这实际上会在{}
中声明变量(如undefined
),但是typeof undeclared
和typeof undefined
都是"undefined"
,因此有代码没有区别。
通过将所有声明放在一个文件中,我可以通过在一行中解构一个 require 语句来获取所有名称空间。
但请记住,为了使其正常工作,您需要在打字文件中使用 export
而不是 declare
。
解决方案有问题
我无法从 JavaScript 个文件中查看 globals.d.ts
中的接口。
export namespace Namespace {
export interface Interface {
property: string;
}
}
我通过将带有接口的命名空间重命名为 Interfaces
(还修复了 globals.d.ts
中的所有引用)暂时解决了这个问题,并创建了另一个带有实现接口的常量的命名空间,如下所示:
export namespace Interfaces {
export interface Interface {
property: string;
}
}
export namespace Namespace {
export const Interface: Interfaces.Interface;
}
我在 JavaScript 评论中使用来自 globals.d.ts
的命名空间时也遇到了问题。为了解决这个问题,我在类型前面添加了 typeof
,如下所示: /** @param {typeof Namespace.Interface} */
更新
我现在找到了将接口从 .d.ts
文件导出到 .js
文件的方法,你可以找到答案