@@ -20,6 +20,7 @@ const ignoreNode = "";
2020export  interface  ICompilerOptions  { 
2121  format ?: "ts"  |  "js:esm"  |  "js:cjs" 
2222  ignoreGenerics ?: boolean ; 
23+   ignoreNotSupported ?: boolean ; 
2324  ignoreIndexSignature ?: boolean ; 
2425  inlineImports ?: boolean ; 
2526} 
@@ -37,7 +38,7 @@ export class Compiler {
3738    if  ( ! topNode )  { 
3839      throw  new  Error ( `Can't process ${ filePath } ${ collectDiagnostics ( program ) }  ) ; 
3940    } 
40-     options  =  { format : defaultFormat ,  ignoreGenerics : false ,  ignoreIndexSignature : false ,  inlineImports : false ,  ...options } 
41+     options  =  { format : defaultFormat ,  ignoreGenerics : false ,  ignoreNotSupported :  false ,   ignoreIndexSignature : false ,  inlineImports : false ,  ...options } 
4142    return  new  Compiler ( checker ,  options ,  topNode ) . compileNode ( topNode ) ; 
4243  } 
4344
@@ -80,6 +81,12 @@ export class Compiler {
8081      case  ts . SyntaxKind . ExportDeclaration :
8182      case  ts . SyntaxKind . ImportDeclaration :
8283        return  this . _compileImportDeclaration ( node  as  ts . ImportDeclaration ) ; 
84+       case  ts . SyntaxKind . ModuleDeclaration :
85+         const  body : ts . ModuleBody  =  node [ "body" ] ; 
86+         if  ( "statements"  in  body )  { 
87+           return  body . statements . map ( this . compileNode ,  this ) . filter ( s  =>  s ) . join ( "\n\n" ) ; 
88+         } 
89+         //return this._compileNamespaceDeclaration(node as ts.NamespaceDeclaration); 
8390      case  ts . SyntaxKind . SourceFile : return  this . _compileSourceFile ( node  as  ts . SourceFile ) ; 
8491      case  ts . SyntaxKind . AnyKeyword : return  '"any"' ; 
8592      case  ts . SyntaxKind . NumberKeyword : return  '"number"' ; 
@@ -97,6 +104,12 @@ export class Compiler {
97104    } 
98105    // Skip top-level statements that we haven't handled. 
99106    if  ( ts . isSourceFile ( node . parent ! ) )  {  return  "" ;  } 
107+     
108+     if  ( this . options . ignoreNotSupported )  { 
109+       console . log ( `Node ${ ts . SyntaxKind [ node . kind ] }   + 
110+         node . getText ( ) ) ; 
111+       return  node . getText ( ) ; 
112+     } 
100113    throw  new  Error ( `Node ${ ts . SyntaxKind [ node . kind ] }   + 
101114      node . getText ( ) ) ; 
102115  } 
@@ -139,6 +152,8 @@ export class Compiler {
139152      return  this . compileNode ( node . typeArguments [ 0 ] ) ; 
140153    }  else  if  ( node . typeName . getText ( )  ===  "Array" )  { 
141154      return  `t.array(${ this . compileNode ( node . typeArguments [ 0 ] ) }  ; 
155+     }  else  if  ( node . typeName . getText ( )  ===  "Record" )  { 
156+       return  '"object"' ; 
142157    }  else  if  ( this . options . ignoreGenerics )  { 
143158      return  '"any"' ; 
144159    }  else  { 
@@ -180,8 +195,15 @@ export class Compiler {
180195  } 
181196  private  _compileEnumDeclaration ( node : ts . EnumDeclaration ) : string  { 
182197    const  name  =  this . getName ( node . name ) ; 
183-     const  members : string [ ]  =  node . members . map ( m  => 
184-       `  "${ this . getName ( m . name ) } ${ getTextOfConstantValue ( this . checker . getConstantValue ( m ) ) }  ) ; 
198+     let  counter  =  0 ; 
199+     const  members : string [ ]  =  node . members . map ( m  =>  { 
200+       let  value  =  getTextOfConstantValue ( this . checker . getConstantValue ( m ) ) ; 
201+       if  ( value  ===  "undefined" )  { 
202+         value  =  counter . toString ( 10 ) ; 
203+         ++ counter ; 
204+       } 
205+       return  `  "${ this . getName ( m . name ) } ${ value }  
206+     } ) ; 
185207    this . exportedNames . push ( name ) ; 
186208    return  this . _formatExport ( name ,  `t.enumtype({\n${ members . join ( "" ) }  ) ; 
187209  } 
@@ -214,6 +236,13 @@ export class Compiler {
214236  private  _compileParenthesizedTypeNode ( node : ts . ParenthesizedTypeNode ) : string  { 
215237    return  this . compileNode ( node . type ) ; 
216238  } 
239+   // private _compileNamespaceDeclaration(node: ts.NamespaceDeclaration): string { 
240+   //   if ("statements" in node.body) { 
241+   //     const name = this.getName(node.name); 
242+   //     const prefix = node.modifiers.map(n => n.getText()).filter(s => s).join(" "); 
243+   //     return `${prefix} ${name} {\n${this._compileSourceFileStatements(node.body.statements)}\n}\n`; 
244+   //   } 
245+   // } 
217246  private  _compileImportDeclaration ( node : ts . ImportDeclaration ) : string  { 
218247    if  ( this . options . inlineImports )  { 
219248      const  importedSym  =  this . checker . getSymbolAtLocation ( node . moduleSpecifier ) ; 
@@ -226,26 +255,27 @@ export class Compiler {
226255    } 
227256    return  '' ; 
228257  } 
229-   private  _compileSourceFileStatements ( node : ts . SourceFile ) : string  { 
230-     return  node . statements . map ( this . compileNode ,  this ) . filter ( ( s )  =>  s ) . join ( "\n\n" ) ; 
258+   private  _compileSourceFileStatements ( statements : ts . NodeArray < ts . Statement > ) : string  { 
259+     
260+     return  statements . map ( this . compileNode ,  this ) . filter ( ( s )  =>  s ) . join ( "\n\n" ) ; 
231261  } 
232262  private  _compileSourceFile ( node : ts . SourceFile ) : string  { 
233263    // for imported source files, skip the wrapper 
234264    if  ( node  !==  this . topNode )  { 
235-       return  this . _compileSourceFileStatements ( node ) ; 
265+       return  this . _compileSourceFileStatements ( node . statements ) ; 
236266    } 
237267    // wrap the top node with a default export 
238268    if  ( this . options . format  ===  "js:cjs" )  { 
239269      return  `const t = require("ts-interface-checker");\n\n`  + 
240270        "module.exports = {\n"  + 
241-         this . _compileSourceFileStatements ( node )  +  "\n"  + 
271+         this . _compileSourceFileStatements ( node . statements )  +  "\n"  + 
242272        "};\n" 
243273    } 
244274    const  prefix  =  `import * as t from "ts-interface-checker";\n`  + 
245275                   ( this . options . format  ===  "ts"  ? "// tslint:disable:object-literal-key-quotes\n"  : "" )  + 
246276                   "\n" ; 
247277    return  prefix  + 
248-       this . _compileSourceFileStatements ( node )  +  "\n\n"  + 
278+       this . _compileSourceFileStatements ( node . statements )  +  "\n\n"  + 
249279      "const exportedTypeSuite"  +  ( this . options . format  ===  "ts"  ? ": t.ITypeSuite"  : "" )  +  " = {\n"  + 
250280      this . exportedNames . map ( ( n )  =>  `  ${ n }  ) . join ( "" )  + 
251281      "};\n"  + 
@@ -302,6 +332,7 @@ export function main() {
302332  . option ( "--format <format>" ,  `Format to use for output; options are 'ts' (default), 'js:esm', 'js:cjs'` ) 
303333  . option ( "-g, --ignore-generics" ,  `Ignores generics` ) 
304334  . option ( "-i, --ignore-index-signature" ,  `Ignores index signature` ) 
335+   . option ( "--ignore-not-supported" ,  `Skip all not supported code` ) 
305336  . option ( "--inline-imports" ,  `Traverses the full import tree and inlines all types into output` ) 
306337  . option ( "-s, --suffix <suffix>" ,  `Suffix to append to generated files (default ${ defaultSuffix }  ,  defaultSuffix ) 
307338  . option ( "-o, --outDir <path>" ,  `Directory for output files; same as source file if omitted` ) 
@@ -317,6 +348,7 @@ export function main() {
317348  const  options : ICompilerOptions  =  { 
318349    format : commander . format  ||  defaultFormat , 
319350    ignoreGenerics : commander . ignoreGenerics , 
351+     ignoreNotSupported : commander . ignoreNotSupported , 
320352    ignoreIndexSignature : commander . ignoreIndexSignature , 
321353    inlineImports : commander . inlineImports , 
322354  } ; 
0 commit comments