I noticed that many ambient declaration files declare a namespace and a module that merely exports the namespace, usually using some gymnastics that I don't really understand. For example, in react.d.ts you see this:
declare namespace __React {
... entire API of the react library ...
}
declare module "react" {
export = __React;
}
Why both a namespace and a module? Why not just declare the module with the library API inside it?
Why is the namespace called __React and not simply React? That seems like a rather awkward "don't use me" name, yet IntelliJ IDEA has imported this all over my source code and it seems to work.
This pattern is used to support UMD libraries.
These libraries generally put something into the global scope if they're loaded through a <script ...> tag, but return something to a module loader if invoked via a module system like RequireJS, CommonJS, or SystemJS.
In TypeScript, this means that if you import the module called 'react', you should get the same type as if you reference the global identifier React.
Most definition files simply write their .d.ts files such that the module shape and the global variable are always both present; the React authors didn't like that you could accidently refer to the global React if you were using a module loader (in which case the global wouldn't actually be there) so they separated out the declaration into __React, a separate .d.ts file that declared a global called React, and a module declaration for "react".
Related
I've noticed that files inside the react-native/Libraries can be imported without specifying the full path.
Like,
const EdgeInsetsPropType = require('react-native/Libraries/StyleSheet/EdgeInsetsPropType');
Is the same as,
const EdgeInsetsPropType = require('EdgeInsetsPropType');
How does this work?
In the case of the EdgeInsetsPropType module, those should be the same thing. The reason that you can import that module directly by its name is because of this line.
The #providesModule EdgeInsetsPropType comment is what makes it so you can import it directly. Here is a good basic explanation of why #providesModule works the way it does.
The packager uses two methods to look up modules. The first is based
on docblock headers: if you write "#providesModule X" in the first
docblock this enables require('X'). The other method is Node's
resolution.
This description was taken from this comment on Github.
To get the Flow type-checker to work with multiple files you need to import and export modules, but the basic setup with Babel does not erase the module keywords, leading to browser problems like
SyntaxError: export declarations may only appear at top level of a module
and
SyntaxError: import declarations may only appear at top level of a module
What's the proposed solution to this?
My babelrc:
{
"plugins": [
"transform-flow-strip-types"
]
}
The Javascript source
export class MyClass {}
gets transformed to the exact same.
Wanted output is
class MyClass {}
The transform-flow-strip-types plugin only removes Flow syntax extensions, but import/export is part of the ES2015 spec. To compile those as well, you need to add some more plugins. preset-es2015 will include these by default or you can use one of the babel-plugin-transform-es2015-modules-* plugins. Hope this helps!
Although I have followed and tried everything from This Thread and read all of Apple's Guide of Swift-ObjC interoperability, I'm unable to recognize or use Swift fies in my project.
I have created a Swift file that declares/defines a class called TorusView that inherits from UIView. I've tried to gain access to this class in another class MenuView by importing the bridging header, importing the Swift class, importing the class with the syntax *-swift.h (which seems to now be *.swift.hin Xcode7.2). I've made all of the modifications to my target build settings recommended in that lengthy Stack question and a variety of others from google searches.
Nothing I've tried has allowed me to create a TorusView objective in my objective-C class.
You need to import a header file YourAppName-Swift.h, it contains all the public (and internal if same target) declared types in Swift.
first: Build Settings --> defines module --> YES.
second:Product Module Name -->YOUR project NAME.
last:improt "YOUR project NAME-Swift.h" in your Object-c file
like this:
enter image description here
I've tried reading several blog posts but TypeScript modules still have me totally confused. In particular, I have used 3 different modules (all installed via npm) and each seems to show totally different behaviour:
(1) I can import and use Angular 2 from npm like this in my .ts:
import {bootstrap, Component, Directive, CORE_DIRECTIVES, FORM_DIRECTIVES} from 'angular2/angular2';
Then in my html I have:
<script src="../node_modules/angular2/bundles/angular2.dev.js"></script>
This has the following results:
The TypeScript compiler knows to look for the angular2.d.ts file under node_modules, even though I just said "angular2/angular2"
The TypeScript compiler adds "var angular2_1 = require('angular2/angular2'); to the output JavaScript
The browser does not attempt to load the angular 2 JavaScript again despite the presence of the require, it somehow knows it's already loaded it via "angular2.dev.js" in the script tag
(2) The npm D3 module does not have a typescript definition, but I can download the one from DefinitelyTyped and then use it by putting:
/// <reference path="../../typings/tsd.d.ts" />
at the top of my .ts. and
<script src="../node_modules/d3/d3.js"></script>
in my html. It seems that being an old-style module it doesn't need an import statement, and as long as I leave it here the output JavaScript works fine. If I do try to use an import statement immediately after the reference line:
import * as d3 from 'd3';
then as with Angular2 it now adds:
var d3 = require('d3');
to the output JavaScript. However, unlike with the Angular case it doesn't realise it's already loaded the JavaScript via the script tag, and so the browser tries and fails to load a file simply called "d3" from the same directory as the html file, which fails.
(3) The npm Phaser module does include a .d.ts file, in a "typescript" subdirectory of the npm module. This is an old style module ("declare module Phaser"), so it seems I need not use "import.." syntax but instead just:
/// <reference path="../node_modules/phaser/typescript/phaser.d.ts"/>
at the top of my .ts file, as with the D3 example. The TypeScript compiler is happy, but unlike with the D3 example, under some circumstances (I haven't worked out quite what yet, doesn't seem to always happen) it outputs:
var phaser_1 = require('phaser');
in the JavaScript even when I haven't used an import statement. I'm not even using commonjs/requirejs in my phaser project, so "require" isn't even defined, causing failure.
And for completeness, unlike with either the Angular or D3 example, if I try putting an import statement after the reference line:
import * as Phaser from 'Phaser';
even the TypeScript compiler isn't happy. Perhaps in the D3 example the TypeScript compiler is treating the tsd.json or typings folder from DefinitelyTyped in special way, or maybe there is some other reason the import compiles for D3 but not for Phaser.
I have all sorts of questions:
1) What determines whether the TypeScript compiler includes a "require(...)" line in the output JavaScript?
2) Under what circumstances does the TypeScript compiler know where to find an external module in "npm_modules" when using "import", with or without needing a reference line at the top of the file?
3) Under what circumstances does the TypeScript compiler know where to find an ambient module in "typings" when using "import", with or without a "reference" line at the top of the file?
4) Under what circumstances does the TypeScript compiler know where to find an ambient module in "npm_modules" when using "import", with or without a "reference" line at the top of the file??
5) Maybe a commonjs/requirejs question rather than a typescript question, but if the TypeScript compiler does output a "require" line in the JavaScript, what do you do if the source of the JavaScript module is not set up with ES6 module exports?
1 ) I can import and use Angular 2 from npm like this in my .ts:
This is because
angular2 ships with its .d.ts file
The browser doesn't attempt to read require because of magic in angular2.dev.js
The npm D3 module fails && the phaser module fails at runtime
They don't have the magic you get from angular2.dev.js. Use something like webpack or browserify to provide this magic.
Unlike with either the Angular or D3 example, if I try putting an import statement after the reference line: import * as Phaser from 'Phaser';
This is because of how Phaser definition is declared. Apprarently it is missing declare module "Phaser" which is what is provided with d3 see here and angular.
In my project I have an doSomething.m and soSomething.h files with the only C function:
void doSomething() {
}
The first question: what should I do to make this function accessible from any place in my code without needing to import any headers?
Note: I guess that to solve this problem the doSomething.h file is not needed at all, but its presence/absence is not a restriction.
I have the following pieces of knowledge but I can't have the whole picture of what is needed:
I can use some another function with attribute((constructor)) that will be run at compilation runtime and it could do some manipulations to register doSomething;
_class_addMethod_ adds methods on "runtime". But I don't know how to resolve "the class of global namespace";
NSObject's + load method but it is not relevant here.
The second tricky question on top of the first: when I will have an answer to the first question, how can I then prevent "Implicit declaration of function 'doSomething' is invalid in C99" exactly for the function doSomething and not for the all others?
UPDATE: I forgot to exclude from the consideration the following options:
.pch file, global headers
The files where I want to use doSomething method should not contain any additional declarations like extern void doSomething()
Well you cant really make it so you dont have to import a header, what you can do however is add the include into your pre compile header
Look in the "Supporting Files" folder in your project.
you will see a file like thise
<ProjectName>-prefix.pch
add your import at the bottom of this file. and every file will then have all the imports added here.
Note
I use Xcode
I guess if your using another IDE such as for GnuStep you would likely have another place similar. I dont know how the other IDE's work.
In the file where you want to use it, import it:
extern void doSomething (void);