Fix react-redux break on DT (#30375)

* Forbid reentrancy in conditional type creation (force deferal on occurance)

* Add repro from react-redux, accept updated baselines
This commit is contained in:
Wesley Wigham 2019-03-13 15:21:46 -07:00 committed by GitHub
parent e42f37fccd
commit 5d08b68122
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 549 additions and 27 deletions

View file

@ -388,7 +388,7 @@ namespace ts {
const intersectionTypes = createMap<IntersectionType>();
const literalTypes = createMap<LiteralType>();
const indexedAccessTypes = createMap<IndexedAccessType>();
const conditionalTypes = createMap<Type>();
const conditionalTypes = createMap<Type | undefined>();
const evolvingArrayTypes: EvolvingArrayType[] = [];
const undefinedProperties = createMap<Symbol>() as UnderscoreEscapedMap<Symbol>;
@ -10138,11 +10138,24 @@ namespace ts {
const trueType = instantiateType(root.trueType, mapper);
const falseType = instantiateType(root.falseType, mapper);
const instantiationId = `${root.isDistributive ? "d" : ""}${getTypeId(checkType)}>${getTypeId(extendsType)}?${getTypeId(trueType)}:${getTypeId(falseType)}`;
const result = conditionalTypes.get(instantiationId);
if (result) {
return result;
if (conditionalTypes.has(instantiationId)) {
const result = conditionalTypes.get(instantiationId);
if (result !== undefined) {
return result;
}
// Somehow the conditional type depends on itself - usually via `infer` types in the `extends` clause
// paired with a (potentially deferred) circularly constrained type.
// The conditional _must_ be deferred.
const deferred = getDeferredConditionalType(root, mapper, /*combinedMapper*/ undefined, checkType, extendsType, trueType, falseType);
conditionalTypes.set(instantiationId, deferred);
return deferred;
}
conditionalTypes.set(instantiationId, undefined);
const newResult = getConditionalTypeWorker(root, mapper, checkType, extendsType, trueType, falseType);
const cachedRecursiveResult = conditionalTypes.get(instantiationId);
if (cachedRecursiveResult) {
return cachedRecursiveResult;
}
conditionalTypes.set(instantiationId, newResult);
return newResult;
}
@ -10206,6 +10219,10 @@ namespace ts {
}
}
// Return a deferred type for a check that is neither definitely true nor definitely false
return getDeferredConditionalType(root, mapper, combinedMapper, checkType, extendsType, trueType, falseType);
}
function getDeferredConditionalType(root: ConditionalRoot, mapper: TypeMapper | undefined, combinedMapper: TypeMapper | undefined, checkType: Type, extendsType: Type, trueType: Type, falseType: Type) {
const erasedCheckType = getActualTypeVariable(checkType);
const result = <ConditionalType>createType(TypeFlags.Conditional);
result.root = root;

View file

@ -4,13 +4,11 @@ tests/cases/conformance/types/specifyingTypes/typeQueries/circularTypeofWithVarO
tests/cases/conformance/types/specifyingTypes/typeQueries/circularTypeofWithVarOrFunc.ts(5,6): error TS2456: Type alias 'typeAlias2' circularly references itself.
tests/cases/conformance/types/specifyingTypes/typeQueries/circularTypeofWithVarOrFunc.ts(7,18): error TS2577: Return type annotation circularly references itself.
tests/cases/conformance/types/specifyingTypes/typeQueries/circularTypeofWithVarOrFunc.ts(9,6): error TS2456: Type alias 'typeAlias3' circularly references itself.
tests/cases/conformance/types/specifyingTypes/typeQueries/circularTypeofWithVarOrFunc.ts(18,6): error TS2456: Type alias 'R' circularly references itself.
tests/cases/conformance/types/specifyingTypes/typeQueries/circularTypeofWithVarOrFunc.ts(19,29): error TS2577: Return type annotation circularly references itself.
tests/cases/conformance/types/specifyingTypes/typeQueries/circularTypeofWithVarOrFunc.ts(25,6): error TS2456: Type alias 'R2' circularly references itself.
tests/cases/conformance/types/specifyingTypes/typeQueries/circularTypeofWithVarOrFunc.ts(26,15): error TS2577: Return type annotation circularly references itself.
tests/cases/conformance/types/specifyingTypes/typeQueries/circularTypeofWithVarOrFunc.ts(20,3): error TS2322: Type 'number' is not assignable to type 'ReturnType<(input: Input) => ReturnType<typeof mul>>'.
tests/cases/conformance/types/specifyingTypes/typeQueries/circularTypeofWithVarOrFunc.ts(26,20): error TS2322: Type '0' is not assignable to type 'ReturnType<() => ReturnType<typeof f>>'.
==== tests/cases/conformance/types/specifyingTypes/typeQueries/circularTypeofWithVarOrFunc.ts (10 errors) ====
==== tests/cases/conformance/types/specifyingTypes/typeQueries/circularTypeofWithVarOrFunc.ts (8 errors) ====
type typeAlias1 = typeof varOfAliasedType1;
~~~~~~~~~~
!!! error TS2456: Type alias 'typeAlias1' circularly references itself.
@ -41,20 +39,16 @@ tests/cases/conformance/types/specifyingTypes/typeQueries/circularTypeofWithVarO
}
type R = ReturnType<typeof mul>;
~
!!! error TS2456: Type alias 'R' circularly references itself.
function mul(input: Input): R {
~
!!! error TS2577: Return type annotation circularly references itself.
return input.a * input.b;
~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2322: Type 'number' is not assignable to type 'ReturnType<(input: Input) => ReturnType<typeof mul>>'.
}
// Repro from #26104
type R2 = ReturnType<typeof f>;
~~
!!! error TS2456: Type alias 'R2' circularly references itself.
function f(): R2 { return 0; }
~~
!!! error TS2577: Return type annotation circularly references itself.
~~~~~~~~~
!!! error TS2322: Type '0' is not assignable to type 'ReturnType<() => ReturnType<typeof f>>'.

View file

@ -37,11 +37,11 @@ interface Input {
}
type R = ReturnType<typeof mul>;
>R : any
>mul : (input: Input) => any
>R : ReturnType<(input: Input) => ReturnType<typeof mul>>
>mul : (input: Input) => ReturnType<typeof mul>
function mul(input: Input): R {
>mul : (input: Input) => any
>mul : (input: Input) => ReturnType<typeof mul>
>input : Input
return input.a * input.b;
@ -57,10 +57,10 @@ function mul(input: Input): R {
// Repro from #26104
type R2 = ReturnType<typeof f>;
>R2 : any
>f : () => any
>R2 : ReturnType<() => ReturnType<typeof f>>
>f : () => ReturnType<typeof f>
function f(): R2 { return 0; }
>f : () => any
>f : () => ReturnType<typeof f>
>0 : 0

View file

@ -0,0 +1,69 @@
//// [circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts]
declare class Component<P> {
constructor(props: Readonly<P>);
constructor(props: P, context?: any);
readonly props: Readonly<P> & Readonly<{ children?: {} }>;
}
interface ComponentClass<P = {}> {
new (props: P, context?: any): Component<P>;
propTypes?: WeakValidationMap<P>;
defaultProps?: Partial<P>;
displayName?: string;
}
interface FunctionComponent<P = {}> {
(props: P & { children?: {} }, context?: any): {} | null;
propTypes?: WeakValidationMap<P>;
defaultProps?: Partial<P>;
displayName?: string;
}
export declare const nominalTypeHack: unique symbol;
export interface Validator<T> {
(props: object, propName: string, componentName: string, location: string, propFullName: string): Error | null;
[nominalTypeHack]?: T;
}
type WeakValidationMap<T> = {
[K in keyof T]?: null extends T[K]
? Validator<T[K] | null | undefined>
: undefined extends T[K]
? Validator<T[K] | null | undefined>
: Validator<T[K]>
};
type ComponentType<P = {}> = ComponentClass<P> | FunctionComponent<P>;
export type Shared<
InjectedProps,
DecorationTargetProps extends Shared<InjectedProps, DecorationTargetProps>
> = {
[P in Extract<keyof InjectedProps, keyof DecorationTargetProps>]?: InjectedProps[P] extends DecorationTargetProps[P] ? DecorationTargetProps[P] : never;
};
// Infers prop type from component C
export type GetProps<C> = C extends ComponentType<infer P> ? P : never;
export type ConnectedComponentClass<
C extends ComponentType<any>,
P
> = ComponentClass<P> & {
WrappedComponent: C;
};
export type Matching<InjectedProps, DecorationTargetProps> = {
[P in keyof DecorationTargetProps]: P extends keyof InjectedProps
? InjectedProps[P] extends DecorationTargetProps[P]
? DecorationTargetProps[P]
: InjectedProps[P]
: DecorationTargetProps[P];
};
export type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
export type InferableComponentEnhancerWithProps<TInjectedProps, TNeedsProps> =
<C extends ComponentType<Matching<TInjectedProps, GetProps<C>>>>(
component: C
) => ConnectedComponentClass<C, Omit<GetProps<C>, keyof Shared<TInjectedProps, GetProps<C>>> & TNeedsProps>;
//// [circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.js]
"use strict";
exports.__esModule = true;

View file

@ -0,0 +1,255 @@
=== tests/cases/compiler/circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts ===
declare class Component<P> {
>Component : Symbol(Component, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 0, 0))
>P : Symbol(P, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 0, 24))
constructor(props: Readonly<P>);
>props : Symbol(props, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 1, 16))
>Readonly : Symbol(Readonly, Decl(lib.es5.d.ts, --, --))
>P : Symbol(P, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 0, 24))
constructor(props: P, context?: any);
>props : Symbol(props, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 2, 16))
>P : Symbol(P, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 0, 24))
>context : Symbol(context, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 2, 25))
readonly props: Readonly<P> & Readonly<{ children?: {} }>;
>props : Symbol(Component.props, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 2, 41))
>Readonly : Symbol(Readonly, Decl(lib.es5.d.ts, --, --))
>P : Symbol(P, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 0, 24))
>Readonly : Symbol(Readonly, Decl(lib.es5.d.ts, --, --))
>children : Symbol(children, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 3, 44))
}
interface ComponentClass<P = {}> {
>ComponentClass : Symbol(ComponentClass, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 4, 1))
>P : Symbol(P, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 5, 25))
new (props: P, context?: any): Component<P>;
>props : Symbol(props, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 6, 9))
>P : Symbol(P, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 5, 25))
>context : Symbol(context, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 6, 18))
>Component : Symbol(Component, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 0, 0))
>P : Symbol(P, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 5, 25))
propTypes?: WeakValidationMap<P>;
>propTypes : Symbol(ComponentClass.propTypes, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 6, 48))
>WeakValidationMap : Symbol(WeakValidationMap, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 22, 1))
>P : Symbol(P, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 5, 25))
defaultProps?: Partial<P>;
>defaultProps : Symbol(ComponentClass.defaultProps, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 7, 37))
>Partial : Symbol(Partial, Decl(lib.es5.d.ts, --, --))
>P : Symbol(P, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 5, 25))
displayName?: string;
>displayName : Symbol(ComponentClass.displayName, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 8, 30))
}
interface FunctionComponent<P = {}> {
>FunctionComponent : Symbol(FunctionComponent, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 10, 1))
>P : Symbol(P, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 11, 28))
(props: P & { children?: {} }, context?: any): {} | null;
>props : Symbol(props, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 12, 5))
>P : Symbol(P, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 11, 28))
>children : Symbol(children, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 12, 17))
>context : Symbol(context, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 12, 34))
propTypes?: WeakValidationMap<P>;
>propTypes : Symbol(FunctionComponent.propTypes, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 12, 61))
>WeakValidationMap : Symbol(WeakValidationMap, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 22, 1))
>P : Symbol(P, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 11, 28))
defaultProps?: Partial<P>;
>defaultProps : Symbol(FunctionComponent.defaultProps, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 13, 37))
>Partial : Symbol(Partial, Decl(lib.es5.d.ts, --, --))
>P : Symbol(P, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 11, 28))
displayName?: string;
>displayName : Symbol(FunctionComponent.displayName, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 14, 30))
}
export declare const nominalTypeHack: unique symbol;
>nominalTypeHack : Symbol(nominalTypeHack, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 18, 20))
export interface Validator<T> {
>Validator : Symbol(Validator, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 18, 52))
>T : Symbol(T, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 19, 27))
(props: object, propName: string, componentName: string, location: string, propFullName: string): Error | null;
>props : Symbol(props, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 20, 5))
>propName : Symbol(propName, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 20, 19))
>componentName : Symbol(componentName, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 20, 37))
>location : Symbol(location, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 20, 60))
>propFullName : Symbol(propFullName, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 20, 78))
>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
[nominalTypeHack]?: T;
>[nominalTypeHack] : Symbol(Validator[nominalTypeHack], Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 20, 115))
>nominalTypeHack : Symbol(nominalTypeHack, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 18, 20))
>T : Symbol(T, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 19, 27))
}
type WeakValidationMap<T> = {
>WeakValidationMap : Symbol(WeakValidationMap, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 22, 1))
>T : Symbol(T, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 23, 23))
[K in keyof T]?: null extends T[K]
>K : Symbol(K, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 24, 5))
>T : Symbol(T, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 23, 23))
>T : Symbol(T, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 23, 23))
>K : Symbol(K, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 24, 5))
? Validator<T[K] | null | undefined>
>Validator : Symbol(Validator, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 18, 52))
>T : Symbol(T, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 23, 23))
>K : Symbol(K, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 24, 5))
: undefined extends T[K]
>T : Symbol(T, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 23, 23))
>K : Symbol(K, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 24, 5))
? Validator<T[K] | null | undefined>
>Validator : Symbol(Validator, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 18, 52))
>T : Symbol(T, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 23, 23))
>K : Symbol(K, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 24, 5))
: Validator<T[K]>
>Validator : Symbol(Validator, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 18, 52))
>T : Symbol(T, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 23, 23))
>K : Symbol(K, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 24, 5))
};
type ComponentType<P = {}> = ComponentClass<P> | FunctionComponent<P>;
>ComponentType : Symbol(ComponentType, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 29, 2))
>P : Symbol(P, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 30, 19))
>ComponentClass : Symbol(ComponentClass, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 4, 1))
>P : Symbol(P, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 30, 19))
>FunctionComponent : Symbol(FunctionComponent, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 10, 1))
>P : Symbol(P, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 30, 19))
export type Shared<
>Shared : Symbol(Shared, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 30, 70))
InjectedProps,
>InjectedProps : Symbol(InjectedProps, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 32, 19))
DecorationTargetProps extends Shared<InjectedProps, DecorationTargetProps>
>DecorationTargetProps : Symbol(DecorationTargetProps, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 33, 18))
>Shared : Symbol(Shared, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 30, 70))
>InjectedProps : Symbol(InjectedProps, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 32, 19))
>DecorationTargetProps : Symbol(DecorationTargetProps, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 33, 18))
> = {
[P in Extract<keyof InjectedProps, keyof DecorationTargetProps>]?: InjectedProps[P] extends DecorationTargetProps[P] ? DecorationTargetProps[P] : never;
>P : Symbol(P, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 36, 9))
>Extract : Symbol(Extract, Decl(lib.es5.d.ts, --, --))
>InjectedProps : Symbol(InjectedProps, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 32, 19))
>DecorationTargetProps : Symbol(DecorationTargetProps, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 33, 18))
>InjectedProps : Symbol(InjectedProps, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 32, 19))
>P : Symbol(P, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 36, 9))
>DecorationTargetProps : Symbol(DecorationTargetProps, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 33, 18))
>P : Symbol(P, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 36, 9))
>DecorationTargetProps : Symbol(DecorationTargetProps, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 33, 18))
>P : Symbol(P, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 36, 9))
};
// Infers prop type from component C
export type GetProps<C> = C extends ComponentType<infer P> ? P : never;
>GetProps : Symbol(GetProps, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 37, 6))
>C : Symbol(C, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 40, 21))
>C : Symbol(C, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 40, 21))
>ComponentType : Symbol(ComponentType, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 29, 2))
>P : Symbol(P, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 40, 55))
>P : Symbol(P, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 40, 55))
export type ConnectedComponentClass<
>ConnectedComponentClass : Symbol(ConnectedComponentClass, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 40, 71))
C extends ComponentType<any>,
>C : Symbol(C, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 42, 36))
>ComponentType : Symbol(ComponentType, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 29, 2))
P
>P : Symbol(P, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 43, 33))
> = ComponentClass<P> & {
>ComponentClass : Symbol(ComponentClass, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 4, 1))
>P : Symbol(P, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 43, 33))
WrappedComponent: C;
>WrappedComponent : Symbol(WrappedComponent, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 45, 25))
>C : Symbol(C, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 42, 36))
};
export type Matching<InjectedProps, DecorationTargetProps> = {
>Matching : Symbol(Matching, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 47, 2))
>InjectedProps : Symbol(InjectedProps, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 49, 21))
>DecorationTargetProps : Symbol(DecorationTargetProps, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 49, 35))
[P in keyof DecorationTargetProps]: P extends keyof InjectedProps
>P : Symbol(P, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 50, 5))
>DecorationTargetProps : Symbol(DecorationTargetProps, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 49, 35))
>P : Symbol(P, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 50, 5))
>InjectedProps : Symbol(InjectedProps, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 49, 21))
? InjectedProps[P] extends DecorationTargetProps[P]
>InjectedProps : Symbol(InjectedProps, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 49, 21))
>P : Symbol(P, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 50, 5))
>DecorationTargetProps : Symbol(DecorationTargetProps, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 49, 35))
>P : Symbol(P, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 50, 5))
? DecorationTargetProps[P]
>DecorationTargetProps : Symbol(DecorationTargetProps, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 49, 35))
>P : Symbol(P, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 50, 5))
: InjectedProps[P]
>InjectedProps : Symbol(InjectedProps, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 49, 21))
>P : Symbol(P, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 50, 5))
: DecorationTargetProps[P];
>DecorationTargetProps : Symbol(DecorationTargetProps, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 49, 35))
>P : Symbol(P, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 50, 5))
};
export type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
>Omit : Symbol(Omit, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 55, 2))
>T : Symbol(T, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 57, 17))
>K : Symbol(K, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 57, 19))
>T : Symbol(T, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 57, 17))
>Pick : Symbol(Pick, Decl(lib.es5.d.ts, --, --))
>T : Symbol(T, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 57, 17))
>Exclude : Symbol(Exclude, Decl(lib.es5.d.ts, --, --))
>T : Symbol(T, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 57, 17))
>K : Symbol(K, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 57, 19))
export type InferableComponentEnhancerWithProps<TInjectedProps, TNeedsProps> =
>InferableComponentEnhancerWithProps : Symbol(InferableComponentEnhancerWithProps, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 57, 70))
>TInjectedProps : Symbol(TInjectedProps, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 59, 48))
>TNeedsProps : Symbol(TNeedsProps, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 59, 63))
<C extends ComponentType<Matching<TInjectedProps, GetProps<C>>>>(
>C : Symbol(C, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 60, 5))
>ComponentType : Symbol(ComponentType, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 29, 2))
>Matching : Symbol(Matching, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 47, 2))
>TInjectedProps : Symbol(TInjectedProps, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 59, 48))
>GetProps : Symbol(GetProps, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 37, 6))
>C : Symbol(C, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 60, 5))
component: C
>component : Symbol(component, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 60, 69))
>C : Symbol(C, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 60, 5))
) => ConnectedComponentClass<C, Omit<GetProps<C>, keyof Shared<TInjectedProps, GetProps<C>>> & TNeedsProps>;
>ConnectedComponentClass : Symbol(ConnectedComponentClass, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 40, 71))
>C : Symbol(C, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 60, 5))
>Omit : Symbol(Omit, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 55, 2))
>GetProps : Symbol(GetProps, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 37, 6))
>C : Symbol(C, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 60, 5))
>Shared : Symbol(Shared, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 30, 70))
>TInjectedProps : Symbol(TInjectedProps, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 59, 48))
>GetProps : Symbol(GetProps, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 37, 6))
>C : Symbol(C, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 60, 5))
>TNeedsProps : Symbol(TNeedsProps, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 59, 63))

