diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index be3965258a516..d951e183b0fa8 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1008,7 +1008,6 @@ import { SignatureFlags, SignatureKind, singleElementArray, - SingleSignatureType, skipOuterExpressions, skipParentheses, skipTrivia, @@ -7192,7 +7191,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const abstractSignatures = filter(resolved.constructSignatures, signature => !!(signature.flags & SignatureFlags.Abstract)); if (some(abstractSignatures)) { - const types = map(abstractSignatures, s => getOrCreateTypeFromSignature(s)); + const types = map(abstractSignatures, getOrCreateTypeFromSignature); // count the number of type elements excluding abstract constructors const typeElementCount = resolved.callSignatures.length + (resolved.constructSignatures.length - abstractSignatures.length) + @@ -16310,15 +16309,17 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return undefined; } - function getSignatureInstantiation(signature: Signature, typeArguments: readonly Type[] | undefined, isJavascript: boolean, inferredTypeParameters?: readonly TypeParameter[]): Signature { + function getSignatureInstantiation(signature: Signature, typeArguments: Type[] | undefined, isJavascript: boolean, inferredTypeParameters?: readonly TypeParameter[]): Signature { const instantiatedSignature = getSignatureInstantiationWithoutFillingInTypeArguments(signature, fillMissingTypeArguments(typeArguments, signature.typeParameters, getMinTypeArgumentCount(signature.typeParameters), isJavascript)); if (inferredTypeParameters) { const returnSignature = getSingleCallOrConstructSignature(getReturnTypeOfSignature(instantiatedSignature)); if (returnSignature) { const newReturnSignature = cloneSignature(returnSignature); newReturnSignature.typeParameters = inferredTypeParameters; + const newReturnType = getOrCreateTypeFromSignature(newReturnSignature) as AnonymousType; + newReturnType.mapper = instantiatedSignature.mapper; const newInstantiatedSignature = cloneSignature(instantiatedSignature); - newInstantiatedSignature.resolvedReturnType = getOrCreateTypeFromSignature(newReturnSignature); + newInstantiatedSignature.resolvedReturnType = newReturnType; return newInstantiatedSignature; } } @@ -16378,16 +16379,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { ); } - function getImplementationSignature(signature: Signature) { - return signature.typeParameters ? - signature.implementationSignatureCache ||= createImplementationSignature(signature) : - signature; - } - - function createImplementationSignature(signature: Signature) { - return signature.typeParameters ? instantiateSignature(signature, createTypeMapper([], [])) : signature; - } - function getBaseSignature(signature: Signature) { const typeParameters = signature.typeParameters; if (typeParameters) { @@ -16409,7 +16400,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return signature; } - function getOrCreateTypeFromSignature(signature: Signature, outerTypeParameters?: TypeParameter[]): ObjectType { + function getOrCreateTypeFromSignature(signature: Signature): ObjectType { // There are two ways to declare a construct signature, one is by declaring a class constructor // using the constructor keyword, and the other is declaring a bare construct signature in an // object type literal or interface (using the new keyword). Each way of declaring a constructor @@ -16420,16 +16411,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // If declaration is undefined, it is likely to be the signature of the default constructor. const isConstructor = kind === undefined || kind === SyntaxKind.Constructor || kind === SyntaxKind.ConstructSignature || kind === SyntaxKind.ConstructorType; - // The type must have a symbol with a `Function` flag and a declaration in order to be correctly flagged as possibly containing - // type variables by `couldContainTypeVariables` - const type = createObjectType(ObjectFlags.Anonymous | ObjectFlags.SingleSignatureType, createSymbol(SymbolFlags.Function, InternalSymbolName.Function)) as SingleSignatureType; - if (signature.declaration && !nodeIsSynthesized(signature.declaration)) { // skip synthetic declarations - keeping those around could be bad, since they lack a parent pointer - type.symbol.declarations = [signature.declaration]; - type.symbol.valueDeclaration = signature.declaration; - } - outerTypeParameters ||= signature.declaration && getOuterTypeParameters(signature.declaration, /*includeThisTypes*/ true); - type.outerTypeParameters = outerTypeParameters; - + const type = createObjectType(ObjectFlags.Anonymous | ObjectFlags.SingleSignatureType, signature.declaration?.symbol); type.members = emptySymbols; type.properties = emptyArray; type.callSignatures = !isConstructor ? [signature] : emptyArray; @@ -20419,6 +20401,14 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return createTypeMapper(map(forwardInferences, i => i.typeParameter), map(forwardInferences, () => unknownType)); } + /** + * Return a type mapper that combines the context's return mapper with a mapper that erases any additional type parameters + * to their inferences at the time of creation. + */ + function createOuterReturnMapper(context: InferenceContext) { + return context.outerReturnMapper ??= mergeTypeMappers(context.returnMapper, cloneInferenceContext(context).mapper); + } + function combineTypeMappers(mapper1: TypeMapper | undefined, mapper2: TypeMapper): TypeMapper { return mapper1 ? makeCompositeTypeMapper(TypeMapKind.Composite, mapper1, mapper2) : mapper2; } @@ -20515,7 +20505,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const links = getNodeLinks(declaration); const target = type.objectFlags & ObjectFlags.Reference ? links.resolvedType! as DeferredTypeReference : type.objectFlags & ObjectFlags.Instantiated ? type.target! : type; - let typeParameters = type.objectFlags & ObjectFlags.SingleSignatureType ? (type as SingleSignatureType).outerTypeParameters : links.outerTypeParameters; + let typeParameters = links.outerTypeParameters; if (!typeParameters) { // The first time an anonymous type is instantiated we compute and store a list of the type // parameters that are in scope (and therefore potentially referenced). For type literals that @@ -20541,19 +20531,17 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const typeArguments = map(typeParameters, t => getMappedType(t, combinedMapper)); const newAliasSymbol = aliasSymbol || type.aliasSymbol; const newAliasTypeArguments = aliasSymbol ? aliasTypeArguments : instantiateTypes(type.aliasTypeArguments, mapper); - const id = (type.objectFlags & ObjectFlags.SingleSignatureType ? "S" : "") + getTypeListId(typeArguments) + getAliasId(newAliasSymbol, newAliasTypeArguments); + const id = getTypeListId(typeArguments) + getAliasId(newAliasSymbol, newAliasTypeArguments); if (!target.instantiations) { target.instantiations = new Map(); target.instantiations.set(getTypeListId(typeParameters) + getAliasId(target.aliasSymbol, target.aliasTypeArguments), target); } let result = target.instantiations.get(id); if (!result) { - if (type.objectFlags & ObjectFlags.SingleSignatureType) { - result = instantiateAnonymousType(type, mapper); - target.instantiations.set(id, result); - return result; + let newMapper = createTypeMapper(typeParameters, typeArguments); + if (target.objectFlags & ObjectFlags.SingleSignatureType && mapper) { + newMapper = combineTypeMappers(newMapper, mapper); } - const newMapper = createTypeMapper(typeParameters, typeArguments); result = target.objectFlags & ObjectFlags.Reference ? createDeferredTypeReference((type as DeferredTypeReference).target, (type as DeferredTypeReference).node, newMapper, newAliasSymbol, newAliasTypeArguments) : target.objectFlags & ObjectFlags.Mapped ? instantiateMappedType(target as MappedType, newMapper, newAliasSymbol, newAliasTypeArguments) : instantiateAnonymousType(target, newMapper, newAliasSymbol, newAliasTypeArguments); @@ -20751,9 +20739,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (type.objectFlags & ObjectFlags.InstantiationExpressionType) { (result as InstantiationExpressionType).node = (type as InstantiationExpressionType).node; } - if (type.objectFlags & ObjectFlags.SingleSignatureType) { - (result as SingleSignatureType).outerTypeParameters = (type as SingleSignatureType).outerTypeParameters; - } result.target = type; result.mapper = mapper; result.aliasSymbol = aliasSymbol || type.aliasSymbol; @@ -26116,7 +26101,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const result = !!(type.flags & TypeFlags.Instantiable || type.flags & TypeFlags.Object && !isNonGenericTopLevelType(type) && ( objectFlags & ObjectFlags.Reference && ((type as TypeReference).node || some(getTypeArguments(type as TypeReference), couldContainTypeVariables)) || - objectFlags & ObjectFlags.SingleSignatureType && !!length((type as SingleSignatureType).outerTypeParameters) || objectFlags & ObjectFlags.Anonymous && type.symbol && type.symbol.flags & (SymbolFlags.Function | SymbolFlags.Method | SymbolFlags.Class | SymbolFlags.TypeLiteral | SymbolFlags.ObjectLiteral) && type.symbol.declarations || objectFlags & (ObjectFlags.Mapped | ObjectFlags.ReverseMapped | ObjectFlags.ObjectRestType | ObjectFlags.InstantiationExpressionType) ) || @@ -26498,13 +26482,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } } - /** - * @returns `true` if `type` has the shape `[T[0]]` where `T` is `typeParameter` - */ - function isTupleOfSelf(typeParameter: TypeParameter, type: Type) { - return isTupleType(type) && getTupleElementType(type, 0) === getIndexedAccessType(typeParameter, getNumberLiteralType(0)) && !getTypeOfPropertyOfType(type, "1" as __String); - } - function inferTypes(inferences: InferenceInfo[], originalSource: Type, originalTarget: Type, priority = InferencePriority.None, contravariant = false) { let bivariant = false; let propagationType: Type; @@ -26633,11 +26610,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { inference.priority = priority; } if (priority === inference.priority) { - // Inferring A to [A[0]] is a zero information inference (it guarantees A becomes its constraint), but oft arises from generic argument list inferences - // By discarding it early, we can allow more fruitful results to be used instead. - if (isTupleOfSelf(inference.typeParameter, candidate)) { - return; - } // We make contravariant inferences only if we are in a pure contravariant position, // i.e. only if we have not descended into a bivariant position. if (contravariant && !bivariant) { @@ -35577,8 +35549,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // from the return type. We need a separate inference pass here because (a) instantiation of // the source type uses the outer context's return mapper (which excludes inferences made from // outer arguments), and (b) we don't want any further inferences going into this context. + // We use `createOuterReturnMapper` to ensure that all occurrences of outer type parameters are + // replaced with inferences produced from the outer return type or preceding outer arguments. + // This protects against circular inferences, i.e. avoiding situations where inferences reference + // type parameters for which the inferences are being made. const returnContext = createInferenceContext(signature.typeParameters!, signature, context.flags); - const returnSourceType = instantiateType(contextualType, outerContext && outerContext.returnMapper); + const returnSourceType = instantiateType(contextualType, outerContext && createOuterReturnMapper(outerContext)); inferTypes(returnContext.inferences, returnSourceType, inferenceTargetType); context.returnMapper = some(returnContext.inferences, hasInferenceCandidates) ? getMapperFromContext(cloneInferredPartOfContext(returnContext)) : undefined; } @@ -35853,7 +35829,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { checkMode: CheckMode, reportErrors: boolean, containingMessageChain: (() => DiagnosticMessageChain | undefined) | undefined, - inferenceContext: InferenceContext | undefined, ): readonly Diagnostic[] | undefined { const errorOutputContainer: ErrorOutputContainer = { errors: undefined, skipLogging: true }; if (isJsxCallLike(node)) { @@ -35888,10 +35863,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // If one or more arguments are still excluded (as indicated by CheckMode.SkipContextSensitive), // we obtain the regular type of any object literal arguments because we may not have inferred complete // parameter types yet and therefore excess property checks may yield false positives (see #17041). - const regularArgType = checkMode & CheckMode.SkipContextSensitive ? getRegularTypeOfObjectLiteral(argType) : argType; - // If this was inferred under a given inference context, we may need to instantiate the expression type to finish resolving - // the type variables in the expression. - const checkArgType = inferenceContext ? instantiateType(regularArgType, inferenceContext.nonFixingMapper) : regularArgType; + const checkArgType = checkMode & CheckMode.SkipContextSensitive ? getRegularTypeOfObjectLiteral(argType) : argType; const effectiveCheckArgumentNode = getEffectiveCheckNode(arg); if (!checkTypeRelatedToAndOptionallyElaborate(checkArgType, paramType, relation, reportErrors ? effectiveCheckArgumentNode : undefined, effectiveCheckArgumentNode, headMessage, containingMessageChain, errorOutputContainer)) { Debug.assert(!reportErrors || !!errorOutputContainer.errors, "parameter should have errors when reporting errors"); @@ -36384,7 +36356,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (headMessage) { chain = chainDiagnosticMessages(chain, headMessage); } - const diags = getSignatureApplicabilityError(node, args, last, assignableRelation, CheckMode.Normal, /*reportErrors*/ true, () => chain, /*inferenceContext*/ undefined); + const diags = getSignatureApplicabilityError(node, args, last, assignableRelation, CheckMode.Normal, /*reportErrors*/ true, () => chain); if (diags) { for (const d of diags) { if (last.declaration && candidatesForArgumentError.length > 3) { @@ -36406,7 +36378,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { let i = 0; for (const c of candidatesForArgumentError) { const chain = () => chainDiagnosticMessages(/*details*/ undefined, Diagnostics.Overload_0_of_1_2_gave_the_following_error, i + 1, candidates.length, signatureToString(c)); - const diags = getSignatureApplicabilityError(node, args, c, assignableRelation, CheckMode.Normal, /*reportErrors*/ true, chain, /*inferenceContext*/ undefined); + const diags = getSignatureApplicabilityError(node, args, c, assignableRelation, CheckMode.Normal, /*reportErrors*/ true, chain); if (diags) { if (diags.length <= min) { min = diags.length; @@ -36495,7 +36467,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (some(typeArguments) || !hasCorrectArity(node, args, candidate, signatureHelpTrailingComma)) { return undefined; } - if (getSignatureApplicabilityError(node, args, candidate, relation, CheckMode.Normal, /*reportErrors*/ false, /*containingMessageChain*/ undefined, /*inferenceContext*/ undefined)) { + if (getSignatureApplicabilityError(node, args, candidate, relation, CheckMode.Normal, /*reportErrors*/ false, /*containingMessageChain*/ undefined)) { candidatesForArgumentError = [candidate]; return undefined; } @@ -36503,7 +36475,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } for (let candidateIndex = 0; candidateIndex < candidates.length; candidateIndex++) { - let candidate = candidates[candidateIndex]; + const candidate = candidates[candidateIndex]; if (!hasCorrectTypeArgumentArity(candidate, typeArguments) || !hasCorrectArity(node, args, candidate, signatureHelpTrailingComma)) { continue; } @@ -36512,14 +36484,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { let inferenceContext: InferenceContext | undefined; if (candidate.typeParameters) { - // If we are *inside the body of candidate*, we need to create a clone of `candidate` with differing type parameter identities, - // so our inference results for this call doesn't pollute expression types referencing the outer type parameter! - const paramLocation = candidate.typeParameters[0].symbol.declarations?.[0]?.parent; - const candidateParameterContext = paramLocation || (candidate.declaration && isConstructorDeclaration(candidate.declaration) ? candidate.declaration.parent : candidate.declaration); - if (candidateParameterContext && findAncestor(node, a => a === candidateParameterContext)) { - candidate = getImplementationSignature(candidate); - } - let typeArgumentTypes: readonly Type[] | undefined; + let typeArgumentTypes: Type[] | undefined; if (some(typeArguments)) { typeArgumentTypes = checkTypeArguments(candidate, typeArguments, /*reportErrors*/ false); if (!typeArgumentTypes) { @@ -36528,10 +36493,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } } else { - inferenceContext = createInferenceContext(candidate.typeParameters!, candidate, /*flags*/ isInJSFile(node) ? InferenceFlags.AnyDefault : InferenceFlags.None); - // The resulting type arguments are instantiated with the inference context mapper, as the inferred types may still contain references to the inference context's - // type variables via contextual projection. These are kept generic until all inferences are locked in, so the dependencies expressed can pass constraint checks. - typeArgumentTypes = instantiateTypes(inferTypeArguments(node, candidate, args, argCheckMode | CheckMode.SkipGenericFunctions, inferenceContext), inferenceContext.nonFixingMapper); + inferenceContext = createInferenceContext(candidate.typeParameters, candidate, /*flags*/ isInJSFile(node) ? InferenceFlags.AnyDefault : InferenceFlags.None); + typeArgumentTypes = inferTypeArguments(node, candidate, args, argCheckMode | CheckMode.SkipGenericFunctions, inferenceContext); argCheckMode |= inferenceContext.flags & InferenceFlags.SkippedGenericFunction ? CheckMode.SkipGenericFunctions : CheckMode.Normal; } checkCandidate = getSignatureInstantiation(candidate, typeArgumentTypes, isInJSFile(candidate.declaration), inferenceContext && inferenceContext.inferredTypeParameters); @@ -36545,7 +36508,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { else { checkCandidate = candidate; } - if (getSignatureApplicabilityError(node, args, checkCandidate, relation, argCheckMode, /*reportErrors*/ false, /*containingMessageChain*/ undefined, inferenceContext)) { + if (getSignatureApplicabilityError(node, args, checkCandidate, relation, argCheckMode, /*reportErrors*/ false, /*containingMessageChain*/ undefined)) { // Give preference to error candidates that have no rest parameters (as they are more specific) (candidatesForArgumentError || (candidatesForArgumentError = [])).push(checkCandidate); continue; @@ -36556,7 +36519,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // round of type inference and applicability checking for this particular candidate. argCheckMode = CheckMode.Normal; if (inferenceContext) { - const typeArgumentTypes = instantiateTypes(inferTypeArguments(node, candidate, args, argCheckMode, inferenceContext), inferenceContext.mapper); + const typeArgumentTypes = inferTypeArguments(node, candidate, args, argCheckMode, inferenceContext); checkCandidate = getSignatureInstantiation(candidate, typeArgumentTypes, isInJSFile(candidate.declaration), inferenceContext.inferredTypeParameters); // If the original signature has a generic rest type, instantiation may produce a // signature with different arity and we need to perform another arity check. @@ -36565,7 +36528,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { continue; } } - if (getSignatureApplicabilityError(node, args, checkCandidate, relation, argCheckMode, /*reportErrors*/ false, /*containingMessageChain*/ undefined, inferenceContext)) { + if (getSignatureApplicabilityError(node, args, checkCandidate, relation, argCheckMode, /*reportErrors*/ false, /*containingMessageChain*/ undefined)) { // Give preference to error candidates that have no rest parameters (as they are more specific) (candidatesForArgumentError || (candidatesForArgumentError = [])).push(checkCandidate); continue; @@ -41272,10 +41235,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } } } - // TODO: The signature may reference any outer inference contexts, but we map pop off and then apply new inference contexts, and thus get different inferred types. - // That this is cached on the *first* such attempt is not currently an issue, since expression types *also* get cached on the first pass. If we ever properly speculate, though, - // the cached "isolatedSignatureType" signature field absolutely needs to be included in the list of speculative caches. - return getOrCreateTypeFromSignature(instantiateSignatureInContextOf(signature, contextualSignature, context), flatMap(inferenceContexts, c => c && map(c.inferences, i => i.typeParameter)).slice()); + return getOrCreateTypeFromSignature(instantiateSignatureInContextOf(signature, contextualSignature, context)); } } } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 5097d295f57ab..26ce72bd93582 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -6492,7 +6492,7 @@ export const enum ObjectFlags { CouldContainTypeVariablesComputed = 1 << 19, // CouldContainTypeVariables flag has been computed /** @internal */ CouldContainTypeVariables = 1 << 20, // Type could contain a type variable - + SingleSignatureType = 1 << 27, // A single signature type extracted from a potentially broader type ClassOrInterface = Class | Interface, /** @internal */ RequiresWidening = ContainsWideningType | ContainsObjectOrArrayLiteral, @@ -6508,7 +6508,6 @@ export const enum ObjectFlags { ContainsSpread = 1 << 21, // Object literal contains spread operation ObjectRestType = 1 << 22, // Originates in object rest declaration InstantiationExpressionType = 1 << 23, // Originates in instantiation expression - SingleSignatureType = 1 << 27, // A single signature type extracted from a potentially broader type /** @internal */ IsClassInstanceClone = 1 << 24, // Type is a clone of a class instance type // Flags that require TypeFlags.Object and ObjectFlags.Reference @@ -6723,12 +6722,6 @@ export interface AnonymousType extends ObjectType { instantiations?: Map; // Instantiations of generic type alias (undefined if non-generic) } -/** @internal */ -// A SingleSignatureType may have bespoke outer type parameters to handle free type variable inferences -export interface SingleSignatureType extends AnonymousType { - outerTypeParameters?: TypeParameter[]; -} - /** @internal */ export interface InstantiationExpressionType extends AnonymousType { node: NodeWithTypeArguments; @@ -7014,8 +7007,6 @@ export interface Signature { isolatedSignatureType?: ObjectType; // A manufactured type that just contains the signature for purposes of signature comparison /** @internal */ instantiations?: Map; // Generic signature instantiation cache - /** @internal */ - implementationSignatureCache?: Signature; // Copy of the signature with fresh type parameters to use in checking the body of a potentially self-referential generic function (deferred) } export const enum IndexKind { @@ -7123,6 +7114,7 @@ export interface InferenceContext { mapper: TypeMapper; // Mapper that fixes inferences nonFixingMapper: TypeMapper; // Mapper that doesn't fix inferences returnMapper?: TypeMapper; // Type mapper for inferences from return types (if any) + outerReturnMapper?: TypeMapper; // Type mapper for inferences from return types of outer function (if any) inferredTypeParameters?: readonly TypeParameter[]; // Inferred type parameters for function result intraExpressionInferenceSites?: IntraExpressionInferenceSite[]; } diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 2967f4534e175..b8c2606bf5ed4 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -6705,11 +6705,11 @@ declare namespace ts { JSLiteral = 4096, FreshLiteral = 8192, ArrayLiteral = 16384, + SingleSignatureType = 134217728, ClassOrInterface = 3, ContainsSpread = 2097152, ObjectRestType = 4194304, InstantiationExpressionType = 8388608, - SingleSignatureType = 134217728, } interface ObjectType extends Type { objectFlags: ObjectFlags; diff --git a/tests/baselines/reference/declarationEmitHigherOrderRetainedGenerics.types b/tests/baselines/reference/declarationEmitHigherOrderRetainedGenerics.types index 32975c6fe794a..1cb7b68c29b8f 100644 --- a/tests/baselines/reference/declarationEmitHigherOrderRetainedGenerics.types +++ b/tests/baselines/reference/declarationEmitHigherOrderRetainedGenerics.types @@ -2,7 +2,7 @@ === Performance Stats === Type Count: 1,000 -Instantiation count: 2,500 -> 5,000 +Instantiation count: 2,500 === declarationEmitHigherOrderRetainedGenerics.ts === export interface TypeLambda { diff --git a/tests/baselines/reference/genericCallInferenceInConditionalTypes1.symbols b/tests/baselines/reference/genericCallInferenceInConditionalTypes1.symbols new file mode 100644 index 0000000000000..7332aa25baa12 --- /dev/null +++ b/tests/baselines/reference/genericCallInferenceInConditionalTypes1.symbols @@ -0,0 +1,173 @@ +//// [tests/cases/compiler/genericCallInferenceInConditionalTypes1.ts] //// + +=== genericCallInferenceInConditionalTypes1.ts === +// https://github.com/microsoft/TypeScript/issues/59937 + +type Ref = { +>Ref : Symbol(Ref, Decl(genericCallInferenceInConditionalTypes1.ts, 0, 0)) +>T : Symbol(T, Decl(genericCallInferenceInConditionalTypes1.ts, 2, 9)) + + current: T; +>current : Symbol(current, Decl(genericCallInferenceInConditionalTypes1.ts, 2, 15)) +>T : Symbol(T, Decl(genericCallInferenceInConditionalTypes1.ts, 2, 9)) + +}; + +type FunctionComponent

= (props: P) => unknown; +>FunctionComponent : Symbol(FunctionComponent, Decl(genericCallInferenceInConditionalTypes1.ts, 4, 2)) +>P : Symbol(P, Decl(genericCallInferenceInConditionalTypes1.ts, 6, 23)) +>props : Symbol(props, Decl(genericCallInferenceInConditionalTypes1.ts, 6, 29)) +>P : Symbol(P, Decl(genericCallInferenceInConditionalTypes1.ts, 6, 23)) + +type ComponentProps> = +>ComponentProps : Symbol(ComponentProps, Decl(genericCallInferenceInConditionalTypes1.ts, 6, 50)) +>T : Symbol(T, Decl(genericCallInferenceInConditionalTypes1.ts, 8, 20)) +>FunctionComponent : Symbol(FunctionComponent, Decl(genericCallInferenceInConditionalTypes1.ts, 4, 2)) + + T extends FunctionComponent ? P : {}; +>T : Symbol(T, Decl(genericCallInferenceInConditionalTypes1.ts, 8, 20)) +>FunctionComponent : Symbol(FunctionComponent, Decl(genericCallInferenceInConditionalTypes1.ts, 4, 2)) +>P : Symbol(P, Decl(genericCallInferenceInConditionalTypes1.ts, 9, 35)) +>P : Symbol(P, Decl(genericCallInferenceInConditionalTypes1.ts, 9, 35)) + +type PropsWithoutRef

= P extends any +>PropsWithoutRef : Symbol(PropsWithoutRef, Decl(genericCallInferenceInConditionalTypes1.ts, 9, 48)) +>P : Symbol(P, Decl(genericCallInferenceInConditionalTypes1.ts, 11, 21)) +>P : Symbol(P, Decl(genericCallInferenceInConditionalTypes1.ts, 11, 21)) + + ? "ref" extends keyof P +>P : Symbol(P, Decl(genericCallInferenceInConditionalTypes1.ts, 11, 21)) + + ? Omit +>Omit : Symbol(Omit, Decl(lib.es5.d.ts, --, --)) +>P : Symbol(P, Decl(genericCallInferenceInConditionalTypes1.ts, 11, 21)) + + : P +>P : Symbol(P, Decl(genericCallInferenceInConditionalTypes1.ts, 11, 21)) + + : P; +>P : Symbol(P, Decl(genericCallInferenceInConditionalTypes1.ts, 11, 21)) + +type ComponentPropsWithoutRef> = +>ComponentPropsWithoutRef : Symbol(ComponentPropsWithoutRef, Decl(genericCallInferenceInConditionalTypes1.ts, 15, 6)) +>T : Symbol(T, Decl(genericCallInferenceInConditionalTypes1.ts, 17, 30)) +>FunctionComponent : Symbol(FunctionComponent, Decl(genericCallInferenceInConditionalTypes1.ts, 4, 2)) + + PropsWithoutRef>; +>PropsWithoutRef : Symbol(PropsWithoutRef, Decl(genericCallInferenceInConditionalTypes1.ts, 9, 48)) +>ComponentProps : Symbol(ComponentProps, Decl(genericCallInferenceInConditionalTypes1.ts, 6, 50)) +>T : Symbol(T, Decl(genericCallInferenceInConditionalTypes1.ts, 17, 30)) + +declare function forwardRef( +>forwardRef : Symbol(forwardRef, Decl(genericCallInferenceInConditionalTypes1.ts, 18, 37)) +>T : Symbol(T, Decl(genericCallInferenceInConditionalTypes1.ts, 20, 28)) +>P : Symbol(P, Decl(genericCallInferenceInConditionalTypes1.ts, 20, 30)) + + component: (props: P, ref: Ref) => unknown, +>component : Symbol(component, Decl(genericCallInferenceInConditionalTypes1.ts, 20, 34)) +>props : Symbol(props, Decl(genericCallInferenceInConditionalTypes1.ts, 21, 14)) +>P : Symbol(P, Decl(genericCallInferenceInConditionalTypes1.ts, 20, 30)) +>ref : Symbol(ref, Decl(genericCallInferenceInConditionalTypes1.ts, 21, 23)) +>Ref : Symbol(Ref, Decl(genericCallInferenceInConditionalTypes1.ts, 0, 0)) +>T : Symbol(T, Decl(genericCallInferenceInConditionalTypes1.ts, 20, 28)) + +): (props: P & { ref?: Ref }) => unknown; +>props : Symbol(props, Decl(genericCallInferenceInConditionalTypes1.ts, 22, 4)) +>P : Symbol(P, Decl(genericCallInferenceInConditionalTypes1.ts, 20, 30)) +>ref : Symbol(ref, Decl(genericCallInferenceInConditionalTypes1.ts, 22, 16)) +>Ref : Symbol(Ref, Decl(genericCallInferenceInConditionalTypes1.ts, 0, 0)) +>T : Symbol(T, Decl(genericCallInferenceInConditionalTypes1.ts, 20, 28)) + +const ComponentWithForwardRef = forwardRef( +>ComponentWithForwardRef : Symbol(ComponentWithForwardRef, Decl(genericCallInferenceInConditionalTypes1.ts, 24, 5)) +>forwardRef : Symbol(forwardRef, Decl(genericCallInferenceInConditionalTypes1.ts, 18, 37)) + + >( +>T : Symbol(T, Decl(genericCallInferenceInConditionalTypes1.ts, 25, 3)) +>FunctionComponent : Symbol(FunctionComponent, Decl(genericCallInferenceInConditionalTypes1.ts, 4, 2)) + + props: ComponentPropsWithoutRef, +>props : Symbol(props, Decl(genericCallInferenceInConditionalTypes1.ts, 25, 37)) +>ComponentPropsWithoutRef : Symbol(ComponentPropsWithoutRef, Decl(genericCallInferenceInConditionalTypes1.ts, 15, 6)) +>T : Symbol(T, Decl(genericCallInferenceInConditionalTypes1.ts, 25, 3)) + + ref: Ref, +>ref : Symbol(ref, Decl(genericCallInferenceInConditionalTypes1.ts, 26, 39)) +>Ref : Symbol(Ref, Decl(genericCallInferenceInConditionalTypes1.ts, 0, 0)) +>HTMLElement : Symbol(HTMLElement, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) + + ) => { + return null; + }, +); + +type Test = T extends { component?: infer Component } +>Test : Symbol(Test, Decl(genericCallInferenceInConditionalTypes1.ts, 31, 2)) +>T : Symbol(T, Decl(genericCallInferenceInConditionalTypes1.ts, 33, 10)) +>T : Symbol(T, Decl(genericCallInferenceInConditionalTypes1.ts, 33, 10)) +>component : Symbol(component, Decl(genericCallInferenceInConditionalTypes1.ts, 33, 26)) +>Component : Symbol(Component, Decl(genericCallInferenceInConditionalTypes1.ts, 33, 44)) + + ? Component extends FunctionComponent +>Component : Symbol(Component, Decl(genericCallInferenceInConditionalTypes1.ts, 33, 44)) +>FunctionComponent : Symbol(FunctionComponent, Decl(genericCallInferenceInConditionalTypes1.ts, 4, 2)) + + ? ComponentProps +>ComponentProps : Symbol(ComponentProps, Decl(genericCallInferenceInConditionalTypes1.ts, 6, 50)) +>Component : Symbol(Component, Decl(genericCallInferenceInConditionalTypes1.ts, 33, 44)) + + : never + : never; + +// the first one here has a chance to pollute the cache +type Result1 = ComponentProps; +>Result1 : Symbol(Result1, Decl(genericCallInferenceInConditionalTypes1.ts, 37, 10)) +>ComponentProps : Symbol(ComponentProps, Decl(genericCallInferenceInConditionalTypes1.ts, 6, 50)) +>ComponentWithForwardRef : Symbol(ComponentWithForwardRef, Decl(genericCallInferenceInConditionalTypes1.ts, 24, 5)) + +// that could be incorrectly reused by this one +type Result2 = Test<{ component: typeof ComponentWithForwardRef }>; // no `T` leak +>Result2 : Symbol(Result2, Decl(genericCallInferenceInConditionalTypes1.ts, 40, 62)) +>Test : Symbol(Test, Decl(genericCallInferenceInConditionalTypes1.ts, 31, 2)) +>component : Symbol(component, Decl(genericCallInferenceInConditionalTypes1.ts, 42, 21)) +>ComponentWithForwardRef : Symbol(ComponentWithForwardRef, Decl(genericCallInferenceInConditionalTypes1.ts, 24, 5)) + +// same as ComponentWithForwardRef above but using a resolved signature instead of a direct inferred result of `forwardRef` +declare const ComponentWithForwardRef2: >( +>ComponentWithForwardRef2 : Symbol(ComponentWithForwardRef2, Decl(genericCallInferenceInConditionalTypes1.ts, 45, 13)) +>T : Symbol(T, Decl(genericCallInferenceInConditionalTypes1.ts, 45, 41)) +>FunctionComponent : Symbol(FunctionComponent, Decl(genericCallInferenceInConditionalTypes1.ts, 4, 2)) + + props: PropsWithoutRef> & { +>props : Symbol(props, Decl(genericCallInferenceInConditionalTypes1.ts, 45, 75)) +>PropsWithoutRef : Symbol(PropsWithoutRef, Decl(genericCallInferenceInConditionalTypes1.ts, 9, 48)) +>ComponentProps : Symbol(ComponentProps, Decl(genericCallInferenceInConditionalTypes1.ts, 6, 50)) +>T : Symbol(T, Decl(genericCallInferenceInConditionalTypes1.ts, 45, 41)) + + className?: string; +>className : Symbol(className, Decl(genericCallInferenceInConditionalTypes1.ts, 46, 47)) + + as?: T | undefined; +>as : Symbol(as, Decl(genericCallInferenceInConditionalTypes1.ts, 47, 23)) +>T : Symbol(T, Decl(genericCallInferenceInConditionalTypes1.ts, 45, 41)) + + } & { + ref?: Ref | undefined; +>ref : Symbol(ref, Decl(genericCallInferenceInConditionalTypes1.ts, 49, 7)) +>Ref : Symbol(Ref, Decl(genericCallInferenceInConditionalTypes1.ts, 0, 0)) +>HTMLElement : Symbol(HTMLElement, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) + + }, +) => unknown; + +type Result3 = ComponentProps; +>Result3 : Symbol(Result3, Decl(genericCallInferenceInConditionalTypes1.ts, 52, 13)) +>ComponentProps : Symbol(ComponentProps, Decl(genericCallInferenceInConditionalTypes1.ts, 6, 50)) +>ComponentWithForwardRef2 : Symbol(ComponentWithForwardRef2, Decl(genericCallInferenceInConditionalTypes1.ts, 45, 13)) + +type Result4 = Test<{ component: typeof ComponentWithForwardRef2 }>; +>Result4 : Symbol(Result4, Decl(genericCallInferenceInConditionalTypes1.ts, 54, 63)) +>Test : Symbol(Test, Decl(genericCallInferenceInConditionalTypes1.ts, 31, 2)) +>component : Symbol(component, Decl(genericCallInferenceInConditionalTypes1.ts, 55, 21)) +>ComponentWithForwardRef2 : Symbol(ComponentWithForwardRef2, Decl(genericCallInferenceInConditionalTypes1.ts, 45, 13)) + diff --git a/tests/baselines/reference/genericCallInferenceInConditionalTypes1.types b/tests/baselines/reference/genericCallInferenceInConditionalTypes1.types new file mode 100644 index 0000000000000..0257dab6a9720 --- /dev/null +++ b/tests/baselines/reference/genericCallInferenceInConditionalTypes1.types @@ -0,0 +1,151 @@ +//// [tests/cases/compiler/genericCallInferenceInConditionalTypes1.ts] //// + +=== genericCallInferenceInConditionalTypes1.ts === +// https://github.com/microsoft/TypeScript/issues/59937 + +type Ref = { +>Ref : Ref +> : ^^^^^^ + + current: T; +>current : T +> : ^ + +}; + +type FunctionComponent

= (props: P) => unknown; +>FunctionComponent : FunctionComponent

+> : ^^^^^^^^^^^^^^^^^^^^ +>props : P +> : ^ + +type ComponentProps> = +>ComponentProps : ComponentProps +> : ^^^^^^^^^^^^^^^^^ + + T extends FunctionComponent ? P : {}; + +type PropsWithoutRef

= P extends any +>PropsWithoutRef : PropsWithoutRef

+> : ^^^^^^^^^^^^^^^^^^ + + ? "ref" extends keyof P + ? Omit + : P + : P; + +type ComponentPropsWithoutRef> = +>ComponentPropsWithoutRef : ComponentPropsWithoutRef +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + PropsWithoutRef>; + +declare function forwardRef( +>forwardRef : (component: (props: P, ref: Ref) => unknown) => (props: P & { ref?: Ref; }) => unknown +> : ^ ^^ ^^ ^^ ^^^^^ + + component: (props: P, ref: Ref) => unknown, +>component : (props: P, ref: Ref) => unknown +> : ^ ^^ ^^ ^^ ^^^^^ +>props : P +> : ^ +>ref : Ref +> : ^^^^^^ + +): (props: P & { ref?: Ref }) => unknown; +>props : P & { ref?: Ref; } +> : ^^^^^^^^^^^^ ^^^ +>ref : Ref | undefined +> : ^^^^^^^^^^^^^^^^^^ + +const ComponentWithForwardRef = forwardRef( +>ComponentWithForwardRef : >(props: PropsWithoutRef> & { ref?: Ref | undefined; }) => unknown +> : ^ ^^^^^^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>forwardRef( >( props: ComponentPropsWithoutRef, ref: Ref, ) => { return null; },) : >(props: PropsWithoutRef> & { ref?: Ref | undefined; }) => unknown +> : ^ ^^^^^^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>forwardRef : (component: (props: P, ref: Ref) => unknown) => (props: P & { ref?: Ref; }) => unknown +> : ^ ^^ ^^ ^^ ^^^^^ + + >( +>>( props: ComponentPropsWithoutRef, ref: Ref, ) => { return null; } : >(props: ComponentPropsWithoutRef, ref: Ref) => null +> : ^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^^^^^^^^ + + props: ComponentPropsWithoutRef, +>props : PropsWithoutRef> +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + ref: Ref, +>ref : Ref +> : ^^^^^^^^^^^^^^^^ + + ) => { + return null; + }, +); + +type Test = T extends { component?: infer Component } +>Test : Test +> : ^^^^^^^ +>component : Component | undefined +> : ^^^^^^^^^^^^^^^^^^^^^ + + ? Component extends FunctionComponent + ? ComponentProps + : never + : never; + +// the first one here has a chance to pollute the cache +type Result1 = ComponentProps; +>Result1 : Omit & { ref?: Ref | undefined; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>ComponentWithForwardRef : >(props: PropsWithoutRef> & { ref?: Ref | undefined; }) => unknown +> : ^ ^^^^^^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +// that could be incorrectly reused by this one +type Result2 = Test<{ component: typeof ComponentWithForwardRef }>; // no `T` leak +>Result2 : Omit & { ref?: Ref | undefined; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>component : >(props: PropsWithoutRef> & { ref?: Ref | undefined; }) => unknown +> : ^ ^^^^^^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>ComponentWithForwardRef : >(props: PropsWithoutRef> & { ref?: Ref | undefined; }) => unknown +> : ^ ^^^^^^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +// same as ComponentWithForwardRef above but using a resolved signature instead of a direct inferred result of `forwardRef` +declare const ComponentWithForwardRef2: >( +>ComponentWithForwardRef2 : >(props: PropsWithoutRef> & { className?: string; as?: T | undefined; } & { ref?: Ref | undefined; }) => unknown +> : ^ ^^^^^^^^^ ^^ ^^ ^^^^^ + + props: PropsWithoutRef> & { +>props : PropsWithoutRef> & { className?: string; as?: T | undefined; } & { ref?: Ref | undefined; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^ ^^^^^^^^^^^^^^ ^^^ + + className?: string; +>className : string | undefined +> : ^^^^^^^^^^^^^^^^^^ + + as?: T | undefined; +>as : T | undefined +> : ^^^^^^^^^^^^^ + + } & { + ref?: Ref | undefined; +>ref : Ref | undefined +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + }, +) => unknown; + +type Result3 = ComponentProps; +>Result3 : Omit & { className?: string; as?: FunctionComponent | undefined; } & { ref?: Ref | undefined; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^ +>ComponentWithForwardRef2 : >(props: PropsWithoutRef> & { className?: string; as?: T | undefined; } & { ref?: Ref | undefined; }) => unknown +> : ^ ^^^^^^^^^ ^^ ^^ ^^^^^ + +type Result4 = Test<{ component: typeof ComponentWithForwardRef2 }>; +>Result4 : Omit & { className?: string; as?: FunctionComponent | undefined; } & { ref?: Ref | undefined; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^ +>component : >(props: PropsWithoutRef> & { className?: string; as?: T | undefined; } & { ref?: Ref | undefined; }) => unknown +> : ^ ^^^^^^^^^ ^^ ^^ ^^^^^ +>ComponentWithForwardRef2 : >(props: PropsWithoutRef> & { className?: string; as?: T | undefined; } & { ref?: Ref | undefined; }) => unknown +> : ^ ^^^^^^^^^ ^^ ^^ ^^^^^ + diff --git a/tests/baselines/reference/genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.symbols b/tests/baselines/reference/genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.symbols new file mode 100644 index 0000000000000..d7a63d38d355d --- /dev/null +++ b/tests/baselines/reference/genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.symbols @@ -0,0 +1,168 @@ +//// [tests/cases/compiler/genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts] //// + +=== genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts === +declare const EffectTypeId: unique symbol; +>EffectTypeId : Symbol(EffectTypeId, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 0, 13)) + +interface Variance { +>Variance : Symbol(Variance, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 0, 42)) +>A : Symbol(A, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 2, 19)) +>E : Symbol(E, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 2, 25)) +>R : Symbol(R, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 2, 32)) + + readonly [EffectTypeId]: VarianceStruct; +>[EffectTypeId] : Symbol(Variance[EffectTypeId], Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 2, 41)) +>EffectTypeId : Symbol(EffectTypeId, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 0, 13)) +>VarianceStruct : Symbol(VarianceStruct, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 6, 36)) +>A : Symbol(A, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 2, 19)) +>E : Symbol(E, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 2, 25)) +>R : Symbol(R, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 2, 32)) +} + +type Covariant = (_: never) => A; +>Covariant : Symbol(Covariant, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 4, 1)) +>A : Symbol(A, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 6, 15)) +>_ : Symbol(_, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 6, 21)) +>A : Symbol(A, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 6, 15)) + +interface VarianceStruct { +>VarianceStruct : Symbol(VarianceStruct, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 6, 36)) +>A : Symbol(A, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 8, 25)) +>E : Symbol(E, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 8, 31)) +>R : Symbol(R, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 8, 38)) + + readonly _V: string; +>_V : Symbol(VarianceStruct._V, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 8, 47)) + + readonly _A: Covariant; +>_A : Symbol(VarianceStruct._A, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 9, 22)) +>Covariant : Symbol(Covariant, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 4, 1)) +>A : Symbol(A, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 8, 25)) + + readonly _E: Covariant; +>_E : Symbol(VarianceStruct._E, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 10, 28)) +>Covariant : Symbol(Covariant, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 4, 1)) +>E : Symbol(E, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 8, 31)) + + readonly _R: Covariant; +>_R : Symbol(VarianceStruct._R, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 11, 28)) +>Covariant : Symbol(Covariant, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 4, 1)) +>R : Symbol(R, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 8, 38)) +} + +interface Effect +>Effect : Symbol(Effect, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 13, 1)) +>A : Symbol(A, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 15, 17)) +>E : Symbol(E, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 15, 23)) +>R : Symbol(R, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 15, 38)) + + extends Variance {} +>Variance : Symbol(Variance, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 0, 42)) +>A : Symbol(A, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 15, 17)) +>E : Symbol(E, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 15, 23)) +>R : Symbol(R, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 15, 38)) + +declare const succeed: (value: A) => Effect; +>succeed : Symbol(succeed, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 18, 13)) +>A : Symbol(A, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 18, 24)) +>value : Symbol(value, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 18, 27)) +>A : Symbol(A, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 18, 24)) +>Effect : Symbol(Effect, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 13, 1)) +>A : Symbol(A, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 18, 24)) + +type F = Y extends { _type: infer Z } +>F : Symbol(F, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 18, 50)) +>X : Symbol(X, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 20, 7)) +>Y : Symbol(Y, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 20, 9)) +>Y : Symbol(Y, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 20, 9)) +>_type : Symbol(_type, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 20, 26)) +>Z : Symbol(Z, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 20, 39)) + + ? X extends Effect +>X : Symbol(X, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 20, 7)) +>Effect : Symbol(Effect, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 13, 1)) +>A : Symbol(A, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 21, 26)) +>E : Symbol(E, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 21, 35)) +>R : Symbol(R, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 21, 44)) + + ? Effect +>Effect : Symbol(Effect, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 13, 1)) +>A : Symbol(A, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 21, 26)) +>E : Symbol(E, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 21, 35)) +>R : Symbol(R, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 21, 44)) +>Z : Symbol(Z, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 20, 39)) + + : X +>X : Symbol(X, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 20, 7)) + + : X; +>X : Symbol(X, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 20, 7)) + +type ProxyMap = { +>ProxyMap : Symbol(ProxyMap, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 24, 6)) +>Service : Symbol(Service, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 26, 14)) + + [K in keyof Service]: (Service & { _type: Service })[K]; +>K : Symbol(K, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 27, 3)) +>Service : Symbol(Service, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 26, 14)) +>Service : Symbol(Service, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 26, 14)) +>_type : Symbol(_type, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 27, 36)) +>Service : Symbol(Service, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 26, 14)) +>K : Symbol(K, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 27, 3)) + +}; + +declare const implement: () => , X>( +>implement : Symbol(implement, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 30, 13)) +>T : Symbol(T, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 30, 26)) +>I : Symbol(I, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 30, 35)) +>ReadonlyArray : Symbol(ReadonlyArray, Decl(lib.es5.d.ts, --, --)) +>X : Symbol(X, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 30, 64)) + + x: (...i: I) => X, +>x : Symbol(x, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 30, 68)) +>i : Symbol(i, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 31, 6)) +>I : Symbol(I, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 30, 35)) +>X : Symbol(X, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 30, 64)) + +) => (...i: I) => F; +>i : Symbol(i, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 32, 6)) +>I : Symbol(I, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 30, 35)) +>F : Symbol(F, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 18, 50)) +>X : Symbol(X, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 30, 64)) +>T : Symbol(T, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 30, 26)) + +class XXX { +>XXX : Symbol(XXX, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 32, 26)) + + log = implement()((n: N) => succeed(n)); +>log : Symbol(XXX.log, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 34, 11)) +>implement : Symbol(implement, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 30, 13)) +>N : Symbol(N, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 35, 27)) +>n : Symbol(n, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 35, 45)) +>N : Symbol(N, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 35, 27)) +>succeed : Symbol(succeed, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 18, 13)) +>n : Symbol(n, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 35, 45)) +} + +export declare const inner: XXX; +>inner : Symbol(inner, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 38, 20)) +>XXX : Symbol(XXX, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 32, 26)) + +export declare const outer: ProxyMap; +>outer : Symbol(outer, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 39, 20)) +>ProxyMap : Symbol(ProxyMap, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 24, 6)) +>XXX : Symbol(XXX, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 32, 26)) + +export const a = inner.log(100); // Effect<100, never, never> +>a : Symbol(a, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 41, 12)) +>inner.log : Symbol(XXX.log, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 34, 11)) +>inner : Symbol(inner, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 38, 20)) +>log : Symbol(XXX.log, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 34, 11)) + +export const b = outer.log(100); // Effect<100, never, XXX> +>b : Symbol(b, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 42, 12)) +>outer.log : Symbol(log, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 34, 11)) +>outer : Symbol(outer, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 39, 20)) +>log : Symbol(log, Decl(genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts, 34, 11)) + diff --git a/tests/baselines/reference/genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.types b/tests/baselines/reference/genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.types new file mode 100644 index 0000000000000..6ff710a93595e --- /dev/null +++ b/tests/baselines/reference/genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.types @@ -0,0 +1,144 @@ +//// [tests/cases/compiler/genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts] //// + +=== genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts === +declare const EffectTypeId: unique symbol; +>EffectTypeId : unique symbol +> : ^^^^^^^^^^^^^ + +interface Variance { + readonly [EffectTypeId]: VarianceStruct; +>[EffectTypeId] : VarianceStruct +> : ^^^^^^^^^^^^^^^^^^^^^^^ +>EffectTypeId : unique symbol +> : ^^^^^^^^^^^^^ +} + +type Covariant = (_: never) => A; +>Covariant : Covariant +> : ^^^^^^^^^^^^ +>_ : never +> : ^^^^^ + +interface VarianceStruct { + readonly _V: string; +>_V : string +> : ^^^^^^ + + readonly _A: Covariant; +>_A : Covariant +> : ^^^^^^^^^^^^ + + readonly _E: Covariant; +>_E : Covariant +> : ^^^^^^^^^^^^ + + readonly _R: Covariant; +>_R : Covariant +> : ^^^^^^^^^^^^ +} + +interface Effect + extends Variance {} + +declare const succeed: (value: A) => Effect; +>succeed : (value: A) => Effect +> : ^ ^^ ^^ ^^^^^ +>value : A +> : ^ + +type F = Y extends { _type: infer Z } +>F : F +> : ^^^^^^^ +>_type : Z +> : ^ + + ? X extends Effect + ? Effect + : X + : X; + +type ProxyMap = { +>ProxyMap : ProxyMap +> : ^^^^^^^^^^^^^^^^^ + + [K in keyof Service]: (Service & { _type: Service })[K]; +>_type : Service +> : ^^^^^^^ + +}; + +declare const implement: () => , X>( +>implement : () => , X>(x: (...i: I) => X) => (...i: I) => F +> : ^ ^^^^^^^ + + x: (...i: I) => X, +>x : (...i: I) => X +> : ^^^^ ^^ ^^^^^ +>i : I +> : ^ + +) => (...i: I) => F; +>i : I +> : ^ + +class XXX { +>XXX : XXX +> : ^^^ + + log = implement()((n: N) => succeed(n)); +>log : (n: N) => F, this> +> : ^ ^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>implement()((n: N) => succeed(n)) : (n: N) => F, this> +> : ^ ^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>implement() : , X>(x: (...i: I) => X) => (...i: I) => F +> : ^ ^^^^^^^^^ ^^ ^^ ^^^^^^ ^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^ +>implement : () => , X>(x: (...i: I) => X) => (...i: I) => F +> : ^ ^^^^^^^ +>(n: N) => succeed(n) : (n: N) => Effect +> : ^ ^^^^^^^^^ ^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>n : N +> : ^ +>succeed(n) : Effect +> : ^^^^^^^^^^^^^^^^^^^^^^^ +>succeed : (value: A) => Effect +> : ^ ^^ ^^ ^^^^^ +>n : N +> : ^ +} + +export declare const inner: XXX; +>inner : XXX +> : ^^^ + +export declare const outer: ProxyMap; +>outer : ProxyMap +> : ^^^^^^^^^^^^^ + +export const a = inner.log(100); // Effect<100, never, never> +>a : F, this> +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>inner.log(100) : F, this> +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>inner.log : (n: N) => F, this> +> : ^ ^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>inner : XXX +> : ^^^ +>log : (n: N) => F, this> +> : ^ ^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>100 : 100 +> : ^^^ + +export const b = outer.log(100); // Effect<100, never, XXX> +>b : F, this> +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>outer.log(100) : F, this> +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>outer.log : (n: N) => F, this> +> : ^ ^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>outer : ProxyMap +> : ^^^^^^^^^^^^^ +>log : (n: N) => F, this> +> : ^ ^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>100 : 100 +> : ^^^ + diff --git a/tests/baselines/reference/genericCallInferenceWithGenericLocalFunction.symbols b/tests/baselines/reference/genericCallInferenceWithGenericLocalFunction.symbols index dec6af6bac2c5..9dd6d91bb1f7d 100644 --- a/tests/baselines/reference/genericCallInferenceWithGenericLocalFunction.symbols +++ b/tests/baselines/reference/genericCallInferenceWithGenericLocalFunction.symbols @@ -42,3 +42,60 @@ const added2 = addP2({ bar: 2 }); >addP2 : Symbol(addP2, Decl(genericCallInferenceWithGenericLocalFunction.ts, 9, 5)) >bar : Symbol(bar, Decl(genericCallInferenceWithGenericLocalFunction.ts, 10, 22)) +function withP3

(p: P) { +>withP3 : Symbol(withP3, Decl(genericCallInferenceWithGenericLocalFunction.ts, 10, 33)) +>P : Symbol(P, Decl(genericCallInferenceWithGenericLocalFunction.ts, 12, 16)) +>p : Symbol(p, Decl(genericCallInferenceWithGenericLocalFunction.ts, 12, 19)) +>P : Symbol(P, Decl(genericCallInferenceWithGenericLocalFunction.ts, 12, 16)) + + const m = +>m : Symbol(m, Decl(genericCallInferenceWithGenericLocalFunction.ts, 13, 7)) + + (from: I) => +>I : Symbol(I, Decl(genericCallInferenceWithGenericLocalFunction.ts, 14, 5)) +>from : Symbol(from, Decl(genericCallInferenceWithGenericLocalFunction.ts, 14, 9)) +>I : Symbol(I, Decl(genericCallInferenceWithGenericLocalFunction.ts, 14, 5)) + + (from2: I2) => ({ ...from, ...from2, ...p }); +>I2 : Symbol(I2, Decl(genericCallInferenceWithGenericLocalFunction.ts, 15, 5)) +>from2 : Symbol(from2, Decl(genericCallInferenceWithGenericLocalFunction.ts, 15, 10)) +>I2 : Symbol(I2, Decl(genericCallInferenceWithGenericLocalFunction.ts, 15, 5)) +>from : Symbol(from, Decl(genericCallInferenceWithGenericLocalFunction.ts, 14, 9)) +>from2 : Symbol(from2, Decl(genericCallInferenceWithGenericLocalFunction.ts, 15, 10)) +>p : Symbol(p, Decl(genericCallInferenceWithGenericLocalFunction.ts, 12, 19)) + + return createTransform(m); +>createTransform : Symbol(createTransform, Decl(genericCallInferenceWithGenericLocalFunction.ts, 2, 5)) +>m : Symbol(m, Decl(genericCallInferenceWithGenericLocalFunction.ts, 13, 7)) +} + +const addP3 = withP3({ a: 1 }); +>addP3 : Symbol(addP3, Decl(genericCallInferenceWithGenericLocalFunction.ts, 19, 5)) +>withP3 : Symbol(withP3, Decl(genericCallInferenceWithGenericLocalFunction.ts, 10, 33)) +>a : Symbol(a, Decl(genericCallInferenceWithGenericLocalFunction.ts, 19, 22)) + +const addedSome3 = addP3({ b: '' }); +>addedSome3 : Symbol(addedSome3, Decl(genericCallInferenceWithGenericLocalFunction.ts, 20, 5)) +>addP3 : Symbol(addP3, Decl(genericCallInferenceWithGenericLocalFunction.ts, 19, 5)) +>b : Symbol(b, Decl(genericCallInferenceWithGenericLocalFunction.ts, 20, 26)) + +const added3 = addedSome3({ c: true }); +>added3 : Symbol(added3, Decl(genericCallInferenceWithGenericLocalFunction.ts, 21, 5)) +>addedSome3 : Symbol(addedSome3, Decl(genericCallInferenceWithGenericLocalFunction.ts, 20, 5)) +>c : Symbol(c, Decl(genericCallInferenceWithGenericLocalFunction.ts, 21, 27)) + +const addP3_other = withP3({ foo: 'bar' }); +>addP3_other : Symbol(addP3_other, Decl(genericCallInferenceWithGenericLocalFunction.ts, 23, 5)) +>withP3 : Symbol(withP3, Decl(genericCallInferenceWithGenericLocalFunction.ts, 10, 33)) +>foo : Symbol(foo, Decl(genericCallInferenceWithGenericLocalFunction.ts, 23, 28)) + +const addedSome3_other = addP3_other({ qwerty: 123 }); +>addedSome3_other : Symbol(addedSome3_other, Decl(genericCallInferenceWithGenericLocalFunction.ts, 24, 5)) +>addP3_other : Symbol(addP3_other, Decl(genericCallInferenceWithGenericLocalFunction.ts, 23, 5)) +>qwerty : Symbol(qwerty, Decl(genericCallInferenceWithGenericLocalFunction.ts, 24, 38)) + +const added3_other = addedSome3_other({ bazinga: true }); +>added3_other : Symbol(added3_other, Decl(genericCallInferenceWithGenericLocalFunction.ts, 25, 5)) +>addedSome3_other : Symbol(addedSome3_other, Decl(genericCallInferenceWithGenericLocalFunction.ts, 24, 5)) +>bazinga : Symbol(bazinga, Decl(genericCallInferenceWithGenericLocalFunction.ts, 25, 39)) + diff --git a/tests/baselines/reference/genericCallInferenceWithGenericLocalFunction.types b/tests/baselines/reference/genericCallInferenceWithGenericLocalFunction.types index a49703b695d51..eba6fd0e72fb2 100644 --- a/tests/baselines/reference/genericCallInferenceWithGenericLocalFunction.types +++ b/tests/baselines/reference/genericCallInferenceWithGenericLocalFunction.types @@ -74,3 +74,128 @@ const added2 = addP2({ bar: 2 }); >2 : 2 > : ^ +function withP3

(p: P) { +>withP3 :

(p: P) => (from: I) => (from2: I2) => I & I2 & P +> : ^ ^^ ^^ ^^^^^^ ^^ ^^^^^^^^^ ^^ ^^ ^^^^^^^^^^^^^^^ +>p : P +> : ^ + + const m = +>m : (from: I) => (from2: I2) => I & I2 & P +> : ^ ^^ ^^ ^^^^^^ ^^ ^^^^^^^^^^^^^^^ + + (from: I) => +>(from: I) => (from2: I2) => ({ ...from, ...from2, ...p }) : (from: I) => (from2: I2) => I & I2 & P +> : ^ ^^ ^^ ^^^^^^ ^^ ^^^^^^^^^^^^^^^ +>from : I +> : ^ + + (from2: I2) => ({ ...from, ...from2, ...p }); +>(from2: I2) => ({ ...from, ...from2, ...p }) : (from2: I2) => I & I2 & P +> : ^ ^^ ^^ ^^^^^^^^^^^^^^^ +>from2 : I2 +> : ^^ +>({ ...from, ...from2, ...p }) : I & I2 & P +> : ^^^^^^^^^^ +>{ ...from, ...from2, ...p } : I & I2 & P +> : ^^^^^^^^^^ +>from : I +> : ^ +>from2 : I2 +> : ^^ +>p : P +> : ^ + + return createTransform(m); +>createTransform(m) : (from: I) => (from2: I2) => I & I2 & P +> : ^ ^^ ^^^^^^^^^ ^^ ^^ ^^^^^^^^^^^^^^^ +>createTransform : (tr: (from: I) => O) => (from: I) => O +> : ^ ^^ ^^ ^^ ^^^^^^ ^^ ^^^^^ +>m : (from: I) => (from2: I2) => I & I2 & P +> : ^ ^^ ^^ ^^^^^^ ^^ ^^^^^^^^^^^^^^^ +} + +const addP3 = withP3({ a: 1 }); +>addP3 : (from: I) => (from2: I2) => I & I2 & { a: number; } +> : ^ ^^ ^^^^^^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>withP3({ a: 1 }) : (from: I) => (from2: I2) => I & I2 & { a: number; } +> : ^ ^^ ^^^^^^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>withP3 :

(p: P) => (from: I) => (from2: I2) => I & I2 & P +> : ^ ^^ ^^ ^^^^^^ ^^ ^^^^^^^^^ ^^ ^^ ^^^^^^^^^^^^^^^ +>{ a: 1 } : { a: number; } +> : ^^^^^^^^^^^^^^ +>a : number +> : ^^^^^^ +>1 : 1 +> : ^ + +const addedSome3 = addP3({ b: '' }); +>addedSome3 : (from2: I2) => { b: string; } & I2 & { a: number; } +> : ^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>addP3({ b: '' }) : (from2: I2) => { b: string; } & I2 & { a: number; } +> : ^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>addP3 : (from: I) => (from2: I2) => I & I2 & { a: number; } +> : ^ ^^ ^^^^^^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>{ b: '' } : { b: string; } +> : ^^^^^^^^^^^^^^ +>b : string +> : ^^^^^^ +>'' : "" +> : ^^ + +const added3 = addedSome3({ c: true }); +>added3 : { b: string; } & { c: boolean; } & { a: number; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>addedSome3({ c: true }) : { b: string; } & { c: boolean; } & { a: number; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>addedSome3 : (from2: I2) => { b: string; } & I2 & { a: number; } +> : ^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>{ c: true } : { c: true; } +> : ^^^^^^^^^^^^ +>c : true +> : ^^^^ +>true : true +> : ^^^^ + +const addP3_other = withP3({ foo: 'bar' }); +>addP3_other : (from: I) => (from2: I2) => I & I2 & { foo: string; } +> : ^ ^^ ^^^^^^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>withP3({ foo: 'bar' }) : (from: I) => (from2: I2) => I & I2 & { foo: string; } +> : ^ ^^ ^^^^^^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>withP3 :

(p: P) => (from: I) => (from2: I2) => I & I2 & P +> : ^ ^^ ^^ ^^^^^^ ^^ ^^^^^^^^^ ^^ ^^ ^^^^^^^^^^^^^^^ +>{ foo: 'bar' } : { foo: string; } +> : ^^^^^^^^^^^^^^^^ +>foo : string +> : ^^^^^^ +>'bar' : "bar" +> : ^^^^^ + +const addedSome3_other = addP3_other({ qwerty: 123 }); +>addedSome3_other : (from2: I2) => { qwerty: number; } & I2 & { foo: string; } +> : ^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>addP3_other({ qwerty: 123 }) : (from2: I2) => { qwerty: number; } & I2 & { foo: string; } +> : ^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>addP3_other : (from: I) => (from2: I2) => I & I2 & { foo: string; } +> : ^ ^^ ^^^^^^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>{ qwerty: 123 } : { qwerty: number; } +> : ^^^^^^^^^^^^^^^^^^^ +>qwerty : number +> : ^^^^^^ +>123 : 123 +> : ^^^ + +const added3_other = addedSome3_other({ bazinga: true }); +>added3_other : { qwerty: number; } & { bazinga: boolean; } & { foo: string; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>addedSome3_other({ bazinga: true }) : { qwerty: number; } & { bazinga: boolean; } & { foo: string; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>addedSome3_other : (from2: I2) => { qwerty: number; } & I2 & { foo: string; } +> : ^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>{ bazinga: true } : { bazinga: true; } +> : ^^^^^^^^^^^^^^^^^^ +>bazinga : true +> : ^^^^ +>true : true +> : ^^^^ + diff --git a/tests/baselines/reference/genericFunctionInference1.types b/tests/baselines/reference/genericFunctionInference1.types index 7275fd51f97be..93ff8f85b3541 100644 --- a/tests/baselines/reference/genericFunctionInference1.types +++ b/tests/baselines/reference/genericFunctionInference1.types @@ -2,7 +2,7 @@ === Performance Stats === Type Count: 1,000 -Instantiation count: 2,500 +Instantiation count: 1,000 === genericFunctionInference1.ts === declare function pipe(ab: (...args: A) => B): (...args: A) => B; diff --git a/tests/baselines/reference/inferenceFromGenericClassNoCrash1.errors.txt b/tests/baselines/reference/inferenceFromGenericClassNoCrash1.errors.txt new file mode 100644 index 0000000000000..6103c38d6d74a --- /dev/null +++ b/tests/baselines/reference/inferenceFromGenericClassNoCrash1.errors.txt @@ -0,0 +1,14 @@ +inferenceFromGenericClassNoCrash1.ts(5,3): error TS2564: Property 't' has no initializer and is not definitely assigned in the constructor. + + +==== inferenceFromGenericClassNoCrash1.ts (1 errors) ==== + // https://github.com/microsoft/TypeScript/issues/61633#issuecomment-2841778576 + + function RenderFlagsMixin object>(Base?: T) {} + class Container { + t: T; + ~ +!!! error TS2564: Property 't' has no initializer and is not definitely assigned in the constructor. + } + RenderFlagsMixin(Container); + \ No newline at end of file diff --git a/tests/baselines/reference/inferenceFromGenericClassNoCrash1.symbols b/tests/baselines/reference/inferenceFromGenericClassNoCrash1.symbols new file mode 100644 index 0000000000000..aa8dca0a91277 --- /dev/null +++ b/tests/baselines/reference/inferenceFromGenericClassNoCrash1.symbols @@ -0,0 +1,24 @@ +//// [tests/cases/compiler/inferenceFromGenericClassNoCrash1.ts] //// + +=== inferenceFromGenericClassNoCrash1.ts === +// https://github.com/microsoft/TypeScript/issues/61633#issuecomment-2841778576 + +function RenderFlagsMixin object>(Base?: T) {} +>RenderFlagsMixin : Symbol(RenderFlagsMixin, Decl(inferenceFromGenericClassNoCrash1.ts, 0, 0)) +>T : Symbol(T, Decl(inferenceFromGenericClassNoCrash1.ts, 2, 26)) +>args : Symbol(args, Decl(inferenceFromGenericClassNoCrash1.ts, 2, 41)) +>Base : Symbol(Base, Decl(inferenceFromGenericClassNoCrash1.ts, 2, 68)) +>T : Symbol(T, Decl(inferenceFromGenericClassNoCrash1.ts, 2, 26)) + +class Container { +>Container : Symbol(Container, Decl(inferenceFromGenericClassNoCrash1.ts, 2, 80)) +>T : Symbol(T, Decl(inferenceFromGenericClassNoCrash1.ts, 3, 16)) + + t: T; +>t : Symbol(Container.t, Decl(inferenceFromGenericClassNoCrash1.ts, 3, 20)) +>T : Symbol(T, Decl(inferenceFromGenericClassNoCrash1.ts, 3, 16)) +} +RenderFlagsMixin(Container); +>RenderFlagsMixin : Symbol(RenderFlagsMixin, Decl(inferenceFromGenericClassNoCrash1.ts, 0, 0)) +>Container : Symbol(Container, Decl(inferenceFromGenericClassNoCrash1.ts, 2, 80)) + diff --git a/tests/baselines/reference/inferenceFromGenericClassNoCrash1.types b/tests/baselines/reference/inferenceFromGenericClassNoCrash1.types new file mode 100644 index 0000000000000..a3a0792e05780 --- /dev/null +++ b/tests/baselines/reference/inferenceFromGenericClassNoCrash1.types @@ -0,0 +1,29 @@ +//// [tests/cases/compiler/inferenceFromGenericClassNoCrash1.ts] //// + +=== inferenceFromGenericClassNoCrash1.ts === +// https://github.com/microsoft/TypeScript/issues/61633#issuecomment-2841778576 + +function RenderFlagsMixin object>(Base?: T) {} +>RenderFlagsMixin : object>(Base?: T) => void +> : ^ ^^^^^^^^^ ^^ ^^^ ^^^^^^^^^ +>args : any[] +> : ^^^^^ +>Base : T | undefined +> : ^^^^^^^^^^^^^ + +class Container { +>Container : Container +> : ^^^^^^^^^^^^ + + t: T; +>t : T +> : ^ +} +RenderFlagsMixin(Container); +>RenderFlagsMixin(Container) : void +> : ^^^^ +>RenderFlagsMixin : object>(Base?: T) => void +> : ^ ^^^^^^^^^ ^^ ^^^ ^^^^^^^^^ +>Container : typeof Container +> : ^^^^^^^^^^^^^^^^ + diff --git a/tests/baselines/reference/nestedGenericSpreadInference.js b/tests/baselines/reference/nestedGenericSpreadInference.js index 00bb4a558c2d4..b1d1fb9645e39 100644 --- a/tests/baselines/reference/nestedGenericSpreadInference.js +++ b/tests/baselines/reference/nestedGenericSpreadInference.js @@ -4,11 +4,9 @@ declare function wrap(x: X): { x: X }; declare function call(x: { x: (...args: A) => T }, ...args: A): T; -// This should be of type `number` - ideally, it also would not error. const leak = call(wrap((x: T) => x), 1); //// [nestedGenericSpreadInference.js] "use strict"; -// This should be of type `number` - ideally, it also would not error. var leak = call(wrap(function (x) { return x; }), 1); diff --git a/tests/baselines/reference/nestedGenericSpreadInference.symbols b/tests/baselines/reference/nestedGenericSpreadInference.symbols index bef06547b70ec..ca6ba2f4361d5 100644 --- a/tests/baselines/reference/nestedGenericSpreadInference.symbols +++ b/tests/baselines/reference/nestedGenericSpreadInference.symbols @@ -22,13 +22,12 @@ declare function call(x: { x: (...args: A) => T }, ...ar >A : Symbol(A, Decl(nestedGenericSpreadInference.ts, 1, 22)) >T : Symbol(T, Decl(nestedGenericSpreadInference.ts, 1, 42)) -// This should be of type `number` - ideally, it also would not error. const leak = call(wrap((x: T) => x), 1); ->leak : Symbol(leak, Decl(nestedGenericSpreadInference.ts, 4, 5)) +>leak : Symbol(leak, Decl(nestedGenericSpreadInference.ts, 3, 5)) >call : Symbol(call, Decl(nestedGenericSpreadInference.ts, 0, 41)) >wrap : Symbol(wrap, Decl(nestedGenericSpreadInference.ts, 0, 0)) ->T : Symbol(T, Decl(nestedGenericSpreadInference.ts, 4, 24)) ->x : Symbol(x, Decl(nestedGenericSpreadInference.ts, 4, 27)) ->T : Symbol(T, Decl(nestedGenericSpreadInference.ts, 4, 24)) ->x : Symbol(x, Decl(nestedGenericSpreadInference.ts, 4, 27)) +>T : Symbol(T, Decl(nestedGenericSpreadInference.ts, 3, 24)) +>x : Symbol(x, Decl(nestedGenericSpreadInference.ts, 3, 27)) +>T : Symbol(T, Decl(nestedGenericSpreadInference.ts, 3, 24)) +>x : Symbol(x, Decl(nestedGenericSpreadInference.ts, 3, 27)) diff --git a/tests/baselines/reference/nestedGenericSpreadInference.types b/tests/baselines/reference/nestedGenericSpreadInference.types index 1d13f4dd71d70..929a9cec916aa 100644 --- a/tests/baselines/reference/nestedGenericSpreadInference.types +++ b/tests/baselines/reference/nestedGenericSpreadInference.types @@ -21,16 +21,15 @@ declare function call(x: { x: (...args: A) => T }, ...ar >args : A > : ^ -// This should be of type `number` - ideally, it also would not error. const leak = call(wrap((x: T) => x), 1); ->leak : number -> : ^^^^^^ ->call(wrap((x: T) => x), 1) : number -> : ^^^^^^ +>leak : unknown +> : ^^^^^^^ +>call(wrap((x: T) => x), 1) : unknown +> : ^^^^^^^ >call : (x: { x: (...args: A) => T; }, ...args: A) => T > : ^ ^^^^^^^^^ ^^ ^^ ^^ ^^^^^ ^^ ^^^^^ ->wrap((x: T) => x) : { x: (x: A[0]) => A[0]; } -> : ^^^^^^ ^^^^^^^^^^^^^^^^^^ +>wrap((x: T) => x) : { x: (x: unknown) => unknown; } +> : ^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^ >wrap : (x: X) => { x: X; } > : ^ ^^ ^^ ^^^^^ >(x: T) => x : (x: T) => T diff --git a/tests/baselines/reference/promisePermutations.types b/tests/baselines/reference/promisePermutations.types index a752a677c0a4e..0c000ea24f39e 100644 --- a/tests/baselines/reference/promisePermutations.types +++ b/tests/baselines/reference/promisePermutations.types @@ -2,7 +2,7 @@ === Performance Stats === Type Count: 1,000 -> 2,500 -Instantiation count: 5,000 -> 10,000 +Instantiation count: 5,000 === promisePermutations.ts === interface Promise { diff --git a/tests/cases/compiler/genericCallInferenceInConditionalTypes1.ts b/tests/cases/compiler/genericCallInferenceInConditionalTypes1.ts new file mode 100644 index 0000000000000..ff95031cbf728 --- /dev/null +++ b/tests/cases/compiler/genericCallInferenceInConditionalTypes1.ts @@ -0,0 +1,59 @@ +// @strict: true +// @noEmit: true + +// https://github.com/microsoft/TypeScript/issues/59937 + +type Ref = { + current: T; +}; + +type FunctionComponent

= (props: P) => unknown; + +type ComponentProps> = + T extends FunctionComponent ? P : {}; + +type PropsWithoutRef

= P extends any + ? "ref" extends keyof P + ? Omit + : P + : P; + +type ComponentPropsWithoutRef> = + PropsWithoutRef>; + +declare function forwardRef( + component: (props: P, ref: Ref) => unknown, +): (props: P & { ref?: Ref }) => unknown; + +const ComponentWithForwardRef = forwardRef( + >( + props: ComponentPropsWithoutRef, + ref: Ref, + ) => { + return null; + }, +); + +type Test = T extends { component?: infer Component } + ? Component extends FunctionComponent + ? ComponentProps + : never + : never; + +// the first one here has a chance to pollute the cache +type Result1 = ComponentProps; +// that could be incorrectly reused by this one +type Result2 = Test<{ component: typeof ComponentWithForwardRef }>; // no `T` leak + +// same as ComponentWithForwardRef above but using a resolved signature instead of a direct inferred result of `forwardRef` +declare const ComponentWithForwardRef2: >( + props: PropsWithoutRef> & { + className?: string; + as?: T | undefined; + } & { + ref?: Ref | undefined; + }, +) => unknown; + +type Result3 = ComponentProps; +type Result4 = Test<{ component: typeof ComponentWithForwardRef2 }>; diff --git a/tests/cases/compiler/genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts b/tests/cases/compiler/genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts new file mode 100644 index 0000000000000..5a7ca11d7905c --- /dev/null +++ b/tests/cases/compiler/genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts @@ -0,0 +1,46 @@ +// @strict: true +// @noEmit: true + +declare const EffectTypeId: unique symbol; + +interface Variance { + readonly [EffectTypeId]: VarianceStruct; +} + +type Covariant = (_: never) => A; + +interface VarianceStruct { + readonly _V: string; + readonly _A: Covariant; + readonly _E: Covariant; + readonly _R: Covariant; +} + +interface Effect + extends Variance {} + +declare const succeed: (value: A) => Effect; + +type F = Y extends { _type: infer Z } + ? X extends Effect + ? Effect + : X + : X; + +type ProxyMap = { + [K in keyof Service]: (Service & { _type: Service })[K]; +}; + +declare const implement: () => , X>( + x: (...i: I) => X, +) => (...i: I) => F; + +class XXX { + log = implement()((n: N) => succeed(n)); +} + +export declare const inner: XXX; +export declare const outer: ProxyMap; + +export const a = inner.log(100); // Effect<100, never, never> +export const b = outer.log(100); // Effect<100, never, XXX> diff --git a/tests/cases/compiler/genericCallInferenceWithGenericLocalFunction.ts b/tests/cases/compiler/genericCallInferenceWithGenericLocalFunction.ts index 1aff11c5b3507..57c14a76ba6f6 100644 --- a/tests/cases/compiler/genericCallInferenceWithGenericLocalFunction.ts +++ b/tests/cases/compiler/genericCallInferenceWithGenericLocalFunction.ts @@ -12,3 +12,18 @@ function withP2

(p: P) { const addP2 = withP2({ foo: 1 }); const added2 = addP2({ bar: 2 }); + +function withP3

(p: P) { + const m = + (from: I) => + (from2: I2) => ({ ...from, ...from2, ...p }); + return createTransform(m); +} + +const addP3 = withP3({ a: 1 }); +const addedSome3 = addP3({ b: '' }); +const added3 = addedSome3({ c: true }); + +const addP3_other = withP3({ foo: 'bar' }); +const addedSome3_other = addP3_other({ qwerty: 123 }); +const added3_other = addedSome3_other({ bazinga: true }); diff --git a/tests/cases/compiler/genericCallWithinOwnBodyCastTypeParameterIdentity.ts b/tests/cases/compiler/genericCallWithinOwnBodyCastTypeParameterIdentity.ts index 97058662ae75d..1358b238f7e00 100644 --- a/tests/cases/compiler/genericCallWithinOwnBodyCastTypeParameterIdentity.ts +++ b/tests/cases/compiler/genericCallWithinOwnBodyCastTypeParameterIdentity.ts @@ -1,4 +1,5 @@ // @strict: true + interface Thenable { then( onFulfilled: (value: Value) => V | Thenable, diff --git a/tests/cases/compiler/inferenceFromGenericClassNoCrash1.ts b/tests/cases/compiler/inferenceFromGenericClassNoCrash1.ts new file mode 100644 index 0000000000000..b8c0657f60823 --- /dev/null +++ b/tests/cases/compiler/inferenceFromGenericClassNoCrash1.ts @@ -0,0 +1,10 @@ +// @strict: true +// @noEmit: true + +// https://github.com/microsoft/TypeScript/issues/61633#issuecomment-2841778576 + +function RenderFlagsMixin object>(Base?: T) {} +class Container { + t: T; +} +RenderFlagsMixin(Container); diff --git a/tests/cases/compiler/nestedGenericSpreadInference.ts b/tests/cases/compiler/nestedGenericSpreadInference.ts index 14e606f5f5cbf..fc3ea67d0ce6f 100644 --- a/tests/cases/compiler/nestedGenericSpreadInference.ts +++ b/tests/cases/compiler/nestedGenericSpreadInference.ts @@ -1,6 +1,6 @@ // @strict: true + declare function wrap(x: X): { x: X }; declare function call(x: { x: (...args: A) => T }, ...args: A): T; -// This should be of type `number` - ideally, it also would not error. const leak = call(wrap((x: T) => x), 1);