Skip to content

fix(typescript): prevent type assertions with array brackets or ? from being treated as HTML tags#4381

Open
KJyang-0114 wants to merge 1 commit intohighlightjs:mainfrom
KJyang-0114:fix/typescript-type-assertion-array-brackets
Open

fix(typescript): prevent type assertions with array brackets or ? from being treated as HTML tags#4381
KJyang-0114 wants to merge 1 commit intohighlightjs:mainfrom
KJyang-0114:fix/typescript-type-assertion-array-brackets

Conversation

@KJyang-0114
Copy link
Copy Markdown

Summary

Fixes #4301 - <string[]> (and <string?>) break TypeScript highlighting.

Root Cause

The isTrulyOpeningTag function in src/languages/javascript.js checks various patterns to determine whether a < followed by word characters is an HTML/XML tag or a TypeScript/JavaScript type expression. It handles < (nested generics) and , (generic parameters), but was missing checks for:

  • [ — TypeScript type assertions with array notation like <string[]>
  • ? — TypeScript non-null assertions like <string?>

When encountering <string[]>, nextChar after the tag name <string is [. Since this wasn't recognized, the function proceeded to look for a closing </string> tag, treating everything after the > as HTML text until it found one.

Fix

Added two new conditions to the isTrulyOpeningTag ignoreMatch check:

  1. nextChar === "[" — catches <string[]>, <number[]>, <T[]> directly
  2. nextChar === "?" — catches <string?>, <T?> directly

Also added afterMatch regex checks for whitespace variants:

  • /^\s*\[\]/ — catches <string []>
  • /^\s+\?/ — catches <string ?>

Test Evidence

Before fix:

INPUT: const myVar = <string[]>this.service.invoke();
OUTPUT: <span class="language-xml">&lt;string[]&gt;this.service.invoke();</span>  ← BROKEN

After fix:

INPUT: const myVar = <string[]>this.service.invoke();
OUTPUT: &lt;<span class="hljs-built_in">string</span>[]&gt;<span class="hljs-variable language_">this</span>.<span class="hljs-property">service</span>.<span class="hljs-title function_">invoke</span>();

JSX constructs like <Component /> and real HTML like <div> continue to be correctly highlighted as XML.

Validation

  • All 1570 existing tests pass (0 new failures)
  • Manually verified: <string[]>, <number[]>, <T[]>, <string?>, <string []> all no longer break highlighting
  • JSX: <div>, <Component />, <MyComponent prop=\"val\" /> still correctly highlighted

Risk & Rollback

  • Risk: Low — only affects the tag-detection logic in isTrulyOpeningTag, which already had similar ignore patterns for < and ,
  • Rollback: Single file (src/languages/javascript.js) revert to previous state
  • Affected languages: TypeScript and JavaScript (which extends the same base)

…treated as HTML tags

Fixes highlightjs#4301 - `<string[]>` breaks highlighting in TypeScript

Root cause: The `isTrulyOpeningTag` function only checked for `<` and `,`
as indicators of non-HTML syntax. When encountering `<string[]>` or
`<string?>`, the `nextChar` after the tag name is `[` or `?`, which
were not recognized as TypeScript type assertion patterns.

Fix: Added `nextChar === "["` and `nextChar === "?"` to the
ignoreMatch conditions, and added `afterMatch` checks for cases with
intervening whitespace (e.g. `<string []>`).

Verified:
- All 1570 existing tests pass
- `<string[]>` no longer treated as HTML tag
- `<string?>` no longer treated as HTML tag
- JSX constructs like `<Component />` still correctly highlighted
- Regular HTML like `<div>` still correctly highlighted
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

(typescript) <string[]> breaks highlighting

1 participant