Skip to content

Commit bc9d806

Browse files
committed
Apply fix, explicitly annotate variance of array subtype in api, accept baselines
1 parent ec6f6ee commit bc9d806

8 files changed

+264
-7
lines changed

src/compiler/checker.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -22914,7 +22914,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2291422914
// of the much more expensive N * M comparison matrix we explore below. We erase type parameters
2291522915
// as they are known to always be the same.
2291622916
for (let i = 0; i < targetSignatures.length; i++) {
22917-
const related = signatureRelatedTo(sourceSignatures[i], targetSignatures[i], /*erase*/ true, reportErrors, intersectionState, incompatibleReporter(sourceSignatures[i], targetSignatures[i]));
22917+
const related = signatureRelatedTo(sourceSignatures[i], targetSignatures[i], /*erase*/ !inVarianceComputation, reportErrors, intersectionState, incompatibleReporter(sourceSignatures[i], targetSignatures[i]));
2291822918
if (!related) {
2291922919
return Ternary.False;
2292022920
}

src/compiler/types.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1540,7 +1540,7 @@ export interface MutableNodeArray<T extends Node> extends Array<T>, TextRange {
15401540
/** @internal */ transformFlags: TransformFlags; // Flags for transforms, possibly undefined
15411541
}
15421542

1543-
export interface NodeArray<T extends Node> extends ReadonlyArray<T>, ReadonlyTextRange {
1543+
export interface NodeArray<out T extends Node> extends ReadonlyArray<T>, ReadonlyTextRange {
15441544
readonly hasTrailingComma: boolean;
15451545
/** @internal */ transformFlags: TransformFlags; // Flags for transforms, possibly undefined
15461546
}

tests/baselines/reference/api/typescript.d.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -4889,7 +4889,7 @@ declare namespace ts {
48894889
type HasExpressionInitializer = VariableDeclaration | ParameterDeclaration | BindingElement | PropertyDeclaration | PropertyAssignment | EnumMember;
48904890
type HasDecorators = ParameterDeclaration | PropertyDeclaration | MethodDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | ClassExpression | ClassDeclaration;
48914891
type HasModifiers = TypeParameterDeclaration | ParameterDeclaration | ConstructorTypeNode | PropertySignature | PropertyDeclaration | MethodSignature | MethodDeclaration | ConstructorDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | IndexSignatureDeclaration | FunctionExpression | ArrowFunction | ClassExpression | VariableStatement | FunctionDeclaration | ClassDeclaration | InterfaceDeclaration | TypeAliasDeclaration | EnumDeclaration | ModuleDeclaration | ImportEqualsDeclaration | ImportDeclaration | ExportAssignment | ExportDeclaration;
4892-
interface NodeArray<T extends Node> extends ReadonlyArray<T>, ReadonlyTextRange {
4892+
interface NodeArray<out T extends Node> extends ReadonlyArray<T>, ReadonlyTextRange {
48934893
readonly hasTrailingComma: boolean;
48944894
}
48954895
interface Token<TKind extends SyntaxKind> extends Node {

tests/baselines/reference/complexRecursiveCollections.errors.txt

+18-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
immutable.ts(305,22): error TS2430: Interface 'Set<T>' incorrectly extends interface 'Seq<never, T>'.
2+
The types of 'map(...).filter(...).concat(...).toMap().toSeq().toOrderedMap().keySeq().toMap().mapKeys(...).toSeq().toOrderedMap().toSet().union' are incompatible between these types.
3+
Type '(...collections: (never[] | Collection<any, never>)[]) => Set<never>' is not assignable to type '(...collections: (any[] | Collection<any, any>)[]) => Set<any>'.
4+
Types of parameters 'collections' and 'collections' are incompatible.
5+
Type 'any[] | Collection<any, any>' is not assignable to type 'never[] | Collection<any, never>'.
6+
Type 'any[]' is not assignable to type 'never[] | Collection<any, never>'.
7+
Type 'any[]' is not assignable to type 'never[]'.
8+
Type 'any' is not assignable to type 'never'.
19
immutable.ts(341,22): error TS2430: Interface 'Keyed<K, V>' incorrectly extends interface 'Collection<K, V>'.
210
The types returned by 'toSeq()' are incompatible between these types.
311
Type 'Keyed<K, V>' is not assignable to type 'this'.
@@ -33,7 +41,7 @@ immutable.ts(391,22): error TS2430: Interface 'Set<T>' incorrectly extends inter
3341
flatMap<M>(mapper: (value: T, key: void, iter: this) => Ara<M>, context?: any): N2<M>;
3442
toSeq(): N2<T>;
3543
}
36-
==== immutable.ts (3 errors) ====
44+
==== immutable.ts (4 errors) ====
3745
// Test that complex recursive collections can pass the `extends` assignability check without
3846
// running out of memory. This bug was exposed in Typescript 2.4 when more generic signatures
3947
// started being checked.
@@ -339,6 +347,15 @@ immutable.ts(391,22): error TS2430: Interface 'Set<T>' incorrectly extends inter
339347
export function Set<T>(): Seq.Set<T>;
340348
export function Set<T>(collection: Iterable<T>): Seq.Set<T>;
341349
export interface Set<T> extends Seq<never, T>, Collection.Set<T> {
350+
~~~
351+
!!! error TS2430: Interface 'Set<T>' incorrectly extends interface 'Seq<never, T>'.
352+
!!! error TS2430: The types of 'map(...).filter(...).concat(...).toMap().toSeq().toOrderedMap().keySeq().toMap().mapKeys(...).toSeq().toOrderedMap().toSet().union' are incompatible between these types.
353+
!!! error TS2430: Type '(...collections: (never[] | Collection<any, never>)[]) => Set<never>' is not assignable to type '(...collections: (any[] | Collection<any, any>)[]) => Set<any>'.
354+
!!! error TS2430: Types of parameters 'collections' and 'collections' are incompatible.
355+
!!! error TS2430: Type 'any[] | Collection<any, any>' is not assignable to type 'never[] | Collection<any, never>'.
356+
!!! error TS2430: Type 'any[]' is not assignable to type 'never[] | Collection<any, never>'.
357+
!!! error TS2430: Type 'any[]' is not assignable to type 'never[]'.
358+
!!! error TS2430: Type 'any' is not assignable to type 'never'.
342359
toJS(): Array<any>;
343360
toJSON(): Array<T>;
344361
toSeq(): this;

tests/baselines/reference/complexRecursiveCollections.types

+1-1
Original file line numberDiff line numberDiff line change
@@ -1139,7 +1139,7 @@ declare module Immutable {
11391139
>Seq : typeof Seq
11401140

11411141
function isSeq(maybeSeq: any): maybeSeq is Seq.Indexed<any> | Seq.Keyed<any, any>;
1142-
>isSeq : (maybeSeq: any) => maybeSeq is Indexed<any> | Keyed<any, any>
1142+
>isSeq : (maybeSeq: any) => maybeSeq is Keyed<any, any> | Indexed<any>
11431143
>maybeSeq : any
11441144
>Seq : any
11451145
>Seq : any

tests/baselines/reference/conditionalTypes2.errors.txt

+18-1
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,16 @@ conditionalTypes2.ts(74,12): error TS2345: Argument of type 'Extract<T, Foo & Ba
3333
conditionalTypes2.ts(75,12): error TS2345: Argument of type 'Extract2<T, Foo, Bar>' is not assignable to parameter of type '{ foo: string; bat: string; }'.
3434
Type 'T extends Bar ? T : never' is not assignable to type '{ foo: string; bat: string; }'.
3535
Property 'bat' is missing in type 'Bar & Foo' but required in type '{ foo: string; bat: string; }'.
36+
conditionalTypes2.ts(91,5): error TS2416: Property 'tail' in type 'Vector<T>' is not assignable to the same property in base type 'Seq<T>'.
37+
Type '() => Opt<Vector<T>>' is not assignable to type '() => Opt<Seq<T>>'.
38+
Call signature return types 'Opt<Vector<T>>' and 'Opt<Seq<T>>' are incompatible.
39+
The types returned by 'toVector().tail().toVector()' are incompatible between these types.
40+
Type 'Vector<Vector<Vector<T>>>' is not assignable to type 'Vector<Vector<Seq<T>>>'.
41+
Type 'Vector<Seq<T>>' is not assignable to type 'Vector<Vector<T>>'.
42+
conditionalTypes2.ts(94,5): error TS2394: This overload signature is not compatible with its implementation signature.
3643

3744

38-
==== conditionalTypes2.ts (7 errors) ====
45+
==== conditionalTypes2.ts (9 errors) ====
3946
interface Covariant<T> {
4047
foo: T extends string ? T : number;
4148
}
@@ -177,9 +184,19 @@ conditionalTypes2.ts(75,12): error TS2345: Argument of type 'Extract2<T, Foo, Ba
177184

178185
class Vector<T> implements Seq<T> {
179186
tail(): Opt<Vector<T>> {
187+
~~~~
188+
!!! error TS2416: Property 'tail' in type 'Vector<T>' is not assignable to the same property in base type 'Seq<T>'.
189+
!!! error TS2416: Type '() => Opt<Vector<T>>' is not assignable to type '() => Opt<Seq<T>>'.
190+
!!! error TS2416: Call signature return types 'Opt<Vector<T>>' and 'Opt<Seq<T>>' are incompatible.
191+
!!! error TS2416: The types returned by 'toVector().tail().toVector()' are incompatible between these types.
192+
!!! error TS2416: Type 'Vector<Vector<Vector<T>>>' is not assignable to type 'Vector<Vector<Seq<T>>>'.
193+
!!! error TS2416: Type 'Vector<Seq<T>>' is not assignable to type 'Vector<Vector<T>>'.
180194
return <any>undefined;
181195
}
182196
partition2<U extends T>(predicate:(v:T)=>v is U): [Vector<U>,Vector<Exclude<T, U>>];
197+
~~~~~~~~~~
198+
!!! error TS2394: This overload signature is not compatible with its implementation signature.
199+
!!! related TS2750 conditionalTypes2.ts:96:5: The implementation signature is declared here.
183200
partition2(predicate:(x:T)=>boolean): [Vector<T>,Vector<T>];
184201
partition2<U extends T>(predicate:(v:T)=>boolean): [Vector<U>,Vector<any>] {
185202
return <any>undefined;

tests/baselines/reference/genericSignaturesConstrainedToDifferingGenericsNotCompatible.errors.txt

+17-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
genericSignaturesConstrainedToDifferingGenericsNotCompatible.ts(9,5): error TS2322: Type 'Fn<T2>' is not assignable to type 'Fn<T1>'.
2+
Type 'T1' is not assignable to type 'T2'.
3+
'T2' could be instantiated with an arbitrary type which could be unrelated to 'T1'.
4+
genericSignaturesConstrainedToDifferingGenericsNotCompatible.ts(10,5): error TS2322: Type 'Fn<T1>' is not assignable to type 'Fn<T2>'.
5+
Type 'T2' is not assignable to type 'T1'.
6+
'T1' could be instantiated with an arbitrary type which could be unrelated to 'T2'.
17
genericSignaturesConstrainedToDifferingGenericsNotCompatible.ts(12,5): error TS2322: Type 'Concrete2' is not assignable to type 'Concrete1'.
28
Types of parameters 'x' and 'x' are incompatible.
39
Type 'U' is not assignable to type 'string'.
@@ -16,7 +22,7 @@ genericSignaturesConstrainedToDifferingGenericsNotCompatible.ts(16,5): error TS2
1622
'T1' could be instantiated with an arbitrary type which could be unrelated to 'U'.
1723

1824

19-
==== genericSignaturesConstrainedToDifferingGenericsNotCompatible.ts (4 errors) ====
25+
==== genericSignaturesConstrainedToDifferingGenericsNotCompatible.ts (6 errors) ====
2026
type Fn<T> = <U extends T>(x: U) => U;
2127

2228
type Concrete1 = <U extends number>(x: U) => U;
@@ -26,7 +32,17 @@ genericSignaturesConstrainedToDifferingGenericsNotCompatible.ts(16,5): error TS2
2632
// every single one of these assignments should error
2733

2834
t1 = t2;
35+
~~
36+
!!! error TS2322: Type 'Fn<T2>' is not assignable to type 'Fn<T1>'.
37+
!!! error TS2322: Type 'T1' is not assignable to type 'T2'.
38+
!!! error TS2322: 'T2' could be instantiated with an arbitrary type which could be unrelated to 'T1'.
39+
!!! related TS2208 genericSignaturesConstrainedToDifferingGenericsNotCompatible.ts:6:12: This type parameter might need an `extends T2` constraint.
2940
t2 = t1;
41+
~~
42+
!!! error TS2322: Type 'Fn<T1>' is not assignable to type 'Fn<T2>'.
43+
!!! error TS2322: Type 'T2' is not assignable to type 'T1'.
44+
!!! error TS2322: 'T1' could be instantiated with an arbitrary type which could be unrelated to 'T2'.
45+
!!! related TS2208 genericSignaturesConstrainedToDifferingGenericsNotCompatible.ts:6:16: This type parameter might need an `extends T1` constraint.
3046

3147
c1 = c2;
3248
~~
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,207 @@
1+
styledComponentsInstantiaionLimitNotReached.ts(171,8): error TS2615: Type of property 'propTypes' circularly references itself in mapped type 'ForwardRefExoticBase<Omit<Omit<any, any> & Partial<Pick<any, any>>, "theme"> & { theme?: any; } & WithChildrenIfReactComponentClass<StyledComponentInnerComponent<WithC>>>'.
2+
3+
4+
==== styledComponentsInstantiaionLimitNotReached.ts (1 errors) ====
5+
/// <reference path="/.lib/react16.d.ts" />
6+
import * as React from "react";
7+
8+
interface REACT_STATICS {
9+
childContextTypes: true;
10+
contextType: true;
11+
contextTypes: true;
12+
defaultProps: true;
13+
displayName: true;
14+
getDefaultProps: true;
15+
getDerivedStateFromError: true;
16+
getDerivedStateFromProps: true;
17+
mixins: true;
18+
propTypes: true;
19+
type: true;
20+
}
21+
22+
interface KNOWN_STATICS {
23+
name: true;
24+
length: true;
25+
prototype: true;
26+
caller: true;
27+
callee: true;
28+
arguments: true;
29+
arity: true;
30+
}
31+
32+
interface MEMO_STATICS {
33+
'$$typeof': true;
34+
compare: true;
35+
defaultProps: true;
36+
displayName: true;
37+
propTypes: true;
38+
type: true;
39+
}
40+
41+
interface FORWARD_REF_STATICS {
42+
'$$typeof': true;
43+
render: true;
44+
defaultProps: true;
45+
displayName: true;
46+
propTypes: true;
47+
}
48+
49+
50+
type NonReactStatics<
51+
S extends React.ComponentType<any>,
52+
C extends {
53+
[key: string]: true
54+
} = {}
55+
> = {
56+
[key in Exclude<
57+
keyof S,
58+
S extends React.MemoExoticComponent<any>
59+
? keyof MEMO_STATICS | keyof C
60+
: S extends React.ForwardRefExoticComponent<any>
61+
? keyof FORWARD_REF_STATICS | keyof C
62+
: keyof REACT_STATICS | keyof KNOWN_STATICS | keyof C
63+
>]: S[key]
64+
};
65+
66+
export type AnyStyledComponent = StyledComponent<any, any, any, any> | StyledComponent<any, any, any>;
67+
export type StyledComponent<
68+
C extends keyof JSX.IntrinsicElements | React.ComponentType<any>,
69+
T extends object,
70+
O extends object = {},
71+
A extends keyof any = never
72+
> = // the "string" allows this to be used as an object key
73+
// I really want to avoid this if possible but it's the only way to use nesting with object styles...
74+
string &
75+
StyledComponentBase<C, T, O, A> &
76+
NonReactStatics<C extends React.ComponentType<any> ? C : never>;
77+
78+
export type StyledComponentProps<
79+
// The Component from whose props are derived
80+
C extends string | React.ComponentType<any>,
81+
// The Theme from the current context
82+
T extends object,
83+
// The other props added by the template
84+
O extends object,
85+
// The props that are made optional by .attrs
86+
A extends keyof any
87+
> =
88+
// Distribute O if O is a union type
89+
O extends object
90+
? WithOptionalTheme<
91+
Omit<
92+
ReactDefaultizedProps<
93+
C,
94+
React.ComponentPropsWithRef<
95+
C extends IntrinsicElementsKeys | React.ComponentType<any> ? C : never
96+
>
97+
> &
98+
O,
99+
A
100+
> &
101+
Partial<
102+
Pick<
103+
React.ComponentPropsWithRef<
104+
C extends IntrinsicElementsKeys | React.ComponentType<any> ? C : never
105+
> &
106+
O,
107+
A
108+
>
109+
>,
110+
T
111+
> &
112+
WithChildrenIfReactComponentClass<C>
113+
: never;
114+
115+
type Defaultize<P, D> = P extends any
116+
? string extends keyof P
117+
? P
118+
: Pick<P, Exclude<keyof P, keyof D>> &
119+
Partial<Pick<P, Extract<keyof P, keyof D>>> &
120+
Partial<Pick<D, Exclude<keyof D, keyof P>>>
121+
: never;
122+
123+
type ReactDefaultizedProps<C, P> = C extends { defaultProps: infer D } ? Defaultize<P, D> : P;
124+
125+
type WithChildrenIfReactComponentClass<C extends string | React.ComponentType<any>> = C extends React.ComponentClass<
126+
any
127+
>
128+
? { children?: React.ReactNode }
129+
: {};
130+
export type IntrinsicElementsKeys = keyof JSX.IntrinsicElements;
131+
type WithOptionalTheme<P extends { theme?: T }, T> = Omit<P, 'theme'> & {
132+
theme?: T;
133+
};
134+
135+
type ForwardRefExoticBase<P> = Pick<React.ForwardRefExoticComponent<P>, keyof React.ForwardRefExoticComponent<any>>;
136+
137+
type StyledComponentPropsWithAs<
138+
C extends string | React.ComponentType<any>,
139+
T extends object,
140+
O extends object,
141+
A extends keyof any,
142+
F extends string | React.ComponentType<any> = C
143+
> = StyledComponentProps<C, T, O, A> & { as?: C; forwardedAs?: F };
144+
145+
export type StyledComponentInnerOtherProps<C extends AnyStyledComponent> = C extends StyledComponent<
146+
any,
147+
any,
148+
infer O,
149+
any
150+
>
151+
? O
152+
: C extends StyledComponent<any, any, infer O>
153+
? O
154+
: never;
155+
export type StyledComponentInnerAttrs<C extends AnyStyledComponent> = C extends StyledComponent<any, any, any, infer A>
156+
? A
157+
: never;
158+
159+
export interface StyledComponentBase<
160+
C extends string | React.ComponentType<any>,
161+
T extends object,
162+
O extends object = {},
163+
A extends keyof any = never
164+
> extends ForwardRefExoticBase<StyledComponentProps<C, T, O, A>> {
165+
// add our own fake call signature to implement the polymorphic 'as' prop
166+
(props: StyledComponentProps<C, T, O, A> & { as?: never; forwardedAs?: never }): React.ReactElement<
167+
StyledComponentProps<C, T, O, A>
168+
>;
169+
<AsC extends string | React.ComponentType<any> = C, FAsC extends string | React.ComponentType<any> = AsC>(
170+
props: StyledComponentPropsWithAs<AsC, T, O, A, FAsC>,
171+
): React.ReactElement<StyledComponentPropsWithAs<AsC, T, O, A, FAsC>>;
172+
173+
withComponent<WithC extends AnyStyledComponent>(
174+
component: WithC,
175+
): StyledComponent<
176+
~~~~~~~~~~~~~~~~
177+
StyledComponentInnerComponent<WithC>,
178+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
179+
T,
180+
~~~~~~~~~~
181+
O & StyledComponentInnerOtherProps<WithC>,
182+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
183+
A | StyledComponentInnerAttrs<WithC>
184+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
185+
>;
186+
~~~~~
187+
!!! error TS2615: Type of property 'propTypes' circularly references itself in mapped type 'ForwardRefExoticBase<Omit<Omit<any, any> & Partial<Pick<any, any>>, "theme"> & { theme?: any; } & WithChildrenIfReactComponentClass<StyledComponentInnerComponent<WithC>>>'.
188+
withComponent<WithC extends keyof JSX.IntrinsicElements | React.ComponentType<any>>(
189+
component: WithC,
190+
): StyledComponent<WithC, T, O, A>;
191+
}
192+
193+
export type StyledComponentInnerComponent<C extends React.ComponentType<any>> = C extends StyledComponent<
194+
infer I,
195+
any,
196+
any,
197+
any
198+
>
199+
? I
200+
: C extends StyledComponent<infer I, any, any>
201+
? I
202+
: C;
203+
export type StyledComponentPropsWithRef<
204+
C extends keyof JSX.IntrinsicElements | React.ComponentType<any>
205+
> = C extends AnyStyledComponent
206+
? React.ComponentPropsWithRef<StyledComponentInnerComponent<C>> // shouldn't have an instantiation limit error
207+
: React.ComponentPropsWithRef<C>;

0 commit comments

Comments
 (0)