Limit possible return types using sealed class

Let’s assume we have the following sealed class hierarchy with char processing functions (a kind of state machine, simplified for example purpose):

sealed class State

class None : State() {
  fun startProcessing(c: Char, idx: Int) : State {
    if(c.isLetterOrDigit())
      return Building(idx + 1)
    if(c.isWhitespace())
      return None()

    return Failed(idx)
  }

  fun startProcessingLast(c: Char, idx: Int) : State {
    if(c.isLetterOrDigit())
      return Finished(idx)
    if(c.isWhitespace())
      return None()

    return Failed(idx)
  }
}

class Building(val idx : Int) : State() {
  fun processChar(c: Char) : State {
    if(c.isLetterOrDigit())
      return Building(idx + 1)
    if(c.isWhitespace())
      return Finished(idx - 1)
    
    return Failed(idx)
  }

  fun processLastChar(c: Char) : State {
    if(c.isLetterOrDigit())
      return Finished(idx)
    if(c.isWhitespace())
      return Finished(idx - 1)

    return Failed(idx)
  }
}

class Finished(val idx : Int) : State() {
  fun reset() : None = None()
}

class Failed(val idx : Int) : State() {
  fun reset() : None = None()
}

So far so good. Now I would like to limit possible return types of my char processing functions so that I can reduce possible when() cases in code which uses this class hierarchy and fully utilize the power of sealed classes. For example, processLastChar() returns only Finished() or Failed(), and processChar() never returns None, hence I can do the following (class None remains unchanged):

sealed class Modified(val idx : Int) : State()

class Building(idx : Int) : Modified(idx) {
  fun processChar(c: Char) : Modified {
    if(c.isLetterOrDigit())
      return Building(idx + 1)
    if(c.isWhitespace())
      return Finished(idx - 1)

    return Failed(idx)
  }

  fun processLastChar(c: Char) : FinalModified {
    if(c.isLetterOrDigit())
      return Finished(idx)
    if(c.isWhitespace())
      return Finished(idx - 1)

    return Failed(idx)
  }
}

sealed class FinalModified(idx : Int) : Modified(idx)

class Finished(idx : Int) : FinalModified(idx) {
  fun reset() : None = None()
}

class Failed(idx : Int) : FinalModified(idx) {
  fun reset() : None = None()
}

But I how can I do a similar thing with startProcessingLast() function? I would like to indicate that it never returns Building, but I cannot create a hypothetical “Final” class which is meant to be the common parent for all classes except Building.

It looks like we need a sort of “sealed interfaces” concept, but it’s not possible as I can see: It is possible to have sealed interfaces?

Any other ideas?

Discriminated union type, but it is unsupported.

You could create custom sealed classes for each return type. They can work as a wrapper around the real return value, but that’s a lot of boiler plate code you have to write.