Skip to content

Commit 81d291c

Browse files
authored
chore: better Typescript types (#9480)
* fix doc type * improve frontmatter types * add types to files.ts * get rid of `any`s from docPage * add types to JsBundleListClient * add TS types to utils.ts * fix dynamicNav types * let the inferred type shine * add proper types to CodeKeywords * add TS to apiExamples * add TS type to sidebar * add TS types to serverSidebar * add TS types to expandable * add TS types to PlatformContent component * add TS types to cliChecksumTableClient * add proper TS types to changelog/list * add proper doc TS type to Include component * improte TS types for Alert component * imropve resolveOpenAPI types * fix type import 🙊 * add missing sidebar_title front matter property * fix TS errors on [[...path]]/page.tsx * fix TS errors in *sidebar.tsx * fix TS errors on apiPage * fix TS errors on docTree * narrow down some anys on docTree * move remark-component-spacing plugin to TS * move remark-toc-headings plugin to TS * move remark-extract-frontmatter plugin to TS
1 parent c77bf5d commit 81d291c

27 files changed

+256
-117
lines changed

app/[[...path]]/page.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import {capitilize} from 'sentry-docs/utils';
2222

2323
export async function generateStaticParams() {
2424
const docs = await getDocsFrontMatter();
25-
const paths = docs.map(doc => {
25+
const paths: {path: string[] | undefined}[] = docs.map(doc => {
2626
const path = doc.slug.split('/');
2727
return {path};
2828
});
@@ -83,7 +83,7 @@ export default async function Page({params}) {
8383
}
8484

8585
// get the MDX for the current doc and render it
86-
let doc: any = null;
86+
let doc: Awaited<ReturnType<typeof getFileBySlug>> | null = null;
8787
try {
8888
doc = await getFileBySlug(`docs/${pageNode.path}`);
8989
} catch (e) {
@@ -128,7 +128,7 @@ export async function generateMetadata({params}: MetadataProps): Promise<Metadat
128128
title =
129129
pageNode.frontmatter.title +
130130
(guideOrPlatform ? ` | Sentry for ${capitilize(guideOrPlatform.name)}` : '');
131-
description = pageNode.frontmatter.description;
131+
description = pageNode.frontmatter.description ?? '';
132132
}
133133
}
134134

src/build/resolveOpenAPI.ts

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,32 @@ export type APIParameter = {
4444
};
4545
};
4646

47+
type APIExample = {
48+
summary: string;
49+
value: any;
50+
};
51+
52+
type APIResponse = {
53+
description: string;
54+
status_code: string;
55+
content?: {
56+
content_type: string;
57+
schema: any;
58+
example?: APIExample;
59+
examples?: {[key: string]: APIExample};
60+
};
61+
};
62+
63+
type APIData = DeRefedOpenAPI['paths'][string][string];
64+
4765
export type API = {
4866
apiPath: string;
4967
bodyParameters: APIParameter[];
5068
method: string;
5169
name: string;
5270
pathParameters: APIParameter[];
5371
queryParameters: APIParameter[];
54-
responses: any;
72+
responses: APIResponse[];
5573
slug: string;
5674
bodyContentType?: string;
5775
descriptionMarkdown?: string;
@@ -154,7 +172,7 @@ async function apiCategoriesUncached(): Promise<APICategory[]> {
154172
return categories;
155173
}
156174

157-
function getBodyParameters(apiData): APIParameter[] {
175+
function getBodyParameters(apiData: APIData): APIParameter[] {
158176
const content = apiData.requestBody?.content;
159177
const contentType = content && Object.values(content)[0];
160178
const properties = contentType?.schema?.properties;
@@ -176,7 +194,7 @@ function getBodyParameters(apiData): APIParameter[] {
176194
}));
177195
}
178196

179-
function getBodyContentType(apiData): string | undefined {
197+
function getBodyContentType(apiData: APIData): string | undefined {
180198
const content = apiData.requestBody?.content;
181199
const types = content && Object.keys(content);
182200
if (!types?.length) {

src/components/alert.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
'use client';
22

3+
import {ReactNode} from 'react';
4+
35
type Props = {
4-
children?: any;
6+
children?: ReactNode;
57
level?: 'info' | 'warning' | 'danger' | 'success' | '';
68
title?: string;
79
};
@@ -11,7 +13,7 @@ export function Alert({title, children, level}: Props) {
1113
if (level) {
1214
className += ` alert-${level}`;
1315
}
14-
if (children.props && typeof children.props.children === 'string') {
16+
if (children && typeof children === 'string') {
1517
className += ' markdown-text-only';
1618
}
1719
return (

src/components/apiExamples.tsx

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,18 @@ import {Fragment, useState} from 'react';
99

1010
import {type API} from 'sentry-docs/build/resolveOpenAPI';
1111

12-
function Example(props) {
13-
const selectedTabView: number = props.selectedTabView;
14-
const api: API = props.api;
15-
const selectedResponse: number = props.selectedResponse;
12+
type ExampleProps = {
13+
api: API;
14+
selectedResponse: number;
15+
selectedTabView: number;
16+
};
1617

17-
let exampleJson;
18+
function Example({api, selectedTabView, selectedResponse}: ExampleProps) {
19+
let exampleJson: any;
1820
if (api.responses[selectedResponse].content?.examples) {
19-
exampleJson = Object.values(api.responses[selectedResponse].content?.examples).map(
20-
(e: any) => e.value
21-
)[0];
21+
exampleJson = Object.values(
22+
api.responses[selectedResponse].content?.examples ?? {}
23+
).map(e => e.value)[0];
2224
} else if (api.responses[selectedResponse].content?.example) {
2325
exampleJson = api.responses[selectedResponse].content?.example;
2426
}
@@ -43,7 +45,7 @@ function Example(props) {
4345
<code
4446
dangerouslySetInnerHTML={{
4547
__html: Prism.highlight(
46-
JSON.stringify(api.responses[selectedResponse].content.schema, null, 2),
48+
JSON.stringify(api.responses[selectedResponse].content?.schema, null, 2),
4749
Prism.languages.json,
4850
'json'
4951
),
@@ -54,7 +56,7 @@ function Example(props) {
5456
);
5557
}
5658

57-
const strFormat = str => {
59+
const strFormat = (str: string) => {
5860
const s = str.trim();
5961
if (s.endsWith('.')) {
6062
return s;

src/components/changelog/list.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,15 +61,16 @@ export default function Changelogs({
6161
});
6262

6363
// iterate over all posts and create a list of months & years
64-
const months = changelogs.reduce((allMonths: any, post: any) => {
65-
const date = new Date(post.publishedAt) as Date;
64+
const months = changelogs.reduce((allMonths, post) => {
65+
// if no date is set, use the epoch (simulate behavior before this refactor)
66+
const date = post.publishedAt ?? new Date(0);
6667
const year = date.getFullYear();
6768
const month = date.toLocaleString('default', {
6869
month: 'long',
6970
});
7071
const dateMonthYear = `${month} ${year}`;
7172
return [...new Set([...allMonths, dateMonthYear])];
72-
}, []);
73+
}, [] as string[]);
7374

7475
const monthsCopy = [...months];
7576

src/components/cliChecksumTableClient.tsx

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,16 @@ const ChecksumValue = styled.code`
77
white-space: nowrap;
88
`;
99

10+
export type Files = {
11+
checksums: {
12+
name: string;
13+
value: string;
14+
}[];
15+
name: string;
16+
};
17+
1018
type Props = {
11-
files: any[];
19+
files: Files[];
1220
version: string;
1321
};
1422

@@ -37,7 +45,7 @@ export function CliChecksumTableClient({version, files}: Props) {
3745
</td>
3846
<td style={{verticalAlign: 'middle', width: '100%'}}>
3947
<ChecksumValue>
40-
{`sha384-${file.checksums.find(c => c.name === 'sha256-hex').value}`}
48+
{`sha384-${file.checksums.find(c => c.name === 'sha256-hex')?.value}`}
4149
</ChecksumValue>
4250
</td>
4351
</tr>

src/components/codeKeywords.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,11 +68,11 @@ function runRegex(
6868
arr: ChildrenItem[],
6969
str: string,
7070
regex: RegExp,
71-
cb: (lastIndex: number, match: any[]) => React.ReactNode
71+
cb: (lastIndex: number, match: RegExpExecArray) => React.ReactNode
7272
): void {
7373
regex.lastIndex = 0;
7474

75-
let match;
75+
let match: RegExpExecArray | null;
7676
let lastIndex = 0;
7777
// eslint-disable-next-line no-cond-assign
7878
while ((match = regex.exec(str)) !== null) {

src/components/docPage.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import {ReactNode} from 'react';
22

33
import {getCurrentPlatformOrGuide} from 'sentry-docs/docTree';
44
import {serverContext} from 'sentry-docs/serverContext';
5+
import {FrontMatter} from 'sentry-docs/types';
56

67
import {Breadcrumbs} from './breadcrumbs';
78
import {CodeContextProvider} from './codeContext';
@@ -15,8 +16,8 @@ import {ServerSidebar} from './serverSidebar';
1516
import {TableOfContents} from './tableOfContents';
1617

1718
type Props = {
18-
children: any;
19-
frontMatter: any;
19+
children: ReactNode;
20+
frontMatter: Omit<FrontMatter, 'slug'>;
2021
notoc?: boolean;
2122
sidebar?: ReactNode;
2223
};

src/components/dynamicNav.tsx

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ type Node = {
1010
[key: string]: any;
1111
context: {
1212
[key: string]: any;
13-
sidebar_order?: number | null;
14-
sidebar_title?: string | null;
15-
title?: string | null;
13+
sidebar_order?: number;
14+
sidebar_title?: string;
15+
title?: string;
1616
};
1717
path: string;
1818
};
@@ -64,13 +64,17 @@ export const renderChildren = (
6464
({name, node}) =>
6565
node && !!node.context.title && name !== '' && exclude.indexOf(node.path) === -1
6666
),
67-
({node}) => node
67+
({node}) => node!
6868
).map(({node, children: nodeChildren}) => {
69+
// will not be null because of the filter above
70+
if (!node) {
71+
return null;
72+
}
6973
return (
7074
<SidebarLink
7175
to={node.path}
7276
key={node.path}
73-
title={node.context.sidebar_title || node.context.title}
77+
title={node.context.sidebar_title || node.context.title!}
7478
collapsed={depth >= showDepth}
7579
path={path}
7680
>

src/components/expandable.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
'use client';
22

3-
import {useState} from 'react';
3+
import {ReactNode, useState} from 'react';
44
import {ArrowDown} from 'react-feather';
55
import styled from '@emotion/styled';
66

77
type Props = {
8-
children: any;
8+
children: ReactNode;
99
title: string;
1010
};
1111

0 commit comments

Comments
 (0)