diff --git a/core/builtin/builtin.go b/core/builtin/builtin.go
index c6c026b..c64c910 100644
--- a/core/builtin/builtin.go
+++ b/core/builtin/builtin.go
@@ -15,6 +15,7 @@ func init() {
 	builtins := map[string]types.KnownFunctionInterface{
 		"len":     builtinLen,
 		"map":     builtinMap,
+		"type":    builtinType,
 		"println": builtinPrintln,
 		"filter":  builtinFilter,
 		"assert":  builtinAssert,
diff --git a/core/builtin/type.go b/core/builtin/type.go
new file mode 100644
index 0000000..9b88773
--- /dev/null
+++ b/core/builtin/type.go
@@ -0,0 +1,34 @@
+package builtin
+
+import (
+	"sophia/core/serror"
+	"sophia/core/token"
+	"sophia/core/types"
+)
+
+func builtinType(tok *token.Token, args ...types.Node) any {
+	if len(args) < 1 {
+		serror.Add(tok, "Argument error", "Expected 1 argument for assert builtin")
+		serror.Panic()
+	}
+	if len(args) > 1 {
+		serror.Add(args[1].GetToken(), "Argument error", "Too many arguments, expected 1 argument for assert builtin")
+		serror.Panic()
+	}
+
+	// TODO: add all missing types
+	switch args[0].Eval().(type) {
+	case []any:
+		return "array"
+	case map[string]any:
+		return "object"
+	case float64:
+		return "float"
+	case string:
+		return "string"
+	default:
+		serror.Add(args[0].GetToken(), "Not implemented", "type built-in Not implemented for %T", args[0])
+		serror.Panic()
+		return nil
+	}
+}