簡體   English   中英

在 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文件打開時有效。 這不是添加我的接口聲明的非常方便的方法。

關於 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

行為沒有變化。

普通 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

這里描述的方法

使用 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 來與 node.js 和導入做朋友。 如果您嘗試將代碼從 import 樣式更改為 require 樣式,您仍然會看到類型和參數,但智能將失敗。

簡單的 babel 檢查:

npm i babel-preset-env babel-cli
./node_modules/.bin/babel-node index.js --presets env

我的 VsCode 版本是 1.24.1

致謝

這個答案主要是由Vitalii 的答案復制/啟發,但由於它必須稍作修改,以配合我的項目,我也添加了這個答案。

解決方案

在我使用外部代碼的每個文件的頂部,我添加了:

if (undefined) var { -List of Namespaces used- } = require("./globals");

Undefined 是在不觸發eslintjshint情況下擁有恆定假值的最短和最簡單的方法(我想到的)。 這確保代碼永遠不會運行,同時仍然“需要”jsdoc。

我使用var而不是letconst因為它不會留在 if 范圍內,而是留在全局文件范圍內。

這實際上將聲明{}內的變量(如undefined ),但typeof undeclaredtypeof 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文件的方法,你可以在這里找到答案。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM