You need flow typing when you do pattern matching on generalized abstract data type (GADT).
Here is an example in Java
sealed interface Foo<T> permits Impl {} // union type
record Impl() implements Foo<String> {} // product type
<T> T m(Foo<T> foo) {
return switch(foo) {
case Impl impl -> "hello"; // flow typing T=String
};
}