Closed
Description
...but currently it’s the union. Discovered while looking at #31485.
Minimal repro:
type F1 = (this: void) => void;
type F2 = (this: number) => void;
declare var fn: F1 | F2;
fn(); // should error
Silly but understandable real-world-ish example (playground):
interface Car {
odometer: number;
drive(): void;
}
interface Cow {
weight: number;
eatGrass(): void;
isARealCow(): boolean;
}
function carWorks(this: Car): boolean {
this.drive();
return this.odometer > 0;
}
function cowWorks(this: Cow): boolean {
const prevWeight = this.weight;
this.eatGrass();
return this.weight > prevWeight;
}
const cow = {
weight: 100,
eatGrass() { this.weight++ },
// Conditional expression creates a union type here
isARealCow: Math.random() > 0.5 ? carWorks : cowWorks
}
// Runtime error ~50% of the time:
// TypeError: this.drive is not a function
// at Object.carWorks [as isARealCow]
cow.isARealCow();
Since cow.isARealCow
might call this.drive()
or might call this.eatGrass()
, the only thing that should be able to call it is something has a weight
, eatGrass()
, odometer
, and drive()
—that is, the intersection of the constitutents’ this
parameter types. (Perhaps a mechanical cow of some kind would do.)
TypeScript Version: 6a559e3
Search Terms: union signatures this parameter variance intersection
Related Issues: #31485