Skip to content

Enhancement: [consistent-indexed-object-style] forbidden from using the "in" keyword in index signature if Record is preferred #6598

Closed
@yeung108

Description

@yeung108

Before You File a Proposal Please Confirm You Have Done The Following...

My proposal is suitable for this project

  • I believe my proposal would be useful to the broader TypeScript community (meaning it is not a niche proposal).

Link to the rule's documentation

https://typescript-eslint.io/rules/consistent-indexed-object-style/

Description

When "record" option is chosen in @typescript-eslint/consistent-indexed-object-style, we should also be forbidden from using the "in" keyword in index signature. It's particularly useful for literal types.

Here's the justification:

  • we should prefer Record versus Index Signature whenever we want to use literal types, as index signature accepts only string, number or symbol as key type.
  • And when Record is preferred, it also brings an advantage of ensuring no missing property in literal types -> which further ensures type safety, and avoid getting unexpected undefined case from non-existing key.
  • However, such advantage will not be kept since the current @typescript-eslint/consistent-indexed-object-style rule allows people using { [key in Option] : string}

Fail

/* eslint @typescript-eslint/consistent-indexed-object-style: ["error", "record"] */

type Option = "red" | "yellow";

const optionToString: { [key in Option]: string} = {
   "red": "this is red" // won't be warned that "yellow" is missing
}

Pass

/* eslint @typescript-eslint/consistent-indexed-object-style: ["error", "record"] */

type Option = "red" | "yellow";

// if we use Record, it will prompt error if any property is missing; 
// E.g. it should say "Property 'yellow' is missing in type '{ red: string; }' but required in type 'Record<Option, string>'." 
// if we just have "red" as the only property.
const optionToString: Record<Option, string> = {
   "red": "this is red",
   "yellow": "this is yellow",
}


// Or, if we indeed want to get undefined for some keys; making them explicit when defining
// the type and value is better and clearer.
const optionToString: Record<Option, string | undefined> = {
   "red": "this is red",
   "yellow": undefined,
}

Additional Info

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    accepting prsGo ahead, send a pull request that resolves this issueenhancement: plugin rule optionNew rule option for an existing eslint-plugin rulelocked due to agePlease open a new issue if you'd like to say more. See https://typescript-eslint.io/contributing.package: eslint-pluginIssues related to @typescript-eslint/eslint-plugin

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions