let isAlive: boolean = false;
A variable with the number data type can contain anynumeric literal with float-ing, hexadecimal, and binary or octal values.
let decimal: number = 6;
let hex: number = 0xf00d;
let binary: number = 0b1010;
let octal: number = 0o744;
let name: string = "Cell";
name = 'cellinlab';
let sentence: string = `There is ${name}'s blog.`;
let list: number[] = [1, 2, 3];
let list2: Array<number> = [1, 2, 3];
The Tuple type gives you the ability to declare an array with a known fixed number of elements that do not have to be of the same type.
let x: [string, number];
x = ['hello', 2022]; // OK
// x = [2022, 'hello']; // Error
console.log(x[0].substr(1)); // OK
// console.log(x[1].substr(1)); // Error, 'number' does not have 'substr'
x[3] = 'cellinlab'; // OK, string type can be assigned to '(string | number)'
console.log(x[5].toString()); // OK, 'string' and 'number' both have the 'toString' method
// x[6] = true; // Error, 'boolean' cannot be assigned to '(string | number)'
Since tuples use array syntax, they can be deconstructed or disassembled in two ways.
console.log(`tupleType[0] = ${tupleType[0]}`);
console.log(`tupleType[1] = ${tupleType[1]}`);
[t1, t2] = tupleType;
console.log(`t1 = ${t1}`);
console.log(`t2 = ${t2}`);
Like function signatures, we can also have optional tuple elements.
let optionalTuple: [string, boolean?];
optionalTuple = ['hello', true];
console.log(`optionalTuple: ${optionalTuple}`); // optionalTuple: 'hello', true
optionalTuple = ['cell'];
console.log(`optionalTuple: ${optionalTuple}`); // optionalTuple: 'cell'
Enum is a special type borrowed from other languages like C#, C ++, and Java that provides a solution to the special numbers problem. Enum binds a human-readable name for a specific number.
enum Color {Red, Green, Blue};
let c: Color = Color.Green;
By default, enums start with 0. You can change this by directly specifying a value for one of the enum members.
enum Color {Red = 1, Green, Blue};
let c: Color = Color.Green;
Or even set values for all members:
enum Color {Red = 1, Green = 2, Blue = 4};
let c: Color = Color.Green;
A convenient feature of enumerations is that you can also get the name of an enumeration member by passing its numeric value.
enum Color {Red = 1, Green = 2, Blue = 4};
let colorName: string = Color[2];
console.log(`colorName: ${colorName}`); // colorName: Green
Enumerations are a convenient way to define an easy-to-remember, easy-to-read name for a special number.
enum DoorState {Open, Closed, Ajar};
let openDoor: DoorState = DoorState.Open;
console.log(`openDoor: ${openDoor}`); // openDoor: 0
let closedDoor: DoorState = DoorState['Closed'];
console.log(`closedDoor: ${closedDoor}`); // closedDoor: 1
Another variant of the enum type is a string enumeration, in which numeric values are replaced with strings.
enum DoorStateString {
Open = 'open',
Closed = 'closed',
Ajar = 'ajar'
};
let openDoorString: DoorStateString = DoorStateString.Open;
console.log(`openDoorString: ${openDoorString}`); // openDoorString: open
We may need to describe the type of variables that wedon’t know when we write our application. These values can be obtained from dynamic content, such as from a user or from a third-party library. In these cases, we want to disable type checking and allow the values to pass validation at compile time.
let notSure: any = 4;
notSure = 'maybe a string instead';
notSure = false; // okay, definitely a boolean
The any type can also be useful if you know some part of the variable type, but not all of it.
let list: any[] = [1, true, 'free'];
list[1] = 100;
Void is the opposite of Any: the absence of any types. It is most often used as the return type of functions that do not return any value.
function warnUser(): void {
console.log('This is my warning message');
}
Declaring variables with the void type is useless, because you can only assign them undefined or null values:
let unusable: void = undefined;
The Null and Undefined types correspond to the same types in JS. These types are subtypes for all other types by default.
let n: number = null; // Primitive types can be null
n = undefined; // Primitive types can be undefined
let x = null; // same as x: any = null
let y = undefined; // same as y: any = undefined
// let e: Null; // Error
// let f: Undefined; // Error
If you declare a variable of type null or undefined, then such a variable can only be assigned the value null or undefined, respectively, which has no practical application.
let n: null = null;
// n = 1; // Error
let u: undefined = undefined;
// u = 'cellinlab'; // Error
In this case, if the variable needs to be assigned a value with the string or null or undefined type, you can use the string | null | undefined union type.
The never type represents a type whose value never occurs. For example, never is a type that returns a function that always throws exceptions or that never exits (for example, an infinite loop). Variables can also have this type, for example, in order to never take the value true.
The never type is a subtype of any type. A variable of type never can be assigned to a variable of any other type. On the other hand, there is no such type that will be a subtype of this type, just as a variable of this type cannot be assigned anything other than a variable of the same type (never).
function error(message: string): never {
throw new Error(message);
}
// the output type of fail() is never
function fail() {
return error('Something failed');
}
// no exit from this function
function infiniteLoop(): never {
while (true) {
}
}
The Symbol type is primitive and corresponds to the same type in JS.
This type provides unique identifiers that can be used askeys for object properties.
let secretKey = Symbol();
let obj = {};
obj[secretKey] = 'secret value'; // Symbol as property
obj[Symbol.toStringTag] = 'test';
Sometimes you find yourself in a situation where you know more about the value of a variable than TS does.This usually happens when you know that the type of an entity may be more specific than its current type.
Type assertion is like typecasting in other languages, but it doesn’t do any special checks or data restructurings.The type conversion has no effect at the execution stage of the program and is used only by the compiler. TS assumes that the programmer will do all the necessary checks that are required.
The type conversion can be done in two ways. The first is the use of angle brackets syntax:
let someValue: any = 'this is a string';
let strLength: number = (<string>someValue).length;
The second is as-syntax:
let someValue: any = 'this is a string';
let strLength: number = (someValue as string).length;
let input = [1, 2];
let [first, second] = input;
console.log(`first: ${first}, second: ${second}`); // first: 1, second: 2
function f ([first, second]: [number, number]) {
console.log(`first: ${first}, second: ${second}`);
}
You can also destruct objects.
let o = {
a: 'foo',
b: 12,
c: 'bar'
};
let { a, b } = o;
console.log(`a: ${a}, b: ${b}`); // a: foo, b: 12
// You can also give different names to the properties.
let { a: newName1, b: newName2 } = o;
console.log(`newName1: ${newName1}, newName2: ${newName2}`); // newName1: foo, newName2: 12
Default values allow you to define a property, even if it was not set.
function keepWholeObject(wholeObject: { a: string, b?: number }) {
let { a, b = 1001 } = wholeObject;
}
type C = { a: string, b?: number };
function f({ a, b }: C): void {
console.log(`a: ${a}, b: ${b}`);
}
// Specifying default values
function f2 ({ a, b } = { a: '', b: 0 }): void {
console.log(`a: ${a}, b: ${b}`);
}
f2() // a: , b: 0