Reputation: 766
From time to time folks tell you that you should not use namespaces in TypeScript. For example here: https://typescript-eslint.io/rules/no-namespace/ (eslint error: "ES2015 module syntax is preferred over namespaces")
Of course I know what an ES module is and of course my TS code is essentially structured in ES modules.
Nevertheless in certain cases (UI components, complex events etc.) I use namespaces to bundle types (only types!), to make it easier to import and use those types later.
See the following example (this is some kind of UI component). The important thing is that later by using import { Button } from 'xyz'
you have access to the function Button
itself and all the types Button.Type
, Button.Variant
and Button.Size
which I consider extremely handy.
export { Button };
namespace Button {
export type Type = 'button' | 'submit' | 'reset';
export type Variant = 'default' | 'primary' | 'warning' | 'danger';
export type Size = 'small' | 'medium' | 'large';
}
function Button(props: {
type?: Button.Type;
variant?: Button.Variant;
size?: Button.Size;
// ... and others ...
}) {
// not important
}
[Edit: Please consider this example as a part of a widget library, not an application]
Do you consider this an anti-pattern? Please explain your answer.
Upvotes: 5
Views: 1849
Reputation: 1619
As you said, Namespace
is considered outdated. It's best to avoid it. Instead do something like:
button.ts
export type Type = 'button' | 'submit' | 'reset';
export type Variant = 'default' | 'primary' | 'warning' | 'danger';
export type Size = 'small' | 'medium' | 'large';
app.ts
import * as Button from './button'
function createButton(props: {
type?: Button.Type;
variant?: Button.Variant;
size?: Button.Size;
}) {
// do something here
}
As for why it's outdated or discouraged, well, for one thing, it can cause conflicts and unintentional overlaying of two namespaces. The pattern above puts you in the driver's seat when you import it.
Upvotes: 2