10000 Enhancement: [ban-types] Suggest `NonNullable<unknown>` as an alternative for `{}` and `Object` · Issue #6486 · typescript-eslint/typescript-eslint · GitHub
[go: up one dir, main page]

Skip to content
Enhancement: [ban-types] Suggest NonNullable<unknown> as an alternative for {} and Object #6486
Closed
@arieljbirnbaum

Description

@arieljbirnbaum

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/ban-types/

Description

The rule forbids the use of the type {} (and its synonym Object), which means "any non-nullish value", and gives some helpful suggestions on what to use instead, depending on what the developer actually might have meant.

However, there seems to be no suggestion (outside disabling the rule) for what to use when the intended meaning really is "any non-nullish value". The suggested alternative for "any object", namely object, doesn't include primitive types such as number, so it's not an equivalent replacement in this case.

Rather than bypassing or disabling the rule, and leaving the easily misunderstood {} in place, I think it would be useful to suggest an explicit alternative for this case as well; something along the lines of

- If you really want a type meaning "any non-nullish value", you probably want `NonNullable<unknown>` instead.

(placed after all the other suggestions).

TypeScript includes the NonNullable utility type since 2.8, so I don't think there shouldn't be any compatibility issues.

PS: I wasn't sure if this issue should go under Documentation or Enhancement; since it changes the output of the rule I opted for the latter. My apologies if I got it wrong :)

Fail

/**
 * This is a generic combinator to add a fallback value to a function, to handle a null input.
 * However, we don't want to accidentally use it when the function _already_ handles null,
 * otherwise our fallback will clobber the original value.
 */
const withFallback: <Input extends {}, Output>( // This fails the rule and that's OK :)
  mapping: (input: Input) => Output,
  fallback: Output
) => (input: Input | null) => Output = (mapping, fallback) => (input) =>
  input === null ? fallback : mapping(input);

const plusOne: (input: number) => number
const plusOneWithFallback = withFallback(plusOne, 0); // This won't compile if we replace {} with object

Pass

const withFallback: <Input extends NonNullable<unknown>, Output>( // Same meaning, explicit, passes :)
  mapping: (input: Input) => Output,
  fallback: Output
) => (input: Input | null) => Output = (mapping, fallback) => (input) =>
  input === null ? fallback : mapping(input);

const plusOne: (input: number) => number
const plusOneWithFallback = withFallback(plusOne, 0); // This compiles

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 rulegood first issueGood for newcomerspackage: 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

      0