Skip to content

Use generic defaults for "empty" constructors of Array, Map, Set #29786

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Closed
aleclarson opened this issue Feb 6, 2019 · 3 comments
Closed

Use generic defaults for "empty" constructors of Array, Map, Set #29786

aleclarson opened this issue Feb 6, 2019 · 3 comments
Labels
In Discussion Not yet reached consensus Suggestion An idea for TypeScript

Comments

@aleclarson
Copy link

TypeScript Version: 3.4.0-dev.20190202

Search Terms:

  • assignment expression
  • RHS infer

Code

class Test {
    foo?: Map<object, string>

    getFoo(obj: object) {
        // "foo" is inferred as "Map<any, any>" instead of "Map<object, string>"
        const foo = this.foo || (this.foo = new Map())
        foo.set(obj, 1) // No error!
    }
}

Expected behavior: Infer foo to be Map<object, string>

Actual behavior: Infers foo to be Map<any, any>

Playground Link: Click here

Related Issues: Maybe #7782

@DanielRosenwasser
Copy link
Member

This is working as intended. JS always returns the RHS, which you can observe by making this.foo a getter that returns something unrelated.

The real problem is that new Map() creates an instantiation with any. I think we could remove that overload and give it default type arguments.

 interface MapConstructor {
-    new(): Map<any, any>;
-    new<K, V>(entries?: ReadonlyArray<[K, V]> | null): Map<K, V>;
+    new<K = any, V = any>(entries?: ReadonlyArray<[K, V]> | null): Map<K, V>;
     // ...
 }

@DanielRosenwasser DanielRosenwasser changed the title RHS type of assignment expression used instead of LHS type Use generic defaults for "empty" constructors of Array, Map, Set Feb 13, 2019
@DanielRosenwasser DanielRosenwasser added Suggestion An idea for TypeScript In Discussion Not yet reached consensus labels Feb 13, 2019
@aleclarson
Copy link
Author

It's worth noting that array literals are special-cased to work according to my expectations in the OP.

See here

@andrewbranch
Copy link
Member

It’s not possible to make this work without breaking other things, primarily preventing people from writing Map<string> and omitting the second type parameter. See #45648 for more detailed notes.

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
In Discussion Not yet reached consensus Suggestion An idea for TypeScript
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants