I’m currently learning the Godot Game Engine and GDScript programming by myself. I have categorized each GDScript data types and found it is useful for understanding many behaviors. So, in this article, I want to share what I have done. The referenced information was based on Godot 3.0.6 stable version and GDScript 3.0 Document.

source : https://github.com/godotengine/godot/blob/
master/core/variant.h
The categorization (highlighted) was added by this article’s author.
From the Godot source code, the Variant class defines 27 type codes:
0 for null, 1 for bool, 2 for int, …, 26 for PoolColorArray. How could we divided these types into categories based on usages.
The first criteria of the categorization is Inheritance. Only classes can be inherited. Other data type such as String, Vector2, int, float, etc. cannot be inherited. So, the first step is to categorize the data types into two groups :
1. Built-in : cannot be inherited
2. Class : can be inherited

The built-in data type can be further divided into:
1. Atomic : contains no further data element. This category consists of 5 data types: null, bool, int, float, and String.
2. Non-Atomic : contains sub-data elements. For example, Vector2 contains x and y as floating points.

Another way to categorize the built-in data type is whether they contain methods or not.
1. Primitive : contains no method to be called. This category consists of 4 data types: null, bool, int and float. Written “5.some_method()” is not allowed. There is no any methods for these data types.
2. Non-Primitive (or Class-Like) : contains some methods. For example, writing “Vector2(0,0).length()” is allowed. Why this category could be called class-like. Because it contains methods. But it is not quite like a class because it does not have inheritance and not use “new()” to create an instance.
The Class data type can be further divided into:
1. Native class : classes created with C++ and mostly created by the Godot Framework/Library.
2. User-Defined class : classes created by users with the GDScript.
This categorization is useful because in some circumstances these two categories act differently. For example, obj.get_class() always returns a native class name even if the object is a user-defined class. To check whether it is a user-defined class, obj.get_script() might be used.
Benefit of the categorization
The benefit from categorization is to see clearer picture when using GDScript. For example:
Q: Why the Vector2 cannot be inherited?
A: Because it is built-in data type not the class data type.
Q: Why bool, int, or float don’t have any methods to be called?
A: Because they are primitive data types.
Q: Why Vector2 and Node have different creation syntax?
For Vector2: Vector2(0, 0)
For Node: Node.new()
A: Because Node is a class. Any class could be created using .new() method. It will then called _init() defined inside the class. While Vector2 is a non-atomic built-in. It use simple syntax like that “Vector2(0, 0)”.
For me, I got many benefits from this categorization. So, I want to share it for every Godot & GDScript enthusiasms and colleagues.
References:
Source code of the Variant class :
https://github.com/godotengine/godot/blob/master/core/variant.h
GDScript Document : https://docs.godotengine.org/en/3.0/getting_started/scripting/gdscript/gdscript_basics.html
Godot Class Reference : https://docs.godotengine.org/en/3.0/classes/index.html