View file

@ -0,0 +1,126 @@
=== tests/cases/compiler/circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts ===
declare class Component<P> {
>Component : Component<P>
constructor(props: Readonly<P>);
>props : Readonly<P>
constructor(props: P, context?: any);
>props : P
>context : any
readonly props: Readonly<P> & Readonly<{ children?: {} }>;
>props : Readonly<P> & Readonly<{ children?: {} | undefined; }>
>children : {} | undefined
}
interface ComponentClass<P = {}> {
new (props: P, context?: any): Component<P>;
>props : P
>context : any
propTypes?: WeakValidationMap<P>;
>propTypes : WeakValidationMap<P> | undefined
defaultProps?: Partial<P>;
>defaultProps : Partial<P> | undefined
displayName?: string;
>displayName : string | undefined
}
interface FunctionComponent<P = {}> {
(props: P & { children?: {} }, context?: any): {} | null;
>props : P & { children?: {} | undefined; }
>children : {} | undefined
>context : any
>null : null
propTypes?: WeakValidationMap<P>;
>propTypes : WeakValidationMap<P> | undefined
defaultProps?: Partial<P>;
>defaultProps : Partial<P> | undefined
displayName?: string;
>displayName : string | undefined
}
export declare const nominalTypeHack: unique symbol;
>nominalTypeHack : unique symbol
export interface Validator<T> {
(props: object, propName: string, componentName: string, location: string, propFullName: string): Error | null;
>props : object
>propName : string
>componentName : string
>location : string
>propFullName : string
>null : null
[nominalTypeHack]?: T;
>[nominalTypeHack] : T | undefined
>nominalTypeHack : unique symbol
}
type WeakValidationMap<T> = {
>WeakValidationMap : WeakValidationMap<T>
[K in keyof T]?: null extends T[K]
>null : null
? Validator<T[K] | null | undefined>
>null : null
: undefined extends T[K]
? Validator<T[K] | null | undefined>
>null : null
: Validator<T[K]>
};
type ComponentType<P = {}> = ComponentClass<P> | FunctionComponent<P>;
>ComponentType : ComponentType<P>
export type Shared<
>Shared : Shared<InjectedProps, DecorationTargetProps>
InjectedProps,
DecorationTargetProps extends Shared<InjectedProps, DecorationTargetProps>
> = {
[P in Extract<keyof InjectedProps, keyof DecorationTargetProps>]?: InjectedProps[P] extends DecorationTargetProps[P] ? DecorationTargetProps[P] : never;
};
// Infers prop type from component C
export type GetProps<C> = C extends ComponentType<infer P> ? P : never;
>GetProps : GetProps<C>
export type ConnectedComponentClass<
>ConnectedComponentClass : ConnectedComponentClass<C, P>
C extends ComponentType<any>,
P
> = ComponentClass<P> & {
WrappedComponent: C;
>WrappedComponent : C
};
export type Matching<InjectedProps, DecorationTargetProps> = {
>Matching : Matching<InjectedProps, DecorationTargetProps>
[P in keyof DecorationTargetProps]: P extends keyof InjectedProps
? InjectedProps[P] extends DecorationTargetProps[P]
? DecorationTargetProps[P]
: InjectedProps[P]
: DecorationTargetProps[P];
};
export type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
>Omit : Pick<T, Exclude<keyof T, K>>
export type InferableComponentEnhancerWithProps<TInjectedProps, TNeedsProps> =
>InferableComponentEnhancerWithProps : InferableComponentEnhancerWithProps<TInjectedProps, TNeedsProps>
<C extends ComponentType<Matching<TInjectedProps, GetProps<C>>>>(
component: C
>component : C
) => ConnectedComponentClass<C, Omit<GetProps<C>, keyof Shared<TInjectedProps, GetProps<C>>> & TNeedsProps>;

