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

SubClass class property assignment lose BaseClass property type #18531

Closed
jeremychone opened this issue Sep 17, 2017 · 5 comments
Closed

SubClass class property assignment lose BaseClass property type #18531

jeremychone opened this issue Sep 17, 2017 · 5 comments
Labels
Duplicate An existing issue was already created

Comments

@jeremychone
Copy link

jeremychone commented Sep 17, 2017

(I did search for this bug, but could not find it. Sorry if I missed anything).

TypeScript Version: 2.5.2

Code

class ClassA {
  val: number = 2;
}

// Works as expected
class ClassB extends ClassA {
  constructor() {
    super();
    this.val = this.val + 1; // this.val type check works as expected
  }
}

// Error as expected
class ClassC extends ClassA {
  val = "hello"; // <-- Error as expected, can't set string as ClassA.val is number
}

// Wrong ERROR (IMO) Should be equivalent to ClassB
class ClassD extends ClassA {
  val = this.val + 1; // <-- ERROR: 'val' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.
}

Expected behavior:

ClassD should be the equivalent as ClassB.

// this.val should be of type "number" as defined in base class (as recognized in ClassB).
class ClassD extends ClassA {
  val = this.val + 1; // <-- should be the exact equivalent as `ClassB`, this.val should be of the typeof BaseClass.val
}

Actual behavior:

// Wrong ERROR (IMO) Somehow assignment of "this.val" make "val" of type any now (but worked fine in ClassB)
class ClassD extends ClassA {
  val = this.val + 1; // <-- Wrong ERROR: 'val' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.
}

Practical usecase

While simple re-assigning might seems uncommon, base property augmentation can be common, and the direct class property make the class more tierce.

Our basic example is as follow:

// base.ts

export class BaseView {
  events: EventBindings = {};
  config: Config = {};
}

// mono type assign
export function assign<T extends object>(a: T, b: T): T {
  return Object.assign(a, b);
}
// SubView.ts
import {assign, BaseView} from 'base';

export class SubView extends { 

  events = assign(this.events, { // <-- Unfortunately, type error here, "this.events" has become "any"
    "click": () => { /* do something */ }
  }  
  config = assign(this.config, { // <-- Unfortunately, type error here, "this.config" has become "any"
    modal: true
  }  
}

Right now, we put those "augmentations" in constructosr, but would be nicer if we can just have them as direct property assignment.

@mhegazy
Copy link
Contributor

mhegazy commented Sep 18, 2017

Please see #3667

@mhegazy mhegazy added the Duplicate An existing issue was already created label Sep 18, 2017
@jeremychone
Copy link
Author

@mhegazy sorry. Too bad it cannot be fixed.

@mhegazy
Copy link
Contributor

mhegazy commented Sep 18, 2017

I would not give up hope just yet. we have not found a solution that is not a breaking change, but we are still looking into it.

@jeremychone
Copy link
Author

jeremychone commented Sep 18, 2017

@mhegazy Cool, thanks for the hopeful note. (it is a relatively small hindrance anyway)

@mhegazy
Copy link
Contributor

mhegazy commented Oct 2, 2017

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

@mhegazy mhegazy closed this as completed Oct 2, 2017
@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

2 participants