diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 898ebbfbcd6ad..5d48697610155 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -388,7 +388,7 @@ namespace ts { const intersectionTypes = createMap(); const literalTypes = createMap(); const indexedAccessTypes = createMap(); - const conditionalTypes = createMap(); + const conditionalTypes = createMap(); const evolvingArrayTypes: EvolvingArrayType[] = []; const undefinedProperties = createMap() as UnderscoreEscapedMap; @@ -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 = createType(TypeFlags.Conditional); result.root = root; diff --git a/tests/baselines/reference/circularTypeofWithVarOrFunc.errors.txt b/tests/baselines/reference/circularTypeofWithVarOrFunc.errors.txt index 1fb989b75f5c1..9adcce6c84582 100644 --- a/tests/baselines/reference/circularTypeofWithVarOrFunc.errors.txt +++ b/tests/baselines/reference/circularTypeofWithVarOrFunc.errors.txt @@ -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>'. +tests/cases/conformance/types/specifyingTypes/typeQueries/circularTypeofWithVarOrFunc.ts(26,20): error TS2322: Type '0' is not assignable to type 'ReturnType<() => ReturnType>'. -==== 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; - ~ -!!! 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>'. } // Repro from #26104 type R2 = ReturnType; - ~~ -!!! 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>'. \ No newline at end of file diff --git a/tests/baselines/reference/circularTypeofWithVarOrFunc.types b/tests/baselines/reference/circularTypeofWithVarOrFunc.types index c2c8ba7947fb5..7f7fe21bba001 100644 --- a/tests/baselines/reference/circularTypeofWithVarOrFunc.types +++ b/tests/baselines/reference/circularTypeofWithVarOrFunc.types @@ -37,11 +37,11 @@ interface Input { } type R = ReturnType; ->R : any ->mul : (input: Input) => any +>R : ReturnType<(input: Input) => ReturnType> +>mul : (input: Input) => ReturnType function mul(input: Input): R { ->mul : (input: Input) => any +>mul : (input: Input) => ReturnType >input : Input return input.a * input.b; @@ -57,10 +57,10 @@ function mul(input: Input): R { // Repro from #26104 type R2 = ReturnType; ->R2 : any ->f : () => any +>R2 : ReturnType<() => ReturnType> +>f : () => ReturnType function f(): R2 { return 0; } ->f : () => any +>f : () => ReturnType >0 : 0 diff --git a/tests/baselines/reference/circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.js b/tests/baselines/reference/circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.js new file mode 100644 index 0000000000000..3117cf0bb1830 --- /dev/null +++ b/tests/baselines/reference/circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.js @@ -0,0 +1,69 @@ +//// [circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts] +declare class Component

{ + constructor(props: Readonly

); + constructor(props: P, context?: any); + readonly props: Readonly

& Readonly<{ children?: {} }>; +} +interface ComponentClass

{ + new (props: P, context?: any): Component

; + propTypes?: WeakValidationMap

; + defaultProps?: Partial

; + displayName?: string; +} +interface FunctionComponent

{ + (props: P & { children?: {} }, context?: any): {} | null; + propTypes?: WeakValidationMap

; + defaultProps?: Partial

; + displayName?: string; +} + +export declare const nominalTypeHack: unique symbol; +export interface Validator { + (props: object, propName: string, componentName: string, location: string, propFullName: string): Error | null; + [nominalTypeHack]?: T; +} +type WeakValidationMap = { + [K in keyof T]?: null extends T[K] + ? Validator + : undefined extends T[K] + ? Validator + : Validator +}; +type ComponentType

= ComponentClass

| FunctionComponent

; + +export type Shared< + InjectedProps, + DecorationTargetProps extends Shared + > = { + [P in Extract]?: InjectedProps[P] extends DecorationTargetProps[P] ? DecorationTargetProps[P] : never; + }; + +// Infers prop type from component C +export type GetProps = C extends ComponentType ? P : never; + +export type ConnectedComponentClass< + C extends ComponentType, + P +> = ComponentClass

& { + WrappedComponent: C; +}; + +export type Matching = { + [P in keyof DecorationTargetProps]: P extends keyof InjectedProps + ? InjectedProps[P] extends DecorationTargetProps[P] + ? DecorationTargetProps[P] + : InjectedProps[P] + : DecorationTargetProps[P]; +}; + +export type Omit = Pick>; + +export type InferableComponentEnhancerWithProps = + >>>( + component: C + ) => ConnectedComponentClass, keyof Shared>> & TNeedsProps>; + + +//// [circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.js] +"use strict"; +exports.__esModule = true; diff --git a/tests/baselines/reference/circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.symbols b/tests/baselines/reference/circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.symbols new file mode 100644 index 0000000000000..aaaeb7b363f67 --- /dev/null +++ b/tests/baselines/reference/circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.symbols @@ -0,0 +1,255 @@ +=== tests/cases/compiler/circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts === +declare class Component

{ +>Component : Symbol(Component, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 0, 0)) +>P : Symbol(P, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 0, 24)) + + constructor(props: Readonly

); +>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

& 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

{ +>ComponentClass : Symbol(ComponentClass, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 4, 1)) +>P : Symbol(P, Decl(circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts, 5, 25)) + + new (props: P, context?: any): Component

; +>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

; +>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

; +>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

