2

I've been dealing with this issue in a project that has been migrated from a default Create-React-App to support Typescript. Currently all the files are not type annotated, however they contain a "// @ts-nocheck" flag at the top so that the project still works, all files are either ts or tsx extensions.

I wrote a new .ts file with a very basic class that I'm trying to use in the rest of the project. Note that this file does not contain a "// @ts-nocheck" flag, since I'm trying to start the process of migrating to a type-annotated typescript codebase.

Here is the file I created (TestType.ts):

export class TestType {

  param1: number;

  constructor(param1:number) {
    this.param1 = param1;
  }

  test() {
    console.log(this.param1);
  }

}

I import it in the MainApp.tsx file and just try to create the object to see if it does not throw an error in the project:

// @ts-nocheck
import React from 'react';
import config from 'config';
import { Route, Switch, withRouter, Redirect } from 'react-router-dom';
import { SendPage } from 'pages';
import MissingRequiredSoftwareModal from 'components/Modal/missingRequiredSoftwareModal';
import MobileNotSupportedModal from 'components/Modal/mobileNotSupported';
import Sidebar from 'components/Sidebar';
import ThemeToggle from 'components/ThemeToggle';
import userIsMobile from 'utils/ui/userIsMobile';
import NewerSignerVersionRequiredModal from 'components/Modal/newerSignerVersionRequiredModal';
import DowntimeModal from 'components/Modal/downtimeModal';
import signerIsOutOfDate from 'utils/validation/signerIsOutOfDate';
import { usePrivateWallet } from 'contexts/privateWalletContext';
import {TestType} from './types/TestType';


function MainApp() {
  const { signerVersion } = usePrivateWallet();
  const onMobile = userIsMobile();

  const a = new TestType(3);
  a.test();

  let warningModal;
  if (config.DOWNTIME) {
    warningModal = <DowntimeModal />;
  } else if (onMobile) {
    warningModal = <MobileNotSupportedModal />;
  } else if (signerIsOutOfDate(signerVersion)) {
    warningModal = <NewerSignerVersionRequiredModal />;
  } else {
    warningModal = <MissingRequiredSoftwareModal />;
  }

  document.title = config.PAGE_TITLE;

  return (
    <div className="main-app bg-primary flex">
      <Sidebar />
      {warningModal}
      <Switch>
        <Route path="/" render={() => <Redirect to="/transact" />} exact />
        <Route path="/send" render={() => <Redirect to="/transact" />} exact />
        <Route path="/transact" component={SendPage} exact />
      </Switch>
      <div className="p-4 hidden change-theme lg:block fixed right-0 bottom-0">
        <ThemeToggle />
      </div>
    </div>
  );
}

export default withRouter(MainApp);

However, when I import it and try to run the app, I get the following compilation error, I believe that the compiler doesn't recognize that it is typescript.

Failed to compile.

./src/types/TestType.ts
SyntaxError: /Users/alex/Desktop/work/app/src/types/TestType.ts: Unexpected token (4:8)

  2 | export class TestType {
  3 |
> 4 |   param1: number;
    |         ^
  5 |
  6 |   constructor(param1:number) {
  7 |     this.param1 = param1;
^C

I've already tried modifying package.json, tsconfig.json and eslintrc.js, based on similar articles to no avail. I have a suspicion that this error has something to do with the parser or the linter. However when I rename the TestType.ts file to TestType.tsx, there is no compilation error and everything works fine. So the main issue is that .ts files are not being compiled in the project. Here are the config files for the project:

tsconfig.json:

{
  "compilerOptions": {
    "target": "es5",
    "baseUrl": "src",
    "lib": [
      "dom",
      "dom.iterable",
      "esnext"
    ],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noFallthroughCasesInSwitch": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react-jsx"
  },
  "checkJs": true,
  "include": [
    "src"
  ]
}

eslintrc.js:

module.exports = {
  env: {
    browser: true,
    es2021: true
  },
  extends: ['eslint:recommended', 'plugin:react/recommended'],
  parser: 'babel-eslint',
  parserOptions: {
    ecmaFeatures: {
      jsx: true
    },
    ecmaVersion: 12,
    sourceType: 'module'
  },
  plugins: ['react', 'eslint-plugin-import'],
  globals: {
    process: true,
    require: true
  },
  root: true,
  rules: {
    indent: ['error', 2],
    'linebreak-style': ['error', 'unix'],
    quotes: ['error', 'single'],
    semi: ['error', 'always'],
    'no-unused-vars': [
      'error',
      { vars: 'all', args: 'after-used', ignoreRestSiblings: false }
    ],
    'import/order': [
      'error',
      { groups: ['builtin', 'external', 'parent', 'sibling', 'index'] }
    ],
    'jsx-quotes': ['error', 'prefer-double'],
    'no-useless-escape': 'off'
  }
};
2
  • Change src in your includes to src/**/*.tsx and src/**/*.ts (add new path to array). Commented Sep 16, 2022 at 18:55
  • @caTS just tried this, changed from "src" to the paths you specified and it had no effect, the problem persists. Commented Sep 16, 2022 at 19:23

1 Answer 1

1

Answer: Removing 'babel-loader' rule from craco.config.js solved the problem.

const { addBeforeLoader, loaderByName } = require('@craco/craco');

module.exports = {
  style: {
    postcss: {
      plugins: [
        require('tailwindcss'),
      ],
    },
  },
  webpack: {
    configure: (webpackConfig) => {
      webpackConfig.module.rules.push(
        {
          test:/\.(js|ts)$/,
          loader: require.resolve('@open-wc/webpack-import-meta-loader'),
        }
      )
      webpackConfig.module.rules.push(
        {
          test: /\.(js|ts)$/,
          use: {
            loader: 'babel-loader'
            options: {
              presets: ['@babel/env']
            }
          }
        }
      )

      const wasmExtensionRegExp = /\.wasm$/;
      webpackConfig.resolve.extensions.push('.wasm');

      webpackConfig.module.rules.forEach((rule) => {
        (rule.oneOf || []).forEach((oneOf) => {
          if (oneOf.loader && oneOf.loader.indexOf('file-loader') >= 0) {
            oneOf.exclude.push(wasmExtensionRegExp);
          }
        });
      });

      const wasmLoader = {
        test: /\.wasm$/,
        exclude: /node_modules/,
        loaders: ['wasm-loader'],
      };

      addBeforeLoader(webpackConfig, loaderByName('file-loader'), wasmLoader);

      return webpackConfig;
    },
  },
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.