mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-13 10:03:31 +01:00
feat(docgen): typescript support
This commit is contained in:
112
packages/docgen/src/util/parseType.ts
Normal file
112
packages/docgen/src/util/parseType.ts
Normal file
@@ -0,0 +1,112 @@
|
||||
import type { JSONOutput } from 'typedoc';
|
||||
import {
|
||||
isArrayType,
|
||||
isConditionalType,
|
||||
isIndexedAccessType,
|
||||
isIntersectionType,
|
||||
isPredicateType,
|
||||
isReferenceType,
|
||||
isReflectionType,
|
||||
isLiteralType,
|
||||
isTupleType,
|
||||
isTypeOperatorType,
|
||||
isUnionType,
|
||||
isQueryType,
|
||||
isInferredType,
|
||||
isIntrinsicType,
|
||||
isUnknownType,
|
||||
} from './types';
|
||||
|
||||
export function parseType(t: JSONOutput.SomeType | JSONOutput.Type | string): string {
|
||||
if (typeof t === 'string') {
|
||||
return t;
|
||||
}
|
||||
|
||||
if (isArrayType(t)) {
|
||||
return `Array<${parseType(t.elementType)}>`;
|
||||
}
|
||||
|
||||
if (isConditionalType(t)) {
|
||||
const { checkType, extendsType, trueType, falseType } = t;
|
||||
return `${parseType(checkType)} extends ${parseType(extendsType)} ? ${parseType(trueType)} : ${parseType(
|
||||
falseType,
|
||||
)}`;
|
||||
}
|
||||
|
||||
if (isIndexedAccessType(t)) {
|
||||
return `${parseType(t.objectType)}[${parseType(t.indexType)}]`;
|
||||
}
|
||||
|
||||
if (isIntersectionType(t)) {
|
||||
return t.types.map(parseType).join(' & ');
|
||||
}
|
||||
|
||||
if (isPredicateType(t)) {
|
||||
return (t.asserts ? 'asserts ' : '') + t.name + (t.targetType ? ` is ${parseType(t.targetType)}` : '');
|
||||
}
|
||||
|
||||
if (isReferenceType(t)) {
|
||||
return t.name + (t.typeArguments ? `<${t.typeArguments.map(parseType).join(', ')}>` : '');
|
||||
}
|
||||
|
||||
if (isReflectionType(t)) {
|
||||
const obj: Record<string, any> = {};
|
||||
|
||||
const { children, signatures } = t.declaration!;
|
||||
|
||||
// This is run when we're parsing interface-like declaration
|
||||
if (children && children.length > 0) {
|
||||
for (const child of children) {
|
||||
const { type } = child;
|
||||
if (type) {
|
||||
obj[child.name] = parseType(type);
|
||||
}
|
||||
}
|
||||
return `{\n${Object.entries(obj)
|
||||
.map(([key, value]) => `${key}: ${value as string}`)
|
||||
.join(',\n')}\n}`;
|
||||
}
|
||||
|
||||
// This is run if we're parsing a function type
|
||||
if (signatures && signatures.length > 0) {
|
||||
const s = signatures[0];
|
||||
const params = s?.parameters?.map((p) => `${p.name}: ${p.type ? parseType(p.type) : 'unknown'}`);
|
||||
return `(${params?.join(', ') ?? '...args: unknown[]'}) => ${s?.type ? parseType(s.type) : 'unknown'}`;
|
||||
}
|
||||
|
||||
return '{}';
|
||||
}
|
||||
|
||||
if (isLiteralType(t)) {
|
||||
if (typeof t.value == 'string') {
|
||||
return `'${t.value}'`;
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
|
||||
return `${t.value}`;
|
||||
}
|
||||
|
||||
if (isTupleType(t)) {
|
||||
return `[${(t.elements ?? []).map(parseType).join(', ')}]`;
|
||||
}
|
||||
|
||||
if (isTypeOperatorType(t)) {
|
||||
return `${t.operator} ${parseType(t.target)}`;
|
||||
}
|
||||
|
||||
if (isUnionType(t)) {
|
||||
return t.types
|
||||
.map(parseType)
|
||||
.filter((s) => Boolean(s) && s.trim().length > 0)
|
||||
.join(' | ');
|
||||
}
|
||||
|
||||
if (isQueryType(t)) {
|
||||
return `(typeof ${parseType(t.queryType)})`;
|
||||
}
|
||||
|
||||
if (isInferredType(t) || isIntrinsicType(t) || isUnknownType(t)) {
|
||||
return t.name;
|
||||
}
|
||||
|
||||
return 'unknown';
|
||||
}
|
||||
28
packages/docgen/src/util/splitVarName.ts
Normal file
28
packages/docgen/src/util/splitVarName.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
export function splitVarName(str: string) {
|
||||
const res: string[][] = [];
|
||||
let currGroup: string[] = [];
|
||||
let currStr = '';
|
||||
|
||||
const isASymbol = (char: string) => '-!$%^&*()_+|~=`{}[]:;<>?, '.includes(char);
|
||||
|
||||
for (const char of str) {
|
||||
const currentlyInASymbolSection = isASymbol(currStr[0]!);
|
||||
const charIsASymbol = isASymbol(char);
|
||||
|
||||
if (currStr.length && currentlyInASymbolSection !== charIsASymbol) {
|
||||
currGroup.push(currStr);
|
||||
currStr = char;
|
||||
|
||||
if (!charIsASymbol) {
|
||||
res.push(currGroup);
|
||||
currGroup = [];
|
||||
}
|
||||
} else {
|
||||
currStr += char;
|
||||
}
|
||||
}
|
||||
currGroup.push(currStr);
|
||||
res.push(currGroup);
|
||||
|
||||
return res;
|
||||
}
|
||||
67
packages/docgen/src/util/types.ts
Normal file
67
packages/docgen/src/util/types.ts
Normal file
@@ -0,0 +1,67 @@
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
||||
import type { JSONOutput } from 'typedoc';
|
||||
|
||||
interface QueryType {
|
||||
type: 'query';
|
||||
queryType: JSONOutput.SomeType;
|
||||
}
|
||||
|
||||
export function isArrayType(value: any): value is JSONOutput.ArrayType {
|
||||
return typeof value == 'object' && value.type === 'array';
|
||||
}
|
||||
|
||||
export function isConditionalType(value: any): value is JSONOutput.ConditionalType {
|
||||
return typeof value == 'object' && value.type === 'conditional';
|
||||
}
|
||||
|
||||
export function isIndexedAccessType(value: any): value is JSONOutput.IndexedAccessType {
|
||||
return typeof value == 'object' && value.type === 'indexedAccess';
|
||||
}
|
||||
|
||||
export function isInferredType(value: any): value is JSONOutput.InferredType {
|
||||
return typeof value == 'object' && value.type === 'inferred';
|
||||
}
|
||||
|
||||
export function isIntersectionType(value: any): value is JSONOutput.IntersectionType {
|
||||
return typeof value == 'object' && value.type === 'intersection';
|
||||
}
|
||||
|
||||
export function isIntrinsicType(value: any): value is JSONOutput.IntrinsicType {
|
||||
return typeof value == 'object' && value.type === 'intrinsic';
|
||||
}
|
||||
|
||||
export function isPredicateType(value: any): value is JSONOutput.PredicateType {
|
||||
return typeof value == 'object' && value.type === 'predicate';
|
||||
}
|
||||
|
||||
export function isReferenceType(value: any): value is JSONOutput.ReferenceType {
|
||||
return typeof value == 'object' && value.type === 'reference';
|
||||
}
|
||||
|
||||
export function isReflectionType(value: any): value is JSONOutput.ReflectionType {
|
||||
return typeof value == 'object' && value.type === 'reflection';
|
||||
}
|
||||
|
||||
export function isLiteralType(value: any): value is JSONOutput.LiteralType {
|
||||
return typeof value == 'object' && value.type === 'literal';
|
||||
}
|
||||
|
||||
export function isTupleType(value: any): value is JSONOutput.TupleType {
|
||||
return typeof value == 'object' && value.type === 'tuple';
|
||||
}
|
||||
|
||||
export function isTypeOperatorType(value: any): value is JSONOutput.TypeOperatorType {
|
||||
return typeof value == 'object' && value.type === 'typeOperator';
|
||||
}
|
||||
|
||||
export function isUnionType(value: any): value is JSONOutput.UnionType {
|
||||
return typeof value == 'object' && value.type === 'union';
|
||||
}
|
||||
|
||||
export function isUnknownType(value: any): value is JSONOutput.UnknownType {
|
||||
return typeof value == 'object' && value.type === 'unknown';
|
||||
}
|
||||
|
||||
export function isQueryType(value: any): value is QueryType {
|
||||
return typeof value == 'object' && value.type === 'query';
|
||||
}
|
||||
Reference in New Issue
Block a user