typings / core

*DEPRECATED* The core logic for Typings
MIT License
13 stars 11 forks source link

Standardize Terminologies #12

Open unional opened 8 years ago

unional commented 8 years ago

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 an ambient internal module or ambient 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

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'.

  • Declaration that don't define an implementation
  • all .d.ts files
  • I think it is named so to describe "These files describe the target JS in ambient to the TS world"

    ambient modules

https://github.com/Microsoft/TypeScript-Handbook/blob/master/pages/Modules.md

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" {.

    ambient namespaces

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

https://github.com/Microsoft/TypeScript-Handbook/blob/master/pages/Modules.md

https://github.com/Microsoft/TypeScript-Handbook/blob/master/pages/Modules.md#export--and-import--require

https://github.com/Microsoft/TypeScript/wiki/What's-new-in-TypeScript#support-for-default-import-interop-with-systemjs

https://github.com/Microsoft/TypeScript-Handbook/blob/master/pages/Namespaces.md#introduction

https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md#111-modules

https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md#16-classes

https://github.com/Microsoft/TypeScript-Handbook/blob/master/pages/Namespaces%20and%20Modules.md

https://github.com/Microsoft/TypeScript/issues/6808

https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md#110-namespaces

https://github.com/Microsoft/TypeScript-Handbook/blob/master/pages/Namespaces.md#namespacing

Instead of putting lots of different names into the global namespace, let's wrap up our objects into a namespace.

  • Top-level namespace will be global (if the file is not a top-level declaration, see below)

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

Namespaces are either instantiated or non-instantiated. A non-instantiated namespace is a namespace containing only interface types, type aliases, and other non-instantiated namespace. An instantiated namespace is a namespace that doesn't meet this definition. In intuitive terms, an instantiated namespace is one for which a namespace instance is created, whereas a non-instantiated namespace is one for which no code is generated.

  • No code is generated for non-instantiated namespace
  • i.e. it can only be used as type
  • A namespace instance is created for instantiated namespace
  • i.e. at top-level, it creates a global namespace object

    top-level declaration

https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md#23-declarations (need to scroll down a bit)

unional commented 8 years ago

It is a bit easier to discuss here. :rose:

unional commented 8 years ago

Translating Typings terms to TypeScript terms

Ambient

Is probably just global as in global namespace

External module declaration

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

Ambient module declaration

top-level namespace declaration

blakeembrey commented 8 years ago

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.

unional commented 8 years ago

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'.

unional commented 8 years ago

Global is a new feature for augmentation

The global I refer to is just global namespace, not global as in global augmentation.

unional commented 8 years ago

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:

unional commented 8 years ago

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.

blakeembrey commented 8 years ago

Sounds good, I think you've got this covered better than me at this point.

unional commented 8 years ago

:beer: Some action items:

unional commented 8 years ago

Terms to clarify:

unional commented 8 years ago

source vs distribution channel vs package manager vs delivery mechanism

unional commented 8 years ago

lib vs env vs global in registry

unional commented 8 years ago

Script vs global in typings install. After a while I start thinking script make sense: User is using the package in a script tag.

johnnyreilly commented 8 years ago

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:

Without clear definitions I feel we should think about whether these terms are helpful and worth keeping.

unional commented 8 years ago

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.

blakeembrey commented 8 years ago

@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):

unional commented 8 years ago

Wrap vs unwrap version terminology: https://github.com/Microsoft/TypeScript-Handbook/issues/242

johnnyreilly commented 8 years ago

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.

unional commented 8 years ago

I've been bugging Blake to death on many things. I think he handles it well. :stuck_out_tongue_winking_eye:

johnnyreilly commented 8 years ago

He does! :tulip:

blakeembrey commented 8 years ago

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.

blakeembrey commented 8 years ago

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.

johnnyreilly commented 8 years ago

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?

blakeembrey commented 8 years ago

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.

johnnyreilly commented 8 years ago

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.

blakeembrey commented 8 years ago

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).

johnnyreilly commented 8 years ago

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:

image

But it is possible? :confused:

johnnyreilly commented 8 years ago

BTW, whilst jasmine becomes part of the environment, react-addons-testutils does not (imported). Sorry for confusion.

blakeembrey commented 8 years ago

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.

johnnyreilly commented 8 years ago

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?

blakeembrey commented 8 years ago

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).

johnnyreilly commented 8 years ago

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?

blakeembrey commented 8 years ago

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.

johnnyreilly commented 8 years ago

Ta. So if something is in lib it isn't anywhere else?

blakeembrey commented 8 years ago

Nope, definitely not.

johnnyreilly commented 8 years ago

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

blakeembrey commented 8 years ago

👍 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.

johnnyreilly commented 8 years ago

Yeah - you're right. Need careful description. :+1: