[TypeScript] How to use TypeScript?

JONGHYUN PARK
12 min readApr 8, 2021

Type Declaration

TypeScript can declare a type by specifying the type after the variable name as shown below.

Type Declaration 1

If a value that does not match the declared type is assigned, an error occurs at compile time. These type declarations help developers predict code. In addition, the type declaration enables strong type checking to detect basic errors such as syntax errors or assignment of values ​​that do not match the type before runtime. The method of declaring the type of function parameters and return values ​​is as follows. As with general variables, if a value that does not match the declared type is given, an error occurs.

Type Declaration 2

Since TypeScript is a superset (upper extension) of ES5 and ES6, the type of JavaScript can be used as it is. In addition to the types of JavaScript, TypeScript-specific types are additionally provided.

Type Declaration 3

How to predeclare various types is as follows.

Type Declaration 4
Type Declaration 5

Types are sensitive to lowercase letters and uppercase letters, so care must be taken. As mentioned above, all types provided by TypeScript are in lower case. Take a look at the code below.

Type Declaration 6

The string type means a string type, which is a primitive type provided by TypeScript. However, the String type starting with an uppercase letter means the String wrapper object type created by the String constructor function. Therefore, if you assign the String type to the string type, an error occurs. However, you can assign a string type to a String type. Like this, the type of an object can also be a type.

Type Declaration 7

Static typing

In C-family languages ​​such as C or Java, when declaring a variable, the type must be explicitly declared in advance according to the type of the value to be assigned to the variable, and a value appropriate for the declared type must be assigned. This is called static typing.

JavaScript is either a dynamic typed language or a loosely typed language. This means that the type is dynamically inferred in the process of assigning a value without declaring the type of the variable. In a dynamic typed language, even after the type of a variable is determined by type inference, multiple types of values ​​can be intersected and assigned to the same variable. This is called dynamic typing.

Dynamic typing is easy to use, but the code is hard to predict, and it is likely to make unexpected errors. It also prevents tools such as IDE from supporting functions such as code assist because the types of variables, parameters, and function return values ​​are not known.

Static typing 1

The most unique feature of TypeScript is that it supports static typing . Statically typed languages ​​explicitly declare types, and once the type is determined, the type cannot be changed. If an incorrect type of value is assigned or returned, the compiler detects it and raises an error.

Static typing 2

The advantage of static typing can be seen as improved code readability, predictability, and stability, which is very suitable for large projects.

Type inference

If the type declaration is omitted, the type is dynamically determined in the process of assigning a value. This is called type inference. In a dynamic typed language, even after the type of a variable is determined by type inference, multiple types of values ​​can be intersected and assigned to the same variable. However, in a statically typed language, the type cannot be changed after the type is determined. Since TypeScript is a statically typed language, an error occurs if a value of another type is assigned after the type is determined by type inference. If the any type cannot be inferred because the type declaration is omitted and a value is not assigned, it becomes a type. any Variables of type can be reassigned to values ​​of any type, just like variables declared with the var keyword in JavaScript. This eliminates the advantage of using TypeScript, so it's better not to use it.

Type inference

Type Casting

To cast a type from an existing type to another type <>, you can use the as keyword or operator. Let's look at the following example.

Type Casting 1

The document.querySelector method uses Element | Returns a null type value. So, the $input in the example above is Element | It is a null type. At this time $input.value, if is executed, a compile error occurs because the value property does not exist in the Element or null type. The value property exists only in the HTMLInputElement type, which is a subtype of the Element type. Therefore, type casting is required as follows. Alternatively <>, you can use an operator instead of the as keyword for type casting .

Type Casting 2

Classes newly introduced in ES6 present a simple and clear new grammar that developers familiar with class-based languages ​​can learn faster than existing prototype-based object-oriented languages. However, classes do not provide a new object-oriented model. In fact, classes are functions and are just syntactic sugars in the existing prototype-based pattern. The classes supported by Typescript are quite similar to those in ECMAScript 6, but there are some Typescript-specific extensions.

Class Definition

ES6 classes can contain only methods in the body of the class. Class properties cannot be declared in the class body, and class properties must be declared and initialized inside the constructor. The Typescript class must declare class properties in the class body in advance.

Class Definition

Access Restrictor

The Typescript class supports public, private, and protected access modifiers supported by class-based object-oriented languages, and the meaning is basically the same. However, when the access limiter is not specified, in the case of other class-based languages, it is implicitly designated as protected and disclosed at the package level, but in the case of Typescript, class properties and methods that omit the access limiter are implicitly declared public. Therefore, for member variables and methods to be designated as public, the access limiter is omitted. The accessibility for the property and method that declares the access modifier is as follows.

Access Restrictor 1

Let’s take a look at the accessibility of a property with an access limiter declared through the example below.

Access Restrictor 2

Declare access limiter in constructor parameter

Access modifiers can also be declared in constructor parameters. At this time, the constructor parameter in which the access limiter is used is implicitly declared as a class property, and initialization is performed implicitly even if there is no separate initialization inside the constructor. At this time, if the private access limiter is used, it can be referenced only inside the class, and when the public access limiter is used, it can be referenced outside the class.

Declare access limiter in constructor parameter

readonly keyword

Typescript can readonly use keywords. Class properties in which readonly is declared can be assigned a value only at the time of declaration or inside the constructor. Otherwise, the value cannot be assigned and only read is possible. This is used to declare constants.

readonly keyword

static keyword

In ES6 classes, the static keyword defines a static method of the class. Static methods are called with the class name, not an instance of the class. Therefore, it can be called without creating an instance of the class.

static keyword 1

In Typescript, the static keyword can also be used for class properties. Like static methods, static class properties are called by class name rather than instance, and can be called without creating an instance of the class.

