microsoft / TypeScript

TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
https://www.typescriptlang.org
Apache License 2.0
100.26k stars 12.38k forks source link

Not possible to have optional object property compatible with both Closure Compiler and Intellisense #30522

Open visj opened 5 years ago

visj commented 5 years ago

Steps to Reproduce:

  1. Enable "checkJs": true in jsconfig.json.
  2. Create a Javascript file:

    
    class A {
    
    /**
    * @param {{field: string|undefined}} obj 
    */
    constructor(obj) {
    this.obj = obj;
    }
    }

let a = new A({});

Results in this error:
![image](https://user-images.githubusercontent.com/8695157/54741956-47af8500-4bc0-11e9-9873-ef9751b1965f.png)

Adding error text here for duplicate detection:
Argument of type '{}' is not assignable to parameter of type '{ field: string; }'.
 Property 'field' is missing in type '{}' but required in type '{ field: string; }' .ts(2345)

<!-- Launch with `code --disable-extensions` to check. -->
Does this issue occur when all extensions are disabled?: Yes

Expected behaviour: 
Some way to mark object properties as optional compatible both with Closure Compiler and VsCode intellisense. Either through @typedef, through structural interfaces with @record, direct @param notation using string|undefined, or something similar. 

This notation works fine today, but it is not recognized by Closure Compiler. It is debatable whether this is an issue with Intellisense or lacking support from Closure Compiler.

```js
class A {

  /**
   * @param {AParam} obj 
   */
  constructor(obj) {
    this.obj = obj;
  }
}

/** @typedef {{field?: string|undefined}} */
var AParam;
let a = new A({});
data-enabler commented 1 year ago

Our team is also trying to use Closure Compiler JavaScript with TypeScript Language server, and this has been one of the biggest thorns in our side.

Using the JSDoc @property annotation would allow us to properly annotate the property's optional-ness, but Closure refuses to support support the annotation. I think it's even less likely that they'd support the TypeScript property?: syntax, since it would mean supporting things like {?property1: ?string, ?property2: string?}.

Realistically, I think the only thing that could be done from the TypeScript side is to add a compiler option that tells TS to not differentiate between optional properties and required properties that allow undefined as a value (which is how Closure Compiler works), i.e. consider {property?: string} and {property: string|undefined} equivalent.