-
-
Notifications
You must be signed in to change notification settings - Fork 47
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
feat: add interface export to definition file #23
Conversation
kleur.d.ts
Outdated
@@ -42,4 +42,4 @@ interface Kleur { | |||
} | |||
|
|||
declare let kleur: Kleur & { enabled: boolean }; | |||
export = kleur; | |||
export default kleur; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a regression from #18 The way I understand is is that CommonJS exports have to be exported as export = FOO
, since export default FOO
would (in CommonJS terms) be exports.default = FOO
explicitly.
I might be mistaken, but it's how I've made sense of it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From what i know, the export = FOO
and export let foo: Bar
is necessary only for code generation, and not for type definition. I will do some additional testing in a CJS only environment to test the claim. Or maybe @marvinhagemeister has another idea or maybe a use case where the export default
creates the ambiguity since it would affect some of my own projects as well 😨
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay indeed it does not properly type the CJS required kleur
with it. I will try to find a better solution for it 🙇 This happens when you get used to ESM 😅
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for looking into it :)
FWIW, here's what I found about the differences: microsoft/TypeScript#7185
I believe it plays a role during ts-check and building your project, since it always has to know where modules' code is coming from & how to assemble it.
I think on your side, you need to do either of these:
import kleur = require('kleur');
// or
import * as kleur from 'kleur';
// or, pick colors
import { green, bold } from 'kleur';
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've worked around it in my project by doing this in my definition file
import kleur from 'kleur'
export interface ITextStyle {
indention: number
padding: boolean
styles: typeof kleur.bgBlack[] // Returns type Color
}
but i think i have got a idea on how to solve it, by defining a declare module "kleur/types" {}
which can be imported in ts environments.
With the example of above it would be written like this
import { Color, Kleur } from 'kleur/types'
export interface ITextStyle {
indention: number
padding: boolean
styles: Color[]
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this should solve the issue i tested it with the following scenarios
const kleur = require('kleur')
import kleur from 'kleur'
import { Color, Kleur } from 'kleur/types'
- and like this
import kleur from 'kleur'
import { Color, Kleur } from 'kleur/types'
function test (kleurInput: Kleur): Color {
return kleur.bgBlack
}
Hmm... this feels more complicated than it should be. The above import statements don't work for you? What about doing this instead? declare namespace kleur {
interface Color {
(x: string | number): string;
(): Kleur;
}
interface Kleur {
// Colors
black: Color;
red: Color;
green: Color;
yellow: Color;
blue: Color;
magenta: Color;
cyan: Color;
white: Color;
gray: Color;
grey: Color;
// Backgrounds
bgBlack: Color;
bgRed: Color;
bgGreen: Color;
bgYellow: Color;
bgBlue: Color;
bgMagenta: Color;
bgCyan: Color;
bgWhite: Color;
// Modifiers
reset: Color;
bold: Color;
dim: Color;
italic: Color;
underline: Color;
inverse: Color;
hidden: Color;
strikethrough: Color;
}
}
declare let kleur: kleur.Kleur & { enabled: boolean };
export = kleur; Of course I don't have your full setup here, but it seems to work locally. I have access to the |
That would be a alternative solution that I was also trying, it works fine in my examples too. But it would change the usage, which could lead to confusion since import kleur from 'kleur'
function test (kleurInput: kleur.Kleur): kleur.Color {
return kleur.bgBlack
} |
Hey sorry – had to step out early yesterday. Not sure what you mean by this:
Do you mean for the import statement? I'll wait to hear from you but as of right now, despite learning something new from this PR, I prefer the solution I pasted since I'm familiar with that setup & IMO it feels a lot weirder to have a separate |
No pressure 😉 The changes your proposed are now in the PR. I was talking about the part that namespace and export share a name, and what happens to the namespace when you rename the import. But I tested it and indeed the namespace name gets also changed. eg: import kleurRenamed from 'kleur'
function test (kleurInput: kleurRenamed.Kleur): kleurRenamed.Color {
return kleurRenamed.bgBlack
} Thank you so much for giving me a much better insight into TS definitions, I really had some misunderstandings and learned a good chunk of new stuff. |
Likewise! I hadn't realized you could declare sub/multiple modules within a definition file. Thanks so much @Hammster, especially for going thru the back-n-forth :) |
Changes the behaviour for #22 while preserving the previous functionality
Closes #22