Skip to content

Commit d8cb8c5

Browse files
leroydevtimneutkenskodiakhq[bot]
authoredOct 30, 2021
Fixed "Expected jsx identifier" error on TypeScript generics & angle bracket type assertions in .ts files (#30619)
* Fixed "Expected jsx identifier" error on TypeScript generics & angle bracket type assertions * Ignore error from node-notifier on M1 * Add tests Co-authored-by: Tim Neutkens <tim@timneutkens.nl> Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
1 parent d7d1a05 commit d8cb8c5

File tree

7 files changed

+46
-10
lines changed

7 files changed

+46
-10
lines changed
 

‎packages/next/build/webpack/loaders/next-swc-loader.js

+7-5
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ const nextDistPath =
3333
/(next[\\/]dist[\\/]shared[\\/]lib)|(next[\\/]dist[\\/]client)|(next[\\/]dist[\\/]pages)/
3434

3535
function getSWCOptions({
36-
isTypeScript,
36+
filename,
3737
isServer,
3838
development,
3939
isPageFile,
@@ -42,11 +42,15 @@ function getSWCOptions({
4242
hasReactRefresh,
4343
isCommonJS,
4444
}) {
45+
const isTSFile = filename.endsWith('.ts')
46+
const isTypeScript = isTSFile || filename.endsWith('.tsx')
47+
4548
const jsc = {
4649
parser: {
4750
syntax: isTypeScript ? 'typescript' : 'ecmascript',
4851
dynamicImport: true,
49-
[isTypeScript ? 'tsx' : 'jsx']: true,
52+
// Exclude regular TypeScript files from React transformation to prevent e.g. generic parameters and angle-bracket type assertion from being interpreted as JSX tags.
53+
[isTypeScript ? 'tsx' : 'jsx']: isTSFile ? false : true,
5054
},
5155

5256
transform: {
@@ -119,8 +123,6 @@ async function loaderTransform(parentTrace, source, inputSourceMap) {
119123
// Make the loader async
120124
const filename = this.resourcePath
121125

122-
const isTypeScript = filename.endsWith('.ts') || filename.endsWith('.tsx')
123-
124126
let loaderOptions = getOptions(this) || {}
125127

126128
const { isServer, pagesDir, hasReactRefresh } = loaderOptions
@@ -131,7 +133,7 @@ async function loaderTransform(parentTrace, source, inputSourceMap) {
131133

132134
const swcOptions = getSWCOptions({
133135
pagesDir,
134-
isTypeScript,
136+
filename,
135137
isServer: isServer,
136138
isPageFile,
137139
development: this.mode === 'development',

‎packages/next/taskfile.js

+9-5
Original file line numberDiff line numberDiff line change
@@ -1172,9 +1172,13 @@ export async function release(task) {
11721172

11731173
// notification helper
11741174
function notify(msg) {
1175-
return notifier.notify({
1176-
title: '▲ Next',
1177-
message: msg,
1178-
icon: false,
1179-
})
1175+
try {
1176+
notifier.notify({
1177+
title: '▲ Next',
1178+
message: msg,
1179+
icon: false,
1180+
})
1181+
} catch (err) {
1182+
// notifier can fail on M1 machines
1183+
}
11801184
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// eslint-disable-next-line
2+
const myVar = <any>'test'
3+
4+
export default myVar
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
class MyClass<T> {
2+
value: T
3+
constructor(value: T) {
4+
this.value = value
5+
}
6+
}
7+
8+
const instance = new MyClass<string>('Hello World from Generic')
9+
10+
export default instance.value
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import value from '../components/angle-bracket-type-assertions'
2+
3+
export default () => <div id="value">{value}</div>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import value from '../components/generics'
2+
3+
export default () => <div id="value">{value}</div>

‎test/integration/typescript/test/index.test.js

+10
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,16 @@ describe('TypeScript Features', () => {
4949
expect($('#cookies').text()).toBe('{}')
5050
})
5151

52+
it('should render the generics page', async () => {
53+
const $ = await get$('/generics')
54+
expect($('#value').text()).toBe('Hello World from Generic')
55+
})
56+
57+
it('should render the angle bracket type assertions page', async () => {
58+
const $ = await get$('/angle-bracket-type-assertions')
59+
expect($('#value').text()).toBe('test')
60+
})
61+
5262
it('should resolve files in correct order', async () => {
5363
const $ = await get$('/hello')
5464
expect($('#imported-value').text()).toBe('OK')

0 commit comments

Comments
 (0)
Please sign in to comment.