My code is as follows (I believe this is mostly a typing issue so I don't think the actual code for downloading is relevant here):
...
TokenService.getToken(id).then(result => {
const { read } = result;
if (typeof read === 'string') {
download(url_template, name, read, is_watermarked);
}
});
**
* Downloads a file
* @param {string} urlTemplate The url to download
* @param {string} name The name of the original file
* @param {string} readToken The access token
* @param {boolean} isWatermarked If a file has a watermark
* @returns {void}
*/
const download = (urlTemplate: string, name: string, readToken: string, isWatermarked: boolean) => {
...
But flow keeps complaining with an errorr about deconstructing read
:
Cannot call TokenService.getToken(...).then with function bound to onFulfill because property read is
missing in String [1] in the first argument.
The strange thing is, I've logged the variable type of read
and it comes back as a string
; so I'm not sure why flow is complaining...
Let's dive into your error messages:
Cannot call TokenService.getToken(...).then with function bound to onFulfill because property read is
missing in String [1] in the first argument.
What this error says is that Flow thinks result
is a String, and thus cannot read property result.read
because Strings don't have such property ("property read is missing
"). Instead of logging the variable type of read
, log it's contents and see if it is a valid String.
The second error
Cannot call download with read bound to readToken because object type [1] is incompatible
with string [2].
Says that Flow thinks the type of read
is other than String in this line:
download(url_template, name, read, is_watermarked);
This is why you should first check if read
is for sure string, and then try setting it's type or overriding it (in Typescript it would be (read as string)
, but I don't know how Flow works sadly)
Keep in mind that what you log into the console is a runtime value, and what Flow thinks a variable's type is, is different because it's only trying to guess what the type of variable will be, but it can't know for sure what will occur in the runtime.
The problem is that when you hover over result
object here,
const { read } = result;
you will see it's type is not set strongly. To bypass that, when you know your API responses are always correct and under result.read
you will always find string, you can force strong type of the read
variable like so:
download(url_template, name, (read as string), is_watermarked);
Keep in mind that logging a variable is different than working with Typescript. What you did was to check the runtime value, but Typescript only works on build level so it is unaware that your API will respond with good object.