Добавить файл пользовательских типов в проект 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
Там нет никаких изменений в поведении.
3 ответа
Простое решение 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/src/index.d.ts
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 должен отлично работать для параметров и результата.
Но. Этот подход требует, чтобы вы использовали 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
Подтверждение
Этот ответ был в основном скопирован / вдохновлен ответом Виталия, но так как его пришлось немного изменить, чтобы работать с моим проектом, я также добавляю этот ответ.
Решение
Вверху каждого файла, в котором я использую внешний код, я добавил:
if (undefined) var { -List of Namespaces used- } = require("./globals");
Undefined - самый короткий и простой способ (о котором я думал) иметь постоянное ложное значение без запуска eslint
или же jshint
, Это гарантирует, что код никогда не будет запущен.
я использовал var
вместо let
или же const
так как он останется не в области видимости if, а в глобальной области файлов.
Это фактически объявит переменные внутри {}
(как undefined
), но typeof undeclared
а также typeof undefined
оба "undefined"
Таким образом, нет никакой разницы в коде.
Имея все объявления в одном файле, я могу получить все пространства имен, уничтожив один оператор require в одной строке.
Проблемы с решением
Я не могу просмотреть интерфейсы в 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
инфронт типа, вот так: /** @param {typeof Namespace.Interface} */