Open unional opened 8 years ago
It is a bit easier to discuss here. :rose:
Is probably just global
as in global namespace
Based in TypeScript terms, what we described as external module declaration
is likely ambient top-level module declaration
. Since all typings are ambient, we might drop the word ambient
and just call it top-level module declaration
top-level namespace declaration
Interesting on the translating. I thought I was pretty accurate to the TypeScript terms. Global is a new feature for augmentation. When you say all typings are ambient, are you talking about from the consumption perspective or the publishing perspective? When we publish, they definitely aren't ambient - the basic distinction from TypeScript is that ambient declarations have no top level import
or export
.
When you say all typings are ambient, are you talking about from the consumption perspective or the publishing perspective?
They seems to define it neutrally:
We call declarations that don't define an implementation "ambient". Typically these are defined in .d.ts files. If you're familiar with C/C++, you can think of these as .h files or 'extern'.
Global is a new feature for augmentation
The global
I refer to is just global namespace, not global
as in global augmentation
.
I'll continue to update the two above comments as we discuss. So that when we are done, they will be close to a complete doc. Feel free to edit them. :rose:
the basic distinction from TypeScript is that ambient declarations have no top level import or export.
On this note: https://github.com/Microsoft/TypeScript-Handbook/blob/master/pages/Modules.md#ambient-modules
We could define each module in its own .d.ts file with top-level export declarations, but it's more convenient to write them as one larger .d.ts file. To do so, we use a construct similar to ambient namespaces, but we use the module keyword and the quoted name of the module which will be available to a later import.
- Refers to both top-level export declaration and
declare module "name" {
.
Seems like they do not have a clean distinction between the two. That's why they have that paragraph there and it prohibits mapping.
However they have the the phrase top-level declaration, that's why I guess it could be ambient top-level module declaration or ambient top-level namespace declaration for global namespace
.
Sounds good, I think you've got this covered better than me at this point.
:beer: Some action items:
Terms to clarify:
source vs distribution channel vs package manager vs delivery mechanism
lib vs env vs global in registry
Script vs global in typings install
. After a while I start thinking script make sense:
User is using the package in a script tag.
Conversation transferrred from Gitter:
https://github.com/typings/registry#structure
lib for shared environment functionality (ambient) env for programming environment typings (ambient) global for global libraries (ambient)
Hmm. Without examples those 3 definitions don't hold a great deal of meaning. Having read the above I couldn't tell you on what basis you'd choose where to put mocha / Angular / jquery etc. They all seem to be different shades of the same thing. And without a clear distinction, a satisfactory way to draw the line, I think the difference is unhelpful to users. As it stands I think this just provides confusion which could well be avoided. Happy to be put right if there is a clear rule that can be applied 💐
To summarise: we need clear definitions for the following:
lib
env
global
Without clear definitions I feel we should think about whether these terms are helpful and worth keeping.
Related to the registry structure, I'm having difficulty in asking the right question in the generator:
https://github.com/typings/generator-typings/blob/beta/generators/app/index.js#L71-L86
Try to use lib
, env
global
, but it doesn't seem to fit.
@unional I'm guessing you've refactoring since then. What are you asking? I thought lib
, env
and global
were pretty well defined (for inherently unstructured data):
lib
- Use for "common utilities", basically stuff that doesn't fit into other ambient categories (E.g. the API definitions someone wanted to add recently)env
- Programming environments. E.g. window
, atom
, electron
, node
, etc. Stuff that comes with execution, even mocha ...
global
- Global programming libraries. Still require an import somehow, but they are purely global.Wrap vs unwrap version terminology: https://github.com/Microsoft/TypeScript-Handbook/issues/242
To me at least lib
and env
are a little unclear.
window, atom, electron, node,
Totally.
mocha
though I find tricky. Whilst it can be installed as a global for use on the command line, i think that's not the only use case? I'm on surer footing with karma and jasmine which are (I think) in the same bracket. I mostly use these as part of a gulp watch process. Though occasionally I will use the command line install (if I'm generating code coverage for instance) Is the rule for env
that it's either part of an environment right from the off or that it can be made to be with an npm install -g
?
That would seem to be a clear ish rule (and worth recording if so).
lib
is still rather unclear to me tbh. What makes something not fit well into ambient?
Not trying to be difficult by the way. I'm just thinking that if it's not clear in our own minds (well, my own mind!) then that confusion is likely to result in things getting badly categorised in the Registry and users also rather puzzling over where they're supposed to find things.
I've been bugging Blake to death on many things. I think he handles it well. :stuck_out_tongue_winking_eye:
He does! :tulip:
What makes something not fit well into ambient?
They are similar, I just wanted to separate the odd-balls that were external modules from the odd-balls that were ambient declarations. That's pretty much it.
Check out what's in lib/
right now, it's kind of random stuff: https://github.com/typings/registry/tree/master/lib.
With mocha
, jasmine
, etc. you're right. There's both the env
component and the npm
component. That's something I've been trying hard to drill in everywhere, but I've had push back on thinking about it like this because it seems most people only want to think about it as a single module. However, if you used it as a single module that would introduce non-existing variables into the global scope.
Will check our lib
and reflect. Ta.
there's both the env component and the npm component.
I'm not too sure what this means? Do you mean env
is extended by the npm install -g
use case?
However, if you used it as a single module that would introduce non-existing variables into the global scope.
I don't quite follow this. When I'm using jasmine I include the jasmine.d.ts which brings describe
and it
etc along to the party. But they are only part of my context in my test code. I have different TypeScript contexts for my src
and for test
. I'm guessing you're thinking about a use case where people share the same context for their test
code and their src
code?
When I'm using jasmine I include the jasmine.d.ts which brings describe and it etc along to the party.
Yes, that's the env
version. The other version would come along if you did import jasmine = require('jasmine')
. Right now, most people are only interested in the env version anyway, but I believe we should try to keep them conceptually separate otherwise I'm introducing describe
, it
, etc. into production code.
otherwise I'm introducing describe, it, etc. into production code
Just for clarity - this is true in the case where you share context between your test
and your src
right? In that case you could write a describe
in your src
code and not have the compiler complain even though describe
does not exist at execution time. Conversely, it's not possible where there are separate contexts for test
and src
.
Sorry to bang on, just want to be sure I understand you correctly.
this is true in the case where you share context between your test and your src right?
Yes, correct.
Conversely, it's not possible where there are separate contexts for test and src.
It is possible with the current format (DefinitelyTyped) since it would mix the module and the environment definitions together in one file. That would cause usage where you're just using the module import syntax to also include the globals like describe
, it
, etc. It's a little edge-casey right now, but it's legitimate to me (I sometimes use the programmatic API without the env/globals that are part of mocha ...
, like when writing a plugin for these systems).
It is possible with the current format (DefinitelyTyped) since it would mix the module and the environment definitions together in one file.
I don't quite follow that? As I understand it, contexts are built based on tsconfig.json
and import statements.
Perhaps an example. Here's a repo of mine. It has this test tsconfig.json
which includes jasmine.d.ts
and react-addon-test-utils.d.ts
. The same repo actually has 2 src
contexts; one for the react demo and one for the npm package library which create contexts which do not include either jasmine.d.ts
and react-addon-test-utils.d.ts
.
In the test code here we do not use import
to bring jasmine in; rather it's part of the environment brought in by karma.conf.js
.
So in this case jasmine is already part of env
. So to loop back again:
It is possible with the current format (DefinitelyTyped) since it would mix the module and the environment definitions together in one file.
I don't think it is possible to use describe
, it
in either of the src
contexts without tsc going:
But it is possible? :confused:
BTW, whilst jasmine becomes part of the environment, react-addons-testutils does not (imported). Sorry for confusion.
I don't think we're discussing the same thing. Let's try to reset. You've got the env
usage fine (which is just "put stuff in the global namespace for testing"). However, that only occurs when running in a test environment. Sometimes, these modules can be used programmatically via require
. That does not populate the global environment.
Simple example: https://github.com/blakeembrey/co-mocha. That's a plugin manipulating the programmatic API of Mocha, not the environment mocha
generates when executing tests. It's entirely probable when working with these types of plugins that you want one interface or the other - not both. Hence, I would like to promote, where possible, clear separation of concerns. This may be just a pipe dream of mine though.
You may be right about the 🚬☁ (closest emoji gets to "pipedream).
I think I follow you. Unfortunately I can't see any examples in the Registry that nicely demonstrate the delineation. I kind of feel that if we want this to happen we need something to point at and say "do it like this! Behold the wonderful good practice!"
Any candidates? Mocha looks like it only appears in env
? Should it have counterparties in global
? Should it be different if so? And if so, in what way?
Sure, I can go in and do one as an example. Mocha is what I'm most familiar with - it would be putting one version in env
and another in npm
. On a side-note, preferably we would publish with the package with two definitions. E.g. npm install mocha
, then require('mocha')
would point to the typings
in package.json
(normal behaviour) which gives up the programmatic API, then using the env interfaces would require some manual hookup (E.g. put node_modules/mocha/env.d.ts
into tsconfig.json
or typings install npm:mocha/env.d.ts -SA
).
Thanks - that'd be v helpful!
Btw is there a scenario when a Typing could appear in env as well as lib as well as global? Or is it one only?
Btw is there a scenario when a Typing could appear in env as well as lib as well as global? Or is it one only?
Yes, env
+ global
(because global
is the same spectrum as npm
or bower
).
No, env
+ lib
or global
+ lib
(because lib
are random things that don't really fit elsewhere).
Edit: Not to say that lib
isn't useful, it's just they aren't a library or a specific definition - but really just helpers people are sharing.
Ta. So if something is in lib it isn't anywhere else?
Nope, definitely not.
Cool. Rules as understood so far:
env
- it's either part of an environment right from the off (eg node
) or that it can be made to be with an npm install -g
(eg mocha
)
global
- brings in new items to the global scope. (eg knockout
)
lib
- the awkward package at the back of the class that just refuses to fit in
npm
- packages on npm
👍 The only thing I'd change is phrasing on mocha
. It's not the global installation that makes it provide an environment. I'll think about how to phrase it, but it's more that it provides environment variables based on specific execution. E.g. node via node
CLI, mocha via mocha
CLI, browsers via browsing, etc.
Yeah - you're right. Need careful description. :+1:
How to write typings
When you write typed definitions for DefinitelyTyped, you create a pull request on DefinitelyTyped with the corresponding
.d.ts
file and you are done. In the.d.ts
file you write either anambient internal module
orambient external module
as in the handbook.Things are a little bit different when you write a definition with Typings.
While it is definitely not harder than writing typed definitions for DefinitelyTyped, there isn't a clear term of reference on how to write a definition with Typings.
First things first...terminology
Going through the handbook and spec to understand everything you need to write typings is a great thing to do, but it isn't fun. Also, since TypeScript is rapidly improving, some information in the handbook is out of date.Here are a list of terms that are relevant in writing typings so you can cut the chase.
If you like to learn by example, you can skim through this section and read the next one. Things will become more clear as you move along.
Typescript terminologies
ambient (declaration)
http://www.typescriptlang.org/Handbook#modules-working-with-other-javascript-libraries
https://github.com/Microsoft/TypeScript-Handbook/blob/master/pages/Modules.md
https://github.com/Microsoft/TypeScript-Handbook/blob/master/pages/Modules.md#ambient-modules
https://github.com/Microsoft/TypeScript-Handbook/blob/master/pages/Namespaces.md#introduction
https://github.com/Microsoft/TypeScript-Handbook/blob/master/pages/Namespaces.md#ambient-namespaces
declare namespace D3
+declare var d3: D3.Base
to declare global object.declare var d3
is needed because in the exampleD3
is a non-instantiated namespace.external module
https://github.com/Microsoft/TypeScript-Handbook/blob/master/pages/Modules.md
export =
andimport = require()
https://github.com/Microsoft/TypeScript-Handbook/blob/master/pages/Modules.md#export--and-import--require
export =
, TypeScript-specificimport X = require("module")
must be used to import the module.https://github.com/Microsoft/TypeScript/wiki/What's-new-in-TypeScript#support-for-default-import-interop-with-systemjs
import X from 'module';
orimport * as X from 'module';
. The exact behavior depends onmodule: system|commonjs
andallowSyntheticDefaultImports: true|false
.internal module
https://github.com/Microsoft/TypeScript-Handbook/blob/master/pages/Namespaces.md#introduction
module
https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md#111-modules
https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md#16-classes
module keyword
https://github.com/Microsoft/TypeScript-Handbook/blob/master/pages/Namespaces%20and%20Modules.md
module X {
is equivalent to the now-preferrednamespace X {
declare module X {
, you are actually writingdeclare namespace X {
.https://github.com/Microsoft/TypeScript/issues/6808
module
keyword will be gradually deprecated.module pattern
https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md#110-namespaces
namespace
https://github.com/Microsoft/TypeScript-Handbook/blob/master/pages/Namespaces.md#namespacing
https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md#10-namespaces
https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md#110-namespaces
https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md#101-namespace-declarations
https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md#23-declarations (need to scroll down a bit)
declare namespace X {
creates a global namespaceX
.declare namespace X {
in such file does not create global namespaceX
.References