This the multi-page printable view of this section. Click here to print.

Return to the regular view of this page.

The Basics

Essential TypeScript to get you up and running quickly with Deno.

Deno provides a consistent, standard environment for running TypeScript.

Although the TypeScript configuration can be modified, this is generally not recommended.

Deno by Example demonstrates the use of TypeScript for maximum productivity with the standard Deno environment.

1 - Hello World

Use console.log to print to standard output.

// `console.log` automatically converts args to strings.
console.log(1, "Hello, World!");

// Arguments are printed with a space between each one.
const name = "Deno";
console.log(2, "Hello,", name, "!");
console.log(3, "Hello,", name, "!", "You are number", 1, "!");

// Use a template literal to embed a variable directly in the
// string for better control over formatting.
console.log(4, `Hello, ${name}!`);

// Template literals allow you to embed expressions, not just
// variables, inside the braces (`${}`).
const getName = () => "Deno";
console.log(5, `Hello, ${getName()}!`);
  
1 Hello, World!
2 Hello, Deno !
3 Hello, Deno ! You are number 1 !
4 Hello, Deno!
5 Hello, Deno!
  

To run a program, use deno run.

To build an executable binary of a program, use deno compile.

2 - Values

Deno supports both JavaScript and TypeScript, which share the same primitive types: string, number, and boolean.

// String values.
// Strings can be concatenated.
console.log("deno" + ".land");

// Number values.
// Numbers support all the usual operations.
// There are no separate types for integer and
// floating point numbers.
console.log("1 + 1 =", 1 + 1);
console.log("2 - 1 =", 2 - 1);
console.log("2 * 2 =", 2 * 2);
console.log("6 / 3 =", 6 / 3);

// Boolean values.
console.log("true =", true);
console.log("false =", false);
console.log("true && false =", true && false);
console.log("true || false =", true || false);
console.log("!true =", !true);
  
deno.land
1 + 1 = 2
2 - 1 = 1
2 * 2 = 4
6 / 3 = 2
true = true
false = false
true && false = false
true || false = true
!true = false
  

2.1 - A bit more about numbers

TypeScript does not have separate types for integer and float values, only number. Be aware that the computations that result in a floating point value might not be what you’re expecting.

console.log("7 / 3 =", 7 / 3);
console.log("7.0 / 3.0 =", 7.0 / 3.0);
console.log("2.33 * 3 =", 2.33 * 3);
console.log("2.3333333333333335 * 3 =", 2.3333333333333335 * 3);
  
7 / 3 = 2.3333333333333335
7.0 / 3.0 = 2.3333333333333335
2.33 * 3 = 6.99
2.3333333333333335 * 3 = 7
  

You can use Math.ceil, Math.floor, and Math.round to convert to an integer rounded up, down, or to the nearest, respectively.

Try using Deno’s REPL (read-eval-print-loop) for experimenting. Enter deno repl (or just simply deno) in your terminal.

$ deno
Deno 1.12.1
exit using ctrl+d or close()
> Math.ceil(.95)
1
> Math.ceil(7/3)
3
> Math.floor(7/3)
2
> Math.round(7/3)
2

If you want to obtain a string value of the result of a calculation to a particular precision, you can use toPrecision() to specify the number of significant digits.

> (7/3).toPrecision(3)
"2.33"
> (2).toPrecision(4)
"2.000"

3 - Variables

Variables are explicitly declared and used by the compiler to check that they are used as expected for their type. You don’t have to declare the type if the compiler can infer it from its use.

let a = "hello";
console.log(a, typeof a);

let b = 1;
console.log(b, typeof b);

let c = b;
console.log(c, typeof c);

// error: c is a number, can't assign a string to it
// c = a;

let d = true;
console.log(d, typeof d);

let e: number;
// error: can't use e before it's assigned a value
// console.log(e, typeof(e));
e = 4;
console.log(e, typeof e);
  
hello string
1 number
1 number
true boolean
4 number
  

4 - Constants

You can use const anywhere you can use let to declare a variable. You use it for variables whose value will not change.

Many programmers consider it a best practice to use it for any variable that that does not specifically need to be mutable to avoid unintended side effects from accidentally reassigning a value.

const s = "constant";
console.log(s, typeof s);

// error: can't assign value to a constant
// s = "nope";

const n = 500000000;
console.log(n, typeof n);

const d = 3e20 / n;
console.log(d, typeof d);

console.log(Math.sin(n));
  
constant string
500000000 number
600000000000 number
-0.28470407323754404
  

5 - For

test

TypeScript supports three looping constructs:

Iterating over collections of something is such a common programming task, you will often find yourself using the for..of loop.

You’ll find yourself using the classic for loop mostly in situations where its syntax streamlines access to a loop counter that’s essential to your code implementation.