{ +>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

; +>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

; +>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 { +>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 = { +>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 +>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 +>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 +>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

= ComponentClass

| FunctionComponent

; +>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 +>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]?: 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 extends ComponentType ? 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, +>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

& { +>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 = { +>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 = Pick>; +>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 = +>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 : 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, keyof Shared>> & 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)) + diff --git a/tests/baselines/reference/circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.types b/tests/baselines/reference/circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.types new file mode 100644 index 0000000000000..5bef1baa732a8 --- /dev/null +++ b/tests/baselines/reference/circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.types @@ -0,0 +1,126 @@ +=== tests/cases/compiler/circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts === +declare class Component

{ +>Component : Component

+ + constructor(props: Readonly

); +>props : Readonly

+ + constructor(props: P, context?: any); +>props : P +>context : any + + readonly props: Readonly

& Readonly<{ children?: {} }>; +>props : Readonly

& Readonly<{ children?: {} | undefined; }> +>children : {} | undefined +} +interface ComponentClass

{ + new (props: P, context?: any): Component

; +>props : P +>context : any + + propTypes?: WeakValidationMap

; +>propTypes : WeakValidationMap

| undefined + + defaultProps?: Partial

; +>defaultProps : Partial

| undefined + + displayName?: string; +>displayName : string | undefined +} +interface FunctionComponent

{ + (props: P & { children?: {} }, context?: any): {} | null; +>props : P & { children?: {} | undefined; } +>children : {} | undefined +>context : any +>null : null + + propTypes?: WeakValidationMap

; +>propTypes : WeakValidationMap

| undefined + + defaultProps?: Partial

; +>defaultProps : Partial

| undefined + + displayName?: string; +>displayName : string | undefined +} + +export declare const nominalTypeHack: unique symbol; +>nominalTypeHack : unique symbol + +export interface Validator { + (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 = { +>WeakValidationMap : WeakValidationMap + + [K in keyof T]?: null extends T[K] +>null : null + + ? Validator +>null : null + + : undefined extends T[K] + ? Validator +>null : null + + : Validator +}; +type ComponentType

= ComponentClass

| FunctionComponent

; +>ComponentType : ComponentType

+ +export type Shared< +>Shared : Shared + + InjectedProps, + DecorationTargetProps extends Shared + > = { + [P in Extract]?: InjectedProps[P] extends DecorationTargetProps[P] ? DecorationTargetProps[P] : never; + }; + +// Infers prop type from component C +export type GetProps = C extends ComponentType ? P : never; +>GetProps : GetProps + +export type ConnectedComponentClass< +>ConnectedComponentClass : ConnectedComponentClass + + C extends ComponentType, + P +> = ComponentClass

& { + WrappedComponent: C; +>WrappedComponent : C + +}; + +export type Matching = { +>Matching : Matching + + [P in keyof DecorationTargetProps]: P extends keyof InjectedProps + ? InjectedProps[P] extends DecorationTargetProps[P] + ? DecorationTargetProps[P] + : InjectedProps[P] + : DecorationTargetProps[P]; +}; + +export type Omit = Pick>; +>Omit : Pick> + +export type InferableComponentEnhancerWithProps = +>InferableComponentEnhancerWithProps : InferableComponentEnhancerWithProps + + >>>( + component: C +>component : C + + ) => ConnectedComponentClass, keyof Shared>> & TNeedsProps>; + diff --git a/tests/baselines/reference/recursiveResolveTypeMembers.errors.txt b/tests/baselines/reference/recursiveResolveTypeMembers.errors.txt index ad5fe6dc1aedc..2a6bab18cbaac 100644 --- a/tests/baselines/reference/recursiveResolveTypeMembers.errors.txt +++ b/tests/baselines/reference/recursiveResolveTypeMembers.errors.txt @@ -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 void> = U extends (h: infer H, ...args: infer R) => [Promise, ...PromisedTuple] ? [] : [] - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2577: Return type annotation circularly references itself. ~ !!! error TS2304: Cannot find name 'H'. ~~~~~~~~~~~~~~~~~~~ diff --git a/tests/cases/compiler/circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts b/tests/cases/compiler/circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts new file mode 100644 index 0000000000000..912bacd551ebe --- /dev/null +++ b/tests/cases/compiler/circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts @@ -0,0 +1,64 @@ +// @strict: true +declare class Component

{ + constructor(props: Readonly

); + constructor(props: P, context?: any); + readonly props: Readonly

& Readonly<{ children?: {} }>; +} +interface ComponentClass

{ + new (props: P, context?: any): Component

; + propTypes?: WeakValidationMap

; + defaultProps?: Partial

; + displayName?: string; +} +interface FunctionComponent

{ + (props: P & { children?: {} }, context?: any): {} | null; + propTypes?: WeakValidationMap

; + defaultProps?: Partial

; + displayName?: string; +} + +export declare const nominalTypeHack: unique symbol; +export interface Validator { + (props: object, propName: string, componentName: string, location: string, propFullName: string): Error | null; + [nominalTypeHack]?: T; +} +type WeakValidationMap = { + [K in keyof T]?: null extends T[K] + ? Validator + : undefined extends T[K] + ? Validator + : Validator +}; +type ComponentType

= ComponentClass

| FunctionComponent

; + +export type Shared< + InjectedProps, + DecorationTargetProps extends Shared + > = { + [P in Extract]?: InjectedProps[P] extends DecorationTargetProps[P] ? DecorationTargetProps[P] : never; + }; + +// Infers prop type from component C +export type GetProps = C extends ComponentType ? P : never; + +export type ConnectedComponentClass< + C extends ComponentType, + P +> = ComponentClass

& { + WrappedComponent: C; +}; + +export type Matching = { + [P in keyof DecorationTargetProps]: P extends keyof InjectedProps + ? InjectedProps[P] extends DecorationTargetProps[P] + ? DecorationTargetProps[P] + : InjectedProps[P] + : DecorationTargetProps[P]; +}; + +export type Omit = Pick>; + +export type InferableComponentEnhancerWithProps = + >>>( + component: C + ) => ConnectedComponentClass, keyof Shared>> & TNeedsProps>;