mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-10-19 05:29:46 +08:00
76 lines
1.8 KiB
TypeScript
76 lines
1.8 KiB
TypeScript
// instanceof across a 3-level hierarchy: positives up the chain, negatives
|
|
// across sibling branches, checker-driven narrowing after the test, and
|
|
// initialization ORDER printed (field initializers run right after super()
|
|
// returns, level by level).
|
|
function trace(tag: string, n: number): number {
|
|
console.log("init", tag);
|
|
return n;
|
|
}
|
|
class A {
|
|
a: number = trace("A.a", 1);
|
|
constructor() {
|
|
console.log("ctor A");
|
|
}
|
|
kind(): string {
|
|
return "A";
|
|
}
|
|
}
|
|
class B extends A {
|
|
b: number = trace("B.b", 2);
|
|
constructor() {
|
|
super();
|
|
console.log("ctor B");
|
|
}
|
|
kind(): string {
|
|
return "B";
|
|
}
|
|
}
|
|
class C extends B {
|
|
c: number = trace("C.c", 3);
|
|
constructor() {
|
|
super();
|
|
console.log("ctor C");
|
|
}
|
|
kind(): string {
|
|
return "C";
|
|
}
|
|
}
|
|
class Sibling extends A {
|
|
s: number = trace("Sibling.s", 9);
|
|
}
|
|
|
|
const c = new C();
|
|
const sib = new Sibling();
|
|
console.log(c.a, c.b, c.c, sib.s);
|
|
|
|
const asA: A = c;
|
|
const sibAsA: A = sib;
|
|
console.log(asA instanceof A, asA instanceof B, asA instanceof C);
|
|
console.log(sibAsA instanceof A, sibAsA instanceof B, sibAsA instanceof C);
|
|
console.log(c instanceof A, sib instanceof C);
|
|
|
|
// Narrowed member access: tsc types the guarded branches as the subclass.
|
|
function inspect(x: A): string {
|
|
if (x instanceof C) {
|
|
return `C:${x.c}:${x.kind()}`;
|
|
}
|
|
if (x instanceof B) {
|
|
return `B:${x.b}`;
|
|
}
|
|
return `A:${x.a}`;
|
|
}
|
|
console.log(inspect(c), inspect(sib), inspect(new B()), inspect(new A()));
|
|
|
|
// Negated guard narrows the tail of the function.
|
|
function tail(x: A): number {
|
|
if (!(x instanceof B)) {
|
|
return x.a;
|
|
}
|
|
return x.b * 10;
|
|
}
|
|
console.log(tail(new A()), tail(c));
|
|
|
|
// instanceof yields a plain boolean value, usable anywhere bools are.
|
|
const flag: boolean = asA instanceof B && !(sibAsA instanceof B);
|
|
console.log(flag, asA instanceof C ? "yes" : "no");
|