Type system of a programming language describes how the types are to be handled. The languages that require the types of all expression to be known at compile-time are called statically typed languages.
The assurance that a variable contains only a certain type of value can be very useful. It can be used to avoid type errors. A type error occurs if an inappropriate operation is applied to a certain value. For example, the operation of decomposing a number into prime factors makes no sense if the number in question is not a natural number. There are many other quite simple operations that make no sense unless the value is an integer. These will be surfacing in the following chapters.
Types can also clarify many aspects of programs' source code. We might find them very useful later on for describing inputs and outputs of functions, making functions easier to understand.
On the other hand, some restrictions are necessary to allow the type system of a statically typed language to work. These restrictions may sometimes turn out to be cumbersome. Advanced knowledge may be required to satisfy the restrictions; even then this could turn out to be impossible to achieve if the programming language in question is lacking a sufficiently versatile type system. Fortunately, the C++ language has one of the most feature-full type systems available. However, this is an advanced topic.
Another way of handling types by a programming language is to remove the requirement that types have to be known at compile-time. In such a language, only values have types, while the expressions and variables generally do not have types. Such languages are called dynamically typed languages.
The advantage of dynamically typed languages is that no type restrictions have to be satisfied, and no types need to be specified. This results in a shorter source code of programs and removes the need for complicated type specifications. The downside is that type errors can happen, which can be detected only during the execution of a program, or in other words, during run-time. If that happens, the program usually crashes, or at least it is unable to complete the operation requested by the user. Dynamically typed languages also produce slower programs, but this might or might not be noticeable, depending on the case.
The advantage of a statically typed language is that all type errors, or at least many of them, are found while translating the program, during compile-time.