Проблемы с вводом текста для работы в Typescript

Изменить: я переписал сообщение, чтобы лучше объяснить шаги, которые я предпринял, и проблемы, с которыми я столкнулся.

Я начал с простой страницы html/js. Я также использую xregexp с CDN.

var reg = XRegExp("^lights:(?<option>on|off)$", "xgi");
var match = XRegExp.exec("lights:on", reg);
document.body.innerText = "Lights are: " + match["option"];
<!DOCTYPE html>
<html lang="en">
   <head></head>
   <body></body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/xregexp/3.1.1/xregexp-all.js"></script>
<script src="app.js"></script>

</html>

Далее я хочу преобразовать файл js в машинописный текст. Так что я:

  • переименовать .js в .ts
  • добавлено declare var XRegExp:any; в начало файла ts (описано здесь)
  • запустил tsc --init для создания файла tsconfig
  • побежал tsc

Пока что Typescript компилируется нормально, и страница все еще работает.

Затем я хочу заменить declare var XRegExp:any интерфейсом из поддерживаемого сообществом файла объявлений.

Я устанавливаю типизацию для xregexp через typings install dt~xregexp -SG (ссылка на файл d.ts< /а>)

Но я не могу получить доступ к интерфейсам, объявленным в файле .d.ts, потому что в объявлении используются declare module 'xregexp' и export =.

Согласно документации Typescript по Модулям, export = используется с import = require(). Но это связано с загрузкой модуля, а это не то, чего я хочу.

Я попробовал предложение Пелле, но до сих пор не знаю, как с его помощью объявить переменную окружения.

declare var XRegExp:xregexp.OuterXRegExp; // <-- TS error: Module 'xregexp' has no exported member 'OuterXRegExp'

Я бы хотел знать:

  1. Объявление d.ts использует declare module "xregexp". Могу ли я ссылаться на любой из его внутренних интерфейсов/типов без import?
  2. is it possible for me to create an additional d.ts to declare the ambient variable? (like what dt~react-global does) How do I do this, without modifying the downloaded d.ts ?
    • reason: I would rather not change the declaration file pulled via typings in case of future changes.

На данный момент я не занимаюсь разработкой Node и не хочу настраивать загрузчик модулей и/или браузеры/webpack.

Я просто хочу преобразовать уже работающий файл js в ts и хотел бы, чтобы Typescript знал об окружающей переменной XRegExp, интерфейс которой указан в загруженном файле d.ts. Могу ли я добиться этого без лишних церемоний?

[Редактировать]

Итак, я переписал файл объявления, используя jquery.d.ts в качестве ориентира.

Кажется, это работает при загрузке через скрипт или импорт, но не отвечает на мой первоначальный вопрос.

interface TokenOpts {
  scope ? : string;
  trigger ? : () => boolean;
  customFlags ? : string;
}

interface XRegExp {
  (pattern: string, flags ? : string): RegExp;
  (pattern: RegExp): RegExp;

  addToken(regex: RegExp, handler: (matchArr: RegExpExecArray, scope: string) => string, options ? : TokenOpts): void;

  build(pattern: string, subs: string[], flags ? : string): RegExp;
  cache(pattern: string, flags ? : string): RegExp;
  escape(str: string): string;
  exec(str: string, regex: RegExp, pos ? : number, sticky ? : boolean): RegExpExecArray;
  forEach(str: string, regex: RegExp, callback: (matchArr: RegExpExecArray, index: number, input: string, regexp: RegExp) => void): any;
  globalize(regex: RegExp): RegExp;

  install(options: string): void;
  install(options: Object): void;

  isInstalled(feature: string): boolean;
  isRegExp(value: any): boolean;
  match(str: string, regex: RegExp, scope: string): any;
  match(str: string, regex: RegExp, scope: "one"): string;
  match(str: string, regex: RegExp, scope: "all"): string[];
  match(str: string, regex: RegExp): string[];
  matchChain(str: string, chain: RegExp[]): string[];
  matchChain(str: string, chain: {
    regex: RegExp;
    backref: string
  }[]): string[];
  matchChain(str: string, chain: {
    regex: RegExp;
    backref: number
  }[]): string[];
  matchRecursive(str: string, left: string, right: string, flags ? : string, options ? : Object): string[];

  replace(str: string, search: string, replacement: string, scope ? : string): string;
  replace(str: string, search: string, replacement: Function, scope ? : string): string;
  replace(str: string, search: RegExp, replacement: string, scope ? : string): string;
  replace(str: string, search: RegExp, replacement: Function, scope ? : string): string;
  replaceEach(str: string, replacements: Array < RegExp | string > []): string;

  split(str: string, separator: string, limit ? : number): string[];
  split(str: string, separator: RegExp, limit ? : number): string[];

  test(str: string, regex: RegExp, pos ? : number, sticky ? : boolean): boolean;

  uninstall(options: Object): void;
  uninstall(options: string): void;

  union(patterns: string[], flags ? : string): RegExp;
  version: string;
}

declare module "xregexp" {
  export = XRegExp;
}

declare var XRegExp: XRegExp;


person jayars    schedule 19.08.2016    source источник
comment
Файл объявления, который вы упоминаете, объявляет явный модуль. В результате, если вы не хотите использовать какие-либо модули и только глобальные зависимости (что нормально), вы не сможете использовать этот файл объявления, не сделав пару изменений, чтобы сделать его файлом глобального объявления.   -  person Pelle Jacobs    schedule 20.08.2016
comment
@PelleJacobs Это имеет смысл. Понятно. Спасибо   -  person jayars    schedule 20.08.2016


Ответы (3)


На самом деле это не проблема машинописного текста: если вы хотите использовать пакеты npm, настоятельно рекомендуется использовать для них менеджер зависимостей, такой как browserify или webpack. (Я бы порекомендовал использовать браузер, если вы ищете только что-то для обработки ваших модулей).

Если вы действительно не хотите использовать потрясающую мощь npm, есть также хакерский способ решения этой конкретной проблемы: изменение файла объявления для объявления пространства имен вместо модуля. Теперь вы можете эффективно использовать типы в любом месте вашего проекта.

Просто внесите эти два изменения в файл объявлений, и все будет готово:

  • объявить пространство имен вместо модуля:

    declare module 'xregexp' {
    //becomes
    declare namespace xregexp {
    
  • избавиться от экспорта внизу страницы:

    // remove this: 
    export = OuterXRegExp;
    

Теперь вы можете звонить в любое место вашего проекта. Например:

var outerxregexp: xregexp.OuterXRegExp.TokenOpts = { trigger: () => true }

Но опять же, настоятельно рекомендуется использовать браузер или около того ????

person Pelle Jacobs    schedule 19.08.2016

Попробуйте добавить следующую строку поверх файла, в котором вы используете XRegExp:

/// <reference path="./path/to/downloaded/xregexp.d.ts" />

Подробнее об директивах с тройной косой чертой

person Amid    schedule 19.08.2016
comment
Спасибо за ответ. Я пробовал директиву, но все равно не повезло. Обновил пост с более подробной информацией - person jayars; 19.08.2016

если у вас есть tsconfig.json, вам нужно добавить файл d.ts следующим образом:

{
    "files": [
        "path/to/definition/xregexp.d.ts",
    ]
}
person Santiago Hernández    schedule 19.08.2016