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

Export types from index.d.ts #252

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

martinmcwhorter
Copy link

@martinmcwhorter martinmcwhorter commented Jan 16, 2020

This is a BREAKING CHANGE for TypeScript which allows export of types.

Where in TypeScript users would use,

import * as Enquirer from 'enquirer';

they would now do:

import Enquirer from 'enquirer';

This PR adds exporting of the PromptOptions type so that developers can type check objects before passing them to prompt(..)

let question: PromptOptions = { name: 'test', type: 'text', message: '' };

More individual types can be exported if this approach is approved, as it would be beneficial for TypeSrcript devs.

This PR also exports the prompt(..) function to allow idiomatic import import { prompt } from 'enquirer'; of prompt.

This is a BREAKING CHANGE for TypeScript which allows export of types.
@g-plane
Copy link
Member

g-plane commented Jan 17, 2020

I'm curious about why we changed to use default export/import instead of namespace.

@martinmcwhorter
Copy link
Author

martinmcwhorter commented Jan 17, 2020

First, this is to allow exporting types at the root level.

Second, this makes the imports more idiomatic with ESM imports: import { prompt } from 'enquirer';

Third, this brings it more inline with the actual JavaScript. The default export is a class.

In TypeScript namespaces solve a few problems, mostly legacy that Enquirer doesn't suffer from:

  • legacy browser JavaScript that was written without commonJS or ESM modules
  • for definitions for object namespaces used in mostly legacy code like: goog.dom.createNode()
  • namespaces prevent collisions when using legacy ambient reference /// <reference path="some.d.ts"/>

Enquirer does not fall into any of these categories.

By moving away from the namespace in .d.ts -- the definitions start to look more like what they would be if Enquirer were written in TypeScript -- and the .d.ts were generated at build time.

When using a namespace as a single export = Enquirer, breaks the ability to destructure imports.

Example: import { prompt, PromptOptions } from 'enquirer';

If this is approach is acceptable, it can be expanded then to export other types:

import { prompt, PromptOptions, Choice} from 'enquirer';

@unional
Copy link

unional commented Jan 17, 2020

The default export is not a good idea because the JavaScript is still in commonJs.

Using the import Enquirer from ‘enquirer’ syntax is simply setting esModuleInterop in your tsconfig.json

@martinmcwhorter
Copy link
Author

martinmcwhorter commented Jan 17, 2020

The point of this PR is not to use import Enquirer from 'enquirer', that is a side effect if this fix.

You cannot have multiple exports when you use export = Enquirer regardless of the tsconfig of the consuming application.

The purpose of this PR is to allow idiomatic type exports, which cannot be exported when export = Enquirer.

@unional
Copy link

unional commented Jan 17, 2020

That is not true. You can do it with namespace.
You can check out the typings that I'm working on: https://github.com/unional/enquirer/tree/typings

In fact, I believe that is a better way to organize the types.

The bottom line thou, is that the typings should stay true to the code.

If you define your typings to be export default Enquirer, then it will not be correct when someone try to use the library in commonjs format:

const enquirer = require('enquirer')

// typings indicates this is Enquirer class but in runtime it is undefined
enquirer.default

This will break many JavaScript users because TypeScript language server is used to power JavaScript in IDE such as VS Code.

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

Successfully merging this pull request may close these issues.

None yet

3 participants