TypeScript, Dart
version | grammar and execution | variables and expressions | arithmetic and logic | strings | regexes | dates and time | arrays | dictionaries | functions | execution control | exceptions | streams | files | file formats | directories | processes and environment | libraries and namespaces | user-defined types | generic types | objects | inheritance and polymorphism | reflection | net and web | debugging and profiling
version | ||
---|---|---|
typescript | dart | |
version used |
1.5 | 1.10 |
show version |
$ tsc --version | $ dart --version |
grammar and execution | ||
typescript | dart | |
hello world | $ cat hello.ts console.log("Hello, World!"); $ tsc hello.ts $ node hello.js Hello, World! |
$ cat hello.dart void main() { print('Hello, World!'); } $ dart hello.dart Hello, World! $ dart2js hello.dart $ node out.js Hello, World! |
file suffixes source, header, object file |
.ts .d.ts .js | .dart none .js |
interpreter |
none | $ dart foo.dart |
block delimiters |
{} | { … } |
statement separator |
; or newline newline not separator inside (), [], {}, "", '', or after binary operator newline sometimes not separator when following line would not parse as a valid statement |
; |
end-of-line comment |
// comment | // comment |
multiple line comment |
/* line another line */ |
/* comment line another line /* nested comment */ */ |
variables and expressions | ||
typescript | dart | |
local variable |
var x: number = 1; var y: number = 2, z: number = 3; // type is inferred: var x = 1; var y = 2, z = 3; |
int i; int j = 3, k = 4; // type is inferred: var x = 1; var y = 2, z = 3; |
regions which define lexical scope | top level: html page nestable: function |
top level: file nestable: block |
global variable | // no globals in TypeScript; if global is defined // in JavaScript it can be declared. // Run time ReferenceError if not found: declare var g; |
|
uninitialized variable |
set to undefined | set to null |
immutable variable | import 'dart:math'; final x = (new Random()).nextDouble(); |
|
constant |
none | const double pi = 3.14; |
assignment |
x = 1; | i = 3; |
parallel assignment |
none | none |
swap |
var tmp = x; x = y; y = tmp; |
int x = 1, y = 2, tmp; tmp = x; x = y; y = tmp; |
compound assignment arithmetic, string, logical, bit |
+= -= *= /= none %= += none <<= >>= &= |= ^= |
arithmetic: += -= *= /= ~/= %= string: += *= bit: <<= >>= &= ^= |= |
increment and decrement |
var x = 1; var y = ++x; var z = --y; |
premodifiers: ++i --i postmodifiers: i++ i-- |
null |
null | null |
null test |
v === null | x == null |
option type | ||
undefined variable |
undefined | |
conditional expression |
x > 0 ? x : -x | x > 0 ? x : -x |
arithmetic and logic | ||
typescript | dart | |
boolean type |
var x: boolean = true; | bool |
true and false |
true false | true false |
falsehoods |
false null undefined "" 0 NaN | everything except for the boolean true |
logical operators |
&& || ! | && || ! |
relational operators |
=== !== < > >= <= perform type coercion: == != |
== != < > <= >= |
min and max |
Math.min(1, 2, 3) Math.max(1, 2, 3) Math.min.apply(Math, [1, 2, 3]) Math.max.apply(Math, [1, 2, 3]) |
|
integer type |
none; use number | int |
float type | var x: number = 3.14; | double |
arithmetic operators addition, subtraction, multiplication, float division, quotient, remainder |
+ - * / none % | + - * / % |
integer division |
Math.floor(x / y) | 3 ~/ 7 |
integer division by zero |
returns assignable value Infinity, NaN, or -Infinity depending upon whether dividend is positive, zero, or negative. There are literals for Infinity and NaN. |
IntegerDivisionByZeroException |
float division |
13 / 5 | 3 / 7 |
float division by zero |
same behavior as for integers | // not literals: Infinity, NaN, or -Infinity |
power |
Math.pow(2, 32) | import 'dart:math' as math; math.pow(2.0, 3.0) |
sqrt | Math.sqrt(2) | import 'dart:math' as math; math.sqrt(2) |
sqrt -1 |
NaN | import 'dart:math' as math; // NaN: math.sqrt(-1) |
transcendental functions |
Math.exp Math.log Math.sin Math.cos Math.tan Math.asin Math.acos Math.atan Math.atan2 | import 'dart:math' as math; math.log none none math.sin math.cos math.tan math.asin math.acos math.atan math.atan2 |
transcendental constants π and e |
Math.PI Math.E |
import 'dart:math' as math; math.PI math.E |
float truncation |
none Math.round(3.1) Math.floor(3.1) Math.ceil(3.1) |
3.14.truncate() 3.14.round() 3.14.floor() 3.14.ceil() // (-3.14).floor() is -4 but -3.14.floor() is -3. |
absolute value |
Math.abs(-3) | (-7.77).abs() |
integer overflow |
all numbers are floats | |
float overflow |
Infinity | |
random number uniform integer, uniform float, normal float |
Math.floor(Math.random() * 100) Math.random() none |
import 'dart:math'; var rnd = new Random(); int n = rnd.nextInt(100); int x = rnd.nextDouble(); |
random seed set, get, restore |
none | import 'dart:math'; var rnd = new Random(17); |
bit operators |
<< >> & | ^ ~ | << >> & | ^ ~ |
binary, octal, and hex literals | none 052 // deprecated 0x2a |
|
radix convert integer to and from string with radix |
(42).toString(7) ?? |
|
strings | ||
typescript | dart | |
string type |
var s: string = "lorem ipsum"; | String |
string literal |
"don't say \"no\"" 'don\'t say "no"' |
var s = 'don\'t say "no"'; var s2 = "don't say \"no\""; var s3 = '''don't say "no"' var s4 = """don't say "no\"""" raw string literals: r'foo' r"foo" |
newline in literal |
yes | // triple quote literals only: var s = '''first line second line'''; var s2 = """first line second line""" |
literal escapes |
single and double quotes: \b \f \n \r \t \v \uhhhh \xhh \" \' \\ |
\b \f \n \r \t \v \" \' \$ \\ \xhh \uhhhh \u{h…} |
here document |
none | |
variable interpolation |
// None; use string concatenation. // Both of these expressions are '11': 1 + "1" "1" + 1 |
|
expression interpolation | none | var count = 3; var item = "BALL"; // 3 balls print('$count ${item.toLowerCase()}s'); |
format string |
// None; use string concatenation. // Evaluates to "12.35": 12.3456.toFixed(2) |
|
are strings mutable? | no | |
compare strings | "hello" === "world" "hello" < "world" |
"hello" == "world" "hello".compareTo("world") < 0 |
copy string | none | |
concatenate |
s = "Hello, " + "World!"; | "hello" + " world" |
replicate |
var hbar = Array(80).join("-"); | var hbar = "-" * 80; |
translate case to upper, to lower |
"lorem".toUpperCase() "LOREM".toLowerCase() |
"hello".toUpperCase() "HELLO".toLowerCase() |
capitalize string, words |
none | |
trim both sides, left, right |
" lorem ".trim() # some browsers: " lorem".trimLeft() "lorem ".trimRight() |
" lorem ".trim() " lorem ".trimLeft() " lorem ".trimRight() |
pad on right, on left, centered |
none | "lorem".padRight(10, " ") "lorem".padLeft(10, " ") |
number to string |
"value: " + 8 | 3.14.toString() 7.toString() |
string to number |
7 + parseInt("12", 10) 73.9 + parseFloat(".037") // 12: parseInt("12A") // NaN: parseInt("A") |
var n = int.parse("17"); var x = double.parse("3.14"); |
string join |
["do", "re", "mi"].join(" ") | ['foo', 'bar', 'baz'].join(' ') |
split |
// [ "do", "re", "", "mi", "" ]: "do re mi ".split(" ") // [ "do", "re", "mi", "" ]: "do re mi ".split(/\s+/) |
var a = "foo bar bar".split(' '); |
split in two |
none | |
split and keep delimiters | none | |
prefix and suffix test | "foobar".startsWith("foo") "foobar".endsWith("bar") |
|
length |
"lorem".length | // number of 16 bit runes: "hello".length |
index of substring first, last |
// returns -1 if not found: "lorem ipsum".indexOf("ipsum") |
"hello".indexOf("ll") |
extract substring by start and length, by start and end, by successive starts |
"lorem ipsum".substr(6, 5) "lorem ipsum".substring(6, 11) |
"hello".substring(2, 4) |
character type | // 16 bits: rune |
|
character lookup | "lorem ipsum"[6] | |
chr and ord |
String.fromCharCode(65) "A".charCodeAt(0) |
new String.fromCharCodes([65]) "A".codeUnitAt(0) // for Unicode points above U+FFFF codeUnitAt will // return part of a surrogate pair |
to array of characters |
"abcd".split("") | |
translate characters |
none | |
delete characters | none | |
squeeze characters | none | |
regular expressions | ||
typescript | dart | |
literal, custom delimited literal | /lorem|ipsum/ | |
metacharacters | . [ ] \ ( ) * + ? { } | ^ $ use raw string (i.e. with r prefix) literals to avoid having to escape backslashes. |
|
character class abbreviations | . \d \D \s \S \w \W | . \d \D \s \S \w \W |
anchors |
^ $ \b \B | ^ $ \b \B |
match test |
if (s.match(/1999/)) { alert("party!"); } |
RegExp rx = new RegExp(r"1999"); String s = "It's 1999"; if (rx.hasMatch(s)) { print("Party!"); } |
case insensitive match test | "Lorem".match(/lorem/i) | RegExp rx = new RegExp(r"lorem", caseSensitive: false); String s = "Lorem Ipsum"; if (rx.hasMatch(s)) { print("case insensitive match"); } |
modifiers |
g i m | RegExp constructor takes two optional boolean named parameters: multiLine caseSensitive |
substitution |
s = "do re mi mi mi"; s.replace(/mi/g, "ma"); |
RegExp re = new RegExp(r'mi'); print("do re mi mi mi".replaceAll(re, "ma")); |
match, prematch, postmatch |
m = /\d{4}/.exec(s); if (m) { match = m[0]; # no prematch or postmatch } |
|
group capture |
rx = /^(\d{4})-(\d{2})-(\d{2})$/; m = rx.exec('2009-06-03'); yr = m[1]; mo = m[2]; dy = m[3]; |
RegExp rx = new RegExp(r'(\d{4})-(\d{2})-(\d{2})'); var md = rx.firstMatch("2010-06-03"); if (md != null) { var yyyy = md.group(1); var mm = md.group(2); var dd = md.group(3); print("year: $yyyy month: $mm day: $dd"); } |
named group capture | none | |
scan |
var a = "dolor sit amet".match(/\w+/g); | |
backreference in match and substitution | /(\w+) \1/.exec("do do") "do re".replace(/(\w+) (\w+)/, '$2 $1') |
|
recursive regex |
none | |
dates and time | ||
typescript | dart | |
broken-down datetime type |
Date | DateTime |
current datetime | var t = new Date(); | var dt = new DateTime.now(); |
current unix epoch | (new Date()).getTime() / 1000 | |
broken-down datetime to unix epoch | Math.round(t.getTime() / 1000) | dt.millisecondsSinceEpoch ~/ 1000 |
unix epoch to broken-down datetime | var epoch = 1315716177; var t2 = new Date(epoch * 1000); |
int t = 1422021432; var dt = new DateTime.fromMillisecondsSinceEpoch(t * 1000); |
format datetime | none | |
parse datetime | none | |
parse datetime w/o format | var t = new Date("July 7, 1999"); | |
date parts | t.getFullYear() t.getMonth() + 1 t.getDate() # getDay() is day of week |
int yr = dt.year; int mo = dt.month; int dy = dt.day; |
time parts | t.getHours() t.getMinutes() t.getSeconds() |
int hr = dt.hour; int mi = dt.minute; int ss = dt.second; |
build broken-down datetime | var yr = 1999; var mo = 9; var dy = 10; var hr = 23; var mi = 30; var ss = 0; var t = new Date(yr, mo - 1, dy, hr, mi, ss); |
var dt = new DateTime(1999, 9, 10, 23, 30, 0); var dt_utc = new DateTime.utc(1999, 9, 10, 23, 30, 0); |
datetime subtraction | number containing time difference in milliseconds | Duration delta = dt.difference(dt2); |
add duration | var t1 = new Date(); var delta = (10 * 60 + 3) * 1000; var t2 = new Date(t1.getTime() + delta); |
Duration delta1 = const Duration(seconds: 1000); Duration delta2 = const Duration(hours: 1000); Duration delta3 = const Duration(days: 1000); var dt2 = dt.add(delta1); var dt3 = dt.subtract(delta3); |
local time zone determination | ||
time zone info name and UTC offset |
||
daylight savings test | ||
microseconds | ||
sleep | none | |
arrays | ||
typescript | dart | |
literal |
var a = [1, 2, 3, 4]; // two ways to declare type: var a: number[] = [1, 2, 3, 4]; var a: Array<number> = [1, 2, 3, 4]; |
var a = [1, 2, 3, 4]; |
size |
a.length | a.length |
empty test |
// TypeError if a is null or undefined: a.length === 0 |
a.isEmpty |
lookup |
a[0] | a[0] |
update |
a[0] = "lorem" | a[0] = "lorem"; |
out-of-bounds behavior | returns undefined | lookups and updates raise RangeError |
element index first and last occurrence |
// returns -1 if not found: [6, 7, 7, 8].indexOf(7) [6, 7, 7, 8].lastIndexOf(7) |
// returns -1 if not found: [6, 7, 7, 8].indexOf(7) [6, 7, 7, 8].lastIndexOf(7) |
slice by endpoints, by length |
// select 3rd and 4th elements: ["a", "b", "c", "d"].slice(2, 4) none |
var a = ["a", "b", "c", "d", "e"]; // ["c", "d"]: List a2 = a.getRange(2, 4); |
slice to end |
["a", "b", "c", "d"].slice(1) | ["a", "b", "c", "d"].skip(1) |
manipulate back |
a = [6, 7, 8]; a.push(9); i = a.pop(); |
a.add(4); var v = a.removeLast(); |
manipulate front |
a = [6, 7, 8]; a.unshift(5); i = a.shift(); |
var a = [6, 7, 8]; a.insertAt(0, 5); var i = a.removeAt(0); |
concatenate | a = [1, 2, 3].concat([4, 5, 6]); | var a = [1, 2, 3]; a.addAll([4, 5, 6]); |
replicate |
none | var a = new List.filled(10, 0); |
copy address copy, shallow copy, deep copy |
a = [1, 2, [3, 4]]; a2 = a; a3 = a.slice(0); a4 = JSON.parse(JSON.stringify(a)); |
var a = ["a", "b"]; List a2 = new List<String>.from(a); |
array as function argument | parameter contains address copy | parameter contains address copy |
iterate over elements |
[1, 2, 3].forEach(function(n) { alert(n); }); |
for (var i in [1, 2, 3]) { print(i); } [1, 2, 3].forEach((i) => print(i)); |
iterate over indices and elements | var len = a.length; for (var i = 0; i < len; i++ ) { alert(a[i]); } |
|
instantiate range as array | ||
reverse non-destructive, in-place |
var a = [1, 2, 3]; a.reverse(); |
var a = ["a", "b", "c"]; List a2 = new List<String>.from(a.reversed); |
sort non-destructive, in-place, custom comparision |
var a = [3, 1, 4, 2]; a.sort(); |
var a = [3, 1, 4, 2]; a.sort(); |
dedupe non-destructive, in-place |
var a = [1, 2, 2, 3]; var set = new Set.from(a); var a2 = new List.from(set); |
|
membership |
[1, 2, 3].contains(7) | |
intersection |
var set1 = new Set.from([1, 2]); var set2 = new Set.from([2, 3, 4]); set1.intersection(set2); |
|
union |
var set1 = new Set.from([1, 2]); var set2 = new Set.from([2, 3, 4]); set1.union(set2); |
|
relative complement | var set1 = new Set.from([1, 2]); var set2 = new Set.from([2, 3, 4]); set1.difference(set2); |
|
map |
// callback gets 3 args: // value, index, array a.map(function(x) { return x * x }) |
var a = [1, 2, 3]; var a2 = new List.from(a.map((n) => n * n)); |
filter |
a.filter(function(x) { return x > 1 }) | var a = [1, 2, 3]; var a2 = new List.from(a.where((n) => n > 1)); |
reduce |
a.reduce(function(m, o) { return m + o; }, 0) |
var a = [1, 2, 3]; var sum = a.reduce((v, e) => v + e); |
universal and existential tests |
var a = [1, 2, 3, 4]; var even = function(x) { return x % 2 == 0; }; a.every(even) a.some(even) |
[1, 2, 3, 4].every((x) => x % 2 == 0) [1, 2, 3, 4].any((x) => x % 2 == 0) |
shuffle and sample | var a = [1, 2, 3, 4]; a.shuffle(); var samp = a.take(2); |
|
flatten one level, completely |
||
zip |
||
dictionaries | ||
typescript | dart | |
literal |
d = {"t": 1, "f": 0}; // keys do not need to be quoted if they // are a legal JavaScript variable name //and not a reserved word // declare type: var d: {[idx: string]: number} = {t: 1, f: 0} |
var d = {"t": 1, "f": 0}; |
size |
var size = 0; for (var k in d) { if (d.hasOwnProperty(k)) size++; } |
d.length |
lookup |
d.hasOwnProperty("t") ? d["t"] : undefined // if type of d not declared: d.hasOwnProperty("t") ? d.t : undefined |
d["t"] |
update | d["t"] = 2; // if type of d not declared: d.t = 2; |
d["t"] = 2; |
missing key behavior |
var d = {}; // sets s to undefined: var s = d["lorem"]; // adds key/value pair: d["lorem"] = "ipsum"; |
returns null |
is key present |
d.hasOwnProperty("t"); | d.containsKey("y") |
delete | delete d["t"]; // if type of d not declared: delete d.t; |
d.remove("f"); |
from array of pairs, from even length array | ||
merge | ||
invert | ||
iterate |
for (var k in d) { if (d.hasOwnProperty(k)) { // use k or d[k] } } |
d.forEach((k, v) { print(k); print(v); }); |
keys and values as arrays | List keys = d.keys; List vals = d.values; |
|
sort by values | function cmp2(a, b) { if (a[1] < b[1]) { return -1; } if (a[1] > b[1]) { return 1; } return 0; } for (p in _.pairs(d).sort(cmp2)) { alert(p[0] + ": " + p[1]); } |
|
default value, computed value | none | |
functions | ||
typescript | dart | |
define |
function add(x: number, y: number): number { return x + y; } // parameter and return types optional: function add(x, y) { return x + y; } |
num add(num n, num m) { return n + m; } // parameter and return types optional: add(n, m) { return n + m; } // expression body shorthand: num add(num n, num m) => n + m; |
invoke | add(1, 2) | add(1, 2) |
overload | function to_number(x: string): number; function to_number(x: number): number; function to_number(x): number { if (typeof(x) == "string") { return parseFloat(x); } if (typeof(x) == "number") { return x; } } |
none |
missing argument behavior |
// compilation error unless arg declared optional. // how to declare arg optional: function safe_length(s?: string): number { return s === undefined ? -1 : s.length; } |
compilation error |
extra argument behavior |
compilation error | compilation error |
default argument |
function my_log(x: number, base: number = 10) { return Math.log(x) / Math.log(base); } |
import 'dart:math' as math; // named params can have defaults: num my_log(num expt, {num base: 10}) { return math.log(expt) / math.log(base); } // positional params can be optional: num my_log(num expt, [num base]) { if (base == null) { return math.log(expt) / math.log(10); } else { return math.log(expt) / math.log(base); } } |
variadic function | function ends(s: string, …rest: string[]): void { console.log(s); if (rest.length) console.log(rest[rest.length - 1]); } |
none |
named parameters |
none | num divide({num dividend, num divisor}) { return dividend / divisor; } divide(divisor: 3, dividend: 9); |
return value |
return arg or undefined. If invoked with new and return value not an object, returns this | return arg or null |
anonymous function literal |
var sqr: (x: number) => number = function(x) { return x * x; } // lambda syntax does not bind "this" // to global object: var sqr2: (x: number) => number = (x) => { return x * x; } |
Function sqr = (num x) => x * x; |
invoke anonymous function |
sqr(2) | ((num x) => x * x)(5) |
function as value |
var func = add; | apply(Function fn, arg) { fn(arg); } apply(print, "lorem ipsum"); |
function with state | Use a variable defined outside the function; the scope of the variable is the containing file. | |
closure | function make_counter(): () => number { var i = 0; return function() { i += 1; return i; } } |
Function make_counter() { num i = 0; return () => ++i; } |
generator | ||
execution control | ||
typescript | dart | |
if |
if (0 == n) { alert("no hits"); } else if (1 == n) { alert("1 hit"); } else { alert(n + " hits"); } |
int signum; if (i > 0) { signum = 1; } else if (i == 0) { signum = 0; } else { signum = -1; } |
switch | switch (n) { case 0: alert("no hits\n"); break; case 1: alert("one hit\n"); break; default: alert(n + " hits\n"); } |
// switch expression can be integer or string switch (i) { case 0: case 1: print("i is boolean"); break; default: print("i is not boolean"); } // Falling through not permitted; exception if last // statement not break, continue, throw, or return. |
while |
while (i < 100) { i += 1; } |
int i = 0; while (i < 10) { ++i; } |
for |
for (var i = 0; i < 10; i++) { alert(i); } |
int n, i; // Initialization and afterthought must be single // statements; there is no comma operator. n = 1; for (i = 1; i <= 10; ++i) { n *= i; } |
break |
break | break |
continue |
continue | continue |
for with local scope | int n = 1; for (int i = 1; i <= 10; ++i) { n *= i; } // is no longer in scope |
|
infinite loop | for (;;) { // code } while (1) { // code } |
|
break from nested loops | int a, b, c; outer: for (a = 1; ; ++a) { for (b = 1; b < a; ++b) { c = (math.sqrt(a * a + b * b)).truncate(); if (c * c == a * a + b * b) { break outer; } } } |
|
single statement branches and loops | while (n % 17 == 0) ++n; if (n < 0) print("negative"); |
|
dangling else | int a = 1, b = -3, c; // indentation shows how ambiguity is resolved if (a > 0) if (b > 0) c = 1; else c = 2; |
|
exceptions | ||
typescript | dart | |
base exception | Any value can be thrown. | Exception Error Any non-null value can be thrown. |
predefined exceptions | Error EvalError RangeError ReferenceError SyntaxError TypeError URIError |
Error AbstractClassInstantiationError ArgumentError RangeError IndexError AssertionError TypeError CastError ConcurrentModificationError CyclicInitializationError FallThroughError JsonUnsupportedObjectError NoSuchMethodError NullThrownError OutOfMemoryError RangeError StackOverflowError StateError UnimplementedError UnsupportedError intended to be caught: Exception FormatException IntegerDivisionByZeroException |
raise exception |
throw new Error("bad arg"); | throw new Exception("bad arg"); |
catch-all handler |
try { risky(); } catch (e) { alert("risky failed"); } |
try { risky(); } catch (e) { print("risky failed"); } |
re-raise exception | try { throw new Error("bam!"); } catch (e) { alert("re-raising..."); throw e; } |
try { throw new Exception("bam!"); } catch (e) { print("re-raising…"); rethrow; } |
define exception | function Bam(msg) { this.message = msg; } Bam.prototype = new Error; |
class Bam implements Exception { String msg; Bam(this.msg); } |
handle exception | try { throw new Bam("bam!"); } catch (e) { if (e instanceof Bam) { alert(e.message); } else { throw e; } } |
try { throw new Bam("bam!"); } on Bam catch (e) { print(e.msg); } |
finally block |
acquire_resource(); try { risky(); } finally { release_resource(); } |
acquire_resource(); try { risky(); } finally { release_resource(); } |
streams | ||
node | dart | |
standard file handles | process.stdin process.stdout process.stderr |
import 'dart:io' as io; io.stdin io.stdout io.stderr |
read line from stdin |
||
end-of-file behavior | ||
chomp |
||
write line to stdout |
console.log("Hello, World"); | import 'dart:io' as io; print('Hello, World!'); io.stdout.writeln('Hello, World!'); |
write formatted string to stdout | ||
open file for reading |
||
open file for writing |
var f = fs.openSync("/tmp/test", "w"); | |
set file handle encoding | ||
open file for appending | ||
close file |
||
close file implicitly | ||
i/o error | ||
encoding error | ||
read line |
||
iterate over file by line |
||
read file into array of strings | ||
read file into string | var fs = require('fs'); var s = fs.readFileSync('/etc/hosts', 'utf8'); |
import 'dart:io' as io; File f = new io.File('/etc/hosts'); f.readAsString().then((String s) { print('length: ${s.length}'); }); |
write string |
||
write line |
||
flush file handle |
||
end-of-file test |
||
file handle position get, set |
||
open temporary file | ||
in memory file | ||
files | ||
node | dart | |
file exists test, file regular test |
var fs = require('fs'); var qry = fs.existsSync('/etc/hosts'); var stat = fs.statSync('/etc/hosts'); var qry2 = stat.isFile(); |
import 'dart:io' as io; File f = new io.File("/tmp/foo"); // existence check? if (f.existsSync()) { print("is a regular file\n"); } |
file size |
var fs = require('fs'); var stat = fs.statSync('/etc/hosts'); var sz = stat.size; |
f.lengthSync() |
is file readable, writable, executable | ||
set file permissions |
var fs = require('fs'); fs.chmodSync('/tmp/foo', parseInt('755', 8)); |
|
last modification time | var fs = require('fs'); var stat = fs.statSync('/etc/hosts'); var dt = stat.mtime; |
import 'dart:io" as io; File f = new io.File("/etc/hosts"); print(f.lastModifiedSync()); |
copy file, remove file, rename file | # npm install fs-extra var fs = require('fs-extra'); fs.copySync('/tmp/foo', '/tmp/bar'); fs.unlinkSync('/tmp/foo'); fs.renameSync('/tmp/bar', '/tmp/foo'); |
import 'dart:io' as io; File f = new io.File("/tmp/foo"); f.copySync("/tmp/bar"); f.deleteSync(); File f2 = new io.File("/tmp/bar"); f2.renameSync("/tmp/foo"); |
create symlink, symlink test, readlink | var fs = require('fs'); fs.symlinkSync('/etc/hosts', '/tmp/hosts'); var stat = fs.statSync('/tmp/hosts'); stat.isSymbolicLink(); var path = fs.readlinkSync( '/tmp/hosts'); |
|
generate unused file name | ||
file formats | ||
node | dart | |
parse csv | var fs = require('fs'); # npm install csv var csv = require('csv'); var s = fs.readFileSync('no-header.csv'); var a; csv().from.string(s).to.array(function(d) { a = d }); |
|
generate csv | # npm install csv var csv = require('csv'); var a = [['one', 'une', 'uno'], ['two', 'deux', 'dos']]; var s; csv().from.array(a).to.string(function (o) { s = o; }); |
|
parse json | var s1 = '{"t":1,"f":0}'; var d1 = JSON.parse(s1); |
|
generate json | var d2 = {'t': 1, 'f': 0}; var s2 = JSON.stringify(d1); |
|
parse yaml | ||
generate yaml | ||
parse xml all nodes matching xpath query; first node matching xpath query |
# npm install xmldom xpath var dom = require('xmldom').DOMParser; var xpath = require('xpath'); var xml = '<a><b><c ref="3">foo</c></b></a>'; var doc = new dom().parseFromString(xml); var nodes = xpath.select('/a/b/c', doc); nodes.length; nodes[0].firstChild.data; |
|
generate xml | # npm install xmlbuilder var builder = require('xmlbuilder'); var xml = builder.create('a').ele('b', {id: 123}, 'foo').end(); |
|
parse html | ||
directories | ||
node | dart | |
working directory | var old_dir = process.cwd(); process.chdir("/tmp"); |
|
build pathname | ||
dirname and basename | ||
absolute pathname and tilde expansion |
||
iterate over directory by file | var fs = require('fs'); fs.readdirSync('/etc').forEach( function(s) { console.log(s); } ); |
|
glob paths | ||
make directory | ||
recursive copy | ||
remove empty directory | ||
remove directory and contents | ||
directory test |
import 'dart:io' as io; bool isDir; io.FileSystemEntity.isDirectory('/tmp').then((isDir) { if (isDir) { print('is directory'); } else { print('not a directory'); } }); |
|
generate unused directory | ||
system temporary file directory | ||
processes and environment | ||
node | dart | |
command line arguments and script name |
process.argv.slice(2) process.argv[1] // process.argv[0] contains "node" |
|
environment variable get, set |
process.env["HOME"] process.env["PATH"] = "/bin"; |
|
get pid, parent pid | process.pid none |
|
user id and name | ||
exit |
process.exit(0); | |
set signal handler |
||
executable test |
||
external command |
import 'dart:io' as io; io.Process.start('ls', ['-l', '/tmp']).then((process) { io.stdout.addStream(process.stdout); io.stderr.addStream(process.stderr); process.exitCode.then(print); }); |
|
shell-escaped external command |
||
command substitution |
||
libraries and namespaces | ||
node | dart | |
load library |
// load ./foo.dart: import 'foo.dart' as foo; // load built-in library: import 'dart:io' as io; // library installed by package manager: import 'package:foo/foo.dart' as foo; |
|
load library in subdirectory | import 'lib/foo.dart' as foo; | |
hot patch |
||
load error | ||
main routine in library | ||
library path | ||
library path environment variable | ||
library path command line option | ||
simple global identifiers | ||
multiple label identifiers | ||
label separator |
||
root namespace definition | ||
namespace declaration |
// not required in file containing main(): library foo; |
|
child namespace declaration | ||
import definitions |
import 'foo' show bar, baz; | |
import all definitions in namespace |
import 'foo'; | |
import all subnamespaces | ||
shadow avoidance | import 'foo' as fu; | |
user-defined-types | ||
typescript | dart | |
enumerated type | enum Color {Red, Green, Blue}; // assigns c the value 1: var c: Color = Color.Green; |
enum Color {red, green, blue} Color col = Color.green; |
struct definition | interface Medals { country: string, gold: number, silver: number, bronze: number }; |
|
optional struct member | interface Person { name: string, alma_mater?: string } |
|
struct literal | var france: Medals = {country: "France", gold: 8, silver: 7, bronze: 9 }; // not an error for the literal to contain members // not in the struct definition |
|
struct lookup | france.gold | |
struct update | france.gold = 9; // assignment to members not in struct definition // is permitted |
|
type alias | // function: interface BinaryOp { (x: number, y: number): number } var add: BinaryOp = (x, y) => { return x + y; } // array or dictionary: interface NumberSeq { [index: number]: number } var primes: NumberSeq = [2, 3, 5, 7, 11]; |
// function types only: typedef num BinaryOp(num x, num y); |
generic types | ||
typescript | dart | |
generic function | function identity<T>(arg: T): T { return arg; } console.log(identity("lorem ipsum")); |
|
generic class | class Holder<T> { constructor(public value: T) {} } var holder = new Holder<number>(3); console.log(holder.value); |
|
objects | ||
typescript | dart | |
define class |
class Int { public value: number; constructor(v: number) { this.value = v; } } // constructor params declared public or // private become object attributes class Int { constructor(public value: number) {} } |
class Int { int value; Int(int n) { this.value = n; } } |
create object |
var i = new Int(0); var i2 = new Int(7); |
Int i = new Int(7); |
instance variable visibility | ||
get and set instance variable |
i.value = i.value + 1; | i.value = i.value + 1; // inside method: this.value = this.value + 1; |
define method |
class Int { constructor(public value: number) {} plus(v: number) { this.value += v; } } |
class Int { int value; Int(int n) { this.value = n; } void plus(num v) { this.value += v; } } |
invoke method |
i.plus(3); | i.plus(3); |
define class method | class Int { static getInstances() { return Int.instances; } } |
class Int { static int getInstances() { return instances; } } |
invoke class method |
Int.getInstances() | Int.getInstances() |
define class variable | class Int { static instances: number = 0; constructor(public value: number) { Int.instances += 1; } } |
class Int { static int instances = 0; int value; Int(int n) { this.value = n; instances += 1; } } |
get and set class variable | Int.instances = Int.instances + 1; | // inside class: instances = instances + 1; // outside class: Int.instances = Int.instances + 1; |
handle undefined method invocation |
||
destructor |
||
inheritance and polymorphism | ||
typescript | dart | |
subclass |
class Counter extends Int { constructor(v: number) { super(v); } incr() { this.value += 1; } } |
|
reflection | ||
typescript | dart | |
object id |
none | |
inspect type |
typeof([]) === 'object' | var n = 3; if (n is int) { n += 1; } if (n is! String) { n += "s"; } |
basic types | number string boolean undefined function object # these evaluate as 'object': typeof(null) typeof([]) typeof({}) |
dynamic num |
inspect class | // returns prototype object: Object.getPrototypeOf(o) |
|
inspect class hierarchy | var pa = Object.getPrototypeOf(o) //prototype's of prototype object: var grandpa = Object.getPrototypeOf(pa) |
|
has method? |
o.reverse && typeof(o.reverse) === 'function' | |
message passing |
not a standard feature | |
eval |
eval('1 + 1') | |
list object methods |
||
list object attributes |
||
list loaded libraries | ||
list loaded namespaces | ||
inspect namespace | ||
pretty-print |
var d = {"lorem": 1, "ipsum": [2, 3]}; console.log(JSON.stringify(d, null, 2)); |
|
source line number and file name | ||
command line documentation | ||
net and web | ||
typescript | dart | |
get local hostname, dns lookup, reverse dns lookup | ||
http get |
// npm install request var request = require('request'); request('http://www.google.com', function(err, resp, body) { if (!err && resp.statusCode == 200) { console.log(body); } } ); |
|
http post |
||
serve working directory | ||
absolute url from base and relative url |
||
parse url | ||
url encode/decode |
||
html escape escape character data, escape attribute value, unescape html entities |
||
base64 encode/decode | ||
debugging and profiling | ||
node | dart | |
check syntax | $ tsc --noEmit foo.ts | |
lint | $ npm install -g tslint $ tslint -c ~/.tslint.json -f foo.ts |
|
____________________________________________ | ____________________________________________ |
Version
Grammar and Execution
Variables and Expressions
Arithmetic and Logic
Strings
Regexes
Dates and Time
Arrays
Dictionaries
Functions
Execution Control
Exceptions
Streams
Files
File Formats
Directories
Processes and Environment
Libraries and Namespaces
User-Defined Types
Generic Types
Objects
Inheritance and Polymorphism
Reflection
Net and Web
Debugging and Profiling
check syntax
lint
typescript:
How to get a tslint.json file:
$ curl https://github.com/palantir/tslint/blob/master/docs/sample.tslint.json > ~/.tslint.json