Skip to content

this parameter of union signatures should be the intersection of constituents’ this parameters #31547

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
andrewbranch opened this issue May 23, 2019 · 1 comment · Fixed by #32538
Assignees
Labels
Bug A bug in TypeScript Fix Available A PR has been opened for this issue

Comments

@andrewbranch
Copy link
Member

andrewbranch commented May 23, 2019

...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

Playground Link

Related Issues: #31485

@andrewbranch andrewbranch added the Bug A bug in TypeScript label May 23, 2019
@fatcerberus
Copy link

Perhaps a mechanical cow of some kind would do.

😄
🤖🐄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug A bug in TypeScript Fix Available A PR has been opened for this issue
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants