Q:

How to get the value of a string in a case statement in elm

Consider the following. Why does it not work. And how could I make it work?
type IntOrString
  = String
  | Int

getInt : IntOrString -> String
getInt intOrString =
  case intOrString of
    String ->
      intOrString

    Int ->
      toString intOrString

A:

Your declaration of the IntOrString type seems to indicate that you want a type that can hold either an integer or a string. However, that's not what you have created. I recommend reading the section on Union Types in the Elm Guide.
When you declare a union type, you have to create constructors. In your example, you're actually creating a type with two constructors, neither of which contain a parameter, so although you call them Int and String, they bear no relationship to Elm's native Int and String types. In this case, they can be considered roughly equivalent to an enum inside a language like C# or Java. 
Furthermore, your declaration causes compiler confusion because you have created constructor names that clash with existing types, so elsewhere in your code the compiler gets confused by which thing you mean when you say Int or String.
Let's redefine the type so that it becomes a single type that can hold an integer or string value. I'll also rename the constructors to avoid name collisions.
type IntOrString
  = MyString String
  | MyInt Int

And now you can tweak the getInt function based on the new definition. Notice how pattern matching is used to pull the string or integer value out of the IntOrString value based on which constructor was used to create it:
getInt : IntOrString -> String
getInt intOrString =
  case intOrString of
    MyString s ->
      s

    MyInt i ->
      toString i

