Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug: no-unsafe-* rules interpret imports ending in .ts as any #5921

Closed
4 tasks done
RobertAKARobin opened this issue Nov 2, 2022 · 2 comments
Closed
4 tasks done
Labels
awaiting response Issues waiting for a reply from the OP or another party working as intended Issues that are closed as they are working as intended

Comments

@RobertAKARobin
Copy link

RobertAKARobin commented Nov 2, 2022

Before You File a Bug Report Please Confirm You Have Done The Following...

  • I have tried restarting my IDE and the issue persists.
  • I have updated to the latest version of the packages.
  • I have searched for related issues and found none that matched my issue.
  • I have read the FAQ and my problem is not listed.

Issue Description

If we import a file from a path ending in .ts, then the no-unsafe-* rules are triggered:

Screen Shot 2022-11-02 at 12 15 33 PM

We're using Eslint with Deno, since Deno's linter doesn't provide alternatives for all the rules we've historically used. Except for this issue it has worked flawlessly: types are resolved correctly and linting works as expected.

Typescript does not yet support importing with .ts extension, but since Eslint otherwise seems compatible with these imports we consider this a bug.

Reproduction Repository Link

https://github.com/RobertAKARobin/eslint-import-debug

Repro Steps

  1. clone the repo
  2. npm install
  3. npm run lint
  4. If viewing in VSCode, install the Deno extension in order to suppress "An import path cannot end with a '.ts' extension."

Versions

package version
@typescript-eslint/eslint-plugin 5.42.0
@typescript-eslint/parser 5.42.0
ESLint 8.26.0
Typescript (via Deno) 4.8.3
Deno 1.26.2
@RobertAKARobin RobertAKARobin added bug Something isn't working triage Waiting for maintainers to take a look labels Nov 2, 2022
@RobertAKARobin RobertAKARobin changed the title Bug: no-unsafe-* rules are not compatible with imports ending in .ts Bug: no-unsafe-* rules interpret imports ending in .ts as any Nov 2, 2022
@bradzacher
Copy link
Member

Except for this issue it has worked flawlessly: types are resolved correctly and linting works as expected.

To clarify - do you mean you use other type-aware lint rules and they work fine with these .ts imports?
Any type-aware rules should work fine for global types and local types, but should fail for "bad" imports.

Typescript does not yet support importing with .ts extension, but since Eslint otherwise seems compatible with these imports we consider this a bug.

Our types come from TypeScript - we're built directly on top of the TS apis.
So for types - if TS doesn't support it out of the box then neither do we.

Given this is probably just module resolution - you could likely work around this by building a custom module resolver:
https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/README.md#parseroptionsmoduleresolver

@bradzacher bradzacher added awaiting response Issues waiting for a reply from the OP or another party working as intended Issues that are closed as they are working as intended and removed bug Something isn't working triage Waiting for maintainers to take a look labels Nov 2, 2022
@RobertAKARobin
Copy link
Author

RobertAKARobin commented Nov 3, 2022

Thanks! We were indeed able to fix this with our own resolver. For anyone else trying to do the same, here's what we went with:

// ts-resolver.js
const ts = require(`typescript`);
const tsExtension = /\.ts$/;
module.exports = {
	resolveModuleNames: (
		moduleNames,
		containingFile,
		reusedNames,
		redirectedReference,
		options
	) => moduleNames.map((moduleName) =>
		ts.resolveModuleName(
			moduleName.replace(tsExtension, ``),
			containingFile,
			options,
			ts.sys
		).resolvedModule
	),
};
// .eslintrc.js
module.exports = {
	env: {
		node: true,
	},
	overrides: [
		{
			files: [`*.ts`],
			parser: `@typescript-eslint/parser`,
			parserOptions: {
				moduleResolver: __dirname + `/ts-resolver.js`,
			},
		},
	],
};

That said, while this works fine for .ts imports, it doesn't play nice with Deno's remote imports, e.g.:

import { serve } from 'https://deno.land/std@0.133.0/http/server.ts';

We made some progress with eslint-import-resolver-deno:

const ts = require(`typescript`);
const denoResolver = require(`eslint-import-resolver-deno`);

const tsExtension = /\.ts$/;
module.exports = {
	resolveModuleNames: (
		moduleNames,
		containingFile,
		reusedNames,
		redirectedReference,
		options
	) => moduleNames.map((moduleName) => {
		if (moduleName.startsWith(`http`)) {
			const { found, path } = denoResolver.resolve(
				moduleName,
				containingFile,
				{
					importMap: __dirname + `/import-map.json`,
				}
			);
			if (found) {
				moduleName = path;
			}
		}
		return ts.resolveModuleName(
			moduleName.replace(tsExtension, ``),
			containingFile,
			options,
			ts.sys
		).resolvedModule;
	}),
};

...but that still doesn't work, probably because Eslint doesn't "know" about Deno's global types.

So, in conclusion, we're going to stop putting lipstick on a pig and trying to use type-aware rules with Deno. @bartolomieju mentioned that Deno is looking into native support for Eslint rules, so hopefully that gets added somewhere down the line.

Thanks for your help @bradzacher !

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
awaiting response Issues waiting for a reply from the OP or another party working as intended Issues that are closed as they are working as intended
Projects
None yet
Development

No branches or pull requests

2 participants