Подтвердить что ты не робот

Добавить пользовательский файл типизации в проект JavaScript VSCode

проблема

Я работаю над проектом JavaScript, используя VSCode. Я использую шаблон проектирования UMD и vscode intellisense не может распознать экспорт модуля из другого файла. Я добавил все объявления в файл с именем globals.d.ts. К сожалению, я не смог найти способ загрузить объявления globals.d.ts из моих файлов JavaScript.

Пример объявления модуля

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

Там нет никаких изменений в поведении.

4b9b3361

Ответ 1

Подтверждение

Этот ответ был в основном скопирован/вдохновлен ответом Виталия, но так как его пришлось немного изменить, чтобы работать с моим проектом, я также добавляю этот ответ.

Решение

Вверху каждого файла, в котором я использую внешний код, я добавил:

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

Undefined - это самый короткий и простой способ (о котором я думал) иметь постоянное ложное значение без запуска eslint или jshint. Это гарантирует, что код никогда не будет запущен.

Я использовал var вместо let или const так как он останется не в области if, а в глобальной области файлов.

Это фактически объявит переменные внутри {} (как undefined), но typeof undeclared и typeof undefined оба являются "undefined", поэтому в коде нет различий.

Имея все объявления в одном файле, я могу получить все пространства имен, уничтожив один оператор require в одной строке. Но имейте в виду, что в ordet, чтобы это работало, вы должны использовать export а не declare в файле для набора текста.

Проблемы с решением

Я не могу просматривать интерфейсы в globals.d.ts из файлов JavaScript.

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;
}

У меня также были проблемы с использованием пространств имен из globals.d.ts в комментариях JavaScript. Чтобы решить эту проблему, я добавил typeof infront типа, например: /** @param {typeof Namespace.Interface} */

Ответ 2

Простое решение 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);

И магия здесь, все работало просто отлично. enter image description here

Код был украден здесь https://github.com/Drag13/WhenDo/blob/master/src/index.d.ts

Ответ 3

ES6 импортирует синтаксическое решение для тех, кто использует babel

Создайте следующие файлы (имена должны быть одинаковыми):

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);

Теперь intellisense должен отлично работать для параметров и результата.

enter image description here

Но. Этот подход требует, чтобы вы использовали babel to friend node.js и import. Если вы попытаетесь изменить код со стиля импорта на требуемый стиль, вы все равно увидите типы и аргументы, но интеллект потерпит неудачу.

Простая проверка вавилона:

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

Моя версия VsCode - 1.24.1