TypeScript

Aiden Kim
9 min readJun 24, 2021

What is TypeScript?

TypeScript is one of the program languages that web developers love, and many developers are using it to develop programs. “What is TypeScript?” In short, TypeScript is a programming language that gives type to JavaScript. It is an extended language of JavaScript.

Why do we use TypeScript?

Why should we learn another language when JavaScript is complicated and difficult enough? We have many concerns such as “Do we have to use it due to other companies use it a lot?” or “It just because of the latest technology?” etc.

TypeScript can increase the quality and development productivity of JavaScript code from the two perspectives below.

Prevention of Errors

TypeScript enhance the quality and readability of code, making it easier to maintain and refactor applications. In particular, it can definitely reduce bugs in applications because it catches errors at compile time rather than at runtime.

Let’s compare the two codes below and see how TypeScript can prevent errors in advance.

// JavaScriptfunction add(num1, num2) {
return num1 + num2;
}
// TypeScriptfunction add(num1: number, num2: number): number {
return num1 + num2;
}

Both codes are function codes that obtain the sum of both numbers. I wrote one in JavaScript and the other in TypeScript. Let’s see the result with this function.

Ex-1 JavaScript
JavaScript Result

Add the numbers 10 and 20 using the add() function. Then we can get 30 as we want result.

However, if string value put in the add() function written through JavaScript, it will not be able to get the desired value through the add() function.

JavaScript Wrong Result

Let’s take a look at the code written in TypeScript. As you can see, Visual Studio Code already warns us that the arguement of the function has an incorrect value inserted.

TypeScript Error

Code Autocomplete and Guide

Another advantage of TypeScript is that we can make the most of the development tool’s capabilities when writing code. Visual Studio Code, which is most commonly used in front-end development these days, is optimized for TypeScript development because the tool created by TypeScript.

Let’s look at the JavaScript code below to see what the advantages of adding a type to JavaScript from a developer’s perspective are.

// JavaScriptfunction add(num1, num2) {
return num1 + num2;
}
let total = add(10, 20);
total.toLocaleString();

The above code is a code that uses the add() function we saw earlier to get the result from the sum of the two numbers and then append “toLocaleString() API”, which marks numbers according to the expression of a particular language. It does not matter what role the API called “toLocaleString()” do it here, but it is important that JavaScript cannot recognize that the type of total variable is number at the time of writing the code.

In other words, the developers themselves expect the result of the add() function and then assume the type of result must be a number before writing a code “toLocaleString()” which API of number. Take a look at this process below.

As you can see above, the type of total variable is any, so I typed code one by one in order to write “toLocaleString()”, which API provided by JavaScript Number. If it were a typo and wrote “toLocalString()”, it would only be possible to check the error when this ex-1.js file was run in the browser.

By the way, what would happen if the code was written by TypeScript as below?

// TypeScriptfunction add(num1: number, num2: number): number {
return num1 + num2;
}
let total = add(10, 20);
total.toLocaleString();

Because the type is already specified for the total variable, Visual Studio Code can preview APIs for that type, so it allows quickly and accurately write APIs with tab rather than typing them one by one.

Types

Number

const num: number = -6;

String

const str: string = 'hello';

Boolean

const boal: boolean = false;

Undefined and Null

Undefined and Null are rarely useful in their own types. On the other hand, it becomes useful when used with an Union type.

type Person: string | undefined | null;

Unknown and Any

It is better to avoid use Unknown and Any types in TypeScript due to making like as JavaScript code.

// unknownlet notSure: unknown = 0;
notSure = 'he';
notSure = true;
// any let anything: any = 0;
anything = 'hello';

As you can see above, a different type can be put into a variable already declared.

Void

Typically Void used as a return type for function that do not return value. If you want to use void for return type when implementing the function, it can be omitted. Because TypeScript considers the return type as void if there is no return type in the function.

// Declared void
function print(): void {
console.log('hello');
}
// Omitted voidfunction print() {
console.log('hello');
}

Never

Never type is commonly used for the deal with exception function or the function that has an infinite loop.

// Exception functionfunction throwErr(message: string): never {
// ... code
throw new Error(message);
}
// Infinite loop in the functionfunction infinite(in: number): never {
// ... code
while(true){}
}

Object

It is not recommended that declare the object type in a variable because the value can be changed.

let obj: object;function acceptSomeObject(obj: object) {}acceptSomeObject({ name: 'aiden' });
acceptSomeObject({ animal: 'dog' });

Array

const scores: number[] = [1, 2, 3];// Use genericconst scores: Array<number> = [1, 2, 3];

Tuple

Tuple is an array but can have different types. It is not good to write recklessly except interfaces, type alias, or class because they are less legible. However, this tuple can be useful if something is dynamically returned it is ambiguous to ask in a class or interface, and the user defines and writes a name by grouping other types of data that are dynamically related to something. Tuple is often used in React hooks.

let student: [string, number];
student = ['name', 123];
student[0]; // name
student[1]; // 123
const [name, age] = student;

