Typescript: Class property inference from constructor does not work with private class fields

Created on 8 Aug 2020  路  6Comments  路  Source: microsoft/TypeScript

TypeScript Version: 4.0.0-dev.20200803


Search Terms: class property inference, private class fields

Expected behavior: private class field's type is inferred from its assignment in the constructor

Actual behavior: typechecker reports implicit any for private class field


Related Issues:

Code

class Example {
  #test;

  constructor(test: number) {
    this.#test = test;
  }

  get test() {
    return this.#test
  }
}

Output

"use strict";
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, privateMap, value) {
    if (!privateMap.has(receiver)) {
        throw new TypeError("attempted to set private field on non-instance");
    }
    privateMap.set(receiver, value);
    return value;
};
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, privateMap) {
    if (!privateMap.has(receiver)) {
        throw new TypeError("attempted to get private field on non-instance");
    }
    return privateMap.get(receiver);
};
var _test;
class Example {
    constructor(test) {
        _test.set(this, void 0);
        __classPrivateFieldSet(this, _test, test);
    }
    get test() {
        return __classPrivateFieldGet(this, _test);
    }
}
_test = new WeakMap();

Compiler Options

{
  "compilerOptions": {
    "noImplicitAny": true,
    "strictNullChecks": true,
    "strictFunctionTypes": true,
    "strictPropertyInitialization": true,
    "strictBindCallApply": true,
    "noImplicitThis": true,
    "noImplicitReturns": true,
    "alwaysStrict": true,
    "esModuleInterop": true,
    "declaration": true,
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "moduleResolution": 2,
    "target": "ES2017",
    "jsx": "React",
    "module": "ESNext"
  }
}

Playground Link: Provided

Bug Fix Available

Most helpful comment

@ahejlsberg think this would be trivial to fix before the 4.0 stable?

All 6 comments

I'm not sure if TS can support this, the syntax sugar for adding the type in the constructor generates a public field but the #syntax isn't allowed in the constructors params

Screen Shot 2020-08-10 at 8 28 13 AM

and

Screen Shot 2020-08-10 at 8 29 20 AM

If we added support for this we might end up taking syntax space from JavaScript

@orta That's not what I was referring to. I was referring to this recently released behavior which currently behaves correctly for non-private fields.
https://devblogs.microsoft.com/typescript/announcing-typescript-4-0-rc/#class-property-inference

The playground that is linked demonstrates the bug without need for modification.

Yep, I know what you're talking about 馃憤馃徎

My point was that that syntax space is already taken for the implicit field which is created how it currently works. We'd have to add support for putting #fieldname in a constructor in order to disambiguate,

I'm afraid I don't really understand what you mean. The playground I linked doesn't use any TypeScript-specific syntactic sugar. Are you referring to parameter properties?
https://www.typescriptlang.org/docs/handbook/classes.html#parameter-properties

// no implicit field created
constructor(test: number) { }

// implicit field created
constructor(public test: number) { }

Except for the one type annotation, the playground I linked is valid vanilla JS so I don't really understand what that has to do with what is or isn't valid in the constructor's params.

Here's another demonstration that's maybe more clear.


class Example {
  #test;  // should not be implicit any error

  constructor() {
    this.#test = 42;
  }
}

This works with no errors in noImplicitAny

class Example {
  test;

  constructor(test: number) {
    this.test = test;
  }

  get publicTest() {
    return this.test
  }
}

But the original example code doesn't. That should be fixed.

@ahejlsberg think this would be trivial to fix before the 4.0 stable?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

weswigham picture weswigham  路  3Comments

manekinekko picture manekinekko  路  3Comments

jbondc picture jbondc  路  3Comments

wmaurer picture wmaurer  路  3Comments

kyasbal-1994 picture kyasbal-1994  路  3Comments