What it does 'declare' in Javascript? - javascript

Taking a brief look of electron-react-boilerplate repository in github I realized a code in javascript that couldn't understand.
declare module "flow-bin" {
declare module.exports: string;
}
What it does declare?, it's part of ES6, ES7? I've searching in the way though can't find something about it. Anyone can give me some information about what it mean?

That is typescript's grammar. Use to
ambient module declaration
Typescript use declare to do a strict type checking.Then make a grammar check before compile.For eg.
declare var jQuery: (string) => any;
jQuery('#foo');
The above code declare that the jQuery accept a string parameter.

Related

Change in builtin objects of JavaScript IntelliSense inside VSCode does not show

When I add a function to the Math object, it does not show inside IntelliSense of VSCode.
Math.dot = function (a,b) {};
If you don't have one already, create a type declaration module file (Ex. index.d.ts) in the root of your project folder, and add to it the following:
declare interface Math {
doc: (a:number, b:number) => number;
}
You can read more about type declaration module files in the official docs at https://www.typescriptlang.org/docs/handbook/declaration-files/templates/module-d-ts.html.
In simpler cases, you can just use JS Doc comments, since a basic subset of JS Doc comments are supported by VS Code's intellisense facilities. As far as I know, this is not one of those supported cases (declaring the type of a function on an existing global object).

VS Code JS: Why / when do definitions break?

I use VS Code for JavaScript.
Definitions within a file work sometimes, but not others. Does anyone know why they fail?
In this example, VS Code finds the definition for edit easily. There is no occurrence of the word 'something' anywhere else in this file. Completely unique. So, why can't VS Code find its definition?
If I knew why, maybe I could change my code to work around it.
VS Code also can't find any references to these 'lost' properties. Which is very frustrating for tracking down where a function is called etc.
You should use this.
const edit = {
something: 5,
test() {
this.something;
},
};
You must not use an arrow function for test field, or this would point elsewhere but not the edit object.
EDIT: In TypeScript 4.3.5, the latest version of TS at the time of writing, TS is able to detect self-references in object literals, and both edit.something and this.something would work. For the case of working with JavaScript, upgrading VS Code should do the trick.
A TS playground link for reference.
There is a length limit. IntelliSense will define type :any if an object description is too long.
There is no way around this at all. The :any type will overwrite imported type definitions (e.g., a .d.ts file).
Two solutions:
Don't write long object declarations in your code.
Don't use VS Code or IntelliSense.
As for specifics:
The behavior is unpredictable.
If a type definition does not generate, reducing the object description length will not cause it to generate
Reducing an object description length to below the limit and re-launching VS Code will cause it to re-generate.
The length limit is unpredictable.
A function definition is 'longer' than a string, even if they have the same character count.
A nested ('deep') object declaration is longer than a shallow ('flat') object declaration, even if they have the same character count.
In short: IntelliSense breaks irreparably if you try to write long object declarations in a JS file.

When do you use declare in TypeScript?

In TypeScript, why do you sometimes need to use declare for declaring a variable, and sometimes you don't (the same question is true for functions, …)?
To give an example: When (and why) do I use
declare var foo: number;
if
let foo: number;
would do the same (at least it seems to me as if it did the same, i.e. they both declare a variable called foo of type number). What's the difference?
You never use declare to declare a variable. You just use it to let TypeScript know that the variable exists, even though it's not declared in the code (for instance, because it's a global declared in other code, or because you're going to combine the JavaScript output of tsc with another file that declares the variable). Or put it another way: It only declares it for the TypeScript compiler, not for the JavaScript runtime.
If you use the playground to compile your declare var foo: number;, it literally outputs nothing for that declaration; example.
In contrast, let foo: number; (or var foo: number;) is a variable declaration; example.
In TypeScript, "declare var foo: number;" means: "In the code there is a number called foo. I know that you would not retrieve it. But please trust me and act just like you know it." It is a kind of forward declaration just like you can see it in C/C++.
Example:
Assume that you are writing a TS script using jQuery. You would include all the JavaScript like this somewhere in your HTML page:
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="myscript.js"></script> <!-- generated from TypeScript, with something like "tsc myscript.ts" -->
As a consequence, there is no need to include jQuery in your TS script, since JS generated from your TS script will know everything about jQuery's stuff. However, the TS transpiler will remark jQuery's iconic "$()" a bunch of time in your code. You do not include jQuery in your TS code (because there is no need to) so it does not know anything about "$()". It will consequently report to you lots of errors asking you what the hell is this "$" it sees everywhere in the code. To solve all those $-related errors, you will write "declare var $: jQuery;" at the beginning of your TS script. By writing this, you tell this to the TS transpiler:
In the code there is a variable called "$" whose type is "jQuery". I know that you would not have retrieved it. But assume that it exists and please act like there was a "import "aTSfile.ts";" which perfectly describes it to you (a description just like I use it) earlier in the code. Trust me, JavaScript will know what that "$" REALLY is when the script is executed. Do not worry about that. ;-)
The declare keyword in typescript is useful for telling the typescript compiler that a declaration is defined somewhere else, Hope this link helps:
http://blogs.microsoft.co.il/gilf/2013/07/22/quick-tip-typescript-declare-keyword/

