web-dev-qa-db-fra.com

Ajouter un fichier de saisie personnalisé dans un projet JavaScript VSCode

Problème

Je travaille sur un projet JavaScript utilisant VSCode. J'utilise le modèle de conception UMD et vscode intellisense ne peut pas reconnaître les exportations d'un module à partir d'un autre fichier. J'ai ajouté toutes les déclarations dans un fichier appelé globals.d.ts. Malheureusement, je n'ai pas trouvé de moyen de charger le globals.d.ts déclarations de mes fichiers JavaScript.

Exemple de déclaration de module

export namespace ModuleName {
    export interface Item {
        toString(): string;
        property: string;
        name: string;
    }
}

Exemple de fichier 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;
}));

Ce que j'ai essayé

J'ai essayé d'utiliser typings install "globals.d.ts" qui a créé le dossier typings, typings.json etc. Cela ne fonctionnait qu'après avoir ouvert le fichier de saisie dans VSCode, puis fermé et rouvert l'application. Cela n'a fonctionné que lorsque j'ai gardé le fichier typings ouvert. Ce n'est pas un moyen très pratique pour ajouter mes déclarations d'interface.

À propos de VSCode (il y a 8 mois)

Version: 1.17.0
Shell: 1.7.7
Node: 7.9.0
Architecture: x64

À propos de VSCode (maintenant)

Version: 1.24.1
Shell: 1.7.12
Node: 7.9.0
Architecture: x64

Il n'y a aucun changement de comportement.

26
nick zoum

Reconnaissance

Cette réponse a été principalement copiée/inspirée par réponse de Vitalii , mais comme elle a dû être modifiée un peu, pour travailler avec mon projet, j'ajoute également cette réponse.

Solution

Au-dessus de chaque fichier où j'utilise du code externe, j'ai ajouté:

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

Undefined est le moyen le plus court et le plus simple (auquel j'ai pensé) d'avoir une fausse valeur constante sans déclencher eslint ou jshint. Cela garantit que le code ne sera jamais exécuté, tout en "nécessitant" le jsdoc.

J'ai utilisé var au lieu de let ou const car il ne restera pas dans la portée if, mais plutôt dans la portée du fichier global.

Cela déclarera en fait les variables à l'intérieur du {} (comme undefined), mais typeof undeclared et typeof undefined sont les deux "undefined", il n'y a donc pas de différence dans le code.

En ayant toutes les déclarations dans un fichier, je peux obtenir tous les espaces de noms en déstructurant une instruction require sur une seule ligne. Mais gardez à l'esprit que pour que cela fonctionne, vous devez utiliser export et non declare dans votre fichier de saisie.

Problèmes avec la solution

Je ne peux pas afficher les interfaces dans globals.d.ts à partir de fichiers JavaScript.

export namespace Namespace {
    export interface Interface {
        property: string;
    }
}

J'ai temporairement résolu ce problème en renommant l'espace de noms avec les interfaces en Interfaces (également corrigé toutes les références dans globals.d.ts) et créé un autre espace de noms avec des constantes qui implémentent les interfaces, comme ceci:

export namespace Interfaces {
    export interface Interface {
        property: string;
    }
}

export namespace Namespace {
    export const Interface: Interfaces.Interface;
}

J'ai également eu du mal à utiliser les espaces de noms de globals.d.ts dans les commentaires JavaScript. Pour résoudre ce problème, j'ai ajouté typeof en face du type, comme ceci: /** @param {typeof Namespace.Interface} */

Mettre à jour

J'ai maintenant trouvé un moyen d'exporter des interfaces à partir de .d.ts fichiers vers .js fichiers, vous pouvez trouver la réponse ici .

4
nick zoum

Solution Node.JS simple

Créez les fichiers suivants (les noms doivent être les mêmes):

lib.js 
lib.d.ts

Dans lib.js, écrivez du code, disons celui-ci:

function whenDo(params) {
    return params;
}

module.exports = whenDo;

Dans lib.d.ts, écrivez ceci:

declare function wd(params: wd.Params): wd.Params;

declare namespace wd {
    interface Params {
        name: string;
    }
}

export = wd;

Ensuite, créez un fichier quelque part pour consommer la fonction nouvellement créée et mettez ce code:

const wd = require('./lib/lib');

const opt = wd({name:'drag13'});
console.log(opt.name);

Et la magie est là, tout a bien fonctionné. enter image description here

Le code a été volé ici https://github.com/Drag13/WhenDo/blob/master/src/index.d.ts

9
Drag13

Solution de syntaxe d'importation ES6 pour ceux qui utilisent babel

Créez les fichiers suivants (les noms doivent être les mêmes):

lib.js 
lib.d.ts

Dans lib.js, écrivez du code, disons celui-ci:

export const testMethod = (name, params) => params && params.age ? `hello ${name} with age: ${params.age}` : `hello ${name}`;
export const myConst = {
     name: 'test',
     age: 5
 };

Dans lib.d.ts, écrivez ceci:

declare namespace MyModule {
    interface IParams { age: number; }

    function testMethod(name: string, params: IParams): string;

    const myConst: {
        name: string,
        age: number
    }
}
export = MyModule;

Ensuite, créez un fichier quelque part pour consommer la fonction nouvellement créée et mettez ce code:

import { testMethod } from "./lib/lib";

const name = 'drag13';
const r = testMethod(name, { age: 5 });
console.log(r);

Maintenant, intellisense devrait bien fonctionner pour les paramètres et le résultat.

enter image description here

Mais . Cette approche nécessite que vous utilisiez babel to friend node.js et les importations. Si vous essayez de changer le code du style d'importation pour exiger un style, vous verrez toujours les types et les arguments, mais l'intélisence échouera.

Contrôle babel simple:

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

Ma version VsCode est 1.24.1

4
Drag13