Skip to content

create-react-app enforces @typescript-eslint/no-namespace, a style rule #7651

Closed
@szhu

Description

@szhu

Describe the bug

  1. create-react-app --typescript
  2. Add a namespace in a file
  3. I get the error: ES2015 module syntax is preferred over custom TypeScript modules and namespaces.eslint(@typescript-eslint/no-namespace). There seems to be no way to turn off this rule, according to Support ESLint configure or disabling ESLint (discussion) #3886.

Why this is a bug:

From #2157 (comment):

Our rules are specifically picked to not enforce style, and to only find logical mistakes.

Whether or not a namespace is used is most definitely not a choice of style and not a logical mistake. Please remove this rule or give me an option to remove this rule.

Activity

heyimalex

heyimalex commented on Sep 6, 2019

@heyimalex
Contributor

Could you comment out that line directly in node_modules and see if compilation works as you'd expect? This landed in #6513 right when we added native ts support, so I'm thinking maybe there's an actual reason it's there. But maybe not.

szhu

szhu commented on Sep 6, 2019

@szhu
ContributorAuthor

Ah:

SyntaxError: .../xxx.tsx: Namespaces are not supported.

Which part of the build process are namespaces not supported by?

heyimalex

heyimalex commented on Sep 6, 2019

@heyimalex
Contributor

We use babel to compile typescript (vs directly with tsc), so probably there. I just checked here and at a glance it looks like support is being added, at least for type-only namespaces (we're usually pinned to a slightly out of date babel, so maybe why you don't see the same error message).

If you want to do the legwork to land the requisite changes I'd be happy to mentor/review! I can write out some steps, just let me know if you're interested.

szhu

szhu commented on Sep 6, 2019

@szhu
ContributorAuthor

Ah, it's Babel.

Also, I tried this with the newest version of CRA. I get the same lint error, but after disabling it according to the above instructions, I now get:

SyntaxError: /Users/Sean/test-app/src/App.tsx: Namespace not marked type-only declare. Non-declarative namespaces are only supported experimentally in Babel. To enable and review caveats see: https://babeljs.io/docs/en/babel-plugin-transform-typescript

heyimalex

heyimalex commented on Sep 6, 2019

@heyimalex
Contributor

Oh lol, then no changes needed? Does a type-only namespace work for your usecase or nah? If not then there's not much we can do until this lands (as non-experimental) in babel. If it is but the lint rule is still firing then we can fix that.

szhu

szhu commented on Sep 6, 2019

@szhu
ContributorAuthor

So, it looks like disabling the lint error can at least get declare namespace to work. I'd be happy to make that change.

Please let me know what I can do! Here are the changes that I think I need to make:

  • In eslint-config-react-app, remove the @typescript-eslint/no-namespace rule.
  • Update react-scripts to use that updated version of eslint-config-react-app
  • (Possibly?) Update in react-scripts, run babel with the allowNamespaces option. (This enables partial support for non-declare-only namespaces, see https://babeljs.io/docs/en/babel-plugin-transform-typescript) Let me know if this is a change we can/should make.
  • Update create-react-app to use that updated version of react-scripts.

Let me know if this seems correct and if you have any pointers!

szhu

szhu commented on Sep 7, 2019

@szhu
ContributorAuthor

Btw, there's one warning I have left. At this point I should probably explain my use case:

namespace Counter {
  interface Props {
    value: number
    setValue: (value: number) => void
  }
}

const Counter: React.FC<Counter.Props> = (props) => {
  return <div>{value}</div>
}

export default Counter

Basically, I don't want to export/use props separately from the component.


For this example, the proposed fixes will make it work! But I'm still left with this warning:

Compiled with warnings.
  'Counter' is already defined  no-redeclare

Let me know what you think. Should no-redeclare also be removed? Is the props organization convention a bad one? Is there a way to achieve the same effect without namespaces? Also let me know if you think this is worthy of a separate issue.

heyimalex

heyimalex commented on Sep 7, 2019

@heyimalex
Contributor

Hm, it's friday night for me so I'll have to take a look this weekend. I'm pretty sure we don't want to get rid of no-redeclare, and I'm actually kinda surprised that it's even firing for what is essentially a type definition since I'm pretty sure I've done similar things in the past. Maybe it just sees namespaces differently.

RE: Your use case: That's a pretty neat pattern! I'm not an expert on the best practices, but I've read a lot of type definitions on DefinitelyTyped and generally I've seen a separate CounterProps export. You can also do React.ComponentProps<typeof Counter> I think. But I understand the ergonomic appeal of having type/constructor-associated access to props, and I'd like to get this sorted either way.

heyimalex

heyimalex commented on Sep 7, 2019

@heyimalex
Contributor

Oh have you tried adding declare in front of your namespace definition? I can actually see why it would complain about re-declaring since it doesn't know that it's types-only, so it has to be an actual callable thing.

20 remaining items

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      Participants

      @heyimalex@szhu@cordasfilip

      Issue actions

        create-react-app enforces @typescript-eslint/no-namespace, a style rule · Issue #7651 · facebook/create-react-app