Books / TypeScript for Java Developers by CodeAhoy / Chapter 3
Variables and Data Types
A variable is a named storage location that holds a value of a certain data type. It’s data type specifies the kind of value that a variable is storing, such as a string
, or a number
.
Declaring and Using Variables
In Java, variables are also used to store values. Variables can be of different data types such as int
, double
, char
, and the type of variable is defined when it is declared.
int age = 30;
double salary = 125000.00;
char grade = 'A';
TypeScript variables are very similar to Java. Here, we can use the var
or let
keyword to declare a variable, followed by the name of the variable, a semi-colon :
, and it’s type:
var name: string = "Zayn";
let age: number = 30;
var isTrained: boolean = true;
The type is optional. If you don’t provide the type, TypeScript will infer it based on the type of variable that you defined. E.g. if you do color = 'green'
, the color
will be of type string
.
You can also use the let
keywords to declare variables in TypeScript. let
is similar to var
, but it has block-level scope, which means that the variable is only accessible within the block of code in which it is defined. var
. on the other hand is are scoped to the function body and hence have Function scope.
What’s the difference between var and let?
The keyword const
is used to declare a constant, which is a variable that cannot be reassigned. In Java, we declare constants are declared using the final
keyword.
Data Types in TypeScript
Java has a few more built-in data types than TypeScript, such as long
and short
, which are used to store large and small integers, respectively. TypeScript, on the other hand, has a few more advanced data types, such as enum
(enumeration) and union
, which allow you to define a set of related values or a value that can be one of several different types.
Here is a list of all the data types in TypeScript and a brief explanation for each:
boolean
: A data type that can hold either atrue
orfalse
value. E.g.let isComplete: boolean = false;
number
: A data type that can hold any numeric value, including integers, floating-point values, and hexadecimal values. E.g.let decimal: number = 10;
string
: A data type that can hold a sequence of characters, represented as a string literal in quotes.symbol
: A data type that represents a unique, immutable identifier.null
andundefined
: These data types represent the absence of a value.null
is an intentional absence of a value, whileundefined
represents an uninitialized or missing value.object
: A data type that represents any non-primitive value, such as arrays, functions, and user-defined objects.array
: A data type that represents an ordered collection of elements. You can declare an array in TypeScript using the[]
notation, followed by the type of elements it will hold:number[]
for an array of numbers,string[]
for an array of strings, etc.tuple
: A data type that represents an ordered collection of elements with a fixed number of elements, each with a specific type. You can declare a tuple in TypeScript using the[ ]
notation, followed by a comma-separated list of types:[string, number]
for a tuple with a string and a number,[boolean, string, number]
for a tuple with a boolean, a string, and a number, etc.enum
: A data type that represents a set of related values. You can declare an enum in TypeScript using theenum
keyword, followed by the name of the enum and a list of values in curly braces:enum Color {Red, Green, Blue}
for an enum with three colors.any
: A data type that represents a value of any type. This is useful when you need to work with values of different types and you don’t want to specify a specific type. Theany
type is a powerful way to work with existing JavaScript, allowing you to gradually opt-in and opt-out of type checking during compilation.void
: A data type that represents the absence of a value, typically used as the return type of functions that do not return a value.void
is a somewhat like the opposite ofany
: the absence of havingany
type at all.never
: A data type that represents a value that never occurs. This is typically used as the return type of functions that throw an exception or never terminate.unknown
: A data type that represents a value that we do not know when we are writing an application.
Checking Data Types at Runtime
We can check the type of a variable using the typeof
operator or the instanceof
operator.
let x: any = "hello";
if (typeof x === "string") {
console.log("x is a string");
} else {
console.log("x is not a string");
}
Here’s an example of using the instanceof
operator:
class MyClass { }
let x: any = new MyClass();
if (x instanceof MyClass) {
console.log("x is an instance of MyClass");
} else {
console.log("x is not an instance of MyClass");
}
When to use typeof
vs instanceof
? According to this Stackoverflow answer:
Use instanceof
for custom types:
var ClassFirst = function () {};
var ClassSecond = function () {};
var instance = new ClassFirst();
typeof instance; // object
typeof instance == 'ClassFirst'; // false
instance instanceof Object; // true
instance instanceof ClassFirst; // true
instance instanceof ClassSecond; // false
Use typeof
for simple built in types:
'example string' instanceof String; // false
typeof 'example string' == 'string'; // true
'example string' instanceof Object; // false
typeof 'example string' == 'object'; // false
true instanceof Boolean; // false
typeof true == 'boolean'; // true
99.99 instanceof Number; // false
typeof 99.99 == 'number'; // true
function() {} instanceof Function; // true
typeof function() {} == 'function'; // true
Use instanceof
for complex built in types:
/regularexpression/ instanceof RegExp; // true
typeof /regularexpression/; // object
[] instanceof Array; // true
typeof []; //object
{} instanceof Object; // true
typeof {}; // object
Type Casting
Type casting is the process of converting a value from one data type to another such as a string e.g. “10” to an integer 10.
To do type casting in Java, you can use the (type) operator, followed by the value you want to cast:
double value = 10.5;
int result = (int) value;
In the example above, the value of 10.5
is stored in a variable of type double. However, we want to convert this value to an integer, so we use the (int)
operator to cast it to the int
type. In addition there are some popular class methods for type conversions that you’ve been familiar with:
toString()
: Converts a value to a string.parseInt()
: Converts a string to an integer.parseDouble()
: Converts a string to a double.
TypeScript has a similar mechanisms for type casting, just the syntax is different.
To type cast in TypeScript, you can use the as
operator, followed by the type you want to cast the value to:
let a: typeA;
let b = a as typeB;
E.g.
let greeting: unknown = 'hello'; // greeting has unknown type
console.log((greeting as string).length); // cast greeting to string and call the string.length method on it
You can also use the <type>
syntax to convert types.
let a: typeA;
let b = <typeB>a;
let greeting: unknown = 'hello';
console.log((<string>greeting).length);
Union Type
Unlike Java, variables in TypeScript can have more than one type at the same time. This is known as the “union type”. A union type represents a value that can be one of several different types.
let x: number | string;
x = "hello";
console.log(x); // Output: "hello"
x = 10;
console.log(x); // Output: 10
In this example, the variable x
is defined as a union type that can be either a number
or a string
. It can be assigned a value of either type, and the assignment is legal and will work.
Destructuring Assignment
TypeScript allows developers to use a syntax known as destructuring assignment to extract values from arrays or object properties into distinct variables. It is a useful feature that makes it easier to work with arrays and objects in TypeScript and makes the code more readable.
Here’s an example with arrays where we are using the destructuring assignment to extract the values 1
, 2
, and 3
from an array and assigning them to the variables: a
, b
, and c
, respectively.
let [a, b, c] = [1, 2, 3];
We can do the same object to extract its properties into separate variables. In the example below we are using the destructuring assignment to extract the values 1
, 2
, and 3
from the object and assigning them to the x
, y
, and z
, respectively.
let {x, y, z} = {x: 1, y: 2, z: 3};
We can also use destructuring assignment to extract values from nested arrays and objects:
let [a, [b, c], d] = [1, [2, 3], 4];
If we run this, we’d get:
a = 1
b = 2
c = 3
d = 4
We also use default values in destructuring assignments, which is used if the value being destructured is undefined
or null
:
let [a, b = 0] = [1]; // b === 0
let {x, y = 0} = {x: 1}; // y === 0