Skip to content

Commit 789bcd3

Browse files
committed
refactor: improve the formatType method
1 parent df8c4d4 commit 789bcd3

1 file changed

Lines changed: 54 additions & 46 deletions

File tree

server/utils/docs/format.ts

Lines changed: 54 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -72,58 +72,66 @@ export function formatParam(param: FunctionParam): string {
7272
export 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

Comments
 (0)