Before spending the time to write your own libdef, we recommend that you look to
see if there is already a libdef for the third-party code that you’re addressing.
flow-typed
is a tool and repository
for sharing common libdefs within the Flow community – so it’s a good way to
knock out a good chunk of any public libdefs you might need for your project.
However sometimes there isn’t a pre-existing libdef or you have third-party
code that isn’t public and/or you really just need to write a libdef yourself.
To do this you’ll start by creating a .js
file for each libdef you’re going to
write and put them in the /flow-typed
directory at the root of your project.
In these libdef file(s) you’ll use a special set of Flow syntax (explained
below) to describe the interfaces of the relevant third-party code.
Declaring A Global Function
To declare a global function that should be accessible throughout your project,
use the declare function
syntax in a libdef file:
flow-typed/myLibDef.js
1
|
declare function foo(a: number): string;
|
{"value":"declare function foo(a: number): string;\n","tokens":[{"type":"T_DECLARE","context":"normal","value":"declare","line":1,"start":0,"end":7},{"type":"T_FUNCTION","context":"normal","value":"function","line":1,"start":8,"end":16},{"type":"T_IDENTIFIER","context":"normal","value":"foo","line":1,"start":17,"end":20},{"type":"T_LPAREN","context":"type","value":"(","line":1,"start":20,"end":21},{"type":"T_IDENTIFIER","context":"normal","value":"a","line":1,"start":21,"end":22},{"type":"T_COLON","context":"type","value":":","line":1,"start":22,"end":23},{"type":"T_NUMBER_TYPE","context":"type","value":"number","line":1,"start":24,"end":30},{"type":"T_RPAREN","context":"type","value":")","line":1,"start":30,"end":31},{"type":"T_COLON","context":"normal","value":":","line":1,"start":31,"end":32},{"type":"T_STRING_TYPE","context":"type","value":"string","line":1,"start":33,"end":39},{"type":"T_SEMICOLON","context":"normal","value":";","line":1,"start":39,"end":40}],"errors":[]}
This tells Flow that any code within the project can reference the
foo
global function, and that the function takes one argument (a number
) and
it returns a string
.
Declaring A Global Class
To declare a global class that should be accessible throughout your project,
use the declare class
syntax in a libdef file:
flow-typed/myLibDef.js
1
2
3
4
5
6
|
declare class URL {
constructor(urlStr: string): URL;
toString(): string;
static compare(url1: URL, url2: URL): boolean;
}
|
{"value":"declare class URL {\n constructor(urlStr: string): URL;\n toString(): string;\n\n static compare(url1: URL, url2: URL): boolean;\n}\n","tokens":[{"type":"T_DECLARE","context":"normal","value":"declare","line":1,"start":0,"end":7},{"type":"T_CLASS","context":"normal","value":"class","line":1,"start":8,"end":13},{"type":"T_IDENTIFIER","context":"normal","value":"URL","line":1,"start":14,"end":17},{"type":"T_LCURLY","context":"type","value":"{","line":1,"start":18,"end":19},{"type":"T_IDENTIFIER","context":"normal","value":"constructor","line":2,"start":22,"end":33},{"type":"T_LPAREN","context":"type","value":"(","line":2,"start":33,"end":34},{"type":"T_IDENTIFIER","context":"normal","value":"urlStr","line":2,"start":34,"end":40},{"type":"T_COLON","context":"type","value":":","line":2,"start":40,"end":41},{"type":"T_STRING_TYPE","context":"type","value":"string","line":2,"start":42,"end":48},{"type":"T_RPAREN","context":"type","value":")","line":2,"start":48,"end":49},{"type":"T_COLON","context":"type","value":":","line":2,"start":49,"end":50},{"type":"T_IDENTIFIER","context":"type","value":"URL","line":2,"start":51,"end":54},{"type":"T_SEMICOLON","context":"type","value":";","line":2,"start":54,"end":55},{"type":"T_IDENTIFIER","context":"normal","value":"toString","line":3,"start":58,"end":66},{"type":"T_LPAREN","context":"type","value":"(","line":3,"start":66,"end":67},{"type":"T_RPAREN","context":"type","value":")","line":3,"start":67,"end":68},{"type":"T_COLON","context":"type","value":":","line":3,"start":68,"end":69},{"type":"T_STRING_TYPE","context":"type","value":"string","line":3,"start":70,"end":76},{"type":"T_SEMICOLON","context":"type","value":";","line":3,"start":76,"end":77},{"type":"T_STATIC","context":"type","value":"static","line":5,"start":81,"end":87},{"type":"T_IDENTIFIER","context":"normal","value":"compare","line":5,"start":88,"end":95},{"type":"T_LPAREN","context":"type","value":"(","line":5,"start":95,"end":96},{"type":"T_IDENTIFIER","context":"normal","value":"url1","line":5,"start":96,"end":100},{"type":"T_COLON","context":"type","value":":","line":5,"start":100,"end":101},{"type":"T_IDENTIFIER","context":"type","value":"URL","line":5,"start":102,"end":105},{"type":"T_COMMA","context":"type","value":",","line":5,"start":105,"end":106},{"type":"T_IDENTIFIER","context":"normal","value":"url2","line":5,"start":107,"end":111},{"type":"T_COLON","context":"type","value":":","line":5,"start":111,"end":112},{"type":"T_IDENTIFIER","context":"type","value":"URL","line":5,"start":113,"end":116},{"type":"T_RPAREN","context":"type","value":")","line":5,"start":116,"end":117},{"type":"T_COLON","context":"type","value":":","line":5,"start":117,"end":118},{"type":"T_BOOLEAN_TYPE","context":"type","value":"boolean","line":5,"start":119,"end":126},{"type":"T_SEMICOLON","context":"type","value":";","line":5,"start":126,"end":127},{"type":"T_RCURLY","context":"type","value":"}","line":6,"start":128,"end":129}],"errors":[]}
This tells Flow that any code within the project can reference the URL
global
class. Note that this class definition does not have any implementation details
– it exclusively defines the interface of the class.
Declaring A Global Variable
To declare a global variable that should be accessible throughout your project,
use the declare var
syntax in a libdef file:
flow-typed/myLibDef.js
1
|
declare var PI: number;
|
{"value":"declare var PI: number;\n","tokens":[{"type":"T_DECLARE","context":"normal","value":"declare","line":1,"start":0,"end":7},{"type":"T_VAR","context":"normal","value":"var","line":1,"start":8,"end":11},{"type":"T_IDENTIFIER","context":"normal","value":"PI","line":1,"start":12,"end":14},{"type":"T_COLON","context":"type","value":":","line":1,"start":14,"end":15},{"type":"T_NUMBER_TYPE","context":"type","value":"number","line":1,"start":16,"end":22},{"type":"T_SEMICOLON","context":"normal","value":";","line":1,"start":22,"end":23}],"errors":[]}
This tells Flow that any code within the project can reference the PI
global
variable – which, in this case, is a number
.
Declaring A Global Type
To declare a global type that should be accessible throughout your project,
use the declare type
syntax in a libdef file:
flow-typed/myLibDef.js
1
|
declare type UserID = number;
|
{"value":"declare type UserID = number;\n","tokens":[{"type":"T_DECLARE","context":"normal","value":"declare","line":1,"start":0,"end":7},{"type":"T_TYPE","context":"normal","value":"type","line":1,"start":8,"end":12},{"type":"T_IDENTIFIER","context":"type","value":"UserID","line":1,"start":13,"end":19},{"type":"T_ASSIGN","context":"type","value":"=","line":1,"start":20,"end":21},{"type":"T_NUMBER_TYPE","context":"type","value":"number","line":1,"start":22,"end":28},{"type":"T_SEMICOLON","context":"normal","value":";","line":1,"start":28,"end":29}],"errors":[]}
This tells Flow that any code within the project can reference the UserID
global type – which, in this case, is just an alias for number
.
Declaring A Module
Often, third-party code is organized in terms of modules rather than globals. To
write a libdef that declares the presence of a module you’ll want to use the
declare module
syntax:
1
2
3
|
declare module "some-third-party-library" {
}
|
{"value":"declare module \"some-third-party-library\" {\n // This is where we'll list the module's exported interface(s)\n}\n","tokens":[{"type":"T_DECLARE","context":"normal","value":"declare","line":1,"start":0,"end":7},{"type":"T_IDENTIFIER","context":"normal","value":"module","line":1,"start":8,"end":14},{"type":"T_STRING","context":"normal","value":"\"some-third-party-library\"","line":1,"start":15,"end":41},{"type":"T_LCURLY","context":"normal","value":"{","line":1,"start":42,"end":43},{"type":"Line","context":"comment","value":"// This is where we'll list the module's exported interface(s)","line":2,"start":46,"end":108},{"type":"T_RCURLY","context":"normal","value":"}","line":3,"start":109,"end":110}],"errors":[]}
The name specified in quotes after declare module
can be any string, but it
should correspond to the same string you’d use to require
or import
the
third-party module into your project. For defining modules that are accessed via
a relative require
/import
path, please see the docs on the .flow
files
Within the body of a declare module
block, you can specify the set of exports
for that module. However, before we start talking about exports we have to talk
about the two kinds of modules that Flow supports: CommonJS and ES modules.
Flow can handle both CommonJS and ES modules, but there are some relevant
differences between the two that need to be considered when using
declare module
.
Declaring An ES Module
ES modules have two kinds of
exports: A named export and a default export. Flow supports the ability
to declare either or both of these kinds of exports within a declare module
body as follows:
Named Exports
flow-typed/some-es-module.js
1
2
3
4
|
declare module "some-es-module" {
declare export function concatPath(dirA: string, dirB: string): string;
}
|
{"value":"declare module \"some-es-module\" {\n // Declares a named \"concatPath\" export\n declare export function concatPath(dirA: string, dirB: string): string;\n}\n","tokens":[{"type":"T_DECLARE","context":"normal","value":"declare","line":1,"start":0,"end":7},{"type":"T_IDENTIFIER","context":"normal","value":"module","line":1,"start":8,"end":14},{"type":"T_STRING","context":"normal","value":"\"some-es-module\"","line":1,"start":15,"end":31},{"type":"T_LCURLY","context":"normal","value":"{","line":1,"start":32,"end":33},{"type":"Line","context":"comment","value":"// Declares a named \"concatPath\" export","line":2,"start":36,"end":75},{"type":"T_DECLARE","context":"normal","value":"declare","line":3,"start":78,"end":85},{"type":"T_EXPORT","context":"normal","value":"export","line":3,"start":86,"end":92},{"type":"T_FUNCTION","context":"normal","value":"function","line":3,"start":93,"end":101},{"type":"T_IDENTIFIER","context":"normal","value":"concatPath","line":3,"start":102,"end":112},{"type":"T_LPAREN","context":"type","value":"(","line":3,"start":112,"end":113},{"type":"T_IDENTIFIER","context":"normal","value":"dirA","line":3,"start":113,"end":117},{"type":"T_COLON","context":"type","value":":","line":3,"start":117,"end":118},{"type":"T_STRING_TYPE","context":"type","value":"string","line":3,"start":119,"end":125},{"type":"T_COMMA","context":"type","value":",","line":3,"start":125,"end":126},{"type":"T_IDENTIFIER","context":"normal","value":"dirB","line":3,"start":127,"end":131},{"type":"T_COLON","context":"type","value":":","line":3,"start":131,"end":132},{"type":"T_STRING_TYPE","context":"type","value":"string","line":3,"start":133,"end":139},{"type":"T_RPAREN","context":"type","value":")","line":3,"start":139,"end":140},{"type":"T_COLON","context":"normal","value":":","line":3,"start":140,"end":141},{"type":"T_STRING_TYPE","context":"type","value":"string","line":3,"start":142,"end":148},{"type":"T_SEMICOLON","context":"normal","value":";","line":3,"start":148,"end":149},{"type":"T_RCURLY","context":"normal","value":"}","line":4,"start":150,"end":151}],"errors":[]}
Note that you can also declare other things inside the body of the
declare module
, and those things will be scoped to the body of the
declare module
– but they will not be exported from the module:
flow-typed/some-es-module.js
1
2
3
4
5
6
7
8
9
10
11
12
|
declare module "some-es-module" {
declare class Path {
toString(): string;
}
declare export function concatPath(dirA: string, dirB: string): Path;
}
|
{"value":"declare module \"some-es-module\" {\n // Defines the type of a Path class within this `declare module` body, but\n // does not export it. It can only be referenced by other things inside the\n // body of this `declare module`\n declare class Path {\n toString(): string;\n }\n\n // Declares a named \"concatPath\" export which returns an instance of the\n // `Path` class (defined above)\n declare export function concatPath(dirA: string, dirB: string): Path;\n}\n","tokens":[{"type":"T_DECLARE","context":"normal","value":"declare","line":1,"start":0,"end":7},{"type":"T_IDENTIFIER","context":"normal","value":"module","line":1,"start":8,"end":14},{"type":"T_STRING","context":"normal","value":"\"some-es-module\"","line":1,"start":15,"end":31},{"type":"T_LCURLY","context":"normal","value":"{","line":1,"start":32,"end":33},{"type":"Line","context":"comment","value":"// Defines the type of a Path class within this `declare module` body, but","line":2,"start":36,"end":110},{"type":"Line","context":"comment","value":"// does not export it. It can only be referenced by other things inside the","line":3,"start":113,"end":188},{"type":"Line","context":"comment","value":"// body of this `declare module`","line":4,"start":191,"end":223},{"type":"T_DECLARE","context":"normal","value":"declare","line":5,"start":226,"end":233},{"type":"T_CLASS","context":"normal","value":"class","line":5,"start":234,"end":239},{"type":"T_IDENTIFIER","context":"normal","value":"Path","line":5,"start":240,"end":244},{"type":"T_LCURLY","context":"type","value":"{","line":5,"start":245,"end":246},{"type":"T_IDENTIFIER","context":"normal","value":"toString","line":6,"start":251,"end":259},{"type":"T_LPAREN","context":"type","value":"(","line":6,"start":259,"end":260},{"type":"T_RPAREN","context":"type","value":")","line":6,"start":260,"end":261},{"type":"T_COLON","context":"type","value":":","line":6,"start":261,"end":262},{"type":"T_STRING_TYPE","context":"type","value":"string","line":6,"start":263,"end":269},{"type":"T_SEMICOLON","context":"type","value":";","line":6,"start":269,"end":270},{"type":"T_RCURLY","context":"type","value":"}","line":7,"start":273,"end":274},{"type":"Line","context":"comment","value":"// Declares a named \"concatPath\" export which returns an instance of the","line":9,"start":278,"end":350},{"type":"Line","context":"comment","value":"// `Path` class (defined above)","line":10,"start":353,"end":384},{"type":"T_DECLARE","context":"normal","value":"declare","line":11,"start":387,"end":394},{"type":"T_EXPORT","context":"normal","value":"export","line":11,"start":395,"end":401},{"type":"T_FUNCTION","context":"normal","value":"function","line":11,"start":402,"end":410},{"type":"T_IDENTIFIER","context":"normal","value":"concatPath","line":11,"start":411,"end":421},{"type":"T_LPAREN","context":"type","value":"(","line":11,"start":421,"end":422},{"type":"T_IDENTIFIER","context":"normal","value":"dirA","line":11,"start":422,"end":426},{"type":"T_COLON","context":"type","value":":","line":11,"start":426,"end":427},{"type":"T_STRING_TYPE","context":"type","value":"string","line":11,"start":428,"end":434},{"type":"T_COMMA","context":"type","value":",","line":11,"start":434,"end":435},{"type":"T_IDENTIFIER","context":"normal","value":"dirB","line":11,"start":436,"end":440},{"type":"T_COLON","context":"type","value":":","line":11,"start":440,"end":441},{"type":"T_STRING_TYPE","context":"type","value":"string","line":11,"start":442,"end":448},{"type":"T_RPAREN","context":"type","value":")","line":11,"start":448,"end":449},{"type":"T_COLON","context":"normal","value":":","line":11,"start":449,"end":450},{"type":"T_IDENTIFIER","context":"type","value":"Path","line":11,"start":451,"end":455},{"type":"T_SEMICOLON","context":"normal","value":";","line":11,"start":455,"end":456},{"type":"T_RCURLY","context":"normal","value":"}","line":12,"start":457,"end":458}],"errors":[]}
Default Exports
flow-typed/some-es-module.js
1
2
3
4
5
6
7
8
9
10
11
|
declare module "some-es-module" {
declare class URL {
constructor(urlStr: string): URL;
toString(): string;
static compare(url1: URL, url2: URL): boolean;
}
declare export default typeof URL;
}
|
{"value":"declare module \"some-es-module\" {\n declare class URL {\n constructor(urlStr: string): URL;\n toString(): string;\n\n static compare(url1: URL, url2: URL): boolean;\n }\n\n // Declares a default export whose type is `typeof URL`\n declare export default typeof URL;\n}\n","tokens":[{"type":"T_DECLARE","context":"normal","value":"declare","line":1,"start":0,"end":7},{"type":"T_IDENTIFIER","context":"normal","value":"module","line":1,"start":8,"end":14},{"type":"T_STRING","context":"normal","value":"\"some-es-module\"","line":1,"start":15,"end":31},{"type":"T_LCURLY","context":"normal","value":"{","line":1,"start":32,"end":33},{"type":"T_DECLARE","context":"normal","value":"declare","line":2,"start":36,"end":43},{"type":"T_CLASS","context":"normal","value":"class","line":2,"start":44,"end":49},{"type":"T_IDENTIFIER","context":"normal","value":"URL","line":2,"start":50,"end":53},{"type":"T_LCURLY","context":"type","value":"{","line":2,"start":54,"end":55},{"type":"T_IDENTIFIER","context":"normal","value":"constructor","line":3,"start":60,"end":71},{"type":"T_LPAREN","context":"type","value":"(","line":3,"start":71,"end":72},{"type":"T_IDENTIFIER","context":"normal","value":"urlStr","line":3,"start":72,"end":78},{"type":"T_COLON","context":"type","value":":","line":3,"start":78,"end":79},{"type":"T_STRING_TYPE","context":"type","value":"string","line":3,"start":80,"end":86},{"type":"T_RPAREN","context":"type","value":")","line":3,"start":86,"end":87},{"type":"T_COLON","context":"type","value":":","line":3,"start":87,"end":88},{"type":"T_IDENTIFIER","context":"type","value":"URL","line":3,"start":89,"end":92},{"type":"T_SEMICOLON","context":"type","value":";","line":3,"start":92,"end":93},{"type":"T_IDENTIFIER","context":"normal","value":"toString","line":4,"start":98,"end":106},{"type":"T_LPAREN","context":"type","value":"(","line":4,"start":106,"end":107},{"type":"T_RPAREN","context":"type","value":")","line":4,"start":107,"end":108},{"type":"T_COLON","context":"type","value":":","line":4,"start":108,"end":109},{"type":"T_STRING_TYPE","context":"type","value":"string","line":4,"start":110,"end":116},{"type":"T_SEMICOLON","context":"type","value":";","line":4,"start":116,"end":117},{"type":"T_STATIC","context":"type","value":"static","line":6,"start":123,"end":129},{"type":"T_IDENTIFIER","context":"normal","value":"compare","line":6,"start":130,"end":137},{"type":"T_LPAREN","context":"type","value":"(","line":6,"start":137,"end":138},{"type":"T_IDENTIFIER","context":"normal","value":"url1","line":6,"start":138,"end":142},{"type":"T_COLON","context":"type","value":":","line":6,"start":142,"end":143},{"type":"T_IDENTIFIER","context":"type","value":"URL","line":6,"start":144,"end":147},{"type":"T_COMMA","context":"type","value":",","line":6,"start":147,"end":148},{"type":"T_IDENTIFIER","context":"normal","value":"url2","line":6,"start":149,"end":153},{"type":"T_COLON","context":"type","value":":","line":6,"start":153,"end":154},{"type":"T_IDENTIFIER","context":"type","value":"URL","line":6,"start":155,"end":158},{"type":"T_RPAREN","context":"type","value":")","line":6,"start":158,"end":159},{"type":"T_COLON","context":"type","value":":","line":6,"start":159,"end":160},{"type":"T_BOOLEAN_TYPE","context":"type","value":"boolean","line":6,"start":161,"end":168},{"type":"T_SEMICOLON","context":"type","value":";","line":6,"start":168,"end":169},{"type":"T_RCURLY","context":"type","value":"}","line":7,"start":172,"end":173},{"type":"Line","context":"comment","value":"// Declares a default export whose type is `typeof URL`","line":9,"start":177,"end":232},{"type":"T_DECLARE","context":"normal","value":"declare","line":10,"start":235,"end":242},{"type":"T_EXPORT","context":"normal","value":"export","line":10,"start":243,"end":249},{"type":"T_DEFAULT","context":"normal","value":"default","line":10,"start":250,"end":257},{"type":"T_TYPEOF","context":"type","value":"typeof","line":10,"start":258,"end":264},{"type":"T_IDENTIFIER","context":"type","value":"URL","line":10,"start":265,"end":268},{"type":"T_SEMICOLON","context":"normal","value":";","line":10,"start":268,"end":269},{"type":"T_RCURLY","context":"normal","value":"}","line":11,"start":270,"end":271}],"errors":[]}
It is also possible to declare both named and default exports in the
same declare module
body.
Declaring A CommonJS Module
CommonJS modules have a single value that is exported (the module.exports
value). To describe the type of this single value within a declare module
body, you’ll use the declare module.exports
syntax:
flow-typed/some-commonjs-module.js
1
2
3
4
5
6
|
declare module "some-commonjs-module" {
declare module.exports: {
concatPath(dirA: string, dirB: string): string;
};
}
|
{"value":"declare module \"some-commonjs-module\" {\n // The export of this module is an object with a \"concatPath\" method\n declare module.exports: {\n concatPath(dirA: string, dirB: string): string;\n };\n}\n","tokens":[{"type":"T_DECLARE","context":"normal","value":"declare","line":1,"start":0,"end":7},{"type":"T_IDENTIFIER","context":"normal","value":"module","line":1,"start":8,"end":14},{"type":"T_STRING","context":"normal","value":"\"some-commonjs-module\"","line":1,"start":15,"end":37},{"type":"T_LCURLY","context":"normal","value":"{","line":1,"start":38,"end":39},{"type":"Line","context":"comment","value":"// The export of this module is an object with a \"concatPath\" method","line":2,"start":42,"end":110},{"type":"T_DECLARE","context":"normal","value":"declare","line":3,"start":113,"end":120},{"type":"T_IDENTIFIER","context":"normal","value":"module","line":3,"start":121,"end":127},{"type":"T_PERIOD","context":"normal","value":".","line":3,"start":127,"end":128},{"type":"T_IDENTIFIER","context":"normal","value":"exports","line":3,"start":128,"end":135},{"type":"T_COLON","context":"type","value":":","line":3,"start":135,"end":136},{"type":"T_LCURLY","context":"type","value":"{","line":3,"start":137,"end":138},{"type":"T_IDENTIFIER","context":"normal","value":"concatPath","line":4,"start":143,"end":153},{"type":"T_LPAREN","context":"type","value":"(","line":4,"start":153,"end":154},{"type":"T_IDENTIFIER","context":"normal","value":"dirA","line":4,"start":154,"end":158},{"type":"T_COLON","context":"type","value":":","line":4,"start":158,"end":159},{"type":"T_STRING_TYPE","context":"type","value":"string","line":4,"start":160,"end":166},{"type":"T_COMMA","context":"type","value":",","line":4,"start":166,"end":167},{"type":"T_IDENTIFIER","context":"normal","value":"dirB","line":4,"start":168,"end":172},{"type":"T_COLON","context":"type","value":":","line":4,"start":172,"end":173},{"type":"T_STRING_TYPE","context":"type","value":"string","line":4,"start":174,"end":180},{"type":"T_RPAREN","context":"type","value":")","line":4,"start":180,"end":181},{"type":"T_COLON","context":"type","value":":","line":4,"start":181,"end":182},{"type":"T_STRING_TYPE","context":"type","value":"string","line":4,"start":183,"end":189},{"type":"T_SEMICOLON","context":"type","value":";","line":4,"start":189,"end":190},{"type":"T_RCURLY","context":"type","value":"}","line":5,"start":193,"end":194},{"type":"T_SEMICOLON","context":"normal","value":";","line":5,"start":194,"end":195},{"type":"T_RCURLY","context":"normal","value":"}","line":6,"start":196,"end":197}],"errors":[]}
Note that you can also declare other things inside the body of the
declare module
, and those things will be scoped to the body of the
declare module
, but they will not be exported from the module:
flow-typed/some-commonjs-module.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
declare module "some-commonjs-module" {
declare class Path {
toString(): string;
}
declare module.exports: {
concatPath(dirA: string, dirB: string): Path
};
}
|
{"value":"declare module \"some-commonjs-module\" {\n // Defines the type of a Path class within this `declare module` body, but\n // does not export it. It can only be referenced by other things inside the\n // body of this `declare module`\n declare class Path {\n toString(): string;\n }\n\n // The \"concatPath\" function now returns an instance of the `Path` class\n // (defined above).\n declare module.exports: {\n concatPath(dirA: string, dirB: string): Path\n };\n}\n","tokens":[{"type":"T_DECLARE","context":"normal","value":"declare","line":1,"start":0,"end":7},{"type":"T_IDENTIFIER","context":"normal","value":"module","line":1,"start":8,"end":14},{"type":"T_STRING","context":"normal","value":"\"some-commonjs-module\"","line":1,"start":15,"end":37},{"type":"T_LCURLY","context":"normal","value":"{","line":1,"start":38,"end":39},{"type":"Line","context":"comment","value":"// Defines the type of a Path class within this `declare module` body, but","line":2,"start":42,"end":116},{"type":"Line","context":"comment","value":"// does not export it. It can only be referenced by other things inside the","line":3,"start":119,"end":194},{"type":"Line","context":"comment","value":"// body of this `declare module`","line":4,"start":197,"end":229},{"type":"T_DECLARE","context":"normal","value":"declare","line":5,"start":232,"end":239},{"type":"T_CLASS","context":"normal","value":"class","line":5,"start":240,"end":245},{"type":"T_IDENTIFIER","context":"normal","value":"Path","line":5,"start":246,"end":250},{"type":"T_LCURLY","context":"type","value":"{","line":5,"start":251,"end":252},{"type":"T_IDENTIFIER","context":"normal","value":"toString","line":6,"start":257,"end":265},{"type":"T_LPAREN","context":"type","value":"(","line":6,"start":265,"end":266},{"type":"T_RPAREN","context":"type","value":")","line":6,"start":266,"end":267},{"type":"T_COLON","context":"type","value":":","line":6,"start":267,"end":268},{"type":"T_STRING_TYPE","context":"type","value":"string","line":6,"start":269,"end":275},{"type":"T_SEMICOLON","context":"type","value":";","line":6,"start":275,"end":276},{"type":"T_RCURLY","context":"type","value":"}","line":7,"start":279,"end":280},{"type":"Line","context":"comment","value":"// The \"concatPath\" function now returns an instance of the `Path` class","line":9,"start":284,"end":356},{"type":"Line","context":"comment","value":"// (defined above).","line":10,"start":359,"end":378},{"type":"T_DECLARE","context":"normal","value":"declare","line":11,"start":381,"end":388},{"type":"T_IDENTIFIER","context":"normal","value":"module","line":11,"start":389,"end":395},{"type":"T_PERIOD","context":"normal","value":".","line":11,"start":395,"end":396},{"type":"T_IDENTIFIER","context":"normal","value":"exports","line":11,"start":396,"end":403},{"type":"T_COLON","context":"type","value":":","line":11,"start":403,"end":404},{"type":"T_LCURLY","context":"type","value":"{","line":11,"start":405,"end":406},{"type":"T_IDENTIFIER","context":"normal","value":"concatPath","line":12,"start":411,"end":421},{"type":"T_LPAREN","context":"type","value":"(","line":12,"start":421,"end":422},{"type":"T_IDENTIFIER","context":"normal","value":"dirA","line":12,"start":422,"end":426},{"type":"T_COLON","context":"type","value":":","line":12,"start":426,"end":427},{"type":"T_STRING_TYPE","context":"type","value":"string","line":12,"start":428,"end":434},{"type":"T_COMMA","context":"type","value":",","line":12,"start":434,"end":435},{"type":"T_IDENTIFIER","context":"normal","value":"dirB","line":12,"start":436,"end":440},{"type":"T_COLON","context":"type","value":":","line":12,"start":440,"end":441},{"type":"T_STRING_TYPE","context":"type","value":"string","line":12,"start":442,"end":448},{"type":"T_RPAREN","context":"type","value":")","line":12,"start":448,"end":449},{"type":"T_COLON","context":"type","value":":","line":12,"start":449,"end":450},{"type":"T_IDENTIFIER","context":"type","value":"Path","line":12,"start":451,"end":455},{"type":"T_RCURLY","context":"type","value":"}","line":13,"start":458,"end":459},{"type":"T_SEMICOLON","context":"normal","value":";","line":13,"start":459,"end":460},{"type":"T_RCURLY","context":"normal","value":"}","line":14,"start":461,"end":462}],"errors":[]}
NOTE: Because a given module cannot be both an ES module and a CommonJS module,
it is an error to mix declare export [...]
with
declare module.exports: ...
in the same declare module
body.