-
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
Library include directives #7156
Comments
Reposting notes from other thread courtesy @mhegazy from Monday
|
Something we need to figure out -- do we rename all files to |
We discussed using the package.json file for this (either the |
Here's a write-up of how this works Library DirectivesSyntaxA library directive is a new simpler way to include definition files for external code which introduces things into the global scope. They look like this: /// <reference library="jquery" /> Note that this is similar to the familiar Library directives are designed to integrate seamlessly with the type acquisition process, as well as bundled type definitions from NPM. BehaviorLibrary definitions can be found in either primary or secondary locations. The primary library definition locations are:
When resolving a library reference, the compiler looks for a folder of the name of the library in each primary definition location. If all primary lookups fail, we defer to the secondary library locations. Because the secondary lookup locations are relative to the referencing file, it is possible that multiple files referencing the same library name might end up loading different files on disk. Conflicts in global code.This "conflict" situation occurs when two different modules claim to have dependencies on different versions of some global code. Once this happens, the definition file for one of the referencing libraries may still have errors. Use with
|
Implemented in #7775 |
In Conflicts in global code:
IMO, this in highly impractical. The consumer would not know which version(s) of typings to use for a library that is 2+ levels deep. For direct dependencies, yes. For nested dependencies, no. In reply to: #7125 (comment)
What defines a "name"? In different version of a package, they may:
For the error part, as mentioned about it won't be practical for end consumer to manage those versions.
|
It is necessarily practical by virtue of the scenario -- the user _has_ a conflict and will be resolving it by some means. Library 1 says use jQuery 1.2, library 2 says use jQuery 1.3; the user isn't going to put script tags for both in their HTML page (or if they do, they should know it's not going to work). Inlining isn't really a practical solution for a variety of reasons. |
The whole design relies on not doing this. the design relies on the "identity" of a library typing from the file name/ package name. bundelling, inlining, renaming, etc.. destroys that |
Yes, true. And as long as user not using So do you see the This is partially align with your "Problems" section in #7156 (comment) |
Do you mean
I discuss with @blakeembrey on this at typings. What is your vision? It is hard to define the identify of a library. The package manager, package name, repo name, source hosting provider can all change during the course of the life of the package. |
Today, it's just a singular string name. We expect to use DefinitelyTyped as the arbiter for who "gets" a particular name (for purposes of publishing to For people who either don't want to publish their typings (directly or indirectly), tools can choose to write to the local |
Through working on
I think that is exactly what |
To clarify: |
Can you educate me why it is not practical? How do you manage to resolve versioning of nested dependencies in the module context? Thanks. 🌹 |
|
Thanks for your explanation. 🌹
I understand the arguments in #7755. But like Blake, I'm not fully convinced either. 😛 My argument is this: I was expecting the type system of TypeScript is duck typing, and I definitely don't want or need to compare the innards of two ducks to determine if they are the same. 🌹 I see it as a design choice, but it does feel artificial and surprise users.
Agree on not bundling, that just doesn't make sense. What I mean by "inlining" is how // generated definitions/chai/index.d.ts (simplified for illustration purpose)
declare module '~chai~assertion-error' {
// assertion-error typings
}
declare module '~chai' {
// chai typings
import * as AE from '~chai~assertion-error';
...
}
declare module 'chai' {
import main = require('~chai');
export = main;
} Typings for Edit: rephrase
Not really getting this.....sorry~ 😢
Yes. Agree. However, we are not talking about bundling source code. We are talking about "inlining"/"wrapping" of typings. There is a lesser impact, but impact nonetheless. 🌷 |
This conversation also related to name conflict and versioning for module augmentation: But that can be a separate topic. |
To complete the story, the current implementation of There is a plan that can eliminate this (typings/core#1), but currently cannot be implemented because of some limitation. @blakeembrey said "there'll always be pollution until things are native in TypeScript": Blake, is it relevant to discuss that here? I don't know would that be too much detail related to |
I'd just leave it for now, it's possible I can refactor the implementation to use the new library directive features anyway. My primary concern here, however, is mentioned in the other thread (since these got kind of messy together). Will the library feature work in sub-dependencies or do those act on the whims of the top-level dependency? Ideally, I could use (or abuse) this feature and create what I want to see anyway - properly isolated module definitions down the entire dependency tree. With library directives (or types, or whatever) I could point it to the |
looks like its coming soon: https://blogs.msdn.microsoft.com/typescript/2016/06/15/the-future-of-declaration-files/ |
I tried do use primary acquisition from a local typings folder as described in this issue in but it does not seem to work. Is what is described in this issue actually included in typescript 2.0.3? |
In addition if I try to use |
Ok after digging around in other issues I found that the syntax is now:
Or you can do the same in the tsconfig file:
So now I can get tsc to pick this up :-). But it still does not resolve, and if I check the output of
So it seems the |
And digging into the source code of the compiler I found that you must set the
Now it works :-). Sorry for polluting this issue with a lot of comments but I hope it can be helpful for anyone else landing here from google like I did. Also if these options are documented somewhere I would appreciate if someone could point me there. |
Problems
/// <reference path="..." />
comments (hereafter "reference directives") currently servemultiple purposes:
The current mechanism has some common shortcomings:
This has resulted in multiple issue reports of people trying to address this:
New Use Case in Bundled Type Acquisition
An important scenario we need to address is the case where multiple typings
files need to refer to the same global set of types or namespaces. If these
libraries refer to multiple versions of the same global types, we have no
existing mechanism for resolving the conflict
Solution: Library include directive
Syntax
The proposed syntax (:bike: :house: of course) would look like this
/// <reference library="jquery/jquery.d.ts" />
Behavior
This syntax means that the compiler should include the first file found
when searching the following paths, where relative paths are resolved relative
to the project root (either the location of
tsconfig.json
, or the commonroot of all input files):
./typings/jquery/jquery.d.ts
./node_modules/jquery/jquery.d.ts
./node_modules/@types/jquery/jquery.d.ts
This search order provides the following desirable behavior:
global version in the local
typings
folder.d.ts
file will be found automaticallytypes
package can fill in for libraries which don't have bundled definitionsWe could conceivably allow for configuration of this search order in
tsconfig.json
ifneeded for complex scenarios.
UMD
Additionally, when a UMD module definition is found, its global export declaration (if present)
is added to the global scope.
All-up World
Along with the rest of the typings acquisition story, we can now have a very coherent way to
explain how file references should be managed in TypeScript programs:
import
import
, and thoseimport
s should resolve to proper modules/// <reference library = ...
directives/// <reference path = ....
directivesThe text was updated successfully, but these errors were encountered: