Skip to content

Commit 33903b3

Browse files
committed
Port TS PR 61668 - Fix type variable leaks and cache inconsistencies
1 parent f2d955b commit 33903b3

16 files changed

+162
-144
lines changed

internal/checker/checker.go

Lines changed: 53 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,7 @@ type InferenceContext struct {
262262
mapper *TypeMapper // Mapper that fixes inferences
263263
nonFixingMapper *TypeMapper // Mapper that doesn't fix inferences
264264
returnMapper *TypeMapper // Type mapper for inferences from return types (if any)
265+
outerReturnMapper *TypeMapper // Type mapper for inferences from return types of outer function (if any)
265266
inferredTypeParameters []*Type // Inferred type parameters for function result
266267
intraExpressionInferenceSites []IntraExpressionInferenceSite
267268
}
@@ -7298,15 +7299,15 @@ func (c *Checker) instantiateTypeWithSingleGenericCallSignature(node *ast.Node,
72987299
if !hasOverlappingInferences(context.inferences, inferences) {
72997300
c.mergeInferences(context.inferences, inferences)
73007301
context.inferredTypeParameters = core.Concatenate(context.inferredTypeParameters, uniqueTypeParameters)
7301-
return c.getOrCreateTypeFromSignature(instantiatedSignature, nil)
7302+
return c.getOrCreateTypeFromSignature(instantiatedSignature)
73027303
}
73037304
}
73047305
}
73057306
// TODO: The signature may reference any outer inference contexts, but we map pop off and then apply new inference contexts,
73067307
// and thus get different inferred types. That this is cached on the *first* such attempt is not currently an issue, since expression
73077308
// types *also* get cached on the first pass. If we ever properly speculate, though, the cached "isolatedSignatureType" signature
73087309
// field absolutely needs to be included in the list of speculative caches.
7309-
return c.getOrCreateTypeFromSignature(c.instantiateSignatureInContextOf(signature, contextualSignature, context, nil), c.getOuterInferenceTypeParameters())
7310+
return c.getOrCreateTypeFromSignature(c.instantiateSignatureInContextOf(signature, contextualSignature, context, nil))
73107311
}
73117312

