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
Note
Always use let
to declare a variable unless you know the value is
constant, which we’ll discuss in the next section.Warning: let vs. var
Although TypeScript allows using var
to declare variables, don’t use it –
always use let
or const
instead.
var
is available to support legacy behavior from older JavaScript, but it’s
use is problematic in modern TypeScript. See the
Handbook
to dig deeper.
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);
}
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++;
}
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;
}
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);
}
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}`);
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);
}
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}`);
}
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()
.