The type of a value refers to information that the system may use to efficiently store and manipulate the value. The type of a value may inform storage requirements and/or operational decisions. Tcl is expressly oblivious to the type of a value, and defers all such functionality to the individual commands themselves.
There is some concept of type at every level of machine instruction. At the assembly level, assemblers deal explicitly with the manipulation of groups of bits/bytes, so the types of operands it understands are strictly related to the physical characteristics of memory and of CPU registers, namely the size of the operand in bits/bytes. Programming languages at each successive layer attempt to provide data types that are more abstracted from the strict characteristics of the underlying machine and closer to the logical data types than humans think in terms of. At the next level up, for example, languages such as C provide numeric types and operators that are closer to the mathematics that humans practice, but that are still somewhat defined in terms of the size they occupy in machine memory. C also provides a struct type, instances of which are composed from user-specified sequences of the other physical types including the struct type itself. Moving up yet another layer, languages like C++ provide facilities to create purely logical data types, along with facilities for giving operators semantics that make sense for the logical types that users define. At yet another layer, scripting Languages attempt to dispense with much of the verbiage of explicitly declaring types, relying instead on either how the value was created or how it is used to determine the logical type of the value. Scripting languages are also generally more dynamic, such that this type resolution can only happen at the point that the particular function/command/statement/expression is executed. Regardless of how far toward logical data types a language leans, internally it must ultimately map these logical types and their operations onto the lower-level physical types that CPU instruction sets accept. Higher-level languages spend a good deal of their processing time working out the details of this mapping, and research into reducing this overhead is a hot topic.
Some languages such as Smalltalk present more novel approaches to data types. In Smalltalk there is only one data type: "object", and there are no operators - only messages between objectw, which are expected to know internally what the messages intended for them mean and how to react to them. Tcl represents another novel approach that bears some similarity to Smalltalk. There are no objects, just values which are all strings, and commands. Each command is a system unto itself, may be implemented in C or some other language, and may use any type strategy it chooses. The only constraint it has is that it must accept Tcl values, and return a Tcl value.
Some languages such as C require the programmer to declare the type of each variable and each argument to each function. Other languages such as ML infer the type of a value or expression by inspecting its syntax and context. In Tcl, at the script level, every value is already a string, so there is no need to try to determine its type. Each command though, can use any strategy it chooses to process values. Many built-in commands such as lappend specify what type they will interpret each of their arguments as. A third-party command might actually be implemented in ML, and would therefore have the full facilities of that language available to process its inputs.
One key difference in Tcl is that because each value is a string, the question is not "what type is this value ?", but "what type can this value be interpreted as?".
DKF: Except this section is intensely misleading. Tcl's values can convey types, and EIAS only in that the string type is the most general type of all value types (i.e., all other types in Tcl are subtypes of string). Where two commands are such that one produces values of some more defined type (e.g., a floating point number) and the other wishes to consume that type, they can conspire to use that other type for the values between them. This is the basis of how the typing systems of both Tcl_Objs and tclquadcode work.
Note that my statement about other types being subtypes of string is true, but can confuse some who think that types tell you everything about representations. The relationship between two types doesn't tell you about how they are implemented, but rather what operations may be performed without error. All string operations work on all values, that's the only type for which that statement is true, so that makes the string type the supertype of all others.
Type Safety refers to the ability of a compiler or interpreter to ensure that functions/commands are invoked only with values of the proper type. An explicitly and statically-typed language like C can provide type safety fairly easily, although C in particular allows the programmer to escape the confines of its type safety mechanism via casting. Higher-level languages that choose that attempt ensure type safety come up with various schemes for doing so. Both Tcl and Smalltalk act simply as conveyers of values (Tcl) or messages (Smalltalk). and any type checks that might be performed would be up to each command (Tcl) or object (Smalltalk).