Alias

If your own type needs to be defined you can use alias type.

type Text = string;const name: Text = 'aiden';
const address: Text = 'canada';
type Num = number;

It is possible to define primitive types as well as object shape types.

type Student = {
name: string;
age: number;
};
const student: Student = {
name: 'aiden',
age: 12,
};

One important fact is that cannot assign a different thing that it is not included to an object that has already been declared. If other data located in there it will be an error.

// Error occurredconst student: Student = {
animal: 'dog',
age: 12,
};

Union

Union is a type that means A or B, such as the OR operator “||” in JavaScript. Thus union type is better to use in case of when only one of all possible cases can be allocated.

type Direction = 'left' | 'right' | 'up' | 'down';function move(direction: Direction) {
console.log(direction);
}
move('down')

The move() function implemented above can only accept arguments declared in the Direction type as factors.

type SuccessState = {
response: {
body: string;
};
};
type FailState = {
reason: string;
};
type LoginState = SuccessState | FailState;function printLoginState(state: LoginState) {
if ('response' in state) {
console.log(state.response.body);
} else {
console.log(state.reason);
}
}

The above code does not cause errors, but it is recommended that use the discriminated union type described below.

Discriminated Union

Discriminated union refers to the assignment of a common key within a union type to be shared.

type SuccessState = {
result: 'succes';
response: {
body: string;
};
};
type FailState = {
result: 'fail';
reason: string;
};
type LoginState = SuccessState | FailState;function printLoginState(state: LoginState) {
if (state.result === 'success') {
console.log(state.response.body);
} else {
console.log(state.reason);
}
}

The discriminated union type, such as the code written above, allows for more intuitive writing of code for the application.

Intersection

Union is “OR” concept whereas intersection is “AND” concept.

type Student = {
name: string;
score: number;
};
type Worker = {
empolyeeId: number;
work: () => void;
};
function internWork(person: Student & Worker) {
console.log(person.name, person.empolyeeId, person.work());
}
internWork({
name: 'aiden',
score: 1,
empolyeeId: 123,
work: () => {},
});

If the intersection type is used as seen in the code above, the argument value must be given all keys of the corresponding types where the function is invoked.

Enum

It is a type that collects and manages the values of various related constants in one place. In other words, enum means a set of sepecific values.

In JavaScript, constants are usually declared as follows.

// JavaScript contantsconst MAX_NUM = 6;
const MAX_STUDENTS_PER_CLASS = 10;
const MONDAY = 0;
const TUESDAY = 1;
const WEDNESDAY = 2;

In JavaScript, an API called freeze() can be used to make objects looks like enum so that constants can be grouped together and defined only once to avoid modification.

// Making an Enum in JavaScriptconst DAYS_ENUM = Object.freeze({ MONDAY: 0, 
TUESDAY: 1,
WEDNESDAY: 2 });
const dayOfToday = DAYS_ENUM.MONDAY;

However, in TypeScript, when declaring enum, only the first letter is capitalized, not the whole of the variable name.

enum Days {
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday,
Sunday,
}
console.log(Days.Monday); // 0

If the initial value is not given as shown in the code above, it will increase by one from zero.

It is not recommended to use enum in a TypeScript frequently because it can assign other values than enum, even though it has already assigned enum to a variable.

let day: Days = Days.Saturday;
day = Days.Tuesday; // Okay
day = 10; // Oops
console.log(day); // 10

For this reason, TypeScript usually use union more than enum. However, when data needs to be exchanged with other languages, for example, if a web-based application and a mobile-based application need to communicate with each other, union type cannot be recognized in other languages, so it is forced to use enum.

Inference

TypeScript can be determined by itself when the type is not specified in a variable or function.

TypeScript examines the data assigned to the variable and considers the variable text to be the string type, when it does not declare a string as shown in the code below.

// TypeScript Inferencelet text = 'hello';
let text: string = 'hello';
function add(x: number, y: number) {
return x + y;
}
function add(x: number, y: number): number {
return x + y;
}
const result = add(1, 3);
console.log(result);

While it is convenient to use type inference when implementing simple functions, using it when creating complex functions may make it difficult for developers to understand the code. Therefore, it is recommended to make it a habit to always declare a return type when implementing a function.

Assertion

TypeScript allows you to override the inference type in any way you want. Assertion is commonly used to migrate code from JavaScript, which is recommended when you know exactly the return type of function or the type of variable. If the type of prediction is uncertain and you use it, there will be no errors in compiling time and when you write code, but you will see unexpected results in the web browser.

function jsStrFunc(): any {
return 2;
}
const result = jsStrFunc();
console.log((result as string).length);
console.log((<string>result).length); // same result above
const wrong: any =5;
console.log((wrong as Array<number>).push(1)); // It's horrible

Tutorial

Now, let’s watch this video and see how to implement a simple calculate() function using the above types.

References

https://joshua1988.github.io/ts/why-ts.html#%ED%83%80%EC%9E%85%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8%EB%9E%80

--

--