facebook / facebook/flow

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

Open
#4,859 0 comments 0 reactions 0 assignees View on GitHub
Typing: refinements
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.