diff --git a/internal/checker/checker.go b/internal/checker/checker.go index 930921e973..fd724d90e8 100644 --- a/internal/checker/checker.go +++ b/internal/checker/checker.go @@ -6987,7 +6987,7 @@ func (c *Checker) getQuickTypeOfExpression(node *ast.Node) *Type { func (c *Checker) getReturnTypeOfSingleNonGenericCallSignature(funcType *Type) *Type { signature := c.getSingleCallSignature(funcType) - if signature != nil && signature.typeParameters == nil { + if signature != nil && len(signature.typeParameters) == 0 { return c.getReturnTypeOfSignature(signature) } return nil @@ -9121,7 +9121,7 @@ func (c *Checker) inferTypeArguments(node *ast.Node, signature *Signature, args // Above, the type of the 'value' parameter is inferred to be 'A'. contextualSignature := c.getSingleCallSignature(instantiatedType) var inferenceSourceType *Type - if contextualSignature != nil && contextualSignature.typeParameters != nil { + if contextualSignature != nil && len(contextualSignature.typeParameters) != 0 { inferenceSourceType = c.getOrCreateTypeFromSignature(c.getSignatureInstantiationWithoutFillingInTypeArguments(contextualSignature, contextualSignature.typeParameters), nil) } else { inferenceSourceType = instantiatedType @@ -9382,7 +9382,7 @@ func (c *Checker) addImplementationSuccessElaboration(s *CallState, failed *Sign candidate := c.getSignatureFromDeclaration(implementation) localState := *s localState.candidates = []*Signature{candidate} - localState.isSingleNonGenericCandidate = candidate.typeParameters == nil + localState.isSingleNonGenericCandidate = len(candidate.typeParameters) == 0 if c.chooseOverload(&localState, c.assignableRelation) != nil { diagnostic.AddRelatedInfo(NewDiagnosticForNode(implementation, diagnostics.The_call_would_have_succeeded_against_this_implementation_but_implementation_signatures_of_overloads_are_not_externally_visible)) } @@ -9949,8 +9949,8 @@ func (c *Checker) isAritySmaller(signature *Signature, target *ast.Node) bool { } func (c *Checker) assignContextualParameterTypes(sig *Signature, context *Signature) { - if context.typeParameters != nil { - if sig.typeParameters != nil { + if len(context.typeParameters) != 0 { + if len(sig.typeParameters) != 0 { // This signature has already has a contextual inference performed and cached on it return } @@ -20201,8 +20201,8 @@ func (c *Checker) getUnionSignatures(signatureLists [][]*Signature) []*Signature if !core.Same(signatures, masterList) { signature := signatures[0] // Debug.assert(signature, "getUnionSignatures bails early on empty signature lists and should not have empty lists on second pass") - if signature.typeParameters != nil && core.Some(results, func(s *Signature) bool { - return s.typeParameters != nil && !c.compareTypeParametersIdentical(signature.typeParameters, s.typeParameters) + if len(signature.typeParameters) != 0 && core.Some(results, func(s *Signature) bool { + return len(s.typeParameters) != 0 && !c.compareTypeParametersIdentical(signature.typeParameters, s.typeParameters) }) { results = nil } else { diff --git a/internal/checker/flow.go b/internal/checker/flow.go index b8e1841171..3ebbf9bf54 100644 --- a/internal/checker/flow.go +++ b/internal/checker/flow.go @@ -2040,7 +2040,7 @@ func (c *Checker) getEffectsSignature(node *ast.Node) *Signature { } signatures := c.getSignaturesOfType(core.OrElse(apparentType, c.unknownType), SignatureKindCall) switch { - case len(signatures) == 1 && signatures[0].typeParameters == nil: + case len(signatures) == 1 && len(signatures[0].typeParameters) == 0: signature = signatures[0] case core.Some(signatures, c.hasTypePredicateOrNeverReturnType): signature = c.getResolvedSignature(node, nil, CheckModeNormal) diff --git a/internal/checker/nodebuilderimpl.go b/internal/checker/nodebuilderimpl.go index e1d876e174..c0e5458afc 100644 --- a/internal/checker/nodebuilderimpl.go +++ b/internal/checker/nodebuilderimpl.go @@ -1690,11 +1690,11 @@ func (b *nodeBuilderImpl) signatureToSignatureDeclarationHelper(signature *Signa b.ctx.approximateLength += 3 // Usually a signature contributes a few more characters than this, but 3 is the minimum - if b.ctx.flags&nodebuilder.FlagsWriteTypeArgumentsOfSignature != 0 && signature.target != nil && signature.mapper != nil && signature.target.typeParameters != nil { + if b.ctx.flags&nodebuilder.FlagsWriteTypeArgumentsOfSignature != 0 && signature.target != nil && signature.mapper != nil && len(signature.target.typeParameters) != 0 { for _, parameter := range signature.target.typeParameters { typeParameters = append(typeParameters, b.typeToTypeNode(b.ch.instantiateType(parameter, signature.mapper))) } - } else if signature.typeParameters != nil { + } else { for _, parameter := range signature.typeParameters { typeParameters = append(typeParameters, b.typeParameterToDeclaration(parameter)) } diff --git a/internal/checker/relater.go b/internal/checker/relater.go index 1e15529a7d..91d7207459 100644 --- a/internal/checker/relater.go +++ b/internal/checker/relater.go @@ -1462,7 +1462,7 @@ func (c *Checker) compareSignaturesRelated(source *Signature, target *Signature, } return TernaryFalse } - if source.typeParameters != nil && !core.Same(source.typeParameters, target.typeParameters) { + if len(source.typeParameters) != 0 && !core.Same(source.typeParameters, target.typeParameters) { target = c.getCanonicalSignature(target) source = c.instantiateSignatureInContextOf(source, target /*inferenceContext*/, nil, compareTypes) } @@ -1653,7 +1653,7 @@ func (c *Checker) compareTypePredicateRelatedTo(source *TypePredicate, target *T // Returns true if `s` is `(...args: A) => R` where `A` is `any`, `any[]`, `never`, or `never[]`, and `R` is `any` or `unknown`. func (c *Checker) isTopSignature(s *Signature) bool { - if s.typeParameters == nil && (s.thisParameter == nil || IsTypeAny(c.getTypeOfParameter(s.thisParameter))) && len(s.parameters) == 1 && signatureHasRestParameter(s) { + if len(s.typeParameters) == 0 && (s.thisParameter == nil || IsTypeAny(c.getTypeOfParameter(s.thisParameter))) && len(s.parameters) == 1 && signatureHasRestParameter(s) { paramType := c.getTypeOfParameter(s.parameters[0]) var restType *Type if c.isArrayType(paramType) { @@ -2090,7 +2090,7 @@ func (c *Checker) isResolvingReturnTypeOfSignature(signature *Signature) bool { } func (c *Checker) findMatchingSignatures(signatureLists [][]*Signature, signature *Signature, listIndex int) []*Signature { - if signature.typeParameters != nil { + if len(signature.typeParameters) != 0 { // We require an exact match for generic signatures, so we only return signatures from the first // signature list and only if they have exact matches in the other signature lists. if listIndex > 0 { @@ -2150,7 +2150,7 @@ func (c *Checker) compareSignaturesIdentical(source *Signature, target *Signatur } // Check that type parameter constraints and defaults match. If they do, instantiate the source // signature with the type parameters of the target signature and continue the comparison. - if target.typeParameters != nil { + if len(target.typeParameters) != 0 { mapper := newTypeMapper(source.typeParameters, target.typeParameters) for i := range len(target.typeParameters) { s := source.typeParameters[i] diff --git a/testdata/baselines/reference/submodule/compiler/abstractClassUnionInstantiation.types b/testdata/baselines/reference/submodule/compiler/abstractClassUnionInstantiation.types index 58d5b00030..d90b333d26 100644 --- a/testdata/baselines/reference/submodule/compiler/abstractClassUnionInstantiation.types +++ b/testdata/baselines/reference/submodule/compiler/abstractClassUnionInstantiation.types @@ -46,7 +46,7 @@ new cls2(); // should error >cls2 : Abstracts new cls3(); // should work ->new cls3() : ConcreteA +>new cls3() : ConcreteA | ConcreteB >cls3 : Concretes [ConcreteA, AbstractA, AbstractB].map(cls => new cls()); // should error diff --git a/testdata/baselines/reference/submodule/compiler/abstractClassUnionInstantiation.types.diff b/testdata/baselines/reference/submodule/compiler/abstractClassUnionInstantiation.types.diff index 64e7be7366..334e8998f2 100644 --- a/testdata/baselines/reference/submodule/compiler/abstractClassUnionInstantiation.types.diff +++ b/testdata/baselines/reference/submodule/compiler/abstractClassUnionInstantiation.types.diff @@ -1,15 +1,6 @@ --- old.abstractClassUnionInstantiation.types +++ new.abstractClassUnionInstantiation.types -@@= skipped -45, +45 lines =@@ - >cls2 : Abstracts - - new cls3(); // should work -->new cls3() : ConcreteA | ConcreteB -+>new cls3() : ConcreteA - >cls3 : Concretes - - [ConcreteA, AbstractA, AbstractB].map(cls => new cls()); // should error -@@= skipped -31, +31 lines =@@ +@@= skipped -76, +76 lines =@@ [ConcreteA, ConcreteB].map(cls => new cls()); // should work >[ConcreteA, ConcreteB].map(cls => new cls()) : ConcreteA[] diff --git a/testdata/baselines/reference/submodule/compiler/jsxComponentTypeErrors.errors.txt b/testdata/baselines/reference/submodule/compiler/jsxComponentTypeErrors.errors.txt index 00cfb1f7bf..4220bd0e48 100644 --- a/testdata/baselines/reference/submodule/compiler/jsxComponentTypeErrors.errors.txt +++ b/testdata/baselines/reference/submodule/compiler/jsxComponentTypeErrors.errors.txt @@ -17,7 +17,13 @@ jsxComponentTypeErrors.tsx(27,16): error TS2786: 'ClassComponent' cannot be used Its instance type 'ClassComponent' is not a valid JSX element. Types of property 'type' are incompatible. Type 'string' is not assignable to type '"element-class"'. -jsxComponentTypeErrors.tsx(28,16): error TS2604: JSX element type 'MixedComponent' does not have any construct or call signatures. +jsxComponentTypeErrors.tsx(28,16): error TS2786: 'MixedComponent' cannot be used as a JSX component. + Its element type 'ClassComponent | { type: string | undefined; }' is not a valid JSX element. + Type 'ClassComponent' is not assignable to type 'Element | ElementClass | null'. + Type 'ClassComponent' is not assignable to type 'Element | ElementClass'. + Type 'ClassComponent' is not assignable to type 'ElementClass'. + Types of property 'type' are incompatible. + Type 'string' is not assignable to type '"element-class"'. jsxComponentTypeErrors.tsx(37,16): error TS2786: 'obj.MemberFunctionComponent' cannot be used as a JSX component. Property 'type' is missing in type '{}' but required in type 'Element'. jsxComponentTypeErrors.tsx(38,16): error TS2786: 'obj. MemberClassComponent' cannot be used as a JSX component. @@ -77,7 +83,13 @@ jsxComponentTypeErrors.tsx(38,16): error TS2786: 'obj. MemberClassComponent' can !!! error TS2786: Type 'string' is not assignable to type '"element-class"'. const elem4 = ; ~~~~~~~~~~~~~~ -!!! error TS2604: JSX element type 'MixedComponent' does not have any construct or call signatures. +!!! error TS2786: 'MixedComponent' cannot be used as a JSX component. +!!! error TS2786: Its element type 'ClassComponent | { type: string | undefined; }' is not a valid JSX element. +!!! error TS2786: Type 'ClassComponent' is not assignable to type 'Element | ElementClass | null'. +!!! error TS2786: Type 'ClassComponent' is not assignable to type 'Element | ElementClass'. +!!! error TS2786: Type 'ClassComponent' is not assignable to type 'ElementClass'. +!!! error TS2786: Types of property 'type' are incompatible. +!!! error TS2786: Type 'string' is not assignable to type '"element-class"'. const obj = { MemberFunctionComponent() { diff --git a/testdata/baselines/reference/submodule/compiler/jsxComponentTypeErrors.errors.txt.diff b/testdata/baselines/reference/submodule/compiler/jsxComponentTypeErrors.errors.txt.diff index 51b3ff35c7..da78fc084d 100644 --- a/testdata/baselines/reference/submodule/compiler/jsxComponentTypeErrors.errors.txt.diff +++ b/testdata/baselines/reference/submodule/compiler/jsxComponentTypeErrors.errors.txt.diff @@ -1,17 +1,8 @@ --- old.jsxComponentTypeErrors.errors.txt +++ new.jsxComponentTypeErrors.errors.txt -@@= skipped -16, +16 lines =@@ - Its instance type 'ClassComponent' is not a valid JSX element. - Types of property 'type' are incompatible. - Type 'string' is not assignable to type '"element-class"'. --jsxComponentTypeErrors.tsx(28,16): error TS2786: 'MixedComponent' cannot be used as a JSX component. -- Its element type 'ClassComponent | { type: string | undefined; }' is not a valid JSX element. -- Type 'ClassComponent' is not assignable to type 'Element | ElementClass | null'. -- Type 'ClassComponent' is not assignable to type 'Element | ElementClass'. -- Type 'ClassComponent' is not assignable to type 'ElementClass'. -- Types of property 'type' are incompatible. -- Type 'string' is not assignable to type '"element-class"'. -+jsxComponentTypeErrors.tsx(28,16): error TS2604: JSX element type 'MixedComponent' does not have any construct or call signatures. +@@= skipped -24, +24 lines =@@ + Types of property 'type' are incompatible. + Type 'string' is not assignable to type '"element-class"'. jsxComponentTypeErrors.tsx(37,16): error TS2786: 'obj.MemberFunctionComponent' cannot be used as a JSX component. - Its return type '{}' is not a valid JSX element. - Property 'type' is missing in type '{}' but required in type 'Element'. @@ -23,22 +14,7 @@ ==== jsxComponentTypeErrors.tsx (7 errors) ==== -@@= skipped -68, +60 lines =@@ - !!! error TS2786: Type 'string' is not assignable to type '"element-class"'. - const elem4 = ; - ~~~~~~~~~~~~~~ --!!! error TS2786: 'MixedComponent' cannot be used as a JSX component. --!!! error TS2786: Its element type 'ClassComponent | { type: string | undefined; }' is not a valid JSX element. --!!! error TS2786: Type 'ClassComponent' is not assignable to type 'Element | ElementClass | null'. --!!! error TS2786: Type 'ClassComponent' is not assignable to type 'Element | ElementClass'. --!!! error TS2786: Type 'ClassComponent' is not assignable to type 'ElementClass'. --!!! error TS2786: Types of property 'type' are incompatible. --!!! error TS2786: Type 'string' is not assignable to type '"element-class"'. -+!!! error TS2604: JSX element type 'MixedComponent' does not have any construct or call signatures. - - const obj = { - MemberFunctionComponent() { -@@= skipped -18, +12 lines =@@ +@@= skipped -78, +76 lines =@@ const elem5 = ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2786: 'obj.MemberFunctionComponent' cannot be used as a JSX component.