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

Assigning to Partial<this> inside the child class leads to error #24946

Closed
nieltg opened this issue Jun 14, 2018 · 3 comments
Closed

Assigning to Partial<this> inside the child class leads to error #24946

nieltg opened this issue Jun 14, 2018 · 3 comments
Labels
Duplicate An existing issue was already created

Comments

@nieltg
Copy link
Contributor

nieltg commented Jun 14, 2018

TypeScript Version: 3.0.0-dev.20180609

Search Terms: polymorphic this, Partial

Code

class A {
  prop1: number
  method1(attr1: Partial<this>) {
  }
}

class B extends A {
  constructor() {
    super()
    this.method1({prop1: 5})  // <-- Not assignable
  }
}

Expected behavior:
No error should occur here. As there is no error in this code below. (append this to the previous snippet)

let a = new A()
a.method1({prop1: 5})   // <-- No error here
let b = new B()
b.method1({prop1: 5})   // <-- Also no error here

A better opinion is available at the next comment.

Actual behavior:

a.ts:10:18 - error TS2345: Argument of type '{ prop1: 5; }' is not assignable to parameter of type 'Partial<this>'.

Playground Link: Playground · TypeScript

Related Issues:
I'm not sure, but this looks similar to me: #22934

Thank you very much.

@nieltg
Copy link
Contributor Author

nieltg commented Jun 15, 2018

Well, I think this one is tricky. This is what I have learned from polymorphic this. Correct me if I wrong.

Working case

The first use-case of polymorphic this type I encountered on the TypeScript documentation here is used to build fluent interfaces. Here is the simplified snippet.

class A {
  method1(): this {
    return this      // <-- Assignable
  }

  method2(): this {
    return new A()   // <-- Not assignable
  }
}

this is assignable with this but not with A instance because there will be a problem when A becomes a parent class of another class.

class B extends A {
  prop1: number

  // method1(): this {  <-- 'this' type becomes B
  //   return this      <-- 'this' instance is B, B is assignable to B
  // }

  // method2(): this {
  //   return new A()   <-- 'this' instance is B, A isn't assignable to B
  //                        (A doesn't have prop1, but B has)
  // }
}

Partial<this> case

Things become a little different with Partial<this> since it makes every single property of this becomes optional.

class C {
  prop1: number

  method1(): Partial<this> {
    return { prop1: 5 }        // <-- Should be assignable
  }
}

In my opinion, assigning to Partial<this> should be allowed because although the subclass of the base class specifies other properties, all of them will be optional.

class D extends C {
  prop2: number

  // method1(): Partial<this> {   <-- 'this' type becomes C
  //   return { prop1: 5 }        <-- Specified object should be assignable to Partial<C>
  //                                  (as prop2 is now optional)
  // }
}

Thank you very much.

@mhegazy
Copy link
Contributor

mhegazy commented Jun 21, 2018

Duplicate of #13442. this is a generic type that represents the type of the most derived class type only known at instantiation time.

@mhegazy mhegazy added the Duplicate An existing issue was already created label Jun 21, 2018
@nieltg
Copy link
Contributor Author

nieltg commented Jun 23, 2018

@mhegazy
I'm sorry I didn't have any idea to search for generic keyword before. Now, I learn that polymorphic this type is tied to the generic type. Thank you very much for the reference.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Duplicate An existing issue was already created
Projects
None yet
Development

No branches or pull requests

2 participants