Create-react-app: Typescript namespaces to be considered?

Created on 30 Oct 2018  路  12Comments  路  Source: facebook/create-react-app

After some initial bickering that Typescript support does not include this and that I've decided to give it a try. Unfortunately, I've stumbled upon a big obstacle.

I am using graphql-code-generator package to generate strong types for my GraphQL queries. In the essence, it generates types like this.

export namespace GLogoutWidget {
  export type Variables = {
    id: string
  }

  export type Query = {
    __typename?: 'Query'
    user: User
  }

  export type User = {
    __typename?: 'User'
    id: string
    firstName?: string | null
    lastName?: string | null
  }
}

Usage of namespaces in this is extremely helpful as it clearly separates types for each query/mutation. Compared to apollo-codegen which outputs extremely long and annoying names for types, this is a clear win.

I would like to know if namespace support is such a huge technical problem that it cannot be included. I mean when bundling the app it should be mostly about stripping type information and let the TypeScript worry about type checking. I am kinda lost why such a decision has been made to have a separate TypeScript parser that's limited like this.

/cc @Timer

question

All 12 comments

You should be able to define these in a .d.ts file, correct? They just can't live in a .ts(x)? file.

Can you co-locate these types next to the source file in a .d.ts version?

Well, I don't want to use .d.ts because I want to explicitly import these types when I am using them. There is too many of those and having them _global_ would pollute autocomplete and it would be rather annoying.

namespace are not supported on @babel/preset-typescript so if we try to support this we need to use ts-loader.

Seems like the best path forward is to have graphql-code-generator generate modern type definitions (based on ES Modules).
Can we file an issue with them?

That module supports custom generators I can write myself. However, I am not sure how it should look like. What do you mean by "modern type definitions"?

If I understand correctly what you mean, the result should look like this?

  export type GLogoutWidgetVariables = {
    id: string
  }

  export type GLogoutWidgetQuery = {
    __typename?: 'Query'
    user: User
  }

  export type GLogoutWidgetUser = {
    __typename?: 'User'
    id: string
    firstName?: string | null
    lastName?: string | null
  }

If that's what you mean then I don't like it at all because that's the same thing that apollo-codegen is doing. A major deal breaker is that I can have namespace that contains like 10 different types. If I want to reference all of them, it means I have to import for each one of them separately. Compare to when I can just import "GLogoutWidget" and have everything neatly packaged.

Why couldn't you just import * as GLogoutWidget from './ThatFile' and get them all packaged?

That does not make much sense. These types are generated from all queries and put into single types.ts file and thanks to namespaces I can import only namespaces I want.

Ok, nevermind I guess. It's not worth spending time on this. I found related babel issue and it's apparent that namespace will never be part of that plugin because they are _legacy_ .

Oh well. I am so glad that react-script-ts are going to be maintained, otherwise the future would be rather dark.

@FredyC Try using export declare namespace instead of export namespace:

-export namespace GLogoutWidget {
+export declare namespace GLogoutWidget {

Let me know if that works for you.

That does not make much sense. These types are generated from all queries and put into single types.ts file and thanks to namespaces I can import only namespaces I want.

Ok, nevermind I guess. It's not worth spending time on this. I found related babel issue and it's apparent that namespace will never be part of that plugin because they are legacy .

I'm sorry and understand that this is likely frustrating, but namespaces are a proprietary, legacy feature. They have been replaced by specification behavior: ES Modules.

If this isn't satisfactory, you are free to continue using this feature until it is deprecated in TypeScript.

You can try what @brunolemos recommended, but aside from that, we'll not be taking any action at present time.

We've provided you with two solutions that work with our implementation, so I'm closing this as resolved.

namespace are not supported on @babel/preset-typescript

Seems like that should just about settle this issue. Either convince the Babel folks to support this, or shoot me a PR over at customize-cra adding the ts-loader, and removing the current Babel solution.

@Timer As it was said a linked babel issue, I wasn't able to find any information about why are namespaces _legacy_. Later in that discussion, it's revealed that it's more of a technical issue than a problem of being deprecated. I can live what that, but let's not spread the false accusations here :)

@brunolemos Thanks for the tip, but I've already switched back to TS fork and don't want to spend time on this anymore. It's kinda a shame. In a sense, I was looking into being able to tap into Babel world while using TypeScript without extra hassle, but this is too much blocker for me.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jnachtigall picture jnachtigall  路  3Comments

rdamian3 picture rdamian3  路  3Comments

oltsa picture oltsa  路  3Comments

fson picture fson  路  3Comments

AlexeyRyashencev picture AlexeyRyashencev  路  3Comments