Flow requires inlined "typeof", does not accept a const (string) variable with typeof result when there is a 2nd if-term also relying on the typeof check
- Dominant language
- Rust
- Stars
- 22.3k
- Forks
- 1.9k
- PR merge metrics
- No merged PRs in 30d
Description
Flow 0.54.1
### Description
Because I needed `typeof myvariable` twice I assigned it to a `const` just before the `if` statement.
This works as long as the `if` only uses this `const` as its only term. When I add a second (AND) condition that relies on this check too it all fails.
The difference between the two demo functions below merely is
```js
const type: string = typeof microdata;
if (type === 'string' && microdata.startsWith(MICRODATA_START))
```
vs.
```js
if (typeof microdata === 'string' && microdata.startsWith(MICRODATA_START))
```
The first one does not work. It works if there is no chained second condition.
### Code
The `send` function with a `mixed` return type stands for a function that receives JSON responses from a network source.
```js
// @flow
'use strict';
async function send (s: string): mixed {
return Math.random() < 0.5 ?
'string' :
{};
}
const MICRODATA_START = '';
// THE DIFFERENCE BETWEEN DEMO FUNCTION fn1 and fn2 is that fn1 uses
// const type: string = typeof microdata;
// while fn2 uses inlined "typeof microdata".
const fn1 = async function (path: Array): Promise {
let microdata: mixed;
try {
microdata = await send('GET_OBJECT');
} catch (err) {
err.stack += (new Error()).stack;
throw err;
}
const type: string = typeof microdata;
if (type === 'string' && microdata.startsWith(MICRODATA_START)) {
return microdata;
} else {
throw new TypeError(
'Expected ONE object microdata string, got ' + String(microdata) + '(' + type + ')'
);
}
};
const fn2 = async function (path: Array): Promise {
let microdata: mixed;
try {
microdata = await send('GET_OBJECT');
} catch (err) {
err.stack += (new Error()).stack;
throw err;
}
if (typeof microdata === 'string' && microdata.startsWith(MICRODATA_START)) {
return microdata;
} else {
throw new TypeError(
'Expected ONE object microdata string, got ' + String(microdata) + '(' + typeof microdata + ')'
);
}
};
```
### Error
```
Error: src/main.js:28
28: if (type === 'string' && microdata.startsWith(MICRODATA_START)) {
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call of method `startsWith`. Method cannot be called on
28: if (type === 'string' && microdata.startsWith(MICRODATA_START)) {
^^^^^^^^^ mixed
Error: src/main.js:29
29: return microdata;
^^^^^^^^^^^^^^^^^ type application of async return. This type is incompatible with the expected return type of
16: const fn1 = async function (path: Array): Promise {
^^^^^^^^^^^^^^^ type application of identifier `Promise`
Type argument `R` is incompatible:
29: return microdata;
^^^^^^^^^ mixed. This type is incompatible with
16: const fn1 = async function (path: Array): Promise {
^^^^^^ string
Found 2 errors
```
### Try
[**Flow Try link**](https://flow.org/try/#0PTAEAEDMBsHsHcBQByArgZwKanQFwE4CWAxrsgNyKICG6AngHbGiSpO6GwM6YMAmoABToAXDgKEGAcwCUYgLaEAHpgEBvRKC2h8mXKnzcAstVwALAHT5q-WPMEzQAHlAAGCwFZQAfk3b-yHhE0sigIn7+WmoAvpTRVMRceKBGAJIAwgBKAPIAIgCCACr5APoAysWZhaAAvKDITugADjYAfBRUIKCFABIAoqC5qQBiw32ZfQBy6QMAQn2FAOp9U4N9RtmgwwCq04Wp2ZMsDACMoDYCkAwATKCE6KDmpsdnGJjoiF1aiQzJuHRNTBiIKSKS1R4AzCwSCgRTEfCwPimaiULrwMyEaDYK63N4PSTQSSqUAAIn+gOhsJICKRuGoJIsCSSuBe4NojGYrHYnG4gha5jE+Xw1jojQk0laclAAAUEYosGLglJWqANP4sSy4TTkQplKpKBFHvg6KrDf4tYjkWz4NRCCysPxBMgAOILErZWYAKT66UKyBklH80VAxFMxDMQkwwscasiWij+AseGoxAA1qAANR1QQMTDwUB9YWwfAOGRJulpwNxx5mBH5hNVrTxQ0-P6Q4HisF1clQmEW2koqj+QgwwQ92o1OqBTuhABks6p8MtdPL1HwuHQiztZkEaSyeSKpQq+SqMhjZu0un0hkX2rpjdAwcw0CwpurNbroFz+cKkMLCJLC842QPolEBUhiUOAZYAAIwAK0wUhb2XahxCVAAaUApFgFlQgzUAyk7QR+2RRx8OQJ1MwhQEqP9ZAgNAANDXiWImV+FkcTZegmBYNhSB5IR+TMQVhWoUUQQlKVZTse5MEVUEVVjLQNWQgddRUPgDX8AgTSUyISLpa1bXtXg+CdV1CndL0fT9JigxDMMI0EBNz3fBNVzTTNs2-AsixLM8PNTB9tNrBBQAbZih20EchB7SkDNQycpwkqQ5wXBLV3XTdt13DIcgKYpykqQozzfasrwMbgEofJ8X2wPSQs-Hzf0Bf9i0EBiAlA8DcEgyZoPgxDNWpFC0NBTDsNwqjCKVYiRoHMj6ko-C4r7earXImR6PfOztBYyggA)
Contributor guide
Assessment
This issue has not been assessed yet.