73127313
func (c *Checker) getOuterInferenceTypeParameters() []*Type {
@@ -9164,7 +9165,7 @@ func (c *Checker) inferTypeArguments(node *ast.Node, signature *Signature, args
91649165
contextualSignature := c.getSingleCallSignature(instantiatedType)
91659166
var inferenceSourceType *Type
91669167
if contextualSignature != nil && len(contextualSignature.typeParameters) != 0 {
9167-
inferenceSourceType = c.getOrCreateTypeFromSignature(c.getSignatureInstantiationWithoutFillingInTypeArguments(contextualSignature, contextualSignature.typeParameters), nil)
9168+
inferenceSourceType = c.getOrCreateTypeFromSignature(c.getSignatureInstantiationWithoutFillingInTypeArguments(contextualSignature, contextualSignature.typeParameters))
91689169
} else {
91699170
inferenceSourceType = instantiatedType
91709171
}
@@ -9175,10 +9176,14 @@ func (c *Checker) inferTypeArguments(node *ast.Node, signature *Signature, args
91759176
// from the return type. We need a separate inference pass here because (a) instantiation of
91769177
// the source type uses the outer context's return mapper (which excludes inferences made from
91779178
// outer arguments), and (b) we don't want any further inferences going into this context.
9179+
// We use `createOuterReturnMapper` to ensure that all occurrences of outer type parameters are
9180+
// replaced with inferences produced from the outer return type or preceding outer arguments.
9181+
// This protects against circular inferences, i.e. avoiding situations where inferences reference
9182+
// type parameters for which the inferences are being made.
91789183
returnContext := c.newInferenceContext(signature.typeParameters, signature, context.flags, nil)
91799184
var outerReturnMapper *TypeMapper
91809185
if outerContext != nil {
9181-
outerReturnMapper = outerContext.returnMapper
9186+
outerReturnMapper = c.createOuterReturnMapper(outerContext)
91829187
}
91839188
returnSourceType := c.instantiateType(contextualType, outerReturnMapper)
91849189
c.inferTypes(returnContext.inferences, returnSourceType, inferenceTargetType, InferencePriorityNone, false)
@@ -16316,6 +16321,9 @@ func (c *Checker) getConstraintOfType(t *Type) *Type {
1631616321
}
1631716322

1631816323
func (c *Checker) getConstraintOfTypeParameter(typeParameter *Type) *Type {
16324+
if typeParameter.flags&TypeFlagsTypeParameter == 0 {
16325+
return nil
16326+
}
1631916327
if c.hasNonCircularBaseConstraint(typeParameter) {
1632016328
return c.getConstraintFromTypeParameter(typeParameter)
1632116329
}
@@ -18447,8 +18455,10 @@ func (c *Checker) getSignatureInstantiation(sig *Signature, typeArguments []*Typ
1844718455
if returnSignature != nil {
1844818456
newReturnSignature := c.cloneSignature(returnSignature)
1844918457
newReturnSignature.typeParameters = inferredTypeParameters
18458+
newReturnType := c.getOrCreateTypeFromSignature(newReturnSignature)
18459+
newReturnType.AsObjectType().mapper = instantiatedSignature.mapper
1845018460
newInstantiatedSignature := c.cloneSignature(instantiatedSignature)
18451-
newInstantiatedSignature.resolvedReturnType = c.getOrCreateTypeFromSignature(newReturnSignature, nil)
18461+
newInstantiatedSignature.resolvedReturnType = newReturnType
1845218462
return newInstantiatedSignature
1845318463
}
1845418464
}
@@ -18513,7 +18523,7 @@ func (c *Checker) getSingleSignature(t *Type, kind SignatureKind, allowMembers b
1851318523
return nil
1851418524
}
1851518525

18516-
func (c *Checker) getOrCreateTypeFromSignature(sig *Signature, outerTypeParameters []*Type) *Type {
18526+
func (c *Checker) getOrCreateTypeFromSignature(sig *Signature) *Type {
1851718527
// There are two ways to declare a construct signature, one is by declaring a class constructor
1851818528
// using the constructor keyword, and the other is declaring a bare construct signature in an
1851918529
// object type literal or interface (using the new keyword). Each way of declaring a constructor
@@ -18525,17 +18535,12 @@ func (c *Checker) getOrCreateTypeFromSignature(sig *Signature, outerTypeParamete
1852518535
}
1852618536
// If declaration is undefined, it is likely to be the signature of the default constructor.
1852718537
isConstructor := kind == ast.KindUnknown || kind == ast.KindConstructor || kind == ast.KindConstructSignature || kind == ast.KindConstructorType
18528-
// The type must have a symbol with a `Function` flag and a declaration in order to be correctly flagged as possibly containing
18529-
// type variables by `couldContainTypeVariables`
18530-
t := c.newObjectType(ObjectFlagsAnonymous|ObjectFlagsSingleSignatureType, c.newSymbol(ast.SymbolFlagsFunction, ast.InternalSymbolNameFunction))
18531-
if sig.declaration != nil && !ast.NodeIsSynthesized(sig.declaration) {
18532-
t.symbol.Declarations = []*ast.Node{sig.declaration}
18533-
t.symbol.ValueDeclaration = sig.declaration
18534-
}
18535-
if outerTypeParameters == nil && sig.declaration != nil {
18536-
outerTypeParameters = c.getOuterTypeParameters(sig.declaration, true /*includeThisTypes*/)
18538+
18539+
var symbol *ast.Symbol
18540+
if sig.declaration != nil {
18541+
symbol = sig.declaration.Symbol()
1853718542
}
18538-
t.AsSingleSignatureType().outerTypeParameters = outerTypeParameters
18543+
t := c.newObjectType(ObjectFlagsAnonymous|ObjectFlagsSingleSignatureType, symbol)
1853918544
if isConstructor {
1854018545
c.setStructuredTypeMembers(t, nil, nil, []*Signature{sig}, nil)
1854118546
} else {
@@ -21182,6 +21187,9 @@ func (c *Checker) getDefaultTypeArgumentType(isInJavaScriptFile bool) *Type {
2118221187
// this gets the instantiated default type of its target. If the type parameter has no default type or
2118321188
// the default is circular, `undefined` is returned.
2118421189
func (c *Checker) getDefaultFromTypeParameter(t *Type) *Type {
21190+
if t.flags&TypeFlagsTypeParameter == 0 {
21191+
return nil
21192+
}
2118521193
defaultType := c.getResolvedTypeParameterDefault(t)
2118621194
if defaultType != c.noConstraintType && defaultType != c.circularConstraintType {
2118721195
return defaultType
@@ -21349,7 +21357,6 @@ func (c *Checker) couldContainTypeVariablesWorker(t *Type) bool {
2134921357
}
2135021358
result := t.flags&TypeFlagsInstantiable != 0 ||
2135121359
t.flags&TypeFlagsObject != 0 && !c.isNonGenericTopLevelType(t) && (objectFlags&ObjectFlagsReference != 0 && (t.AsTypeReference().node != nil || core.Some(c.getTypeArguments(t), c.couldContainTypeVariables)) ||
21352-
objectFlags&ObjectFlagsSingleSignatureType != 0 && len(t.AsSingleSignatureType().outerTypeParameters) != 0 ||
2135321360
objectFlags&ObjectFlagsAnonymous != 0 && t.symbol != nil && t.symbol.Flags&(ast.SymbolFlagsFunction|ast.SymbolFlagsMethod|ast.SymbolFlagsClass|ast.SymbolFlagsTypeLiteral|ast.SymbolFlagsObjectLiteral) != 0 && t.symbol.Declarations != nil ||
2135421361
objectFlags&(ObjectFlagsMapped|ObjectFlagsReverseMapped|ObjectFlagsObjectRestType|ObjectFlagsInstantiationExpressionType) != 0) ||
2135521362
t.flags&TypeFlagsUnionOrIntersection != 0 && t.flags&TypeFlagsEnumLiteral == 0 && !c.isNonGenericTopLevelType(t) && core.Some(t.Types(), c.couldContainTypeVariables)
@@ -21458,9 +21465,9 @@ func (c *Checker) instantiateTypeWorker(t *Type, m *TypeMapper, alias *TypeAlias
2145821465
// Handles instantiation of the following object types:
2145921466
// AnonymousType (ObjectFlagsAnonymous)
2146021467
// TypeReference with node != nil (ObjectFlagsReference)
21461-
// SingleSignatureType (ObjectFlagsSingleSignatureType)
2146221468
// InstantiationExpressionType (ObjectFlagsInstantiationExpressionType)
2146321469
// MappedType (ObjectFlagsMapped)
21470+
// Note: ObjectFlagsSingleSignatureType types are handled as anonymous types
2146421471
func (c *Checker) getObjectTypeInstantiation(t *Type, m *TypeMapper, alias *TypeAlias) *Type {
2146521472
var declaration *ast.Node
2146621473
var target *Type
@@ -21482,34 +21489,30 @@ func (c *Checker) getObjectTypeInstantiation(t *Type, m *TypeMapper, alias *Type
2148221489
default:
2148321490
target = t
2148421491
}
21485-
if t.objectFlags&ObjectFlagsSingleSignatureType != 0 {
21486-
typeParameters = t.AsSingleSignatureType().outerTypeParameters
21487-
} else {
21488-
typeParameters = links.outerTypeParameters
21489-
if typeParameters == nil {
21490-
// The first time an anonymous type is instantiated we compute and store a list of the type
21491-
// parameters that are in scope (and therefore potentially referenced). For type literals that
21492-
// aren't the right hand side of a generic type alias declaration we optimize by reducing the
21493-
// set of type parameters to those that are possibly referenced in the literal.
21494-
typeParameters = c.getOuterTypeParameters(declaration, true /*includeThisTypes*/)
21495-
if len(target.alias.TypeArguments()) == 0 {
21496-
if t.objectFlags&(ObjectFlagsReference|ObjectFlagsInstantiationExpressionType) != 0 {
21497-
typeParameters = core.Filter(typeParameters, func(tp *Type) bool {
21498-
return c.isTypeParameterPossiblyReferenced(tp, declaration)
21499-
})
21500-
} else if target.symbol.Flags&(ast.SymbolFlagsMethod|ast.SymbolFlagsTypeLiteral) != 0 {
21501-
typeParameters = core.Filter(typeParameters, func(tp *Type) bool {
21502-
return core.Some(t.symbol.Declarations, func(d *ast.Node) bool {
21503-
return c.isTypeParameterPossiblyReferenced(tp, d)
21504-
})
21492+
typeParameters = links.outerTypeParameters
21493+
if typeParameters == nil {
21494+
// The first time an anonymous type is instantiated we compute and store a list of the type
21495+
// parameters that are in scope (and therefore potentially referenced). For type literals that
21496+
// aren't the right hand side of a generic type alias declaration we optimize by reducing the
21497+
// set of type parameters to those that are possibly referenced in the literal.
21498+
typeParameters = c.getOuterTypeParameters(declaration, true /*includeThisTypes*/)
21499+
if len(target.alias.TypeArguments()) == 0 {
21500+
if t.objectFlags&(ObjectFlagsReference|ObjectFlagsInstantiationExpressionType) != 0 {
21501+
typeParameters = core.Filter(typeParameters, func(tp *Type) bool {
21502+
return c.isTypeParameterPossiblyReferenced(tp, declaration)
21503+
})
21504+
} else if target.symbol.Flags&(ast.SymbolFlagsMethod|ast.SymbolFlagsTypeLiteral) != 0 {
21505+
typeParameters = core.Filter(typeParameters, func(tp *Type) bool {
21506+
return core.Some(t.symbol.Declarations, func(d *ast.Node) bool {
21507+
return c.isTypeParameterPossiblyReferenced(tp, d)
2150521508
})
21506-
}
21507-
}
21508-
if typeParameters == nil {
21509-
typeParameters = []*Type{}
21509+
})
2151021510
}
21511-
links.outerTypeParameters = typeParameters
2151221511
}
21512+
if typeParameters == nil {
21513+
typeParameters = []*Type{}
21514+
}
21515+
links.outerTypeParameters = typeParameters
2151321516
}
2151421517
if len(typeParameters) == 0 {
2151521518
return t
@@ -21534,12 +21537,10 @@ func (c *Checker) getObjectTypeInstantiation(t *Type, m *TypeMapper, alias *Type
2153421537
}
2153521538
result := data.instantiations[key]
2153621539
if result == nil {
21537-
if t.objectFlags&ObjectFlagsSingleSignatureType != 0 {
21538-
result = c.instantiateAnonymousType(t, m, nil /*alias*/)
21539-
data.instantiations[key] = result
21540-
return result
21541-
}
2154221540
newMapper := newTypeMapper(typeParameters, typeArguments)
21541+
if target.objectFlags&ObjectFlagsSingleSignatureType != 0 && m != nil {
21542+
newMapper = c.combineTypeMappers(newMapper, m)
21543+
}
2154321544
switch {
2154421545
case target.objectFlags&ObjectFlagsReference != 0:
2154521546
result = c.createDeferredTypeReference(t.Target(), t.AsTypeReference().node, newMapper, newAlias)
@@ -21635,8 +21636,6 @@ func (c *Checker) instantiateAnonymousType(t *Type, m *TypeMapper, alias *TypeAl
2163521636
freshTypeParameter.AsTypeParameter().mapper = m
2163621637
case t.objectFlags&ObjectFlagsInstantiationExpressionType != 0:
2163721638
result.AsInstantiationExpressionType().node = t.AsInstantiationExpressionType().node
21638-
case t.objectFlags&ObjectFlagsSingleSignatureType != 0:
21639-
result.AsSingleSignatureType().outerTypeParameters = t.AsSingleSignatureType().outerTypeParameters
2164021639
}
2164121640
if alias == nil {
2164221641
alias = c.instantiateTypeAlias(t.alias, m)
@@ -24161,7 +24160,7 @@ func (c *Checker) newObjectType(objectFlags ObjectFlags, symbol *ast.Symbol) *Ty
2416124160
case objectFlags&ObjectFlagsInstantiationExpressionType != 0:
2416224161
data = &InstantiationExpressionType{}
2416324162
case objectFlags&ObjectFlagsSingleSignatureType != 0:
24164-
data = &SingleSignatureType{}
24163+
data = &ObjectType{}
2416524164
case objectFlags&ObjectFlagsAnonymous != 0:
2416624165
data = &ObjectType{}
2416724166
default:
@@ -28447,7 +28446,7 @@ func (c *Checker) getContextualTypeForArgumentAtIndex(callTarget *ast.Node, argI
2844728446
func (c *Checker) getContextualTypeForDecorator(decorator *ast.Node) *Type {
2844828447
signature := c.getDecoratorCallSignature(decorator)
2844928448
if signature != nil {
28450-
return c.getOrCreateTypeFromSignature(signature, nil)
28449+
return c.getOrCreateTypeFromSignature(signature)
2845128450
}
2845228451
return nil
2845328452
}
@@ -28977,7 +28976,7 @@ func (c *Checker) getESDecoratorCallSignature(decorator *ast.Node) *Signature {
2897728976
// instance, depending on whether the member was `static`.
2897828977
var valueType *Type
2897928978
if ast.IsMethodDeclaration(node) {
28980-
valueType = c.getOrCreateTypeFromSignature(c.getSignatureFromDeclaration(node), nil)
28979+
valueType = c.getOrCreateTypeFromSignature(c.getSignatureFromDeclaration(node))
2898128980
} else {
2898228981
valueType = c.getTypeOfNode(node)
2898328982
}
@@ -29144,7 +29143,7 @@ func (c *Checker) newESDecoratorCallSignature(targetType *Type, contextType *Typ
2914429143
// Creates a synthetic `FunctionType`
2914529144
func (c *Checker) newFunctionType(typeParameters []*Type, thisParameter *ast.Symbol, parameters []*ast.Symbol, returnType *Type) *Type {
2914629145
signature := c.newCallSignature(typeParameters, thisParameter, parameters, returnType)
29147-
return c.getOrCreateTypeFromSignature(signature, nil)
29146+
return c.getOrCreateTypeFromSignature(signature)
2914829147
}
2914929148

2915029149
func (c *Checker) newGetterFunctionType(t *Type) *Type {

internal/checker/inference.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1349,6 +1349,20 @@ func (c *Checker) getMapperFromContext(n *InferenceContext) *TypeMapper {
13491349
return n.mapper
13501350
}
13511351

1352+
// Return a type mapper that combines the context's return mapper with a mapper that erases any additional type parameters
1353+
// to their inferences at the time of creation.
1354+
func (c *Checker) createOuterReturnMapper(context *InferenceContext) *TypeMapper {
1355+
if context.outerReturnMapper == nil {
1356+
clonedMapper := c.getMapperFromContext(c.cloneInferenceContext(context, InferenceFlagsNone))
1357+
if context.returnMapper != nil {
1358+
context.outerReturnMapper = newMergedTypeMapper(context.returnMapper, clonedMapper)
1359+
} else {
1360+
context.outerReturnMapper = clonedMapper
1361+
}
1362+
}
1363+
return context.outerReturnMapper
1364+
}
1365+
13521366
func (c *Checker) getCovariantInference(inference *InferenceInfo, signature *Signature) *Type {
13531367
// Extract all object and array literal types and replace them with a single widened and normalized type.
13541368
candidates := c.unionObjectAndArrayLiteralCandidates(inference.candidates)

internal/checker/jsx.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1107,7 +1107,7 @@ func (c *Checker) getStaticTypeOfReferencedJsxConstructor(context *ast.Node) *Ty
11071107
if isJsxIntrinsicTagName(context.TagName()) {
11081108
result := c.getIntrinsicAttributesTypeFromJsxOpeningLikeElement(context)
11091109
fakeSignature := c.createSignatureForJSXIntrinsic(context, result)
1110-
return c.getOrCreateTypeFromSignature(fakeSignature, nil)
1110+
return c.getOrCreateTypeFromSignature(fakeSignature)
11111111
}
11121112
tagType := c.checkExpressionCached(context.TagName())
11131113
if tagType.flags&TypeFlagsStringLiteral != 0 {
@@ -1116,7 +1116,7 @@ func (c *Checker) getStaticTypeOfReferencedJsxConstructor(context *ast.Node) *Ty
11161116
return c.errorType
11171117
}
11181118
fakeSignature := c.createSignatureForJSXIntrinsic(context, result)
1119-
return c.getOrCreateTypeFromSignature(fakeSignature, nil)
1119+
return c.getOrCreateTypeFromSignature(fakeSignature)
11201120
}
11211121
return tagType
11221122
}

internal/checker/nodebuilderimpl.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2376,7 +2376,7 @@ func (b *nodeBuilderImpl) createTypeNodeFromObjectType(t *Type) *ast.TypeNode {
23762376
})
23772377
if len(abstractSignatures) > 0 {
23782378
types := core.Map(abstractSignatures, func(s *Signature) *Type {
2379-
return b.ch.getOrCreateTypeFromSignature(s, nil)
2379+
return b.ch.getOrCreateTypeFromSignature(s)
23802380
})
23812381
// count the number of type elements excluding abstract constructors
23822382
typeElementCount := len(callSigs) + (len(ctorSigs) - len(abstractSignatures)) + len(resolved.indexInfos) + (core.IfElse(b.ctx.flags&nodebuilder.FlagsWriteClassExpressionAsTypeLiteral != 0, core.CountWhere(resolved.properties, func(p *ast.Symbol) bool {

internal/checker/types.go

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -578,7 +578,6 @@ func (t *Type) AsIntrinsicType() *IntrinsicType { return t.data.(*In
578578
func (t *Type) AsLiteralType() *LiteralType { return t.data.(*LiteralType) }
579579
func (t *Type) AsUniqueESSymbolType() *UniqueESSymbolType { return t.data.(*UniqueESSymbolType) }
580580
func (t *Type) AsTupleType() *TupleType { return t.data.(*TupleType) }
581-
func (t *Type) AsSingleSignatureType() *SingleSignatureType { return t.data.(*SingleSignatureType) }
582581
func (t *Type) AsInstantiationExpressionType() *InstantiationExpressionType {
583582
return t.data.(*InstantiationExpressionType)
584583
}
@@ -838,9 +837,7 @@ func (t *StructuredType) Properties() []*ast.Symbol {
838837
// ObjectFlagsAnonymous|ObjectFlagsInstantiationExpression: Originating instantiation expression type
839838
// ObjectFlagsAnonymous|ObjectFlagsInstantiated|ObjectFlagsInstantiationExpression: Instantiated instantiation expression type
840839

841-
// SingleSignatureType:
842-
// ObjectFlagsAnonymous|ObjectFlagsSingleSignatureType: Originating single signature type
843-
// ObjectFlagsAnonymous|ObjectFlagsInstantiated|ObjectFlagsSingleSignatureType: Instantiated single signature type
840+
// Note: ObjectFlagsSingleSignatureType types are AnonymousType with the flag set (no separate struct)
844841

845842
// ReverseMappedType:
846843
// ObjectFlagsAnonymous|ObjectFlagsReverseMapped: Reverse mapped type
@@ -948,13 +945,6 @@ func (t *TupleType) ElementFlags() []ElementFlags {
948945
return elementFlags
949946
}
950947

951-
// SingleSignatureType
952-
953-
type SingleSignatureType struct {
954-
ObjectType
955-
outerTypeParameters []*Type
956-
}
957-
958948
// InstantiationExpressionType
959949

960950
type InstantiationExpressionType struct {

internal/testrunner/compiler_runner.go

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -105,9 +105,6 @@ var skippedTests = []string{
105105
"noImplicitUseStrict_amd.ts",
106106
"noImplicitAnyIndexingSuppressed.ts",
107107
"excessPropertyErrorsSuppressed.ts",
108-
109-
// Broken
110-
"inferenceFromGenericClassNoCrash1.ts",
111108
}
112109

113110
func (r *CompilerBaselineRunner) RunTests(t *testing.T) {

testdata/baselines/reference/submodule/compiler/genericCallInferenceInConditionalTypes1.types

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ type Result1 = ComponentProps<typeof ComponentWithForwardRef>;
8080

8181
// that could be incorrectly reused by this one
8282
type Result2 = Test<{ component: typeof ComponentWithForwardRef }>; // no `T` leak
83-
>Result2 : PropsWithoutRef<ComponentProps<T>> & { ref?: Ref<HTMLElement> | undefined; }
83+
>Result2 : Omit<any, "ref"> & { ref?: Ref<HTMLElement> | undefined; }
8484
>component : <T extends FunctionComponent<any>>(props: PropsWithoutRef<ComponentProps<T>> & { ref?: Ref<HTMLElement> | undefined; }) => unknown
8585
>ComponentWithForwardRef : <T extends FunctionComponent<any>>(props: PropsWithoutRef<ComponentProps<T>> & { ref?: Ref<HTMLElement> | undefined; }) => unknown
8686

0 commit comments

Comments
 (0)