Skip to content

Commit fae2403

Browse files
authored
Check this params when comparing pseudotype signatures to type signatures (#4062)
1 parent c9968e6 commit fae2403

5 files changed

Lines changed: 114 additions & 35 deletions

internal/checker/pseudotypenodebuilder.go

Lines changed: 52 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -450,22 +450,10 @@ func (b *NodeBuilderImpl) pseudoTypeEquivalentToType(t *pseudochecker.PseudoType
450450
// Target property type doesn't have a single call signature; can't validate
451451
continue
452452
}
453-
if len(targetSig.parameters) != len(d.Parameters) {
454-
if reportErrors {
455-
b.ctx.tracker.ReportInferenceFallback(e.Name.Parent)
456-
}
453+
paramEq := b.pseudoParametersEquivalentToParameters(d.Parameters, targetSig, reportErrors, e.Name.Parent)
454+
if !paramEq {
457455
return false
458456
}
459-
for i, p := range d.Parameters {
460-
targetParam := targetSig.parameters[i]
461-
paramType := b.ch.getTypeOfParameter(targetParam)
462-
if !b.pseudoTypeEquivalentToType(p.Type, paramType, p.Optional, false) {
463-
if reportErrors {
464-
b.ctx.tracker.ReportInferenceFallback(e.Name.Parent)
465-
}
466-
return false
467-
}
468-
}
469457
targetPredicate := b.ch.getTypePredicateOfSignature(targetSig)
470458
if targetPredicate != nil {
471459
if !b.pseudoReturnTypeMatchesPredicate(d.ReturnType, targetPredicate) {
@@ -533,27 +521,9 @@ func (b *NodeBuilderImpl) pseudoTypeEquivalentToType(t *pseudochecker.PseudoType
533521
}
534522
return false
535523
}
536-
if len(targetSig.parameters) != len(pt.Parameters) {
537-
if reportErrors {
538-
b.ctx.tracker.ReportInferenceFallback(pt.Signature)
539-
}
540-
return false // TODO: spread tuple params may mess with this check
541-
}
542-
for i, p := range pt.Parameters {
543-
targetParam := targetSig.parameters[i]
544-
if p.Optional != b.ch.isOptionalParameter(targetParam.ValueDeclaration) {
545-
if reportErrors {
546-
b.ctx.tracker.ReportInferenceFallback(p.Name.Parent)
547-
}
548-
return false
549-
}
550-
paramType := b.ch.getTypeOfParameter(targetParam)
551-
if !b.pseudoTypeEquivalentToType(p.Type, paramType, p.Optional, false) {
552-
if reportErrors {
553-
b.ctx.tracker.ReportInferenceFallback(p.Name.Parent)
554-
}
555-
return false
556-
}
524+
paramEq := b.pseudoParametersEquivalentToParameters(pt.Parameters, targetSig, reportErrors, pt.Signature)
525+
if !paramEq {
526+
return false
557527
}
558528
targetPredicate := b.ch.getTypePredicateOfSignature(targetSig)
559529
if targetPredicate != nil {
@@ -578,6 +548,53 @@ func (b *NodeBuilderImpl) pseudoTypeEquivalentToType(t *pseudochecker.PseudoType
578548
}
579549
}
580550

551+
func (b *NodeBuilderImpl) pseudoParametersEquivalentToParameters(params []*pseudochecker.PseudoParameter, targetSig *Signature, reportErrors bool, nonParamErrorLocation *ast.Node) bool {
552+
if targetSig.thisParameter != nil && len(params) == 0 {
553+
if reportErrors {
554+
b.ctx.tracker.ReportInferenceFallback(nonParamErrorLocation) // missing `this` param
555+
}
556+
return false
557+
} else if targetSig.thisParameter != nil && ast.IsThisIdentifier(params[0].Name) {
558+
targetParam := targetSig.thisParameter
559+
paramType := b.ch.getTypeOfParameter(targetParam)
560+
if !b.pseudoTypeEquivalentToType(params[0].Type, paramType, params[0].Optional, false) {
561+
if reportErrors {
562+
b.ctx.tracker.ReportInferenceFallback(params[0].Name.Parent)
563+
}
564+
return false
565+
}
566+
params = params[1:]
567+
} else if targetSig.thisParameter != nil {
568+
if reportErrors {
569+
b.ctx.tracker.ReportInferenceFallback(nonParamErrorLocation)
570+
}
571+
return false
572+
}
573+
if len(targetSig.parameters) != len(params) {
574+
if reportErrors {
575+
b.ctx.tracker.ReportInferenceFallback(nonParamErrorLocation)
576+
}
577+
return false // TODO: spread tuple params may mess with this check
578+
}
579+
for i, p := range params {
580+
targetParam := targetSig.parameters[i]
581+
if p.Optional != b.ch.isOptionalParameter(targetParam.ValueDeclaration) {
582+
if reportErrors {
583+
b.ctx.tracker.ReportInferenceFallback(p.Name.Parent)
584+
}
585+
return false
586+
}
587+
paramType := b.ch.getTypeOfParameter(targetParam)
588+
if !b.pseudoTypeEquivalentToType(p.Type, paramType, p.Optional, false) {
589+
if reportErrors {
590+
b.ctx.tracker.ReportInferenceFallback(p.Name.Parent)
591+
}
592+
return false
593+
}
594+
}
595+
return true
596+
}
597+
581598
func isStructuralPseudoType(t *pseudochecker.PseudoType) bool {
582599
switch t.Kind {
583600
case pseudochecker.PseudoTypeKindObjectLiteral, pseudochecker.PseudoTypeKindTuple, pseudochecker.PseudoTypeKindSingleCallSignature:
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//// [tests/cases/compiler/isolatedDeclarationsThisParameterWithCapturedGeneric.ts] ////
2+
3+
//// [isolatedDeclarationsThisParameterWithCapturedGeneric.ts]
4+
export function fromProviders<T>() {
5+
return {
6+
tearDown(this: {state: T}): void {}
7+
};
8+
}
9+
10+
//// [isolatedDeclarationsThisParameterWithCapturedGeneric.js]
11+
export function fromProviders() {
12+
return {
13+
tearDown() { }
14+
};
15+
}
16+
17+
18+
//// [isolatedDeclarationsThisParameterWithCapturedGeneric.d.ts]
19+
export declare function fromProviders<T>(): {
20+
tearDown(this: {
21+
state: T;
22+
}): void;
23+
};
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
//// [tests/cases/compiler/isolatedDeclarationsThisParameterWithCapturedGeneric.ts] ////
2+
3+
=== isolatedDeclarationsThisParameterWithCapturedGeneric.ts ===
4+
export function fromProviders<T>() {
5+
>fromProviders : Symbol(fromProviders, Decl(isolatedDeclarationsThisParameterWithCapturedGeneric.ts, 0, 0))
6+
>T : Symbol(T, Decl(isolatedDeclarationsThisParameterWithCapturedGeneric.ts, 0, 30))
7+
8+
return {
9+
tearDown(this: {state: T}): void {}
10+
>tearDown : Symbol(tearDown, Decl(isolatedDeclarationsThisParameterWithCapturedGeneric.ts, 1, 10))
11+
>this : Symbol(this, Decl(isolatedDeclarationsThisParameterWithCapturedGeneric.ts, 2, 13))
12+
>state : Symbol(state, Decl(isolatedDeclarationsThisParameterWithCapturedGeneric.ts, 2, 20))
13+
>T : Symbol(T, Decl(isolatedDeclarationsThisParameterWithCapturedGeneric.ts, 0, 30))
14+
15+
};
16+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
//// [tests/cases/compiler/isolatedDeclarationsThisParameterWithCapturedGeneric.ts] ////
2+
3+
=== isolatedDeclarationsThisParameterWithCapturedGeneric.ts ===
4+
export function fromProviders<T>() {
5+
>fromProviders : <T>() => { tearDown(this: { state: T; }): void; }
6+
7+
return {
8+
>{ tearDown(this: {state: T}): void {} } : { tearDown(this: { state: T; }): void; }
9+
10+
tearDown(this: {state: T}): void {}
11+
>tearDown : (this: { state: T; }) => void
12+
>this : { state: T; }
13+
>state : T
14+
15+
};
16+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// @declaration: true
2+
// @isolatedDeclarations: true
3+
export function fromProviders<T>() {
4+
return {
5+
tearDown(this: {state: T}): void {}
6+
};
7+
}

0 commit comments

Comments
 (0)