mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-27 23:58:38 -06:00
Fix type variable leaks and cache inconsistencies (#61668)
This commit is contained in:
parent
cb38d99d08
commit
34d1ea68f6
@ -1009,7 +1009,6 @@ import {
|
||||
SignatureFlags,
|
||||
SignatureKind,
|
||||
singleElementArray,
|
||||
SingleSignatureType,
|
||||
skipOuterExpressions,
|
||||
skipParentheses,
|
||||
skipTrivia,
|
||||
@ -7291,7 +7290,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) +
|
||||
@ -16415,15 +16414,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;
|
||||
}
|
||||
}
|
||||
@ -16483,16 +16484,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) {
|
||||
@ -16514,7 +16505,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
|
||||
@ -16525,16 +16516,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;
|
||||
@ -20524,6 +20506,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;
|
||||
}
|
||||
@ -20620,7 +20610,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
|
||||
@ -20646,19 +20636,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<string, Type>();
|
||||
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);
|
||||
@ -20856,9 +20844,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;
|
||||
@ -26241,7 +26226,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)
|
||||
) ||
|
||||
@ -26623,13 +26607,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;
|
||||
@ -26758,11 +26735,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) {
|
||||
@ -35718,8 +35690,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;
|
||||
}
|
||||
@ -35994,7 +35970,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)) {
|
||||
@ -36029,10 +36004,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");
|
||||
@ -36525,7 +36497,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) {
|
||||
@ -36547,7 +36519,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;
|
||||
@ -36636,7 +36608,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;
|
||||
}
|
||||
@ -36644,7 +36616,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;
|
||||
}
|
||||
@ -36653,14 +36625,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) {
|
||||
@ -36669,10 +36634,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);
|
||||
@ -36686,7 +36649,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;
|
||||
@ -36697,7 +36660,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.
|
||||
@ -36706,7 +36669,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;
|
||||
@ -41418,10 +41381,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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -6539,7 +6539,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,
|
||||
@ -6555,7 +6555,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
|
||||
@ -6770,12 +6769,6 @@ export interface AnonymousType extends ObjectType {
|
||||
instantiations?: Map<string, Type>; // 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;
|
||||
@ -7061,8 +7054,6 @@ export interface Signature {
|
||||
isolatedSignatureType?: ObjectType; // A manufactured type that just contains the signature for purposes of signature comparison
|
||||
/** @internal */
|
||||
instantiations?: Map<string, Signature>; // 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 {
|
||||
@ -7170,6 +7161,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[];
|
||||
}
|
||||
|
||||
@ -6717,11 +6717,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;
|
||||
|
||||
@ -0,0 +1,173 @@
|
||||
//// [tests/cases/compiler/genericCallInferenceInConditionalTypes1.ts] ////
|
||||
|
||||
=== genericCallInferenceInConditionalTypes1.ts ===
|
||||
// https://github.com/microsoft/TypeScript/issues/59937
|
||||
|
||||
type Ref<T> = {
|
||||
>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<P> = (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<T extends FunctionComponent<any>> =
|
||||
>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<infer P> ? 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> = 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<P, "ref">
|
||||
>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<T extends FunctionComponent<any>> =
|
||||
>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<ComponentProps<T>>;
|
||||
>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<T, P>(
|
||||
>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<T>) => 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<T> }) => 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 extends FunctionComponent<any>>(
|
||||
>T : Symbol(T, Decl(genericCallInferenceInConditionalTypes1.ts, 25, 3))
|
||||
>FunctionComponent : Symbol(FunctionComponent, Decl(genericCallInferenceInConditionalTypes1.ts, 4, 2))
|
||||
|
||||
props: ComponentPropsWithoutRef<T>,
|
||||
>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<HTMLElement>,
|
||||
>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> = 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<any>
|
||||
>Component : Symbol(Component, Decl(genericCallInferenceInConditionalTypes1.ts, 33, 44))
|
||||
>FunctionComponent : Symbol(FunctionComponent, Decl(genericCallInferenceInConditionalTypes1.ts, 4, 2))
|
||||
|
||||
? ComponentProps<Component>
|
||||
>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<typeof ComponentWithForwardRef>;
|
||||
>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: <T extends FunctionComponent<any>>(
|
||||
>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<ComponentProps<T>> & {
|
||||
>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<HTMLElement> | 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<typeof ComponentWithForwardRef2>;
|
||||
>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))
|
||||
|
||||
@ -0,0 +1,151 @@
|
||||
//// [tests/cases/compiler/genericCallInferenceInConditionalTypes1.ts] ////
|
||||
|
||||
=== genericCallInferenceInConditionalTypes1.ts ===
|
||||
// https://github.com/microsoft/TypeScript/issues/59937
|
||||
|
||||
type Ref<T> = {
|
||||
>Ref : Ref<T>
|
||||
> : ^^^^^^
|
||||
|
||||
current: T;
|
||||
>current : T
|
||||
> : ^
|
||||
|
||||
};
|
||||
|
||||
type FunctionComponent<P> = (props: P) => unknown;
|
||||
>FunctionComponent : FunctionComponent<P>
|
||||
> : ^^^^^^^^^^^^^^^^^^^^
|
||||
>props : P
|
||||
> : ^
|
||||
|
||||
type ComponentProps<T extends FunctionComponent<any>> =
|
||||
>ComponentProps : ComponentProps<T>
|
||||
> : ^^^^^^^^^^^^^^^^^
|
||||
|
||||
T extends FunctionComponent<infer P> ? P : {};
|
||||
|
||||
type PropsWithoutRef<P> = P extends any
|
||||
>PropsWithoutRef : PropsWithoutRef<P>
|
||||
> : ^^^^^^^^^^^^^^^^^^
|
||||
|
||||
? "ref" extends keyof P
|
||||
? Omit<P, "ref">
|
||||
: P
|
||||
: P;
|
||||
|
||||
type ComponentPropsWithoutRef<T extends FunctionComponent<any>> =
|
||||
>ComponentPropsWithoutRef : ComponentPropsWithoutRef<T>
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
PropsWithoutRef<ComponentProps<T>>;
|
||||
|
||||
declare function forwardRef<T, P>(
|
||||
>forwardRef : <T, P>(component: (props: P, ref: Ref<T>) => unknown) => (props: P & { ref?: Ref<T>; }) => unknown
|
||||
> : ^ ^^ ^^ ^^ ^^^^^
|
||||
|
||||
component: (props: P, ref: Ref<T>) => unknown,
|
||||
>component : (props: P, ref: Ref<T>) => unknown
|
||||
> : ^ ^^ ^^ ^^ ^^^^^
|
||||
>props : P
|
||||
> : ^
|
||||
>ref : Ref<T>
|
||||
> : ^^^^^^
|
||||
|
||||
): (props: P & { ref?: Ref<T> }) => unknown;
|
||||
>props : P & { ref?: Ref<T>; }
|
||||
> : ^^^^^^^^^^^^ ^^^
|
||||
>ref : Ref<T> | undefined
|
||||
> : ^^^^^^^^^^^^^^^^^^
|
||||
|
||||
const ComponentWithForwardRef = forwardRef(
|
||||
>ComponentWithForwardRef : <T extends FunctionComponent<any>>(props: PropsWithoutRef<ComponentProps<T>> & { ref?: Ref<HTMLElement> | undefined; }) => unknown
|
||||
> : ^ ^^^^^^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>forwardRef( <T extends FunctionComponent<any>>( props: ComponentPropsWithoutRef<T>, ref: Ref<HTMLElement>, ) => { return null; },) : <T extends FunctionComponent<any>>(props: PropsWithoutRef<ComponentProps<T>> & { ref?: Ref<HTMLElement> | undefined; }) => unknown
|
||||
> : ^ ^^^^^^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>forwardRef : <T, P>(component: (props: P, ref: Ref<T>) => unknown) => (props: P & { ref?: Ref<T>; }) => unknown
|
||||
> : ^ ^^ ^^ ^^ ^^^^^
|
||||
|
||||
<T extends FunctionComponent<any>>(
|
||||
><T extends FunctionComponent<any>>( props: ComponentPropsWithoutRef<T>, ref: Ref<HTMLElement>, ) => { return null; } : <T extends FunctionComponent<any>>(props: ComponentPropsWithoutRef<T>, ref: Ref<HTMLElement>) => null
|
||||
> : ^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^^^^^^^^
|
||||
|
||||
props: ComponentPropsWithoutRef<T>,
|
||||
>props : PropsWithoutRef<ComponentProps<T>>
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
ref: Ref<HTMLElement>,
|
||||
>ref : Ref<HTMLElement>
|
||||
> : ^^^^^^^^^^^^^^^^
|
||||
|
||||
) => {
|
||||
return null;
|
||||
},
|
||||
);
|
||||
|
||||
type Test<T> = T extends { component?: infer Component }
|
||||
>Test : Test<T>
|
||||
> : ^^^^^^^
|
||||
>component : Component | undefined
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
? Component extends FunctionComponent<any>
|
||||
? ComponentProps<Component>
|
||||
: never
|
||||
: never;
|
||||
|
||||
// the first one here has a chance to pollute the cache
|
||||
type Result1 = ComponentProps<typeof ComponentWithForwardRef>;
|
||||
>Result1 : Omit<any, "ref"> & { ref?: Ref<HTMLElement> | undefined; }
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>ComponentWithForwardRef : <T extends FunctionComponent<any>>(props: PropsWithoutRef<ComponentProps<T>> & { ref?: Ref<HTMLElement> | undefined; }) => unknown
|
||||
> : ^ ^^^^^^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
// that could be incorrectly reused by this one
|
||||
type Result2 = Test<{ component: typeof ComponentWithForwardRef }>; // no `T` leak
|
||||
>Result2 : Omit<any, "ref"> & { ref?: Ref<HTMLElement> | undefined; }
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>component : <T extends FunctionComponent<any>>(props: PropsWithoutRef<ComponentProps<T>> & { ref?: Ref<HTMLElement> | undefined; }) => unknown
|
||||
> : ^ ^^^^^^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>ComponentWithForwardRef : <T extends FunctionComponent<any>>(props: PropsWithoutRef<ComponentProps<T>> & { ref?: Ref<HTMLElement> | undefined; }) => unknown
|
||||
> : ^ ^^^^^^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
// same as ComponentWithForwardRef above but using a resolved signature instead of a direct inferred result of `forwardRef`
|
||||
declare const ComponentWithForwardRef2: <T extends FunctionComponent<any>>(
|
||||
>ComponentWithForwardRef2 : <T extends FunctionComponent<any>>(props: PropsWithoutRef<ComponentProps<T>> & { className?: string; as?: T | undefined; } & { ref?: Ref<HTMLElement> | undefined; }) => unknown
|
||||
> : ^ ^^^^^^^^^ ^^ ^^ ^^^^^
|
||||
|
||||
props: PropsWithoutRef<ComponentProps<T>> & {
|
||||
>props : PropsWithoutRef<ComponentProps<T>> & { className?: string; as?: T | undefined; } & { ref?: Ref<HTMLElement> | undefined; }
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^ ^^^^^^^^^^^^^^ ^^^
|
||||
|
||||
className?: string;
|
||||
>className : string | undefined
|
||||
> : ^^^^^^^^^^^^^^^^^^
|
||||
|
||||
as?: T | undefined;
|
||||
>as : T | undefined
|
||||
> : ^^^^^^^^^^^^^
|
||||
|
||||
} & {
|
||||
ref?: Ref<HTMLElement> | undefined;
|
||||
>ref : Ref<HTMLElement> | undefined
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
},
|
||||
) => unknown;
|
||||
|
||||
type Result3 = ComponentProps<typeof ComponentWithForwardRef2>;
|
||||
>Result3 : Omit<any, "ref"> & { className?: string; as?: FunctionComponent<any> | undefined; } & { ref?: Ref<HTMLElement> | undefined; }
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^
|
||||
>ComponentWithForwardRef2 : <T extends FunctionComponent<any>>(props: PropsWithoutRef<ComponentProps<T>> & { className?: string; as?: T | undefined; } & { ref?: Ref<HTMLElement> | undefined; }) => unknown
|
||||
> : ^ ^^^^^^^^^ ^^ ^^ ^^^^^
|
||||
|
||||
type Result4 = Test<{ component: typeof ComponentWithForwardRef2 }>;
|
||||
>Result4 : Omit<any, "ref"> & { className?: string; as?: FunctionComponent<any> | undefined; } & { ref?: Ref<HTMLElement> | undefined; }
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^
|
||||
>component : <T extends FunctionComponent<any>>(props: PropsWithoutRef<ComponentProps<T>> & { className?: string; as?: T | undefined; } & { ref?: Ref<HTMLElement> | undefined; }) => unknown
|
||||
> : ^ ^^^^^^^^^ ^^ ^^ ^^^^^
|
||||
>ComponentWithForwardRef2 : <T extends FunctionComponent<any>>(props: PropsWithoutRef<ComponentProps<T>> & { className?: string; as?: T | undefined; } & { ref?: Ref<HTMLElement> | undefined; }) => unknown
|
||||
> : ^ ^^^^^^^^^ ^^ ^^ ^^^^^
|
||||
|
||||
@ -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<out A, out E, out R> {
|
||||
>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<A, E, R>;
|
||||
>[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<A> = (_: 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<out A, out E, out R> {
|
||||
>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>;
|
||||
>_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>;
|
||||
>_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>;
|
||||
>_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<out A, out E = never, out R = never>
|
||||
>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<A, E, R> {}
|
||||
>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: <A>(value: A) => Effect<A>;
|
||||
>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<X, Y> = 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<infer A, infer E, infer R>
|
||||
>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<A, E, R | Z>
|
||||
>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<Service> = {
|
||||
>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: <T>() => <I extends ReadonlyArray<any>, 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<X, T>;
|
||||
>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<this>()(<N extends number>(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<XXX>;
|
||||
>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))
|
||||
|
||||
@ -0,0 +1,144 @@
|
||||
//// [tests/cases/compiler/genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts] ////
|
||||
|
||||
=== genericCallInferenceUsingThisTypeNoInvalidCacheReuseAfterMappedTypeApplication1.ts ===
|
||||
declare const EffectTypeId: unique symbol;
|
||||
>EffectTypeId : unique symbol
|
||||
> : ^^^^^^^^^^^^^
|
||||
|
||||
interface Variance<out A, out E, out R> {
|
||||
readonly [EffectTypeId]: VarianceStruct<A, E, R>;
|
||||
>[EffectTypeId] : VarianceStruct<A, E, R>
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>EffectTypeId : unique symbol
|
||||
> : ^^^^^^^^^^^^^
|
||||
}
|
||||
|
||||
type Covariant<A> = (_: never) => A;
|
||||
>Covariant : Covariant<A>
|
||||
> : ^^^^^^^^^^^^
|
||||
>_ : never
|
||||
> : ^^^^^
|
||||
|
||||
interface VarianceStruct<out A, out E, out R> {
|
||||
readonly _V: string;
|
||||
>_V : string
|
||||
> : ^^^^^^
|
||||
|
||||
readonly _A: Covariant<A>;
|
||||
>_A : Covariant<A>
|
||||
> : ^^^^^^^^^^^^
|
||||
|
||||
readonly _E: Covariant<E>;
|
||||
>_E : Covariant<E>
|
||||
> : ^^^^^^^^^^^^
|
||||
|
||||
readonly _R: Covariant<R>;
|
||||
>_R : Covariant<R>
|
||||
> : ^^^^^^^^^^^^
|
||||
}
|
||||
|
||||
interface Effect<out A, out E = never, out R = never>
|
||||
extends Variance<A, E, R> {}
|
||||
|
||||
declare const succeed: <A>(value: A) => Effect<A>;
|
||||
>succeed : <A>(value: A) => Effect<A>
|
||||
> : ^ ^^ ^^ ^^^^^
|
||||
>value : A
|
||||
> : ^
|
||||
|
||||
type F<X, Y> = Y extends { _type: infer Z }
|
||||
>F : F<X, Y>
|
||||
> : ^^^^^^^
|
||||
>_type : Z
|
||||
> : ^
|
||||
|
||||
? X extends Effect<infer A, infer E, infer R>
|
||||
? Effect<A, E, R | Z>
|
||||
: X
|
||||
: X;
|
||||
|
||||
type ProxyMap<Service> = {
|
||||
>ProxyMap : ProxyMap<Service>
|
||||
> : ^^^^^^^^^^^^^^^^^
|
||||
|
||||
[K in keyof Service]: (Service & { _type: Service })[K];
|
||||
>_type : Service
|
||||
> : ^^^^^^^
|
||||
|
||||
};
|
||||
|
||||
declare const implement: <T>() => <I extends ReadonlyArray<any>, X>(
|
||||
>implement : <T>() => <I extends ReadonlyArray<any>, X>(x: (...i: I) => X) => (...i: I) => F<X, T>
|
||||
> : ^ ^^^^^^^
|
||||
|
||||
x: (...i: I) => X,
|
||||
>x : (...i: I) => X
|
||||
> : ^^^^ ^^ ^^^^^
|
||||
>i : I
|
||||
> : ^
|
||||
|
||||
) => (...i: I) => F<X, T>;
|
||||
>i : I
|
||||
> : ^
|
||||
|
||||
class XXX {
|
||||
>XXX : XXX
|
||||
> : ^^^
|
||||
|
||||
log = implement<this>()(<N extends number>(n: N) => succeed(n));
|
||||
>log : <N extends number>(n: N) => F<Effect<N, never, never>, this>
|
||||
> : ^ ^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>implement<this>()(<N extends number>(n: N) => succeed(n)) : <N extends number>(n: N) => F<Effect<N, never, never>, this>
|
||||
> : ^ ^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>implement<this>() : <I extends ReadonlyArray<any>, X>(x: (...i: I) => X) => (...i: I) => F<X, this>
|
||||
> : ^ ^^^^^^^^^ ^^ ^^ ^^^^^^ ^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^
|
||||
>implement : <T>() => <I extends ReadonlyArray<any>, X>(x: (...i: I) => X) => (...i: I) => F<X, T>
|
||||
> : ^ ^^^^^^^
|
||||
><N extends number>(n: N) => succeed(n) : <N extends number>(n: N) => Effect<N, never, never>
|
||||
> : ^ ^^^^^^^^^ ^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>n : N
|
||||
> : ^
|
||||
>succeed(n) : Effect<N, never, never>
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>succeed : <A>(value: A) => Effect<A>
|
||||
> : ^ ^^ ^^ ^^^^^
|
||||
>n : N
|
||||
> : ^
|
||||
}
|
||||
|
||||
export declare const inner: XXX;
|
||||
>inner : XXX
|
||||
> : ^^^
|
||||
|
||||
export declare const outer: ProxyMap<XXX>;
|
||||
>outer : ProxyMap<XXX>
|
||||
> : ^^^^^^^^^^^^^
|
||||
|
||||
export const a = inner.log(100); // Effect<100, never, never>
|
||||
>a : F<Effect<100, never, never>, this>
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>inner.log(100) : F<Effect<100, never, never>, this>
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>inner.log : <N extends number>(n: N) => F<Effect<N, never, never>, this>
|
||||
> : ^ ^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>inner : XXX
|
||||
> : ^^^
|
||||
>log : <N extends number>(n: N) => F<Effect<N, never, never>, this>
|
||||
> : ^ ^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>100 : 100
|
||||
> : ^^^
|
||||
|
||||
export const b = outer.log(100); // Effect<100, never, XXX>
|
||||
>b : F<Effect<100, never, never>, this>
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>outer.log(100) : F<Effect<100, never, never>, this>
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>outer.log : <N extends number>(n: N) => F<Effect<N, never, never>, this>
|
||||
> : ^ ^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>outer : ProxyMap<XXX>
|
||||
> : ^^^^^^^^^^^^^
|
||||
>log : <N extends number>(n: N) => F<Effect<N, never, never>, this>
|
||||
> : ^ ^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>100 : 100
|
||||
> : ^^^
|
||||
|
||||
@ -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: 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))
|
||||
|
||||
<I,>(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))
|
||||
|
||||
<I2,>(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))
|
||||
|
||||
|
||||
@ -74,3 +74,128 @@ const added2 = addP2({ bar: 2 });
|
||||
>2 : 2
|
||||
> : ^
|
||||
|
||||
function withP3<P>(p: P) {
|
||||
>withP3 : <P>(p: P) => <I>(from: I) => <I2>(from2: I2) => I & I2 & P
|
||||
> : ^ ^^ ^^ ^^^^^^ ^^ ^^^^^^^^^ ^^ ^^ ^^^^^^^^^^^^^^^
|
||||
>p : P
|
||||
> : ^
|
||||
|
||||
const m =
|
||||
>m : <I>(from: I) => <I2>(from2: I2) => I & I2 & P
|
||||
> : ^ ^^ ^^ ^^^^^^ ^^ ^^^^^^^^^^^^^^^
|
||||
|
||||
<I,>(from: I) =>
|
||||
><I,>(from: I) => <I2,>(from2: I2) => ({ ...from, ...from2, ...p }) : <I>(from: I) => <I2>(from2: I2) => I & I2 & P
|
||||
> : ^ ^^ ^^ ^^^^^^ ^^ ^^^^^^^^^^^^^^^
|
||||
>from : I
|
||||
> : ^
|
||||
|
||||
<I2,>(from2: I2) => ({ ...from, ...from2, ...p });
|
||||
><I2,>(from2: I2) => ({ ...from, ...from2, ...p }) : <I2>(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) : <I>(from: I) => <I2>(from2: I2) => I & I2 & P
|
||||
> : ^ ^^ ^^^^^^^^^ ^^ ^^ ^^^^^^^^^^^^^^^
|
||||
>createTransform : <I, O>(tr: (from: I) => O) => (from: I) => O
|
||||
> : ^ ^^ ^^ ^^ ^^^^^^ ^^ ^^^^^
|
||||
>m : <I>(from: I) => <I2>(from2: I2) => I & I2 & P
|
||||
> : ^ ^^ ^^ ^^^^^^ ^^ ^^^^^^^^^^^^^^^
|
||||
}
|
||||
|
||||
const addP3 = withP3({ a: 1 });
|
||||
>addP3 : <I>(from: I) => <I2>(from2: I2) => I & I2 & { a: number; }
|
||||
> : ^ ^^ ^^^^^^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>withP3({ a: 1 }) : <I>(from: I) => <I2>(from2: I2) => I & I2 & { a: number; }
|
||||
> : ^ ^^ ^^^^^^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>withP3 : <P>(p: P) => <I>(from: I) => <I2>(from2: I2) => I & I2 & P
|
||||
> : ^ ^^ ^^ ^^^^^^ ^^ ^^^^^^^^^ ^^ ^^ ^^^^^^^^^^^^^^^
|
||||
>{ a: 1 } : { a: number; }
|
||||
> : ^^^^^^^^^^^^^^
|
||||
>a : number
|
||||
> : ^^^^^^
|
||||
>1 : 1
|
||||
> : ^
|
||||
|
||||
const addedSome3 = addP3({ b: '' });
|
||||
>addedSome3 : <I2>(from2: I2) => { b: string; } & I2 & { a: number; }
|
||||
> : ^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>addP3({ b: '' }) : <I2>(from2: I2) => { b: string; } & I2 & { a: number; }
|
||||
> : ^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>addP3 : <I>(from: I) => <I2>(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 : <I2>(from2: I2) => { b: string; } & I2 & { a: number; }
|
||||
> : ^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>{ c: true } : { c: true; }
|
||||
> : ^^^^^^^^^^^^
|
||||
>c : true
|
||||
> : ^^^^
|
||||
>true : true
|
||||
> : ^^^^
|
||||
|
||||
const addP3_other = withP3({ foo: 'bar' });
|
||||
>addP3_other : <I>(from: I) => <I2>(from2: I2) => I & I2 & { foo: string; }
|
||||
> : ^ ^^ ^^^^^^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>withP3({ foo: 'bar' }) : <I>(from: I) => <I2>(from2: I2) => I & I2 & { foo: string; }
|
||||
> : ^ ^^ ^^^^^^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>withP3 : <P>(p: P) => <I>(from: I) => <I2>(from2: I2) => I & I2 & P
|
||||
> : ^ ^^ ^^ ^^^^^^ ^^ ^^^^^^^^^ ^^ ^^ ^^^^^^^^^^^^^^^
|
||||
>{ foo: 'bar' } : { foo: string; }
|
||||
> : ^^^^^^^^^^^^^^^^
|
||||
>foo : string
|
||||
> : ^^^^^^
|
||||
>'bar' : "bar"
|
||||
> : ^^^^^
|
||||
|
||||
const addedSome3_other = addP3_other({ qwerty: 123 });
|
||||
>addedSome3_other : <I2>(from2: I2) => { qwerty: number; } & I2 & { foo: string; }
|
||||
> : ^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>addP3_other({ qwerty: 123 }) : <I2>(from2: I2) => { qwerty: number; } & I2 & { foo: string; }
|
||||
> : ^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>addP3_other : <I>(from: I) => <I2>(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 : <I2>(from2: I2) => { qwerty: number; } & I2 & { foo: string; }
|
||||
> : ^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>{ bazinga: true } : { bazinga: true; }
|
||||
> : ^^^^^^^^^^^^^^^^^^
|
||||
>bazinga : true
|
||||
> : ^^^^
|
||||
>true : true
|
||||
> : ^^^^
|
||||
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
=== Performance Stats ===
|
||||
Type Count: 1,000
|
||||
Instantiation count: 2,500
|
||||
Instantiation count: 1,000
|
||||
|
||||
=== genericFunctionInference1.ts ===
|
||||
declare function pipe<A extends any[], B>(ab: (...args: A) => B): (...args: A) => B;
|
||||
|
||||
@ -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<T extends new (...args: any[]) => object>(Base?: T) {}
|
||||
class Container<T> {
|
||||
t: T;
|
||||
~
|
||||
!!! error TS2564: Property 't' has no initializer and is not definitely assigned in the constructor.
|
||||
}
|
||||
RenderFlagsMixin(Container);
|
||||
|
||||
@ -0,0 +1,24 @@
|
||||
//// [tests/cases/compiler/inferenceFromGenericClassNoCrash1.ts] ////
|
||||
|
||||
=== inferenceFromGenericClassNoCrash1.ts ===
|
||||
// https://github.com/microsoft/TypeScript/issues/61633#issuecomment-2841778576
|
||||
|
||||
function RenderFlagsMixin<T extends new (...args: any[]) => 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<T> {
|
||||
>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))
|
||||
|
||||
@ -0,0 +1,29 @@
|
||||
//// [tests/cases/compiler/inferenceFromGenericClassNoCrash1.ts] ////
|
||||
|
||||
=== inferenceFromGenericClassNoCrash1.ts ===
|
||||
// https://github.com/microsoft/TypeScript/issues/61633#issuecomment-2841778576
|
||||
|
||||
function RenderFlagsMixin<T extends new (...args: any[]) => object>(Base?: T) {}
|
||||
>RenderFlagsMixin : <T extends new (...args: any[]) => object>(Base?: T) => void
|
||||
> : ^ ^^^^^^^^^ ^^ ^^^ ^^^^^^^^^
|
||||
>args : any[]
|
||||
> : ^^^^^
|
||||
>Base : T | undefined
|
||||
> : ^^^^^^^^^^^^^
|
||||
|
||||
class Container<T> {
|
||||
>Container : Container<T>
|
||||
> : ^^^^^^^^^^^^
|
||||
|
||||
t: T;
|
||||
>t : T
|
||||
> : ^
|
||||
}
|
||||
RenderFlagsMixin(Container);
|
||||
>RenderFlagsMixin(Container) : void
|
||||
> : ^^^^
|
||||
>RenderFlagsMixin : <T extends new (...args: any[]) => object>(Base?: T) => void
|
||||
> : ^ ^^^^^^^^^ ^^ ^^^ ^^^^^^^^^
|
||||
>Container : typeof Container
|
||||
> : ^^^^^^^^^^^^^^^^
|
||||
|
||||
@ -4,11 +4,9 @@
|
||||
declare function wrap<X>(x: X): { x: X };
|
||||
declare function call<A extends unknown[], T>(x: { x: (...args: A) => T }, ...args: A): T;
|
||||
|
||||
// This should be of type `number` - ideally, it also would not error.
|
||||
const leak = call(wrap(<T>(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);
|
||||
|
||||
@ -22,13 +22,12 @@ declare function call<A extends unknown[], T>(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(<T>(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))
|
||||
|
||||
|
||||
@ -21,16 +21,15 @@ declare function call<A extends unknown[], T>(x: { x: (...args: A) => T }, ...ar
|
||||
>args : A
|
||||
> : ^
|
||||
|
||||
// This should be of type `number` - ideally, it also would not error.
|
||||
const leak = call(wrap(<T>(x: T) => x), 1);
|
||||
>leak : number
|
||||
> : ^^^^^^
|
||||
>call(wrap(<T>(x: T) => x), 1) : number
|
||||
> : ^^^^^^
|
||||
>leak : unknown
|
||||
> : ^^^^^^^
|
||||
>call(wrap(<T>(x: T) => x), 1) : unknown
|
||||
> : ^^^^^^^
|
||||
>call : <A extends unknown[], T>(x: { x: (...args: A) => T; }, ...args: A) => T
|
||||
> : ^ ^^^^^^^^^ ^^ ^^ ^^ ^^^^^ ^^ ^^^^^
|
||||
>wrap(<T>(x: T) => x) : { x: (x: A[0]) => A[0]; }
|
||||
> : ^^^^^^ ^^^^^^^^^^^^^^^^^^
|
||||
>wrap(<T>(x: T) => x) : { x: (x: unknown) => unknown; }
|
||||
> : ^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>wrap : <X>(x: X) => { x: X; }
|
||||
> : ^ ^^ ^^ ^^^^^
|
||||
><T>(x: T) => x : <T>(x: T) => T
|
||||
|
||||
@ -0,0 +1,59 @@
|
||||
// @strict: true
|
||||
// @noEmit: true
|
||||
|
||||
// https://github.com/microsoft/TypeScript/issues/59937
|
||||
|
||||
type Ref<T> = {
|
||||
current: T;
|
||||
};
|
||||
|
||||
type FunctionComponent<P> = (props: P) => unknown;
|
||||
|
||||
type ComponentProps<T extends FunctionComponent<any>> =
|
||||
T extends FunctionComponent<infer P> ? P : {};
|
||||
|
||||
type PropsWithoutRef<P> = P extends any
|
||||
? "ref" extends keyof P
|
||||
? Omit<P, "ref">
|
||||
: P
|
||||
: P;
|
||||
|
||||
type ComponentPropsWithoutRef<T extends FunctionComponent<any>> =
|
||||
PropsWithoutRef<ComponentProps<T>>;
|
||||
|
||||
declare function forwardRef<T, P>(
|
||||
component: (props: P, ref: Ref<T>) => unknown,
|
||||
): (props: P & { ref?: Ref<T> }) => unknown;
|
||||
|
||||
const ComponentWithForwardRef = forwardRef(
|
||||
<T extends FunctionComponent<any>>(
|
||||
props: ComponentPropsWithoutRef<T>,
|
||||
ref: Ref<HTMLElement>,
|
||||
) => {
|
||||
return null;
|
||||
},
|
||||
);
|
||||
|
||||
type Test<T> = T extends { component?: infer Component }
|
||||
? Component extends FunctionComponent<any>
|
||||
? ComponentProps<Component>
|
||||
: never
|
||||
: never;
|
||||
|
||||
// the first one here has a chance to pollute the cache
|
||||
type Result1 = ComponentProps<typeof ComponentWithForwardRef>;
|
||||
// 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: <T extends FunctionComponent<any>>(
|
||||
props: PropsWithoutRef<ComponentProps<T>> & {
|
||||
className?: string;
|
||||
as?: T | undefined;
|
||||
} & {
|
||||
ref?: Ref<HTMLElement> | undefined;
|
||||
},
|
||||
) => unknown;
|
||||
|
||||
type Result3 = ComponentProps<typeof ComponentWithForwardRef2>;
|
||||
type Result4 = Test<{ component: typeof ComponentWithForwardRef2 }>;
|
||||
@ -0,0 +1,46 @@
|
||||
// @strict: true
|
||||
// @noEmit: true
|
||||
|
||||
declare const EffectTypeId: unique symbol;
|
||||
|
||||
interface Variance<out A, out E, out R> {
|
||||
readonly [EffectTypeId]: VarianceStruct<A, E, R>;
|
||||
}
|
||||
|
||||
type Covariant<A> = (_: never) => A;
|
||||
|
||||
interface VarianceStruct<out A, out E, out R> {
|
||||
readonly _V: string;
|
||||
readonly _A: Covariant<A>;
|
||||
readonly _E: Covariant<E>;
|
||||
readonly _R: Covariant<R>;
|
||||
}
|
||||
|
||||
interface Effect<out A, out E = never, out R = never>
|
||||
extends Variance<A, E, R> {}
|
||||
|
||||
declare const succeed: <A>(value: A) => Effect<A>;
|
||||
|
||||
type F<X, Y> = Y extends { _type: infer Z }
|
||||
? X extends Effect<infer A, infer E, infer R>
|
||||
? Effect<A, E, R | Z>
|
||||
: X
|
||||
: X;
|
||||
|
||||
type ProxyMap<Service> = {
|
||||
[K in keyof Service]: (Service & { _type: Service })[K];
|
||||
};
|
||||
|
||||
declare const implement: <T>() => <I extends ReadonlyArray<any>, X>(
|
||||
x: (...i: I) => X,
|
||||
) => (...i: I) => F<X, T>;
|
||||
|
||||
class XXX {
|
||||
log = implement<this>()(<N extends number>(n: N) => succeed(n));
|
||||
}
|
||||
|
||||
export declare const inner: XXX;
|
||||
export declare const outer: ProxyMap<XXX>;
|
||||
|
||||
export const a = inner.log(100); // Effect<100, never, never>
|
||||
export const b = outer.log(100); // Effect<100, never, XXX>
|
||||
@ -12,3 +12,18 @@ function withP2<P>(p: P) {
|
||||
|
||||
const addP2 = withP2({ foo: 1 });
|
||||
const added2 = addP2({ bar: 2 });
|
||||
|
||||
function withP3<P>(p: P) {
|
||||
const m =
|
||||
<I,>(from: I) =>
|
||||
<I2,>(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 });
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
// @strict: true
|
||||
|
||||
interface Thenable<Value> {
|
||||
then<V>(
|
||||
onFulfilled: (value: Value) => V | Thenable<V>,
|
||||
|
||||
10
tests/cases/compiler/inferenceFromGenericClassNoCrash1.ts
Normal file
10
tests/cases/compiler/inferenceFromGenericClassNoCrash1.ts
Normal file
@ -0,0 +1,10 @@
|
||||
// @strict: true
|
||||
// @noEmit: true
|
||||
|
||||
// https://github.com/microsoft/TypeScript/issues/61633#issuecomment-2841778576
|
||||
|
||||
function RenderFlagsMixin<T extends new (...args: any[]) => object>(Base?: T) {}
|
||||
class Container<T> {
|
||||
t: T;
|
||||
}
|
||||
RenderFlagsMixin(Container);
|
||||
@ -1,6 +1,6 @@
|
||||
// @strict: true
|
||||
|
||||
declare function wrap<X>(x: X): { x: X };
|
||||
declare function call<A extends unknown[], T>(x: { x: (...args: A) => T }, ...args: A): T;
|
||||
|
||||
// This should be of type `number` - ideally, it also would not error.
|
||||
const leak = call(wrap(<T>(x: T) => x), 1);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user