For testing reasons, is there a way to access a module's local variable?
module m {
var i = 0;
export function go() {
++i;
}
}
m.go();
expect(m["i"]).toBe(1); // m["i"] is undefined
[That is - is it possible to access a javascript function's local var?]
Ofcourse I can export it, or make it static and wrap it in a class, but I'm looking for something cleaner.
No, looking at the generated JavaScript helps in these situations:
var m;
(function (m) {
var i = 0;
function go() {
++i;
}
m.go = go;
})(m || (m = {}));
As you can see, var i is scoped within the function and therefore inaccessible outside that function.
Just follow your suggestion:
Of course I can export it, or make it static and wrap it in a class
Related
In Kotlin, if we declare a class member as var and nullable type, compiler doesn't allow us to run the member function although we put an if statement before calling the function because the compiler can't guarantee that the member isn't been set to null after checking against null and before calling the method.
But if we are using a safe call compiler approves our code.
My question, how the compiler makes the safe call atomic? Isn't a second thread can change the variable between checking for null and calling the method (eat method in the example)?
Code for first situation:
class MyWolf
{
var w : Wolf? = Wolf()
fun myFunction()
{
if (w != null)
{
w.eat()
}
}
}
class Wolf
{
fun eat() : Unit
println("wolf is eating")
}
Code for second situation:
class MyWolf
{
var w : Wolf? = Wolf()
fun myFunction()
{
w?.eat()
}
}
class Wolf
{
fun eat():Unit
{
//code
}
}
The compiler puts the contents of the field to the local variable and then compares it with null. You can clearly see it if you decompile Kotlin bytecode.
How do I check whether a variable exists, i.e. is already declared in D?
The background is that I want to use version conditions but still have a default value:
version(A)
{
immutable int var = 1;
}
version(B)
{
immutable int var = 2;
}
// this is pseudo code
if (var is not yet declared)
{
immutable int var = 3;
}
I just assume that this is possible in D as it has so much introspection...
Well, given what your use case appears to be, you're going about it incorrectly. You really should do something more like
version(A)
{
immutable int var = 1;
}
else version(B)
{
immutable int var = 2;
}
else
{
immutable int var = 3;
}
But in the general case, if you're looking specifically to test whether a symbol exists, use is(typeof(symbol)) where symbol is the name of the symbol that you're testing for. So, if you wanted to test whether the variable var existed, you would do something like
static if(is(typeof(var)))
{
//var exists
}
and of course to test that it doesn't exist, you just negate the condition:
static if(!is(typeof(var)))
{
//var does not exist
}
typeof(exp) gets the type of an expression, and if the expression is invalid (because of a variable which doesn't exist or a function in the expression doesn't work with those arguments or whatever), then the result is void. is(type) checks whether the type is non-void. So, is(typeof(exp)) tests whether exp is a valid expression, and in the case where it's just a symbol name, that means that it's testing whether it's a valid symbol or not.
I want to create a function object, which also has some properties held on it. For example in JavaScript I would do:
var f = function() { }
f.someValue = 3;
Now in TypeScript I can describe the type of this as:
var f: { (): any; someValue: number; };
However I can't actually build it, without requiring a cast. Such as:
var f: { (): any; someValue: number; } =
<{ (): any; someValue: number; }>(
function() { }
);
f.someValue = 3;
How would you build this without a cast?
Update: This answer was the best solution in earlier versions of TypeScript, but there are better options available in newer versions (see other answers).
The accepted answer works and might be required in some situations, but have the downside of providing no type safety for building up the object. This technique will at least throw a type error if you attempt to add an undefined property.
interface F { (): any; someValue: number; }
var f = <F>function () { }
f.someValue = 3
// type error
f.notDeclard = 3
This is easily achievable now (typescript 2.x) with Object.assign(target, source)
example:
The magic here is that Object.assign<T, U>(t: T, u: U) is typed to return the intersection T & U.
Enforcing that this resolves to a known interface is also straight-forward. For example:
interface Foo {
(a: number, b: string): string[];
foo: string;
}
let method: Foo = Object.assign(
(a: number, b: string) => { return a * a; },
{ foo: 10 }
);
which errors due to incompatible typing:
Error: foo:number not assignable to foo:string
Error: number not assignable to string[] (return type)
caveat: you may need to polyfill Object.assign if targeting older browsers.
TypeScript is designed to handle this case through declaration merging:
you may also be familiar with JavaScript practice of creating a function and then extending the function further by adding properties onto the function. TypeScript uses declaration merging to build up definitions like this in a type-safe way.
Declaration merging lets us say that something is both a function and a namespace (internal module):
function f() { }
namespace f {
export var someValue = 3;
}
This preserves typing and lets us write both f() and f.someValue. When writing a .d.ts file for existing JavaScript code, use declare:
declare function f(): void;
declare namespace f {
export var someValue: number;
}
Adding properties to functions is often a confusing or unexpected pattern in TypeScript, so try to avoid it, but it can be necessary when using or converting older JS code. This is one of the only times it would be appropriate to mix internal modules (namespaces) with external.
So if the requirement is to simply build and assign that function to "f" without a cast, here is a possible solution:
var f: { (): any; someValue: number; };
f = (() => {
var _f : any = function () { };
_f.someValue = 3;
return _f;
})();
Essentially, it uses a self executing function literal to "construct" an object that will match that signature before the assignment is done. The only weirdness is that the inner declaration of the function needs to be of type 'any', otherwise the compiler cries that you're assigning to a property which does not exist on the object yet.
EDIT: Simplified the code a bit.
Old question, but for versions of TypeScript starting with 3.1, you can simply do the property assignment as you would in plain JS, as long as you use a function declaration or the const keyword for your variable:
function f () {}
f.someValue = 3; // fine
const g = function () {};
g.someValue = 3; // also fine
var h = function () {};
h.someValue = 3; // Error: "Property 'someValue' does not exist on type '() => void'"
Reference and online example.
As a shortcut, you can dynamically assign the object value using the ['property'] accessor:
var f = function() { }
f['someValue'] = 3;
This bypasses the type checking. However, it is pretty safe because you have to intentionally access the property the same way:
var val = f.someValue; // This won't work
var val = f['someValue']; // Yeah, I meant to do that
However, if you really want the type checking for the property value, this won't work.
I can't say that it's very straightforward but it's definitely possible:
interface Optional {
<T>(value?: T): OptionalMonad<T>;
empty(): OptionalMonad<any>;
}
const Optional = (<T>(value?: T) => OptionalCreator(value)) as Optional;
Optional.empty = () => OptionalCreator();
if you got curious this is from a gist of mine with the TypeScript/JavaScript version of Optional
An updated answer: since the addition of intersection types via &, it is possible to "merge" two inferred types on the fly.
Here's a general helper that reads the properties of some object from and copies them over an object onto. It returns the same object onto but with a new type that includes both sets of properties, so correctly describing the runtime behaviour:
function merge<T1, T2>(onto: T1, from: T2): T1 & T2 {
Object.keys(from).forEach(key => onto[key] = from[key]);
return onto as T1 & T2;
}
This low-level helper does still perform a type-assertion, but it is type-safe by design. With this helper in place, we have an operator that we can use to solve the OP's problem with full type safety:
interface Foo {
(message: string): void;
bar(count: number): void;
}
const foo: Foo = merge(
(message: string) => console.log(`message is ${message}`), {
bar(count: number) {
console.log(`bar was passed ${count}`)
}
}
);
Click here to try it out in the TypeScript Playground. Note that we have constrained foo to be of type Foo, so the result of merge has to be a complete Foo. So if you rename bar to bad then you get a type error.
NB There is still one type hole here, however. TypeScript doesn't provide a way to constrain a type parameter to be "not a function". So you could get confused and pass your function as the second argument to merge, and that wouldn't work. So until this can be declared, we have to catch it at runtime:
function merge<T1, T2>(onto: T1, from: T2): T1 & T2 {
if (typeof from !== "object" || from instanceof Array) {
throw new Error("merge: 'from' must be an ordinary object");
}
Object.keys(from).forEach(key => onto[key] = from[key]);
return onto as T1 & T2;
}
This departs from strong typing, but you can do
var f: any = function() { }
f.someValue = 3;
if you are trying to get around oppressive strong typing like I was when I found this question. Sadly this is a case TypeScript fails on perfectly valid JavaScript so you have to you tell TypeScript to back off.
"You JavaScript is perfectly valid TypeScript" evaluates to false. (Note: using 0.95)
We can create Em.Object like this:
var foo = Em.Object.create({
somevar : '123'
});
and then use it:
foo.get('somevar');
but how to create a private property or method in Em.Object which would be accessable from the object but wouldnt be ourside?
There is indeed a way to have private variables in Ember objects, as follows:
MyObject = Ember.Object.extend({
init: function() {
// private variable
var a = 1;
// methods to get, set, or otherwise accesss the private variables
this.getA = function() {return a;};
this.setA = function(val) {a = val;}
// don't forget this!
this._super(...arguments);
}
});
now try
o1 = MyObject.create()
o2 = MyObject.create()
o1.setA(42);
o2.getA(); //1
In other words, you have to declare the private variables, AND any getters, setters, or other routines that want to use them, in the init hook. Of course, this means that those getters/setters will be present on each instance of the class, rather than in its prototype. That's slightly inefficient, but the same holds for any approach to private variables for classes in JavaScript.
It is conceivable that Ember could introduce a new private: {} hash on objects, but then Ember would need a lot of machinery to handle finding and controlling access to private variables across class hierarchies. It would be equivalent to redesigning or extending the language itself, which is not part of the Ember mission.
Meanwhile, the above approach works fine if the number of private instance variables is limited and the number of routines that need to access them is small. So the accepted answer that says this is impossible is, well, wrong.
It's not possible, since Ember.js does not provide any encapsulation mechanisms.
However, you can simply use some convention for private members. For example, prefix them with _ sign.
You could use a closure:
(function() {
var somePrivateProperty = 'xyz';
MyObject = Em.Object.extend({
someComputedProperty: function() {
return 'somePrivateProperty = ' + somePrivateProperty;
}).property()
})
})();
Is possible with a little trick:
var obj = Em.Em.Object.create(
new function(){
var privateVar = "this is private";
this.getPrivateVar = function(){
return privateVar ;
}
},
{
emberVar: "Ember var",
emberMethod : function(){
return this.getPrivateVar();
},
emberMethod1 : function(){
return privateVar ;
},
emberBinding : 'emberVar'
}
)
now if U try to get private var
obj.privateVar
> unknown
obj.getPrivateVar()
> "this is private"
obj.emberMethod()
> "this is private"
The only problem is that:
obj.emberMethod1()
> unknown
in node.js, is there any shortcut to export ALL functions in a given file? i want to do this for unit testing purposes, as my unit tests are in a separate file from my production code.
I know i can go through and export each function manually, as in:
exports.myFunction = myFunction;
But i'm wondering if there is a simpler/slicker way to do this.
(and yes, i realize for modularity reasons it isn't always a good idea to export all functions, but for unit testing purposes you do want to see all the little functions so you can test them piece by piece.)
Thanks!
You could do something like this:
// save this into a variable, so it can be used reliably in other contexts
var self = this;
// the scope of the file is the `exports` object, so `this === self === exports`
self.fnName = function () { ... }
// call it the same way
self.fnName();
Or this:
// You can declare your exported functions here
var file = module.exports = {
fn1: function () {
// do stuff...
},
fn2: function () {
// do stuff...
}
}
// and use them like this in the file as well
file.fn1();
Or this:
// each function is declared like this. Have to watch for typeos, as we're typing fnName twice
fnName = exports.fnName = function () { ... }
// now you can use them as file-scoped functions, rather than as properties of an object
fnName();
Mixin objects is the answer.
This lib can help you: https://github.com/shimondoodkin/nodejs-clone-extend
//file1.js
var _ = require('cloneextend');
_.extend(this, require('file2.js'));
file1.js has now all exports from file2.js
Here's a simple way to do it. Parse the AST and look for top level function definitions, and export those.
const esprima = require('esprima')
const program = fs.readFileSync(__filename,'utf8')
const parsed = esprima.parseScript(program)
for (let fn of parsed.body) {
if (fn.type.endsWith('FunctionDeclaration')) {
module.exports[fn.id.name] = eval(fn.id.name)
}
}