Skip to content

Commit

Permalink
Allow mixed args to string.prototype.concat()
Browse files Browse the repository at this point in the history
According to MDN docs for the `concat()` method of the `String` type:

> If the arguments are not of the type string, they are converted to string
> values before concatenating.

Passing numbers, objects, etc to `String.prototype.concat` is is valid JS
behavior but currently causes an error in Flow. It also may be blocking
facebook/react#22064.

This commit changes the arg type: `Array<string>` -> `Array<mixed>`.
  • Loading branch information
justingrant committed Aug 17, 2021
1 parent f9afdbc commit 4f6e2dd
Show file tree
Hide file tree
Showing 22 changed files with 201 additions and 199 deletions.
6 changes: 4 additions & 2 deletions lib/core.js
Original file line number Diff line number Diff line change
Expand Up @@ -1103,9 +1103,11 @@ declare class String {
codePointAt(index: number): number;
/**
* Returns a string that contains the concatenation of two or more strings.
* @param strings The strings to append to the end of the string.
* If the arguments are not of the type string, they are converted to string values before
* concatenating.
* @param values The values to append to the end of the string.
*/
concat(...strings: Array<string>): string;
concat(...values: Array<mixed>): string;
constructor(value?: mixed): void;
/**
* Returns true if the sequence of elements of searchString converted to a String is the
Expand Down
2 changes: 1 addition & 1 deletion newtests/autocomplete/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ export default (suite(({addFile, flowCmd}) => [
},
{
"name": "concat",
"type": "(...strings: Array<string>) => string"
"type": "(...values: Array<mixed>) => string"
},
{
"name": "endsWith",
Expand Down
24 changes: 12 additions & 12 deletions tests/async/async.exp
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ References:
async.js:11:30
11| async function f1(): Promise<bool> {
^^^^ [2]
<BUILTINS>/core.js:1809:24
1809| declare class Promise<+R> {
<BUILTINS>/core.js:1811:24
1811| declare class Promise<+R> {
^ [3]


Expand All @@ -31,8 +31,8 @@ References:
async.js:30:48
30| async function f4(p: Promise<number>): Promise<bool> {
^^^^ [2]
<BUILTINS>/core.js:1809:24
1809| declare class Promise<+R> {
<BUILTINS>/core.js:1811:24
1811| declare class Promise<+R> {
^ [3]


Expand Down Expand Up @@ -99,8 +99,8 @@ undefined in type argument `R` [2]. [incompatible-return]
^^^^^^ [1]

References:
<BUILTINS>/core.js:1809:24
1809| declare class Promise<+R> {
<BUILTINS>/core.js:1811:24
1811| declare class Promise<+R> {
^ [2]


Expand Down Expand Up @@ -134,8 +134,8 @@ References:
async_return_void.js:3:32
3| async function foo1(): Promise<string> {
^^^^^^ [2]
<BUILTINS>/core.js:1809:24
1809| declare class Promise<+R> {
<BUILTINS>/core.js:1811:24
1811| declare class Promise<+R> {
^ [3]


Expand All @@ -152,8 +152,8 @@ References:
async_return_void.js:7:32
7| async function foo2(): Promise<string> {
^^^^^^ [2]
<BUILTINS>/core.js:1809:24
1809| declare class Promise<+R> {
<BUILTINS>/core.js:1811:24
1811| declare class Promise<+R> {
^ [3]


Expand All @@ -173,8 +173,8 @@ References:
async_return_void.js:11:32
11| async function foo3(): Promise<string> {
^^^^^^ [2]
<BUILTINS>/core.js:1809:24
1809| declare class Promise<+R> {
<BUILTINS>/core.js:1811:24
1811| declare class Promise<+R> {
^ [3]


Expand Down
4 changes: 2 additions & 2 deletions tests/async_iteration/async_iteration.exp
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,8 @@ Cannot cast `result.value` to string because undefined [1] is incompatible with
^^^^^^^^^^^^

References:
<BUILTINS>/core.js:1635:14
1635| +value?: Return,
<BUILTINS>/core.js:1637:14
1637| +value?: Return,
^^^^^^ [1]
return.js:20:20
20| (result.value: string); // error: number | void ~> string
Expand Down
4 changes: 2 additions & 2 deletions tests/autocomplete/autocomplete.exp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ Flags: --pretty
{"name":"charAt","type":"(pos: number) => string"},
{"name":"charCodeAt","type":"(index: number) => number"},
{"name":"codePointAt","type":"(index: number) => number"},
{"name":"concat","type":"(...strings: Array<string>) => string"},
{"name":"concat","type":"(...values: Array<mixed>) => string"},
{
"name":"endsWith",
"type":"(searchString: string, position?: number) => boolean"
Expand Down Expand Up @@ -389,7 +389,7 @@ Flags: --pretty
{"name":"charAt","type":"(pos: number) => string"},
{"name":"charCodeAt","type":"(index: number) => number"},
{"name":"codePointAt","type":"(index: number) => number"},
{"name":"concat","type":"(...strings: Array<string>) => string"},
{"name":"concat","type":"(...values: Array<mixed>) => string"},
{
"name":"endsWith",
"type":"(searchString: string, position?: number) => boolean"
Expand Down
72 changes: 36 additions & 36 deletions tests/core_tests/core_tests.exp
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ Cannot cast `JSON.stringify(...)` to string because undefined [1] is incompatibl
^^^^^^^^^^^^^^^^^^^^

References:
<BUILTINS>/core.js:1627:17
1627| ): string | void;
<BUILTINS>/core.js:1629:17
1629| ): string | void;
^^^^ [1]
json_stringify.js:9:24
9| (JSON.stringify(bad1): string);
Expand All @@ -28,11 +28,11 @@ References:
map.js:23:22
23| let x = new Map(['foo', 123]); // error
^^^^^ [1]
<BUILTINS>/core.js:1710:38
1710| constructor(iterable?: ?Iterable<[K, V]>): void;
<BUILTINS>/core.js:1712:38
1712| constructor(iterable?: ?Iterable<[K, V]>): void;
^^^^^^ [2]
<BUILTINS>/core.js:1644:22
1644| interface $Iterator<+Yield,+Return,-Next> {
<BUILTINS>/core.js:1646:22
1646| interface $Iterator<+Yield,+Return,-Next> {
^^^^^ [3]


Expand All @@ -49,11 +49,11 @@ References:
map.js:23:29
23| let x = new Map(['foo', 123]); // error
^^^ [1]
<BUILTINS>/core.js:1710:38
1710| constructor(iterable?: ?Iterable<[K, V]>): void;
<BUILTINS>/core.js:1712:38
1712| constructor(iterable?: ?Iterable<[K, V]>): void;
^^^^^^ [2]
<BUILTINS>/core.js:1644:22
1644| interface $Iterator<+Yield,+Return,-Next> {
<BUILTINS>/core.js:1646:22
1646| interface $Iterator<+Yield,+Return,-Next> {
^^^^^ [3]


Expand Down Expand Up @@ -102,8 +102,8 @@ Cannot cast `x.get(...)` to boolean because undefined [1] is incompatible with b
^^^^^^^^^^^^

References:
<BUILTINS>/core.js:1718:22
1718| get(key: K): V | void;
<BUILTINS>/core.js:1720:22
1720| get(key: K): V | void;
^^^^ [1]
map.js:29:20
29| (x.get('foo'): boolean); // error, string | void
Expand Down Expand Up @@ -183,17 +183,17 @@ property `@@iterator`: [incompatible-call]
^^^^^^^^^

References:
<BUILTINS>/core.js:1644:22
1644| interface $Iterator<+Yield,+Return,-Next> {
<BUILTINS>/core.js:1646:22
1646| interface $Iterator<+Yield,+Return,-Next> {
^^^^^ [1]
weakset.js:19:24
19| let ws3 = new WeakSet([1, 2, 3]); // error, must be objects
^ [2]
<BUILTINS>/core.js:1796:26
1796| declare class WeakSet<T: {...} | $ReadOnlyArray<any>> extends $ReadOnlyWeakSet<T> {
<BUILTINS>/core.js:1798:26
1798| declare class WeakSet<T: {...} | $ReadOnlyArray<any>> extends $ReadOnlyWeakSet<T> {
^^^^^ [3]
<BUILTINS>/core.js:1796:34
1796| declare class WeakSet<T: {...} | $ReadOnlyArray<any>> extends $ReadOnlyWeakSet<T> {
<BUILTINS>/core.js:1798:34
1798| declare class WeakSet<T: {...} | $ReadOnlyArray<any>> extends $ReadOnlyWeakSet<T> {
^^^^^^^^^^^^^^^^^^^ [4]


Expand All @@ -209,17 +209,17 @@ property `@@iterator`: [incompatible-call]
^^^^^^^^^

References:
<BUILTINS>/core.js:1644:22
1644| interface $Iterator<+Yield,+Return,-Next> {
<BUILTINS>/core.js:1646:22
1646| interface $Iterator<+Yield,+Return,-Next> {
^^^^^ [1]
weakset.js:19:27
19| let ws3 = new WeakSet([1, 2, 3]); // error, must be objects
^ [2]
<BUILTINS>/core.js:1796:26
1796| declare class WeakSet<T: {...} | $ReadOnlyArray<any>> extends $ReadOnlyWeakSet<T> {
<BUILTINS>/core.js:1798:26
1798| declare class WeakSet<T: {...} | $ReadOnlyArray<any>> extends $ReadOnlyWeakSet<T> {
^^^^^ [3]
<BUILTINS>/core.js:1796:34
1796| declare class WeakSet<T: {...} | $ReadOnlyArray<any>> extends $ReadOnlyWeakSet<T> {
<BUILTINS>/core.js:1798:34
1798| declare class WeakSet<T: {...} | $ReadOnlyArray<any>> extends $ReadOnlyWeakSet<T> {
^^^^^^^^^^^^^^^^^^^ [4]


Expand All @@ -235,17 +235,17 @@ property `@@iterator`: [incompatible-call]
^^^^^^^^^

References:
<BUILTINS>/core.js:1644:22
1644| interface $Iterator<+Yield,+Return,-Next> {
<BUILTINS>/core.js:1646:22
1646| interface $Iterator<+Yield,+Return,-Next> {
^^^^^ [1]
weakset.js:19:30
19| let ws3 = new WeakSet([1, 2, 3]); // error, must be objects
^ [2]
<BUILTINS>/core.js:1796:26
1796| declare class WeakSet<T: {...} | $ReadOnlyArray<any>> extends $ReadOnlyWeakSet<T> {
<BUILTINS>/core.js:1798:26
1798| declare class WeakSet<T: {...} | $ReadOnlyArray<any>> extends $ReadOnlyWeakSet<T> {
^^^^^ [3]
<BUILTINS>/core.js:1796:34
1796| declare class WeakSet<T: {...} | $ReadOnlyArray<any>> extends $ReadOnlyWeakSet<T> {
<BUILTINS>/core.js:1798:34
1798| declare class WeakSet<T: {...} | $ReadOnlyArray<any>> extends $ReadOnlyWeakSet<T> {
^^^^^^^^^^^^^^^^^^^ [4]


Expand All @@ -260,17 +260,17 @@ Cannot call `WeakSet` with `numbers()` bound to `iterable` because in type argum
^^^^^^^^^

References:
<BUILTINS>/core.js:1650:22
1650| interface $Iterable<+Yield,+Return,-Next> {
<BUILTINS>/core.js:1652:22
1652| interface $Iterable<+Yield,+Return,-Next> {
^^^^^ [1]
weakset.js:29:31
29| function* numbers(): Iterable<number> {
^^^^^^ [2]
<BUILTINS>/core.js:1796:26
1796| declare class WeakSet<T: {...} | $ReadOnlyArray<any>> extends $ReadOnlyWeakSet<T> {
<BUILTINS>/core.js:1798:26
1798| declare class WeakSet<T: {...} | $ReadOnlyArray<any>> extends $ReadOnlyWeakSet<T> {
^^^^^ [3]
<BUILTINS>/core.js:1796:34
1796| declare class WeakSet<T: {...} | $ReadOnlyArray<any>> extends $ReadOnlyWeakSet<T> {
<BUILTINS>/core.js:1798:34
1798| declare class WeakSet<T: {...} | $ReadOnlyArray<any>> extends $ReadOnlyWeakSet<T> {
^^^^^^^^^^^^^^^^^^^ [4]


Expand Down
56 changes: 28 additions & 28 deletions tests/date/date.exp
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ Cannot assign `d.getTime()` to `x` because number [1] is incompatible with strin
^^^^^^^^^^^

References:
<BUILTINS>/core.js:1364:16
1364| getTime(): number;
<BUILTINS>/core.js:1366:16
1366| getTime(): number;
^^^^^^ [1]
date.js:2:7
2| var x:string = d.getTime(); // expect error
Expand Down Expand Up @@ -44,8 +44,8 @@ References:
date.js:18:10
18| new Date({});
^^ [1]
<BUILTINS>/core.js:1344:23
1344| constructor(date: Date): void;
<BUILTINS>/core.js:1346:23
1346| constructor(date: Date): void;
^^^^ [2]


Expand All @@ -61,8 +61,8 @@ References:
date.js:19:16
19| new Date(2015, '6');
^^^ [1]
<BUILTINS>/core.js:1346:38
1346| constructor(year: number, month: number, day?: number, hour?: number, minute?: number, second?: number, millisecond?: number): void;
<BUILTINS>/core.js:1348:38
1348| constructor(year: number, month: number, day?: number, hour?: number, minute?: number, second?: number, millisecond?: number): void;
^^^^^^ [2]


Expand All @@ -78,8 +78,8 @@ References:
date.js:20:19
20| new Date(2015, 6, '18');
^^^^ [1]
<BUILTINS>/core.js:1346:52
1346| constructor(year: number, month: number, day?: number, hour?: number, minute?: number, second?: number, millisecond?: number): void;
<BUILTINS>/core.js:1348:52
1348| constructor(year: number, month: number, day?: number, hour?: number, minute?: number, second?: number, millisecond?: number): void;
^^^^^^ [2]


Expand All @@ -95,8 +95,8 @@ References:
date.js:21:23
21| new Date(2015, 6, 18, '11');
^^^^ [1]
<BUILTINS>/core.js:1346:67
1346| constructor(year: number, month: number, day?: number, hour?: number, minute?: number, second?: number, millisecond?: number): void;
<BUILTINS>/core.js:1348:67
1348| constructor(year: number, month: number, day?: number, hour?: number, minute?: number, second?: number, millisecond?: number): void;
^^^^^^ [2]


Expand All @@ -112,8 +112,8 @@ References:
date.js:22:27
22| new Date(2015, 6, 18, 11, '55');
^^^^ [1]
<BUILTINS>/core.js:1346:84
1346| constructor(year: number, month: number, day?: number, hour?: number, minute?: number, second?: number, millisecond?: number): void;
<BUILTINS>/core.js:1348:84
1348| constructor(year: number, month: number, day?: number, hour?: number, minute?: number, second?: number, millisecond?: number): void;
^^^^^^ [2]


Expand All @@ -129,8 +129,8 @@ References:
date.js:23:31
23| new Date(2015, 6, 18, 11, 55, '42');
^^^^ [1]
<BUILTINS>/core.js:1346:101
1346| constructor(year: number, month: number, day?: number, hour?: number, minute?: number, second?: number, millisecond?: number): void;
<BUILTINS>/core.js:1348:101
1348| constructor(year: number, month: number, day?: number, hour?: number, minute?: number, second?: number, millisecond?: number): void;
^^^^^^ [2]


Expand All @@ -146,8 +146,8 @@ References:
date.js:24:35
24| new Date(2015, 6, 18, 11, 55, 42, '999');
^^^^^ [1]
<BUILTINS>/core.js:1346:123
1346| constructor(year: number, month: number, day?: number, hour?: number, minute?: number, second?: number, millisecond?: number): void;
<BUILTINS>/core.js:1348:123
1348| constructor(year: number, month: number, day?: number, hour?: number, minute?: number, second?: number, millisecond?: number): void;
^^^^^^ [2]


Expand All @@ -165,20 +165,20 @@ Cannot call `Date` because: [incompatible-call]
^^^^

References:
<BUILTINS>/core.js:1342:5
1342| constructor(): void;
<BUILTINS>/core.js:1344:5
1344| constructor(): void;
^^^^^^^^^^^^^^^^^^^ [1]
<BUILTINS>/core.js:1343:5
1343| constructor(timestamp: number): void;
<BUILTINS>/core.js:1345:5
1345| constructor(timestamp: number): void;
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ [2]
<BUILTINS>/core.js:1344:5
1344| constructor(date: Date): void;
<BUILTINS>/core.js:1346:5
1346| constructor(date: Date): void;
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ [3]
<BUILTINS>/core.js:1345:5
1345| constructor(dateString: string): void;
<BUILTINS>/core.js:1347:5
1347| constructor(dateString: string): void;
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ [4]
<BUILTINS>/core.js:1346:5
1346| constructor(year: number, month: number, day?: number, hour?: number, minute?: number, second?: number, millisecond?: number): void;
<BUILTINS>/core.js:1348:5
1348| constructor(year: number, month: number, day?: number, hour?: number, minute?: number, second?: number, millisecond?: number): void;
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ [5]


Expand All @@ -194,8 +194,8 @@ References:
date.js:26:10
26| new Date('2015', 6);
^^^^^^ [1]
<BUILTINS>/core.js:1346:23
1346| constructor(year: number, month: number, day?: number, hour?: number, minute?: number, second?: number, millisecond?: number): void;
<BUILTINS>/core.js:1348:23
1348| constructor(year: number, month: number, day?: number, hour?: number, minute?: number, second?: number, millisecond?: number): void;
^^^^^^ [2]


Expand Down
Loading

0 comments on commit 4f6e2dd

Please sign in to comment.