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
Move named exports to properties of default export #206
Move named exports to properties of default export #206
Conversation
@sindresorhus I couldn't figure out how to update the TypeScript types correctly. I tried making the |
I think you can do: /**
The error has a response property with the `Response` object.
*/
declare class HTTPError extends Error {
constructor(response: Response);
response: Response;
}
/**
The error thrown when the request times out.
*/
declare class TimeoutError extends Error {
constructor();
}
// ...
declare const ky: {
...
readonly HTTPError: HTTPError;
readonly TimeoutError: TimeoutError;
};
export default ky; |
I tried that, but it didn't work, unfortunately (see the tsd errors in the CI logs). I got even more errors when I tried to make |
Weird. 02818df is passing for me locally. |
Maybe a caching issue? I don't know if |
Yeah, it was some kind of caching issue. I'm honestly not sure how to make this work. |
My take: As the error says when you use a type as declare namespace ky {
export class HTTPError extends Error {}
export class TimeoutError extends Error {}
};
declare function ky(): Promise;
export = ky; Would make this a CJS module similar to: module.exports = {
default: () => {},
HTTPError: class {},
TimeoutError: class {},
}; and would then require you to use That said, at a time everyone's switching to ESM, including Node.js (starting from Node 13.2), I'm not sure this is the right approach. It's turning a completely fine ESM into a CJS-like module, limiting it to always have a single export. Moreover, you have the memory footprint of adding classes to every "instance" of Would also be interested to see the type definitions TSC would output :) |
@joaovieira Adding properties to an default exported function is completely fine in JavaScript (ESM), so I'm hoping there's a way to do it in TypeScript too. |
Yeah, it's fine, but before wasn't wrong either :) Here's my investigation: // index.ts
class HTTPError extends Error {
constructor() {
super();
this.name = 'HTTPError';
}
}
class Ky {
constructor() {
}
}
const createInstance = () => {
const ky = () => new Ky();
ky.create = () => createInstance();
ky.HTTPError = HTTPError;
return ky;
};
export default createInstance(); Results in: // index.d.ts
declare class HTTPError extends Error {
constructor();
}
declare class Ky {
constructor();
}
declare const _default: {
(): Ky;
create(): any;
HTTPError: typeof HTTPError;
};
export default _default; However, the test still complains it can't find import {expectType} from 'tsd';
import ky from '.';
expectType<ky.HTTPError>(new ky.HTTPError()); |
Though I'm still of the opinion named exports are better. TypeScript users will have to use that |
…xports # Conflicts: # test/browser.js
Using @sindresorhus the tests are passing now and this is ready to merge. |
Awesome. This is much nicer 👍 |
Closes #205
This PR moves
HTTPError
andTimeoutError
to properties of the default export rather than named exports.CommonJS users can now just use
ky
instead ofky.default
. Also eliminates a warning logged during the build.