Merge pull request #17708 from Microsoft/fix-type-predicate-index-in-errors

Fix type predicate index in error reporting
This commit is contained in:
Nathan Shively-Sanders
2017-08-09 16:12:46 -07:00
committed by GitHub
5 changed files with 61 additions and 6 deletions

View File

@@ -8592,7 +8592,7 @@ namespace ts {
// The following block preserves behavior forbidding boolean returning functions from being assignable to type guard returning functions
if (target.typePredicate) {
if (source.typePredicate) {
result &= compareTypePredicateRelatedTo(source.typePredicate, target.typePredicate, reportErrors, errorReporter, compareTypes);
result &= compareTypePredicateRelatedTo(source.typePredicate, target.typePredicate, source.declaration, target.declaration, reportErrors, errorReporter, compareTypes);
}
else if (isIdentifierTypePredicate(target.typePredicate)) {
if (reportErrors) {
@@ -8614,8 +8614,11 @@ namespace ts {
return result;
}
function compareTypePredicateRelatedTo(source: TypePredicate,
function compareTypePredicateRelatedTo(
source: TypePredicate,
target: TypePredicate,
sourceDeclaration: SignatureDeclaration,
targetDeclaration: SignatureDeclaration,
reportErrors: boolean,
errorReporter: ErrorReporter,
compareTypes: (s: Type, t: Type, reportErrors?: boolean) => Ternary): Ternary {
@@ -8628,11 +8631,13 @@ namespace ts {
}
if (source.kind === TypePredicateKind.Identifier) {
const sourceIdentifierPredicate = source as IdentifierTypePredicate;
const targetIdentifierPredicate = target as IdentifierTypePredicate;
if (sourceIdentifierPredicate.parameterIndex !== targetIdentifierPredicate.parameterIndex) {
const sourcePredicate = source as IdentifierTypePredicate;
const targetPredicate = target as IdentifierTypePredicate;
const sourceIndex = sourcePredicate.parameterIndex - (getThisParameter(sourceDeclaration) ? 1 : 0);
const targetIndex = targetPredicate.parameterIndex - (getThisParameter(targetDeclaration) ? 1 : 0);
if (sourceIndex !== targetIndex) {
if (reportErrors) {
errorReporter(Diagnostics.Parameter_0_is_not_in_the_same_position_as_parameter_1, sourceIdentifierPredicate.parameterName, targetIdentifierPredicate.parameterName);
errorReporter(Diagnostics.Parameter_0_is_not_in_the_same_position_as_parameter_1, sourcePredicate.parameterName, targetPredicate.parameterName);
errorReporter(Diagnostics.Type_predicate_0_is_not_assignable_to_1, typePredicateToString(source), typePredicateToString(target));
}
return Ternary.False;

View File

@@ -0,0 +1,7 @@
//// [thisTypeInTypePredicate.ts]
declare function filter<S>(f: (this: void, x: any) => x is S): S[];
const numbers = filter<number>((x): x is number => 'number' == typeof x)
//// [thisTypeInTypePredicate.js]
var numbers = filter(function (x) { return 'number' == typeof x; });

View File

@@ -0,0 +1,18 @@
=== tests/cases/conformance/types/thisType/thisTypeInTypePredicate.ts ===
declare function filter<S>(f: (this: void, x: any) => x is S): S[];
>filter : Symbol(filter, Decl(thisTypeInTypePredicate.ts, 0, 0))
>S : Symbol(S, Decl(thisTypeInTypePredicate.ts, 0, 24))
>f : Symbol(f, Decl(thisTypeInTypePredicate.ts, 0, 27))
>this : Symbol(this, Decl(thisTypeInTypePredicate.ts, 0, 31))
>x : Symbol(x, Decl(thisTypeInTypePredicate.ts, 0, 42))
>x : Symbol(x, Decl(thisTypeInTypePredicate.ts, 0, 42))
>S : Symbol(S, Decl(thisTypeInTypePredicate.ts, 0, 24))
>S : Symbol(S, Decl(thisTypeInTypePredicate.ts, 0, 24))
const numbers = filter<number>((x): x is number => 'number' == typeof x)
>numbers : Symbol(numbers, Decl(thisTypeInTypePredicate.ts, 1, 5))
>filter : Symbol(filter, Decl(thisTypeInTypePredicate.ts, 0, 0))
>x : Symbol(x, Decl(thisTypeInTypePredicate.ts, 1, 32))
>x : Symbol(x, Decl(thisTypeInTypePredicate.ts, 1, 32))
>x : Symbol(x, Decl(thisTypeInTypePredicate.ts, 1, 32))

View File

@@ -0,0 +1,23 @@
=== tests/cases/conformance/types/thisType/thisTypeInTypePredicate.ts ===
declare function filter<S>(f: (this: void, x: any) => x is S): S[];
>filter : <S>(f: (this: void, x: any) => x is S) => S[]
>S : S
>f : (this: void, x: any) => x is S
>this : void
>x : any
>x : any
>S : S
>S : S
const numbers = filter<number>((x): x is number => 'number' == typeof x)
>numbers : number[]
>filter<number>((x): x is number => 'number' == typeof x) : number[]
>filter : <S>(f: (this: void, x: any) => x is S) => S[]
>(x): x is number => 'number' == typeof x : (this: void, x: any) => x is number
>x : any
>x : any
>'number' == typeof x : boolean
>'number' : "number"
>typeof x : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"
>x : any

View File

@@ -0,0 +1,2 @@
declare function filter<S>(f: (this: void, x: any) => x is S): S[];
const numbers = filter<number>((x): x is number => 'number' == typeof x)