Skip to content

Commit

Permalink
Fixed "Expected jsx identifier" error on TypeScript generics & angle …
Browse files Browse the repository at this point in the history
…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>
  • Loading branch information
3 people committed Oct 30, 2021
1 parent d7d1a05 commit d8cb8c5
Show file tree
Hide file tree
Showing 7 changed files with 46 additions and 10 deletions.
12 changes: 7 additions & 5 deletions packages/next/build/webpack/loaders/next-swc-loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ const nextDistPath =
/(next[\\/]dist[\\/]shared[\\/]lib)|(next[\\/]dist[\\/]client)|(next[\\/]dist[\\/]pages)/

function getSWCOptions({
isTypeScript,
filename,
isServer,
development,
isPageFile,
Expand All @@ -42,11 +42,15 @@ function getSWCOptions({
hasReactRefresh,
isCommonJS,
}) {
const isTSFile = filename.endsWith('.ts')
const isTypeScript = isTSFile || filename.endsWith('.tsx')

const jsc = {
parser: {
syntax: isTypeScript ? 'typescript' : 'ecmascript',
dynamicImport: true,
[isTypeScript ? 'tsx' : 'jsx']: true,
// Exclude regular TypeScript files from React transformation to prevent e.g. generic parameters and angle-bracket type assertion from being interpreted as JSX tags.
[isTypeScript ? 'tsx' : 'jsx']: isTSFile ? false : true,
},

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

const isTypeScript = filename.endsWith('.ts') || filename.endsWith('.tsx')

let loaderOptions = getOptions(this) || {}

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

const swcOptions = getSWCOptions({
pagesDir,
isTypeScript,
filename,
isServer: isServer,
isPageFile,
development: this.mode === 'development',
Expand Down
14 changes: 9 additions & 5 deletions packages/next/taskfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -1172,9 +1172,13 @@ export async function release(task) {

// notification helper
function notify(msg) {
return notifier.notify({
title: '▲ Next',
message: msg,
icon: false,
})
try {
notifier.notify({
title: '▲ Next',
message: msg,
icon: false,
})
} catch (err) {
// notifier can fail on M1 machines
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// eslint-disable-next-line
const myVar = <any>'test'

export default myVar
10 changes: 10 additions & 0 deletions test/integration/typescript/components/generics.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
class MyClass<T> {
value: T
constructor(value: T) {
this.value = value
}
}

const instance = new MyClass<string>('Hello World from Generic')

export default instance.value
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import value from '../components/angle-bracket-type-assertions'

export default () => <div id="value">{value}</div>
3 changes: 3 additions & 0 deletions test/integration/typescript/pages/generics.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import value from '../components/generics'

export default () => <div id="value">{value}</div>
10 changes: 10 additions & 0 deletions test/integration/typescript/test/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,16 @@ describe('TypeScript Features', () => {
expect($('#cookies').text()).toBe('{}')
})

it('should render the generics page', async () => {
const $ = await get$('/generics')
expect($('#value').text()).toBe('Hello World from Generic')
})

it('should render the angle bracket type assertions page', async () => {
const $ = await get$('/angle-bracket-type-assertions')
expect($('#value').text()).toBe('test')
})

it('should resolve files in correct order', async () => {
const $ = await get$('/hello')
expect($('#imported-value').text()).toBe('OK')
Expand Down

0 comments on commit d8cb8c5

Please sign in to comment.