{"action":"created","issue":{"url":"https://api.github.com/repos/facebook/flow/issues/1171","labels_url":"https://api.github.com/repos/facebook/flow/issues/1171/labels{/name}","comments_url":"https://api.github.com/repos/facebook/flow/issues/1171/comments","events_url":"https://api.github.com/repos/facebook/flow/issues/1171/events","html_url":"https://github.com/facebook/flow/issues/1171","id":121377336,"number":1171,"title":"Lots of oddities when declaring parameterized classes","user":{"login":"STRML","id":1197375,"avatar_url":"https://avatars.githubusercontent.com/u/1197375?v=3","gravatar_id":"","url":"https://api.github.com/users/STRML","html_url":"https://github.com/STRML","followers_url":"https://api.github.com/users/STRML/followers","following_url":"https://api.github.com/users/STRML/following{/other_user}","gists_url":"https://api.github.com/users/STRML/gists{/gist_id}","starred_url":"https://api.github.com/users/STRML/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/STRML/subscriptions","organizations_url":"https://api.github.com/users/STRML/orgs","repos_url":"https://api.github.com/users/STRML/repos","events_url":"https://api.github.com/users/STRML/events{/privacy}","received_events_url":"https://api.github.com/users/STRML/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":7,"created_at":"2015-12-10T00:56:03Z","updated_at":"2015-12-10T17:52:57Z","closed_at":null,"body":"I'm trying to shim Bluebird.\r\n\r\nI'd like to use the following shim:\r\n\r\n```js\r\n// @flow\r\ndeclare module \"bluebird\" {\r\n  export default class Promise<R>  {\r\n    constructor(callback: (\r\n      resolve: (result: Promise<R> | R) => void,\r\n      reject:  (error: any) => void\r\n    ) => mixed): void;\r\n\r\n    then<U>(\r\n      onFulfill?: (value: R) => Promise<U> | U,\r\n      onReject?: (error: any) => Promise<U> | U\r\n    ): Promise<U>;\r\n\r\n    catch<U>(\r\n      onReject?: (error: any) => ?Promise<U> | U\r\n    ): Promise<U>;\r\n\r\n    static resolve<T>(object?: Promise<T> | T): Promise<T>;\r\n    static reject<T>(error?: any): Promise<T>;\r\n    static all<T, Elem: Promise<T> | T>(promises: Array<Elem>): Promise<Array<T>>;\r\n    static race<T, Elem: Promise<T> | T>(promises: Array<Elem>): Promise<T>;\r\n  }\r\n}\r\n```\r\n\r\nThis shim is of course incomplete but it mimics the native promise typedef exactly.\r\n\r\nThis fails with:\r\n\r\n```\r\ninterfaces/bluebird.js:4\r\n  4:   declare export default class Promise<R>  {\r\n               ^^^^^^ Library parse error:\r\n  4:   declare export default class Promise<R>  {\r\n               ^^^^^^ Unexpected token export\r\n```\r\n\r\nNope, that's not the syntax...\r\n\r\n```\r\ninterfaces/bluebird.js:4\r\n  4:   declare default export class Promise<R>  {\r\n               ^^^^^^^ Library parse error:\r\n  4:   declare default export class Promise<R>  {\r\n               ^^^^^^^ Unexpected token default\r\n```\r\n\r\nNope... so I guess you can't do this at all.\r\n\r\nSo I switch to the undocumented `haste` style (some very basic notes on what this is for those of us not working at Facebook would be very welcome):\r\n\r\n```js\r\n// @flow\r\n// @providesModule bluebird\r\ndeclare export default class Promise<R>  { ...\r\n```\r\n\r\nThis fails with:\r\n\r\n```\r\n[No file]:0\r\ninconsistent use of library definitions\r\n  3: declare export default class Promise<R>  {\r\n                                  ^^^^^^^ export default class Promise {}. Type is incompatible with (unclassified use type: SetNamedExportsT). See: interfaces/bluebird.js:3\r\nmodule\r\n```\r\n\r\nRenaming to `Bluebird` (in case we're clobbering Promise) doesn't change the error.\r\n\r\nSo I ran into @jeffmo on IRC and he suggested:\r\n\r\n```js\r\ndeclare class default<T>{...\r\n```\r\n\r\nwhich returns `unexpected token default`, so that's out.\r\n\r\n@jeffmo suggests:\r\n\r\n```js\r\n// @flow\r\n// @providesModule bluebird \r\n\r\ndeclare class Promise<R> {\r\n  constructor(callback: (\r\n    resolve: (result: Promise<R> | R) => void,\r\n    reject:  (error: any) => void\r\n  ) => mixed): void;\r\n\r\n  then<U>(\r\n    onFulfill?: (value: R) => Promise<U> | U,\r\n    onReject?: (error: any) => Promise<U> | U\r\n  ): Promise<U>;\r\n\r\n  catch<U>(\r\n    onReject?: (error: any) => ?Promise<U> | U\r\n  ): Promise<U>;\r\n\r\n  static resolve<T>(object?: Promise<T> | T): Promise<T>;\r\n  static reject<T>(error?: any): Promise<T>;\r\n  static all<T, Elem: Promise<T> | T>(promises: Array<Elem>): Promise<Array<T>>;\r\n  static race<T, Elem: Promise<T> | T>(promises: Array<Elem>): Promise<T>;\r\n}\r\n\r\ndeclare var exports: {default: Class<Promise>};\r\n```\r\n\r\nWhich sounds like it could work, while hacky, but this does the oddest thing - my console is filled with errors like:\r\n\r\n```\r\n160:   assert(key.length <= 16);\r\n       ^^^^^^^^^^^^^^^^^^^^^^^^ function call. Callable signature not found in\r\n160:   assert(key.length <= 16);\r\n       ^^^^^^ module `assert`\r\n```\r\n\r\n... which is nowhere near the code I'm writing! It appears I've managed to clobber the hack used to [define assert()](https://github.com/facebook/flow/blob/d2a4515be5ea1ab06d1a087eb75cb1f2cb9df3a8/lib/node.js#L1119).\r\n\r\nA last-ditch effort was something like:\r\n\r\n```js\r\ndeclare module \"bluebird\" {\r\n  declare class Promise<R>  {\r\n    constructor(callback: (\r\n      resolve: (result: Promise<R> | R) => void,\r\n      reject:  (error: any) => void\r\n    ) => mixed): void;\r\n\r\n    then<U>(\r\n      onFulfill?: (value: R) => Promise<U> | U,\r\n      onReject?: (error: any) => Promise<U> | U\r\n    ): Promise<U>;\r\n\r\n    catch<U>(\r\n      onReject?: (error: any) => ?Promise<U> | U\r\n    ): Promise<U>;\r\n\r\n    static resolve<T>(object?: Promise<T> | T): Promise<T>;\r\n    static reject<T>(error?: any): Promise<T>;\r\n    static all<T, Elem: Promise<T> | T>(promises: Array<Elem>): Promise<Array<T>>;\r\n    static race<T, Elem: Promise<T> | T>(promises: Array<Elem>): Promise<T>;\r\n  }\r\n  // Also tried exports: Promise, exports: {default: Promise}, etc..\r\n  declare var exports: {default: Class<Promise>};\r\n}\r\n```\r\n\r\nThis simply reports no errors, even on obviously wrong code.\r\n\r\nSo I've hit a wall - is there any way in 0.19 to declare a parameterized class type as a default export?\r\n\r\n"},"comment":{"url":"https://api.github.com/repos/facebook/flow/issues/comments/163701690","html_url":"https://github.com/facebook/flow/issues/1171#issuecomment-163701690","issue_url":"https://api.github.com/repos/facebook/flow/issues/1171","id":163701690,"user":{"login":"samwgoldman","id":254842,"avatar_url":"https://avatars.githubusercontent.com/u/254842?v=3","gravatar_id":"","url":"https://api.github.com/users/samwgoldman","html_url":"https://github.com/samwgoldman","followers_url":"https://api.github.com/users/samwgoldman/followers","following_url":"https://api.github.com/users/samwgoldman/following{/other_user}","gists_url":"https://api.github.com/users/samwgoldman/gists{/gist_id}","starred_url":"https://api.github.com/users/samwgoldman/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/samwgoldman/subscriptions","organizations_url":"https://api.github.com/users/samwgoldman/orgs","repos_url":"https://api.github.com/users/samwgoldman/repos","events_url":"https://api.github.com/users/samwgoldman/events{/privacy}","received_events_url":"https://api.github.com/users/samwgoldman/received_events","type":"User","site_admin":false},"created_at":"2015-12-10T17:52:57Z","updated_at":"2015-12-10T17:52:57Z","body":"Async/await uses the builtin Promise implementation, which I believe is the correct behavior. (Browsers don't use Bluebird.) Another reason to prefer the builtin Promise support if you can.\r\n\r\nAt this point, I think the most helpful thing for me would be if you could publish a repo to GH that I can use to try to reproduce what you're seeing."}}