@@ -122,19 +122,86 @@ export default class typescriptToFileDatas {
122122 * @param {string } file
123123 * @returns {any } {string}
124124 */
125- handleFilterFiles ( file : string ) : string {
126- const res = this . filterFiles . filter ( ( item : string ) => file . indexOf ( item ) > - 1 ) ;
125+ handleFilterFiles ( file : string ) : { filePath : string , fileType : 'import' | 'npm' } | undefined {
126+ const res = this . filterFiles . filter ( ( item : string ) => file === item ) ;
127127 // 过滤不需要匹配的文件
128128 if ( res . length ) {
129- return '' ;
129+ return ;
130+ }
131+
132+ // import 文件
133+ if ( file === '.' || file === '/' ) {
134+ return { filePath : 'index' , fileType : 'import' } ;
130135 }
131136
132137 if ( file . indexOf ( './' ) > - 1 || file . indexOf ( '../' ) > - 1 ) {
133- return file ;
138+ return { filePath : file , fileType : 'import' } ;
134139 }
135140
136- // 不解析npm包
137- return '' ;
141+ // npm包
142+ return { filePath : file , fileType : 'npm' } ;
143+ }
144+
145+ getTypeFileFromNpm ( { sourceValue } : { sourceValue : string } ) {
146+ // 1. 优先查找 index.d.ts 其次查找 ${sourceValue}.d.ts
147+ const sourceValueArr = sourceValue . split ( '/' ) ;
148+ const possibleExt : any = sourceValueArr . splice ( sourceValueArr . length - 1 , 1 ) [ 0 ] ;
149+ let possibleExtArr : string [ ] = [ ] ;
150+ possibleExt ?
151+ possibleExtArr . push ( `${ possibleExt } /index.d.ts` , `${ possibleExt } .d.ts` ) :
152+ possibleExtArr . push ( 'index.d.ts' ) ;
153+ possibleExtArr = possibleExtArr . map ( item => sourceValueArr ? `${ sourceValueArr . join ( '/' ) } /${ item } ` : item ) ;
154+ let source = ''
155+ for ( const possibleExt of possibleExtArr ) {
156+ const possibleFile = path . resolve ( process . cwd ( ) , 'node_modules' , possibleExt ) ;
157+ if ( fs . existsSync ( possibleFile ) ) {
158+ source = possibleFile ;
159+ break ;
160+ }
161+ }
162+ // 2. 查找 package.json.typings 或 index.d.ts
163+ if ( ! source ) {
164+ const possibleFile = path . resolve ( process . cwd ( ) , 'node_modules' , sourceValue , 'package.json' ) ;
165+ if ( fs . existsSync ( possibleFile ) ) {
166+ const packageJson = require ( possibleFile ) ;
167+ const typingFile = packageJson . typings || packageJson . types ;
168+ if ( typingFile ) {
169+ const possibleFile = path . resolve ( process . cwd ( ) , 'node_modules' , sourceValue , typingFile ) ;
170+ if ( fs . existsSync ( possibleFile ) ) source = possibleFile ;
171+ } else {
172+ const possibleFile = path . resolve ( process . cwd ( ) , 'node_modules' , sourceValue , 'index.d.ts' ) ;
173+ if ( fs . existsSync ( possibleFile ) ) source = possibleFile ;
174+ }
175+ }
176+ }
177+ // 3. 查找 @types/xxx
178+ if ( ! source ) {
179+ const possibleFile = path . resolve ( process . cwd ( ) , 'node_modules' , '@types' , sourceValue , 'package.json' ) ;
180+ if ( fs . existsSync ( possibleFile ) ) {
181+ const packageJson = require ( possibleFile ) ;
182+ const typingFile = packageJson . typings || packageJson . types ;
183+ if ( typingFile ) {
184+ const possibleFile = path . resolve ( process . cwd ( ) , 'node_modules' , '@types' , sourceValue , typingFile ) ;
185+ if ( fs . existsSync ( possibleFile ) ) source = possibleFile ;
186+ }
187+ }
188+ }
189+ // 避免重复处理
190+ this . filterFiles = [ ...this . filterFiles , sourceValue ] ;
191+ return source
192+ }
193+
194+ getTypeFileFromImport ( { dir, sourceValue, ext } : { dir : string ; sourceValue : string ; ext : string } ) {
195+ let source = '' ;
196+ // 找依赖的文件,优先级 .ts >> .d.ts >> /index.ts >> /index.d.ts
197+ for ( const possibleExt of [ '' , '.d' , '/index' , '/index.d' ] ) {
198+ const possibleFile = path . resolve ( dir , sourceValue + possibleExt + ext ) ;
199+ if ( fs . existsSync ( possibleFile ) ) {
200+ source = possibleFile ;
201+ break ;
202+ }
203+ }
204+ return source ;
138205 }
139206
140207 /**
@@ -165,21 +232,16 @@ export default class typescriptToFileDatas {
165232 const sourceValue = _ . get ( path_ , 'node.source.value' ) ;
166233 if ( ! sourceValue ) return ;
167234
168- const filePath = _this . handleFilterFiles ( sourceValue ) ;
235+ const { filePath, fileType } = _this . handleFilterFiles ( sourceValue ) || { } ;
236+
169237 if ( ! filePath ) {
170238 path_ . skip ( ) ;
171239 return ;
172240 }
173241
174- let source = '' ;
175- // 找依赖的文件,优先级 .ts >> .d.ts >> /index.ts >> /index.d.ts
176- for ( const possibleExt of [ '' , '.d' , '/index' , '/index.d' ] ) {
177- const possibleFile = path . resolve ( dir , sourceValue + possibleExt + ext ) ;
178- if ( fs . existsSync ( possibleFile ) ) {
179- source = possibleFile ;
180- break ;
181- }
182- }
242+ const source = fileType === 'import' ?
243+ _this . getTypeFileFromImport ( { dir, sourceValue : filePath , ext } ) :
244+ _this . getTypeFileFromNpm ( { sourceValue : filePath } )
183245
184246 if ( ! source ) return ;
185247
@@ -378,37 +440,40 @@ export default class typescriptToFileDatas {
378440 const tsTypeName = path . get ( 'id' ) . toString ( ) ;
379441 const key = namespaces . length ? `${ namespaces . join ( '.' ) } .${ tsTypeName } ` : tsTypeName ;
380442 const members = path . get ( 'members' ) ;
381-
382443 const memberMap = new Map ( ) ;
444+ let jsonType : string = ''
445+
383446 const enumKeys = members . reduce ( ( accEnumKeys : ( number | string ) [ ] , member : any ) => {
384- const type = _this . simpleTsTypeTransform ( member . get ( 'initializer' ) . type ) ;
447+ const type = _this . simpleTsTypeTransform ( member . get ( 'initializer' ) . type ) || 'number' ;
385448 let value = member . get ( 'initializer' ) . toString ( ) . replace ( / ' / g, '' ) ;
386449 const prevEnumKey = accEnumKeys . length ? accEnumKeys [ accEnumKeys . length - 1 ] : - 1 ;
450+ const nameObj = member . get ( 'name' ) ;
451+ const name = _ . get ( nameObj , 'container.id.name' ) || _ . get ( nameObj , 'container.id.value' ) ;
387452
388- const name = _ . get ( member . get ( 'name' ) , 'container.id.name' ) ;
453+ if ( ! jsonType ) {
454+ jsonType = type ;
455+ } else if ( jsonType !== type ) {
456+ jsonType = 'any' ;
457+ }
389458
390459 if ( value === '' ) {
391460 value = ( prevEnumKey as number ) + 1 ;
392- } else {
461+ } else if ( type === 'number' ) {
393462 try {
394463 [ ...memberMap . keys ( ) ] . forEach ( ( memberName ) => {
395464 value = value . replace ( new RegExp ( memberName , 'g' ) , memberMap . get ( memberName ) ) ;
396465 } ) ;
397- // eslint-disable-next-line no-eval
398466 value = eval ( value ) ;
399- } catch ( error ) {
400- if ( json . type && json . type !== 'string' ) {
401- value = NaN ;
402- }
403- }
467+ } catch ( error ) { /* do nothing */ }
404468 }
405469 memberMap . set ( name , value ) ;
406-
407- if ( ! json . type ) json . type = type || 'number' ;
408-
409470 return [ ...accEnumKeys , value ] ;
410471 } , [ ] ) ;
411472
473+ if ( jsonType && jsonType !== 'any' ) {
474+ json . type = jsonType ;
475+ }
476+
412477 json . enum = enumKeys ;
413478 if ( ! json . enum . length ) {
414479 ( console as Console ) . warn (
@@ -645,7 +710,7 @@ export default class typescriptToFileDatas {
645710
646711 // 处理any|never|null类型 转换为object类型
647712 if ( type === 'any' || type === 'never' || type === 'null' ) {
648- if ( file && attrKey ) {
713+ if ( file && attrKey && ! file . includes ( '.d.ts' ) ) {
649714 ( console as Console ) . warn (
650715 chalk . yellow ( `警告:%s 文件下的【%s】属性,不推荐定义为【%s】它将会被解析为object类型。` ) ,
651716 file ,
@@ -889,10 +954,10 @@ export default class typescriptToFileDatas {
889954 } ) ;
890955
891956 if ( isEmpty ) {
892- if ( file && attrKey ) {
957+ if ( file && attrKey && ! file . includes ( '.d.ts' ) ) {
893958 ( console as Console ) . warn (
894959 chalk . yellow (
895- `警告:% s 文件下的【% s】属性,类型定义较复杂,请考虑简化,它将会被解析为object类型。` ,
960+ `警告:%s 文件下的【%s】属性,类型定义较复杂,请考虑简化,它将会被解析为object类型。` ,
896961 ) ,
897962 file ,
898963 attrKey ,
0 commit comments