首页 > 解决方案 > TSLint `import-name` complains about import React from 'react' and turns it lowercase

问题描述

I'm currently using React with TypeScript and TSLint and up until now I was importing React as:

import * as React from 'react';

I'd like to switch that to:

import React from 'react';

So that I don't need an additional line and const declaration to destructure hooks like useCallback, useEffect or useRef:

import React, { useCallback, useEffect, useRef } from 'react';

But I get the following error from TSLint:

Misnamed import. Import should be named 'react' but found 'React' (import-name) tslint(1)

When running with fix: true, that will automatically be converted to:

import react from 'react';

The error will go away, but I'd like to keep it as React.

I'm using TypeScript 3.5.1 and TSLint 5.17.0.

标签: javascriptreactjstypescriptbabeljstslint

解决方案


To make that error go away you need to add this rule into tslint.json:

"import-name": [true, { "react": "React" }],

As stated in the docs:

Since version 2.0.9 it is possible to configure this rule with a list of exceptions.

For example, to allow underscore to be imported as _, add this configuration:

 'import-name': [ true, { 'underscore': '_' }]

Then, in tsconfig.json you need to add:

"esModuleInterop": true,
"allowSyntheticDefaultImports": true,

While "esModuleInterop": true should set "allowSyntheticDefaultImports": true automatically (so there's no need to define both), there was an issue with that and some tools might be checking the value of those flags, so you might need to set both if using an pre-fix TypeScript version.

For more on that, see Do I ever need explicit allowSyntheticDefaultImports if esModuleInterop is true configuring TypeScript transpilation?.

From the docs:

--allowSyntheticDefaultImports: Allow default imports from modules with no default export. This does not affect code emit, just typechecking.

--esModuleInterop: Emit __importStar and __importDefault helpers for runtime babel ecosystem compatibility and enable --allowSyntheticDefaultImports for typesystem compatibility.

Also, allowSyntheticDefaultImports was added in TypeScript 1.8 while esModuleInterop was added in TypeScript 2.7, so depending on the version you are using you would have to stick to allowSyntheticDefaultImports. For more on that, see https://devblogs.microsoft.com/typescript/announcing-typescript-2-7/

If you don't set them, you will get the following error:

Module '".../node_modules/@types/react/index"' can only be default-imported using the 'esModuleInterop' flag

If you are still getting errors when setting one or the two of them to true, it might be worth taking a look at: https://github.com/microsoft/TypeScript/issues/27329.


推荐阅读