static keyword 2

Abstract Class

An abstract class contains one or more abstract methods and may also contain general methods. Abstract method refers to a method in which only the method name and type are declared without content, and the abstract keyword is used when declaring. When defining an abstract class, the abstract keyword is used, and it cannot be instantiated directly, it is used only for inheritance. A class that inherits an abstract class must implement the abstract method of the abstract class.

Abstract Class

Interfaces

Interfaces are generally used for type checking and can be used for variables, functions, and classes . Interfaces are similar to defining a new type of properties with different types. It is to maintain consistency by forcing the implementation of the property or method declared in the interface. ES6 does not support interfaces, but TypeScript does.

Interfaces are similar to classes in that they can have properties and methods, but they cannot be instantiated directly, and all methods are abstract methods. However, unlike abstract methods of abstract classes, the abstract keyword is not used.

Variables and Interfaces

Interfaces can be used as variable types. At this time, the variable that declares the interface as a type must comply with the corresponding interface. This is similar to defining a new type. You can use interfaces to declare the types of function parameters. In this case, an argument that conforms to the interface specified as the type of the function parameter must be passed to the function. When passing an object to a function, it is very useful because there is no need for complicated parameter checking.

Variables and Interfaces

Functions and Interfaces

Interfaces can be used as function types. In this case, the parameter list in which the type is declared and the return type are defined in the function interface. Functions implementing the function interface must conform to the interface.

Functions and Interfaces

Classes and Interfaces

When an interface is declared after implements of a class declaration statement, the class must implement the specified interface. This has the advantage of maintaining the consistency of the class implementing the interface. Interfaces are similar to classes in that they can have properties and methods, but they cannot be instantiated directly.

Classes and Interfaces 1

Interfaces can contain methods as well as properties. However, all methods must be abstract methods. The class implementing the interface must implement the properties and abstract methods defined in the interface.

Classes and Interfaces 2

Duck typing

Note that implementing an interface is not the only way to pass type checks. The important thing in type checking is that you actually have a value. It can be difficult to understand, so I will explain with an example.

Duck typing 1

(1) Interface IDuck defined quack method.

(2) The makeNoise function receives the instance duck of the class that implements the interface IDuck as an argument.

(3) Class MallardDuck implements the interface IDuck.

(4) Class RedheadDuck does not implement interface IDuck, but has quack method.

(5) Even if an instance of the class RedheadDuck that does not implement the interface IDuck to the makeNoise function is passed as an argument, it is processed without error.

If TypeScript has a property or method defined in the relevant interface, it is recognized as implementing the interface. This is called duck typing or structural typing. Duck typing also applies when using interfaces for variables.

Duck typing 2

The variable me does not match the interface IPerson. However, if you have IPerson’s name property, it is recognized as matching the interface. Interface is a function provided to help in the development stage and is not a standard of JavaScript. Therefore, if the TypeScript file in the above example is transpiled into a JavaScript file, the interface is deleted as follows.

Optional properties

Interface properties must be implemented. However, there may be cases where the properties of the interface are selectively required. Optional property ? is appended after the property name, and an error does not occur even if omitted.

Optional properties

Interface inheritance

Interfaces can inherit interfaces or classes by using the extends keyword. Multiple interfaces can also be inherited. Interfaces can inherit not only interfaces but also classes. However, all members (public, protected, private) of the class are inherited, but not even the implementation.

Interface inheritance

Type Alias

Type aliases define a new type. Type aliases are similar to interfaces in that they can be used as types. Interfaces can be used in the following types.

Type Alias 1

Type aliases can also be used as types, just like interfaces.

Type Alias 2

However, type aliases can also specify primitive values, union types, and tuples as types.

Type Alias 3

Interfaces can be extends or implements, but type aliases cannot. In other words, if you need to extend through inheritance, interfaces are more advantageous than type aliases. However, if you cannot express it as an interface, or if you need to use unions or tuples, it is better to use type aliases.

Generic

In the case of a statically typed language such as Java or C#, the type of parameter or return value must be declared when defining a function or class. Since TypeScript is also a statically typed language, you must declare the type of parameter or return value when defining a function or class. However, there are cases in which it is difficult to declare the type of parameter or return value when defining a function or class.

Let’s look at an example below. It represents a queue that stores data in a FIFO (First In First Out) structure.

Generic 1

The data property of the Queue class is any[] type. The any[] type means an array that can have any type of element.

The any[] type has a problem that the types of array elements are not all the same. In the above example, Number.prototype.toFixed was used for each element with the expectation that the data property is an array containing only number type . Therefore, for elements other than number type, a runtime error occurs.

To solve the above problem, you can define NumberQueue class exclusively for number type by inheriting Queue class.

Generic 2

If you define the NumberQueue class exclusively for number type in this way, when an element other than number type is pushed, an error can be detected before runtime.

However, if you need to support various types, this is also not a good method because you have to inherit and add classes for each type. Let’s solve this problem using generics.

Generic 3

Generics are a technique in which a type is specified at the time of creation, not at the time of declaration, so that various types can be used. It has the advantage that it can be reused for various types with one declaration.

T is an identifier commonly used when declaring a generic, and is called a type parameter. T is an abbreviation of Type, and it is not necessary to use T. You can also use generics in functions. If you use generics, you can use parameters and return values ​​of various types, not just one type.

In the reverse function, the type parameter is determined by the type of the argument. The Reverse function receives an array composed of various types of elements as an argument. For example, if an array with elements of type number is received, the type parameter becomes number. If an array with elements of type {name: string} is received, the type parameter becomes {name: string}.

Generic 4

--

--

JONGHYUN PARK
0 Followers

IT (Software Development) Student at Southern Alberta Institute of Technology Calgary, Alberta, Canada