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

Allow declaring properties inside class constructors #12613

Open
mmkal opened this issue Dec 2, 2016 · 4 comments
Open

Allow declaring properties inside class constructors #12613

mmkal opened this issue Dec 2, 2016 · 4 comments
Labels
Awaiting More Feedback This means we'd like to hear from more people who would be helped by this feature Suggestion An idea for TypeScript

Comments

@mmkal
Copy link

mmkal commented Dec 2, 2016

It's a little clunky setting up properties in classes right now.

Here's what I have to do at the moment to set a property value in the constructor:

class Animal {
    public interruptedSound: string;
    constructor(public sound: string) {
        this.interruptedSound = sound.substring(0, 3);
    }
}
let dog = new Animal("woof");
console.log(dog.sound); // woof
console.log(dog.interruptedSound); // woo

Notice that interruptedSound's setup is split over two lines, and I have to declare it as a string even though it could be inferred from the fact that sound.substring returns a string.
What I'd like to be able to do:

class Animal {
    constructor(public sound: string) {
        this.interruptedSound = sound.substring(0, 3); // now a detectable property of type string
    }
}
let dog = new Animal("woof");
console.log(dog.sound); // woof
console.log(dog.interruptedSound); // woo

This would avoid having to declare all properties at the top before being able to use them in constructors, saving a lot of boilerplate on complex classes. F# already does something similar to make setting up types much quicker and simpler. There wouldn't be any JavaScript compatibility issues, because JavaScript already works this way.

In cases where the property is declared separately, give precedence to the declaration.

The private, public or readonly keywords could even be used before the assignment to modify the property, e.g.

class Animal {
    constructor(public sound: string) {
        private readonly this.interruptedSound = sound.substring(0, 3);
    }
    changeSounds() {
        this.sound = "meow";
        this.interruptedSound = "meo"; // error, interruptedSound is readonly
    }
}
let dog = new Animal("woof");
console.log(dog.sound); // woof
console.log(dog.interruptedSound); // error, interruptedSound is private
@mmkal
Copy link
Author

mmkal commented Mar 7, 2017

@RyanCavanaugh any thoughts on this?

@RyanCavanaugh RyanCavanaugh added Awaiting More Feedback This means we'd like to hear from more people who would be helped by this feature Suggestion An idea for TypeScript labels Mar 7, 2017
@RyanCavanaugh
Copy link
Member

You can already do something like this (slightly unsafe if the constructor is aliased by a constructor with more arguments, but this is rare):

class Foo {
  constructor(x: string);
  constructor(public x: string,
    public y = x.toUpperCase(),
    private z = 3) {

  }
}

@mmkal
Copy link
Author

mmkal commented Mar 8, 2017

Ah, I didn't know I could access other parameters when assigning a value to constructor parameters like that. It'd still be nice to have the feature, but this is good enough for me, so I'll close the issue. Feel free to re-open if someone else thinks this would be worth introducing.

@mmkal mmkal closed this as completed Mar 8, 2017
@mmkal
Copy link
Author

mmkal commented Mar 20, 2017

Actually, I want to re-open this one. With es6 classes, this feature would make it much, much less painful to upgrade from JavaScript to TypeScript. There are many perfectly valid, well written javascript classes that do something like

class Foo {
  constructor() {
    this.port = process.env.PORT || 12345;
  }
}

And on converting to TypeScript these will all give errors that could be avoided if this was added to the language.

I just tried upgrading a medium-sized JavaScript project to TypeScript, and just over half of all errors are of this type.
That was on 207 javascript files, with around 100 lines of code each. There were 272 errors, 146 of which would go away with this feature.

@RyanCavanaugh while your workaround will work ok for existing TypeScript projects, it's not very idiomatic, so it doesn't help those moving from JavaScript (plus it's confusing). Do you know how realistic it is to hope to get this feature into a future typescript release?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Awaiting More Feedback This means we'd like to hear from more people who would be helped by this feature Suggestion An idea for TypeScript
Projects
None yet
Development

No branches or pull requests

2 participants