/* eslint-disable react/no-array-index-key */ // https://github.com/TypeStrong/typedoc-default-themes/blob/master/src/default/partials/type.hbs import { Fragment } from 'react'; import type { JSONOutput } from 'typedoc'; import Link from '@docusaurus/Link'; import { useReflectionMap } from '../hooks/useReflectionMap'; import type { TSDDeclarationReflection } from '../types'; import { MemberSignatureTitle } from './MemberSignatureTitle'; export function extractDeclarationFromType( type?: JSONOutput.Reflection | JSONOutput.SomeType, ): TSDDeclarationReflection | undefined { if (!type) { return undefined; } return (type as unknown as { declaration?: TSDDeclarationReflection })?.declaration; } function parens(element: JSX.Element, needsParens: boolean): JSX.Element { if (!needsParens) { return element; } return ( <> {needsParens && (} {element} {needsParens && )} ); } export interface TypeProps { needsParens?: boolean; type?: { type: string; value?: unknown }; } // eslint-disable-next-line complexity export function Type({ needsParens = false, type: base }: TypeProps) { const reflections = useReflectionMap(); if (!base) { return null; } // Cast to string since `type` doesnt include all string values in the union. // https://github.com/TypeStrong/typedoc/blob/master/src/lib/output/themes/default/partials/type.tsx switch (String(base.type)) { case 'array': { const type = base as JSONOutput.ArrayType; return ( <> [] ); } case 'conditional': { const type = base as JSONOutput.ConditionalType; return parens( <> extends ? : , needsParens, ); } case 'indexedAccess': { const type = base as JSONOutput.IndexedAccessType; return ( <> [ ] ); } case 'inferred': { const type = base as JSONOutput.InferredType; return ( <> infer {type.name} ); } case 'intersection': { const type = base as JSONOutput.IntersectionType; return parens( <> {type.types.map((t, i) => ( {i > 0 && & } ))} , needsParens, ); } case 'intrinsic': { const type = base as JSONOutput.IntrinsicType; return {type.name}; } case 'literal': { const type = base as JSONOutput.LiteralType; return {String(type.value)}; } case 'mapped': { const type = base as unknown as JSONOutput.MappedType; return ( <> {'{ '} {type.readonlyModifier === '+' && readonly } {type.readonlyModifier === '-' && ( -readonly )} [ {type.parameter} in {type.nameType && ( <> as )} ] {type.optionalModifier === '+' && ?: } {type.optionalModifier === '-' && -?: } {!type.optionalModifier && : } {' }'} ); } case 'optional': { const type = base as JSONOutput.OptionalType; return ( <> ? ); } case 'predicate': { const type = base as JSONOutput.PredicateType; return ( <> {type.asserts && asserts } {type.name} {type.targetType && ( <> is )} ); } case 'query': { const type = base as JSONOutput.QueryType; return ( <> typeof ); } case 'reference': { const type = base as JSONOutput.ReferenceType; const ref = type.target ? reflections[Number(type.target)] : null; const genericClass = ref?.id && !ref.sources ? 'tsd-signature-type-generic' : ''; return ( <> {ref?.permalink ? ( {type.name} ) : ( {type.name} )} {type.typeArguments && type.typeArguments.length > 0 && ( <> < {type.typeArguments.map((t, i) => ( {i > 0 && , } ))} > )} ); } case 'reflection': { const type = base as JSONOutput.ReflectionType; const decl = type.declaration; // object literal if (decl?.children && decl.children.length > 0) { return ( <> {'{ '} {decl.children.map((child, i) => ( {i > 0 && ; } {child.name} {child.flags?.isOptional && '?'}: {child.type ? : 'any'} ))} {' }'} ); } if (decl?.signatures && decl.signatures.length === 1) { return ; } if (decl?.signatures && decl.signatures.length > 0) { return parens( <> {'{ '} {decl.signatures.map((sig, i) => ( {i > 0 && ; } ))} {' }'} , needsParens, ); } return <>{'{}'}; } case 'rest': { const type = base as JSONOutput.RestType; return ( <> ... ); } case 'tuple': { const type = base as JSONOutput.TupleType; return ( <> [ {type.elements?.map((t, i) => ( {i > 0 && , } ))} ] ); } case 'typeOperator': { const type = base as JSONOutput.TypeOperatorType; return ( <> {type.operator} ); } // case 'typeParameter': { // const type = base as JSONOutput.TypeParameterType; // return {type.name}; // } case 'union': { const type = base as JSONOutput.UnionType; return parens( <> {type.types.map((t, i) => ( {i > 0 && | } ))} , needsParens, ); } case 'unknown': { const type = base as JSONOutput.UnknownType; return {type.name}; } case 'named-tuple-member': case 'namedTupleMember': { const type = base as unknown as JSONOutput.NamedTupleMemberType; return ( <> {type.name} {type.isOptional ? '?: ' : ': '} ); } case 'template-literal': case 'templateLiteral': { const type = base as unknown as JSONOutput.TemplateLiteralType; return ( <> ` {type.head && {type.head}} {type.tail.map((t, i) => ( {'${'} {typeof t[0] !== 'string' && } {'}'} {typeof t[1] === 'string' && {t[1]}} ))} ` ); } default: return void; } }