Reusing class names in JavaScript

Is it in someway possible to reuse a class name that is defined in the Global objects list found here? (Like Number, String)
Lets say that I want to have my own String class. I can define it, and use it like this:
String.js
export default class String {
}
App.js
import String from './String'
let string = new String();
This actually works, but then
PHPStorm tells me: yeah you used a primitive object wrapper (thinking it's
the global object String).
Then ESLint tells me: Disallow Primitive Wrapper Instances (no-new-wrappers)
And lastly SonarQube tells me: The use of wrapper objects for primitive types is gratuitous, confusing and dangerous. Simple literals should be used instead.
So yeah is there a way to encapsulate my class so it doesn't get confused with the global String class?
import './String'
Function and class definitions are local to the module. You're importing the file, but not using anything from it.
That's why this:
let string = new String();
will use the global String—there is no String definition in the module scope.
Make sure you name the imports you need:
import String from './String'
Incidentally, this is one of multiple reasons why it is better practice to give your String class a unique name, like PhysicsString or StringMaterial or Thread. That way if you forget to import it somewhere, you won't accidentally be using the global definition.

Leading underscore for marking private members

As I know, in JavaScript there is no good solution to make private member. Solution described here is not efficient, because private members become parts of objects, not prototypes, and hence require more memory.
So, I decided just use Python practice - to mark private stuff with leading underscore, letting other to know that makred property or method is not intended to be used from outside.
But there is well-known code quality tool - JSLint, and it suggests to not use leading or trailing underscores.
What is the rationale behind this? Is this just code style suggestion or underscores can lead to more serious problems? If its just code style convention in JS community, how strong it is?
JSLint is a good tool, but it expresses opinions about coding practices that are in the style of its authors. Read about what those preferences are here. There is no harm in the JavaScript parser in using a leading underscore/underbar, the tool is programmed to see this as a bad convention and warn you against using it. If using leading underscores is your preference and it makes sense, use them.
If you don't want to see the warnings in JSLint when using identifiers that begin with an underscore/underbar there is a setting within JSLint to hide these from you. Wrap the code that you don't want to be evaluated like this example and you won't see the warnings:
/*jslint nomen: true */
var _gaq = {};
/*jslint nomen: false */
This is true if you're having code evaluated from a file, but if you're on the JSLint website there is an option to "Tolerate... dangling _ in identifiers" that removes the warning as well.
Please note that doing this may cause issues in how JSHint parses the file. Take a look at this link showing JSLint vs JSHint in relation to that flag. But if you're going to go by the JSLint standard mixing JSHint can cause a bit of confusion.
Private variables don't exist in JavaScript without using closures, but it's not a pattern needed for every project execution. If you want to know more about closures in JavaScript check out Ben Nadel's wonderful blog post and NetTuts+
It's just a code style suggestion.
You can use JSHint instead and set-up it following the code style in your project/company.
As to me there's nothing bad if you mark private members in this way. The main rule should be to follow the unified convention in the whole project. If this makes your code more readable and maintainable, you're free to follow own convention for current project.
Underscore prefix can be use as convention. But is just a convention.
If the private member is a property of the object's instance the only way is to declare a variable in constructor. The properties of an object are never registred in prototype. If you store a property in proto, his value was share with all other instance.
It work like statics in POO.
The prototype is only use to solve an undefined property in the instance.
Exemple:
function O(){}
O.prototype.name = "John";
var o = new O;
// o look like that :
// {
// __proto__: { name: "John"}
// }
console.log(o.name); // write "John"
o.name = "Tom";
// now :
// {
// name: "Tom",
// __poto__: { name: "John" }
// }
console.log(o.name); // write "Tom"
The definition of name on instance not override the prototype value. It only store in the instance before the proto value in cascade resolution.
Sorry for my bad english.

Categories