Skip to content

Prettier and @typescript-eslint disagree on function types in generics #33452

@joeframbach

Description

@joeframbach

Description

TypeScript projects passing setState argument types to a generic function trips up ESLint's JavaScript rules and does not instead use the TypeScript replacement. Prettier and ESLint disagree on the style and nobody is happy.

// Suppose we have some function with a type argument
declare function foo<T>(): any;

// This is OK! We can call it with a number type argument.
foo<number>();

// This is OK! We can call it with an array type argument.
foo<[number, string]>();

// This is OK! We can call it with a function type argument.
foo<[() => void]>();

// This is NOT OK! We can not call it with an array type argument containing a function, like React setState syntax for example.
// eslint's no-spaced-func wants this:
foo<[number,() => void]>();
//         ~~ no space here
// but Prettier wants to inject a space here, and nobody is happy.
// eslint's no-spaced-func has been deprecated for a long time in favor of func-call-spacing, but that doesn't work either.

// eslint's func-call-spacing wants this:
foo<[number,() => void]>();
//         ~~ no space here
// but Prettier wants to inject a space here, and nobody is happy.

// Using @typescript-eslint/func-call-spacing, this now works.
// @typescript-eslint/func-call-spacing is ok with either of these:
foo<[number,() => void]>(); // but Prettier will inject a space here,
foo<[number, () => void]>(); // and everyone is happy.

Version

0.67.3

Output of npx react-native info

info Fetching system and libraries information...
System:
    OS: macOS 12.2.1
    CPU: (12) x64 Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
    Memory: 31.27 MB / 16.00 GB
    Shell: 5.8 - /bin/zsh
  Binaries:
    Node: 16.0.0 - ~/.nvm/versions/node/v16.0.0/bin/node
    Yarn: 1.22.17 - ~/.nvm/versions/node/v16.0.0/bin/yarn
    npm: 7.10.0 - ~/.nvm/versions/node/v16.0.0/bin/npm
    Watchman: 2022.03.07.00 - /usr/local/bin/watchman
  Managers:
    CocoaPods: 1.11.2 - /usr/local/bin/pod
  SDKs:
    iOS SDK:
      Platforms: DriverKit 21.4, iOS 15.4, macOS 12.3, tvOS 15.4, watchOS 8.5
    Android SDK:
      API Levels: 29, 30
      Build Tools: 30.0.2, 32.0.0, 32.1.0
      System Images: android-29 | Google Play Intel x86 Atom, android-30 | Google APIs Intel x86 Atom, android-30 | Google Play Intel x86 Atom
      Android NDK: Not Found
  IDEs:
    Android Studio: 2021.1 AI-211.7628.21.2111.8193401
    Xcode: 13.3/13E113 - /usr/bin/xcodebuild
  Languages:
    Java: 1.8.0_322 - /usr/bin/javac
  npmPackages:
    @react-native-community/cli: Not Found
    react: 17.0.2 => 17.0.2
    react-native: 0.67.3 => 0.67.3
    react-native-macos: Not Found
  npmGlobalPackages:
    *react-native*: Not Found

Steps to reproduce

  1. npx react-native init MyApp --template react-native-template-typescript
  2. In App.tsx write:
declare function foo<T>(): T;
foo<[string, () => number]>();

ESLint complains about the space between , and (. When fixed, Prettier complains about the missing space. When fixed, ESLint complains about the space between , and (.

Snack, code example, screenshot, or link to a repository

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions