Skip to content

Commit 7597c92

Browse files
heiskrCopilot
andauthored
Remove any types from 16 files (#59772)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 72792a7 commit 7597c92

17 files changed

Lines changed: 178 additions & 192 deletions

File tree

eslint.config.ts

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,6 @@ export default [
193193
'src/article-api/scripts/generate-api-docs.ts',
194194
'src/article-api/transformers/audit-logs-transformer.ts',
195195
'src/article-api/transformers/rest-transformer.ts',
196-
'src/assets/scripts/validate-asset-images.ts',
197196
'src/automated-pipelines/tests/rendering.ts',
198197
'src/codeql-cli/scripts/convert-markdown-for-docs.ts',
199198
'src/content-linter/lib/helpers/get-lintable-yml.ts',
@@ -226,27 +225,18 @@ export default [
226225
'src/content-render/scripts/move-content.ts',
227226
'src/content-render/tests/data.ts',
228227
'src/content-render/tests/link-error-line-numbers.ts',
229-
'src/content-render/unified/alerts.ts',
230228
'src/content-render/unified/annotate.ts',
231-
'src/content-render/unified/code-header.ts',
232-
'src/content-render/unified/copilot-prompt.ts',
233229
'src/content-render/unified/index.ts',
234230
'src/content-render/unified/module-types.d.ts',
235-
'src/content-render/unified/rewrite-empty-table-rows.ts',
236-
'src/content-render/unified/rewrite-for-rowheaders.ts',
237231
'src/content-render/unified/rewrite-local-links.ts',
238232
'src/data-directory/lib/data-directory.ts',
239-
'src/data-directory/lib/data-schemas/features.ts',
240233
'src/data-directory/lib/data-schemas/learning-tracks.ts',
241234
'src/data-directory/lib/get-data.ts',
242235
'src/data-directory/scripts/find-orphaned-features/find.ts',
243-
'src/dev-toc/generate.ts',
244236
'src/early-access/scripts/migrate-early-access-product.ts',
245237
'src/early-access/scripts/what-docs-early-access-branch.ts',
246238
'src/fixtures/tests/categories-and-subcategory.ts',
247-
'src/fixtures/tests/glossary.ts',
248239
'src/fixtures/tests/guides.ts',
249-
'src/fixtures/tests/homepage.ts',
250240
'src/fixtures/tests/liquid.ts',
251241
'src/fixtures/tests/markdown.ts',
252242
'src/fixtures/tests/translations.ts',
@@ -267,10 +257,7 @@ export default [
267257
'src/ghes-releases/scripts/deprecate/update-content.ts',
268258
'src/github-apps/lib/index.ts',
269259
'src/graphql/lib/index.ts',
270-
'src/graphql/pages/breaking-changes.tsx',
271-
'src/graphql/pages/changelog.tsx',
272260
'src/graphql/pages/reference.tsx',
273-
'src/graphql/pages/schema-previews.tsx',
274261
'src/graphql/scripts/build-changelog.ts',
275262
'src/graphql/scripts/utils/process-previews.ts',
276263
'src/graphql/scripts/utils/process-schemas.ts',
@@ -285,7 +272,6 @@ export default [
285272
'src/landings/pages/home.tsx',
286273
'src/landings/pages/product.tsx',
287274
'src/languages/lib/correct-translation-content.ts',
288-
'src/languages/lib/get-alert-titles.ts',
289275
'src/languages/lib/render-with-fallback.ts',
290276
'src/languages/lib/translation-utils.ts',
291277
'src/learning-track/lib/process-learning-tracks.ts',
@@ -324,12 +310,10 @@ export default [
324310
'src/search/scripts/index/index-cli.ts',
325311
'src/search/scripts/index/utils/indexing-elasticsearch-utils.ts',
326312
'src/search/scripts/scrape/lib/parse-page-sections-into-records.ts',
327-
'src/search/tests/topics.ts',
328313
'src/tests/helpers/check-url.ts',
329314
'src/tests/helpers/e2etest.ts',
330315
'src/tests/scripts/copy-fixture-data.ts',
331316
'src/tests/vitest.setup.ts',
332-
'src/tools/components/Picker.tsx',
333317
'src/types/github__markdownlint-github.d.ts',
334318
'src/types/markdownlint-lib-rules.d.ts',
335319
'src/types/markdownlint-rule-helpers.d.ts',

src/assets/scripts/validate-asset-images.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,8 @@ async function checkFile(filePath: string) {
115115
}
116116
try {
117117
checkSVGContent(content)
118-
} catch (error: any) {
119-
return [CRITICAL, filePath, error.message]
118+
} catch (error: unknown) {
119+
return [CRITICAL, filePath, error instanceof Error ? error.message : String(error)]
120120
}
121121
} else if (EXPECT[ext]) {
122122
const fileType = await fileTypeFromFile(filePath)

src/content-render/unified/alerts.ts

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ Custom "Alerts", based on similar filter/styling in the monolith code.
55
import { visit } from 'unist-util-visit'
66
import { h } from 'hastscript'
77
import octicons from '@primer/octicons'
8-
import type { Element } from 'hast'
8+
import type { Element, Root, ElementContent } from 'hast'
99

1010
interface AlertType {
1111
icon: string
@@ -22,56 +22,56 @@ const alertTypes: Record<string, AlertType> = {
2222

2323
// Must contain one of [!NOTE], [!IMPORTANT], ...
2424
const ALERT_REGEXP = new RegExp(`\\[!(${Object.keys(alertTypes).join('|')})\\]`, 'gi')
25-
26-
// Using any due to conflicting unist/hast type definitions between dependencies
27-
const matcher = (node: any): boolean =>
28-
node.type === 'element' &&
29-
node.tagName === 'blockquote' &&
30-
ALERT_REGEXP.test(JSON.stringify(node.children))
25+
// Non-global version for .test() and .match() to avoid stateful lastIndex issues
26+
const ALERT_REGEXP_DETECT = new RegExp(`\\[!(${Object.keys(alertTypes).join('|')})\\]`, 'i')
3127

3228
export default function alerts({ alertTitles = {} }: { alertTitles?: Record<string, string> }) {
33-
// Using any due to conflicting unist/hast type definitions between dependencies
34-
return (tree: any) => {
35-
// Using any due to conflicting unist/hast type definitions between dependencies
36-
visit(tree, matcher, (node: any) => {
37-
const key = getAlertKey(node)
29+
return (tree: Root) => {
30+
visit(tree, 'element', (node) => {
31+
const el = node as Element
32+
if (el.tagName !== 'blockquote' || !ALERT_REGEXP_DETECT.test(JSON.stringify(el.children)))
33+
return
34+
const key = getAlertKey(el)
3835
if (!(key in alertTypes)) {
3936
console.warn(
4037
`Alert key '${key}' should be all uppercase (change it to '${key.toUpperCase()}')`,
4138
)
4239
}
43-
const alertType = alertTypes[getAlertKey(node).toUpperCase()]
44-
node.tagName = 'div'
45-
node.properties.className = `ghd-alert ghd-alert-${alertType.color}`
46-
node.properties.dataContainer = 'alert'
47-
node.children = [
40+
const alertType = alertTypes[getAlertKey(el).toUpperCase()]
41+
el.tagName = 'div'
42+
el.properties.className = `ghd-alert ghd-alert-${alertType.color}`
43+
el.properties.dataContainer = 'alert'
44+
el.children = [
4845
h(
4946
'p',
5047
{ className: 'ghd-alert-title' },
5148
getOcticonSVG(alertType.icon),
5249
alertTitles[key] || '',
5350
),
54-
...removeAlertSyntax(node.children),
51+
...removeAlertSyntax(el.children),
5552
]
5653
})
5754
}
5855
}
5956

6057
function getAlertKey(node: Element): string {
6158
const body = JSON.stringify(node.children)
62-
const matches = body.match(ALERT_REGEXP)
59+
const matches = body.match(ALERT_REGEXP_DETECT)
6360
return matches![0].slice(2, -1)
6461
}
6562

66-
// Using any to handle both array and object node types recursively
67-
function removeAlertSyntax(node: any): any {
63+
function removeAlertSyntax(node: ElementContent[]): ElementContent[]
64+
function removeAlertSyntax(node: ElementContent): ElementContent
65+
function removeAlertSyntax(
66+
node: ElementContent | ElementContent[],
67+
): ElementContent | ElementContent[] {
6868
if (Array.isArray(node)) {
69-
return node.map(removeAlertSyntax)
69+
return node.map((n) => removeAlertSyntax(n))
7070
}
71-
if (node.children) {
72-
node.children = node.children.map(removeAlertSyntax)
71+
if ('children' in node) {
72+
node.children = node.children.map((n) => removeAlertSyntax(n)) as typeof node.children
7373
}
74-
if (node.value) {
74+
if ('value' in node) {
7575
node.value = node.value.replace(ALERT_REGEXP, '')
7676
}
7777
return node

src/content-render/unified/code-header.ts

Lines changed: 24 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -13,44 +13,40 @@ import { fromParse5 } from 'hast-util-from-parse5'
1313
import murmur from 'imurmurhash'
1414
import { getPrompt } from './copilot-prompt'
1515
import { generatePromptId } from '../lib/prompt-id'
16-
import type { Element } from 'hast'
16+
import type { Element, Root } from 'hast'
1717

1818
interface LanguageConfig {
1919
name: string
20-
// Using any for language properties that can vary (aliases, extensions, etc.)
21-
[key: string]: any
20+
[key: string]: string | string[] | boolean | undefined
2221
}
2322

2423
type Languages = Record<string, LanguageConfig>
2524

2625
const languages = yaml.load(fs.readFileSync('./data/code-languages.yml', 'utf8')) as Languages
2726

28-
// Using any due to conflicting unist/hast type definitions between dependencies
29-
const matcher = (node: any): boolean =>
30-
node.type === 'element' &&
31-
node.tagName === 'pre' &&
32-
// For now, limit to ones with the copy or prompt meta,
33-
// but we may enable for all examples later.
34-
(getPreMeta(node).copy || getPreMeta(node).prompt) &&
35-
// Don't add this header for annotated examples.
36-
!getPreMeta(node).annotate
37-
3827
export default function codeHeader() {
39-
// Using any due to conflicting unist/hast type definitions between dependencies
40-
return (tree: any) => {
41-
// Using any due to conflicting unist/hast type definitions between dependencies
42-
visit(tree, matcher, (node: any, index: number | undefined, parent: any) => {
43-
if (index !== undefined && parent) {
44-
parent.children[index] = wrapCodeExample(node, tree)
28+
return (tree: Root) => {
29+
visit(tree, 'element', (node, index, parent) => {
30+
const el = node as Element
31+
if (
32+
el.tagName !== 'pre' ||
33+
!(getPreMeta(el).copy || getPreMeta(el).prompt) ||
34+
getPreMeta(el).annotate
35+
)
36+
return
37+
if (index !== undefined && parent && 'children' in parent) {
38+
;(parent as Element).children[index] = wrapCodeExample(el, tree)
4539
}
4640
})
4741
}
4842
}
4943

50-
// Using any due to conflicting unist/hast type definitions between dependencies
51-
function wrapCodeExample(node: any, tree: any): Element {
52-
const lang: string = node.children[0].properties.className?.[0].replace('language-', '')
53-
const code: string = node.children[0].children[0].value
44+
function wrapCodeExample(node: Element, tree: Root): Element {
45+
const codeChild = node.children[0] as Element
46+
const classNames = codeChild.properties.className as string[] | undefined
47+
const lang: string = classNames?.[0]?.replace('language-', '') ?? ''
48+
const textNode = codeChild.children[0] as { value: string }
49+
const code: string = textNode.value
5450

5551
const subnav = null // getSubnav() lives in annotate.ts, not needed for normal code blocks
5652
const hasPrompt: boolean = Boolean(getPreMeta(node).prompt)
@@ -120,16 +116,14 @@ export function header(
120116
function btnIcon(): Element {
121117
const btnIconHtml: string = octicons.copy.toSVG()
122118
const btnIconAst = parse(String(btnIconHtml), { sourceCodeLocationInfo: true })
123-
// Using any because fromParse5 expects VFile but we only have a string
124-
// This is safe because parse5 only needs the string content
125-
const btnIconElement = fromParse5(btnIconAst, { file: btnIconHtml as any })
119+
const btnIconElement = fromParse5(btnIconAst)
126120
return btnIconElement as Element
127121
}
128122

129-
// Using any due to conflicting unist/hast type definitions between dependencies
130-
// node can be various mdast/hast node types, return value contains meta properties from code blocks
131-
export function getPreMeta(node: any): Record<string, any> {
123+
// node can be various hast element types, return value contains meta properties from code blocks
124+
export function getPreMeta(node: Element): Record<string, unknown> {
132125
// Here's why this monstrosity works:
133126
// https://github.com/syntax-tree/mdast-util-to-hast/blob/c87cd606731c88a27dbce4bfeaab913a9589bf83/lib/handlers/code.js#L40-L42
134-
return node.children[0]?.data?.meta || {}
127+
const firstChild = node.children[0] as Element | undefined
128+
return (firstChild?.data as Record<string, Record<string, unknown>> | undefined)?.meta || {}
135129
}

src/content-render/unified/copilot-prompt.ts

Lines changed: 22 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,13 @@ import { parse } from 'parse5'
99
import { fromParse5 } from 'hast-util-from-parse5'
1010
import { getPreMeta } from './code-header'
1111
import { generatePromptId } from '../lib/prompt-id'
12+
import type { Element, Root } from 'hast'
1213

13-
// node and tree are hast/unist AST nodes without proper TypeScript definitions
14-
// Returns an object with the prompt button element and the full prompt content
1514
export function getPrompt(
16-
node: any,
17-
tree: any,
15+
node: Element,
16+
tree: Root,
1817
code: string,
19-
): { element: any; promptContent: string } | null {
18+
): { element: Element; promptContent: string } | null {
2019
const hasPrompt = Boolean(getPreMeta(node).prompt)
2120
if (!hasPrompt) return null
2221

@@ -40,11 +39,9 @@ export function getPrompt(
4039
return { element, promptContent }
4140
}
4241

43-
// Using any because node and tree are hast/unist AST nodes without proper TypeScript definitions
44-
// node is the current code block element, tree is used to find referenced code blocks
4542
function buildPromptData(
46-
node: any,
47-
tree: any,
43+
node: Element,
44+
tree: Root,
4845
code: string,
4946
): { promptContent: string; ariaLabel: string } {
5047
// Find a ref meta in the format 'ref=<id>'
@@ -56,14 +53,18 @@ function buildPromptData(
5653
}
5754

5855
// If the 'ref=<id>' meta is found, find a matching code block to include as context in the prompt link.
59-
const matchingCodeEl = findMatchingCode(ref, tree)
56+
const matchingCodeEl = findMatchingCode(ref as string, tree)
6057
if (!matchingCodeEl) {
6158
console.warn(`Can't find referenced code block with id=${ref}`)
6259
return promptOnly(code)
6360
}
64-
// Using any to access children property on untyped hast element node
6561
// AST structure: element -> code -> text node with value property
66-
const matchingCode = (matchingCodeEl as any)?.children[0].children[0].value || null
62+
const codeChild = matchingCodeEl.children[0] as Element | undefined
63+
const textNode = codeChild?.children[0] as { value?: string } | undefined
64+
const matchingCode = textNode?.value || null
65+
if (!matchingCode) {
66+
return promptOnly(code)
67+
}
6768
return promptAndContext(code, matchingCode)
6869
}
6970

@@ -84,21 +85,17 @@ function promptAndContext(
8485
}
8586
}
8687

87-
// Using any because tree and node are hast/unist AST nodes without proper TypeScript definitions
88-
// Searches the AST tree for a code block with matching id in meta
89-
function findMatchingCode(ref: string, tree: any): any {
90-
return find(tree, (node: any) => {
91-
// Using any to access tagName property on untyped hast element node
92-
return node.type === 'element' && (node as any).tagName === 'pre' && getPreMeta(node).id === ref
93-
})
88+
function findMatchingCode(ref: string, tree: Root): Element | undefined {
89+
return find<Element>(tree, ((node: { type: string; tagName?: string }) => {
90+
return (
91+
node.type === 'element' && node.tagName === 'pre' && getPreMeta(node as Element).id === ref
92+
)
93+
}) as Parameters<typeof find>[1])
9494
}
9595

96-
// Returns a hast element node for the Copilot icon
97-
// Using any return type because fromParse5 returns untyped hast nodes
98-
function copilotIcon(): any {
96+
function copilotIcon(): Element {
9997
const copilotIconHtml = octicons.copilot.toSVG()
10098
const copilotIconAst = parse(String(copilotIconHtml), { sourceCodeLocationInfo: true })
101-
// Using any because fromParse5 expects VFile but we only have a string
102-
const copilotIconElement = fromParse5(copilotIconAst, { file: copilotIconHtml as any })
103-
return copilotIconElement
99+
const copilotIconElement = fromParse5(copilotIconAst)
100+
return copilotIconElement as Element
104101
}

src/content-render/unified/rewrite-empty-table-rows.ts

Lines changed: 19 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { visit, SKIP } from 'unist-util-visit'
2+
import type { Element, Root } from 'hast'
23

34
/**
45
* Where it can mutate the AST to swap from:
@@ -49,31 +50,23 @@ import { visit, SKIP } from 'unist-util-visit'
4950
* isn't the same all the way down. But Unified will still parse it.
5051
* */
5152

52-
// node is a hast element node without proper TypeScript definitions
53-
function matcher(node: any): boolean {
54-
return node.type === 'element' && node.tagName === 'tr'
55-
}
56-
57-
// node, parent, and grandChild are hast element nodes without proper TypeScript definitions
58-
function visitor(
59-
node: any,
60-
index: number | undefined,
61-
parent: any,
62-
): [typeof SKIP, number] | undefined {
63-
if (
64-
node.children.every(
65-
(grandChild: any) =>
66-
grandChild.type === 'element' && grandChild.tagName === 'td' && !grandChild.children.length,
67-
)
68-
) {
69-
if (index !== undefined) {
70-
parent.children.splice(index, 1)
71-
return [SKIP, index]
72-
}
73-
}
74-
}
75-
76-
// tree is a hast root node without proper TypeScript definitions
7753
export default function rewriteEmptyTableRows() {
78-
return (tree: any) => visit(tree, matcher, visitor)
54+
return (tree: Root) =>
55+
visit(tree, 'element', (node, index, parent) => {
56+
const el = node as Element
57+
if (el.tagName !== 'tr') return
58+
if (
59+
el.children.every(
60+
(grandChild) =>
61+
grandChild.type === 'element' &&
62+
grandChild.tagName === 'td' &&
63+
!grandChild.children.length,
64+
)
65+
) {
66+
if (index !== undefined && parent) {
67+
parent.children.splice(index, 1)
68+
return [SKIP, index] as const
69+
}
70+
}
71+
})
7972
}

0 commit comments

Comments
 (0)