# Strange things with Class

**URL:** <https://forum.crystal-lang.org/t/strange-things-with-class/1066>\
**Category:** Help & Support\
**Created:** [August 26, 2019, 6:24am UTC](https://forum.crystal-lang.org/t/strange-things-with-class/1066 "2019-08-26T06:24:00Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![pfischer](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/pfischer/32/330_2.png) [@pfischer](https://forum.crystal-lang.org/u/pfischer)\
**Post date:** [August 26, 2019, 6:24am UTC](https://forum.crystal-lang.org/t/strange-things-with-class/1066/1 "2019-08-26T06:24:00Z")

</div>

Hello, I need a variable of type `Class` and I found the following behaviors:

I can do this:

```crystal
puts typeof(Bool | Int32 | Int64 | String)
# => (Bool | Int32 | Int64 | String).class

```

but not this (why?):

```crystal
c : typeof(Bool | Int32 | Int64 | String) = Bool
# => Error: type must be (Bool | Int32 | Int64 | String).class, not Bool.class

```

also I can do this:

```crystal
c : Bool.class | Int32.class | Int64.class | String.class = Bool
puts typeof(c) # => Class (!!!)
puts c # => Bool

```

Look at this! `typeof(c)` is **Class** (so, union of several Classes is aggregated to the **Class** and it works)!

but I can’t do this:

```crystal
c : Class = Bool
puts c
# => Error: can't use Object as the type of a variable yet, use a more specific type

```

Can’t use `Class` as type directly - but look at example above, when union is aggregated to the `Class`

Is this OK?

---

<div class="post-metadata">

**Author:** ![vladfaust](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/vladfaust/32/48_2.png) [@vladfaust](https://forum.crystal-lang.org/u/vladfaust)\
**Post date:** [August 26, 2019, 8:09am UTC](https://forum.crystal-lang.org/t/strange-things-with-class/1066/2 "2019-08-26T08:09:23Z")

</div>

I’m really wondering what’s your use case 🤔

---

<div class="post-metadata">

**Author:** ![pfischer](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/pfischer/32/330_2.png) [@pfischer](https://forum.crystal-lang.org/u/pfischer)\
**Post date:** [August 26, 2019, 8:21am UTC](https://forum.crystal-lang.org/t/strange-things-with-class/1066/3 "2019-08-26T08:21:44Z")

</div>

We have dozens of “Entity” classes and we need to store some internal metadata about relations etc., so we need an attribute (instance variable) with type “Class” to point to our relation class.

It’s not about use case - it’s just an instance variable (or simple variable) that stores Class - simple.  
And that work with Classes is a little strange as you can see.

---

<div class="post-metadata">

**Author:** ![asterite](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/asterite/32/60_2.png) [@asterite](https://forum.crystal-lang.org/u/asterite)\
**Post date:** [August 26, 2019, 12:01pm UTC](https://forum.crystal-lang.org/t/strange-things-with-class/1066/4 "2019-08-26T12:01:56Z")

</div>

The type of a union of classes is different than the union of classes.

So in:

```crystal
c : typeof(Bool | Int32 | Int64 | String)

```

the only thing you can assign is `Bool | Int32 | Int64 | String`, while in:

```crystal
c : Bool.class | Int32.class | Int64.class | String.class

```

you can assign any of `Bool`, `Int32`, etc.

I think in the past both types were equal or resolved to a same time and I think we changed that because it was unsound (I can’t remember why).

Then you get `Class` for asking the type of a class (like `Bool.class`). There’s a PR to change that so that `typeof(Bool.class)` gives you `Bool:Class:Class` but we are not sure it’s the right thing to do: [https://github.com/crystal-lang/crystal/pull/7255](https://github.com/crystal-lang/crystal/pull/7255)

In your case you probably need to use the `Bool.class | Int32.class` approach, but maybe showing some more code for what you want/need might be better.
