Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Best way to export interfaces for a module that only has a default export #9

Open
hodavidhara opened this issue Mar 3, 2016 · 2 comments

Comments

@hodavidhara
Copy link

This is more a question about writing type definitions than about typings, feel free to let me know if I should post this elsewhere!

I've been working on the type definitions for Griddle, which only exports a React class, essentially to be used like so:

import * as React from 'react';
import { render } from 'react-dom';
import Griddle from 'griddle-react';

render(
  <Griddle />,
  document.getElementById('root')
);

There are some interfaces in my definition that would be really great for a developer to be able to consume, but I haven't found a good way to make it available. If I simply export them along side the true default export, they need to access it in a way that doesn't look so great:

import {default as Griddle, CustomColumnComponentProps} from 'griddle-react';

If I was able to declare a namespace that contained the interface that wasn't wrapped by typings in the ambient module declaration, they could gain direct access to the interface. Something resulting like:

declare namespace GriddleReact {
    export interface GriddleProps {
        someProp: string;
    }
}
declare module 'griddle-react' {
    export default class Griddle extends React.Component<GriddleReact.GriddleProps, any> {}
}

which could then be used like:

import Griddle from 'griddle-react';
var someProps: GriddleReact.GriddleProps = {someProp: 'prop'};

Is this frowned upon because it pollutes the environment with a namespace that the consumer may not be expecting? Any other thoughts or good ways to do this?

@blakeembrey
Copy link
Member

Is this frowned upon because it pollutes the environment with a namespace that the consumer may not be expecting?

Yes.

Any other thoughts or good ways to do this?

If this is ES6 style with a default export, do how it currently is. Just export alongside the default export. Also, the syntax you're using could be simpler since it's an ES6 import: import Griddle, { CustomColumnComponentProps } from 'griddle-react'. That's what I would normally do, there's no namespacing issues and it's all on the users to do what they want. Does that help?

For ES5/CommonJS modules using module.exports, the type definition is usually a slightly different but similar pattern using a namespace.

declare function main (options: main.Options): void;

declare namespace main {
  export interface Options {}
}

export = main;

@hodavidhara
Copy link
Author

Ah I had forgotten about the syntax that allows for both default and destructuring, that does make it nicer! I guess I didn't like it because it seems a little misleading to look like you're importing something that doesn't actually exist in the library and is purely defined in the typings, but I guess there is no getting around that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants