Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[no-type-alias] Allow exception for Record<T, U> to avoid conflict with consistent-indexed-object-style #3784

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

Closed
3 tasks done
scottohara opened this issue Aug 24, 2021 · 2 comments · Fixed by #3865
Closed
3 tasks done
Labels
enhancement: plugin rule option New rule option for an existing eslint-plugin rule package: eslint-plugin Issues related to @typescript-eslint/eslint-plugin

Comments

@scottohara
Copy link
Contributor

scottohara commented Aug 24, 2021

  • I have tried restarting my IDE and the issue persists.
  • I have updated to the latest version of the packages.
  • I have read the FAQ and my problem is not listed.

Repro

{
  "rules": {
    "@typescript-eslint/no-type-alias": ["error"],
    "@typescript-eslint/consistent-indexed-object-style": ["error"]
  }
}
type MyType = Record<string, { foo: string; bar: number; baz: boolean; }>;

Expected Result

I would like to configure Record<T, U> as an allowed exception to the no-type-alias rule.

Actual Result

Type aliases are not allowed

Additional Info

The documentation for the no-type-alias rule provides numerous good reasons why type aliases are best avoided, with a general preference for interfaces instead:

// no-type-alias

// bad
type MyType = { foo: string; bar: number; baz: boolean; };

// good
interface MyType {
  foo: string;
  bar: number;
  baz: boolean;
};

The consistent-indexed-object-style rule (introduced in v4.4.0) defaults to "record", which also seems reasonable because it is (at least in my opinion) more concise and readable than an interface containing only an indexed signature:

// consistent-indexed-object-style: "record"

// bad
interface MyType {
  [key: string]: { foo: string; bar: number; baz: boolean; };
};

// good
type MyType = Record<string, { foo: string; bar: number; baz: boolean; }>;

With their default configurations, these two rules appear to be mutually exclusive.

Looking at the configuration options for no-type-alias, unless I'm mistaken, I couldn't see a way of configuring an exception for Record to be allowed while still rejecting other forms of type aliases.

Wonder if there would be appetite for adding a config option to no-type-alias to allow for this use case?

Versions

package version
@typescript-eslint/eslint-plugin 4.29.2
@typescript-eslint/parser 4.29.2
TypeScript 4.3.5
ESLint 7.35.0
node 16.4.2
@scottohara scottohara added package: eslint-plugin Issues related to @typescript-eslint/eslint-plugin triage Waiting for team members to take a look labels Aug 24, 2021
@bradzacher bradzacher added enhancement: plugin rule option New rule option for an existing eslint-plugin rule and removed triage Waiting for team members to take a look labels Aug 26, 2021
@scottohara
Copy link
Contributor Author

Just thinking through how we might implement such a change, and taking inspiration from other rules:

Option 1

One approach would be to introduce a new array option for alias names to be allowed/ignored by the rule, for example:

{
  "rules": {
    "@typescript-eslint/no-type-alias": ["error", {
      "allowAliases": "never",
      "ignoredTypesNames": ["Record"]  // <- new option
    }]
  }
}

Doing a quick survey of other rules that support an array of things to allow/ignore, there doesn't seem to be a lot of consistency in how these options are named. Some use the prefix "allowed..", some use "ignored..", other use a "..ToIgnore" suffix e.g.

Rule Option
explicit-member-accessibility ignoredMethodNames
explicit-module-boundary-types allowedNames
no-base-to-string ignoredTypesNames
no-this-alias allowedNames
no-unnecessary-type-assertion typesToIgnore
promise-function-async allowedPromiseNames
indent ignoredNodes
no-empty-function allow
no-shadow allow

So if we took this approach, is there a preference for what the new option should be called?

Option 2

An alternate approach, which is perhaps not quite as flexible/extensible as the first option, would be a boolean specifically for allowing Record to be used for indexed objects, e.g.

{
  "rules": {
    "@typescript-eslint/no-type-alias": ["error", {
      "allowAliases": "never",
      "allowIndexedObjects": true   // or more explicitly: allowRecord?
    }]
  }
}

This follows the existing pattern of booleans for other types of exceptions to the rule (e.g. allowCallbacks, allowLiterals, allowTupleTypes etc.)

Option 3

A third option would be a new value (or set of values) for the "allowAliases" option, e.g.

{
  "rules": {
    "@typescript-eslint/no-type-alias": ["error", {
      "allowAliases": "in-indexed-objects"
    }]
  }
}

This approach may also require additional values for all composition types, e.g.

type Values =
  | 'always'
  | 'never'
  | 'in-unions'
  | 'in-intersections'
  | 'in-indexed-objects'                                // new
  | 'in-unions-and-intersections'
  | 'in-unions-and-indexed-objects'                     // new
  | 'in-intersections-and-indexed-objects'              // new
  | 'in-unions-and-intersections-and-indexed-objects';  // new

I be happy to have a stab at a PR for this, just looking for a bit of guidance as to which approach best fits with conventions.

@JounQin
Copy link
Contributor

JounQin commented Sep 12, 2021

I think it's similar as #3181

And the solution at #3181 (comment) could also help.

It runs very well in my projects through https://github.com/1stG/configs/blob/master/packages/eslint-config/overrides.js#L184-L192

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Oct 22, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement: plugin rule option New rule option for an existing eslint-plugin rule package: eslint-plugin Issues related to @typescript-eslint/eslint-plugin
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants