Reputation: 1357
Edit: I rewrote the post to better explain the steps I've taken and the issues I'm facing
I started out with a simple html/js page.
I'm also using xregexp
from a 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>
Next, I want to convert the js file to typescript. So I:
.js
to .ts
declare var XRegExp:any;
to the top of the ts
file (described here)tsc --init
to create tsconfig filetsc
So far, Typescript compiles fine, and page is still working.
Next, I want to replace the declare var XRegExp:any
with an interface, one from a community-maintained declaration file.
I install the typings for xregexp
via typings install dt~xregexp -SG
(d.ts file link)
But I'm unable to access the interfaces declared in the .d.ts
file, because the declaration uses declare module 'xregexp'
and export =
.
According to Typescript's documentation on Modules, export =
is used with import = require()
. But that involves module loading, which is not what I want.
I've tried Pelle's suggestion, but still have no idea how to declare an ambient variable using it.
declare var XRegExp:xregexp.OuterXRegExp; // <-- TS error: Module 'xregexp' has no exported member 'OuterXRegExp'
I would like to know:
d.ts
declaration uses declare module "xregexp"
. Can I refer to any of its inner interfaces/types without an import
?d.ts
to declare the ambient variable? (like what dt~react-global
does) How do I do this, without modifying the downloaded d.ts
?
typings
in case of future changes. At this point, I'm not doing Node development, nor do I want to set up a module loader and/or browserify/webpack.
I simply want to convert an already-working js file to ts, and would like to make Typescript aware of an ambient variable XRegExp
, which has an interface as specified in the downloaded d.ts
. Is it possible for me to achieve this without too much ceremony?
[Edit]
So, I rewrote the declaration file, using jquery.d.ts
as a guide.
This appears to work when loading via script or import, but doesn't answer my original question.
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;
Upvotes: 0
Views: 741
Reputation: 5646
if you have a tsconfig.json
you'll need to add the d.ts
file like this:
{
"files": [
"path/to/definition/xregexp.d.ts",
]
}
Upvotes: 0
Reputation: 2589
This is not really a typescript problem: if you want to use npm packages, it is strongly recommended to use a dependency manager like browserify or webpack to them. (I would recommend browserify, if you're only looking for something to handle your modules).
If you really don't want to use the amazing power of npm, there is also a hacky way of solving this specific problem: changing the declaration file to declare a namespace instead of a module. Now you can effectively use the types anywhere in your project.
Just make these two changes to your declaration file, and you should be good to go:
declare a namespace instead of a module:
declare module 'xregexp' {
//becomes
declare namespace xregexp {
get rid of the export on the bottom of the page:
// remove this:
export = OuterXRegExp;
Now you can call anywhere in your project. Eg:
var outerxregexp: xregexp.OuterXRegExp.TokenOpts = { trigger: () => true }
But again, it is strongly recommended to pull in browserify or so 🙂
Upvotes: 2
Reputation: 22382
Try adding the following line on top of the file where you are using XRegExp:
/// <reference path="./path/to/downloaded/xregexp.d.ts" />
More on the matter triple slash directives
Upvotes: 0