johnsoncodehk / tsslint

πŸ”‹βš‘οΈ The fastest and lightest TypeScript semantic linting solution
MIT License
272 stars 2 forks source link

πŸš€ Feature: Compatibility layer for ESLint plugins #17

Open JoshuaKGoldberg opened 1 month ago

JoshuaKGoldberg commented 1 month ago

πŸ‘‹ again! This and https://github.com/Quramy/typescript-eslint-language-service are two really exciting avenues of being able to run ideally much faster typed linting as a part of the TypeScript language service. Ideally we'd be able to run all of a project's linting through this one - including existing ESLint plugins.

One issue that plagued TSLint back in the day was that it didn't support ESLint plugins natively. Everything had to be rewritten from ESTree to TypeScript's AST format.

Would you be interested in some kind of compatibility layer that lets folks natively use ESLint rules and plugins in TSSLint?

Vaguely guessing at an initial API design:

import { defineConfig, eslintPluginCompat } from '@tsslint/config';
import example from 'eslint-plugin-example';

export default defineConfig({
    rules: {
        // ...
        eslintPluginCompat(example.recommended),
    },
});

It looks like ./packages/eslint already has a convertRule that does a lot of this work - so maybe this is already planned? πŸ™‚

johnsoncodehk commented 1 month ago

Hey πŸ‘‹ Thanks for the suggestion, I did plan to add this API but I'm very new to ESLint hence the delay. (I would appreciate it if you could share a repo suitable for testing this API.)

JoshuaKGoldberg commented 1 month ago

Swell! I've got a couple on my personal account that exercise some edge cases:

https://github.com/eslint/eslint/issues/18093 is a good tracking issue to see plugins that support ESLint's new flat config format.

johnsoncodehk commented 1 month ago

1.0.14 added the loadPluginRules API in @tsslint/eslint, which is not a complete compatibility layer yet.

Example:

import { defineConfig } from '@tsslint/config';
import { loadPluginRules } from '@tsslint/eslint';

export default defineConfig({
    rules: {
        ...await loadPluginRules(((await import('eslint-plugin-expect-type')).configs).recommended.rules),
        ...await loadPluginRules(((await import('@typescript-eslint/eslint-plugin')).default.configs).recommended.rules ?? {}),
    },
});

Since some plugin config has the extends option, implementing the eslintPluginCompat API need more considerations.