@@ -25,7 +25,7 @@ export function getNodeSignature(node: DenoDocNode): string | null {
2525 return `${ asyncStr } function ${ name } ${ typeParamsStr } (${ params } ): ${ ret } `
2626 }
2727 case 'class' : {
28- const ext = node . classDef ?. extends ? ` extends ${ formatType ( node . classDef . extends ) } ` : ''
28+ const ext = node . classDef ?. extends ? ` extends ${ node . classDef . extends } ` : ''
2929 const impl = node . classDef ?. implements ?. map ( t => formatType ( t ) ) . join ( ', ' )
3030 const implStr = impl ? ` implements ${ impl } ` : ''
3131 const abstractStr = node . classDef ?. isAbstract ? 'abstract ' : ''
@@ -72,25 +72,66 @@ export function formatParam(param: FunctionParam): string {
7272export function formatType ( type ?: TsType ) : string {
7373 if ( ! type ) return ''
7474
75- // Strip ANSI codes from repr (deno doc may include terminal colors since it's built for that)
76- if ( type . repr ) return stripAnsi ( type . repr )
75+ const formatter = TYPE_FORMATTERS [ type . kind ]
76+ const formatted = formatter ?. ( type )
7777
78- if ( type . kind === 'keyword' && type . keyword ) {
79- return type . keyword
80- }
78+ if ( formatted ) return formatted
79+ return type . repr ? stripAnsi ( type . repr ) : 'unknown'
80+ }
8181
82- 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 ''
8393 const params = type . typeRef . typeParams ?. map ( t => formatType ( t ) ) . join ( ', ' )
8494 return params ? `${ type . typeRef . typeName } <${ params } >` : type . typeRef . typeName
85- }
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 ''
105+ return `${ formatType ( type . indexedAccess . objType ) } [${ formatType ( type . indexedAccess . indexType ) } ]`
106+ } ,
107+ typeOperator : type => {
108+ if ( ! type . typeOperator ) return ''
109+ return `${ type . typeOperator . operator } ${ formatType ( type . typeOperator . tsType ) } `
110+ } ,
111+ fnOrConstructor : type =>
112+ type . fnOrConstructor ? formatFnOrConstructorType ( type . fnOrConstructor ) : '' ,
113+ typeLiteral : type => ( type . typeLiteral ? formatTypeLiteralType ( type . typeLiteral ) : '' ) ,
114+ }
86115
87- if ( type . kind === 'array' && type . array ) {
88- return `${ formatType ( type . array ) } []`
89- }
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+ }
90123
91- if ( type . kind === 'union' && type . union ) {
92- return type . union . map ( t => formatType ( t ) ) . 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' } ` )
93130 }
94-
95- 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 ( '; ' ) } }`
96137}
0 commit comments