Skip to content

Commit

Permalink
chore!: remove @ts-ignore syntax [skip release] (#57)
Browse files Browse the repository at this point in the history
BREAKING CHANGE: removed @ts-ignore syntax for lint-markdown-ts-check
  • Loading branch information
dsanders11 authored May 7, 2024
1 parent 0cc09d7 commit 212d3cd
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 126 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ by adding `@nolint` to the info string.

`lint-roller-markdown-ts-check` is a command to type check JS/TS code blocks
in Markdown with `tsc`. Type checking can be disabled for specific code blocks
by adding `@ts-nocheck` to the info string, specific lines can be ignored
by adding `@ts-ignore=[<line1>,<line2>]` to the info string, and additional
by adding `@ts-nocheck` to the info string, specific lines can be ignored by
adding `@ts-expect-error=[<line1>,<line2>]` to the info string, and additional
globals can be defined with `@ts-type={name:type}`. The `Window` object can
be extended with more types using `@ts-window-type={name:type}`. When type
checking TypeScript blocks in the same Markdown file, global augmentation
Expand Down
49 changes: 11 additions & 38 deletions bin/lint-markdown-ts-check.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ async function typeCheckFiles(
'',
);

// Strip any @ts-expect-error/@ts-ignore comments we added
correctedOutput = correctedOutput.replace(/ \/\/ @ts-(?:expect-error|ignore)/g, '');
// Strip any @ts-expect-error comments we added
correctedOutput = correctedOutput.replace(/ \/\/ @ts-expect-error/g, '');

if (correctedOutput.trim()) {
for (const [filename, originalFilename] of filenameMapping.entries()) {
Expand Down Expand Up @@ -110,38 +110,16 @@ async function main(
?.match(/\B@ts-expect-error=\[([\d,]*)\]\B/)?.[1]
.split(',')
.map((line) => parseInt(line));
const tsIgnoreLines = codeBlock.meta
?.match(/\B@ts-ignore=\[([\d,]*)\]\B/)?.[1]
.split(',')
.map((line) => parseInt(line));
const tsTypeLines = codeBlock.meta ? parseDirectives('@ts-type', codeBlock.meta) : [];
const tsWindowTypeLines = codeBlock.meta
? parseDirectives('@ts-window-type', codeBlock.meta)
: [];

if (
tsNoCheck &&
(tsExpectErrorLines || tsIgnoreLines || tsTypeLines.length || tsWindowTypeLines.length)
) {
console.log(
`${filepath}:${line}:${
indent + 1
}: Code block has both @ts-nocheck and @ts-expect-error/@ts-ignore/@ts-type/@ts-window-type, they conflict`,
);
errors = true;
continue;
}

// There should be no overlap between @ts-expect-error and @ts-ignore
if (
tsExpectErrorLines &&
tsIgnoreLines &&
tsExpectErrorLines.some((line) => tsIgnoreLines.includes(line))
) {
if (tsNoCheck && (tsExpectErrorLines || tsTypeLines.length || tsWindowTypeLines.length)) {
console.log(
`${filepath}:${line}:${
indent + 1
}: Code block has both @ts-expect-error and @ts-ignore with same line number(s)`,
}: Code block has both @ts-nocheck and @ts-expect-error/@ts-type/@ts-window-type, they conflict`,
);
errors = true;
continue;
Expand All @@ -165,11 +143,11 @@ async function main(
const insertComment = (comment: string, line: number) => {
// Inserting additional lines will make the tsc output
// incorrect which would be a pain to manually adjust,
// and there is no @ts-ignore-line, so tack the comment
// on to the end of the previous line - looks ugly but
// we never have to see it since it's in a temp file.
// The first line of the file is an edge case where an
// insertion is necessary, so take that into account
// and there is no @ts-expect-error-line, so tack the
// comment on to the end of the previous line - looks
// ugly but we never have to see it since it's in a temp
// file. The first line of the file is an edge case where
// an insertion is necessary, so take that into account
if (line === 1) {
codeLines.unshift(comment);
insertedInitialLine = true;
Expand All @@ -186,15 +164,10 @@ async function main(
}
};

// Blocks can have @ts-ignore=[1,10,50] in their info string
// (1-based lines) to insert an "// @ts-ignore" comment before
// Blocks can have @ts-expect-error=[1,10,50] in their info string
// (1-based lines) to insert an "// @ts-expect-error" comment before
// specified lines, in order to ignore specific lines (like
// requires of extra modules) without skipping the whole block
for (const line of tsIgnoreLines ?? []) {
insertComment('// @ts-ignore', line);
}

// Blocks can also have @ts-expect-error
for (const line of tsExpectErrorLines ?? []) {
insertComment('// @ts-expect-error', line);
}
Expand Down
70 changes: 32 additions & 38 deletions tests/__snapshots__/lint-roller-markdown-ts-check.spec.ts.snap
Original file line number Diff line number Diff line change
@@ -1,92 +1,86 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`lint-roller-markdown-ts-check should type check code blocks 1`] = `
"ts-check.md:49:1: Code block has both @ts-nocheck and @ts-expect-error/@ts-ignore/@ts-type/@ts-window-type, they conflict
ts-check.md:55:1: Code block has both @ts-nocheck and @ts-expect-error/@ts-ignore/@ts-type/@ts-window-type, they conflict
[96mts-check.md[0m:[93m128[0m:[93m8[0m - [91merror[0m[90m TS2339: [0mProperty 'myAwesomeAPI' does not exist on type 'Window & typeof globalThis'.
"ts-check.md:37:1: Code block has both @ts-nocheck and @ts-expect-error/@ts-type/@ts-window-type, they conflict
ts-check.md:43:1: Code block has both @ts-nocheck and @ts-expect-error/@ts-type/@ts-window-type, they conflict
[96mts-check.md[0m:[93m109[0m:[93m5[0m - [91merror[0m[90m TS2304: [0mCannot find name 'a'.
128 window.myAwesomeAPI()
   ~~~~~~~~~~~~
ts-check.md:154:5 - error TS2304: Cannot find name 'a'.
154 if (a > b) {
109 if (a > b) {
   ~
[96mts-check.md[0m:[93m154[0m:[93m9[0m - [91merror[0m[90m TS2304: [0mCannot find name 'b'.
[96mts-check.md[0m:[93m109[0m:[93m9[0m - [91merror[0m[90m TS2304: [0mCannot find name 'b'.
[7m154[0m if (a > b) {
[7m109[0m if (a > b) {
   ~
[96mts-check.md[0m:[93m157[0m:[93m28[0m - [91merror[0m[90m TS2304: [0mCannot find name 'a'.
[96mts-check.md[0m:[93m112[0m:[93m28[0m - [91merror[0m[90m TS2304: [0mCannot find name 'a'.
[7m157[0m console.log(\`not true: \${a} < \${b}\`)
[7m112[0m console.log(\`not true: \${a} < \${b}\`)
   ~
[96mts-check.md[0m:[93m157[0m:[93m35[0m - [91merror[0m[90m TS2304: [0mCannot find name 'b'.
[96mts-check.md[0m:[93m112[0m:[93m35[0m - [91merror[0m[90m TS2304: [0mCannot find name 'b'.
[7m157[0m console.log(\`not true: \${a} < \${b}\`)
[7m112[0m console.log(\`not true: \${a} < \${b}\`)
   ~
[96mts-check.md[0m:[93m160[0m:[93m8[0m - [91merror[0m[90m TS2339: [0mProperty 'AwesomeAPI' does not exist on type 'Window & typeof globalThis'.
[96mts-check.md[0m:[93m115[0m:[93m8[0m - [91merror[0m[90m TS2339: [0mProperty 'AwesomeAPI' does not exist on type 'Window & typeof globalThis'.
[7m160[0m window.AwesomeAPI.bar('baz')
[7m115[0m window.AwesomeAPI.bar('baz')
   ~~~~~~~~~~
[96mts-check.md[0m:[93m174[0m:[93m15[0m - [91merror[0m[90m TS2339: [0mProperty 'wrongAPI' does not exist on type 'typeof BrowserWindow'.
[96mts-check.md[0m:[93m129[0m:[93m15[0m - [91merror[0m[90m TS2339: [0mProperty 'wrongAPI' does not exist on type 'typeof BrowserWindow'.
[7m174[0m BrowserWindow.wrongAPI('foo')
[7m129[0m BrowserWindow.wrongAPI('foo')
   ~~~~~~~~
[96mts-check.md[0m:[93m180[0m:[93m15[0m - [91merror[0m[90m TS2339: [0mProperty 'wrongAPI' does not exist on type 'typeof BrowserWindow'.
[96mts-check.md[0m:[93m135[0m:[93m15[0m - [91merror[0m[90m TS2339: [0mProperty 'wrongAPI' does not exist on type 'typeof BrowserWindow'.
[7m180[0m BrowserWindow.wrongAPI('foo')
[7m135[0m BrowserWindow.wrongAPI('foo')
   ~~~~~~~~
[96mts-check.md[0m:[93m212[0m:[93m8[0m - [91merror[0m[90m TS2339: [0mProperty 'AwesomeAPI' does not exist on type 'Window & typeof globalThis'.
[96mts-check.md[0m:[93m167[0m:[93m8[0m - [91merror[0m[90m TS2339: [0mProperty 'AwesomeAPI' does not exist on type 'Window & typeof globalThis'.
[7m212[0m window.AwesomeAPI.foo(42)
[7m167[0m window.AwesomeAPI.foo(42)
   ~~~~~~~~~~
ts-check.md:4:9 - error TS2339: Property 'foo' does not exist on type 'Console'.
4 console.foo('whoops')
   ~~~
[96mts-check.md[0m:[93m66[0m:[93m15[0m - [91merror[0m[90m TS2339: [0mProperty 'wrongAPI' does not exist on type 'typeof BrowserWindow'.
[96mts-check.md[0m:[93m54[0m:[93m15[0m - [91merror[0m[90m TS2339: [0mProperty 'wrongAPI' does not exist on type 'typeof BrowserWindow'.
[7m66[0m BrowserWindow.wrongAPI('foo')
[7m54[0m BrowserWindow.wrongAPI('foo')
   ~~~~~~~~
[96mts-check.md[0m:[93m72[0m:[93m15[0m - [91merror[0m[90m TS2339: [0mProperty 'wrongAPI' does not exist on type 'typeof BrowserWindow'.
[96mts-check.md[0m:[93m60[0m:[93m15[0m - [91merror[0m[90m TS2339: [0mProperty 'wrongAPI' does not exist on type 'typeof BrowserWindow'.
[7m72[0m BrowserWindow.wrongAPI('foo')
[7m60[0m BrowserWindow.wrongAPI('foo')
   ~~~~~~~~
ts-check.md:8:9 - error TS2339: Property 'foo' does not exist on type 'Console'.
8 console.foo('whoops')
   ~~~
[96mts-check.md[0m:[93m95[0m:[93m8[0m - [91merror[0m[90m TS2339: [0mProperty 'myAwesomeAPI' does not exist on type 'Window & typeof globalThis'.
[96mts-check.md[0m:[93m83[0m:[93m8[0m - [91merror[0m[90m TS2339: [0mProperty 'myAwesomeAPI' does not exist on type 'Window & typeof globalThis'.
[7m95[0m window.myAwesomeAPI()
[7m83[0m window.myAwesomeAPI()
   ~~~~~~~~~~~~
Found 14 errors in 10 files.
Found 13 errors in 9 files.
Errors Files
1 ts-check.md:128
5 ts-check.md:154
1 ts-check.md:174
1 ts-check.md:180
1 ts-check.md:212
5 ts-check.md:109
1 ts-check.md:129
1 ts-check.md:135
1 ts-check.md:167
1 ts-check.md:4
1 ts-check.md[90m:66[0m
1 ts-check.md[90m:72[0m
1 ts-check.md[90m:54[0m
1 ts-check.md[90m:60[0m
1 ts-check.md:8
1 ts-check.md[90m:95[0m
1 ts-check.md[90m:83[0m
"
`;
49 changes: 2 additions & 47 deletions tests/fixtures/ts-check.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,6 @@ console.bar('whoops')

These blocks suppress specific lines (1-based)

```js @ts-ignore=[3]
console.log('test')

window.myAwesomeAPI()
```

```js title='main.js' @ts-ignore=[3]
console.log('test')

window.myAwesomeAPI()
```

```js @ts-expect-error=[3]
console.log('test')

Expand All @@ -46,13 +34,13 @@ window.myAwesomeAPI()

These blocks have conflicting options

```js @ts-nocheck @ts-ignore=[3]
```js @ts-nocheck @ts-expect-error=[3]
console.log('test')

window.myAwesomeAPI()
```

```js @ts-nocheck title='main.js' @ts-ignore=[3]
```js @ts-nocheck title='main.js' @ts-expect-error=[3]
console.log('test')

window.myAwesomeAPI()
Expand All @@ -72,39 +60,6 @@ const { BrowserWindow } = require('electron')
BrowserWindow.wrongAPI('foo')
```

These blocks have multiple @ts-ignore lines

```js @ts-ignore=[3,5]
console.log('test')

window.myAwesomeAPI()

window.myOtherAwesomeAPI()
```

```js @ts-ignore=[1,4]
window.myAwesomeAPI()

console.log('test')
window.myOtherAwesomeAPI()
```

This confirms @ts-ignore output is stripped

```js @ts-ignore=[2]
window.myAwesomeAPI()
window.myOtherAwesomeAPI()
```

This confirms @ts-ignore works if the previous line is a comment

```js @ts-ignore=[4]
console.log('test')

// This is a comment
window.myAwesomeAPI()
```

These blocks have multiple @ts-expect-error lines

```js @ts-expect-error=[3,5]
Expand Down
7 changes: 6 additions & 1 deletion tests/lint-roller-markdown-ts-check.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,12 @@ function runLintMarkdownTsCheck(...args: string[]) {
return cp.spawnSync(
process.execPath,
[path.resolve(__dirname, '../dist/bin/lint-markdown-ts-check.js'), ...args],
{ stdio: 'pipe', encoding: 'utf-8', cwd: FIXTURES_DIR },
{
stdio: 'pipe',
encoding: 'utf-8',
cwd: FIXTURES_DIR,
env: { NODE_OPTIONS: '--no-deprecation' },
},
);
}

Expand Down

0 comments on commit 212d3cd

Please sign in to comment.