@@ -72,58 +72,66 @@ export function formatParam(param: FunctionParam): string {
7272export function formatType ( type ?: TsType ) : string {
7373 if ( ! type ) return ''
7474
75- if ( type . kind === 'keyword' && type . keyword ) {
76- return type . keyword
77- }
75+ const formatter = TYPE_FORMATTERS [ type . kind ]
76+ const formatted = formatter ?.( type )
77+
78+ if ( formatted ) return formatted
79+ return type . repr ? stripAnsi ( type . repr ) : 'unknown'
80+ }
7881
79- if ( type . kind === 'typeRef' && type . typeRef ) {
82+ const TYPE_FORMATTERS : Partial < Record < TsType [ 'kind' ] , ( type : TsType ) => string > > = {
83+ keyword : type => type . keyword || '' ,
84+ literal : type => {
85+ if ( ! type . literal ) return ''
86+ if ( type . literal . kind === 'string' ) return `"${ type . literal . string } "`
87+ if ( type . literal . kind === 'number' ) return String ( type . literal . number )
88+ if ( type . literal . kind === 'boolean' ) return String ( type . literal . boolean )
89+ return ''
90+ } ,
91+ typeRef : type => {
92+ if ( ! type . typeRef ) return ''
8093 const params = type . typeRef . typeParams ?. map ( t => formatType ( t ) ) . join ( ', ' )
8194 return params ? `${ type . typeRef . typeName } <${ params } >` : type . typeRef . typeName
82- }
83-
84- if ( type . kind === 'array' && type . array ) {
85- return `${ formatType ( type . array ) } []`
86- }
87-
88- if ( type . kind === 'union' && type . union ) {
89- return type . union . map ( t => formatType ( t ) ) . join ( ' | ' )
90- }
91-
92- if ( type . kind === 'this' ) {
93- return 'this'
94- }
95-
96- if ( type . kind === 'indexedAccess' && type . indexedAccess ) {
95+ } ,
96+ array : type => {
97+ if ( ! type . array ) return ''
98+ const element = formatType ( type . array )
99+ return type . array . kind === 'union' ? `(${ element } )[]` : `${ element } []`
100+ } ,
101+ union : type => ( type . union ? type . union . map ( t => formatType ( t ) ) . join ( ' | ' ) : '' ) ,
102+ this : ( ) => 'this' ,
103+ indexedAccess : type => {
104+ if ( ! type . indexedAccess ) return ''
97105 return `${ formatType ( type . indexedAccess . objType ) } [${ formatType ( type . indexedAccess . indexType ) } ]`
98- }
99-
100- if ( type . kind === 'typeOperator' && type . typeOperator ) {
106+ } ,
107+ typeOperator : type => {
108+ if ( ! type . typeOperator ) return ''
101109 return `${ type . typeOperator . operator } ${ formatType ( type . typeOperator . tsType ) } `
102- }
110+ } ,
111+ fnOrConstructor : type =>
112+ type . fnOrConstructor ? formatFnOrConstructorType ( type . fnOrConstructor ) : '' ,
113+ typeLiteral : type => ( type . typeLiteral ? formatTypeLiteralType ( type . typeLiteral ) : '' ) ,
114+ }
103115
104- if ( type . kind === 'fnOrConstructor' && type . fnOrConstructor ) {
105- const { fnOrConstructor : fn } = type
106- const typeParams = fn . typeParams ?. map ( t => t . name ) . join ( ', ' )
107- const typeParamsStr = typeParams ? `<${ typeParams } >` : ''
108- const params = fn . params . map ( p => formatParam ( p ) ) . join ( ', ' )
109- const ret = formatType ( fn . tsType ) || 'void'
110- return `${ typeParamsStr } (${ params } ) => ${ ret } `
111- }
116+ function formatFnOrConstructorType ( fn : NonNullable < TsType [ 'fnOrConstructor' ] > ) : string {
117+ const typeParams = fn . typeParams ?. map ( t => t . name ) . join ( ', ' )
118+ const typeParamsStr = typeParams ? `<${ typeParams } >` : ''
119+ const params = fn . params . map ( p => formatParam ( p ) ) . join ( ', ' )
120+ const ret = formatType ( fn . tsType ) || 'void'
121+ return `${ typeParamsStr } (${ params } ) => ${ ret } `
122+ }
112123
113- if ( type . kind === 'typeLiteral' && type . typeLiteral ) {
114- const parts : string [ ] = [ ]
115- for ( const prop of type . typeLiteral . properties ) {
116- const opt = prop . optional ? '?' : ''
117- const ro = prop . readonly ? 'readonly ' : ''
118- parts . push ( `${ ro } ${ prop . name } ${ opt } : ${ formatType ( prop . tsType ) || 'unknown' } ` )
119- }
120- for ( const method of type . typeLiteral . methods ) {
121- const params = method . params ?. map ( p => formatParam ( p ) ) . join ( ', ' ) || ''
122- const ret = formatType ( method . returnType ) || 'void'
123- parts . push ( `${ method . name } (${ params } ): ${ ret } ` )
124- }
125- return `{ ${ parts . join ( '; ' ) } }`
124+ function formatTypeLiteralType ( lit : NonNullable < TsType [ 'typeLiteral' ] > ) : string {
125+ const parts : string [ ] = [ ]
126+ for ( const prop of lit . properties ) {
127+ const opt = prop . optional ? '?' : ''
128+ const ro = prop . readonly ? 'readonly ' : ''
129+ parts . push ( `${ ro } ${ prop . name } ${ opt } : ${ formatType ( prop . tsType ) || 'unknown' } ` )
126130 }
127-
128- return type . repr ? stripAnsi ( type . repr ) : 'unknown'
131+ for ( const method of lit . methods ) {
132+ const params = method . params ?. map ( p => formatParam ( p ) ) . join ( ', ' ) || ''
133+ const ret = formatType ( method . returnType ) || 'void'
134+ parts . push ( `${ method . name } (${ params } ): ${ ret } ` )
135+ }
136+ return `{ ${ parts . join ( '; ' ) } }`
129137}
0 commit comments