Skip to content

Commit

Permalink
[flow][libdef] Update core libdefs to use mapped type on array instea…
Browse files Browse the repository at this point in the history
…d of $TupleMap

Summary:
This diff changes the core libdef to stop using `$TupleMap` and instead use the mapped type on array inputs.

`$TupleMap` currently has a hacky support for iterables by first translating them into array type. I decide not to do that, but instead use conditional type to model the return: first checking for array input and use the more precise mapped type if we can, and then fall back to the general iterable typing where the extra power of $TupleMap is not needed.

Changelog: [libdef] `Promise.all` and `Promise.allSettled` have been updated to use mapped type instead of `$TupleMap`. The requirement on the type arguments are slightly changed.

Reviewed By: panagosg7

Differential Revision: D62473784

fbshipit-source-id: b819359e7a9be3626b82c995e2f5a074ca7ac121
  • Loading branch information
SamChou19815 authored and facebook-github-bot committed Sep 12, 2024
1 parent f985ab1 commit 35790c5
Show file tree
Hide file tree
Showing 9 changed files with 180 additions and 164 deletions.
12 changes: 10 additions & 2 deletions lib/core.js
Original file line number Diff line number Diff line change
Expand Up @@ -2031,14 +2031,20 @@ declare class Promise<+R = mixed> {
* @param promises An iterable of Promises.
* @returns A new Promise.
*/
static all<T: Iterable<mixed>>(promises: T): Promise<$TupleMap<T, <T>(p: Promise<T> | T) => T>>;
static all<T: Iterable<mixed>>(promises: T): Promise<
T extends $ReadOnlyArray<mixed> ? {[K in keyof T]: Awaited<T[K]>} :
T extends Iterable<infer V> ? Array<Awaited<V>> : any
>;
/**
* Creates a Promise that is resolved with an array of results when all
* of the provided Promises resolve or reject.
* @param promises An array of Promises.
* @returns A new Promise.
*/
static allSettled<T: Iterable<mixed>>(promises: T): Promise<$TupleMap<T, <T>(p: Promise<T> | T) => $SettledPromiseResult<T>>>;
static allSettled<T: Iterable<mixed>>(promises: T): Promise<
T extends $ReadOnlyArray<mixed> ? {[K in keyof T]: $SettledPromiseResult<Awaited<T[K]>>} :
T extends Iterable<infer V> ? Array<$SettledPromiseResult<Awaited<V>>> : any
>;
/**
* Creates a Promise that is resolved or rejected when any of the provided Promises are resolved
* or rejected.
Expand Down Expand Up @@ -2808,6 +2814,8 @@ type ThisParameterType<T> = T extends (this: infer U, ...args: empty) => mixed ?
*/
type OmitThisParameter<T> = mixed extends ThisParameterType<T> ? T : T extends (...args: infer A) => infer R ? (...args: A) => R : T;

type Awaited<T> = T extends Promise<infer U> ? U : T;

/**
* Extract specific fields from an object, e.g. Pick<O, 'foo' | 'bar'>
*/
Expand Down
12 changes: 6 additions & 6 deletions tests/async/async.exp
Original file line number Diff line number Diff line change
Expand Up @@ -220,9 +220,9 @@ string [2] in type argument `Yield` [3]. [incompatible-return]
^^^^^^ [1]

References:
generator.js:22:31
22| yield* await Promise.all(["a"]); // error string ~> number
^^^ [2]
<BUILTINS>/core.js:2035:58
2035| T extends $ReadOnlyArray<mixed> ? {[K in keyof T]: Awaited<T[K]>} :
^^^^^^^^^^^^^ [2]
<BUILTINS>/core.js:1778:27
1778| interface AsyncGenerator<+Yield,+Return,-Next> {
^^^^^ [3]
Expand All @@ -237,9 +237,9 @@ string [1] is incompatible with number [2] in type argument `Yield` [3]. [incomp
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

References:
generator.js:22:31
22| yield* await Promise.all(["a"]); // error string ~> number
^^^ [1]
<BUILTINS>/core.js:2035:58
2035| T extends $ReadOnlyArray<mixed> ? {[K in keyof T]: Awaited<T[K]>} :
^^^^^^^^^^^^^ [1]
generator.js:21:45
21| async function *genError1(): AsyncGenerator<number, void, void> {
^^^^^^ [2]
Expand Down
24 changes: 12 additions & 12 deletions tests/bigint/bigint.exp
Original file line number Diff line number Diff line change
Expand Up @@ -30,23 +30,23 @@ Cannot call `BigInt` with `null` bound to `value` because: [incompatible-call]
^^^^ [1]

References:
<BUILTINS>/core.js:2756:18
2756| static (value: boolean | string | number | bigint | interface {} | $ReadOnlyArray<mixed>): bigint;
<BUILTINS>/core.js:2762:18
2762| static (value: boolean | string | number | bigint | interface {} | $ReadOnlyArray<mixed>): bigint;
^^^^^^^ [2]
<BUILTINS>/core.js:2756:28
2756| static (value: boolean | string | number | bigint | interface {} | $ReadOnlyArray<mixed>): bigint;
<BUILTINS>/core.js:2762:28
2762| static (value: boolean | string | number | bigint | interface {} | $ReadOnlyArray<mixed>): bigint;
^^^^^^ [3]
<BUILTINS>/core.js:2756:37
2756| static (value: boolean | string | number | bigint | interface {} | $ReadOnlyArray<mixed>): bigint;
<BUILTINS>/core.js:2762:37
2762| static (value: boolean | string | number | bigint | interface {} | $ReadOnlyArray<mixed>): bigint;
^^^^^^ [4]
<BUILTINS>/core.js:2756:46
2756| static (value: boolean | string | number | bigint | interface {} | $ReadOnlyArray<mixed>): bigint;
<BUILTINS>/core.js:2762:46
2762| static (value: boolean | string | number | bigint | interface {} | $ReadOnlyArray<mixed>): bigint;
^^^^^^ [5]
<BUILTINS>/core.js:2756:55
2756| static (value: boolean | string | number | bigint | interface {} | $ReadOnlyArray<mixed>): bigint;
<BUILTINS>/core.js:2762:55
2762| static (value: boolean | string | number | bigint | interface {} | $ReadOnlyArray<mixed>): bigint;
^^^^^^^^^^^^ [6]
<BUILTINS>/core.js:2756:70
2756| static (value: boolean | string | number | bigint | interface {} | $ReadOnlyArray<mixed>): bigint;
<BUILTINS>/core.js:2762:70
2762| static (value: boolean | string | number | bigint | interface {} | $ReadOnlyArray<mixed>): bigint;
^^^^^^^^^^^^^^^^^^^^^ [7]


Expand Down
120 changes: 60 additions & 60 deletions tests/enums/enums.exp
Original file line number Diff line number Diff line change
Expand Up @@ -48,20 +48,20 @@ Cannot instantiate `EnumValue` because in type argument `TRepresentationType`: [
^^^^^^^^ [1]

References:
<BUILTINS>/core.js:2838:32
2838| type EnumRepresentationTypes = string | number | symbol | boolean | bigint;
<BUILTINS>/core.js:2846:32
2846| type EnumRepresentationTypes = string | number | symbol | boolean | bigint;
^^^^^^ [2]
<BUILTINS>/core.js:2838:41
2838| type EnumRepresentationTypes = string | number | symbol | boolean | bigint;
<BUILTINS>/core.js:2846:41
2846| type EnumRepresentationTypes = string | number | symbol | boolean | bigint;
^^^^^^ [3]
<BUILTINS>/core.js:2838:50
2838| type EnumRepresentationTypes = string | number | symbol | boolean | bigint;
<BUILTINS>/core.js:2846:50
2846| type EnumRepresentationTypes = string | number | symbol | boolean | bigint;
^^^^^^ [4]
<BUILTINS>/core.js:2838:59
2838| type EnumRepresentationTypes = string | number | symbol | boolean | bigint;
<BUILTINS>/core.js:2846:59
2846| type EnumRepresentationTypes = string | number | symbol | boolean | bigint;
^^^^^^^ [5]
<BUILTINS>/core.js:2838:69
2838| type EnumRepresentationTypes = string | number | symbol | boolean | bigint;
<BUILTINS>/core.js:2846:69
2846| type EnumRepresentationTypes = string | number | symbol | boolean | bigint;
^^^^^^ [6]


Expand Down Expand Up @@ -143,8 +143,8 @@ Cannot cast `x` to `EnumValue` because number [1] is incompatible with boolean [
^

References:
<BUILTINS>/core.js:2852:16
2852| > = $EnumValue<TRepresentationType>;
<BUILTINS>/core.js:2860:16
2860| > = $EnumValue<TRepresentationType>;
^^^^^^^^^^^^^^^^^^^ [1]
abstract-enum-value.js:35:18
35| x as EnumValue<boolean>; // ERROR
Expand All @@ -161,8 +161,8 @@ Cannot cast `x` to `EnumValue` because string [1] is incompatible with boolean [
^

References:
<BUILTINS>/core.js:2852:16
2852| > = $EnumValue<TRepresentationType>;
<BUILTINS>/core.js:2860:16
2860| > = $EnumValue<TRepresentationType>;
^^^^^^^^^^^^^^^^^^^ [1]
abstract-enum-value.js:35:18
35| x as EnumValue<boolean>; // ERROR
Expand Down Expand Up @@ -232,8 +232,8 @@ Cannot instantiate `Enum` because boolean [1] is incompatible with `EnumValue` [
^^^^^^^ [1]

References:
<BUILTINS>/core.js:2869:24
2869| type Enum<+TEnumValue: EnumValue<> = EnumValue<>> = $Enum<TEnumValue>;
<BUILTINS>/core.js:2877:24
2877| type Enum<+TEnumValue: EnumValue<> = EnumValue<>> = $Enum<TEnumValue>;
^^^^^^^^^^^ [2]


Expand Down Expand Up @@ -270,11 +270,11 @@ References:
abstract-enum.js:19:23
19| x as Enum<EnumValue<boolean>>; // ERROR
^^^^^^^ [2]
<BUILTINS>/core.js:2851:4
2851| +TRepresentationType: EnumRepresentationTypes = EnumRepresentationTypes
<BUILTINS>/core.js:2859:4
2859| +TRepresentationType: EnumRepresentationTypes = EnumRepresentationTypes
^^^^^^^^^^^^^^^^^^^ [3]
<BUILTINS>/core.js:2869:12
2869| type Enum<+TEnumValue: EnumValue<> = EnumValue<>> = $Enum<TEnumValue>;
<BUILTINS>/core.js:2877:12
2877| type Enum<+TEnumValue: EnumValue<> = EnumValue<>> = $Enum<TEnumValue>;
^^^^^^^^^^ [4]


Expand All @@ -294,8 +294,8 @@ References:
abstract-enum.js:20:13
20| x as Enum<E>; // ERROR
^ [2]
<BUILTINS>/core.js:2869:12
2869| type Enum<+TEnumValue: EnumValue<> = EnumValue<>> = $Enum<TEnumValue>;
<BUILTINS>/core.js:2877:12
2877| type Enum<+TEnumValue: EnumValue<> = EnumValue<>> = $Enum<TEnumValue>;
^^^^^^^^^^ [3]


Expand Down Expand Up @@ -338,8 +338,8 @@ Cannot call `f` because boolean [1] is incompatible with `EnumValue` [2] in type
^^^^ [1]

References:
<BUILTINS>/core.js:2869:24
2869| type Enum<+TEnumValue: EnumValue<> = EnumValue<>> = $Enum<TEnumValue>;
<BUILTINS>/core.js:2877:24
2877| type Enum<+TEnumValue: EnumValue<> = EnumValue<>> = $Enum<TEnumValue>;
^^^^^^^^^^^ [2]


Expand Down Expand Up @@ -1794,8 +1794,8 @@ References:
exhaustive-check.js:3:6
3| enum E {
^ [2]
<BUILTINS>/core.js:2641:3
2641| isValid(this: TEnum, input: ?TRepresentationType | TEnumValue): boolean,
<BUILTINS>/core.js:2647:3
2647| isValid(this: TEnum, input: ?TRepresentationType | TEnumValue): boolean,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ [3]


Expand Down Expand Up @@ -2513,15 +2513,15 @@ Cannot get `E.nonExistent` because property `nonExistent` is missing in `$EnumPr
^^^^^^^^^^^

References:
<BUILTINS>/core.js:2638:59
<BUILTINS>/core.js:2644:59
v-
2638| type $EnumProto<TEnum, TEnumValue, TRepresentationType> = {|
2639| cast(this: TEnum, input: ?TRepresentationType): void | TEnumValue,
2640| getName(this: TEnum, input: TEnumValue): string,
2641| isValid(this: TEnum, input: ?TRepresentationType | TEnumValue): boolean,
2642| members(this: TEnum): Iterator<TEnumValue>,
2643| __proto__: null,
2644| |}
2644| type $EnumProto<TEnum, TEnumValue, TRepresentationType> = {|
2645| cast(this: TEnum, input: ?TRepresentationType): void | TEnumValue,
2646| getName(this: TEnum, input: TEnumValue): string,
2647| isValid(this: TEnum, input: ?TRepresentationType | TEnumValue): boolean,
2648| members(this: TEnum): Iterator<TEnumValue>,
2649| __proto__: null,
2650| |}
-^ [1]


Expand All @@ -2534,15 +2534,15 @@ Cannot call `E.nonExistent` because property `nonExistent` is missing in `$EnumP
^^^^^^^^^^^

References:
<BUILTINS>/core.js:2638:59
<BUILTINS>/core.js:2644:59
v-
2638| type $EnumProto<TEnum, TEnumValue, TRepresentationType> = {|
2639| cast(this: TEnum, input: ?TRepresentationType): void | TEnumValue,
2640| getName(this: TEnum, input: TEnumValue): string,
2641| isValid(this: TEnum, input: ?TRepresentationType | TEnumValue): boolean,
2642| members(this: TEnum): Iterator<TEnumValue>,
2643| __proto__: null,
2644| |}
2644| type $EnumProto<TEnum, TEnumValue, TRepresentationType> = {|
2645| cast(this: TEnum, input: ?TRepresentationType): void | TEnumValue,
2646| getName(this: TEnum, input: TEnumValue): string,
2647| isValid(this: TEnum, input: ?TRepresentationType | TEnumValue): boolean,
2648| members(this: TEnum): Iterator<TEnumValue>,
2649| __proto__: null,
2650| |}
-^ [1]


Expand All @@ -2569,15 +2569,15 @@ Cannot call `E.A` because property `A` is missing in `$EnumProto` [1]. [prop-mis
^

References:
<BUILTINS>/core.js:2638:59
<BUILTINS>/core.js:2644:59
v-
2638| type $EnumProto<TEnum, TEnumValue, TRepresentationType> = {|
2639| cast(this: TEnum, input: ?TRepresentationType): void | TEnumValue,
2640| getName(this: TEnum, input: TEnumValue): string,
2641| isValid(this: TEnum, input: ?TRepresentationType | TEnumValue): boolean,
2642| members(this: TEnum): Iterator<TEnumValue>,
2643| __proto__: null,
2644| |}
2644| type $EnumProto<TEnum, TEnumValue, TRepresentationType> = {|
2645| cast(this: TEnum, input: ?TRepresentationType): void | TEnumValue,
2646| getName(this: TEnum, input: TEnumValue): string,
2647| isValid(this: TEnum, input: ?TRepresentationType | TEnumValue): boolean,
2648| members(this: TEnum): Iterator<TEnumValue>,
2649| __proto__: null,
2650| |}
-^ [1]


Expand All @@ -2590,15 +2590,15 @@ Cannot call `E.toString` because property `toString` is missing in `$EnumProto`
^^^^^^^^

References:
<BUILTINS>/core.js:2638:59
<BUILTINS>/core.js:2644:59
v-
2638| type $EnumProto<TEnum, TEnumValue, TRepresentationType> = {|
2639| cast(this: TEnum, input: ?TRepresentationType): void | TEnumValue,
2640| getName(this: TEnum, input: TEnumValue): string,
2641| isValid(this: TEnum, input: ?TRepresentationType | TEnumValue): boolean,
2642| members(this: TEnum): Iterator<TEnumValue>,
2643| __proto__: null,
2644| |}
2644| type $EnumProto<TEnum, TEnumValue, TRepresentationType> = {|
2645| cast(this: TEnum, input: ?TRepresentationType): void | TEnumValue,
2646| getName(this: TEnum, input: TEnumValue): string,
2647| isValid(this: TEnum, input: ?TRepresentationType | TEnumValue): boolean,
2648| members(this: TEnum): Iterator<TEnumValue>,
2649| __proto__: null,
2650| |}
-^ [1]


Expand All @@ -2611,8 +2611,8 @@ Cannot cast `E.getName(...)` to boolean because string [1] is incompatible with
^^^^^^^^^^^^^^

References:
<BUILTINS>/core.js:2640:44
2640| getName(this: TEnum, input: TEnumValue): string,
<BUILTINS>/core.js:2646:44
2646| getName(this: TEnum, input: TEnumValue): string,
^^^^^^ [1]
methods.js:44:19
44| E.getName(E.B) as boolean; // Error - wrong type
Expand Down
16 changes: 8 additions & 8 deletions tests/fetch/fetch.exp
Original file line number Diff line number Diff line change
Expand Up @@ -721,17 +721,17 @@ References:
<BUILTINS>/bom.js:1637:62
1637| type BodyInit = string | URLSearchParams | FormData | Blob | ArrayBuffer | $ArrayBufferView | ReadableStream;
^^^^^^^^^^^ [5]
<BUILTINS>/core.js:2084:20
2084| type $TypedArray = $TypedArrayNumber | BigInt64Array | BigUint64Array;
<BUILTINS>/core.js:2090:20
2090| type $TypedArray = $TypedArrayNumber | BigInt64Array | BigUint64Array;
^^^^^^^^^^^^^^^^^ [6]
<BUILTINS>/core.js:2084:40
2084| type $TypedArray = $TypedArrayNumber | BigInt64Array | BigUint64Array;
<BUILTINS>/core.js:2090:40
2090| type $TypedArray = $TypedArrayNumber | BigInt64Array | BigUint64Array;
^^^^^^^^^^^^^ [7]
<BUILTINS>/core.js:2084:56
2084| type $TypedArray = $TypedArrayNumber | BigInt64Array | BigUint64Array;
<BUILTINS>/core.js:2090:56
2090| type $TypedArray = $TypedArrayNumber | BigInt64Array | BigUint64Array;
^^^^^^^^^^^^^^ [8]
<BUILTINS>/core.js:2080:39
2080| type $ArrayBufferView = $TypedArray | DataView;
<BUILTINS>/core.js:2086:39
2086| type $ArrayBufferView = $TypedArray | DataView;
^^^^^^^^ [9]
<BUILTINS>/bom.js:1637:95
1637| type BodyInit = string | URLSearchParams | FormData | Blob | ArrayBuffer | $ArrayBufferView | ReadableStream;
Expand Down
4 changes: 2 additions & 2 deletions tests/get_def_enums/get_def_enums.exp
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ library.js:4:3,4:5

main.js:27:13
Flags:
[LIB] core.js:2639:3,2639:6
[LIB] core.js:2645:3,2645:6

main.js:30:13
Flags:
[LIB] core.js:2641:3,2641:9
[LIB] core.js:2647:3,2647:9

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

References:
<BUILTINS>/core.js:2814:62
2814| type Pick<O: interface {}, Keys: $Keys<O>> = {[key in Keys]: O[key]};
<BUILTINS>/core.js:2822:62
2822| type Pick<O: interface {}, Keys: $Keys<O>> = {[key in Keys]: O[key]};
^^^^^^ [1]
pick.js:9:16
9| (pickedO1.bar: string); // ERROR bar is optional
Expand Down
16 changes: 8 additions & 8 deletions tests/meta_property/meta_property.exp
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ Cannot cast `import.meta` to number literal `1` because `Import$Meta` [1] is inc
^^^^^^^^^^^

References:
<BUILTINS>/core.js:2749:20
<BUILTINS>/core.js:2755:20
v
2749| type Import$Meta = {
2750| [string]: mixed,
2751| url?: string,
2752| ...
2753| };
2755| type Import$Meta = {
2756| [string]: mixed,
2757| url?: string,
2758| ...
2759| };
^ [1]
import_meta.js:5:15
5| (import.meta: 1); // Error
Expand All @@ -31,8 +31,8 @@ Cannot cast `import.meta.XXX` to number literal `1` because mixed [1] is incompa
^^^^^^^^^^^^^^^

References:
<BUILTINS>/core.js:2750:13
2750| [string]: mixed,
<BUILTINS>/core.js:2756:13
2756| [string]: mixed,
^^^^^ [1]
import_meta.js:6:19
6| (import.meta.XXX: 1); // Error
Expand Down
Loading

0 comments on commit 35790c5

Please sign in to comment.