You will rarely need to iterate over an object’s properties, but when you do, you’ll see that you can still use a for..of loop instead of the more nuanced, legacy for..in loop.

5.1 - For loop

Classic for loop

All three “initialization/test/update” parts used.

for (let j = 4; j < 10; j++) {
  console.log(j);
}
  
4
5
6
7
8
9
  

Basic for loop

No initialization or update parts; only the test condition in the middle part (between the two semi-colons (;)).

let i = 1;

for (; i <= 3;) {
  console.log(i);
  i++;
}
  
1
2
3
  

For loop that only exits with break or return

This for loop will continuously “spin” unless it reaches a break or return statement, usually based on some condition to wait on that’s easier to specify in the loop body. Shown for completeness, but avoid doing this in normal code.

for (;;) {
  console.log("loop");
  break;
}
  
loop
  

For loop with continue

This for loop will conditionally continue to the next iteration of the loop, bypassing any remaining statements in the loop body.

for (let n = 0; n <= 5; n++) {
  if (n % 2 == 0) continue;
  console.log(n);
}
  
1
3
5
  

5.2 - For..of loop

The for..of loop is for looping over objects that implement the Iterable interface (expose a Symbol.iterator property).

In this section we’ll demonstrate iterating over:

5.2.1 - Iterating over a string

const str = "hello";

for (const s of str) {
  console.log(s, typeof s);
}
  
h string
e string
l string
l string
o string
  

5.2.2 - Iterating over an array

const nums = [2, 3, 4];

let sum = 0;

// Use `let i` because i mutates (`i++`).
for (let i = 0; i < nums.length; i++) {
  sum += nums[i];
}

console.log(`sum: ${sum}`);
  
sum: 9
  

5.2.3 - Iterating over a set

const set = new Set([2, 2, 3, 3, 4, 4]);

for (const val of set) {
  console.log(val);
}
  
2
3
4
  

5.2.4 - Iterating over a map

Iterate over map entries as key,value tuples.

const map = new Map([
  ["a", 1],
  ["b", 2],
  ["c", 3],
]);

for (const entry of map) {
  console.log(entry);
}
  
[ "a", 1 ]
[ "b", 2 ]
[ "c", 3 ]
  

Iterate over the map, accessing the key and value parts as variables.

const map = new Map([["a", 1], ["b", 2], ["c", 3]]);

for (const [k, v] of map) {
  console.log(`key: ${k} => value: ${v}`);
}
  
key: a => value: 1
key: b => value: 2
key: c => value: 3
  

Iterate over just keys.

const map = new Map([["a", 1], ["b", 2], ["c", 3]]);

for (const [key] of map) {
  console.log(`key: ${key}`);
}
  
key: a
key: b
key: c
  

Iterate over just the values. Note that a placeholder is required for each key, as designated by the underscore (_).

const map = new Map([["a", 1], ["b", 2], ["c", 3]]);

for (const [_, value] of map) {
  console.log(`value: ${value}`);
}
  
value: 1
value: 2
value: 3
  

5.3 - For..in loop

The for..in loop is used to iterate over an object’s properties. Its classic usage with JavaScript has complex behavior that can be surprising, but as long as you use TypeScript, you avoid the nuances of JavaScript’s object-based inheritance and object prototype chaining.

Here we demonstrate the for..in loop, followed by the equivalent example using the for..of loop discussed in the previous section. Our recommendation is that you focus on using the for..of loop to keep things simple.

Iterating object properties with for..in

This example will use code that has not been discussed yet. The main point of this example right now is just to highlight the for..in and for..of loops with objects.

class A {
  foo = "base-value";
}

class B extends A {
  bar = "derived-value";
}

const b = new B();

for (const prop in b) {
  console.log(prop, "=", b[prop as keyof B]);
}
  
foo = base-value
bar = derived-value
  

There are two things to note about the output:

  • Looping over an object’s properties enumerates all of the properties in the inheritance chain. This normally what you want (and this is different from iterating over the prototype chain when using classic JavaScript object-based inheritance, which might or might not be what you want).

  • Because TypeScript is strongly typed, you have to cast each element of the enumeration to an indexed access type using keyof for the type.

Iterating object properties with for..of

There’s an easier way to do this. Simply use the for..of loop discussed in the previous section. The object itself (b) is not directly iterable, but you can get an iterator using Object.entries(b), as shown here:

class A {
  foo = "base-value";
}

class B extends A {
  bar = "derived-value";
}

const b = new B();

for (const [key, value] of Object.entries(b)) {
  console.log(key, "=", value);
}
  
foo = base-value
bar = derived-value
  

If you want to iterate only over an object’s keys or its values, you can use Object.keys() or Object.values(), respectively, instead of Object.entries().