-
Notifications
You must be signed in to change notification settings - Fork 12.5k
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
Possible limitations of *.d.ts files #18791
Comments
In the case above, there is a different shape depending on which loader is being used and I am not sure that makes a huge amount of sense. The AMD shape is different than the CommonJS shape. While that is technically possible, that feels like that is an issue. Under AMD, the shape would be just Instead of re-writing as classes (when they aren't) you could do something like this, which is what we do for Dojo 1, which is AMD. If there are weird shapes, we deal with it in the global namespace. We haven't had the time/desire to move to UMD type definitions: declare module 'dijit/form/FilteringSelect' {
type FilteringSelect<C extends dijit.form.Constraints, T extends Object, Q extends string | Object | Function, O extends dojo.store.api.QueryOptions> = dijit.form.FilteringSelect<C, T, Q, O>;
const FilteringSelect: dijit.form.FilteringSelectConstructor;
export = FilteringSelect;
} We use the older |
Hi. I dropped the import * as BigJs from 'big.js';
const lookABigJs = new BigJs.Big(1); or import { Big } from 'big.js';
const lookABigJs = new Big(1); That will fail at runtime however, if webpack actually bundles the AMD export, since the shape of the AMD and commonjs exports is different, which I didn't expect to be a problem.
Documentation for the loader: https://webpack.js.org/loaders/imports-loader/#disable-amd To make this less painful, I suppose the best would be to match the exports in big.js itself (add the named export to AMD too). on 2. Rewriting as class won't help with 1. anyways. To a user both of these look approximately the same: class Big {
}
exports = Big; interface BigConstructor{
}
const Big: BigConstructor;
exports = Big; I hope this helps. Let me know if I can help with this further |
Re this code: import * as BigJs from 'big.js';
const lookABigJs = new BigJs(1); See https://stackoverflow.com/questions/39415661/what-does-resolves-to-a-non-module-entity-and-cannot-be-imported-using-this . Working hard trying to make this work is counterproductive because it's not legal according to the ES6 spec. In general when you have a library that you want to import and then immediately
These libraries will hopefully be moving their class export to a default export in the future so you can write
|
Hi @RyanCavanaugh / @googol and @kitsonk, Thanks all for responding. To take things in reverse order:
I think it's clear that decomposed classes are the only game in town. Fine. @kitsonk expresses the problem well when he says:
To be clear, I think it's "possible" in JavaScript but unless I've misunderstood it's not "possible" to model in TypeScript. Please do correct me if I misunderstood there. Thanks for sharing a proposed solution; indeed I can drop this in:
Which allows us to do this:
However, whilst it gives with one hand it takes with the other. What I really want to do, and what @googol is doing it seems, is this:
The above definition amend torpedos the usage above. Also, since that's very much the desired usage I think that's a backward step. I feel you @googol when you say this:
Our codebase is ES6 as well. However the only way you have it working at present is by killing AMD imports in webpack. I don't think this is good as AMD imports might be needed for some other package in the future. So I don't think this is an advisable course of action in the long term. Something I've tried is amending
I've tested this locally and it works. I'm up for sending a PR to the 'big.js' project and hopefully getting that into a future release. Is that the only route out of dodge? But am I then right in thinking that this a limitation of TypeScript definition files as is? Where the different module format is different shapes (as here) then there is no way to cater for that in definition files? It sounds like "yes" which would be good information to have. I think it's almost certainly "yes" since TypeScript doesn't know how the file is being delivered (i.e. which module format served it up) Oh and as an aside:
unfortunately does not inspire webpack into using the CommonJS import. (But upon reflection I guess that makes sense) |
Last night I raised a PR against big.js to fix the problems we were experiencing yesterday: MikeMcl/big.js#87 @googol made a better suggestion. The @MikeMcl implemented that and released v4.0 of big.js overnight. @googol submitted another PR this morning which I merged: DefinitelyTyped/DefinitelyTyped#20096 v4.0 of the type definitions were published this morning. Yay open source! I might try and write this up as a blog post. Spread the knowledge and all that. |
Hello!
I'm a member of the Definitely Typed team and I'm confused. I've spent a number of hours trying out various scenarios / solutions. All have died like tears in rain. So I turn to you good folks of TypeScript; set me straight! I'm implore you; right my addled brain. Or tell me that I'm right; there's limitations when it comes to defining definition files.
The story begins here:
Once upon a time (yesterday) we decided to use big.js in our project. It's popular and my old friend @nycdotnet apparently originally wrote the type definitions which can be found here. They were updated by @googol a couple of days ago.
Our project uses webpack to bundle and I thought we'd be off to the races there and then. We weren't.
There's a couple of problems that I encountered. Late me take them in turn.
UMD / CommonJS and Global exports oh my!
My usage code was as simple as this:
If you execute it in a browser it works. It makes me a
Big
. However the TypeScript compiler is not happy. No siree. Nope. It's bellowing at me:So I think; huh! I guess @googol just missed something off when he updated the definition files. No bother. I'll fix it. I take a look at how
big.js
exposes itself to the outside world. Thusly:Now, webpack is supersmart; it can take all kinds of module formats. That includes AMD / UMD. So when webpack encounters the above code it rolls with the AMD branch and the
import * as BigJs from 'big.js';
lands up resolving to thereturn Big;
above.Big
is essentially the constructor function ofbig.js
. I took a look at the relevant portion of the definition file I find this:Which tells me that
Big
is being exported as a subproperty of the definition. I do a little dance with options that might occur to me; adding aexport = Big
seems like a good option. Hey! It works in my local project; success! So I fork DT and add my amend to the definition file only to be confronted by this:Huh. Now I'm stuck. It occurs to try something different.
Static .... constructors?
I dig my way through the various examples and look for the example closest to what
big.js
actually is:https://www.typescriptlang.org/docs/handbook/declaration-files/templates.html
The most obvious candidate is the
module-class.d.ts
template.big.js
is essentially a class so I should rewrite the definition file accordingly. I do. Look at the first lines below and you will see a problem:Yup the constructor function exposed by big.js is more than just a constructor function. Alas.
https://github.com/MikeMcl/big.js#use
As you can see, the constructor function can be used to directly instantiate a
Big
(soBig(1)
is legitimate usage). What's more there's this valid use case:What's more, using the approach laid out in the template I can't expose
Big
as both the child export (for commonjs) as well as the default export for AMD and commonjs. So again I'm toast.Help me, I'm dying
I'm not; I know. I'm sure this is possible and I'm just missing how.
But it definitely (ha!) seems that there's some holes in the definition file templates that are in need of filling. Could you answer this question and hopefully we can improve the templates off the back of it. I'm happy to help with that if I can.
There's a related comment here which may prove relevant: DefinitelyTyped/DefinitelyTyped#3548 (comment) However; it's kind of old and so I'm not sure if it still applies.
As mentioned; I'm probably the idiot. But if I'm confused I guarantee others are. Please help me.
To Summarise
The text was updated successfully, but these errors were encountered: