diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 68dea4eb4eb..e496a0b07bc 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -123,8 +123,8 @@ namespace ts { const noConstraintType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined); - const anySignature = createSignature(undefined, undefined, emptyArray, anyType, undefined, 0, /*hasRestParameter*/ false, /*hasStringLiterals*/ false); - const unknownSignature = createSignature(undefined, undefined, emptyArray, unknownType, undefined, 0, /*hasRestParameter*/ false, /*hasStringLiterals*/ false); + const anySignature = createSignature(undefined, undefined, emptyArray, anyType, 0, /*hasRestParameter*/ false, /*hasStringLiterals*/ false); + const unknownSignature = createSignature(undefined, undefined, emptyArray, unknownType, 0, /*hasRestParameter*/ false, /*hasStringLiterals*/ false); const globals: SymbolTable = {}; @@ -2074,15 +2074,7 @@ namespace ts { } writeSpace(writer); - let returnType: Type; - const predicate = signature.typePredicate; - if (predicate) { - buildTypePredicateDisplay(writer, predicate); - returnType = predicate.type; - } - else { - returnType = getReturnTypeOfSignature(signature); - } + const returnType = getReturnTypeOfSignature(signature); buildTypeDisplay(returnType, writer, enclosingDeclaration, flags, symbolStack); } @@ -3378,13 +3370,12 @@ namespace ts { } function createSignature(declaration: SignatureDeclaration, typeParameters: TypeParameter[], parameters: Symbol[], - resolvedReturnType: Type, typePredicate: IdentifierTypePredicate | ThisTypePredicate, minArgumentCount: number, hasRestParameter: boolean, hasStringLiterals: boolean): Signature { + resolvedReturnType: Type, minArgumentCount: number, hasRestParameter: boolean, hasStringLiterals: boolean): Signature { const sig = new Signature(checker); sig.declaration = declaration; sig.typeParameters = typeParameters; sig.parameters = parameters; sig.resolvedReturnType = resolvedReturnType; - sig.typePredicate = typePredicate; sig.minArgumentCount = minArgumentCount; sig.hasRestParameter = hasRestParameter; sig.hasStringLiterals = hasStringLiterals; @@ -3392,13 +3383,13 @@ namespace ts { } function cloneSignature(sig: Signature): Signature { - return createSignature(sig.declaration, sig.typeParameters, sig.parameters, sig.resolvedReturnType, sig.typePredicate, + return createSignature(sig.declaration, sig.typeParameters, sig.parameters, sig.resolvedReturnType, sig.minArgumentCount, sig.hasRestParameter, sig.hasStringLiterals); } function getDefaultConstructSignatures(classType: InterfaceType): Signature[] { if (!hasClassBaseType(classType)) { - return [createSignature(undefined, classType.localTypeParameters, emptyArray, classType, undefined, 0, /*hasRestParameter*/ false, /*hasStringLiterals*/ false)]; + return [createSignature(undefined, classType.localTypeParameters, emptyArray, classType, 0, /*hasRestParameter*/ false, /*hasStringLiterals*/ false)]; } const baseConstructorType = getBaseConstructorTypeOfClass(classType); const baseSignatures = getSignaturesOfType(baseConstructorType, SignatureKind.Construct); @@ -3924,15 +3915,11 @@ namespace ts { } let returnType: Type; - let typePredicate: IdentifierTypePredicate | ThisTypePredicate; if (classType) { returnType = classType; } else if (declaration.type) { returnType = getTypeFromTypeNode(declaration.type); - if (declaration.type.kind === SyntaxKind.TypePredicate) { - typePredicate = createTypePredicateFromTypePredicateNode(declaration.type as TypePredicateNode); - } } else { // TypeScript 1.0 spec (April 2014): @@ -3947,8 +3934,7 @@ namespace ts { } } - links.resolvedSignature = createSignature(declaration, typeParameters, parameters, returnType, typePredicate, - minArgumentCount, hasRestParameter(declaration), hasStringLiterals); + links.resolvedSignature = createSignature(declaration, typeParameters, parameters, returnType, minArgumentCount, hasRestParameter(declaration), hasStringLiterals); } return links.resolvedSignature; } @@ -4608,15 +4594,10 @@ namespace ts { } function getPredicateType(node: TypePredicateNode): Type { - if (!(node.parent.kind === SyntaxKind.PropertyDeclaration || node.parent.kind === SyntaxKind.PropertySignature || node.parent.kind === SyntaxKind.GetAccessor)) { - return booleanType; - } - else { - return createPredicateType(getSymbolOfNode(node), createTypePredicateFromTypePredicateNode(node) as ThisTypePredicate); - } + return createPredicateType(getSymbolOfNode(node), createTypePredicateFromTypePredicateNode(node)); } - function createPredicateType(symbol: Symbol, predicate: ThisTypePredicate) { + function createPredicateType(symbol: Symbol, predicate: ThisTypePredicate | IdentifierTypePredicate) { const type = createType(TypeFlags.Boolean | TypeFlags.PredicateType) as PredicateType; type.symbol = symbol; type.predicate = predicate; @@ -4801,7 +4782,6 @@ namespace ts { const result = createSignature(signature.declaration, freshTypeParameters, instantiateList(signature.parameters, mapper, instantiateSymbol), instantiateType(signature.resolvedReturnType, mapper), - signature.typePredicate && cloneTypePredicate(signature.typePredicate, mapper), signature.minArgumentCount, signature.hasRestParameter, signature.hasStringLiterals); result.target = signature; result.mapper = mapper; @@ -4872,7 +4852,8 @@ namespace ts { return getIntersectionType(instantiateList((type).types, mapper, instantiateType)); } if (type.flags & TypeFlags.PredicateType) { - return createPredicateType(type.symbol, {kind: TypePredicateKind.This, type: instantiateType((type as PredicateType).predicate.type, mapper)} as ThisTypePredicate); + const predicate = (type as PredicateType).predicate; + return createPredicateType(type.symbol, cloneTypePredicate(predicate, mapper)); } } return type; @@ -5044,7 +5025,36 @@ namespace ts { if (relation === assignableRelation) { if (isTypeAny(source)) return Ternary.True; if (source === numberType && target.flags & TypeFlags.Enum) return Ternary.True; - if (source.flags & TypeFlags.Boolean && target.flags & TypeFlags.Boolean && (source.flags & TypeFlags.PredicateType || target.flags & TypeFlags.PredicateType)) return Ternary.True; + } + if (source.flags & TypeFlags.Boolean && target.flags & TypeFlags.Boolean) { + if (source.flags & TypeFlags.PredicateType && target.flags & TypeFlags.PredicateType) { + const sourcePredicate = source as PredicateType; + const targetPredicate = target as PredicateType; + if (sourcePredicate.predicate.kind !== targetPredicate.predicate.kind) { + if (reportErrors) { + reportError(Diagnostics.A_this_based_type_guard_is_not_assignable_to_a_parameter_based_type_guard); + reportError(Diagnostics.Type_predicate_0_is_not_assignable_to_1, typeToString(source), typeToString(target)); + } + return Ternary.False; + } + if (sourcePredicate.predicate.kind === TypePredicateKind.Identifier) { + const sourceIdentifierPredicate = sourcePredicate.predicate as IdentifierTypePredicate; + const targetIdentifierPredicate = targetPredicate.predicate as IdentifierTypePredicate; + if (sourceIdentifierPredicate.parameterIndex !== targetIdentifierPredicate.parameterIndex) { + if (reportErrors) { + reportError(Diagnostics.Parameter_0_is_not_in_the_same_position_as_parameter_1, sourceIdentifierPredicate.parameterName, targetIdentifierPredicate.parameterName); + reportError(Diagnostics.Type_predicate_0_is_not_assignable_to_1, typeToString(source), typeToString(target)); + } + return Ternary.False; + } + } + const related = isRelatedTo(sourcePredicate.predicate.type, targetPredicate.predicate.type, reportErrors, headMessage); + if (related === Ternary.False && reportErrors) { + reportError(Diagnostics.Type_predicate_0_is_not_assignable_to_1, typeToString(source), typeToString(target)); + } + return related; + } + return Ternary.True; } if (source.flags & TypeFlags.FreshObjectLiteral) { @@ -5619,65 +5629,6 @@ namespace ts { result &= related; } - if (source.typePredicate && target.typePredicate) { - const sourcePredicate = source.typePredicate; - const targetPredicate = target.typePredicate; - if (source.typePredicate.kind !== target.typePredicate.kind) { - if (reportErrors) { - reportError(Diagnostics.A_this_based_type_guard_is_not_assignable_to_a_parameter_based_type_guard); - } - return Ternary.False; - } - if (!(isIdentifierTypePredicate(sourcePredicate) && isIdentifierTypePredicate(targetPredicate))) { - if (!isTypeIdenticalTo(sourcePredicate.type, targetPredicate.type)) { - if (reportErrors) { - const sourceTypeText = typeToString(sourcePredicate.type); - const targetTypeText = typeToString(targetPredicate.type); - reportError(Diagnostics.Type_0_is_not_assignable_to_type_1, - sourceTypeText, - targetTypeText); - } - return Ternary.False; - } - } - else { - const hasDifferentParameterIndex = sourcePredicate.parameterIndex !== targetPredicate.parameterIndex; - let hasDifferentTypes: boolean; - if (hasDifferentParameterIndex || - (hasDifferentTypes = !isTypeIdenticalTo(sourcePredicate.type, targetPredicate.type))) { - - if (reportErrors) { - const sourceParamText = sourcePredicate.parameterName; - const targetParamText = targetPredicate.parameterName; - const sourceTypeText = typeToString(sourcePredicate.type); - const targetTypeText = typeToString(targetPredicate.type); - - if (hasDifferentParameterIndex) { - reportError(Diagnostics.Parameter_0_is_not_in_the_same_position_as_parameter_1, - sourceParamText, - targetParamText); - } - else if (hasDifferentTypes) { - reportError(Diagnostics.Type_0_is_not_assignable_to_type_1, - sourceTypeText, - targetTypeText); - } - - reportError(Diagnostics.Type_predicate_0_is_not_assignable_to_1, - `${sourceParamText} is ${sourceTypeText}`, - `${targetParamText} is ${targetTypeText}`); - } - return Ternary.False; - } - } - } - else if (!source.typePredicate && target.typePredicate) { - if (reportErrors) { - reportError(Diagnostics.Signature_0_must_have_a_type_predicate, signatureToString(source)); - } - return Ternary.False; - } - const targetReturnType = getReturnTypeOfSignature(target); if (targetReturnType === voidType) return result; const sourceReturnType = getReturnTypeOfSignature(source); @@ -6239,6 +6190,11 @@ namespace ts { inferFromTypes(sourceTypes[i], targetTypes[i]); } } + else if (source.flags & TypeFlags.PredicateType && target.flags & TypeFlags.PredicateType) { + if ((source as PredicateType).predicate.kind === (target as PredicateType).predicate.kind) { + inferFromTypes((source as PredicateType).predicate.type, (target as PredicateType).predicate.type); + } + } else if (source.flags & TypeFlags.Tuple && target.flags & TypeFlags.Tuple && (source).elementTypes.length === (target).elementTypes.length) { // If source and target are tuples of the same size, infer from element types const sourceTypes = (source).elementTypes; @@ -6331,21 +6287,7 @@ namespace ts { function inferFromSignature(source: Signature, target: Signature) { forEachMatchingParameterType(source, target, inferFromTypes); - if (source.typePredicate && target.typePredicate) { - if (target.typePredicate.kind === source.typePredicate.kind) { - if ((target.typePredicate.kind === TypePredicateKind.Identifier - && (target.typePredicate as IdentifierTypePredicate).parameterIndex === (source.typePredicate as IdentifierTypePredicate).parameterIndex) - || target.typePredicate.kind === TypePredicateKind.This) { - // Return types from type predicates are treated as booleans. In order to infer types - // from type predicates we would need to infer using the type within the type predicate - // (i.e. 'Foo' from 'x is Foo'). - inferFromTypes(source.typePredicate.type, target.typePredicate.type); - } - } - } - else { - inferFromTypes(getReturnTypeOfSignature(source), getReturnTypeOfSignature(target)); - } + inferFromTypes(getReturnTypeOfSignature(source), getReturnTypeOfSignature(target)); } function inferFromIndexTypes(source: Type, target: Type, sourceKind: IndexKind, targetKind: IndexKind) { @@ -6791,11 +6733,12 @@ namespace ts { return type; } const signature = getResolvedSignature(expr); + const predicateType = getReturnTypeOfSignature(signature); - if (!signature.typePredicate) { + if (!predicateType || !(predicateType.flags & TypeFlags.PredicateType)) { return type; } - const predicate = signature.typePredicate; + const predicate = (predicateType as PredicateType).predicate; if (isIdentifierTypePredicate(predicate)) { const callExpression = expr as CallExpression; if (callExpression.arguments[predicate.parameterIndex] && @@ -6819,7 +6762,7 @@ namespace ts { return type; } - return narrowTypeByThisTypePredicate(type, (memberType as PredicateType).predicate, expr, assumeTrue); + return narrowTypeByThisTypePredicate(type, (memberType as PredicateType).predicate as ThisTypePredicate, expr, assumeTrue); } function narrowTypeByThisTypePredicate(type: Type, predicate: ThisTypePredicate, expression: Expression, assumeTrue: boolean): Type { @@ -11119,8 +11062,12 @@ namespace ts { if (node.type) { if (node.type.kind === SyntaxKind.TypePredicate) { - const typePredicate = getSignatureFromDeclaration(node).typePredicate; - const typePredicateNode = node.type; + const returnType = getReturnTypeOfSignature(getSignatureFromDeclaration(node)); + if (!returnType || !(returnType.flags & TypeFlags.PredicateType)) { + return; + } + const typePredicate = (returnType as PredicateType).predicate; + const typePredicateNode = node.type as TypePredicateNode; checkSourceElement(typePredicateNode); if (isIdentifierTypePredicate(typePredicate)) { if (typePredicate.parameterIndex >= 0) { @@ -13126,7 +13073,7 @@ namespace ts { error(node.expression, Diagnostics.Return_type_of_constructor_signature_must_be_assignable_to_the_instance_type_of_the_class); } } - else if (func.type || isGetAccessorWithAnnotatatedSetAccessor(func) || signature.typePredicate) { + else if (func.type || isGetAccessorWithAnnotatatedSetAccessor(func) || returnType.flags & TypeFlags.PredicateType) { if (isAsyncFunctionLike(func)) { const promisedType = getPromisedType(returnType); const awaitedType = checkAwaitedType(exprType, node.expression, Diagnostics.Return_expression_in_async_function_does_not_have_a_valid_callable_then_member); diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 54eb4f449dd..9358ec24333 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2143,7 +2143,7 @@ namespace ts { // Predicate types (TypeFlags.Predicate) export interface PredicateType extends Type { - predicate: ThisTypePredicate; + predicate: ThisTypePredicate | IdentifierTypePredicate; } // String literal types (TypeFlags.StringLiteral) @@ -2262,7 +2262,6 @@ namespace ts { declaration: SignatureDeclaration; // Originating declaration typeParameters: TypeParameter[]; // Type parameters (undefined if non-generic) parameters: Symbol[]; // Parameters - typePredicate?: ThisTypePredicate | IdentifierTypePredicate; // Type predicate /* @internal */ resolvedReturnType: Type; // Resolved return type /* @internal */ diff --git a/tests/baselines/reference/arrayBufferIsViewNarrowsType.types b/tests/baselines/reference/arrayBufferIsViewNarrowsType.types index 129b7d601d8..b9d4f3db81b 100644 --- a/tests/baselines/reference/arrayBufferIsViewNarrowsType.types +++ b/tests/baselines/reference/arrayBufferIsViewNarrowsType.types @@ -4,7 +4,7 @@ var obj: Object; >Object : Object if (ArrayBuffer.isView(obj)) { ->ArrayBuffer.isView(obj) : boolean +>ArrayBuffer.isView(obj) : arg is ArrayBufferView >ArrayBuffer.isView : (arg: any) => arg is ArrayBufferView >ArrayBuffer : ArrayBufferConstructor >isView : (arg: any) => arg is ArrayBufferView diff --git a/tests/baselines/reference/isArray.types b/tests/baselines/reference/isArray.types index bc452b12bef..de54e9d064c 100644 --- a/tests/baselines/reference/isArray.types +++ b/tests/baselines/reference/isArray.types @@ -4,7 +4,7 @@ var maybeArray: number | number[]; if (Array.isArray(maybeArray)) { ->Array.isArray(maybeArray) : boolean +>Array.isArray(maybeArray) : arg is any[] >Array.isArray : (arg: any) => arg is any[] >Array : ArrayConstructor >isArray : (arg: any) => arg is any[] diff --git a/tests/baselines/reference/stringLiteralCheckedInIf02.types b/tests/baselines/reference/stringLiteralCheckedInIf02.types index 79f4c6a223a..f91eea03097 100644 --- a/tests/baselines/reference/stringLiteralCheckedInIf02.types +++ b/tests/baselines/reference/stringLiteralCheckedInIf02.types @@ -31,7 +31,7 @@ function f(foo: T) { >T : ("a" | "b")[] | "a" | "b" if (isS(foo)) { ->isS(foo) : boolean +>isS(foo) : t is "a" | "b" >isS : (t: ("a" | "b")[] | "a" | "b") => t is "a" | "b" >foo : ("a" | "b")[] | "a" | "b" diff --git a/tests/baselines/reference/stringLiteralTypesAsTags01.errors.txt b/tests/baselines/reference/stringLiteralTypesAsTags01.errors.txt index 6e4f8943fb6..de3b7be2612 100644 --- a/tests/baselines/reference/stringLiteralTypesAsTags01.errors.txt +++ b/tests/baselines/reference/stringLiteralTypesAsTags01.errors.txt @@ -1,10 +1,7 @@ -tests/cases/conformance/types/stringLiteral/stringLiteralTypesAsTags01.ts(18,10): error TS2382: Specialized overload signature is not assignable to any non-specialized signature. -tests/cases/conformance/types/stringLiteral/stringLiteralTypesAsTags01.ts(19,10): error TS2382: Specialized overload signature is not assignable to any non-specialized signature. -tests/cases/conformance/types/stringLiteral/stringLiteralTypesAsTags01.ts(20,10): error TS2394: Overload signature is not compatible with function implementation. tests/cases/conformance/types/stringLiteral/stringLiteralTypesAsTags01.ts(22,21): error TS2304: Cannot find name 'is'. -==== tests/cases/conformance/types/stringLiteral/stringLiteralTypesAsTags01.ts (4 errors) ==== +==== tests/cases/conformance/types/stringLiteral/stringLiteralTypesAsTags01.ts (1 errors) ==== type Kind = "A" | "B" @@ -23,14 +20,8 @@ tests/cases/conformance/types/stringLiteral/stringLiteralTypesAsTags01.ts(22,21) } function hasKind(entity: Entity, kind: "A"): entity is A; - ~~~~~~~ -!!! error TS2382: Specialized overload signature is not assignable to any non-specialized signature. function hasKind(entity: Entity, kind: "B"): entity is B; - ~~~~~~~ -!!! error TS2382: Specialized overload signature is not assignable to any non-specialized signature. function hasKind(entity: Entity, kind: Kind): entity is Entity; - ~~~~~~~ -!!! error TS2394: Overload signature is not compatible with function implementation. function hasKind(entity: Entity, kind: Kind): boolean { return kind === is; ~~ diff --git a/tests/baselines/reference/typeGuardFunction.types b/tests/baselines/reference/typeGuardFunction.types index 50a5fcaf324..9bab1e7ca2c 100644 --- a/tests/baselines/reference/typeGuardFunction.types +++ b/tests/baselines/reference/typeGuardFunction.types @@ -54,7 +54,7 @@ var b: B; // Basic if (isC(a)) { ->isC(a) : boolean +>isC(a) : p1 is C >isC : (p1: any) => p1 is C >a : A @@ -70,7 +70,7 @@ var subType: C; >C : C if(isA(subType)) { ->isA(subType) : boolean +>isA(subType) : p1 is A >isA : (p1: any) => p1 is A >subType : C @@ -87,7 +87,7 @@ var union: A | B; >B : B if(isA(union)) { ->isA(union) : boolean +>isA(union) : p1 is A >isA : (p1: any) => p1 is A >union : A | B @@ -118,7 +118,7 @@ declare function isC_multipleParams(p1, p2): p1 is C; >C : C if (isC_multipleParams(a, 0)) { ->isC_multipleParams(a, 0) : boolean +>isC_multipleParams(a, 0) : p1 is C >isC_multipleParams : (p1: any, p2: any) => p1 is C >a : A >0 : number @@ -197,7 +197,7 @@ declare function acceptingBoolean(a: boolean); acceptingBoolean(isA(a)); >acceptingBoolean(isA(a)) : any >acceptingBoolean : (a: boolean) => any ->isA(a) : boolean +>isA(a) : p1 is A >isA : (p1: any) => p1 is A >a : A @@ -223,8 +223,8 @@ let union2: C | B; let union3: boolean | B = isA(union2) || union2; >union3 : boolean | B >B : B ->isA(union2) || union2 : boolean | B ->isA(union2) : boolean +>isA(union2) || union2 : p1 is A | B +>isA(union2) : p1 is A >isA : (p1: any) => p1 is A >union2 : C | B >union2 : B diff --git a/tests/baselines/reference/typeGuardFunctionErrors.errors.txt b/tests/baselines/reference/typeGuardFunctionErrors.errors.txt index 2d40520a8ce..445738e9783 100644 --- a/tests/baselines/reference/typeGuardFunctionErrors.errors.txt +++ b/tests/baselines/reference/typeGuardFunctionErrors.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(15,12): error TS2322: Type 'string' is not assignable to type 'boolean'. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(15,12): error TS2322: Type 'string' is not assignable to type 'x is A'. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(22,33): error TS2304: Cannot find name 'x'. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(26,33): error TS1225: Cannot find parameter 'x'. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(30,10): error TS2391: Function implementation is missing or not immediately following the declaration. @@ -16,8 +16,7 @@ tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(70,7): tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(75,46): error TS2345: Argument of type '(p1: any) => p1 is C' is not assignable to parameter of type '(p1: any) => p1 is B'. Type predicate 'p1 is C' is not assignable to 'p1 is B'. Type 'C' is not assignable to type 'B'. -tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(79,1): error TS2322: Type '(p1: any, p2: any) => boolean' is not assignable to type '(p1: any, p2: any) => p1 is A'. - Signature '(p1: any, p2: any): boolean' must have a type predicate. + Property 'propB' is missing in type 'C'. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(85,1): error TS2322: Type '(p1: any, p2: any) => p2 is A' is not assignable to type '(p1: any, p2: any) => p1 is A'. Type predicate 'p2 is A' is not assignable to 'p1 is A'. Parameter 'p2' is not in the same position as parameter 'p1'. @@ -25,7 +24,6 @@ tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(91,1): tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(96,9): error TS1228: A type predicate is only allowed in return type position for functions and methods. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(97,16): error TS1228: A type predicate is only allowed in return type position for functions and methods. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(98,20): error TS1228: A type predicate is only allowed in return type position for functions and methods. -tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(104,25): error TS1228: A type predicate is only allowed in return type position for functions and methods. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(105,16): error TS2322: Type 'boolean' is not assignable to type 'D'. Property 'm1' is missing in type 'Boolean'. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(105,16): error TS2409: Return type of constructor signature must be assignable to the instance type of the class @@ -41,7 +39,7 @@ tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(133,34 tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(137,39): error TS1230: A type predicate cannot reference element 'p1' in a binding pattern. -==== tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts (34 errors) ==== +==== tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts (32 errors) ==== class A { propA: number; @@ -58,7 +56,7 @@ tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(137,39 function hasANonBooleanReturnStatement(x): x is A { return ''; ~~ -!!! error TS2322: Type 'string' is not assignable to type 'boolean'. +!!! error TS2322: Type 'string' is not assignable to type 'x is A'. } function hasTypeGuardTypeInsideTypeGuardType(x): x is x is A { @@ -150,13 +148,11 @@ tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(137,39 !!! error TS2345: Argument of type '(p1: any) => p1 is C' is not assignable to parameter of type '(p1: any) => p1 is B'. !!! error TS2345: Type predicate 'p1 is C' is not assignable to 'p1 is B'. !!! error TS2345: Type 'C' is not assignable to type 'B'. +!!! error TS2345: Property 'propB' is missing in type 'C'. // Boolean not assignable to type guard var assign1: (p1, p2) => p1 is A; assign1 = function(p1, p2): boolean { - ~~~~~~~ -!!! error TS2322: Type '(p1: any, p2: any) => boolean' is not assignable to type '(p1: any, p2: any) => p1 is A'. -!!! error TS2322: Signature '(p1: any, p2: any): boolean' must have a type predicate. return true; }; @@ -194,8 +190,6 @@ tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(137,39 // Non-compatiable type predicate positions for signature declarations class D { constructor(p1: A): p1 is C { - ~~~~~~~ -!!! error TS1228: A type predicate is only allowed in return type position for functions and methods. return true; ~~~~ !!! error TS2322: Type 'boolean' is not assignable to type 'D'. diff --git a/tests/baselines/reference/typeGuardFunctionGenerics.types b/tests/baselines/reference/typeGuardFunctionGenerics.types index c4655e71f0c..1f2ad2b69be 100644 --- a/tests/baselines/reference/typeGuardFunctionGenerics.types +++ b/tests/baselines/reference/typeGuardFunctionGenerics.types @@ -100,7 +100,7 @@ let test1: boolean = funA(isB); >isB : (p1: any) => p1 is B if (funB(retC, a)) { ->funB(retC, a) : boolean +>funB(retC, a) : p2 is C >funB : (p1: (p1: any) => T, p2: any) => p2 is T >retC : (x: any) => C >a : A @@ -118,7 +118,7 @@ let test2: B = funC(isB); >isB : (p1: any) => p1 is B if (funD(isC, a)) { ->funD(isC, a) : boolean +>funD(isC, a) : p2 is C >funD : (p1: (p1: any) => p1 is T, p2: any) => p2 is T >isC : (p1: any) => p1 is C >a : A diff --git a/tests/baselines/reference/typeGuardFunctionOfFormThis.types b/tests/baselines/reference/typeGuardFunctionOfFormThis.types index 6b21fea3457..e91c77dd07a 100644 --- a/tests/baselines/reference/typeGuardFunctionOfFormThis.types +++ b/tests/baselines/reference/typeGuardFunctionOfFormThis.types @@ -45,7 +45,7 @@ let a: RoyalGuard = new FollowerGuard(); >FollowerGuard : typeof FollowerGuard if (a.isLeader()) { ->a.isLeader() : boolean +>a.isLeader() : this is LeadGuard >a.isLeader : () => this is LeadGuard >a : RoyalGuard >isLeader : () => this is LeadGuard @@ -57,7 +57,7 @@ if (a.isLeader()) { >lead : () => void } else if (a.isFollower()) { ->a.isFollower() : boolean +>a.isFollower() : this is FollowerGuard >a.isFollower : () => this is FollowerGuard >a : RoyalGuard >isFollower : () => this is FollowerGuard @@ -78,7 +78,7 @@ let b: GuardInterface; >GuardInterface : GuardInterface if (b.isLeader()) { ->b.isLeader() : boolean +>b.isLeader() : this is LeadGuard >b.isLeader : () => this is LeadGuard >b : GuardInterface >isLeader : () => this is LeadGuard @@ -90,7 +90,7 @@ if (b.isLeader()) { >lead : () => void } else if (b.isFollower()) { ->b.isFollower() : boolean +>b.isFollower() : this is FollowerGuard >b.isFollower : () => this is FollowerGuard >b : GuardInterface >isFollower : () => this is FollowerGuard @@ -103,8 +103,8 @@ else if (b.isFollower()) { } if (((a.isLeader)())) { ->((a.isLeader)()) : boolean ->(a.isLeader)() : boolean +>((a.isLeader)()) : this is LeadGuard +>(a.isLeader)() : this is LeadGuard >(a.isLeader) : () => this is LeadGuard >a.isLeader : () => this is LeadGuard >a : RoyalGuard @@ -117,8 +117,8 @@ if (((a.isLeader)())) { >lead : () => void } else if (((a).isFollower())) { ->((a).isFollower()) : boolean ->(a).isFollower() : boolean +>((a).isFollower()) : this is FollowerGuard +>(a).isFollower() : this is FollowerGuard >(a).isFollower : () => this is FollowerGuard >(a) : RoyalGuard >a : RoyalGuard @@ -132,8 +132,8 @@ else if (((a).isFollower())) { } if (((a["isLeader"])())) { ->((a["isLeader"])()) : boolean ->(a["isLeader"])() : boolean +>((a["isLeader"])()) : this is LeadGuard +>(a["isLeader"])() : this is LeadGuard >(a["isLeader"]) : () => this is LeadGuard >a["isLeader"] : () => this is LeadGuard >a : RoyalGuard @@ -146,8 +146,8 @@ if (((a["isLeader"])())) { >lead : () => void } else if (((a)["isFollower"]())) { ->((a)["isFollower"]()) : boolean ->(a)["isFollower"]() : boolean +>((a)["isFollower"]()) : this is FollowerGuard +>(a)["isFollower"]() : this is FollowerGuard >(a)["isFollower"] : () => this is FollowerGuard >(a) : RoyalGuard >a : RoyalGuard @@ -166,7 +166,7 @@ var holder2 = {a}; >a : RoyalGuard if (holder2.a.isLeader()) { ->holder2.a.isLeader() : boolean +>holder2.a.isLeader() : this is LeadGuard >holder2.a.isLeader : () => this is LeadGuard >holder2.a : RoyalGuard >holder2 : { a: RoyalGuard; } @@ -232,7 +232,7 @@ let guard = new ArrowGuard(); >ArrowGuard : typeof ArrowGuard if (guard.isElite()) { ->guard.isElite() : boolean +>guard.isElite() : this is ArrowElite >guard.isElite : () => this is ArrowElite >guard : ArrowGuard >isElite : () => this is ArrowElite @@ -244,7 +244,7 @@ if (guard.isElite()) { >defend : () => void } else if (guard.isMedic()) { ->guard.isMedic() : boolean +>guard.isMedic() : this is ArrowMedic >guard.isMedic : () => this is ArrowMedic >guard : ArrowGuard >isMedic : () => this is ArrowMedic @@ -297,7 +297,7 @@ let crate: Crate<{}>; >Crate : Crate if (crate.isSundries()) { ->crate.isSundries() : boolean +>crate.isSundries() : this is Crate >crate.isSundries : () => this is Crate >crate : Crate<{}> >isSundries : () => this is Crate @@ -312,7 +312,7 @@ if (crate.isSundries()) { >true : boolean } else if (crate.isSupplies()) { ->crate.isSupplies() : boolean +>crate.isSupplies() : this is Crate >crate.isSupplies : () => this is Crate >crate : Crate<{}> >isSupplies : () => this is Crate @@ -405,7 +405,7 @@ a.isFollower = mimic.isFollower; >isFollower : () => this is MimicFollower if (mimic.isFollower()) { ->mimic.isFollower() : boolean +>mimic.isFollower() : this is MimicFollower >mimic.isFollower : () => this is MimicFollower >mimic : MimicGuard >isFollower : () => this is MimicFollower diff --git a/tests/baselines/reference/typeGuardFunctionOfFormThisErrors.errors.txt b/tests/baselines/reference/typeGuardFunctionOfFormThisErrors.errors.txt index 605282f19bb..9f9f5d6533c 100644 --- a/tests/baselines/reference/typeGuardFunctionOfFormThisErrors.errors.txt +++ b/tests/baselines/reference/typeGuardFunctionOfFormThisErrors.errors.txt @@ -1,11 +1,17 @@ tests/cases/conformance/expressions/typeGuards/typeGuardFunctionOfFormThisErrors.ts(23,1): error TS2322: Type '() => this is LeadGuard' is not assignable to type '() => this is FollowerGuard'. - Type 'LeadGuard' is not assignable to type 'FollowerGuard'. + Type predicate 'this is LeadGuard' is not assignable to 'this is FollowerGuard'. + Type 'LeadGuard' is not assignable to type 'FollowerGuard'. + Property 'follow' is missing in type 'LeadGuard'. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionOfFormThisErrors.ts(24,1): error TS2322: Type '() => this is FollowerGuard' is not assignable to type '() => this is LeadGuard'. - Type 'FollowerGuard' is not assignable to type 'LeadGuard'. + Type predicate 'this is FollowerGuard' is not assignable to 'this is LeadGuard'. + Type 'FollowerGuard' is not assignable to type 'LeadGuard'. + Property 'lead' is missing in type 'FollowerGuard'. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionOfFormThisErrors.ts(26,1): error TS2322: Type '() => this is LeadGuard' is not assignable to type '() => this is FollowerGuard'. - Type 'LeadGuard' is not assignable to type 'FollowerGuard'. + Type predicate 'this is LeadGuard' is not assignable to 'this is FollowerGuard'. + Type 'LeadGuard' is not assignable to type 'FollowerGuard'. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionOfFormThisErrors.ts(27,1): error TS2322: Type '() => this is FollowerGuard' is not assignable to type '() => this is LeadGuard'. - Type 'FollowerGuard' is not assignable to type 'LeadGuard'. + Type predicate 'this is FollowerGuard' is not assignable to 'this is LeadGuard'. + Type 'FollowerGuard' is not assignable to type 'LeadGuard'. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionOfFormThisErrors.ts(29,32): error TS2526: A 'this' type is available only in a non-static member of a class or interface. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionOfFormThisErrors.ts(55,7): error TS2339: Property 'follow' does not exist on type 'RoyalGuard'. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionOfFormThisErrors.ts(58,7): error TS2339: Property 'lead' does not exist on type 'RoyalGuard'. @@ -37,20 +43,26 @@ tests/cases/conformance/expressions/typeGuards/typeGuardFunctionOfFormThisErrors b.isFollower = b.isLeader; ~~~~~~~~~~~~ !!! error TS2322: Type '() => this is LeadGuard' is not assignable to type '() => this is FollowerGuard'. -!!! error TS2322: Type 'LeadGuard' is not assignable to type 'FollowerGuard'. +!!! error TS2322: Type predicate 'this is LeadGuard' is not assignable to 'this is FollowerGuard'. +!!! error TS2322: Type 'LeadGuard' is not assignable to type 'FollowerGuard'. +!!! error TS2322: Property 'follow' is missing in type 'LeadGuard'. b.isLeader = b.isFollower; ~~~~~~~~~~ !!! error TS2322: Type '() => this is FollowerGuard' is not assignable to type '() => this is LeadGuard'. -!!! error TS2322: Type 'FollowerGuard' is not assignable to type 'LeadGuard'. +!!! error TS2322: Type predicate 'this is FollowerGuard' is not assignable to 'this is LeadGuard'. +!!! error TS2322: Type 'FollowerGuard' is not assignable to type 'LeadGuard'. +!!! error TS2322: Property 'lead' is missing in type 'FollowerGuard'. a.isFollower = a.isLeader; ~~~~~~~~~~~~ !!! error TS2322: Type '() => this is LeadGuard' is not assignable to type '() => this is FollowerGuard'. -!!! error TS2322: Type 'LeadGuard' is not assignable to type 'FollowerGuard'. +!!! error TS2322: Type predicate 'this is LeadGuard' is not assignable to 'this is FollowerGuard'. +!!! error TS2322: Type 'LeadGuard' is not assignable to type 'FollowerGuard'. a.isLeader = a.isFollower; ~~~~~~~~~~ !!! error TS2322: Type '() => this is FollowerGuard' is not assignable to type '() => this is LeadGuard'. -!!! error TS2322: Type 'FollowerGuard' is not assignable to type 'LeadGuard'. +!!! error TS2322: Type predicate 'this is FollowerGuard' is not assignable to 'this is LeadGuard'. +!!! error TS2322: Type 'FollowerGuard' is not assignable to type 'LeadGuard'. function invalidGuard(c: any): this is number { ~~~~ diff --git a/tests/baselines/reference/typeGuardOfFormIsType.types b/tests/baselines/reference/typeGuardOfFormIsType.types index e2059be7b63..aa8f8cc7d60 100644 --- a/tests/baselines/reference/typeGuardOfFormIsType.types +++ b/tests/baselines/reference/typeGuardOfFormIsType.types @@ -67,7 +67,7 @@ str = isC1(c1Orc2) && c1Orc2.p1; // C1 >str = isC1(c1Orc2) && c1Orc2.p1 : string >str : string >isC1(c1Orc2) && c1Orc2.p1 : string ->isC1(c1Orc2) : boolean +>isC1(c1Orc2) : x is C1 >isC1 : (x: any) => x is C1 >c1Orc2 : C1 | C2 >c1Orc2.p1 : string @@ -78,7 +78,7 @@ num = isC2(c1Orc2) && c1Orc2.p2; // C2 >num = isC2(c1Orc2) && c1Orc2.p2 : number >num : number >isC2(c1Orc2) && c1Orc2.p2 : number ->isC2(c1Orc2) : boolean +>isC2(c1Orc2) : x is C2 >isC2 : (x: any) => x is C2 >c1Orc2 : C1 | C2 >c1Orc2.p2 : number @@ -89,7 +89,7 @@ str = isD1(c1Orc2) && c1Orc2.p1; // D1 >str = isD1(c1Orc2) && c1Orc2.p1 : string >str : string >isD1(c1Orc2) && c1Orc2.p1 : string ->isD1(c1Orc2) : boolean +>isD1(c1Orc2) : x is D1 >isD1 : (x: any) => x is D1 >c1Orc2 : C1 | C2 >c1Orc2.p1 : string @@ -100,7 +100,7 @@ num = isD1(c1Orc2) && c1Orc2.p3; // D1 >num = isD1(c1Orc2) && c1Orc2.p3 : number >num : number >isD1(c1Orc2) && c1Orc2.p3 : number ->isD1(c1Orc2) : boolean +>isD1(c1Orc2) : x is D1 >isD1 : (x: any) => x is D1 >c1Orc2 : C1 | C2 >c1Orc2.p3 : number @@ -116,7 +116,7 @@ num = isC2(c2Ord1) && c2Ord1.p2; // C2 >num = isC2(c2Ord1) && c2Ord1.p2 : number >num : number >isC2(c2Ord1) && c2Ord1.p2 : number ->isC2(c2Ord1) : boolean +>isC2(c2Ord1) : x is C2 >isC2 : (x: any) => x is C2 >c2Ord1 : C2 | D1 >c2Ord1.p2 : number @@ -127,7 +127,7 @@ num = isD1(c2Ord1) && c2Ord1.p3; // D1 >num = isD1(c2Ord1) && c2Ord1.p3 : number >num : number >isD1(c2Ord1) && c2Ord1.p3 : number ->isD1(c2Ord1) : boolean +>isD1(c2Ord1) : x is D1 >isD1 : (x: any) => x is D1 >c2Ord1 : C2 | D1 >c2Ord1.p3 : number @@ -138,7 +138,7 @@ str = isD1(c2Ord1) && c2Ord1.p1; // D1 >str = isD1(c2Ord1) && c2Ord1.p1 : string >str : string >isD1(c2Ord1) && c2Ord1.p1 : string ->isD1(c2Ord1) : boolean +>isD1(c2Ord1) : x is D1 >isD1 : (x: any) => x is D1 >c2Ord1 : C2 | D1 >c2Ord1.p1 : string @@ -150,7 +150,7 @@ var r2: C2 | D1 = isC1(c2Ord1) && c2Ord1; // C2 | D1 >C2 : C2 >D1 : D1 >isC1(c2Ord1) && c2Ord1 : D1 ->isC1(c2Ord1) : boolean +>isC1(c2Ord1) : x is C1 >isC1 : (x: any) => x is C1 >c2Ord1 : C2 | D1 >c2Ord1 : D1 diff --git a/tests/baselines/reference/typeGuardOfFormIsTypeOnInterfaces.types b/tests/baselines/reference/typeGuardOfFormIsTypeOnInterfaces.types index ea169e95413..4e28e6a4d38 100644 --- a/tests/baselines/reference/typeGuardOfFormIsTypeOnInterfaces.types +++ b/tests/baselines/reference/typeGuardOfFormIsTypeOnInterfaces.types @@ -98,7 +98,7 @@ str = isC1(c1Orc2) && c1Orc2.p1; // C1 >str = isC1(c1Orc2) && c1Orc2.p1 : string >str : string >isC1(c1Orc2) && c1Orc2.p1 : string ->isC1(c1Orc2) : boolean +>isC1(c1Orc2) : x is C1 >isC1 : (x: any) => x is C1 >c1Orc2 : C1 | C2 >c1Orc2.p1 : string @@ -109,7 +109,7 @@ num = isC2(c1Orc2) && c1Orc2.p2; // C2 >num = isC2(c1Orc2) && c1Orc2.p2 : number >num : number >isC2(c1Orc2) && c1Orc2.p2 : number ->isC2(c1Orc2) : boolean +>isC2(c1Orc2) : x is C2 >isC2 : (x: any) => x is C2 >c1Orc2 : C1 | C2 >c1Orc2.p2 : number @@ -120,7 +120,7 @@ str = isD1(c1Orc2) && c1Orc2.p1; // D1 >str = isD1(c1Orc2) && c1Orc2.p1 : string >str : string >isD1(c1Orc2) && c1Orc2.p1 : string ->isD1(c1Orc2) : boolean +>isD1(c1Orc2) : x is D1 >isD1 : (x: any) => x is D1 >c1Orc2 : C1 | C2 >c1Orc2.p1 : string @@ -131,7 +131,7 @@ num = isD1(c1Orc2) && c1Orc2.p3; // D1 >num = isD1(c1Orc2) && c1Orc2.p3 : number >num : number >isD1(c1Orc2) && c1Orc2.p3 : number ->isD1(c1Orc2) : boolean +>isD1(c1Orc2) : x is D1 >isD1 : (x: any) => x is D1 >c1Orc2 : C1 | C2 >c1Orc2.p3 : number @@ -147,7 +147,7 @@ num = isC2(c2Ord1) && c2Ord1.p2; // C2 >num = isC2(c2Ord1) && c2Ord1.p2 : number >num : number >isC2(c2Ord1) && c2Ord1.p2 : number ->isC2(c2Ord1) : boolean +>isC2(c2Ord1) : x is C2 >isC2 : (x: any) => x is C2 >c2Ord1 : C2 | D1 >c2Ord1.p2 : number @@ -158,7 +158,7 @@ num = isD1(c2Ord1) && c2Ord1.p3; // D1 >num = isD1(c2Ord1) && c2Ord1.p3 : number >num : number >isD1(c2Ord1) && c2Ord1.p3 : number ->isD1(c2Ord1) : boolean +>isD1(c2Ord1) : x is D1 >isD1 : (x: any) => x is D1 >c2Ord1 : C2 | D1 >c2Ord1.p3 : number @@ -169,7 +169,7 @@ str = isD1(c2Ord1) && c2Ord1.p1; // D1 >str = isD1(c2Ord1) && c2Ord1.p1 : string >str : string >isD1(c2Ord1) && c2Ord1.p1 : string ->isD1(c2Ord1) : boolean +>isD1(c2Ord1) : x is D1 >isD1 : (x: any) => x is D1 >c2Ord1 : C2 | D1 >c2Ord1.p1 : string @@ -181,7 +181,7 @@ var r2: C2 | D1 = isC1(c2Ord1) && c2Ord1; // C2 | D1 >C2 : C2 >D1 : D1 >isC1(c2Ord1) && c2Ord1 : D1 ->isC1(c2Ord1) : boolean +>isC1(c2Ord1) : x is C1 >isC1 : (x: any) => x is C1 >c2Ord1 : C2 | D1 >c2Ord1 : D1 diff --git a/tests/baselines/reference/typeGuardOfFormThisMember.js b/tests/baselines/reference/typeGuardOfFormThisMember.js index cbf70c4a640..8cb5b89aa90 100644 --- a/tests/baselines/reference/typeGuardOfFormThisMember.js +++ b/tests/baselines/reference/typeGuardOfFormThisMember.js @@ -2,6 +2,7 @@ // There's a 'File' class in the stdlib, wrap with a namespace to avoid collision namespace Test { export class FileSystemObject { + isFSO: this is FileSystemObject; get isFile(): this is File { return this instanceof File; } @@ -27,8 +28,8 @@ namespace Test { let file: FileSystemObject = new File("foo/bar.txt", "foo"); file.isNetworked = false; - file.isNetworked = file.isDirectory; - file.isFile = file.isNetworked; + file.isFSO = file.isFile; + file.isFile = true; let x = file.isFile; if (file.isFile) { file.content; @@ -133,8 +134,8 @@ var Test; Test.Directory = Directory; var file = new File("foo/bar.txt", "foo"); file.isNetworked = false; - file.isNetworked = file.isDirectory; - file.isFile = file.isNetworked; + file.isFSO = file.isFile; + file.isFile = true; var x = file.isFile; if (file.isFile) { file.content; @@ -167,6 +168,7 @@ var Test; declare namespace Test { class FileSystemObject { path: string; + isFSO: this is FileSystemObject; isFile: this is File; isDirectory: this is Directory; isNetworked: this is (Networked & this); diff --git a/tests/baselines/reference/typeGuardOfFormThisMember.symbols b/tests/baselines/reference/typeGuardOfFormThisMember.symbols index 84573ddf0c7..50e15b68ca4 100644 --- a/tests/baselines/reference/typeGuardOfFormThisMember.symbols +++ b/tests/baselines/reference/typeGuardOfFormThisMember.symbols @@ -6,234 +6,235 @@ namespace Test { export class FileSystemObject { >FileSystemObject : Symbol(FileSystemObject, Decl(typeGuardOfFormThisMember.ts, 1, 16)) + isFSO: this is FileSystemObject; +>isFSO : Symbol(isFSO, Decl(typeGuardOfFormThisMember.ts, 2, 32)) +>FileSystemObject : Symbol(FileSystemObject, Decl(typeGuardOfFormThisMember.ts, 1, 16)) + get isFile(): this is File { ->isFile : Symbol(isFile, Decl(typeGuardOfFormThisMember.ts, 2, 32), Decl(typeGuardOfFormThisMember.ts, 5, 3)) ->File : Symbol(File, Decl(typeGuardOfFormThisMember.ts, 14, 2)) +>isFile : Symbol(isFile, Decl(typeGuardOfFormThisMember.ts, 3, 34), Decl(typeGuardOfFormThisMember.ts, 6, 3)) +>File : Symbol(File, Decl(typeGuardOfFormThisMember.ts, 15, 2)) return this instanceof File; >this : Symbol(FileSystemObject, Decl(typeGuardOfFormThisMember.ts, 1, 16)) ->File : Symbol(File, Decl(typeGuardOfFormThisMember.ts, 14, 2)) +>File : Symbol(File, Decl(typeGuardOfFormThisMember.ts, 15, 2)) } set isFile(param) { ->isFile : Symbol(isFile, Decl(typeGuardOfFormThisMember.ts, 2, 32), Decl(typeGuardOfFormThisMember.ts, 5, 3)) ->param : Symbol(param, Decl(typeGuardOfFormThisMember.ts, 6, 13)) +>isFile : Symbol(isFile, Decl(typeGuardOfFormThisMember.ts, 3, 34), Decl(typeGuardOfFormThisMember.ts, 6, 3)) +>param : Symbol(param, Decl(typeGuardOfFormThisMember.ts, 7, 13)) // noop } get isDirectory(): this is Directory { ->isDirectory : Symbol(isDirectory, Decl(typeGuardOfFormThisMember.ts, 8, 3)) ->Directory : Symbol(Directory, Decl(typeGuardOfFormThisMember.ts, 18, 2)) +>isDirectory : Symbol(isDirectory, Decl(typeGuardOfFormThisMember.ts, 9, 3)) +>Directory : Symbol(Directory, Decl(typeGuardOfFormThisMember.ts, 19, 2)) return this instanceof Directory; >this : Symbol(FileSystemObject, Decl(typeGuardOfFormThisMember.ts, 1, 16)) ->Directory : Symbol(Directory, Decl(typeGuardOfFormThisMember.ts, 18, 2)) +>Directory : Symbol(Directory, Decl(typeGuardOfFormThisMember.ts, 19, 2)) } isNetworked: this is (Networked & this); ->isNetworked : Symbol(isNetworked, Decl(typeGuardOfFormThisMember.ts, 11, 3)) ->Networked : Symbol(Networked, Decl(typeGuardOfFormThisMember.ts, 21, 2)) +>isNetworked : Symbol(isNetworked, Decl(typeGuardOfFormThisMember.ts, 12, 3)) +>Networked : Symbol(Networked, Decl(typeGuardOfFormThisMember.ts, 22, 2)) constructor(public path: string) {} ->path : Symbol(path, Decl(typeGuardOfFormThisMember.ts, 13, 14)) +>path : Symbol(path, Decl(typeGuardOfFormThisMember.ts, 14, 14)) } export class File extends FileSystemObject { ->File : Symbol(File, Decl(typeGuardOfFormThisMember.ts, 14, 2)) +>File : Symbol(File, Decl(typeGuardOfFormThisMember.ts, 15, 2)) >FileSystemObject : Symbol(FileSystemObject, Decl(typeGuardOfFormThisMember.ts, 1, 16)) constructor(path: string, public content: string) { super(path); } ->path : Symbol(path, Decl(typeGuardOfFormThisMember.ts, 17, 14)) ->content : Symbol(content, Decl(typeGuardOfFormThisMember.ts, 17, 27)) +>path : Symbol(path, Decl(typeGuardOfFormThisMember.ts, 18, 14)) +>content : Symbol(content, Decl(typeGuardOfFormThisMember.ts, 18, 27)) >super : Symbol(FileSystemObject, Decl(typeGuardOfFormThisMember.ts, 1, 16)) ->path : Symbol(path, Decl(typeGuardOfFormThisMember.ts, 17, 14)) +>path : Symbol(path, Decl(typeGuardOfFormThisMember.ts, 18, 14)) } export class Directory extends FileSystemObject { ->Directory : Symbol(Directory, Decl(typeGuardOfFormThisMember.ts, 18, 2)) +>Directory : Symbol(Directory, Decl(typeGuardOfFormThisMember.ts, 19, 2)) >FileSystemObject : Symbol(FileSystemObject, Decl(typeGuardOfFormThisMember.ts, 1, 16)) children: FileSystemObject[]; ->children : Symbol(children, Decl(typeGuardOfFormThisMember.ts, 19, 50)) +>children : Symbol(children, Decl(typeGuardOfFormThisMember.ts, 20, 50)) >FileSystemObject : Symbol(FileSystemObject, Decl(typeGuardOfFormThisMember.ts, 1, 16)) } export interface Networked { ->Networked : Symbol(Networked, Decl(typeGuardOfFormThisMember.ts, 21, 2)) +>Networked : Symbol(Networked, Decl(typeGuardOfFormThisMember.ts, 22, 2)) host: string; ->host : Symbol(host, Decl(typeGuardOfFormThisMember.ts, 22, 29)) +>host : Symbol(host, Decl(typeGuardOfFormThisMember.ts, 23, 29)) } let file: FileSystemObject = new File("foo/bar.txt", "foo"); ->file : Symbol(file, Decl(typeGuardOfFormThisMember.ts, 26, 4)) +>file : Symbol(file, Decl(typeGuardOfFormThisMember.ts, 27, 4)) >FileSystemObject : Symbol(FileSystemObject, Decl(typeGuardOfFormThisMember.ts, 1, 16)) ->File : Symbol(File, Decl(typeGuardOfFormThisMember.ts, 14, 2)) +>File : Symbol(File, Decl(typeGuardOfFormThisMember.ts, 15, 2)) file.isNetworked = false; ->file.isNetworked : Symbol(FileSystemObject.isNetworked, Decl(typeGuardOfFormThisMember.ts, 11, 3)) ->file : Symbol(file, Decl(typeGuardOfFormThisMember.ts, 26, 4)) ->isNetworked : Symbol(FileSystemObject.isNetworked, Decl(typeGuardOfFormThisMember.ts, 11, 3)) +>file.isNetworked : Symbol(FileSystemObject.isNetworked, Decl(typeGuardOfFormThisMember.ts, 12, 3)) +>file : Symbol(file, Decl(typeGuardOfFormThisMember.ts, 27, 4)) +>isNetworked : Symbol(FileSystemObject.isNetworked, Decl(typeGuardOfFormThisMember.ts, 12, 3)) - file.isNetworked = file.isDirectory; ->file.isNetworked : Symbol(FileSystemObject.isNetworked, Decl(typeGuardOfFormThisMember.ts, 11, 3)) ->file : Symbol(file, Decl(typeGuardOfFormThisMember.ts, 26, 4)) ->isNetworked : Symbol(FileSystemObject.isNetworked, Decl(typeGuardOfFormThisMember.ts, 11, 3)) ->file.isDirectory : Symbol(FileSystemObject.isDirectory, Decl(typeGuardOfFormThisMember.ts, 8, 3)) ->file : Symbol(file, Decl(typeGuardOfFormThisMember.ts, 26, 4)) ->isDirectory : Symbol(FileSystemObject.isDirectory, Decl(typeGuardOfFormThisMember.ts, 8, 3)) + file.isFSO = file.isFile; +>file.isFSO : Symbol(FileSystemObject.isFSO, Decl(typeGuardOfFormThisMember.ts, 2, 32)) +>file : Symbol(file, Decl(typeGuardOfFormThisMember.ts, 27, 4)) +>isFSO : Symbol(FileSystemObject.isFSO, Decl(typeGuardOfFormThisMember.ts, 2, 32)) +>file.isFile : Symbol(FileSystemObject.isFile, Decl(typeGuardOfFormThisMember.ts, 3, 34), Decl(typeGuardOfFormThisMember.ts, 6, 3)) +>file : Symbol(file, Decl(typeGuardOfFormThisMember.ts, 27, 4)) +>isFile : Symbol(FileSystemObject.isFile, Decl(typeGuardOfFormThisMember.ts, 3, 34), Decl(typeGuardOfFormThisMember.ts, 6, 3)) - file.isFile = file.isNetworked; ->file.isFile : Symbol(FileSystemObject.isFile, Decl(typeGuardOfFormThisMember.ts, 2, 32), Decl(typeGuardOfFormThisMember.ts, 5, 3)) ->file : Symbol(file, Decl(typeGuardOfFormThisMember.ts, 26, 4)) ->isFile : Symbol(FileSystemObject.isFile, Decl(typeGuardOfFormThisMember.ts, 2, 32), Decl(typeGuardOfFormThisMember.ts, 5, 3)) ->file.isNetworked : Symbol(FileSystemObject.isNetworked, Decl(typeGuardOfFormThisMember.ts, 11, 3)) ->file : Symbol(file, Decl(typeGuardOfFormThisMember.ts, 26, 4)) ->isNetworked : Symbol(FileSystemObject.isNetworked, Decl(typeGuardOfFormThisMember.ts, 11, 3)) + file.isFile = true; +>file.isFile : Symbol(FileSystemObject.isFile, Decl(typeGuardOfFormThisMember.ts, 3, 34), Decl(typeGuardOfFormThisMember.ts, 6, 3)) +>file : Symbol(file, Decl(typeGuardOfFormThisMember.ts, 27, 4)) +>isFile : Symbol(FileSystemObject.isFile, Decl(typeGuardOfFormThisMember.ts, 3, 34), Decl(typeGuardOfFormThisMember.ts, 6, 3)) let x = file.isFile; ->x : Symbol(x, Decl(typeGuardOfFormThisMember.ts, 30, 4)) ->file.isFile : Symbol(FileSystemObject.isFile, Decl(typeGuardOfFormThisMember.ts, 2, 32), Decl(typeGuardOfFormThisMember.ts, 5, 3)) ->file : Symbol(file, Decl(typeGuardOfFormThisMember.ts, 26, 4)) ->isFile : Symbol(FileSystemObject.isFile, Decl(typeGuardOfFormThisMember.ts, 2, 32), Decl(typeGuardOfFormThisMember.ts, 5, 3)) +>x : Symbol(x, Decl(typeGuardOfFormThisMember.ts, 31, 4)) +>file.isFile : Symbol(FileSystemObject.isFile, Decl(typeGuardOfFormThisMember.ts, 3, 34), Decl(typeGuardOfFormThisMember.ts, 6, 3)) +>file : Symbol(file, Decl(typeGuardOfFormThisMember.ts, 27, 4)) +>isFile : Symbol(FileSystemObject.isFile, Decl(typeGuardOfFormThisMember.ts, 3, 34), Decl(typeGuardOfFormThisMember.ts, 6, 3)) if (file.isFile) { ->file.isFile : Symbol(FileSystemObject.isFile, Decl(typeGuardOfFormThisMember.ts, 2, 32), Decl(typeGuardOfFormThisMember.ts, 5, 3)) ->file : Symbol(file, Decl(typeGuardOfFormThisMember.ts, 26, 4)) ->isFile : Symbol(FileSystemObject.isFile, Decl(typeGuardOfFormThisMember.ts, 2, 32), Decl(typeGuardOfFormThisMember.ts, 5, 3)) +>file.isFile : Symbol(FileSystemObject.isFile, Decl(typeGuardOfFormThisMember.ts, 3, 34), Decl(typeGuardOfFormThisMember.ts, 6, 3)) +>file : Symbol(file, Decl(typeGuardOfFormThisMember.ts, 27, 4)) +>isFile : Symbol(FileSystemObject.isFile, Decl(typeGuardOfFormThisMember.ts, 3, 34), Decl(typeGuardOfFormThisMember.ts, 6, 3)) file.content; ->file.content : Symbol(File.content, Decl(typeGuardOfFormThisMember.ts, 17, 27)) ->file : Symbol(file, Decl(typeGuardOfFormThisMember.ts, 26, 4)) ->content : Symbol(File.content, Decl(typeGuardOfFormThisMember.ts, 17, 27)) +>file.content : Symbol(File.content, Decl(typeGuardOfFormThisMember.ts, 18, 27)) +>file : Symbol(file, Decl(typeGuardOfFormThisMember.ts, 27, 4)) +>content : Symbol(File.content, Decl(typeGuardOfFormThisMember.ts, 18, 27)) if (file.isNetworked) { ->file.isNetworked : Symbol(FileSystemObject.isNetworked, Decl(typeGuardOfFormThisMember.ts, 11, 3)) ->file : Symbol(file, Decl(typeGuardOfFormThisMember.ts, 26, 4)) ->isNetworked : Symbol(FileSystemObject.isNetworked, Decl(typeGuardOfFormThisMember.ts, 11, 3)) +>file.isNetworked : Symbol(FileSystemObject.isNetworked, Decl(typeGuardOfFormThisMember.ts, 12, 3)) +>file : Symbol(file, Decl(typeGuardOfFormThisMember.ts, 27, 4)) +>isNetworked : Symbol(FileSystemObject.isNetworked, Decl(typeGuardOfFormThisMember.ts, 12, 3)) file.host; ->file.host : Symbol(Networked.host, Decl(typeGuardOfFormThisMember.ts, 22, 29)) ->file : Symbol(file, Decl(typeGuardOfFormThisMember.ts, 26, 4)) ->host : Symbol(Networked.host, Decl(typeGuardOfFormThisMember.ts, 22, 29)) +>file.host : Symbol(Networked.host, Decl(typeGuardOfFormThisMember.ts, 23, 29)) +>file : Symbol(file, Decl(typeGuardOfFormThisMember.ts, 27, 4)) +>host : Symbol(Networked.host, Decl(typeGuardOfFormThisMember.ts, 23, 29)) file.content; ->file.content : Symbol(File.content, Decl(typeGuardOfFormThisMember.ts, 17, 27)) ->file : Symbol(file, Decl(typeGuardOfFormThisMember.ts, 26, 4)) ->content : Symbol(File.content, Decl(typeGuardOfFormThisMember.ts, 17, 27)) +>file.content : Symbol(File.content, Decl(typeGuardOfFormThisMember.ts, 18, 27)) +>file : Symbol(file, Decl(typeGuardOfFormThisMember.ts, 27, 4)) +>content : Symbol(File.content, Decl(typeGuardOfFormThisMember.ts, 18, 27)) } } else if (file.isDirectory) { ->file.isDirectory : Symbol(FileSystemObject.isDirectory, Decl(typeGuardOfFormThisMember.ts, 8, 3)) ->file : Symbol(file, Decl(typeGuardOfFormThisMember.ts, 26, 4)) ->isDirectory : Symbol(FileSystemObject.isDirectory, Decl(typeGuardOfFormThisMember.ts, 8, 3)) +>file.isDirectory : Symbol(FileSystemObject.isDirectory, Decl(typeGuardOfFormThisMember.ts, 9, 3)) +>file : Symbol(file, Decl(typeGuardOfFormThisMember.ts, 27, 4)) +>isDirectory : Symbol(FileSystemObject.isDirectory, Decl(typeGuardOfFormThisMember.ts, 9, 3)) file.children; ->file.children : Symbol(Directory.children, Decl(typeGuardOfFormThisMember.ts, 19, 50)) ->file : Symbol(file, Decl(typeGuardOfFormThisMember.ts, 26, 4)) ->children : Symbol(Directory.children, Decl(typeGuardOfFormThisMember.ts, 19, 50)) +>file.children : Symbol(Directory.children, Decl(typeGuardOfFormThisMember.ts, 20, 50)) +>file : Symbol(file, Decl(typeGuardOfFormThisMember.ts, 27, 4)) +>children : Symbol(Directory.children, Decl(typeGuardOfFormThisMember.ts, 20, 50)) } else if (file.isNetworked) { ->file.isNetworked : Symbol(FileSystemObject.isNetworked, Decl(typeGuardOfFormThisMember.ts, 11, 3)) ->file : Symbol(file, Decl(typeGuardOfFormThisMember.ts, 26, 4)) ->isNetworked : Symbol(FileSystemObject.isNetworked, Decl(typeGuardOfFormThisMember.ts, 11, 3)) +>file.isNetworked : Symbol(FileSystemObject.isNetworked, Decl(typeGuardOfFormThisMember.ts, 12, 3)) +>file : Symbol(file, Decl(typeGuardOfFormThisMember.ts, 27, 4)) +>isNetworked : Symbol(FileSystemObject.isNetworked, Decl(typeGuardOfFormThisMember.ts, 12, 3)) file.host; ->file.host : Symbol(Networked.host, Decl(typeGuardOfFormThisMember.ts, 22, 29)) ->file : Symbol(file, Decl(typeGuardOfFormThisMember.ts, 26, 4)) ->host : Symbol(Networked.host, Decl(typeGuardOfFormThisMember.ts, 22, 29)) +>file.host : Symbol(Networked.host, Decl(typeGuardOfFormThisMember.ts, 23, 29)) +>file : Symbol(file, Decl(typeGuardOfFormThisMember.ts, 27, 4)) +>host : Symbol(Networked.host, Decl(typeGuardOfFormThisMember.ts, 23, 29)) } interface GenericLeadGuard extends GenericGuard { ->GenericLeadGuard : Symbol(GenericLeadGuard, Decl(typeGuardOfFormThisMember.ts, 43, 2)) ->T : Symbol(T, Decl(typeGuardOfFormThisMember.ts, 45, 28)) ->GenericGuard : Symbol(GenericGuard, Decl(typeGuardOfFormThisMember.ts, 51, 2)) ->T : Symbol(T, Decl(typeGuardOfFormThisMember.ts, 45, 28)) +>GenericLeadGuard : Symbol(GenericLeadGuard, Decl(typeGuardOfFormThisMember.ts, 44, 2)) +>T : Symbol(T, Decl(typeGuardOfFormThisMember.ts, 46, 28)) +>GenericGuard : Symbol(GenericGuard, Decl(typeGuardOfFormThisMember.ts, 52, 2)) +>T : Symbol(T, Decl(typeGuardOfFormThisMember.ts, 46, 28)) lead(): void; ->lead : Symbol(lead, Decl(typeGuardOfFormThisMember.ts, 45, 56)) +>lead : Symbol(lead, Decl(typeGuardOfFormThisMember.ts, 46, 56)) } interface GenericFollowerGuard extends GenericGuard { ->GenericFollowerGuard : Symbol(GenericFollowerGuard, Decl(typeGuardOfFormThisMember.ts, 47, 2)) ->T : Symbol(T, Decl(typeGuardOfFormThisMember.ts, 49, 32)) ->GenericGuard : Symbol(GenericGuard, Decl(typeGuardOfFormThisMember.ts, 51, 2)) ->T : Symbol(T, Decl(typeGuardOfFormThisMember.ts, 49, 32)) +>GenericFollowerGuard : Symbol(GenericFollowerGuard, Decl(typeGuardOfFormThisMember.ts, 48, 2)) +>T : Symbol(T, Decl(typeGuardOfFormThisMember.ts, 50, 32)) +>GenericGuard : Symbol(GenericGuard, Decl(typeGuardOfFormThisMember.ts, 52, 2)) +>T : Symbol(T, Decl(typeGuardOfFormThisMember.ts, 50, 32)) follow(): void; ->follow : Symbol(follow, Decl(typeGuardOfFormThisMember.ts, 49, 60)) +>follow : Symbol(follow, Decl(typeGuardOfFormThisMember.ts, 50, 60)) } interface GenericGuard { ->GenericGuard : Symbol(GenericGuard, Decl(typeGuardOfFormThisMember.ts, 51, 2)) ->T : Symbol(T, Decl(typeGuardOfFormThisMember.ts, 53, 24)) +>GenericGuard : Symbol(GenericGuard, Decl(typeGuardOfFormThisMember.ts, 52, 2)) +>T : Symbol(T, Decl(typeGuardOfFormThisMember.ts, 54, 24)) target: T; ->target : Symbol(target, Decl(typeGuardOfFormThisMember.ts, 53, 28)) ->T : Symbol(T, Decl(typeGuardOfFormThisMember.ts, 53, 24)) +>target : Symbol(target, Decl(typeGuardOfFormThisMember.ts, 54, 28)) +>T : Symbol(T, Decl(typeGuardOfFormThisMember.ts, 54, 24)) isLeader: this is (GenericLeadGuard); ->isLeader : Symbol(isLeader, Decl(typeGuardOfFormThisMember.ts, 54, 12)) ->GenericLeadGuard : Symbol(GenericLeadGuard, Decl(typeGuardOfFormThisMember.ts, 43, 2)) ->T : Symbol(T, Decl(typeGuardOfFormThisMember.ts, 53, 24)) +>isLeader : Symbol(isLeader, Decl(typeGuardOfFormThisMember.ts, 55, 12)) +>GenericLeadGuard : Symbol(GenericLeadGuard, Decl(typeGuardOfFormThisMember.ts, 44, 2)) +>T : Symbol(T, Decl(typeGuardOfFormThisMember.ts, 54, 24)) isFollower: this is GenericFollowerGuard; ->isFollower : Symbol(isFollower, Decl(typeGuardOfFormThisMember.ts, 55, 42)) ->GenericFollowerGuard : Symbol(GenericFollowerGuard, Decl(typeGuardOfFormThisMember.ts, 47, 2)) ->T : Symbol(T, Decl(typeGuardOfFormThisMember.ts, 53, 24)) +>isFollower : Symbol(isFollower, Decl(typeGuardOfFormThisMember.ts, 56, 42)) +>GenericFollowerGuard : Symbol(GenericFollowerGuard, Decl(typeGuardOfFormThisMember.ts, 48, 2)) +>T : Symbol(T, Decl(typeGuardOfFormThisMember.ts, 54, 24)) } let guard: GenericGuard; ->guard : Symbol(guard, Decl(typeGuardOfFormThisMember.ts, 59, 4)) ->GenericGuard : Symbol(GenericGuard, Decl(typeGuardOfFormThisMember.ts, 51, 2)) ->File : Symbol(File, Decl(typeGuardOfFormThisMember.ts, 14, 2)) +>guard : Symbol(guard, Decl(typeGuardOfFormThisMember.ts, 60, 4)) +>GenericGuard : Symbol(GenericGuard, Decl(typeGuardOfFormThisMember.ts, 52, 2)) +>File : Symbol(File, Decl(typeGuardOfFormThisMember.ts, 15, 2)) if (guard.isLeader) { ->guard.isLeader : Symbol(GenericGuard.isLeader, Decl(typeGuardOfFormThisMember.ts, 54, 12)) ->guard : Symbol(guard, Decl(typeGuardOfFormThisMember.ts, 59, 4)) ->isLeader : Symbol(GenericGuard.isLeader, Decl(typeGuardOfFormThisMember.ts, 54, 12)) +>guard.isLeader : Symbol(GenericGuard.isLeader, Decl(typeGuardOfFormThisMember.ts, 55, 12)) +>guard : Symbol(guard, Decl(typeGuardOfFormThisMember.ts, 60, 4)) +>isLeader : Symbol(GenericGuard.isLeader, Decl(typeGuardOfFormThisMember.ts, 55, 12)) guard.lead(); ->guard.lead : Symbol(GenericLeadGuard.lead, Decl(typeGuardOfFormThisMember.ts, 45, 56)) ->guard : Symbol(guard, Decl(typeGuardOfFormThisMember.ts, 59, 4)) ->lead : Symbol(GenericLeadGuard.lead, Decl(typeGuardOfFormThisMember.ts, 45, 56)) +>guard.lead : Symbol(GenericLeadGuard.lead, Decl(typeGuardOfFormThisMember.ts, 46, 56)) +>guard : Symbol(guard, Decl(typeGuardOfFormThisMember.ts, 60, 4)) +>lead : Symbol(GenericLeadGuard.lead, Decl(typeGuardOfFormThisMember.ts, 46, 56)) } else if (guard.isFollower) { ->guard.isFollower : Symbol(GenericGuard.isFollower, Decl(typeGuardOfFormThisMember.ts, 55, 42)) ->guard : Symbol(guard, Decl(typeGuardOfFormThisMember.ts, 59, 4)) ->isFollower : Symbol(GenericGuard.isFollower, Decl(typeGuardOfFormThisMember.ts, 55, 42)) +>guard.isFollower : Symbol(GenericGuard.isFollower, Decl(typeGuardOfFormThisMember.ts, 56, 42)) +>guard : Symbol(guard, Decl(typeGuardOfFormThisMember.ts, 60, 4)) +>isFollower : Symbol(GenericGuard.isFollower, Decl(typeGuardOfFormThisMember.ts, 56, 42)) guard.follow(); ->guard.follow : Symbol(GenericFollowerGuard.follow, Decl(typeGuardOfFormThisMember.ts, 49, 60)) ->guard : Symbol(guard, Decl(typeGuardOfFormThisMember.ts, 59, 4)) ->follow : Symbol(GenericFollowerGuard.follow, Decl(typeGuardOfFormThisMember.ts, 49, 60)) +>guard.follow : Symbol(GenericFollowerGuard.follow, Decl(typeGuardOfFormThisMember.ts, 50, 60)) +>guard : Symbol(guard, Decl(typeGuardOfFormThisMember.ts, 60, 4)) +>follow : Symbol(GenericFollowerGuard.follow, Decl(typeGuardOfFormThisMember.ts, 50, 60)) } interface SpecificGuard { ->SpecificGuard : Symbol(SpecificGuard, Decl(typeGuardOfFormThisMember.ts, 65, 2)) +>SpecificGuard : Symbol(SpecificGuard, Decl(typeGuardOfFormThisMember.ts, 66, 2)) isMoreSpecific: this is MoreSpecificGuard; ->isMoreSpecific : Symbol(isMoreSpecific, Decl(typeGuardOfFormThisMember.ts, 67, 26)) ->MoreSpecificGuard : Symbol(MoreSpecificGuard, Decl(typeGuardOfFormThisMember.ts, 69, 2)) +>isMoreSpecific : Symbol(isMoreSpecific, Decl(typeGuardOfFormThisMember.ts, 68, 26)) +>MoreSpecificGuard : Symbol(MoreSpecificGuard, Decl(typeGuardOfFormThisMember.ts, 70, 2)) } interface MoreSpecificGuard extends SpecificGuard { ->MoreSpecificGuard : Symbol(MoreSpecificGuard, Decl(typeGuardOfFormThisMember.ts, 69, 2)) ->SpecificGuard : Symbol(SpecificGuard, Decl(typeGuardOfFormThisMember.ts, 65, 2)) +>MoreSpecificGuard : Symbol(MoreSpecificGuard, Decl(typeGuardOfFormThisMember.ts, 70, 2)) +>SpecificGuard : Symbol(SpecificGuard, Decl(typeGuardOfFormThisMember.ts, 66, 2)) do(): void; ->do : Symbol(do, Decl(typeGuardOfFormThisMember.ts, 71, 52)) +>do : Symbol(do, Decl(typeGuardOfFormThisMember.ts, 72, 52)) } let general: SpecificGuard; ->general : Symbol(general, Decl(typeGuardOfFormThisMember.ts, 75, 4)) ->SpecificGuard : Symbol(SpecificGuard, Decl(typeGuardOfFormThisMember.ts, 65, 2)) +>general : Symbol(general, Decl(typeGuardOfFormThisMember.ts, 76, 4)) +>SpecificGuard : Symbol(SpecificGuard, Decl(typeGuardOfFormThisMember.ts, 66, 2)) if (general.isMoreSpecific) { ->general.isMoreSpecific : Symbol(SpecificGuard.isMoreSpecific, Decl(typeGuardOfFormThisMember.ts, 67, 26)) ->general : Symbol(general, Decl(typeGuardOfFormThisMember.ts, 75, 4)) ->isMoreSpecific : Symbol(SpecificGuard.isMoreSpecific, Decl(typeGuardOfFormThisMember.ts, 67, 26)) +>general.isMoreSpecific : Symbol(SpecificGuard.isMoreSpecific, Decl(typeGuardOfFormThisMember.ts, 68, 26)) +>general : Symbol(general, Decl(typeGuardOfFormThisMember.ts, 76, 4)) +>isMoreSpecific : Symbol(SpecificGuard.isMoreSpecific, Decl(typeGuardOfFormThisMember.ts, 68, 26)) general.do(); ->general.do : Symbol(MoreSpecificGuard.do, Decl(typeGuardOfFormThisMember.ts, 71, 52)) ->general : Symbol(general, Decl(typeGuardOfFormThisMember.ts, 75, 4)) ->do : Symbol(MoreSpecificGuard.do, Decl(typeGuardOfFormThisMember.ts, 71, 52)) +>general.do : Symbol(MoreSpecificGuard.do, Decl(typeGuardOfFormThisMember.ts, 72, 52)) +>general : Symbol(general, Decl(typeGuardOfFormThisMember.ts, 76, 4)) +>do : Symbol(MoreSpecificGuard.do, Decl(typeGuardOfFormThisMember.ts, 72, 52)) } } diff --git a/tests/baselines/reference/typeGuardOfFormThisMember.types b/tests/baselines/reference/typeGuardOfFormThisMember.types index 3ecb174653b..68343947fb4 100644 --- a/tests/baselines/reference/typeGuardOfFormThisMember.types +++ b/tests/baselines/reference/typeGuardOfFormThisMember.types @@ -6,6 +6,10 @@ namespace Test { export class FileSystemObject { >FileSystemObject : FileSystemObject + isFSO: this is FileSystemObject; +>isFSO : this is FileSystemObject +>FileSystemObject : FileSystemObject + get isFile(): this is File { >isFile : this is File >File : File @@ -79,23 +83,21 @@ namespace Test { >isNetworked : this is Networked & FileSystemObject >false : boolean - file.isNetworked = file.isDirectory; ->file.isNetworked = file.isDirectory : this is Directory ->file.isNetworked : this is Networked & FileSystemObject + file.isFSO = file.isFile; +>file.isFSO = file.isFile : this is File +>file.isFSO : this is FileSystemObject >file : FileSystemObject ->isNetworked : this is Networked & FileSystemObject ->file.isDirectory : this is Directory ->file : FileSystemObject ->isDirectory : this is Directory - - file.isFile = file.isNetworked; ->file.isFile = file.isNetworked : this is Networked & FileSystemObject +>isFSO : this is FileSystemObject >file.isFile : this is File >file : FileSystemObject >isFile : this is File ->file.isNetworked : this is Networked & FileSystemObject + + file.isFile = true; +>file.isFile = true : boolean +>file.isFile : this is File >file : FileSystemObject ->isNetworked : this is Networked & FileSystemObject +>isFile : this is File +>true : boolean let x = file.isFile; >x : boolean diff --git a/tests/baselines/reference/typeGuardOfFormThisMemberErrors.errors.txt b/tests/baselines/reference/typeGuardOfFormThisMemberErrors.errors.txt new file mode 100644 index 00000000000..754cbffe6e6 --- /dev/null +++ b/tests/baselines/reference/typeGuardOfFormThisMemberErrors.errors.txt @@ -0,0 +1,51 @@ +tests/cases/conformance/expressions/typeGuards/typeGuardOfFormThisMemberErrors.ts(29,2): error TS1226: Type predicate 'this is File' is not assignable to 'this is Networked & FileSystemObject'. + Type 'File' is not assignable to type 'Networked & FileSystemObject'. + Type 'File' is not assignable to type 'Networked'. + Property 'host' is missing in type 'File'. +tests/cases/conformance/expressions/typeGuards/typeGuardOfFormThisMemberErrors.ts(31,2): error TS1226: Type predicate 'this is FileSystemObject' is not assignable to 'this is File'. + Type 'FileSystemObject' is not assignable to type 'File'. + Property 'content' is missing in type 'FileSystemObject'. + + +==== tests/cases/conformance/expressions/typeGuards/typeGuardOfFormThisMemberErrors.ts (2 errors) ==== + // There's a 'File' class in the stdlib, wrap with a namespace to avoid collision + namespace Test { + export class FileSystemObject { + isFSO: this is FileSystemObject; + get isFile(): this is File { + return this instanceof File; + } + set isFile(param) { + // noop + } + get isDirectory(): this is Directory { + return this instanceof Directory; + } + isNetworked: this is (Networked & this); + constructor(public path: string) {} + } + + export class File extends FileSystemObject { + constructor(path: string, public content: string) { super(path); } + } + export class Directory extends FileSystemObject { + children: FileSystemObject[]; + } + export interface Networked { + host: string; + } + + let file: FileSystemObject = new File("foo/bar.txt", "foo"); + file.isNetworked = file.isFile; + ~~~~~~~~~~~~~~~~ +!!! error TS1226: Type predicate 'this is File' is not assignable to 'this is Networked & FileSystemObject'. +!!! error TS1226: Type 'File' is not assignable to type 'Networked & FileSystemObject'. +!!! error TS1226: Type 'File' is not assignable to type 'Networked'. +!!! error TS1226: Property 'host' is missing in type 'File'. + file.isFSO = file.isNetworked; + file.isFile = file.isFSO; + ~~~~~~~~~~~ +!!! error TS1226: Type predicate 'this is FileSystemObject' is not assignable to 'this is File'. +!!! error TS1226: Type 'FileSystemObject' is not assignable to type 'File'. +!!! error TS1226: Property 'content' is missing in type 'FileSystemObject'. + } \ No newline at end of file diff --git a/tests/baselines/reference/typeGuardOfFormThisMemberErrors.js b/tests/baselines/reference/typeGuardOfFormThisMemberErrors.js new file mode 100644 index 00000000000..e6b2f556621 --- /dev/null +++ b/tests/baselines/reference/typeGuardOfFormThisMemberErrors.js @@ -0,0 +1,112 @@ +//// [typeGuardOfFormThisMemberErrors.ts] +// There's a 'File' class in the stdlib, wrap with a namespace to avoid collision +namespace Test { + export class FileSystemObject { + isFSO: this is FileSystemObject; + get isFile(): this is File { + return this instanceof File; + } + set isFile(param) { + // noop + } + get isDirectory(): this is Directory { + return this instanceof Directory; + } + isNetworked: this is (Networked & this); + constructor(public path: string) {} + } + + export class File extends FileSystemObject { + constructor(path: string, public content: string) { super(path); } + } + export class Directory extends FileSystemObject { + children: FileSystemObject[]; + } + export interface Networked { + host: string; + } + + let file: FileSystemObject = new File("foo/bar.txt", "foo"); + file.isNetworked = file.isFile; + file.isFSO = file.isNetworked; + file.isFile = file.isFSO; +} + +//// [typeGuardOfFormThisMemberErrors.js] +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +// There's a 'File' class in the stdlib, wrap with a namespace to avoid collision +var Test; +(function (Test) { + var FileSystemObject = (function () { + function FileSystemObject(path) { + this.path = path; + } + Object.defineProperty(FileSystemObject.prototype, "isFile", { + get: function () { + return this instanceof File; + }, + set: function (param) { + // noop + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(FileSystemObject.prototype, "isDirectory", { + get: function () { + return this instanceof Directory; + }, + enumerable: true, + configurable: true + }); + return FileSystemObject; + })(); + Test.FileSystemObject = FileSystemObject; + var File = (function (_super) { + __extends(File, _super); + function File(path, content) { + _super.call(this, path); + this.content = content; + } + return File; + })(FileSystemObject); + Test.File = File; + var Directory = (function (_super) { + __extends(Directory, _super); + function Directory() { + _super.apply(this, arguments); + } + return Directory; + })(FileSystemObject); + Test.Directory = Directory; + var file = new File("foo/bar.txt", "foo"); + file.isNetworked = file.isFile; + file.isFSO = file.isNetworked; + file.isFile = file.isFSO; +})(Test || (Test = {})); + + +//// [typeGuardOfFormThisMemberErrors.d.ts] +declare namespace Test { + class FileSystemObject { + path: string; + isFSO: this is FileSystemObject; + isFile: this is File; + isDirectory: this is Directory; + isNetworked: this is (Networked & this); + constructor(path: string); + } + class File extends FileSystemObject { + content: string; + constructor(path: string, content: string); + } + class Directory extends FileSystemObject { + children: FileSystemObject[]; + } + interface Networked { + host: string; + } +} diff --git a/tests/baselines/reference/unionAndIntersectionInference1.types b/tests/baselines/reference/unionAndIntersectionInference1.types index 5d23688f0b7..3de2514a2fa 100644 --- a/tests/baselines/reference/unionAndIntersectionInference1.types +++ b/tests/baselines/reference/unionAndIntersectionInference1.types @@ -110,7 +110,7 @@ function foo1(value: void|a): void { >a : a if (isVoid(value)) { ->isVoid(value) : boolean +>isVoid(value) : value is void >isVoid : (value: void | a) => value is void >value : void | a @@ -130,7 +130,7 @@ function baz1(value: void|a): void { >a : a if (isNonVoid(value)) { ->isNonVoid(value) : boolean +>isNonVoid(value) : value is {} >isNonVoid : (value: void | a) => value is a >value : void | a diff --git a/tests/cases/conformance/expressions/typeGuards/typeGuardOfFormThisMember.ts b/tests/cases/conformance/expressions/typeGuards/typeGuardOfFormThisMember.ts index 707f0f6eea5..decf6d99353 100644 --- a/tests/cases/conformance/expressions/typeGuards/typeGuardOfFormThisMember.ts +++ b/tests/cases/conformance/expressions/typeGuards/typeGuardOfFormThisMember.ts @@ -3,6 +3,7 @@ // There's a 'File' class in the stdlib, wrap with a namespace to avoid collision namespace Test { export class FileSystemObject { + isFSO: this is FileSystemObject; get isFile(): this is File { return this instanceof File; } @@ -28,8 +29,8 @@ namespace Test { let file: FileSystemObject = new File("foo/bar.txt", "foo"); file.isNetworked = false; - file.isNetworked = file.isDirectory; - file.isFile = file.isNetworked; + file.isFSO = file.isFile; + file.isFile = true; let x = file.isFile; if (file.isFile) { file.content; diff --git a/tests/cases/conformance/expressions/typeGuards/typeGuardOfFormThisMemberErrors.ts b/tests/cases/conformance/expressions/typeGuards/typeGuardOfFormThisMemberErrors.ts new file mode 100644 index 00000000000..d629a2a1cdd --- /dev/null +++ b/tests/cases/conformance/expressions/typeGuards/typeGuardOfFormThisMemberErrors.ts @@ -0,0 +1,34 @@ +// @target: es5 +// @declaration: true +// There's a 'File' class in the stdlib, wrap with a namespace to avoid collision +namespace Test { + export class FileSystemObject { + isFSO: this is FileSystemObject; + get isFile(): this is File { + return this instanceof File; + } + set isFile(param) { + // noop + } + get isDirectory(): this is Directory { + return this instanceof Directory; + } + isNetworked: this is (Networked & this); + constructor(public path: string) {} + } + + export class File extends FileSystemObject { + constructor(path: string, public content: string) { super(path); } + } + export class Directory extends FileSystemObject { + children: FileSystemObject[]; + } + export interface Networked { + host: string; + } + + let file: FileSystemObject = new File("foo/bar.txt", "foo"); + file.isNetworked = file.isFile; + file.isFSO = file.isNetworked; + file.isFile = file.isFSO; +} \ No newline at end of file