> ## Content Index
> Fetch the complete content index at: https://nolongerset.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# TypeName vs. TypeOf
- URL: https://nolongerset.com/typeof-vs-typename/
- Published: 2021-05-12T21:26:14.000Z
- Updated: 2026-05-08T13:04:44.000Z
- Description: You can check the type of a variable in VBA using TypeName or TypeOf. But do you know when to use which? And why? Let's explore.
- Author: Mike Wolfe
- Tags: Advanced, #Import 2026-05-20 02:59

There are two primary ways to query the types of your variables in VBA: the TypeName function and the TypeOf...Is expression. Let's explore both options.

## TypeName Function

The [TypeName function](https://docs.microsoft.com/en-us/office/vba/language/reference/user-interface-help/typename-function) returns a string that represents the variable's type. 

For example:

```vba
' --== Immediate Window ==--
?TypeName(42)
Integer

?TypeName(42.0)
Double

?TypeName("42")
String

?TypeName(CreateObject("Scripting.Dictionary"))
Dictionary
```

## TypeOf...Is Expression

The [TypeOf...Is expression](https://docs.microsoft.com/en-us/openspecs/microsoft%5Fgeneral%5Fpurpose%5Fprogramming%5Flanguages/ms-vbal/22d0220a-65bc-412a-9052-adb02aadb875) checks to see if the type of the variable is *compatible with* the given type.

For example, let's say I add a text box named *Text0* to a new form. I then add the following code to the form's Load event:

```vba
Private Sub Form_Load()
    Debug.Print "Text0's type name: "; TypeName(Me.Text0)
    Debug.Print "Type name of Text0's value: "; TypeName(Me.Text0.Value)
    Debug.Print
    Debug.Print "Is a type of textbox? "; TypeOf Me.Text0 Is Access.TextBox
    Debug.Print "Is a type of control? "; TypeOf Me.Text0 Is Access.Control
    Debug.Print "Is a type of object?  "; TypeOf Me.Text0 Is Object
    Debug.Print "Is a type of form?    "; TypeOf Me.Text0 Is Access.Form
End Sub
```

Here's the output from the above code:

```vba
'--== Immediate Window (output of Form_Load Sub) ==--
Text0's type name: TextBox
Type name of Text0's value: Null

Is a type of textbox? True
Is a type of control? True
Is a type of object?  True
Is a type of form?    False
```

### When would you use TypeName?

There are four times that I prefer (or have) to use TypeName:

- Value types
- Debugging
- Error logging
- Late-binding

#### Value types

The TypeOf...Is expression can only be used with object types in VBA. For example, TypeName works fine here:

```vba
Foo = 42: ?TypeName(Foo)
Integer
```

But if we try to do the same sort of thing with TypeOf, we get a compiler error:

![](https://storage.ghost.io/c/eb/d7/ebd732c1-5f03-4f07-b386-5d08557e15c9/content/images/2021/05/image-37.png)

TypeOf only works with object types.

#### Debugging

I often use TypeName when I'm debugging because I don't have to know what type it *could* be; I just have to know the name of the variable.

#### Error logging

This benefit also lends itself well to error logging, especially if you have access to the call stack because you're using [vbWatchdog](nolongerset.com/error-handling-evolution/).

#### Late-bound types

Finally, if the object contains a late-bound type, then TypeOf won't work. 

What do I mean by a late-bound type? For example, the Dictionary class is part of the Microsoft Scripting Runtime. That reference is not included by default in Access applications. 

The following code will always work:

```vba
?TypeName(CreateObject("Scripting.Dictionary"))
Dictionary
```

The code below, though, will fail if Microsoft Scripting Runtime is not included as a reference:

![](https://storage.ghost.io/c/eb/d7/ebd732c1-5f03-4f07-b386-5d08557e15c9/content/images/2021/05/image-38.png)

Microsoft Scripting Runtime is *NOT CHECKED* as an included reference.

To clarify, the problem in the above screenshot is not the call to CreateObject("Scripting.Dictionary"). Rather, the problem is that the **Dictionary** type is defined in the Microsoft Scripting Runtime, which is not included as a reference.

If I include Microsoft Scripting Runtime as a reference, then the code works fine:

```vba
?TypeOf CreateObject("Scripting.Dictionary") Is Dictionary
True
```

Microsoft Scripting Runtime must *BE CHECKED* for this code to compile and run.

### When would you use TypeOf?

Generally speaking, if my situation doesn't fall into one of the four categories above, I use the TypeOf...Is expression. It offers several advantages over TypeName:

- Compile-time checks
- Interface support
- Multiple matches
- Greater specificity

#### Compile-time checks

Since TypeOf uses the type name itself, most typos in your code will be caught at compile time. On the other hand, with TypeName, you would be comparing the variable type to a string. A typo in your string won't be caught until run time...and maybe not even then, depending on how you're doing the comparison.

#### Interface support

Let's say you have a class that implements an interface. If you use TypeName on an instance of the class, it will only ever return the name of the class. However, you can use the TypeOf expression to see if that class implements a certain interface. 

I demonstrate this technique in my [Graduate Level Error Handling](https://nolongerset.com/graduate-level-error-handling/) article, where I write about recreating Python's `.__repr__` method to fetch identifying information from specific instances of classes to aid in troubleshooting bugs.

#### Multiple matches

The TypeOf...Is expression will return true for *every* compatible object type of a given variable. The TypeName function, on the other hand, can only ever return a single string representation of the variable's type.

For example, all three lines below will return true if Me.Text0 is a textbox control:

```vba
Debug.Print "Is a type of textbox? "; TypeOf Me.Text0 Is Access.TextBox
Debug.Print "Is a type of control? "; TypeOf Me.Text0 Is Access.Control
Debug.Print "Is a type of object?  "; TypeOf Me.Text0 Is Object
```

However, TypeName only tells us that the object is a "TextBox":

```vba
?TypeName(Me.Text0)
TextBox
```

#### Greater specificity

What if you have multiple references in your project that provide overlapping class names. Like, oh, I don't know, the DAO and ADO classes' *Recordset* type?

```vba
Private Sub Form_Load()
    Debug.Print TypeName(Me.Recordset)
    Debug.Print TypeOf Me.Recordset Is DAO.Recordset
    Debug.Print TypeOf Me.Recordset Is ADODB.Recordset
End Sub

'--== Output in immediate window: ==--
Recordset2
True
False
```

Try doing *that* with TypeName!

### Rule of Thumb

Generally speaking, if you can do it with a TypeOf...Is expression, you should. 

But TypeName still has great value of its own.

*Image by [Ronny Overhate](https://pixabay.com/users/roverhate-1759589/?utm%5Fsource=link-attribution&utm%5Fmedium=referral&utm%5Fcampaign=image&utm%5Fcontent=1127666) from [Pixabay](https://pixabay.com/?utm%5Fsource=link-attribution&utm%5Fmedium=referral&utm%5Fcampaign=image&utm%5Fcontent=1127666)*