Skip to content

Instantly share code, notes, and snippets.

@BruJu
Last active April 21, 2022 16:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save BruJu/8d7f918916092c9017ba43513458666f to your computer and use it in GitHub Desktop.
Save BruJu/8d7f918916092c9017ba43513458666f to your computer and use it in GitHub Desktop.
TypeScript strange downcast rules
// ==== Basic Elements
class Elem {
public String id;
}
class NamedElem extends Elem {
public String name;
}
interface Printer<E extends Elem> {
public void print(E e);
}
class PrintNamed implements Printer<NamedElem> {
public void print(NamedElem e) {
System.out.println(e);
}
}
public class Main {
public static void main(String[] args) {
Elem ebase = new Elem();
NamedElem namedelem = new NamedElem();
PrintNamed named = new PrintNamed();
named.print(namedelem);
Printer<NamedElem> n2 = named;
n2.print(namedelem);
// Unlike TS, Java says
// error: incompatible types: Printer<NamedElem> cannot be converted to Printer<Elem>
Printer<Elem> n3 = n2;
n3.print(namedelem);
}
}
// ==== Basic Elements
type Elem = { id: string };
type NamedElem = Elem & { name: string };
// Any NamedElem is an Elem
// ==== Printers
interface Printer<E extends Elem = Elem> {
print(e: E): void;
}
class PrintBase implements Printer<Elem> {
print(e: Elem): void {
console.log(e);
}
}
class PrintNamed implements Printer<NamedElem> {
print(e: NamedElem) {
console.log(e);
}
}
// ==== Go
const base = new PrintBase();
base.print({ id: "Basic elem" });
const named = new PrintNamed();
named.print({ id: "Named element", name: "COUCOU" });
// named.print({ id: "Not named but error" }); // error
const notSoNamed: Printer<Elem> = named;
notSoNamed.print({ id: "same printer but now accepts without name" });
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment