'jest issue with typescript react components
I'm currently having an issue with Jest and Typescript inside a Lerna mono repo.
Inside the test file, I've imported the component import { Doctor } from '../src';
and the test step is as follows:
it('should be selectable by class "btn-doctor"', function() {
expect(shallow(<Doctor/>).is('.btn-doctor')).toBe(true);
});
<Doctor />
is underlined as warning; saying: 'Doctor' refers to a value, but is being used as a type here. Did you mean 'typeof Doctor'?ts(2749)
I think the issue is related to the configuration but i did not find anything in the official docs for Typescript and Jest.
The issue can be reproduced in this repo https://github.com/umarmw/lopital-sdk when running lerna run test
lerna ERR! npm run test stderr:
FAIL __tests__/doctor.test.ts
● Test suite failed to run
__tests__/doctor.test.ts:14:21 - error TS2749: 'Doctor' refers to a value, but is being used as a type here. Did you mean 'typeof Doctor'?
14 expect(shallow(<Doctor/>).is('.btn-doctor')).toBe(true);
~~~~~~
__tests__/doctor.test.ts:18:19 - error TS2749: 'Doctor' refers to a value, but is being used as a type here. Did you mean 'typeof Doctor'?
18 expect(mount(<Doctor title="MO" />).find('.btn-doctor').length).toBe(1);
~~~~~~
__tests__/doctor.test.ts:18:26 - error TS2304: Cannot find name 'title'.
18 expect(mount(<Doctor title="MO" />).find('.btn-doctor').length).toBe(1);
The current config files are as follows:
tsconfig.json
{
"compilerOptions": {
"target": "es6", // Specify ECMAScript target version
"sourceMap": true, // Generates corresponding .map file.
"lib": [
"dom",
"dom.iterable",
"esnext"
], // List of library files to be included in the compilation.
"allowJs": false, // Allow JavaScript files to be compiled.
"skipLibCheck": true, // Skip type checking of all declaration files (*.d.ts).
"esModuleInterop": true, // Emit __importStar and __importDefault helpers for runtime babel ecosystem compatibility and enable --allowSyntheticDefaultImports for typesystem compatibility.
"allowSyntheticDefaultImports": true, // Allow default imports from modules with no default export. This does not affect code emit, just typechecking.
"strict": true, // Enable all strict type checking options.
"forceConsistentCasingInFileNames": true, // Disallow inconsistently-cased references to the same file.
"noImplicitAny": false, // Raise error on expressions and declarations with an implied any type.
"noLib": false, // Do not include the default library file (lib.d.ts).
"emitDecoratorMetadata": true, // Emit design-type metadata for decorated declarations in source.
"experimentalDecorators": true, // Enables experimental support for ES decorators.
"module": "commonjs", // Specify module code generation: "None", "CommonJS", "AMD", "System", "UMD", "ES6", "ES2015" or "ESNext".
// "moduleResolution": "node",
// "resolveJsonModule": true,
"jsx": "react", // Support JSX in .tsx files: "react", "preserve", "react-native". See JSX.
"declaration": true, // Generates corresponding .d.ts file.
},
"exclude": [
"node_modules",
"**/*.spec.ts"
]
}
jest.config.js
module.exports = {
preset: "ts-jest",
testEnvironment: "node",
globals: {
"ts-jest": {
extends: './babel.config.js',
tsConfig: {
// allow js in typescript
allowJs: true,
},
},
},
verbose: true,
moduleFileExtensions: ['ts', 'tsx', 'js'],
notify: true,
notifyMode: 'always',
testMatch: ['**/__tests__/*.+(ts|tsx|js)', '**/*.test.+(ts|tsx|js)'],
transform: {
'^.+\\.(ts|tsx)$': 'ts-jest',
},
// testRegex: '(/__tests__/.*|(\\.|/)(test|spec))\\.tsx?$',
testPathIgnorePatterns: [
'/node_modules/',
'(/__tests__/.*|(\\.|/)(test|spec))\\.d\.ts$'
],
snapshotSerializers: ['enzyme-to-json/serializer'],
// setupFilesAfterEnv: ['<rootDir>../setupTests.js'],
}
babel.config.js
module.exports = {
presets: [
'@babel/preset-react',
'@babel/preset-typescript',
[
'@babel/preset-env',
{
targets: {node: 'current'}
}
],
],
"plugins": [
[
"@babel/plugin-proposal-class-properties",
{
"loose": true
}
]
]
}
Any idea?
Solution 1:[1]
The error means that JSX syntax isn't recognized by TypeScript compiler and is parsed as a generic.
Since tsconfig.json has "jsx": "react"
, this means that it wasn't picked up by ts-jest for some reason. The reason is that it was overridden by tsConfig
option. A common way to provide a config for tests is to extend another config
tsconfig.test.json
{
"extends": "./tsconfig",
"compilerOptions": {
"allowJs": true
}
}
And specify it for ts-jest:
"tsConfig": "tsconfig.test.json"
Also, ts-jest doesn't have extends
option, and even if it had, it wouldn't accept Babel config. There is babelConfig
option for that. Since ts-jest transforms TypeScript and JSX, @babel/preset-react
and @babel/preset-typescript
may be unneeded in Babel config.
Solution 2:[2]
It looks like you've not used the correct file extension here. Was your test named doctor.test.ts
instead of doctor.test.tsx
?
When testing React components you need to ensure you use (j|t)sx
extension.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Estus Flask |
Solution 2 |