View file

@ -1,16 +1,13 @@
tests/cases/compiler/recursiveResolveTypeMembers.ts(4,49): error TS2577: Return type annotation circularly references itself.
tests/cases/compiler/recursiveResolveTypeMembers.ts(4,58): error TS2304: Cannot find name 'H'.
tests/cases/compiler/recursiveResolveTypeMembers.ts(4,62): error TS2574: A rest element type must be an array type.
tests/cases/compiler/recursiveResolveTypeMembers.ts(4,79): error TS2304: Cannot find name 'R'.
==== tests/cases/compiler/recursiveResolveTypeMembers.ts (4 errors) ====
==== tests/cases/compiler/recursiveResolveTypeMembers.ts (3 errors) ====
// Repro from #25291
type PromisedTuple<L extends any[], U = (...args: L) => void> =
U extends (h: infer H, ...args: infer R) => [Promise<H>, ...PromisedTuple<R>] ? [] : []
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2577: Return type annotation circularly references itself.
~
!!! error TS2304: Cannot find name 'H'.
~~~~~~~~~~~~~~~~~~~

View file

@ -0,0 +1,64 @@
// @strict: true
declare class Component<P> {
constructor(props: Readonly<P>);
constructor(props: P, context?: any);
readonly props: Readonly<P> & Readonly<{ children?: {} }>;
}
interface ComponentClass<P = {}> {
new (props: P, context?: any): Component<P>;
propTypes?: WeakValidationMap<P>;
defaultProps?: Partial<P>;
displayName?: string;
}
interface FunctionComponent<P = {}> {
(props: P & { children?: {} }, context?: any): {} | null;
propTypes?: WeakValidationMap<P>;
defaultProps?: Partial<P>;
displayName?: string;
}
export declare const nominalTypeHack: unique symbol;
export interface Validator<T> {
(props: object, propName: string, componentName: string, location: string, propFullName: string): Error | null;
[nominalTypeHack]?: T;
}
type WeakValidationMap<T> = {
[K in keyof T]?: null extends T[K]
? Validator<T[K] | null | undefined>
: undefined extends T[K]
? Validator<T[K] | null | undefined>
: Validator<T[K]>
};
type ComponentType<P = {}> = ComponentClass<P> | FunctionComponent<P>;
export type Shared<
InjectedProps,
DecorationTargetProps extends Shared<InjectedProps, DecorationTargetProps>
> = {
[P in Extract<keyof InjectedProps, keyof DecorationTargetProps>]?: InjectedProps[P] extends DecorationTargetProps[P] ? DecorationTargetProps[P] : never;
};
// Infers prop type from component C
export type GetProps<C> = C extends ComponentType<infer P> ? P : never;
export type ConnectedComponentClass<
C extends ComponentType<any>,
P
> = ComponentClass<P> & {
WrappedComponent: C;
};
export type Matching<InjectedProps, DecorationTargetProps> = {
[P in keyof DecorationTargetProps]: P extends keyof InjectedProps
? InjectedProps[P] extends DecorationTargetProps[P]
? DecorationTargetProps[P]
: InjectedProps[P]
: DecorationTargetProps[P];
};
export type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
export type InferableComponentEnhancerWithProps<TInjectedProps, TNeedsProps> =
<C extends ComponentType<Matching<TInjectedProps, GetProps<C>>>>(
component: C
) => ConnectedComponentClass<C, Omit<GetProps<C>, keyof Shared<TInjectedProps, GetProps<C>>> & TNeedsProps>;