Skip to content

JavaScript Static Types

brett hartshorn edited this page Sep 6, 2015 · 5 revisions

Why use static type checking in JavaScript? see this post

The JavaScript backend by default will inject code that checks the type of function arguments at runtime. The runtime type checking is applied to any statically typed arguments in a function.

def myfunction( a:int, b:float, c:string, d:MyClass ):
    pass

Above defines a function that will fail if not given the proper argument types, the first must be an integer, followed by: a float, a string, and a custom class called MyClass. A TypeError will be thrown if any of those arguments are not the correct type.

When you have tested your program, and ready for production release, you can disable the type checking using the --release option.

rusthon.py myinput.md myoutput.tar --release

Arrays

Typed arrays can be declared using syntax inspired by Golang, a type starting with [] is an array, and the type is given at the end. For example a 2D array of strings looks like this: [][]string.

def F( arr:[]int ):
    pass

The example above will check the first element of arr at runtime, and throw an error if it is not an integer.

Callbacks

The syntax for a callbacks is also inspired by Golang. The special keyword func followed by the arguments and return type are each enclosed in parenthesis.

def F( mycallback:func(int float)(string) ):
    pass

In the example above the function F must be given as the first argument a callback function that takes two arguments, the first is an int and the second is a float, and returns a string. note: the arguments are space separated.

Dict

Typed dictionaries, (hash maps) are checked at runtime when passed to a function with the argument type given as: map[KEY_TYPE]VALUE_TYPE. Note, the object is a standard javascript Object (with two hidden properties), and it is compatible with external javascript libraries.

input

def foo( d:map[string]int ):
	print d
	print 'foo OK'

def bar( d:map[int]string ):
	print d
	print 'bar OK'

def test():
	a = map[string]int{}
	a['x'] = 1
	a['y'] = 2

	b = map[int]string{
		10 : 'w',
		11 : 'z'
	}

	foo( a )
	bar( b )

output

var foo =  function foo(d)
{
	if (d.__keytype__ != "string") {throw new TypeError("invalid dict key type")};
	if (d.__valuetype__ != "int") {throw new TypeError("invalid dict value type")};
	𝑷𝒓𝒊𝒏𝒕(d);
	𝑷𝒓𝒊𝒏𝒕("foo OK");
}
foo.args = ["map[string]int"];

var bar =  function bar(d)
{
	if (d.__keytype__ != "int") {throw new TypeError("invalid dict key type")};
	if (d.__valuetype__ != "string") {throw new TypeError("invalid dict value type")};
	𝑷𝒓𝒊𝒏𝒕(d);
	𝑷𝒓𝒊𝒏𝒕("bar OK");
}
bar.args = ["map[int]string"];

var test = function test()
{
	var a,b;
	a = 𝑫𝒊𝒄𝒕({  }, { copy:false ,keytype:"string",valuetype:"int" });
	a["x"] = 1;
	a["y"] = 2;
	b = 𝑫𝒊𝒄𝒕({ 10:"w", 11:"z" }, { copy:false, keytype:"int" ,valuetype:"string" });
	foo(a);
	bar(b);
}

Gotchas

  • the float type is valid for any number, because JavaScript always stores all numbers as floats, and a literal like 1.0 will be shortened to 1 when coerced to a string.
  • the int type checks if . appears in the number when converted to a string.
  • only the first element of a typed array is check to see if it is of the correct type
  • inside a webworker the static type syntax is used for runtime class restoration, and not for runtime type checking.

Examples

Sidebar

Clone this wiki locally