# Type must be (Int64 | Int8), not Int32

**URL:** <https://forum.crystal-lang.org/t/type-must-be-int64-int8-not-int32/574>\
**Category:** Help & Support\
**Created:** [March 20, 2019, 1:58am UTC](https://forum.crystal-lang.org/t/type-must-be-int64-int8-not-int32/574 "2019-03-20T01:58:52Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![angryrabbit](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/angryrabbit/32/313_2.png) [@angryrabbit](https://forum.crystal-lang.org/u/angryrabbit)\
**Post date:** [March 20, 2019, 1:58am UTC](https://forum.crystal-lang.org/t/type-must-be-int64-int8-not-int32/574/1 "2019-03-20T01:58:52Z")

</div>

Following code:

```
x : Int64 | Int8 = 0

```

Yields error:

```
 type must be (Int64 | Int8), not Int32

```

What’s happening?

---

<div class="post-metadata">

**Author:** ![Blacksmoke16](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/blacksmoke16/32/1241_2.png) [@Blacksmoke16](https://forum.crystal-lang.org/u/Blacksmoke16)\
**Post date:** [March 20, 2019, 2:03am UTC](https://forum.crystal-lang.org/t/type-must-be-int64-int8-not-int32/574/2 "2019-03-20T02:03:31Z")

</div>

You are giving `x` a type restriction of `Int64 | Int8`, but are assigning a value that is of type `Int32`.

---

<div class="post-metadata">

**Author:** ![angryrabbit](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/angryrabbit/32/313_2.png) [@angryrabbit](https://forum.crystal-lang.org/u/angryrabbit)\
**Post date:** [March 20, 2019, 2:05am UTC](https://forum.crystal-lang.org/t/type-must-be-int64-int8-not-int32/574/3 "2019-03-20T02:05:44Z")

</div>

Crystal docs say -128…127 are valid Int8.

[https://crystal-lang.org/reference/syntax\_and\_semantics/literals/integers.html](https://crystal-lang.org/reference/syntax_and_semantics/literals/integers.html)

Now what?

---

<div class="post-metadata">

**Author:** ![Blacksmoke16](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/blacksmoke16/32/1241_2.png) [@Blacksmoke16](https://forum.crystal-lang.org/u/Blacksmoke16)\
**Post date:** [March 20, 2019, 2:08am UTC](https://forum.crystal-lang.org/t/type-must-be-int64-int8-not-int32/574/4 "2019-03-20T02:08:08Z")

</div>

Yes but in this context `0` has a type of `Int32` by default. You would have to tell the compiler that you want `0` to be of type `Int8`, i.e. `0_i8`.

`If no suffix is present, the literal's type is the lowest between Int32, Int64 and UInt64 in which the number fits`. Notice the little example they have in the doc you linked.

---

<div class="post-metadata">

**Author:** ![angryrabbit](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/angryrabbit/32/313_2.png) [@angryrabbit](https://forum.crystal-lang.org/u/angryrabbit)\
**Post date:** [March 20, 2019, 2:10am UTC](https://forum.crystal-lang.org/t/type-must-be-int64-int8-not-int32/574/5 "2019-03-20T02:10:12Z")

</div>

Okay yes I remember reading that now.

By my previous statement, reading doesn’t imply learning, in my case. So I must actually TYPE Crystal in order to learn, which I am enjoying btw. 🙂

Thank-you for responding quickly.

---

<div class="post-metadata">

**Author:** ![angryrabbit](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/angryrabbit/32/313_2.png) [@angryrabbit](https://forum.crystal-lang.org/u/angryrabbit)\
**Post date:** [March 20, 2019, 2:10am UTC](https://forum.crystal-lang.org/t/type-must-be-int64-int8-not-int32/574/6 "2019-03-20T02:10:50Z")

</div>

I really, really like having types. I learned to love types via SQL. And now I get it in “Ruby”.

---

<div class="post-metadata">

**Author:** ![Blacksmoke16](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/blacksmoke16/32/1241_2.png) [@Blacksmoke16](https://forum.crystal-lang.org/u/Blacksmoke16)\
**Post date:** [March 20, 2019, 2:12am UTC](https://forum.crystal-lang.org/t/type-must-be-int64-int8-not-int32/574/7 "2019-03-20T02:12:17Z")

</div>

No problem. Yes the type system is quite handy :)

---

<div class="post-metadata">

**Author:** ![angryrabbit](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/angryrabbit/32/313_2.png) [@angryrabbit](https://forum.crystal-lang.org/u/angryrabbit)\
**Post date:** [March 20, 2019, 2:12am UTC](https://forum.crystal-lang.org/t/type-must-be-int64-int8-not-int32/574/8 "2019-03-20T02:12:27Z")

</div>

Is there a way to see the set of types for a variable? `typeof` only shows me what the type of the variable’s current value is.

…

Maybe my question is not so good. First, I see there are functions for objects like `tuple` that give the set of types. If I always declare my types, which I plan to, I should be able to find the variable’s declaration and know from that.

---

<div class="post-metadata">

**Author:** ![Blacksmoke16](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/blacksmoke16/32/1241_2.png) [@Blacksmoke16](https://forum.crystal-lang.org/u/Blacksmoke16)\
**Post date:** [March 20, 2019, 2:16am UTC](https://forum.crystal-lang.org/t/type-must-be-int64-int8-not-int32/574/9 "2019-03-20T02:16:19Z")

</div>

`typeof` is kinda smart in that it shows you the types a variable have a chance of being. In your case `x` is only ever assigned to `0_i8` so the type of `x` is always going to be `Int8`. However if you do like:

```crystal
val = "Foo"

if val == "bar"
  val = 123
end

typeof(val) # => (String | Int32)

```

In this case val is initialized as a string, but is _possible_ it could be an `Int32` as well. `typeof(val)` reflects that.

`Tuple` is a bit unique as the types of each element are known at compile time.

---

<div class="post-metadata">

**Author:** ![angryrabbit](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/angryrabbit/32/313_2.png) [@angryrabbit](https://forum.crystal-lang.org/u/angryrabbit)\
**Post date:** [March 20, 2019, 2:19am UTC](https://forum.crystal-lang.org/t/type-must-be-int64-int8-not-int32/574/10 "2019-03-20T02:19:35Z")

</div>

Very cool example. I hope to never do such things in my own code. Specifically, have union-type of 2 disparate types, e.g. String, Integer. Obviously Int8, Int32 is less disparate.

My training in relational-theory taught me to avoid NULL at almost any cost. I intend to carry that into Crystal. Time shall tell.

---

<div class="post-metadata">

**Author:** ![bcardiff](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/bcardiff/32/3_2.png) [@bcardiff](https://forum.crystal-lang.org/u/bcardiff)\
**Post date:** [March 20, 2019, 3:34am UTC](https://forum.crystal-lang.org/t/type-must-be-int64-int8-not-int32/574/11 "2019-03-20T03:34:40Z")

</div>

Note that `x : Int64 = 0` or `x : Int8 = 0` works thanks to auto-casting, but `x : Int64 | Int8 = 0` does not.

---

<div class="post-metadata">

**Author:** ![angryrabbit](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/angryrabbit/32/313_2.png) [@angryrabbit](https://forum.crystal-lang.org/u/angryrabbit)\
**Post date:** [March 20, 2019, 3:40am UTC](https://forum.crystal-lang.org/t/type-must-be-int64-int8-not-int32/574/12 "2019-03-20T03:40:47Z")

</div>

What do you mean by “works”? `x : Int64 = 0` does-not look “auto-casted” to me; it looks explicit.

---

<div class="post-metadata">

**Author:** ![angryrabbit](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/angryrabbit/32/313_2.png) [@angryrabbit](https://forum.crystal-lang.org/u/angryrabbit)\
**Post date:** [March 20, 2019, 3:43am UTC](https://forum.crystal-lang.org/t/type-must-be-int64-int8-not-int32/574/13 "2019-03-20T03:43:24Z")

</div>

I think I get what you’re saying.

Absent a union-type, Crystal will assign the right type based on the singular type given.

Oh… okay. Auto-casting of the LITERAL value, 0. Gotcha. Cool. Yes, lots to learn, lots of nuance.

---

<div class="post-metadata">

**Author:** ![bcardiff](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/bcardiff/32/3_2.png) [@bcardiff](https://forum.crystal-lang.org/u/bcardiff)\
**Post date:** [March 20, 2019, 3:44am UTC](https://forum.crystal-lang.org/t/type-must-be-int64-int8-not-int32/574/14 "2019-03-20T03:44:07Z")

</div>

> [@angryrabbit](#):
>
> What do you mean by “works”?

That it compiles and does what you would expect 🙂

`0` as an expression is of type Int32. But the compiler will notice on some cases that literals are used as values of other types and will interpret them different. More about it [here](https://crystal-lang.org/2018/06/15/crystal-0.25.0-released.html#automatic-casts-for-literal-values).
