From 51d71f6a66106ebd4a555f8ed6255b94895b65e5 Mon Sep 17 00:00:00 2001 From: Nicolas DUBIEN Date: Tue, 18 Feb 2020 08:32:49 +0100 Subject: [PATCH 1/3] Better typings for oneof and frequency Related to #546 --- src/check/arbitrary/FrequencyArbitrary.ts | 6 ++++-- src/check/arbitrary/OneOfArbitrary.ts | 6 ++++-- test/type/index.test-d.ts | 9 ++------- 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/src/check/arbitrary/FrequencyArbitrary.ts b/src/check/arbitrary/FrequencyArbitrary.ts index 0f7567a7a32..3b612e1c566 100644 --- a/src/check/arbitrary/FrequencyArbitrary.ts +++ b/src/check/arbitrary/FrequencyArbitrary.ts @@ -40,11 +40,13 @@ class FrequencyArbitrary extends Arbitrary { * * @param warbs (Arbitrary, weight)s that might be called to produce a value */ -function frequency(...warbs: WeightedArbitrary[]): Arbitrary { +function frequency[]>( + ...warbs: Ts +): Arbitrary<{ [K in keyof Ts]: Ts[K] extends WeightedArbitrary ? U : never }[number]> { if (warbs.length === 0) { throw new Error('fc.frequency expects at least one parameter'); } - return new FrequencyArbitrary([...warbs]); + return new FrequencyArbitrary([...warbs]) as any; } export { frequency }; diff --git a/src/check/arbitrary/OneOfArbitrary.ts b/src/check/arbitrary/OneOfArbitrary.ts index fa14f74877b..9236e9210d9 100644 --- a/src/check/arbitrary/OneOfArbitrary.ts +++ b/src/check/arbitrary/OneOfArbitrary.ts @@ -23,11 +23,13 @@ class OneOfArbitrary extends Arbitrary { * * @param arbs Arbitraries that might be called to produce a value */ -function oneof(...arbs: Arbitrary[]): Arbitrary { +function oneof[]>( + ...arbs: Ts +): Arbitrary<{ [K in keyof Ts]: Ts[K] extends Arbitrary ? U : never }[number]> { if (arbs.length === 0) { throw new Error('fc.oneof expects at least one parameter'); } - return new OneOfArbitrary([...arbs]); + return new OneOfArbitrary([...arbs]) as any; } export { oneof }; diff --git a/test/type/index.test-d.ts b/test/type/index.test-d.ts index 3b5c0af2d47..c555bab7ed5 100644 --- a/test/type/index.test-d.ts +++ b/test/type/index.test-d.ts @@ -55,8 +55,7 @@ expectError(fc.tuple(fc.nat(), '')); // oneof arbitrary expectType>(fc.oneof(fc.string(), fc.fullUnicodeString())); -expectType>(fc.oneof(fc.string() as fc.Arbitrary, fc.nat())); -expectError(fc.oneof(fc.string(), fc.nat())); // TODO Typings should be improved +expectType>(fc.oneof(fc.string(), fc.nat())); expectError(fc.oneof(fc.string(), '1')); // frequency arbitrary @@ -64,12 +63,8 @@ expectType>( fc.frequency({ arbitrary: fc.string(), weight: 1 }, { arbitrary: fc.fullUnicodeString(), weight: 1 }) ); expectType>( - fc.frequency( - { arbitrary: fc.string() as fc.Arbitrary, weight: 1 }, - { arbitrary: fc.nat(), weight: 1 } - ) + fc.frequency({ arbitrary: fc.string(), weight: 1 }, { arbitrary: fc.nat(), weight: 1 }) ); -expectError(fc.frequency({ arbitrary: fc.string(), weight: 1 }, { arbitrary: fc.nat(), weight: 1 })); // TODO Typings should be improved expectError(fc.frequency({ arbitrary: fc.string(), weight: 1 }, { arbitrary: '1', weight: 1 })); // option arbitrary From 02d1af048d575841796085b986eea152ca03af3e Mon Sep 17 00:00:00 2001 From: Nicolas DUBIEN Date: Mon, 2 Mar 2020 23:24:57 +0100 Subject: [PATCH 2/3] Better internal typings (no any cast) --- src/check/arbitrary/FrequencyArbitrary.ts | 10 +++++++++- src/check/arbitrary/OneOfArbitrary.ts | 10 +++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/check/arbitrary/FrequencyArbitrary.ts b/src/check/arbitrary/FrequencyArbitrary.ts index 3b612e1c566..8a165900a9d 100644 --- a/src/check/arbitrary/FrequencyArbitrary.ts +++ b/src/check/arbitrary/FrequencyArbitrary.ts @@ -33,6 +33,14 @@ class FrequencyArbitrary extends Arbitrary { } } +/** + * @hidden + * @internal + */ +type InferArbitraryType[]> = { + [K in keyof Ts]: Ts[K] extends WeightedArbitrary ? U : never +}[number]; + /** * For one of the values generated by `...warbs` - the probability of selecting the ith warb is of `warb[i].weight / sum(warb[j].weight)` * @@ -46,7 +54,7 @@ function frequency[]>( if (warbs.length === 0) { throw new Error('fc.frequency expects at least one parameter'); } - return new FrequencyArbitrary([...warbs]) as any; + return new FrequencyArbitrary>([...warbs] as WeightedArbitrary>[]); } export { frequency }; diff --git a/src/check/arbitrary/OneOfArbitrary.ts b/src/check/arbitrary/OneOfArbitrary.ts index 9236e9210d9..1ac438e2563 100644 --- a/src/check/arbitrary/OneOfArbitrary.ts +++ b/src/check/arbitrary/OneOfArbitrary.ts @@ -16,6 +16,14 @@ class OneOfArbitrary extends Arbitrary { } } +/** + * @hidden + * @internal + */ +type InferArbitraryType[]> = { + [K in keyof Ts]: Ts[K] extends Arbitrary ? U : never +}[number]; + /** * For one of the values generated by `...arbs` - with all `...arbs` equiprobable * @@ -29,7 +37,7 @@ function oneof[]>( if (arbs.length === 0) { throw new Error('fc.oneof expects at least one parameter'); } - return new OneOfArbitrary([...arbs]) as any; + return new OneOfArbitrary>([...arbs] as Arbitrary>[]); } export { oneof }; From 643318819d39781c1d0d70974d274a3bda208fe1 Mon Sep 17 00:00:00 2001 From: Nicolas DUBIEN Date: Mon, 2 Mar 2020 23:34:04 +0100 Subject: [PATCH 3/3] Better naming of InferArbitraryType --- src/check/arbitrary/FrequencyArbitrary.ts | 14 +++++++------- src/check/arbitrary/OneOfArbitrary.ts | 12 +++++------- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/src/check/arbitrary/FrequencyArbitrary.ts b/src/check/arbitrary/FrequencyArbitrary.ts index 8a165900a9d..19df15426d3 100644 --- a/src/check/arbitrary/FrequencyArbitrary.ts +++ b/src/check/arbitrary/FrequencyArbitrary.ts @@ -34,10 +34,10 @@ class FrequencyArbitrary extends Arbitrary { } /** - * @hidden - * @internal + * Infer the type of the Arbitrary produced by oneof + * given the type of the source arbitraries */ -type InferArbitraryType[]> = { +type FrequencyArbitraryType[]> = { [K in keyof Ts]: Ts[K] extends WeightedArbitrary ? U : never }[number]; @@ -48,13 +48,13 @@ type InferArbitraryType[]> = { * * @param warbs (Arbitrary, weight)s that might be called to produce a value */ -function frequency[]>( - ...warbs: Ts -): Arbitrary<{ [K in keyof Ts]: Ts[K] extends WeightedArbitrary ? U : never }[number]> { +function frequency[]>(...warbs: Ts): Arbitrary> { if (warbs.length === 0) { throw new Error('fc.frequency expects at least one parameter'); } - return new FrequencyArbitrary>([...warbs] as WeightedArbitrary>[]); + return new FrequencyArbitrary>([...warbs] as WeightedArbitrary< + FrequencyArbitraryType + >[]); } export { frequency }; diff --git a/src/check/arbitrary/OneOfArbitrary.ts b/src/check/arbitrary/OneOfArbitrary.ts index 1ac438e2563..2979ef56b6e 100644 --- a/src/check/arbitrary/OneOfArbitrary.ts +++ b/src/check/arbitrary/OneOfArbitrary.ts @@ -17,10 +17,10 @@ class OneOfArbitrary extends Arbitrary { } /** - * @hidden - * @internal + * Infer the type of the Arbitrary produced by oneof + * given the type of the source arbitraries */ -type InferArbitraryType[]> = { +type OneOfArbitraryType[]> = { [K in keyof Ts]: Ts[K] extends Arbitrary ? U : never }[number]; @@ -31,13 +31,11 @@ type InferArbitraryType[]> = { * * @param arbs Arbitraries that might be called to produce a value */ -function oneof[]>( - ...arbs: Ts -): Arbitrary<{ [K in keyof Ts]: Ts[K] extends Arbitrary ? U : never }[number]> { +function oneof[]>(...arbs: Ts): Arbitrary> { if (arbs.length === 0) { throw new Error('fc.oneof expects at least one parameter'); } - return new OneOfArbitrary>([...arbs] as Arbitrary>[]); + return new OneOfArbitrary>([...arbs] as Arbitrary>[]); } export { oneof };