Skip to content
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

Partial<this> not working as expected #16356

Closed
felixfbecker opened this issue Jun 8, 2017 · 11 comments
Closed

Partial<this> not working as expected #16356

felixfbecker opened this issue Jun 8, 2017 · 11 comments
Labels
Duplicate An existing issue was already created

Comments

@felixfbecker
Copy link
Contributor

felixfbecker commented Jun 8, 2017

I refactored the typings of sequelize to use Partial<this> to type .update(), but it is not working as expected.

TypeScript Version: 2.3.4

Code

http://www.typescriptlang.org/play/index.html#src=%0D%0Aclass%20User%20%7B%0D%0A%20%20%20%20activated%3A%20boolean%3B%0D%0A%20%20%20%20async%20activate()%3A%20Promise%3Cvoid%3E%20%7B%0D%0A%20%20%20%20%20%20%20%20await%20this.update(%7B%20activated%3A%20true%20%7D)%3B%0D%0A%20%20%20%20%7D%0D%0A%20%20%20%20async%20update(keys%3A%20Partial%3Cthis%3E)%3A%20Promise%3Cvoid%3E%20%7B%0D%0A%20%20%20%20%20%20%20%20%2F%2F%20Do%20SQL%20UPDATE%20query%0D%0A%20%20%20%20%7D%0D%0A%7D%0D%0A

// A *self-contained* demonstration of the problem follows...

class User {
    activated: boolean;
    async activate(): Promise<void> {
        await this.update({ activated: true });
    }
    async update(keys: Partial<this>): Promise<void> {
        // Do SQL UPDATE query
    }
}

Expected behavior:
Should compile, as { activated: true } should satisfy Partial<User> and in turn Partial<this>

Actual behavior:

Argument of type '{ activated: true; }' is not assignable to parameter of type 'Partial<this>'.
@mhegazy mhegazy added the Needs Investigation This issue needs a team member to investigate its status. label Aug 29, 2017
@drew-r
Copy link

drew-r commented Sep 12, 2017

I'm suffering with this as well.

class Foo {
  constructor() {}
  x: number;
  bar() {
    // compile error - Type '{ x: number; }' is not assignable to type 'Partial<this>'.
    const y: Partial<this> = { x: 10 };
  }
}

@mhegazy
Copy link
Contributor

mhegazy commented Oct 31, 2017

Duplicate of #19388.

this is a generic type. it represents the type of the derived class at instantiation time. The compiler can not guarantee that type of a property on this has not been overridden by a derived class.

Seems that what you want here is Partial<Base> and not Partial<this>

@mhegazy mhegazy added Duplicate An existing issue was already created and removed Needs Investigation This issue needs a team member to investigate its status. labels Oct 31, 2017
@typescript-bot
Copy link
Collaborator

Automatically closing this issue for housekeeping purposes. The issue labels indicate that it is unactionable at the moment or has already been addressed.

@felixfbecker
Copy link
Contributor Author

@mhegazy if I used Partial<Base>, how would this work?

class Model {
  update(values: Partial<Model>): void {}
}

class User {
  firstName: string
}

const user = new User()
user.update({ firstName: 'Felix' }) // Property firstName does not exist on type Model

@mhegazy
Copy link
Contributor

mhegazy commented Nov 16, 2017

in this case you need Partial<this>, but setting a default in the function body is unsafe.

@felixfbecker
Copy link
Contributor Author

Sorry, what do you mean with setting a default in the function body is unsafe?

@mhegazy
Copy link
Contributor

mhegazy commented Nov 16, 2017

    async activate(): Promise<void> {
        await this.update({ activated: true });  // u do not know what type `activated` will be an a more derived type
    }

@felixfbecker
Copy link
Contributor Author

Maybe I am misunderstanding you, but any subclass should follow Liskov's substitution principle, so if the superclass declared activated: boolean, the subclass shouldn't change that type?

@mhegazy
Copy link
Contributor

mhegazy commented Nov 16, 2017

they are substituable for read, but not write.. the sub class are guaranteed to have a type boolean, but they can have a more specialized type, e.g. true. Please see #19388 for explanation.

@felixfbecker
Copy link
Contributor Author

Hmm, is there any language feature that would solve this use case?

@mhegazy
Copy link
Contributor

mhegazy commented Nov 17, 2017

readonly/strict variance, see #18770 for more links

@microsoft microsoft locked and limited conversation to collaborators Jun 14, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Duplicate An existing issue was already created
Projects
None yet
Development

No branches or pull requests

4 participants