Skip to content

Commit eb87036

Browse files
committed
Mapped type support for array subtypes, like microsoft#26063
1 parent 7726464 commit eb87036

8 files changed

+114
-32
lines changed

src/compiler/checker.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -13589,8 +13589,8 @@ namespace ts {
1358913589
return mapType(mappedTypeVariable, t => {
1359013590
if (t.flags & (TypeFlags.AnyOrUnknown | TypeFlags.InstantiableNonPrimitive | TypeFlags.Object | TypeFlags.Intersection) && t !== wildcardType && t !== errorType) {
1359113591
const replacementMapper = createReplacementMapper(typeVariable, t, mapper);
13592-
return isArrayType(t) ? instantiateMappedArrayType(t, type, replacementMapper) :
13593-
isTupleType(t) ? instantiateMappedTupleType(t, type, replacementMapper) :
13592+
return isTupleType(t) ? instantiateMappedTupleType(t, type, replacementMapper) :
13593+
t.flags & (TypeFlags.Object | TypeFlags.Intersection) && isArrayLikeType(t) ? instantiateMappedArrayType(t, type, replacementMapper) :
1359413594
instantiateAnonymousType(type, replacementMapper);
1359513595
}
1359613596
return t;

tests/baselines/reference/circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.errors.txt

+20-11
Large diffs are not rendered by default.

tests/baselines/reference/keyofAndIndexedAccess2.errors.txt

+5-1
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,10 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts(67,3): error TS232
2626
tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts(68,3): error TS2322: Type '123' is not assignable to type 'T[K]'.
2727
tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts(108,5): error TS2322: Type '123' is not assignable to type 'Type[K]'.
2828
Type '123' is not assignable to type 'never'.
29+
tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts(115,21): error TS2313: Type parameter 'Q' has a circular constraint.
2930

3031

31-
==== tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts (23 errors) ====
32+
==== tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts (24 errors) ====
3233
function f1(obj: { a: number, b: 0 | 1, c: string }, k0: 'a', k1: 'a' | 'b', k2: 'a' | 'b' | 'c') {
3334
obj[k0] = 1;
3435
obj[k0] = 2;
@@ -195,6 +196,9 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts(108,5): error TS23
195196
type StrictExtract<T, U> = T extends U ? U extends T ? T : never : never;
196197
type StrictExclude<T, U> = T extends StrictExtract<T, U> ? never : T;
197198
type A<T> = { [Q in { [P in keyof T]: P; }[keyof T]]: T[Q]; };
199+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
200+
!!! error TS2313: Type parameter 'Q' has a circular constraint.
201+
!!! related TS2751 tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts:116:36: Circularity originates in type at this location.
198202
type B<T, V> = A<{ [Q in keyof T]: StrictExclude<B<T[Q], V>, {}>; }>;
199203

200204
// Repros from #30938

tests/baselines/reference/keyofAndIndexedAccess2.types

+1-1
Original file line numberDiff line numberDiff line change
@@ -435,7 +435,7 @@ type A<T> = { [Q in { [P in keyof T]: P; }[keyof T]]: T[Q]; };
435435
>A : A<T>
436436

437437
type B<T, V> = A<{ [Q in keyof T]: StrictExclude<B<T[Q], V>, {}>; }>;
438-
>B : A<{ [Q in keyof T]: StrictExclude<A<{ [Q in keyof T[Q]]: StrictExclude<A<{ [Q in keyof T[Q][Q]]: StrictExclude<A<{ [Q in keyof T[Q][Q][Q]]: StrictExclude<A<{ [Q in keyof T[Q][Q][Q][Q]]: StrictExclude<A<{ [Q in keyof T[Q][Q][Q][Q][Q]]: StrictExclude<A<{ [Q in keyof T[Q][Q][Q][Q][Q][Q]]: StrictExclude<A<{ [Q in keyof T[Q][Q][Q][Q][Q][Q][Q]]: StrictExclude<A<{ [Q in keyof T[Q][Q][Q][Q][Q][Q][Q][Q]]: StrictExclude<A<{ [Q in keyof T[Q][Q][Q][Q][Q][Q][Q][Q][Q]]: StrictExclude<A<{ [Q in keyof T[Q][Q][Q][Q][Q][Q][Q][Q][Q][Q]]: StrictExclude<A<any>, {}>; }>, {}>; }>, {}>; }>, {}>; }>, {}>; }>, {}>; }>, {}>; }>, {}>; }>, {}>; }>, {}>; }>, {}>; }>
438+
>B : A<{ [Q in keyof T]: never; }>
439439

440440
// Repros from #30938
441441

tests/baselines/reference/ramdaToolsNoInfinite.types

+2-2
Original file line numberDiff line numberDiff line change
@@ -200,14 +200,14 @@ declare namespace Curry {
200200
};
201201

202202
type Gaps<T extends any[]> = CleanedGaps<PartialGaps<T>>;
203-
>Gaps : CleanedGaps<PartialGaps<T>>
203+
>Gaps : NonNullable<PartialGaps<T>[number]>[]
204204

205205
type Curry<F extends ((...args: any) => any)> =
206206
>Curry : Curry<F>
207207
>args : any
208208

209209
<T extends any[]>(...args: Tools.Cast<Tools.Cast<T, Gaps<Parameters<F>>>, any[]>) =>
210-
>args : Tools.Cast<Tools.Cast<T, CleanedGaps<PartialGaps<Parameters<F>>>>, any[]>
210+
>args : Tools.Cast<Tools.Cast<T, NonNullable<PartialGaps<Parameters<F>>[number]>[]>, any[]>
211211
>Tools : any
212212
>Tools : any
213213

tests/baselines/reference/reactReduxLikeDeferredInferenceAllowsAssignment.errors.txt

+20-11
Large diffs are not rendered by default.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
tests/cases/compiler/specedNoStackBlown.ts(7,50): error TS2315: Type 'SpecValue' is not generic.
2+
tests/cases/compiler/specedNoStackBlown.ts(7,84): error TS2315: Type 'SpecValue' is not generic.
3+
tests/cases/compiler/specedNoStackBlown.ts(22,29): error TS2315: Type 'SpecObject' is not generic.
4+
tests/cases/compiler/specedNoStackBlown.ts(25,13): error TS2456: Type alias 'SpecObject' circularly references itself.
5+
tests/cases/compiler/specedNoStackBlown.ts(25,81): error TS2315: Type 'SpecValue' is not generic.
6+
tests/cases/compiler/specedNoStackBlown.ts(27,13): error TS2456: Type alias 'SpecValue' circularly references itself.
7+
tests/cases/compiler/specedNoStackBlown.ts(30,78): error TS2315: Type 'SpecObject' is not generic.
8+
9+
10+
==== tests/cases/compiler/specedNoStackBlown.ts (7 errors) ====
11+
// Type definitions for spected 0.7
12+
// Project: https://github.com/25th-floor/spected
13+
// Definitions by: Benjamin Makus <https://github.com/benneq>
14+
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
15+
// TypeScript Version: 2.8
16+
17+
declare function spected<ROOTINPUT, SPEC extends SpecValue<ROOTINPUT, ROOTINPUT> = SpecValue<ROOTINPUT, ROOTINPUT>>(spec: SPEC, input: ROOTINPUT): Result<ROOTINPUT, SPEC>;
18+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
19+
!!! error TS2315: Type 'SpecValue' is not generic.
20+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
21+
!!! error TS2315: Type 'SpecValue' is not generic.
22+
23+
type Predicate<INPUT, ROOTINPUT> = (value: INPUT, inputs: ROOTINPUT) => boolean;
24+
25+
type ErrorMsg<INPUT> =
26+
| (string | number | boolean | symbol | null | undefined | object)
27+
| ((value: INPUT, field: string) => any);
28+
29+
export type Spec<INPUT, ROOTINPUT = any> = [Predicate<INPUT, ROOTINPUT>, ErrorMsg<INPUT>];
30+
31+
export type SpecArray<INPUT, ROOTINPUT = any> = Array<Spec<INPUT, ROOTINPUT>>;
32+
33+
export type SpecFunction<INPUT, ROOTINPUT = any> = [INPUT] extends [ReadonlyArray<infer U>]
34+
? (value: INPUT) => ReadonlyArray<SpecArray<U, ROOTINPUT>>
35+
: [INPUT] extends [object]
36+
? (value: INPUT) => SpecObject<INPUT, ROOTINPUT>
37+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
38+
!!! error TS2315: Type 'SpecObject' is not generic.
39+
: (value: INPUT) => SpecArray<INPUT, ROOTINPUT>;
40+
41+
export type SpecObject<INPUT, ROOTINPUT = any> = Partial<{[key in keyof INPUT]: SpecValue<INPUT[key], ROOTINPUT>}>;
42+
~~~~~~~~~~
43+
!!! error TS2456: Type alias 'SpecObject' circularly references itself.
44+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
45+
!!! error TS2315: Type 'SpecValue' is not generic.
46+
47+
export type SpecValue<INPUT, ROOTINPUT = any> = [INPUT] extends [ReadonlyArray<any>]
48+
~~~~~~~~~
49+
!!! error TS2456: Type alias 'SpecValue' circularly references itself.
50+
? SpecArray<INPUT, ROOTINPUT> | SpecFunction<INPUT, ROOTINPUT>
51+
: [INPUT] extends [object]
52+
? SpecArray<INPUT, ROOTINPUT> | SpecFunction<INPUT, ROOTINPUT> | SpecObject<INPUT, ROOTINPUT>
53+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
54+
!!! error TS2315: Type 'SpecObject' is not generic.
55+
: SpecArray<INPUT, ROOTINPUT> | SpecFunction<INPUT, ROOTINPUT>;
56+
57+
export type Result<INPUT, SPEC> = {[key in keyof INPUT]: true | any[] | Result<INPUT[key], any>};
58+
59+
export default spected;
60+

tests/baselines/reference/specedNoStackBlown.types

+4-4
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
// TypeScript Version: 2.8
77

88
declare function spected<ROOTINPUT, SPEC extends SpecValue<ROOTINPUT, ROOTINPUT> = SpecValue<ROOTINPUT, ROOTINPUT>>(spec: SPEC, input: ROOTINPUT): Result<ROOTINPUT, SPEC>;
9-
>spected : <ROOTINPUT, SPEC extends SpecValue<ROOTINPUT, ROOTINPUT> = SpecValue<ROOTINPUT, ROOTINPUT>>(spec: SPEC, input: ROOTINPUT) => Result<ROOTINPUT, SPEC>
9+
>spected : <ROOTINPUT, SPEC extends any = any>(spec: SPEC, input: ROOTINPUT) => Result<ROOTINPUT, SPEC>
1010
>spec : SPEC
1111
>input : ROOTINPUT
1212

@@ -45,10 +45,10 @@ export type SpecFunction<INPUT, ROOTINPUT = any> = [INPUT] extends [ReadonlyArra
4545
>value : INPUT
4646

4747
export type SpecObject<INPUT, ROOTINPUT = any> = Partial<{[key in keyof INPUT]: SpecValue<INPUT[key], ROOTINPUT>}>;
48-
>SpecObject : Partial<{ [key in keyof INPUT]: SpecValue<INPUT[key], ROOTINPUT>; }>
48+
>SpecObject : any
4949

5050
export type SpecValue<INPUT, ROOTINPUT = any> = [INPUT] extends [ReadonlyArray<any>]
51-
>SpecValue : SpecValue<INPUT, ROOTINPUT>
51+
>SpecValue : any
5252

5353
? SpecArray<INPUT, ROOTINPUT> | SpecFunction<INPUT, ROOTINPUT>
5454
: [INPUT] extends [object]
@@ -60,5 +60,5 @@ export type Result<INPUT, SPEC> = {[key in keyof INPUT]: true | any[] | Result<I
6060
>true : true
6161

6262
export default spected;
63-
>spected : <ROOTINPUT, SPEC extends SpecValue<ROOTINPUT, ROOTINPUT> = SpecValue<ROOTINPUT, ROOTINPUT>>(spec: SPEC, input: ROOTINPUT) => Result<ROOTINPUT, SPEC>
63+
>spected : <ROOTINPUT, SPEC extends any = any>(spec: SPEC, input: ROOTINPUT) => Result<ROOTINPUT, SPEC>
6464

0 commit comments

Comments
 (0)