diff --git a/Jakefile.js b/Jakefile.js index b198d285a4f..1f88ee39082 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -149,7 +149,7 @@ var librarySourceMap = [ { target: "lib.scriptHost.d.ts", sources: ["importcore.d.ts", "scriptHost.d.ts"], }, { target: "lib.d.ts", sources: ["core.d.ts", "extensions.d.ts", "intl.d.ts", "dom.generated.d.ts", "webworker.importscripts.d.ts", "scriptHost.d.ts"], }, { target: "lib.core.es6.d.ts", sources: ["core.d.ts", "es6.d.ts"]}, - { target: "lib.es6.d.ts", sources: ["core.d.ts", "es6.d.ts", "intl.d.ts", "dom.generated.d.ts", "webworker.importscripts.d.ts", "scriptHost.d.ts"]}, + { target: "lib.es6.d.ts", sources: ["core.d.ts", "es6.d.ts", "intl.d.ts", "dom.generated.d.ts", "dom.es6.d.ts", "webworker.importscripts.d.ts", "scriptHost.d.ts"] }, ]; var libraryTargets = librarySourceMap.map(function (f) { diff --git a/bin/tsc b/bin/tsc old mode 100644 new mode 100755 diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index ea589891241..a0e177e7659 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -338,6 +338,7 @@ module ts { case SyntaxKind.ArrowFunction: case SyntaxKind.ModuleDeclaration: case SyntaxKind.SourceFile: + case SyntaxKind.TypeAliasDeclaration: return ContainerFlags.IsContainerWithLocals; case SyntaxKind.CatchClause: @@ -385,10 +386,10 @@ module ts { function declareSymbolAndAddToSymbolTableWorker(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags): Symbol { switch (container.kind) { - // Modules, source files, and classes need specialized handling for how their + // Modules, source files, and classes need specialized handling for how their // members are declared (for example, a member of a class will go into a specific - // symbol table depending on if it is static or not). As such, we defer to - // specialized handlers to take care of declaring these child members. + // symbol table depending on if it is static or not). We defer to specialized + // handlers to take care of declaring these child members. case SyntaxKind.ModuleDeclaration: return declareModuleMember(node, symbolFlags, symbolExcludes); @@ -406,9 +407,10 @@ module ts { case SyntaxKind.ObjectLiteralExpression: case SyntaxKind.InterfaceDeclaration: // Interface/Object-types always have their children added to the 'members' of - // their container. They are only accessible through an instance of their - // container, and are never in scope otherwise (even inside the body of the - // object / type / interface declaring them). + // their container. They are only accessible through an instance of their + // container, and are never in scope otherwise (even inside the body of the + // object / type / interface declaring them). An exception is type parameters, + // which are in scope without qualification (similar to 'locals'). return declareSymbol(container.symbol.members, container.symbol, node, symbolFlags, symbolExcludes); case SyntaxKind.FunctionType: @@ -424,11 +426,12 @@ module ts { case SyntaxKind.FunctionDeclaration: case SyntaxKind.FunctionExpression: case SyntaxKind.ArrowFunction: + case SyntaxKind.TypeAliasDeclaration: // All the children of these container types are never visible through another - // symbol (i.e. through another symbol's 'exports' or 'members'). Instead, - // they're only accessed 'lexically' (i.e. from code that exists underneath + // symbol (i.e. through another symbol's 'exports' or 'members'). Instead, + // they're only accessed 'lexically' (i.e. from code that exists underneath // their container in the tree. To accomplish this, we simply add their declared - // symbol to the 'locals' of the container. These symbols can then be found as + // symbol to the 'locals' of the container. These symbols can then be found as // the type checker walks up the containers, checking them for matching names. return declareSymbol(container.locals, undefined, node, symbolFlags, symbolExcludes); } diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 4347a4976a9..a3e8d1234c3 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -97,8 +97,8 @@ module ts { let anyFunctionType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined); let noConstraintType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined); - let anySignature = createSignature(undefined, undefined, emptyArray, anyType, 0, false, false); - let unknownSignature = createSignature(undefined, undefined, emptyArray, unknownType, 0, false, false); + let anySignature = createSignature(undefined, undefined, emptyArray, anyType, undefined, 0, false, false); + let unknownSignature = createSignature(undefined, undefined, emptyArray, unknownType, undefined, 0, false, false); let globals: SymbolTable = {}; @@ -1352,7 +1352,15 @@ module ts { function symbolToString(symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags): string { let writer = getSingleLineStringWriter(); getSymbolDisplayBuilder().buildSymbolDisplay(symbol, writer, enclosingDeclaration, meaning); + let result = writer.string(); + releaseStringWriter(writer); + return result; + } + + function signatureToString(signature: Signature, enclosingDeclaration?: Node, flags?: TypeFormatFlags): string { + let writer = getSingleLineStringWriter(); + getSymbolDisplayBuilder().buildSignatureDisplay(signature, writer, enclosingDeclaration, flags); let result = writer.string(); releaseStringWriter(writer); @@ -1362,7 +1370,6 @@ module ts { function typeToString(type: Type, enclosingDeclaration?: Node, flags?: TypeFormatFlags): string { let writer = getSingleLineStringWriter(); getSymbolDisplayBuilder().buildTypeDisplay(type, writer, enclosingDeclaration, flags); - let result = writer.string(); releaseStringWriter(writer); @@ -1370,7 +1377,6 @@ module ts { if (maxLength && result.length >= maxLength) { result = result.substr(0, maxLength - "...".length) + "..."; } - return result; } @@ -1789,7 +1795,7 @@ module ts { function buildTypeParameterDisplayFromSymbol(symbol: Symbol, writer: SymbolWriter, enclosingDeclaraiton?: Node, flags?: TypeFormatFlags) { let targetSymbol = getTargetSymbol(symbol); if (targetSymbol.flags & SymbolFlags.Class || targetSymbol.flags & SymbolFlags.Interface) { - buildDisplayForTypeParametersAndDelimiters(getLocalTypeParametersOfClassOrInterface(symbol), writer, enclosingDeclaraiton, flags); + buildDisplayForTypeParametersAndDelimiters(getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol), writer, enclosingDeclaraiton, flags); } } @@ -2573,12 +2579,13 @@ module ts { return appendOuterTypeParameters(undefined, getDeclarationOfKind(symbol, kind)); } - // The local type parameters are the combined set of type parameters from all declarations of the class or interface. - function getLocalTypeParametersOfClassOrInterface(symbol: Symbol): TypeParameter[] { + // The local type parameters are the combined set of type parameters from all declarations of the class, + // interface, or type alias. + function getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol: Symbol): TypeParameter[] { let result: TypeParameter[]; for (let node of symbol.declarations) { - if (node.kind === SyntaxKind.InterfaceDeclaration || node.kind === SyntaxKind.ClassDeclaration) { - let declaration = node; + if (node.kind === SyntaxKind.InterfaceDeclaration || node.kind === SyntaxKind.ClassDeclaration || node.kind === SyntaxKind.TypeAliasDeclaration) { + let declaration = node; if (declaration.typeParameters) { result = appendTypeParameters(result, declaration.typeParameters); } @@ -2590,7 +2597,7 @@ module ts { // The full set of type parameters for a generic class or interface type consists of its outer type parameters plus // its locally declared type parameters. function getTypeParametersOfClassOrInterface(symbol: Symbol): TypeParameter[] { - return concatenate(getOuterTypeParametersOfClassOrInterface(symbol), getLocalTypeParametersOfClassOrInterface(symbol)); + return concatenate(getOuterTypeParametersOfClassOrInterface(symbol), getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol)); } function getBaseTypes(type: InterfaceType): ObjectType[] { @@ -2663,7 +2670,7 @@ module ts { let kind = symbol.flags & SymbolFlags.Class ? TypeFlags.Class : TypeFlags.Interface; let type = links.declaredType = createObjectType(kind, symbol); let outerTypeParameters = getOuterTypeParametersOfClassOrInterface(symbol); - let localTypeParameters = getLocalTypeParametersOfClassOrInterface(symbol); + let localTypeParameters = getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol); if (outerTypeParameters || localTypeParameters) { type.flags |= TypeFlags.Reference; type.typeParameters = concatenate(outerTypeParameters, localTypeParameters); @@ -2688,7 +2695,16 @@ module ts { } let declaration = getDeclarationOfKind(symbol, SyntaxKind.TypeAliasDeclaration); let type = getTypeFromTypeNode(declaration.type); - if (!popTypeResolution()) { + if (popTypeResolution()) { + links.typeParameters = getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol); + if (links.typeParameters) { + // Initialize the instantiation cache for generic type aliases. The declared type corresponds to + // an instantiation of the type alias with the type parameters supplied as type arguments. + links.instantiations = {}; + links.instantiations[getTypeListId(links.typeParameters)] = type; + } + } + else { type = unknownType; error(declaration.name, Diagnostics.Type_alias_0_circularly_references_itself, symbolToString(symbol)); } @@ -2782,7 +2798,7 @@ module ts { function resolveDeclaredMembers(type: InterfaceType): InterfaceTypeWithDeclaredMembers { if (!(type).declaredProperties) { - var symbol = type.symbol; + let symbol = type.symbol; (type).declaredProperties = getNamedMembers(symbol.members); (type).declaredCallSignatures = getSignaturesOfSymbol(symbol.members["__call"]); (type).declaredConstructSignatures = getSignaturesOfSymbol(symbol.members["__new"]); @@ -2833,12 +2849,13 @@ module ts { } function createSignature(declaration: SignatureDeclaration, typeParameters: TypeParameter[], parameters: Symbol[], - resolvedReturnType: Type, minArgumentCount: number, hasRestParameter: boolean, hasStringLiterals: boolean): Signature { + resolvedReturnType: Type, typePredicate: TypePredicate, minArgumentCount: number, hasRestParameter: boolean, hasStringLiterals: boolean): Signature { let 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; @@ -2846,7 +2863,7 @@ module ts { } function cloneSignature(sig: Signature): Signature { - return createSignature(sig.declaration, sig.typeParameters, sig.parameters, sig.resolvedReturnType, + return createSignature(sig.declaration, sig.typeParameters, sig.parameters, sig.resolvedReturnType, sig.typePredicate, sig.minArgumentCount, sig.hasRestParameter, sig.hasStringLiterals); } @@ -2863,7 +2880,7 @@ module ts { return signature; }); } - return [createSignature(undefined, classType.localTypeParameters, emptyArray, classType, 0, false, false)]; + return [createSignature(undefined, classType.localTypeParameters, emptyArray, classType, undefined, 0, false, false)]; } function createTupleTypeMemberSymbols(memberTypes: Type[]): SymbolTable { @@ -3239,11 +3256,20 @@ module ts { } let returnType: Type; + let typePredicate: TypePredicate; if (classType) { returnType = classType; } else if (declaration.type) { returnType = getTypeFromTypeNode(declaration.type); + if (declaration.type.kind === SyntaxKind.TypePredicate) { + let typePredicateNode = declaration.type; + typePredicate = { + parameterName: typePredicateNode.parameterName ? typePredicateNode.parameterName.text : undefined, + parameterIndex: typePredicateNode.parameterName ? getTypePredicateParameterIndex(declaration.parameters, typePredicateNode.parameterName) : undefined, + type: getTypeFromTypeNode(typePredicateNode.type) + }; + } } else { // TypeScript 1.0 spec (April 2014): @@ -3258,7 +3284,7 @@ module ts { } } - links.resolvedSignature = createSignature(declaration, typeParameters, parameters, returnType, + links.resolvedSignature = createSignature(declaration, typeParameters, parameters, returnType, typePredicate, minArgumentCount, hasRestParameter(declaration), hasStringLiterals); } return links.resolvedSignature; @@ -3513,72 +3539,87 @@ module ts { } } - function getTypeFromTypeReferenceOrExpressionWithTypeArguments(node: TypeReferenceNode | ExpressionWithTypeArguments): Type { - let links = getNodeLinks(node); - if (!links.resolvedType) { - let type: Type; - - // We don't currently support heritage clauses with complex expressions in them. - // For these cases, we just set the type to be the unknownType. - if (node.kind !== SyntaxKind.ExpressionWithTypeArguments || isSupportedExpressionWithTypeArguments(node)) { - let typeNameOrExpression = node.kind === SyntaxKind.TypeReference - ? (node).typeName - : (node).expression; - - let symbol = resolveEntityName(typeNameOrExpression, SymbolFlags.Type); - if (symbol) { - if ((symbol.flags & SymbolFlags.TypeParameter) && isTypeParameterReferenceIllegalInConstraint(node, symbol)) { - // TypeScript 1.0 spec (April 2014): 3.4.1 - // Type parameters declared in a particular type parameter list - // may not be referenced in constraints in that type parameter list - // Implementation: such type references are resolved to 'unknown' type that usually denotes error - type = unknownType; - } - else { - type = createTypeReferenceIfGeneric( - getDeclaredTypeOfSymbol(symbol), - node, node.typeArguments); - } - } + // Get type from reference to class or interface + function getTypeFromClassOrInterfaceReference(node: TypeReferenceNode | ExpressionWithTypeArguments, symbol: Symbol): Type { + let type = getDeclaredTypeOfSymbol(symbol); + let typeParameters = (type).localTypeParameters; + if (typeParameters) { + if (!node.typeArguments || node.typeArguments.length !== typeParameters.length) { + error(node, Diagnostics.Generic_type_0_requires_1_type_argument_s, typeToString(type, /*enclosingDeclaration*/ undefined, TypeFormatFlags.WriteArrayAsGenericType), typeParameters.length); + return unknownType; } - - links.resolvedType = type || unknownType; - } - - return links.resolvedType; - } - - function createTypeReferenceIfGeneric(type: Type, node: Node, typeArguments: NodeArray): Type { - if (type.flags & (TypeFlags.Class | TypeFlags.Interface) && type.flags & TypeFlags.Reference) { // In a type reference, the outer type parameters of the referenced class or interface are automatically // supplied as type arguments and the type reference only specifies arguments for the local type parameters // of the class or interface. - let localTypeParameters = (type).localTypeParameters; - let expectedTypeArgCount = localTypeParameters ? localTypeParameters.length : 0; - let typeArgCount = typeArguments ? typeArguments.length : 0; - if (typeArgCount === expectedTypeArgCount) { - // When no type arguments are expected we already have the right type because all outer type parameters - // have themselves as default type arguments. - if (typeArgCount) { - return createTypeReference(type, concatenate((type).outerTypeParameters, - map(typeArguments, getTypeFromTypeNode))); - } - } - else { - error(node, Diagnostics.Generic_type_0_requires_1_type_argument_s, typeToString(type, /*enclosingDeclaration*/ undefined, TypeFormatFlags.WriteArrayAsGenericType), expectedTypeArgCount); - return undefined; - } + return createTypeReference(type, concatenate((type).outerTypeParameters, + map(node.typeArguments, getTypeFromTypeNode))); } - else { - if (typeArguments) { - error(node, Diagnostics.Type_0_is_not_generic, typeToString(type)); - return undefined; - } + if (node.typeArguments) { + error(node, Diagnostics.Type_0_is_not_generic, typeToString(type)); + return unknownType; } - return type; } + // Get type from reference to type alias. When a type alias is generic, the declared type of the type alias may include + // references to the type parameters of the alias. We replace those with the actual type arguments by instantiating the + // declared type. Instantiations are cached using the type identities of the type arguments as the key. + function getTypeFromTypeAliasReference(node: TypeReferenceNode | ExpressionWithTypeArguments, symbol: Symbol): Type { + let type = getDeclaredTypeOfSymbol(symbol); + let links = getSymbolLinks(symbol); + let typeParameters = links.typeParameters; + if (typeParameters) { + if (!node.typeArguments || node.typeArguments.length !== typeParameters.length) { + error(node, Diagnostics.Generic_type_0_requires_1_type_argument_s, symbolToString(symbol), typeParameters.length); + return unknownType; + } + let typeArguments = map(node.typeArguments, getTypeFromTypeNode); + let id = getTypeListId(typeArguments); + return links.instantiations[id] || (links.instantiations[id] = instantiateType(type, createTypeMapper(typeParameters, typeArguments))); + } + if (node.typeArguments) { + error(node, Diagnostics.Type_0_is_not_generic, symbolToString(symbol)); + return unknownType; + } + return type; + } + + // Get type from reference to named type that cannot be generic (enum or type parameter) + function getTypeFromNonGenericTypeReference(node: TypeReferenceNode | ExpressionWithTypeArguments, symbol: Symbol): Type { + if (symbol.flags & SymbolFlags.TypeParameter && isTypeParameterReferenceIllegalInConstraint(node, symbol)) { + // TypeScript 1.0 spec (April 2014): 3.4.1 + // Type parameters declared in a particular type parameter list + // may not be referenced in constraints in that type parameter list + // Implementation: such type references are resolved to 'unknown' type that usually denotes error + return unknownType; + } + if (node.typeArguments) { + error(node, Diagnostics.Type_0_is_not_generic, symbolToString(symbol)); + return unknownType; + } + return getDeclaredTypeOfSymbol(symbol); + } + + function getTypeFromTypeReference(node: TypeReferenceNode | ExpressionWithTypeArguments): Type { + let links = getNodeLinks(node); + if (!links.resolvedType) { + // We only support expressions that are simple qualified names. For other expressions this produces undefined. + let typeNameOrExpression = node.kind === SyntaxKind.TypeReference ? (node).typeName : + isSupportedExpressionWithTypeArguments(node) ? (node).expression : + undefined; + let symbol = typeNameOrExpression && resolveEntityName(typeNameOrExpression, SymbolFlags.Type) || unknownSymbol; + let type = symbol === unknownSymbol ? unknownType : + symbol.flags & (SymbolFlags.Class | SymbolFlags.Interface) ? getTypeFromClassOrInterfaceReference(node, symbol) : + symbol.flags & SymbolFlags.TypeAlias ? getTypeFromTypeAliasReference(node, symbol) : + getTypeFromNonGenericTypeReference(node, symbol); + // Cache both the resolved symbol and the resolved type. The resolved symbol is needed in when we check the + // type reference in checkTypeReferenceOrExpressionWithTypeArguments. + links.resolvedSymbol = symbol; + links.resolvedType = type; + } + return links.resolvedType; + } + function getTypeFromTypeQueryNode(node: TypeQueryNode): Type { let links = getNodeLinks(node); if (!links.resolvedType) { @@ -3848,9 +3889,11 @@ module ts { case SyntaxKind.StringLiteral: return getTypeFromStringLiteral(node); case SyntaxKind.TypeReference: - return getTypeFromTypeReferenceOrExpressionWithTypeArguments(node); + return getTypeFromTypeReference(node); + case SyntaxKind.TypePredicate: + return booleanType; case SyntaxKind.ExpressionWithTypeArguments: - return getTypeFromTypeReferenceOrExpressionWithTypeArguments(node); + return getTypeFromTypeReference(node); case SyntaxKind.TypeQuery: return getTypeFromTypeQueryNode(node); case SyntaxKind.ArrayType: @@ -3968,13 +4011,22 @@ module ts { function instantiateSignature(signature: Signature, mapper: TypeMapper, eraseTypeParameters?: boolean): Signature { let freshTypeParameters: TypeParameter[]; + let freshTypePredicate: TypePredicate; if (signature.typeParameters && !eraseTypeParameters) { freshTypeParameters = instantiateList(signature.typeParameters, mapper, instantiateTypeParameter); mapper = combineTypeMappers(createTypeMapper(signature.typeParameters, freshTypeParameters), mapper); } + if (signature.typePredicate) { + freshTypePredicate = { + parameterName: signature.typePredicate.parameterName, + parameterIndex: signature.typePredicate.parameterIndex, + type: instantiateType(signature.typePredicate.type, mapper) + } + } let result = createSignature(signature.declaration, freshTypeParameters, instantiateList(signature.parameters, mapper, instantiateSymbol), signature.resolvedReturnType ? instantiateType(signature.resolvedReturnType, mapper) : undefined, + freshTypePredicate, signature.minArgumentCount, signature.hasRestParameter, signature.hasStringLiterals); result.target = signature; result.mapper = mapper; @@ -4631,6 +4683,44 @@ module ts { } result &= related; } + + if (source.typePredicate && target.typePredicate) { + let hasDifferentParameterIndex = source.typePredicate.parameterIndex !== target.typePredicate.parameterIndex; + let hasDifferentTypes: boolean; + if (hasDifferentParameterIndex || + (hasDifferentTypes = !isTypeIdenticalTo(source.typePredicate.type, target.typePredicate.type))) { + + if (reportErrors) { + let sourceParamText = source.typePredicate.parameterName; + let targetParamText = target.typePredicate.parameterName; + let sourceTypeText = typeToString(source.typePredicate.type); + let targetTypeText = typeToString(target.typePredicate.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; + } + let t = getReturnTypeOfSignature(target); if (t === voidType) return result; let s = getReturnTypeOfSignature(source); @@ -5163,7 +5253,17 @@ module ts { function inferFromSignature(source: Signature, target: Signature) { forEachMatchingParameterType(source, target, inferFromTypes); - inferFromTypes(getReturnTypeOfSignature(source), getReturnTypeOfSignature(target)); + if (source.typePredicate && target.typePredicate) { + if (target.typePredicate.parameterIndex === source.typePredicate.parameterIndex) { + // 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)); + } } function inferFromIndexTypes(source: Type, target: Type, sourceKind: IndexKind, targetKind: IndexKind) { @@ -5547,7 +5647,7 @@ module ts { let targetType: Type; let prototypeProperty = getPropertyOfType(rightType, "prototype"); if (prototypeProperty) { - // Target type is type of the protoype property + // Target type is type of the prototype property let prototypePropertyType = getTypeOfSymbol(prototypeProperty); if (!isTypeAny(prototypePropertyType)) { targetType = prototypePropertyType; @@ -5563,30 +5663,56 @@ module ts { else if (rightType.flags & TypeFlags.Anonymous) { constructSignatures = getSignaturesOfType(rightType, SignatureKind.Construct); } - if (constructSignatures && constructSignatures.length) { targetType = getUnionType(map(constructSignatures, signature => getReturnTypeOfSignature(getErasedSignature(signature)))); } } if (targetType) { - // Narrow to the target type if it's a subtype of the current type - if (isTypeSubtypeOf(targetType, type)) { - return targetType; - } - // If the current type is a union type, remove all constituents that aren't subtypes of the target. - if (type.flags & TypeFlags.Union) { - return getUnionType(filter((type).types, t => isTypeSubtypeOf(t, targetType))); - } + return getNarrowedType(type, targetType); } return type; } + function getNarrowedType(originalType: Type, narrowedTypeCandidate: Type) { + // Narrow to the target type if it's a subtype of the current type + if (isTypeSubtypeOf(narrowedTypeCandidate, originalType)) { + return narrowedTypeCandidate; + } + // If the current type is a union type, remove all constituents that aren't subtypes of the target. + if (originalType.flags & TypeFlags.Union) { + return getUnionType(filter((originalType).types, t => isTypeSubtypeOf(t, narrowedTypeCandidate))); + } + return originalType; + } + + function narrowTypeByTypePredicate(type: Type, expr: CallExpression, assumeTrue: boolean): Type { + if (type.flags & TypeFlags.Any) { + return type; + } + let signature = getResolvedSignature(expr); + + if (signature.typePredicate && + getSymbolAtLocation(expr.arguments[signature.typePredicate.parameterIndex]) === symbol) { + + if (!assumeTrue) { + if (type.flags & TypeFlags.Union) { + return getUnionType(filter((type).types, t => !isTypeSubtypeOf(t, signature.typePredicate.type))); + } + return type; + } + return getNarrowedType(type, signature.typePredicate.type); + } + return type; + } + // Narrow the given type based on the given expression having the assumed boolean value. The returned type // will be a subtype or the same type as the argument. function narrowType(type: Type, expr: Expression, assumeTrue: boolean): Type { switch (expr.kind) { + case SyntaxKind.CallExpression: + return narrowTypeByTypePredicate(type, expr, assumeTrue); case SyntaxKind.ParenthesizedExpression: return narrowType(type, (expr).expression, assumeTrue); case SyntaxKind.BinaryExpression: @@ -8506,6 +8632,34 @@ module ts { node.kind === SyntaxKind.FunctionExpression; } + function getTypePredicateParameterIndex(parameterList: NodeArray, parameter: Identifier): number { + if (parameterList) { + for (let i = 0; i < parameterList.length; i++) { + let param = parameterList[i]; + if (param.name.kind === SyntaxKind.Identifier && + (param.name).text === parameter.text) { + + return i; + } + } + } + return -1; + } + + function isInLegalTypePredicatePosition(node: Node): boolean { + switch (node.parent.kind) { + case SyntaxKind.ArrowFunction: + case SyntaxKind.CallSignature: + case SyntaxKind.FunctionDeclaration: + case SyntaxKind.FunctionExpression: + case SyntaxKind.FunctionType: + case SyntaxKind.MethodDeclaration: + case SyntaxKind.MethodSignature: + return node === (node.parent).type; + } + return false; + } + function checkSignatureDeclaration(node: SignatureDeclaration) { // Grammar checking if (node.kind === SyntaxKind.IndexSignature) { @@ -8523,7 +8677,65 @@ module ts { forEach(node.parameters, checkParameter); if (node.type) { - checkSourceElement(node.type); + if (node.type.kind === SyntaxKind.TypePredicate) { + let typePredicate = getSignatureFromDeclaration(node).typePredicate; + let typePredicateNode = node.type; + if (isInLegalTypePredicatePosition(typePredicateNode)) { + if (typePredicate.parameterIndex >= 0) { + if (node.parameters[typePredicate.parameterIndex].dotDotDotToken) { + error(typePredicateNode.parameterName, + Diagnostics.A_type_predicate_cannot_reference_a_rest_parameter); + } + else { + checkTypeAssignableTo(typePredicate.type, + getTypeAtLocation(node.parameters[typePredicate.parameterIndex]), + typePredicateNode.type); + } + } + else if (typePredicateNode.parameterName) { + let hasReportedError = false; + for (var param of node.parameters) { + if (hasReportedError) { + break; + } + if (param.name.kind === SyntaxKind.ObjectBindingPattern || + param.name.kind === SyntaxKind.ArrayBindingPattern) { + + (function checkBindingPattern(pattern: BindingPattern) { + for (let element of pattern.elements) { + if (element.name.kind === SyntaxKind.Identifier && + (element.name).text === typePredicate.parameterName) { + + error(typePredicateNode.parameterName, + Diagnostics.A_type_predicate_cannot_reference_element_0_in_a_binding_pattern, + typePredicate.parameterName); + hasReportedError = true; + break; + } + else if (element.name.kind === SyntaxKind.ArrayBindingPattern || + element.name.kind === SyntaxKind.ObjectBindingPattern) { + + checkBindingPattern(element.name); + } + } + })(param.name); + } + } + if (!hasReportedError) { + error(typePredicateNode.parameterName, + Diagnostics.Cannot_find_parameter_0, + typePredicate.parameterName); + } + } + } + else { + error(typePredicateNode, + Diagnostics.A_type_predicate_is_only_allowed_in_return_type_position_for_functions_and_methods); + } + } + else { + checkSourceElement(node.type); + } } if (produceDiagnostics) { @@ -8766,13 +8978,15 @@ module ts { // Grammar checking checkGrammarTypeArguments(node, node.typeArguments); - let type = getTypeFromTypeReferenceOrExpressionWithTypeArguments(node); + let type = getTypeFromTypeReference(node); if (type !== unknownType && node.typeArguments) { // Do type argument local checks only if referenced type is successfully resolved + let symbol = getNodeLinks(node).resolvedSymbol; + let typeParameters = symbol.flags & SymbolFlags.TypeAlias ? getSymbolLinks(symbol).typeParameters : (type).target.localTypeParameters; let len = node.typeArguments.length; for (let i = 0; i < len; i++) { checkSourceElement(node.typeArguments[i]); - let constraint = getConstraintOfTypeParameter((type).target.typeParameters[i]); + let constraint = getConstraintOfTypeParameter(typeParameters[i]); if (produceDiagnostics && constraint) { let typeArgument = (type).typeArguments[i]; checkTypeAssignableTo(typeArgument, constraint, node, Diagnostics.Type_0_does_not_satisfy_the_constraint_1); @@ -10085,9 +10299,10 @@ module ts { if (node.expression) { let func = getContainingFunction(node); if (func) { - let returnType = getReturnTypeOfSignature(getSignatureFromDeclaration(func)); + let signature = getSignatureFromDeclaration(func); + let returnType = getReturnTypeOfSignature(signature); let exprType = checkExpressionCached(node.expression); - + if (func.asteriskToken) { // A generator does not need its return expressions checked against its return type. // Instead, the yield expressions are checked against the element type. @@ -10104,7 +10319,7 @@ module 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)) { + else if (func.type || isGetAccessorWithAnnotatatedSetAccessor(func) || signature.typePredicate) { checkTypeAssignableTo(exprType, returnType, node.expression, /*headMessage*/ undefined); } } @@ -11157,6 +11372,12 @@ module ts { } } + function checkTypePredicate(node: TypePredicateNode) { + if(!isInLegalTypePredicatePosition(node)) { + error(node, Diagnostics.A_type_predicate_is_only_allowed_in_return_type_position_for_functions_and_methods); + } + } + function checkSourceElement(node: Node): void { if (!node) return; switch (node.kind) { @@ -11184,6 +11405,8 @@ module ts { return checkAccessorDeclaration(node); case SyntaxKind.TypeReference: return checkTypeReferenceNode(node); + case SyntaxKind.TypePredicate: + return checkTypePredicate(node); case SyntaxKind.TypeQuery: return checkTypeQuery(node); case SyntaxKind.TypeLiteral: @@ -11832,80 +12055,80 @@ module ts { // Emitter support - function isExternalModuleSymbol(symbol: Symbol): boolean { - return symbol.flags & SymbolFlags.ValueModule && symbol.declarations.length === 1 && symbol.declarations[0].kind === SyntaxKind.SourceFile; - } - - function getAliasNameSubstitution(symbol: Symbol, getGeneratedNameForNode: (node: Node) => string): string { - // If this is es6 or higher, just use the name of the export - // no need to qualify it. - if (languageVersion >= ScriptTarget.ES6) { - return undefined; - } - - let node = getDeclarationOfAliasSymbol(symbol); - if (node) { - if (node.kind === SyntaxKind.ImportClause) { - let defaultKeyword: string; - - if (languageVersion === ScriptTarget.ES3) { - defaultKeyword = "[\"default\"]"; - } else { - defaultKeyword = ".default"; - } - return getGeneratedNameForNode(node.parent) + defaultKeyword; - } - if (node.kind === SyntaxKind.ImportSpecifier) { - let moduleName = getGeneratedNameForNode(node.parent.parent.parent); - let propertyName = (node).propertyName || (node).name; - return moduleName + "." + unescapeIdentifier(propertyName.text); - } - } - } - - function getExportNameSubstitution(symbol: Symbol, location: Node, getGeneratedNameForNode: (Node: Node) => string): string { - if (isExternalModuleSymbol(symbol.parent)) { - // 1. If this is es6 or higher, just use the name of the export - // no need to qualify it. - // 2. export mechanism for System modules is different from CJS\AMD - // and it does not need qualifications for exports - if (languageVersion >= ScriptTarget.ES6 || compilerOptions.module === ModuleKind.System) { - return undefined; - } - return "exports." + unescapeIdentifier(symbol.name); - } - let node = location; - let containerSymbol = getParentOfSymbol(symbol); - while (node) { - if ((node.kind === SyntaxKind.ModuleDeclaration || node.kind === SyntaxKind.EnumDeclaration) && getSymbolOfNode(node) === containerSymbol) { - return getGeneratedNameForNode(node) + "." + unescapeIdentifier(symbol.name); - } - node = node.parent; - } - } - - function getExpressionNameSubstitution(node: Identifier, getGeneratedNameForNode: (Node: Node) => string): string { - let symbol = getNodeLinks(node).resolvedSymbol || (isDeclarationName(node) ? getSymbolOfNode(node.parent) : undefined); + // When resolved as an expression identifier, if the given node references an exported entity, return the declaration + // node of the exported entity's container. Otherwise, return undefined. + function getReferencedExportContainer(node: Identifier): SourceFile | ModuleDeclaration | EnumDeclaration { + let symbol = getReferencedValueSymbol(node); if (symbol) { - // Whan an identifier resolves to a parented symbol, it references an exported entity from - // another declaration of the same internal module. - if (symbol.parent) { - return getExportNameSubstitution(symbol, node.parent, getGeneratedNameForNode); + if (symbol.flags & SymbolFlags.ExportValue) { + // If we reference an exported entity within the same module declaration, then whether + // we prefix depends on the kind of entity. SymbolFlags.ExportHasLocal encompasses all the + // kinds that we do NOT prefix. + let exportSymbol = getMergedSymbol(symbol.exportSymbol); + if (exportSymbol.flags & SymbolFlags.ExportHasLocal) { + return undefined; + } + symbol = exportSymbol; } - // If we reference an exported entity within the same module declaration, then whether - // we prefix depends on the kind of entity. SymbolFlags.ExportHasLocal encompasses all the - // kinds that we do NOT prefix. - let exportSymbol = getExportSymbolOfValueSymbolIfExported(symbol); - if (symbol !== exportSymbol && !(exportSymbol.flags & SymbolFlags.ExportHasLocal)) { - return getExportNameSubstitution(exportSymbol, node.parent, getGeneratedNameForNode); - } - // Named imports from ES6 import declarations are rewritten - if (symbol.flags & SymbolFlags.Alias) { - return getAliasNameSubstitution(symbol, getGeneratedNameForNode); + let parentSymbol = getParentOfSymbol(symbol); + if (parentSymbol) { + if (parentSymbol.flags & SymbolFlags.ValueModule && parentSymbol.valueDeclaration.kind === SyntaxKind.SourceFile) { + return parentSymbol.valueDeclaration; + } + for (let n = node.parent; n; n = n.parent) { + if ((n.kind === SyntaxKind.ModuleDeclaration || n.kind === SyntaxKind.EnumDeclaration) && getSymbolOfNode(n) === parentSymbol) { + return n; + } + } } } } + // When resolved as an expression identifier, if the given node references an import, return the declaration of + // that import. Otherwise, return undefined. + function getReferencedImportDeclaration(node: Identifier): Declaration { + let symbol = getReferencedValueSymbol(node); + return symbol && symbol.flags & SymbolFlags.Alias ? getDeclarationOfAliasSymbol(symbol) : undefined; + } + + function isStatementWithLocals(node: Node) { + switch (node.kind) { + case SyntaxKind.Block: + case SyntaxKind.CaseBlock: + case SyntaxKind.ForStatement: + case SyntaxKind.ForInStatement: + case SyntaxKind.ForOfStatement: + return true; + } + return false; + } + + function isNestedRedeclarationSymbol(symbol: Symbol): boolean { + if (symbol.flags & SymbolFlags.BlockScoped) { + let links = getSymbolLinks(symbol); + if (links.isNestedRedeclaration === undefined) { + let container = getEnclosingBlockScopeContainer(symbol.valueDeclaration); + links.isNestedRedeclaration = isStatementWithLocals(container) && + !!resolveName(container.parent, symbol.name, SymbolFlags.Value, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined); + } + return links.isNestedRedeclaration; + } + return false; + } + + // When resolved as an expression identifier, if the given node references a nested block scoped entity with + // a name that hides an existing name, return the declaration of that entity. Otherwise, return undefined. + function getReferencedNestedRedeclaration(node: Identifier): Declaration { + let symbol = getReferencedValueSymbol(node); + return symbol && isNestedRedeclarationSymbol(symbol) ? symbol.valueDeclaration : undefined; + } + + // Return true if the given node is a declaration of a nested block scoped entity with a name that hides an + // existing name. + function isNestedRedeclaration(node: Declaration): boolean { + return isNestedRedeclarationSymbol(getSymbolOfNode(node)); + } + function isValueAliasDeclaration(node: Node): boolean { switch (node.kind) { case SyntaxKind.ImportEqualsDeclaration: @@ -12007,10 +12230,13 @@ module ts { } /** Serializes an EntityName (with substitutions) to an appropriate JS constructor value. Used by the __metadata decorator. */ - function serializeEntityName(node: EntityName, getGeneratedNameForNode: (Node: Node) => string, fallbackPath?: string[]): string { + function serializeEntityName(node: EntityName, fallbackPath?: string[]): string { if (node.kind === SyntaxKind.Identifier) { - var substitution = getExpressionNameSubstitution(node, getGeneratedNameForNode); - var text = substitution || (node).text; + // TODO(ron.buckton): The getExpressionNameSubstitution function has been removed, but calling it + // here has no effect anyway as an identifier in a type name is not an expression. + // var substitution = getExpressionNameSubstitution(node, getGeneratedNameForNode); + // var text = substitution || (node).text; + var text = (node).text; if (fallbackPath) { fallbackPath.push(text); } @@ -12019,8 +12245,8 @@ module ts { } } else { - var left = serializeEntityName((node).left, getGeneratedNameForNode, fallbackPath); - var right = serializeEntityName((node).right, getGeneratedNameForNode, fallbackPath); + var left = serializeEntityName((node).left, fallbackPath); + var right = serializeEntityName((node).right, fallbackPath); if (!fallbackPath) { return left + "." + right; } @@ -12028,7 +12254,7 @@ module ts { } /** Serializes a TypeReferenceNode to an appropriate JS constructor value. Used by the __metadata decorator. */ - function serializeTypeReferenceNode(node: TypeReferenceNode, getGeneratedNameForNode: (Node: Node) => string): string | string[] { + function serializeTypeReferenceNode(node: TypeReferenceNode): string | string[] { // serialization of a TypeReferenceNode uses the following rules: // // * The serialized type of a TypeReference that is `void` is "void 0". @@ -12061,11 +12287,11 @@ module ts { } else if (type === unknownType) { var fallbackPath: string[] = []; - serializeEntityName(node.typeName, getGeneratedNameForNode, fallbackPath); + serializeEntityName(node.typeName, fallbackPath); return fallbackPath; } else if (type.symbol && type.symbol.valueDeclaration) { - return serializeEntityName(node.typeName, getGeneratedNameForNode); + return serializeEntityName(node.typeName); } else if (typeHasCallOrConstructSignatures(type)) { return "Function"; @@ -12075,7 +12301,7 @@ module ts { } /** Serializes a TypeNode to an appropriate JS constructor value. Used by the __metadata decorator. */ - function serializeTypeNode(node: TypeNode | LiteralExpression, getGeneratedNameForNode: (Node: Node) => string): string | string[] { + function serializeTypeNode(node: TypeNode | LiteralExpression): string | string[] { // serialization of a TypeNode uses the following rules: // // * The serialized type of `void` is "void 0" (undefined). @@ -12091,7 +12317,7 @@ module ts { case SyntaxKind.VoidKeyword: return "void 0"; case SyntaxKind.ParenthesizedType: - return serializeTypeNode((node).type, getGeneratedNameForNode); + return serializeTypeNode((node).type); case SyntaxKind.FunctionType: case SyntaxKind.ConstructorType: return "Function"; @@ -12106,7 +12332,7 @@ module ts { case SyntaxKind.NumberKeyword: return "Number"; case SyntaxKind.TypeReference: - return serializeTypeReferenceNode(node, getGeneratedNameForNode); + return serializeTypeReferenceNode(node); case SyntaxKind.TypeQuery: case SyntaxKind.TypeLiteral: case SyntaxKind.UnionType: @@ -12122,7 +12348,7 @@ module ts { } /** Serializes the type of a declaration to an appropriate JS constructor value. Used by the __metadata decorator for a class member. */ - function serializeTypeOfNode(node: Node, getGeneratedNameForNode: (Node: Node) => string): string | string[] { + function serializeTypeOfNode(node: Node): string | string[] { // serialization of the type of a declaration uses the following rules: // // * The serialized type of a ClassDeclaration is "Function" @@ -12135,10 +12361,10 @@ module ts { // For rules on serializing type annotations, see `serializeTypeNode`. switch (node.kind) { case SyntaxKind.ClassDeclaration: return "Function"; - case SyntaxKind.PropertyDeclaration: return serializeTypeNode((node).type, getGeneratedNameForNode); - case SyntaxKind.Parameter: return serializeTypeNode((node).type, getGeneratedNameForNode); - case SyntaxKind.GetAccessor: return serializeTypeNode((node).type, getGeneratedNameForNode); - case SyntaxKind.SetAccessor: return serializeTypeNode(getSetAccessorTypeAnnotationNode(node), getGeneratedNameForNode); + case SyntaxKind.PropertyDeclaration: return serializeTypeNode((node).type); + case SyntaxKind.Parameter: return serializeTypeNode((node).type); + case SyntaxKind.GetAccessor: return serializeTypeNode((node).type); + case SyntaxKind.SetAccessor: return serializeTypeNode(getSetAccessorTypeAnnotationNode(node)); } if (isFunctionLike(node)) { return "Function"; @@ -12147,7 +12373,7 @@ module ts { } /** Serializes the parameter types of a function or the constructor of a class. Used by the __metadata decorator for a method or set accessor. */ - function serializeParameterTypesOfNode(node: Node, getGeneratedNameForNode: (Node: Node) => string): (string | string[])[] { + function serializeParameterTypesOfNode(node: Node): (string | string[])[] { // serialization of parameter types uses the following rules: // // * If the declaration is a class, the parameters of the first constructor with a body are used. @@ -12180,10 +12406,10 @@ module ts { else { parameterType = undefined; } - result[i] = serializeTypeNode(parameterType, getGeneratedNameForNode); + result[i] = serializeTypeNode(parameterType); } else { - result[i] = serializeTypeOfNode(parameters[i], getGeneratedNameForNode); + result[i] = serializeTypeOfNode(parameters[i]); } } return result; @@ -12194,9 +12420,9 @@ module ts { } /** Serializes the return type of function. Used by the __metadata decorator for a method. */ - function serializeReturnTypeOfNode(node: Node, getGeneratedNameForNode: (Node: Node) => string): string | string[] { + function serializeReturnTypeOfNode(node: Node): string | string[] { if (node && isFunctionLike(node)) { - return serializeTypeNode((node).type, getGeneratedNameForNode); + return serializeTypeNode((node).type); } return "void 0"; } @@ -12225,17 +12451,15 @@ module ts { return hasProperty(globals, name); } - function resolvesToSomeValue(location: Node, name: string): boolean { - Debug.assert(!nodeIsSynthesized(location), "resolvesToSomeValue called with a synthesized location"); - return !!resolveName(location, name, SymbolFlags.Value, /*nodeNotFoundMessage*/ undefined, /*nameArg*/ undefined); + function getReferencedValueSymbol(reference: Identifier): Symbol { + return getNodeLinks(reference).resolvedSymbol || + resolveName(reference, reference.text, SymbolFlags.Value | SymbolFlags.ExportValue | SymbolFlags.Alias, + /*nodeNotFoundMessage*/ undefined, /*nameArg*/ undefined); } function getReferencedValueDeclaration(reference: Identifier): Declaration { Debug.assert(!nodeIsSynthesized(reference)); - let symbol = - getNodeLinks(reference).resolvedSymbol || - resolveName(reference, reference.text, SymbolFlags.Value | SymbolFlags.Alias, /*nodeNotFoundMessage*/ undefined, /*nameArg*/ undefined); - + let symbol = getReferencedValueSymbol(reference); return symbol && getExportSymbolOfValueSymbolIfExported(symbol).valueDeclaration; } @@ -12280,7 +12504,10 @@ module ts { function createResolver(): EmitResolver { return { - getExpressionNameSubstitution, + getReferencedExportContainer, + getReferencedImportDeclaration, + getReferencedNestedRedeclaration, + isNestedRedeclaration, isValueAliasDeclaration, hasGlobalName, isReferencedAliasDeclaration, @@ -12294,7 +12521,6 @@ module ts { isSymbolAccessible, isEntityNameVisible, getConstantValue, - resolvesToSomeValue, collectLinkedAliases, getBlockScopedVariableId, getReferencedValueDeclaration, diff --git a/src/compiler/diagnosticInformationMap.generated.ts b/src/compiler/diagnosticInformationMap.generated.ts index f0b46b26dc8..0c8be2d3c54 100644 --- a/src/compiler/diagnosticInformationMap.generated.ts +++ b/src/compiler/diagnosticInformationMap.generated.ts @@ -179,6 +179,13 @@ module ts { Generators_are_not_allowed_in_an_ambient_context: { code: 1221, category: DiagnosticCategory.Error, key: "Generators are not allowed in an ambient context." }, An_overload_signature_cannot_be_declared_as_a_generator: { code: 1222, category: DiagnosticCategory.Error, key: "An overload signature cannot be declared as a generator." }, _0_tag_already_specified: { code: 1223, category: DiagnosticCategory.Error, key: "'{0}' tag already specified." }, + Signature_0_must_have_a_type_predicate: { code: 1224, category: DiagnosticCategory.Error, key: "Signature '{0}' must have a type predicate." }, + Cannot_find_parameter_0: { code: 1225, category: DiagnosticCategory.Error, key: "Cannot find parameter '{0}'." }, + Type_predicate_0_is_not_assignable_to_1: { code: 1226, category: DiagnosticCategory.Error, key: "Type predicate '{0}' is not assignable to '{1}'." }, + Parameter_0_is_not_in_the_same_position_as_parameter_1: { code: 1227, category: DiagnosticCategory.Error, key: "Parameter '{0}' is not in the same position as parameter '{1}'." }, + A_type_predicate_is_only_allowed_in_return_type_position_for_functions_and_methods: { code: 1228, category: DiagnosticCategory.Error, key: "A type predicate is only allowed in return type position for functions and methods." }, + A_type_predicate_cannot_reference_a_rest_parameter: { code: 1229, category: DiagnosticCategory.Error, key: "A type predicate cannot reference a rest parameter." }, + A_type_predicate_cannot_reference_element_0_in_a_binding_pattern: { code: 1230, category: DiagnosticCategory.Error, key: "A type predicate cannot reference element '{0}' in a binding pattern." }, Duplicate_identifier_0: { code: 2300, category: DiagnosticCategory.Error, key: "Duplicate identifier '{0}'." }, Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor: { code: 2301, category: DiagnosticCategory.Error, key: "Initializer of instance member variable '{0}' cannot reference identifier '{1}' declared in the constructor." }, Static_members_cannot_reference_class_type_parameters: { code: 2302, category: DiagnosticCategory.Error, key: "Static members cannot reference class type parameters." }, diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 4e322725946..08273011745 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -703,6 +703,35 @@ "category": "Error", "code": 1223 }, + "Signature '{0}' must have a type predicate.": { + "category": "Error", + "code": 1224 + }, + "Cannot find parameter '{0}'.": { + "category": "Error", + "code": 1225 + }, + "Type predicate '{0}' is not assignable to '{1}'.": { + "category": "Error", + "code": 1226 + }, + "Parameter '{0}' is not in the same position as parameter '{1}'.": { + "category": "Error", + "code": 1227 + }, + "A type predicate is only allowed in return type position for functions and methods.": { + "category": "Error", + "code": 1228 + }, + "A type predicate cannot reference a rest parameter.": { + "category": "Error", + "code": 1229 + }, + "A type predicate cannot reference element '{0}' in a binding pattern.": { + "category": "Error", + "code": 1230 + }, + "Duplicate identifier '{0}'.": { "category": "Error", diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index ddccfad3108..df40d10ddf1 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -125,7 +125,6 @@ var __param = (this && this.__param) || function (paramIndex, decorator) { let generatedNameSet: Map = {}; let nodeToGeneratedName: string[] = []; - let blockScopedVariableToGeneratedName: string[]; let computedPropertyNamesToGeneratedNames: string[]; let extendsEmitted = false; @@ -249,81 +248,44 @@ var __param = (this && this.__param) || function (paramIndex, decorator) { } } - function assignGeneratedName(node: Node, name: string) { - nodeToGeneratedName[getNodeId(node)] = unescapeIdentifier(name); - } - - function generateNameForFunctionOrClassDeclaration(node: Declaration) { - if (!node.name) { - assignGeneratedName(node, makeUniqueName("default")); - } - } - function generateNameForModuleOrEnum(node: ModuleDeclaration | EnumDeclaration) { - if (node.name.kind === SyntaxKind.Identifier) { - let name = node.name.text; - // Use module/enum name itself if it is unique, otherwise make a unique variation - assignGeneratedName(node, isUniqueLocalName(name, node) ? name : makeUniqueName(name)); - } + let name = node.name.text; + // Use module/enum name itself if it is unique, otherwise make a unique variation + return isUniqueLocalName(name, node) ? name : makeUniqueName(name); } function generateNameForImportOrExportDeclaration(node: ImportDeclaration | ExportDeclaration) { let expr = getExternalModuleName(node); let baseName = expr.kind === SyntaxKind.StringLiteral ? escapeIdentifier(makeIdentifierFromModuleName((expr).text)) : "module"; - assignGeneratedName(node, makeUniqueName(baseName)); + return makeUniqueName(baseName); } - function generateNameForImportDeclaration(node: ImportDeclaration) { - if (node.importClause) { - generateNameForImportOrExportDeclaration(node); - } - } - - function generateNameForExportDeclaration(node: ExportDeclaration) { - if (node.moduleSpecifier) { - generateNameForImportOrExportDeclaration(node); - } - } - - function generateNameForExportAssignment(node: ExportAssignment) { - if (node.expression && node.expression.kind !== SyntaxKind.Identifier) { - assignGeneratedName(node, makeUniqueName("default")); - } + function generateNameForExportDefault() { + return makeUniqueName("default"); } function generateNameForNode(node: Node) { switch (node.kind) { + case SyntaxKind.Identifier: + return makeUniqueName((node).text); + case SyntaxKind.ModuleDeclaration: + case SyntaxKind.EnumDeclaration: + return generateNameForModuleOrEnum(node); + case SyntaxKind.ImportDeclaration: + case SyntaxKind.ExportDeclaration: + return generateNameForImportOrExportDeclaration(node); case SyntaxKind.FunctionDeclaration: case SyntaxKind.ClassDeclaration: case SyntaxKind.ClassExpression: - generateNameForFunctionOrClassDeclaration(node); - break; - case SyntaxKind.ModuleDeclaration: - generateNameForModuleOrEnum(node); - generateNameForNode((node).body); - break; - case SyntaxKind.EnumDeclaration: - generateNameForModuleOrEnum(node); - break; - case SyntaxKind.ImportDeclaration: - generateNameForImportDeclaration(node); - break; - case SyntaxKind.ExportDeclaration: - generateNameForExportDeclaration(node); - break; case SyntaxKind.ExportAssignment: - generateNameForExportAssignment(node); - break; + return generateNameForExportDefault(); } } function getGeneratedNameForNode(node: Node) { - let nodeId = getNodeId(node); - if (!nodeToGeneratedName[nodeId]) { - generateNameForNode(node); - } - return nodeToGeneratedName[nodeId]; + let id = getNodeId(node); + return nodeToGeneratedName[id] || (nodeToGeneratedName[id] = unescapeIdentifier(generateNameForNode(node))); } function initializeEmitterWithSourceMaps() { @@ -687,19 +649,19 @@ var __param = (this && this.__param) || function (paramIndex, decorator) { sourceMapDir = getDirectoryPath(normalizePath(jsFilePath)); } - function emitNodeWithSourceMap(node: Node, allowGeneratedIdentifiers?: boolean) { + function emitNodeWithSourceMap(node: Node) { if (node) { if (nodeIsSynthesized(node)) { - return emitNodeWithoutSourceMap(node, /*allowGeneratedIdentifiers*/ false); + return emitNodeWithoutSourceMap(node); } if (node.kind != SyntaxKind.SourceFile) { recordEmitNodeStartSpan(node); - emitNodeWithoutSourceMap(node, allowGeneratedIdentifiers); + emitNodeWithoutSourceMap(node); recordEmitNodeEndSpan(node); } else { recordNewSourceFileStart(node); - emitNodeWithoutSourceMap(node, /*allowGeneratedIdentifiers*/ false); + emitNodeWithoutSourceMap(node); } } } @@ -1201,80 +1163,129 @@ var __param = (this && this.__param) || function (paramIndex, decorator) { } } - function isNotExpressionIdentifier(node: Identifier) { + function isExpressionIdentifier(node: Node): boolean { let parent = node.parent; switch (parent.kind) { - case SyntaxKind.Parameter: - case SyntaxKind.VariableDeclaration: - case SyntaxKind.BindingElement: - case SyntaxKind.PropertyDeclaration: - case SyntaxKind.PropertySignature: - case SyntaxKind.PropertyAssignment: - case SyntaxKind.ShorthandPropertyAssignment: - case SyntaxKind.EnumMember: - case SyntaxKind.MethodDeclaration: - case SyntaxKind.MethodSignature: - case SyntaxKind.FunctionDeclaration: - case SyntaxKind.GetAccessor: - case SyntaxKind.SetAccessor: - case SyntaxKind.FunctionExpression: - case SyntaxKind.ClassDeclaration: - case SyntaxKind.InterfaceDeclaration: - case SyntaxKind.EnumDeclaration: - case SyntaxKind.ModuleDeclaration: - case SyntaxKind.ImportEqualsDeclaration: - case SyntaxKind.ImportClause: - case SyntaxKind.NamespaceImport: - return (parent).name === node; - case SyntaxKind.ImportSpecifier: - case SyntaxKind.ExportSpecifier: - return (parent).name === node || (parent).propertyName === node; - case SyntaxKind.BreakStatement: - case SyntaxKind.ContinueStatement: + case SyntaxKind.ArrayLiteralExpression: + case SyntaxKind.BinaryExpression: + case SyntaxKind.CallExpression: + case SyntaxKind.CaseClause: + case SyntaxKind.ComputedPropertyName: + case SyntaxKind.ConditionalExpression: + case SyntaxKind.Decorator: + case SyntaxKind.DeleteExpression: + case SyntaxKind.DoStatement: + case SyntaxKind.ElementAccessExpression: case SyntaxKind.ExportAssignment: - return false; - case SyntaxKind.LabeledStatement: - return (node.parent).label === node; + case SyntaxKind.ExpressionStatement: + case SyntaxKind.ExpressionWithTypeArguments: + case SyntaxKind.ForStatement: + case SyntaxKind.ForInStatement: + case SyntaxKind.ForOfStatement: + case SyntaxKind.IfStatement: + case SyntaxKind.NewExpression: + case SyntaxKind.ParenthesizedExpression: + case SyntaxKind.PostfixUnaryExpression: + case SyntaxKind.PrefixUnaryExpression: + case SyntaxKind.ReturnStatement: + case SyntaxKind.ShorthandPropertyAssignment: + case SyntaxKind.SpreadElementExpression: + case SyntaxKind.SwitchStatement: + case SyntaxKind.TaggedTemplateExpression: + case SyntaxKind.TemplateSpan: + case SyntaxKind.ThrowStatement: + case SyntaxKind.TypeAssertionExpression: + case SyntaxKind.TypeOfExpression: + case SyntaxKind.VoidExpression: + case SyntaxKind.WhileStatement: + case SyntaxKind.WithStatement: + case SyntaxKind.YieldExpression: + return true; + case SyntaxKind.BindingElement: + case SyntaxKind.EnumMember: + case SyntaxKind.Parameter: + case SyntaxKind.PropertyAssignment: + case SyntaxKind.PropertyDeclaration: + case SyntaxKind.VariableDeclaration: + return (parent).initializer === node; + case SyntaxKind.PropertyAccessExpression: + return (parent).expression === node; + case SyntaxKind.ArrowFunction: + case SyntaxKind.FunctionExpression: + return (parent).body === node; + case SyntaxKind.ImportEqualsDeclaration: + return (parent).moduleReference === node; + case SyntaxKind.QualifiedName: + return (parent).left === node; } + return false; } function emitExpressionIdentifier(node: Identifier) { - let substitution = resolver.getExpressionNameSubstitution(node, getGeneratedNameForNode); - if (substitution) { - write(substitution); + let container = resolver.getReferencedExportContainer(node); + if (container) { + if (container.kind === SyntaxKind.SourceFile) { + // Identifier references module export + if (languageVersion < ScriptTarget.ES6 && compilerOptions.module !== ModuleKind.System) { + write("exports."); + } + } + else { + // Identifier references namespace export + write(getGeneratedNameForNode(container)); + write("."); + } } - else { - writeTextOfNode(currentSourceFile, node); - } - } - - function getGeneratedNameForIdentifier(node: Identifier): string { - if (nodeIsSynthesized(node) || !blockScopedVariableToGeneratedName) { - return undefined; - } - - var variableId = resolver.getBlockScopedVariableId(node) - if (variableId === undefined) { - return undefined; - } - - return blockScopedVariableToGeneratedName[variableId]; - } - - function emitIdentifier(node: Identifier, allowGeneratedIdentifiers: boolean) { - if (allowGeneratedIdentifiers) { - let generatedName = getGeneratedNameForIdentifier(node); - if (generatedName) { - write(generatedName); + else if (languageVersion < ScriptTarget.ES6) { + let declaration = resolver.getReferencedImportDeclaration(node); + if (declaration) { + if (declaration.kind === SyntaxKind.ImportClause) { + // Identifier references default import + write(getGeneratedNameForNode(declaration.parent)); + write(languageVersion === ScriptTarget.ES3 ? '["default"]' : ".default"); + return; + } + else if (declaration.kind === SyntaxKind.ImportSpecifier) { + // Identifier references named import + write(getGeneratedNameForNode(declaration.parent.parent.parent)); + write("."); + writeTextOfNode(currentSourceFile, (declaration).propertyName || (declaration).name); + return; + } + } + declaration = resolver.getReferencedNestedRedeclaration(node); + if (declaration) { + write(getGeneratedNameForNode(declaration.name)); return; } } + writeTextOfNode(currentSourceFile, node); + } + + function isNameOfNestedRedeclaration(node: Identifier) { + if (languageVersion < ScriptTarget.ES6) { + let parent = node.parent; + switch (parent.kind) { + case SyntaxKind.BindingElement: + case SyntaxKind.ClassDeclaration: + case SyntaxKind.EnumDeclaration: + case SyntaxKind.VariableDeclaration: + return (parent).name === node && resolver.isNestedRedeclaration(parent); + } + } + return false; + } + + function emitIdentifier(node: Identifier) { if (!node.parent) { write(node.text); } - else if (!isNotExpressionIdentifier(node)) { + else if (isExpressionIdentifier(node)) { emitExpressionIdentifier(node); } + else if (isNameOfNestedRedeclaration(node)) { + write(getGeneratedNameForNode(node)); + } else { writeTextOfNode(currentSourceFile, node); } @@ -1320,7 +1331,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) { function emitBindingElement(node: BindingElement) { if (node.propertyName) { - emit(node.propertyName, /*allowGeneratedIdentifiers*/ false); + emit(node.propertyName); write(": "); } if (node.dotDotDotToken) { @@ -1682,7 +1693,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) { write("*"); } - emit(node.name, /*allowGeneratedIdentifiers*/ false); + emit(node.name); if (languageVersion < ScriptTarget.ES6) { write(": function "); } @@ -1690,40 +1701,34 @@ var __param = (this && this.__param) || function (paramIndex, decorator) { } function emitPropertyAssignment(node: PropertyDeclaration) { - emit(node.name, /*allowGeneratedIdentifiers*/ false); + emit(node.name); write(": "); emit(node.initializer); } + // Return true if identifier resolves to an exported member of a namespace + function isNamespaceExportReference(node: Identifier) { + let container = resolver.getReferencedExportContainer(node); + return container && container.kind !== SyntaxKind.SourceFile; + } + function emitShorthandPropertyAssignment(node: ShorthandPropertyAssignment) { - emit(node.name, /*allowGeneratedIdentifiers*/ false); - // If short-hand property has a prefix, then regardless of the target version, we will emit it as normal property assignment. For example: - // module m { - // export let y; - // } - // module m { - // export let obj = { y }; - // } - // The short-hand property in obj need to emit as such ... = { y : m.y } regardless of the TargetScript version - if (languageVersion < ScriptTarget.ES6) { + // The name property of a short-hand property assignment is considered an expression position, so here + // we manually emit the identifier to avoid rewriting. + writeTextOfNode(currentSourceFile, node.name); + // If emitting pre-ES6 code, or if the name requires rewriting when resolved as an expression identifier, + // we emit a normal property assignment. For example: + // module m { + // export let y; + // } + // module m { + // let obj = { y }; + // } + // Here we need to emit obj = { y : m.y } regardless of the output target. + if (languageVersion < ScriptTarget.ES6 || isNamespaceExportReference(node.name)) { // Emit identifier as an identifier write(": "); - var generatedName = getGeneratedNameForIdentifier(node.name); - if (generatedName) { - write(generatedName); - } - else { - // Even though this is stored as identifier treat it as an expression - // Short-hand, { x }, is equivalent of normal form { x: x } - emitExpressionIdentifier(node.name); - } - } - else if (resolver.getExpressionNameSubstitution(node.name, getGeneratedNameForNode)) { - // Emit identifier as an identifier - write(": "); - // Even though this is stored as identifier treat it as an expression - // Short-hand, { x }, is equivalent of normal form { x: x } - emitExpressionIdentifier(node.name); + emit(node.name); } } @@ -1776,7 +1781,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) { let indentedBeforeDot = indentIfOnDifferentLines(node, node.expression, node.dotToken); write("."); let indentedAfterDot = indentIfOnDifferentLines(node, node.dotToken, node.name); - emit(node.name, /*allowGeneratedIdentifiers*/ false); + emit(node.name); decreaseIndentIf(indentedBeforeDot, indentedAfterDot); } @@ -1898,23 +1903,21 @@ var __param = (this && this.__param) || function (paramIndex, decorator) { function emitNewExpression(node: NewExpression) { write("new "); - // Spread operator logic can be supported in new expressions in ES5 using a combination + // Spread operator logic is supported in new expressions in ES5 using a combination // of Function.prototype.bind() and Function.prototype.apply(). // // Example: // - // var arguments = [1, 2, 3, 4, 5]; - // new Array(...arguments); + // var args = [1, 2, 3, 4, 5]; + // new Array(...args); // - // Could be transpiled into ES5: + // is compiled into the following ES5: // - // var arguments = [1, 2, 3, 4, 5]; - // new (Array.bind.apply(Array, [void 0].concat(arguments))); + // var args = [1, 2, 3, 4, 5]; + // new (Array.bind.apply(Array, [void 0].concat(args))); // - // `[void 0]` is the first argument which represents `thisArg` to the bind method above. - // And `thisArg` will be set to the return value of the constructor when instantiated - // with the new operator — regardless of any value we set `thisArg` to. Thus, we set it - // to an undefined, `void 0`. + // The 'thisArg' to 'bind' is ignored when invoking the result of 'bind' with 'new', + // Thus, we set it to undefined ('void 0'). if (languageVersion === ScriptTarget.ES5 && node.arguments && hasSpreadElement(node.arguments)) { @@ -2781,8 +2784,6 @@ var __param = (this && this.__param) || function (paramIndex, decorator) { write(", "); } - renameNonTopLevelLetAndConst(name); - const isVariableDeclarationOrBindingElement = name.parent && (name.parent.kind === SyntaxKind.VariableDeclaration || name.parent.kind === SyntaxKind.BindingElement); @@ -2850,11 +2851,14 @@ var __param = (this && this.__param) || function (paramIndex, decorator) { } function createPropertyAccessForDestructuringProperty(object: Expression, propName: Identifier | LiteralExpression): Expression { - if (propName.kind !== SyntaxKind.Identifier) { - return createElementAccessExpression(object, propName); + // We create a synthetic copy of the identifier in order to avoid the rewriting that might + // otherwise occur when the identifier is emitted. + let syntheticName = createSynthesizedNode(propName.kind); + syntheticName.text = propName.text; + if (syntheticName.kind !== SyntaxKind.Identifier) { + return createElementAccessExpression(object, syntheticName); } - - return createPropertyAccessExpression(object, propName); + return createPropertyAccessExpression(object, syntheticName); } function createSliceCall(value: Expression, sliceIndex: number): CallExpression { @@ -2876,8 +2880,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) { } for (let p of properties) { if (p.kind === SyntaxKind.PropertyAssignment || p.kind === SyntaxKind.ShorthandPropertyAssignment) { - // TODO(andersh): Computed property support - let propName = ((p).name); + let propName = (p).name; emitDestructuringAssignment((p).initializer || propName, createPropertyAccessForDestructuringProperty(value, propName)); } } @@ -2991,8 +2994,6 @@ var __param = (this && this.__param) || function (paramIndex, decorator) { } } else { - renameNonTopLevelLetAndConst(node.name); - let initializer = node.initializer; if (!initializer && languageVersion < ScriptTarget.ES6) { @@ -3052,54 +3053,6 @@ var __param = (this && this.__param) || function (paramIndex, decorator) { return getCombinedNodeFlags(node.parent); } - function renameNonTopLevelLetAndConst(node: Node): void { - // do not rename if - // - language version is ES6+ - // - node is synthesized - // - node is not identifier (can happen when tree is malformed) - // - node is definitely not name of variable declaration. - // it still can be part of parameter declaration, this check will be done next - if (languageVersion >= ScriptTarget.ES6 || - nodeIsSynthesized(node) || - node.kind !== SyntaxKind.Identifier || - (node.parent.kind !== SyntaxKind.VariableDeclaration && node.parent.kind !== SyntaxKind.BindingElement)) { - return; - } - - let combinedFlags = getCombinedFlagsForIdentifier(node); - if (((combinedFlags & NodeFlags.BlockScoped) === 0) || combinedFlags & NodeFlags.Export) { - // do not rename exported or non-block scoped variables - return; - } - - // here it is known that node is a block scoped variable - let list = getAncestor(node, SyntaxKind.VariableDeclarationList); - if (list.parent.kind === SyntaxKind.VariableStatement) { - let isSourceFileLevelBinding = list.parent.parent.kind === SyntaxKind.SourceFile; - let isModuleLevelBinding = list.parent.parent.kind === SyntaxKind.ModuleBlock; - let isFunctionLevelBinding = - list.parent.parent.kind === SyntaxKind.Block && isFunctionLike(list.parent.parent.parent); - if (isSourceFileLevelBinding || isModuleLevelBinding || isFunctionLevelBinding) { - return; - } - } - - let blockScopeContainer = getEnclosingBlockScopeContainer(node); - let parent = blockScopeContainer.kind === SyntaxKind.SourceFile - ? blockScopeContainer - : blockScopeContainer.parent; - - if (resolver.resolvesToSomeValue(parent, (node).text)) { - let variableId = resolver.getBlockScopedVariableId(node); - if (!blockScopedVariableToGeneratedName) { - blockScopedVariableToGeneratedName = []; - } - - let generatedName = makeUniqueName((node).text); - blockScopedVariableToGeneratedName[variableId] = generatedName; - } - } - function isES6ExportedDeclaration(node: Node) { return !!(node.flags & NodeFlags.Export) && languageVersion >= ScriptTarget.ES6 && @@ -3263,7 +3216,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) { function emitAccessor(node: AccessorDeclaration) { write(node.kind === SyntaxKind.GetAccessor ? "get " : "set "); - emit(node.name, /*allowGeneratedIdentifiers*/ false); + emit(node.name); emitSignatureAndBody(node); } @@ -4366,7 +4319,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) { let argumentsWritten = 0; if (compilerOptions.emitDecoratorMetadata) { if (shouldEmitTypeMetadata(node)) { - var serializedType = resolver.serializeTypeOfNode(node, getGeneratedNameForNode); + var serializedType = resolver.serializeTypeOfNode(node); if (serializedType) { if (writeComma) { write(", "); @@ -4379,7 +4332,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) { } } if (shouldEmitParamTypesMetadata(node)) { - var serializedTypes = resolver.serializeParameterTypesOfNode(node, getGeneratedNameForNode); + var serializedTypes = resolver.serializeParameterTypesOfNode(node); if (serializedTypes) { if (writeComma || argumentsWritten) { write(", "); @@ -4397,7 +4350,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) { } } if (shouldEmitReturnTypeMetadata(node)) { - var serializedType = resolver.serializeReturnTypeOfNode(node, getGeneratedNameForNode); + var serializedType = resolver.serializeReturnTypeOfNode(node); if (serializedType) { if (writeComma || argumentsWritten) { write(", "); @@ -4995,13 +4948,16 @@ var __param = (this && this.__param) || function (paramIndex, decorator) { } } - function getLocalNameForExternalImport(importNode: ImportDeclaration | ExportDeclaration | ImportEqualsDeclaration): string { - let namespaceDeclaration = getNamespaceDeclarationNode(importNode); - if (namespaceDeclaration && !isDefaultImport(importNode)) { + function getLocalNameForExternalImport(node: ImportDeclaration | ExportDeclaration | ImportEqualsDeclaration): string { + let namespaceDeclaration = getNamespaceDeclarationNode(node); + if (namespaceDeclaration && !isDefaultImport(node)) { return getSourceTextOfNodeFromSourceFile(currentSourceFile, namespaceDeclaration.name); } - else { - return getGeneratedNameForNode(importNode); + if (node.kind === SyntaxKind.ImportDeclaration && (node).importClause) { + return getGeneratedNameForNode(node); + } + if (node.kind === SyntaxKind.ExportDeclaration && (node).moduleSpecifier) { + return getGeneratedNameForNode(node); } } @@ -5389,10 +5345,10 @@ var __param = (this && this.__param) || function (paramIndex, decorator) { emitSetters(exportStarFunction); writeLine(); emitExecute(node, startIndex); - emitTempDeclarations(/*newLine*/ true) decreaseIndent(); writeLine(); write("}"); // return + emitTempDeclarations(/*newLine*/ true) } function emitSetters(exportStarFunction: string) { @@ -5790,7 +5746,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) { emitLeadingComments(node.endOfFileToken); } - function emitNodeWithoutSourceMap(node: Node, allowGeneratedIdentifiers?: boolean): void { + function emitNodeWithoutSourceMap(node: Node): void { if (!node) { return; } @@ -5804,7 +5760,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) { emitLeadingComments(node); } - emitJavaScriptWorker(node, allowGeneratedIdentifiers); + emitJavaScriptWorker(node); if (emitComments) { emitTrailingComments(node); @@ -5854,11 +5810,11 @@ var __param = (this && this.__param) || function (paramIndex, decorator) { return true; } - function emitJavaScriptWorker(node: Node, allowGeneratedIdentifiers: boolean = true) { + function emitJavaScriptWorker(node: Node) { // Check if the node can be emitted regardless of the ScriptTarget switch (node.kind) { case SyntaxKind.Identifier: - return emitIdentifier(node, allowGeneratedIdentifiers); + return emitIdentifier(node); case SyntaxKind.Parameter: return emitParameter(node); case SyntaxKind.MethodDeclaration: diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 4d619447513..394bb0f401d 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -103,6 +103,9 @@ module ts { case SyntaxKind.TypeReference: return visitNode(cbNode, (node).typeName) || visitNodes(cbNodes, (node).typeArguments); + case SyntaxKind.TypePredicate: + return visitNode(cbNode, (node).parameterName) || + visitNode(cbNode, (node).type); case SyntaxKind.TypeQuery: return visitNode(cbNode, (node).exprName); case SyntaxKind.TypeLiteral: @@ -255,6 +258,7 @@ module ts { return visitNodes(cbNodes, node.decorators) || visitNodes(cbNodes, node.modifiers) || visitNode(cbNode, (node).name) || + visitNodes(cbNodes, (node).typeParameters) || visitNode(cbNode, (node).type); case SyntaxKind.EnumDeclaration: return visitNodes(cbNodes, node.decorators) || @@ -1897,9 +1901,17 @@ module ts { // TYPES - function parseTypeReference(): TypeReferenceNode { - let node = createNode(SyntaxKind.TypeReference); - node.typeName = parseEntityName(/*allowReservedWords*/ false, Diagnostics.Type_expected); + function parseTypeReferenceOrTypePredicate(): TypeReferenceNode | TypePredicateNode { + let typeName = parseEntityName(/*allowReservedWords*/ false, Diagnostics.Type_expected); + if (typeName.kind === SyntaxKind.Identifier && token === SyntaxKind.IsKeyword && !scanner.hasPrecedingLineBreak()) { + nextToken(); + let node = createNode(SyntaxKind.TypePredicate, typeName.pos); + node.parameterName = typeName; + node.type = parseType(); + return finishNode(node); + } + let node = createNode(SyntaxKind.TypeReference, typeName.pos); + node.typeName = typeName; if (!scanner.hasPrecedingLineBreak() && token === SyntaxKind.LessThanToken) { node.typeArguments = parseBracketedList(ParsingContext.TypeArguments, parseType, SyntaxKind.LessThanToken, SyntaxKind.GreaterThanToken); } @@ -2336,7 +2348,7 @@ module ts { case SyntaxKind.SymbolKeyword: // If these are followed by a dot, then parse these out as a dotted type reference instead. let node = tryParse(parseKeywordAndNoDot); - return node || parseTypeReference(); + return node || parseTypeReferenceOrTypePredicate(); case SyntaxKind.VoidKeyword: return parseTokenNode(); case SyntaxKind.TypeOfKeyword: @@ -2348,7 +2360,7 @@ module ts { case SyntaxKind.OpenParenToken: return parseParenthesizedType(); default: - return parseTypeReference(); + return parseTypeReferenceOrTypePredicate(); } } @@ -4580,6 +4592,7 @@ module ts { setModifiers(node, modifiers); parseExpected(SyntaxKind.TypeKeyword); node.name = parseIdentifier(); + node.typeParameters = parseTypeParameters(); parseExpected(SyntaxKind.EqualsToken); node.type = parseType(); parseSemicolon(); diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts index 89ac837ab24..d7e65dff81c 100644 --- a/src/compiler/scanner.ts +++ b/src/compiler/scanner.ts @@ -72,6 +72,7 @@ module ts { "in": SyntaxKind.InKeyword, "instanceof": SyntaxKind.InstanceOfKeyword, "interface": SyntaxKind.InterfaceKeyword, + "is": SyntaxKind.IsKeyword, "let": SyntaxKind.LetKeyword, "module": SyntaxKind.ModuleKeyword, "namespace": SyntaxKind.NamespaceKeyword, diff --git a/src/compiler/types.ts b/src/compiler/types.ts index e8954c282cb..75eb99d55ac 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -145,6 +145,7 @@ module ts { ConstructorKeyword, DeclareKeyword, GetKeyword, + IsKeyword, ModuleKeyword, NamespaceKeyword, RequireKeyword, @@ -177,6 +178,7 @@ module ts { ConstructSignature, IndexSignature, // Type + TypePredicate, TypeReference, FunctionType, ConstructorType, @@ -614,6 +616,11 @@ module ts { typeArguments?: NodeArray; } + export interface TypePredicateNode extends TypeNode { + parameterName: Identifier; + type: TypeNode; + } + export interface TypeQueryNode extends TypeNode { exprName: EntityName; } @@ -939,6 +946,7 @@ module ts { export interface TypeAliasDeclaration extends Declaration, Statement { name: Identifier; + typeParameters?: NodeArray; type: TypeNode; } @@ -1394,6 +1402,12 @@ module ts { NotAccessible, CannotBeNamed } + + export interface TypePredicate { + parameterName: string; + parameterIndex: number; + type: Type; + } /* @internal */ export type AnyImportSyntax = ImportDeclaration | ImportEqualsDeclaration; @@ -1414,7 +1428,10 @@ module ts { /* @internal */ export interface EmitResolver { hasGlobalName(name: string): boolean; - getExpressionNameSubstitution(node: Identifier, getGeneratedNameForNode: (node: Node) => string): string; + getReferencedExportContainer(node: Identifier): SourceFile | ModuleDeclaration | EnumDeclaration; + getReferencedImportDeclaration(node: Identifier): Declaration; + getReferencedNestedRedeclaration(node: Identifier): Declaration; + isNestedRedeclaration(node: Declaration): boolean; isValueAliasDeclaration(node: Node): boolean; isReferencedAliasDeclaration(node: Node, checkChildren?: boolean): boolean; isTopLevelValueImportEqualsWithEntityName(node: ImportEqualsDeclaration): boolean; @@ -1429,12 +1446,11 @@ module ts { isEntityNameVisible(entityName: EntityName | Expression, enclosingDeclaration: Node): SymbolVisibilityResult; // Returns the constant value this property access resolves to, or 'undefined' for a non-constant getConstantValue(node: EnumMember | PropertyAccessExpression | ElementAccessExpression): number; - resolvesToSomeValue(location: Node, name: string): boolean; getBlockScopedVariableId(node: Identifier): number; getReferencedValueDeclaration(reference: Identifier): Declaration; - serializeTypeOfNode(node: Node, getGeneratedNameForNode: (Node: Node) => string): string | string[]; - serializeParameterTypesOfNode(node: Node, getGeneratedNameForNode: (Node: Node) => string): (string | string[])[]; - serializeReturnTypeOfNode(node: Node, getGeneratedNameForNode: (Node: Node) => string): string | string[]; + serializeTypeOfNode(node: Node): string | string[]; + serializeParameterTypesOfNode(node: Node): (string | string[])[]; + serializeReturnTypeOfNode(node: Node): string | string[]; } export const enum SymbolFlags { @@ -1511,6 +1527,8 @@ module ts { HasExports = Class | Enum | Module, HasMembers = Class | Interface | TypeLiteral | ObjectLiteral, + BlockScoped = BlockScopedVariable | Class | Enum, + PropertyOrAccessor = Property | Accessor, Export = ExportNamespace | ExportType | ExportValue, } @@ -1534,12 +1552,15 @@ module ts { export interface SymbolLinks { target?: Symbol; // Resolved (non-alias) target of an alias type?: Type; // Type of value symbol - declaredType?: Type; // Type of class, interface, enum, or type parameter + declaredType?: Type; // Type of class, interface, enum, type alias, or type parameter + typeParameters?: TypeParameter[]; // Type parameters of type alias (undefined if non-generic) + instantiations?: Map; // Instantiations of generic type alias (undefined if non-generic) mapper?: TypeMapper; // Type mapper for instantiation alias referenced?: boolean; // True if alias symbol has been referenced as a value unionType?: UnionType; // Containing union type for union property resolvedExports?: SymbolTable; // Resolved exports of module exportsChecked?: boolean; // True if exports of external module have been checked + isNestedRedeclaration?: boolean; // True if symbol is block scoped redeclaration } /* @internal */ @@ -1601,12 +1622,12 @@ module ts { Union = 0x00004000, // Union Anonymous = 0x00008000, // Anonymous Instantiated = 0x00010000, // Instantiated anonymous type - /* @internal */ + /* @internal */ FromSignature = 0x00020000, // Created for signature assignment check ObjectLiteral = 0x00040000, // Originates in an object literal - /* @internal */ + /* @internal */ ContainsUndefinedOrNull = 0x00080000, // Type is or contains Undefined or Null type - /* @internal */ + /* @internal */ ContainsObjectLiteral = 0x00100000, // Type is or contains object literal type ESSymbol = 0x00200000, // Type of symbol primitive introduced in ES6 @@ -1722,6 +1743,7 @@ module ts { declaration: SignatureDeclaration; // Originating declaration typeParameters: TypeParameter[]; // Type parameters (undefined if non-generic) parameters: Symbol[]; // Parameters + typePredicate?: TypePredicate; // Type predicate /* @internal */ resolvedReturnType: Type; // Resolved return type /* @internal */ diff --git a/src/lib/dom.es6.d.ts b/src/lib/dom.es6.d.ts new file mode 100644 index 00000000000..8702201bb9e --- /dev/null +++ b/src/lib/dom.es6.d.ts @@ -0,0 +1,11 @@ +interface DOMTokenList { + [Symbol.iterator](): IterableIterator; +} + +interface NodeList { + [Symbol.iterator](): IterableIterator +} + +interface NodeListOf { + [Symbol.iterator](): IterableIterator +} \ No newline at end of file diff --git a/tests/baselines/reference/APISample_linter.js b/tests/baselines/reference/APISample_linter.js index cd2df23ffbf..9b2675535f2 100644 --- a/tests/baselines/reference/APISample_linter.js +++ b/tests/baselines/reference/APISample_linter.js @@ -75,26 +75,26 @@ function delint(sourceFile) { delintNode(sourceFile); function delintNode(node) { switch (node.kind) { - case 187 /* ForStatement */: - case 188 /* ForInStatement */: - case 186 /* WhileStatement */: - case 185 /* DoStatement */: - if (node.statement.kind !== 180 /* Block */) { + case 189 /* ForStatement */: + case 190 /* ForInStatement */: + case 188 /* WhileStatement */: + case 187 /* DoStatement */: + if (node.statement.kind !== 182 /* Block */) { report(node, "A looping statement's contents should be wrapped in a block body."); } break; - case 184 /* IfStatement */: + case 186 /* IfStatement */: var ifStatement = node; - if (ifStatement.thenStatement.kind !== 180 /* Block */) { + if (ifStatement.thenStatement.kind !== 182 /* Block */) { report(ifStatement.thenStatement, "An if statement's contents should be wrapped in a block body."); } if (ifStatement.elseStatement && - ifStatement.elseStatement.kind !== 180 /* Block */ && - ifStatement.elseStatement.kind !== 184 /* IfStatement */) { + ifStatement.elseStatement.kind !== 182 /* Block */ && + ifStatement.elseStatement.kind !== 186 /* IfStatement */) { report(ifStatement.elseStatement, "An else statement's contents should be wrapped in a block body."); } break; - case 170 /* BinaryExpression */: + case 172 /* BinaryExpression */: var op = node.operatorToken.kind; if (op === 28 /* EqualsEqualsToken */ || op == 29 /* ExclamationEqualsToken */) { report(node, "Use '===' and '!=='."); diff --git a/tests/baselines/reference/ES5For-of17.js b/tests/baselines/reference/ES5For-of17.js index 50064d82932..fb3a02fd0e9 100644 --- a/tests/baselines/reference/ES5For-of17.js +++ b/tests/baselines/reference/ES5For-of17.js @@ -11,7 +11,7 @@ for (let v of []) { for (var _i = 0, _a = []; _i < _a.length; _i++) { var v = _a[_i]; v; - for (var _b = 0, _c = [v]; _b < _c.length; _b++) { + for (var _b = 0, _c = [v_1]; _b < _c.length; _b++) { var v_1 = _c[_b]; var x = v_1; v_1++; diff --git a/tests/baselines/reference/ES5For-of20.js b/tests/baselines/reference/ES5For-of20.js index c6376ab05d7..d21ab73f8b5 100644 --- a/tests/baselines/reference/ES5For-of20.js +++ b/tests/baselines/reference/ES5For-of20.js @@ -10,7 +10,7 @@ for (let v of []) { for (var _i = 0, _a = []; _i < _a.length; _i++) { var v = _a[_i]; var v_1; - for (var _b = 0, _c = [v]; _b < _c.length; _b++) { + for (var _b = 0, _c = [v_2]; _b < _c.length; _b++) { var v_2 = _c[_b]; var v_3; } diff --git a/tests/baselines/reference/classDeclarationBlockScoping1.js b/tests/baselines/reference/classDeclarationBlockScoping1.js index 717c2f788c3..4c7f9d8e24a 100644 --- a/tests/baselines/reference/classDeclarationBlockScoping1.js +++ b/tests/baselines/reference/classDeclarationBlockScoping1.js @@ -14,9 +14,9 @@ var C = (function () { return C; })(); { - var C = (function () { - function C() { + var C_1 = (function () { + function C_1() { } - return C; + return C_1; })(); } diff --git a/tests/baselines/reference/classDeclarationBlockScoping2.js b/tests/baselines/reference/classDeclarationBlockScoping2.js index 9e468077119..57001d0d287 100644 --- a/tests/baselines/reference/classDeclarationBlockScoping2.js +++ b/tests/baselines/reference/classDeclarationBlockScoping2.js @@ -18,12 +18,12 @@ function f() { })(); var c1 = C; { - var C = (function () { - function C() { + var C_1 = (function () { + function C_1() { } - return C; + return C_1; })(); - var c2 = C; + var c2 = C_1; } return C === c1; } diff --git a/tests/baselines/reference/exportsAndImports3-amd.js b/tests/baselines/reference/exportsAndImports3-amd.js index e816dec9f62..3a33b12c7ff 100644 --- a/tests/baselines/reference/exportsAndImports3-amd.js +++ b/tests/baselines/reference/exportsAndImports3-amd.js @@ -40,25 +40,25 @@ define(["require", "exports"], function (require, exports) { exports.v1 = exports.v; function f() { } exports.f = f; - exports.f1 = exports.f; + exports.f1 = f; var C = (function () { function C() { } return C; })(); exports.C = C; - exports.C1 = exports.C; + exports.C1 = C; (function (E) { E[E["A"] = 0] = "A"; E[E["B"] = 1] = "B"; E[E["C"] = 2] = "C"; })(exports.E || (exports.E = {})); var E = exports.E; - exports.E1 = exports.E; + exports.E1 = E; var M; (function (M) { })(M = exports.M || (exports.M = {})); - exports.M1 = exports.M; + exports.M1 = M; exports.a = M.x; exports.a1 = exports.a; }); diff --git a/tests/baselines/reference/exportsAndImports3.js b/tests/baselines/reference/exportsAndImports3.js index db29b62449e..47491ccbc04 100644 --- a/tests/baselines/reference/exportsAndImports3.js +++ b/tests/baselines/reference/exportsAndImports3.js @@ -39,25 +39,25 @@ exports.v = 1; exports.v1 = exports.v; function f() { } exports.f = f; -exports.f1 = exports.f; +exports.f1 = f; var C = (function () { function C() { } return C; })(); exports.C = C; -exports.C1 = exports.C; +exports.C1 = C; (function (E) { E[E["A"] = 0] = "A"; E[E["B"] = 1] = "B"; E[E["C"] = 2] = "C"; })(exports.E || (exports.E = {})); var E = exports.E; -exports.E1 = exports.E; +exports.E1 = E; var M; (function (M) { })(M = exports.M || (exports.M = {})); -exports.M1 = exports.M; +exports.M1 = M; exports.a = M.x; exports.a1 = exports.a; //// [t2.js] diff --git a/tests/baselines/reference/genericTypeAliases.js b/tests/baselines/reference/genericTypeAliases.js new file mode 100644 index 00000000000..8218f5c886c --- /dev/null +++ b/tests/baselines/reference/genericTypeAliases.js @@ -0,0 +1,120 @@ +//// [genericTypeAliases.ts] +type Tree = T | { left: Tree, right: Tree }; + +var tree: Tree = { + left: { + left: 0, + right: { + left: 1, + right: 2 + }, + }, + right: 3 +}; + +type Lazy = T | (() => T); + +var ls: Lazy; +ls = "eager"; +ls = () => "lazy"; + +type Foo = T | { x: Foo }; +type Bar = U | { x: Bar }; + +// Deeply instantiated generics +var x: Foo; +var y: Bar; +x = y; +y = x; + +x = "string"; +x = { x: "hello" }; +x = { x: { x: "world" } }; + +var z: Foo; +z = 42; +z = { x: 42 }; +z = { x: { x: 42 } }; + +type Strange = string; // Type parameter not used +var s: Strange; +s = "hello"; + +interface Tuple { + a: A; + b: B; +} + +type Pair = Tuple; + +interface TaggedPair extends Pair { + tag: string; +} + +var p: TaggedPair; +p.a = 1; +p.b = 2; +p.tag = "test"; + +function f() { + type Foo = T | { x: Foo }; + var x: Foo; + return x; +} + +function g() { + type Bar = U | { x: Bar }; + var x: Bar; + return x; +} + +// Deeply instantiated generics +var a = f(); +var b = g(); +a = b; + + +//// [genericTypeAliases.js] +var tree = { + left: { + left: 0, + right: { + left: 1, + right: 2 + } + }, + right: 3 +}; +var ls; +ls = "eager"; +ls = function () { return "lazy"; }; +// Deeply instantiated generics +var x; +var y; +x = y; +y = x; +x = "string"; +x = { x: "hello" }; +x = { x: { x: "world" } }; +var z; +z = 42; +z = { x: 42 }; +z = { x: { x: 42 } }; +var s; +s = "hello"; +var p; +p.a = 1; +p.b = 2; +p.tag = "test"; +function f() { + var x; + return x; +} +function g() { + var x; + return x; +} +// Deeply instantiated generics +var a = f(); +var b = g(); +a = b; diff --git a/tests/baselines/reference/genericTypeAliases.symbols b/tests/baselines/reference/genericTypeAliases.symbols new file mode 100644 index 00000000000..1a1d0e51487 --- /dev/null +++ b/tests/baselines/reference/genericTypeAliases.symbols @@ -0,0 +1,231 @@ +=== tests/cases/conformance/types/typeAliases/genericTypeAliases.ts === +type Tree = T | { left: Tree, right: Tree }; +>Tree : Symbol(Tree, Decl(genericTypeAliases.ts, 0, 0)) +>T : Symbol(T, Decl(genericTypeAliases.ts, 0, 10)) +>T : Symbol(T, Decl(genericTypeAliases.ts, 0, 10)) +>left : Symbol(left, Decl(genericTypeAliases.ts, 0, 20)) +>Tree : Symbol(Tree, Decl(genericTypeAliases.ts, 0, 0)) +>T : Symbol(T, Decl(genericTypeAliases.ts, 0, 10)) +>right : Symbol(right, Decl(genericTypeAliases.ts, 0, 35)) +>Tree : Symbol(Tree, Decl(genericTypeAliases.ts, 0, 0)) +>T : Symbol(T, Decl(genericTypeAliases.ts, 0, 10)) + +var tree: Tree = { +>tree : Symbol(tree, Decl(genericTypeAliases.ts, 2, 3)) +>Tree : Symbol(Tree, Decl(genericTypeAliases.ts, 0, 0)) + + left: { +>left : Symbol(left, Decl(genericTypeAliases.ts, 2, 26)) + + left: 0, +>left : Symbol(left, Decl(genericTypeAliases.ts, 3, 11)) + + right: { +>right : Symbol(right, Decl(genericTypeAliases.ts, 4, 16)) + + left: 1, +>left : Symbol(left, Decl(genericTypeAliases.ts, 5, 16)) + + right: 2 +>right : Symbol(right, Decl(genericTypeAliases.ts, 6, 20)) + + }, + }, + right: 3 +>right : Symbol(right, Decl(genericTypeAliases.ts, 9, 6)) + +}; + +type Lazy = T | (() => T); +>Lazy : Symbol(Lazy, Decl(genericTypeAliases.ts, 11, 2)) +>T : Symbol(T, Decl(genericTypeAliases.ts, 13, 10)) +>T : Symbol(T, Decl(genericTypeAliases.ts, 13, 10)) +>T : Symbol(T, Decl(genericTypeAliases.ts, 13, 10)) + +var ls: Lazy; +>ls : Symbol(ls, Decl(genericTypeAliases.ts, 15, 3)) +>Lazy : Symbol(Lazy, Decl(genericTypeAliases.ts, 11, 2)) + +ls = "eager"; +>ls : Symbol(ls, Decl(genericTypeAliases.ts, 15, 3)) + +ls = () => "lazy"; +>ls : Symbol(ls, Decl(genericTypeAliases.ts, 15, 3)) + +type Foo = T | { x: Foo }; +>Foo : Symbol(Foo, Decl(genericTypeAliases.ts, 17, 18)) +>T : Symbol(T, Decl(genericTypeAliases.ts, 19, 9)) +>T : Symbol(T, Decl(genericTypeAliases.ts, 19, 9)) +>x : Symbol(x, Decl(genericTypeAliases.ts, 19, 19)) +>Foo : Symbol(Foo, Decl(genericTypeAliases.ts, 17, 18)) +>T : Symbol(T, Decl(genericTypeAliases.ts, 19, 9)) + +type Bar = U | { x: Bar }; +>Bar : Symbol(Bar, Decl(genericTypeAliases.ts, 19, 32)) +>U : Symbol(U, Decl(genericTypeAliases.ts, 20, 9)) +>U : Symbol(U, Decl(genericTypeAliases.ts, 20, 9)) +>x : Symbol(x, Decl(genericTypeAliases.ts, 20, 19)) +>Bar : Symbol(Bar, Decl(genericTypeAliases.ts, 19, 32)) +>U : Symbol(U, Decl(genericTypeAliases.ts, 20, 9)) + +// Deeply instantiated generics +var x: Foo; +>x : Symbol(x, Decl(genericTypeAliases.ts, 23, 3)) +>Foo : Symbol(Foo, Decl(genericTypeAliases.ts, 17, 18)) + +var y: Bar; +>y : Symbol(y, Decl(genericTypeAliases.ts, 24, 3)) +>Bar : Symbol(Bar, Decl(genericTypeAliases.ts, 19, 32)) + +x = y; +>x : Symbol(x, Decl(genericTypeAliases.ts, 23, 3)) +>y : Symbol(y, Decl(genericTypeAliases.ts, 24, 3)) + +y = x; +>y : Symbol(y, Decl(genericTypeAliases.ts, 24, 3)) +>x : Symbol(x, Decl(genericTypeAliases.ts, 23, 3)) + +x = "string"; +>x : Symbol(x, Decl(genericTypeAliases.ts, 23, 3)) + +x = { x: "hello" }; +>x : Symbol(x, Decl(genericTypeAliases.ts, 23, 3)) +>x : Symbol(x, Decl(genericTypeAliases.ts, 29, 5)) + +x = { x: { x: "world" } }; +>x : Symbol(x, Decl(genericTypeAliases.ts, 23, 3)) +>x : Symbol(x, Decl(genericTypeAliases.ts, 30, 5)) +>x : Symbol(x, Decl(genericTypeAliases.ts, 30, 10)) + +var z: Foo; +>z : Symbol(z, Decl(genericTypeAliases.ts, 32, 3)) +>Foo : Symbol(Foo, Decl(genericTypeAliases.ts, 17, 18)) + +z = 42; +>z : Symbol(z, Decl(genericTypeAliases.ts, 32, 3)) + +z = { x: 42 }; +>z : Symbol(z, Decl(genericTypeAliases.ts, 32, 3)) +>x : Symbol(x, Decl(genericTypeAliases.ts, 34, 5)) + +z = { x: { x: 42 } }; +>z : Symbol(z, Decl(genericTypeAliases.ts, 32, 3)) +>x : Symbol(x, Decl(genericTypeAliases.ts, 35, 5)) +>x : Symbol(x, Decl(genericTypeAliases.ts, 35, 10)) + +type Strange = string; // Type parameter not used +>Strange : Symbol(Strange, Decl(genericTypeAliases.ts, 35, 21)) +>T : Symbol(T, Decl(genericTypeAliases.ts, 37, 13)) + +var s: Strange; +>s : Symbol(s, Decl(genericTypeAliases.ts, 38, 3)) +>Strange : Symbol(Strange, Decl(genericTypeAliases.ts, 35, 21)) + +s = "hello"; +>s : Symbol(s, Decl(genericTypeAliases.ts, 38, 3)) + +interface Tuple { +>Tuple : Symbol(Tuple, Decl(genericTypeAliases.ts, 39, 12)) +>A : Symbol(A, Decl(genericTypeAliases.ts, 41, 16)) +>B : Symbol(B, Decl(genericTypeAliases.ts, 41, 18)) + + a: A; +>a : Symbol(a, Decl(genericTypeAliases.ts, 41, 23)) +>A : Symbol(A, Decl(genericTypeAliases.ts, 41, 16)) + + b: B; +>b : Symbol(b, Decl(genericTypeAliases.ts, 42, 9)) +>B : Symbol(B, Decl(genericTypeAliases.ts, 41, 18)) +} + +type Pair = Tuple; +>Pair : Symbol(Pair, Decl(genericTypeAliases.ts, 44, 1)) +>T : Symbol(T, Decl(genericTypeAliases.ts, 46, 10)) +>Tuple : Symbol(Tuple, Decl(genericTypeAliases.ts, 39, 12)) +>T : Symbol(T, Decl(genericTypeAliases.ts, 46, 10)) +>T : Symbol(T, Decl(genericTypeAliases.ts, 46, 10)) + +interface TaggedPair extends Pair { +>TaggedPair : Symbol(TaggedPair, Decl(genericTypeAliases.ts, 46, 27)) +>T : Symbol(T, Decl(genericTypeAliases.ts, 48, 21)) +>Pair : Symbol(Pair, Decl(genericTypeAliases.ts, 44, 1)) +>T : Symbol(T, Decl(genericTypeAliases.ts, 48, 21)) + + tag: string; +>tag : Symbol(tag, Decl(genericTypeAliases.ts, 48, 41)) +} + +var p: TaggedPair; +>p : Symbol(p, Decl(genericTypeAliases.ts, 52, 3)) +>TaggedPair : Symbol(TaggedPair, Decl(genericTypeAliases.ts, 46, 27)) + +p.a = 1; +>p.a : Symbol(Tuple.a, Decl(genericTypeAliases.ts, 41, 23)) +>p : Symbol(p, Decl(genericTypeAliases.ts, 52, 3)) +>a : Symbol(Tuple.a, Decl(genericTypeAliases.ts, 41, 23)) + +p.b = 2; +>p.b : Symbol(Tuple.b, Decl(genericTypeAliases.ts, 42, 9)) +>p : Symbol(p, Decl(genericTypeAliases.ts, 52, 3)) +>b : Symbol(Tuple.b, Decl(genericTypeAliases.ts, 42, 9)) + +p.tag = "test"; +>p.tag : Symbol(TaggedPair.tag, Decl(genericTypeAliases.ts, 48, 41)) +>p : Symbol(p, Decl(genericTypeAliases.ts, 52, 3)) +>tag : Symbol(TaggedPair.tag, Decl(genericTypeAliases.ts, 48, 41)) + +function f() { +>f : Symbol(f, Decl(genericTypeAliases.ts, 55, 15)) +>A : Symbol(A, Decl(genericTypeAliases.ts, 57, 11)) + + type Foo = T | { x: Foo }; +>Foo : Symbol(Foo, Decl(genericTypeAliases.ts, 57, 17)) +>T : Symbol(T, Decl(genericTypeAliases.ts, 58, 13)) +>T : Symbol(T, Decl(genericTypeAliases.ts, 58, 13)) +>x : Symbol(x, Decl(genericTypeAliases.ts, 58, 23)) +>Foo : Symbol(Foo, Decl(genericTypeAliases.ts, 57, 17)) +>T : Symbol(T, Decl(genericTypeAliases.ts, 58, 13)) + + var x: Foo; +>x : Symbol(x, Decl(genericTypeAliases.ts, 59, 7)) +>Foo : Symbol(Foo, Decl(genericTypeAliases.ts, 57, 17)) +>A : Symbol(A, Decl(genericTypeAliases.ts, 57, 11)) + + return x; +>x : Symbol(x, Decl(genericTypeAliases.ts, 59, 7)) +} + +function g() { +>g : Symbol(g, Decl(genericTypeAliases.ts, 61, 1)) +>B : Symbol(B, Decl(genericTypeAliases.ts, 63, 11)) + + type Bar = U | { x: Bar }; +>Bar : Symbol(Bar, Decl(genericTypeAliases.ts, 63, 17)) +>U : Symbol(U, Decl(genericTypeAliases.ts, 64, 13)) +>U : Symbol(U, Decl(genericTypeAliases.ts, 64, 13)) +>x : Symbol(x, Decl(genericTypeAliases.ts, 64, 23)) +>Bar : Symbol(Bar, Decl(genericTypeAliases.ts, 63, 17)) +>U : Symbol(U, Decl(genericTypeAliases.ts, 64, 13)) + + var x: Bar; +>x : Symbol(x, Decl(genericTypeAliases.ts, 65, 7)) +>Bar : Symbol(Bar, Decl(genericTypeAliases.ts, 63, 17)) +>B : Symbol(B, Decl(genericTypeAliases.ts, 63, 11)) + + return x; +>x : Symbol(x, Decl(genericTypeAliases.ts, 65, 7)) +} + +// Deeply instantiated generics +var a = f(); +>a : Symbol(a, Decl(genericTypeAliases.ts, 70, 3)) +>f : Symbol(f, Decl(genericTypeAliases.ts, 55, 15)) + +var b = g(); +>b : Symbol(b, Decl(genericTypeAliases.ts, 71, 3)) +>g : Symbol(g, Decl(genericTypeAliases.ts, 61, 1)) + +a = b; +>a : Symbol(a, Decl(genericTypeAliases.ts, 70, 3)) +>b : Symbol(b, Decl(genericTypeAliases.ts, 71, 3)) + diff --git a/tests/baselines/reference/genericTypeAliases.types b/tests/baselines/reference/genericTypeAliases.types new file mode 100644 index 00000000000..b43e2610725 --- /dev/null +++ b/tests/baselines/reference/genericTypeAliases.types @@ -0,0 +1,274 @@ +=== tests/cases/conformance/types/typeAliases/genericTypeAliases.ts === +type Tree = T | { left: Tree, right: Tree }; +>Tree : T | { left: T | any; right: T | any; } +>T : T +>T : T +>left : T | { left: T | any; right: T | any; } +>Tree : T | { left: T | any; right: T | any; } +>T : T +>right : T | { left: T | any; right: T | any; } +>Tree : T | { left: T | any; right: T | any; } +>T : T + +var tree: Tree = { +>tree : number | { left: number | any; right: number | any; } +>Tree : T | { left: T | any; right: T | any; } +>{ left: { left: 0, right: { left: 1, right: 2 }, }, right: 3} : { left: { left: number; right: { left: number; right: number; }; }; right: number; } + + left: { +>left : { left: number; right: { left: number; right: number; }; } +>{ left: 0, right: { left: 1, right: 2 }, } : { left: number; right: { left: number; right: number; }; } + + left: 0, +>left : number +>0 : number + + right: { +>right : { left: number; right: number; } +>{ left: 1, right: 2 } : { left: number; right: number; } + + left: 1, +>left : number +>1 : number + + right: 2 +>right : number +>2 : number + + }, + }, + right: 3 +>right : number +>3 : number + +}; + +type Lazy = T | (() => T); +>Lazy : T | (() => T) +>T : T +>T : T +>T : T + +var ls: Lazy; +>ls : string | (() => string) +>Lazy : T | (() => T) + +ls = "eager"; +>ls = "eager" : string +>ls : string | (() => string) +>"eager" : string + +ls = () => "lazy"; +>ls = () => "lazy" : () => string +>ls : string | (() => string) +>() => "lazy" : () => string +>"lazy" : string + +type Foo = T | { x: Foo }; +>Foo : T | { x: T | any; } +>T : T +>T : T +>x : T | { x: T | any; } +>Foo : T | { x: T | any; } +>T : T + +type Bar = U | { x: Bar }; +>Bar : U | { x: U | any; } +>U : U +>U : U +>x : U | { x: U | any; } +>Bar : U | { x: U | any; } +>U : U + +// Deeply instantiated generics +var x: Foo; +>x : string | { x: string | any; } +>Foo : T | { x: T | any; } + +var y: Bar; +>y : string | { x: string | any; } +>Bar : U | { x: U | any; } + +x = y; +>x = y : string | { x: string | any; } +>x : string | { x: string | any; } +>y : string | { x: string | any; } + +y = x; +>y = x : string | { x: string | any; } +>y : string | { x: string | any; } +>x : string | { x: string | any; } + +x = "string"; +>x = "string" : string +>x : string | { x: string | any; } +>"string" : string + +x = { x: "hello" }; +>x = { x: "hello" } : { x: string; } +>x : string | { x: string | any; } +>{ x: "hello" } : { x: string; } +>x : string +>"hello" : string + +x = { x: { x: "world" } }; +>x = { x: { x: "world" } } : { x: { x: string; }; } +>x : string | { x: string | any; } +>{ x: { x: "world" } } : { x: { x: string; }; } +>x : { x: string; } +>{ x: "world" } : { x: string; } +>x : string +>"world" : string + +var z: Foo; +>z : number | { x: number | any; } +>Foo : T | { x: T | any; } + +z = 42; +>z = 42 : number +>z : number | { x: number | any; } +>42 : number + +z = { x: 42 }; +>z = { x: 42 } : { x: number; } +>z : number | { x: number | any; } +>{ x: 42 } : { x: number; } +>x : number +>42 : number + +z = { x: { x: 42 } }; +>z = { x: { x: 42 } } : { x: { x: number; }; } +>z : number | { x: number | any; } +>{ x: { x: 42 } } : { x: { x: number; }; } +>x : { x: number; } +>{ x: 42 } : { x: number; } +>x : number +>42 : number + +type Strange = string; // Type parameter not used +>Strange : string +>T : T + +var s: Strange; +>s : string +>Strange : string + +s = "hello"; +>s = "hello" : string +>s : string +>"hello" : string + +interface Tuple { +>Tuple : Tuple +>A : A +>B : B + + a: A; +>a : A +>A : A + + b: B; +>b : B +>B : B +} + +type Pair = Tuple; +>Pair : Tuple +>T : T +>Tuple : Tuple +>T : T +>T : T + +interface TaggedPair extends Pair { +>TaggedPair : TaggedPair +>T : T +>Pair : Tuple +>T : T + + tag: string; +>tag : string +} + +var p: TaggedPair; +>p : TaggedPair +>TaggedPair : TaggedPair + +p.a = 1; +>p.a = 1 : number +>p.a : number +>p : TaggedPair +>a : number +>1 : number + +p.b = 2; +>p.b = 2 : number +>p.b : number +>p : TaggedPair +>b : number +>2 : number + +p.tag = "test"; +>p.tag = "test" : string +>p.tag : string +>p : TaggedPair +>tag : string +>"test" : string + +function f() { +>f : () => A[] | { x: A[] | any; } +>A : A + + type Foo = T | { x: Foo }; +>Foo : T | { x: T | any; } +>T : T +>T : T +>x : T | { x: T | any; } +>Foo : T | { x: T | any; } +>T : T + + var x: Foo; +>x : A[] | { x: A[] | any; } +>Foo : T | { x: T | any; } +>A : A + + return x; +>x : A[] | { x: A[] | any; } +} + +function g() { +>g : () => B[] | { x: B[] | any; } +>B : B + + type Bar = U | { x: Bar }; +>Bar : U | { x: U | any; } +>U : U +>U : U +>x : U | { x: U | any; } +>Bar : U | { x: U | any; } +>U : U + + var x: Bar; +>x : B[] | { x: B[] | any; } +>Bar : U | { x: U | any; } +>B : B + + return x; +>x : B[] | { x: B[] | any; } +} + +// Deeply instantiated generics +var a = f(); +>a : string[] | { x: string[] | any; } +>f() : string[] | { x: string[] | any; } +>f : () => A[] | { x: A[] | any; } + +var b = g(); +>b : string[] | { x: string[] | any; } +>g() : string[] | { x: string[] | any; } +>g : () => B[] | { x: B[] | any; } + +a = b; +>a = b : string[] | { x: string[] | any; } +>a : string[] | { x: string[] | any; } +>b : string[] | { x: string[] | any; } + diff --git a/tests/baselines/reference/localTypes1.js b/tests/baselines/reference/localTypes1.js index d1c3758920e..09fa9c04f3c 100644 --- a/tests/baselines/reference/localTypes1.js +++ b/tests/baselines/reference/localTypes1.js @@ -202,12 +202,12 @@ function f3(b) { return a; } else { - var A = (function () { - function A() { + var A_1 = (function () { + function A_1() { } - return A; + return A_1; })(); - var c = [new A()]; + var c = [new A_1()]; c[0].x = E.B; return c; } diff --git a/tests/baselines/reference/nonGenericTypeReferenceWithTypeArguments.errors.txt b/tests/baselines/reference/nonGenericTypeReferenceWithTypeArguments.errors.txt new file mode 100644 index 00000000000..b227ff0f0ae --- /dev/null +++ b/tests/baselines/reference/nonGenericTypeReferenceWithTypeArguments.errors.txt @@ -0,0 +1,53 @@ +tests/cases/conformance/types/specifyingTypes/typeReferences/nonGenericTypeReferenceWithTypeArguments.ts(7,9): error TS2315: Type 'C' is not generic. +tests/cases/conformance/types/specifyingTypes/typeReferences/nonGenericTypeReferenceWithTypeArguments.ts(8,9): error TS2315: Type 'I' is not generic. +tests/cases/conformance/types/specifyingTypes/typeReferences/nonGenericTypeReferenceWithTypeArguments.ts(9,9): error TS2315: Type 'E' is not generic. +tests/cases/conformance/types/specifyingTypes/typeReferences/nonGenericTypeReferenceWithTypeArguments.ts(10,9): error TS2315: Type 'T' is not generic. +tests/cases/conformance/types/specifyingTypes/typeReferences/nonGenericTypeReferenceWithTypeArguments.ts(17,13): error TS2315: Type 'C' is not generic. +tests/cases/conformance/types/specifyingTypes/typeReferences/nonGenericTypeReferenceWithTypeArguments.ts(18,13): error TS2315: Type 'I' is not generic. +tests/cases/conformance/types/specifyingTypes/typeReferences/nonGenericTypeReferenceWithTypeArguments.ts(19,13): error TS2315: Type 'E' is not generic. +tests/cases/conformance/types/specifyingTypes/typeReferences/nonGenericTypeReferenceWithTypeArguments.ts(20,13): error TS2315: Type 'T' is not generic. +tests/cases/conformance/types/specifyingTypes/typeReferences/nonGenericTypeReferenceWithTypeArguments.ts(21,13): error TS2315: Type 'U' is not generic. + + +==== tests/cases/conformance/types/specifyingTypes/typeReferences/nonGenericTypeReferenceWithTypeArguments.ts (9 errors) ==== + // Check that errors are reported for non-generic types with type arguments + + class C { } + interface I { } + enum E { } + type T = { }; + var v1: C; + ~~~~~~~~~ +!!! error TS2315: Type 'C' is not generic. + var v2: I; + ~~~~~~~~~ +!!! error TS2315: Type 'I' is not generic. + var v3: E; + ~~~~~~~~~ +!!! error TS2315: Type 'E' is not generic. + var v4: T; + ~~~~~~~~~ +!!! error TS2315: Type 'T' is not generic. + + function f() { + class C { } + interface I { } + enum E { } + type T = {}; + var v1: C; + ~~~~~~~~~ +!!! error TS2315: Type 'C' is not generic. + var v2: I; + ~~~~~~~~~ +!!! error TS2315: Type 'I' is not generic. + var v3: E; + ~~~~~~~~~ +!!! error TS2315: Type 'E' is not generic. + var v4: T; + ~~~~~~~~~ +!!! error TS2315: Type 'T' is not generic. + var v5: U; + ~~~~~~~~~ +!!! error TS2315: Type 'U' is not generic. + } + \ No newline at end of file diff --git a/tests/baselines/reference/nonGenericTypeReferenceWithTypeArguments.js b/tests/baselines/reference/nonGenericTypeReferenceWithTypeArguments.js new file mode 100644 index 00000000000..5558cb2fc8b --- /dev/null +++ b/tests/baselines/reference/nonGenericTypeReferenceWithTypeArguments.js @@ -0,0 +1,54 @@ +//// [nonGenericTypeReferenceWithTypeArguments.ts] +// Check that errors are reported for non-generic types with type arguments + +class C { } +interface I { } +enum E { } +type T = { }; +var v1: C; +var v2: I; +var v3: E; +var v4: T; + +function f() { + class C { } + interface I { } + enum E { } + type T = {}; + var v1: C; + var v2: I; + var v3: E; + var v4: T; + var v5: U; +} + + +//// [nonGenericTypeReferenceWithTypeArguments.js] +// Check that errors are reported for non-generic types with type arguments +var C = (function () { + function C() { + } + return C; +})(); +var E; +(function (E) { +})(E || (E = {})); +var v1; +var v2; +var v3; +var v4; +function f() { + var C = (function () { + function C() { + } + return C; + })(); + var E; + (function (E) { + })(E || (E = {})); + var v1; + var v2; + var v3; + var v4; + var v5; +} diff --git a/tests/baselines/reference/project/privacyCheckOnImportedModuleDeclarationsInsideModule/amd/testGlo.js b/tests/baselines/reference/project/privacyCheckOnImportedModuleDeclarationsInsideModule/amd/testGlo.js index 5bdce5cf48a..1ce3452dbed 100644 --- a/tests/baselines/reference/project/privacyCheckOnImportedModuleDeclarationsInsideModule/amd/testGlo.js +++ b/tests/baselines/reference/project/privacyCheckOnImportedModuleDeclarationsInsideModule/amd/testGlo.js @@ -18,7 +18,7 @@ var m2; _super.apply(this, arguments); } return class1; - })(mExported.me.class1); + })(m2.mExported.me.class1); m2.class1 = class1; var c2 = new m2.mExported.me.class1; function f2() { @@ -31,7 +31,7 @@ var m2; _super.apply(this, arguments); } return class2; - })(mExported.me.class1); + })(m2.mExported.me.class1); m2.c3 = new mNonExported.mne.class1; function f3() { return new mNonExported.mne.class1(); diff --git a/tests/baselines/reference/project/privacyCheckOnImportedModuleDeclarationsInsideModule/node/testGlo.js b/tests/baselines/reference/project/privacyCheckOnImportedModuleDeclarationsInsideModule/node/testGlo.js index 5bdce5cf48a..1ce3452dbed 100644 --- a/tests/baselines/reference/project/privacyCheckOnImportedModuleDeclarationsInsideModule/node/testGlo.js +++ b/tests/baselines/reference/project/privacyCheckOnImportedModuleDeclarationsInsideModule/node/testGlo.js @@ -18,7 +18,7 @@ var m2; _super.apply(this, arguments); } return class1; - })(mExported.me.class1); + })(m2.mExported.me.class1); m2.class1 = class1; var c2 = new m2.mExported.me.class1; function f2() { @@ -31,7 +31,7 @@ var m2; _super.apply(this, arguments); } return class2; - })(mExported.me.class1); + })(m2.mExported.me.class1); m2.c3 = new mNonExported.mne.class1; function f3() { return new mNonExported.mne.class1(); diff --git a/tests/baselines/reference/systemModule8.js b/tests/baselines/reference/systemModule8.js index 6196005dc62..be4f8c05374 100644 --- a/tests/baselines/reference/systemModule8.js +++ b/tests/baselines/reference/systemModule8.js @@ -65,6 +65,6 @@ System.register([], function(exports_1) { exports_1("x", x = _b[_i][0]); } } - var _a; } + var _a; }); diff --git a/tests/baselines/reference/typeAliasesForObjectTypes.errors.txt b/tests/baselines/reference/typeAliasesForObjectTypes.errors.txt index 45e3c2da32f..d5bc01f93ba 100644 --- a/tests/baselines/reference/typeAliasesForObjectTypes.errors.txt +++ b/tests/baselines/reference/typeAliasesForObjectTypes.errors.txt @@ -2,12 +2,9 @@ tests/cases/conformance/types/typeAliases/typeAliasesForObjectTypes.ts(4,22): er tests/cases/conformance/types/typeAliases/typeAliasesForObjectTypes.ts(5,21): error TS2422: A class may only implement another class or interface. tests/cases/conformance/types/typeAliases/typeAliasesForObjectTypes.ts(10,6): error TS2300: Duplicate identifier 'T2'. tests/cases/conformance/types/typeAliases/typeAliasesForObjectTypes.ts(11,6): error TS2300: Duplicate identifier 'T2'. -tests/cases/conformance/types/typeAliases/typeAliasesForObjectTypes.ts(14,8): error TS1005: '=' expected. -tests/cases/conformance/types/typeAliases/typeAliasesForObjectTypes.ts(14,12): error TS1005: '(' expected. -tests/cases/conformance/types/typeAliases/typeAliasesForObjectTypes.ts(14,19): error TS2304: Cannot find name 'T'. -==== tests/cases/conformance/types/typeAliases/typeAliasesForObjectTypes.ts (7 errors) ==== +==== tests/cases/conformance/types/typeAliases/typeAliasesForObjectTypes.ts (4 errors) ==== type T1 = { x: string } // An interface can be named in an extends or implements clause, but a type alias for an object type literal cannot. @@ -30,10 +27,4 @@ tests/cases/conformance/types/typeAliases/typeAliasesForObjectTypes.ts(14,19): e // An interface can have type parameters, but a type alias for an object type literal cannot. type T3 = { x: T } - ~ -!!! error TS1005: '=' expected. - ~ -!!! error TS1005: '(' expected. - ~ -!!! error TS2304: Cannot find name 'T'. \ No newline at end of file diff --git a/tests/baselines/reference/typeAliasesForObjectTypes.js b/tests/baselines/reference/typeAliasesForObjectTypes.js index eb1ec7f130a..0b583528ade 100644 --- a/tests/baselines/reference/typeAliasesForObjectTypes.js +++ b/tests/baselines/reference/typeAliasesForObjectTypes.js @@ -21,6 +21,3 @@ var C1 = (function () { } return C1; })(); -{ - x: T; -} diff --git a/tests/baselines/reference/typeGuardFunction.js b/tests/baselines/reference/typeGuardFunction.js new file mode 100644 index 00000000000..f6b752c8c04 --- /dev/null +++ b/tests/baselines/reference/typeGuardFunction.js @@ -0,0 +1,149 @@ +//// [typeGuardFunction.ts] + +class A { + propA: number; +} + +class B { + propB: number; +} + +class C extends A { + propC: number; +} + +declare function isA(p1: any): p1 is A; +declare function isB(p1: any): p1 is B; +declare function isC(p1: any): p1 is C; + +declare function retC(): C; + +var a: A; +var b: B; + +// Basic +if (isC(a)) { + a.propC; +} + +// Sub type +var subType: C; +if(isA(subType)) { + subType.propC; +} + +// Union type +var union: A | B; +if(isA(union)) { + union.propA; +} + +// Call signature +interface I1 { + (p1: A): p1 is C; +} + +// The parameter index and argument index for the type guard target is matching. +// The type predicate type is assignable to the parameter type. +declare function isC_multipleParams(p1, p2): p1 is C; +if (isC_multipleParams(a, 0)) { + a.propC; +} + +// Methods +var obj: { + func1(p1: A): p1 is C; +} +class D { + method1(p1: A): p1 is C { + return true; + } +} + +// Arrow function +let f1 = (p1: A): p1 is C => false; + +// Function type +declare function f2(p1: (p1: A) => p1 is C); + +// Function expressions +f2(function(p1: A): p1 is C { + return true; +}); + +// Evaluations are asssignable to boolean. +declare function acceptingBoolean(a: boolean); +acceptingBoolean(isA(a)); + +// Type predicates with different parameter name. +declare function acceptingTypeGuardFunction(p1: (item) => item is A); +acceptingTypeGuardFunction(isA); + +// Binary expressions +let union2: C | B; +let union3: boolean | B = isA(union2) || union2; + +//// [typeGuardFunction.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; } + __.prototype = b.prototype; + d.prototype = new __(); +}; +var A = (function () { + function A() { + } + return A; +})(); +var B = (function () { + function B() { + } + return B; +})(); +var C = (function (_super) { + __extends(C, _super); + function C() { + _super.apply(this, arguments); + } + return C; +})(A); +var a; +var b; +// Basic +if (isC(a)) { + a.propC; +} +// Sub type +var subType; +if (isA(subType)) { + subType.propC; +} +// Union type +var union; +if (isA(union)) { + union.propA; +} +if (isC_multipleParams(a, 0)) { + a.propC; +} +// Methods +var obj; +var D = (function () { + function D() { + } + D.prototype.method1 = function (p1) { + return true; + }; + return D; +})(); +// Arrow function +var f1 = function (p1) { return false; }; +// Function expressions +f2(function (p1) { + return true; +}); +acceptingBoolean(isA(a)); +acceptingTypeGuardFunction(isA); +// Binary expressions +var union2; +var union3 = isA(union2) || union2; diff --git a/tests/baselines/reference/typeGuardFunction.symbols b/tests/baselines/reference/typeGuardFunction.symbols new file mode 100644 index 00000000000..c315e721085 --- /dev/null +++ b/tests/baselines/reference/typeGuardFunction.symbols @@ -0,0 +1,203 @@ +=== tests/cases/conformance/expressions/typeGuards/typeGuardFunction.ts === + +class A { +>A : Symbol(A, Decl(typeGuardFunction.ts, 0, 0)) + + propA: number; +>propA : Symbol(propA, Decl(typeGuardFunction.ts, 1, 9)) +} + +class B { +>B : Symbol(B, Decl(typeGuardFunction.ts, 3, 1)) + + propB: number; +>propB : Symbol(propB, Decl(typeGuardFunction.ts, 5, 9)) +} + +class C extends A { +>C : Symbol(C, Decl(typeGuardFunction.ts, 7, 1)) +>A : Symbol(A, Decl(typeGuardFunction.ts, 0, 0)) + + propC: number; +>propC : Symbol(propC, Decl(typeGuardFunction.ts, 9, 19)) +} + +declare function isA(p1: any): p1 is A; +>isA : Symbol(isA, Decl(typeGuardFunction.ts, 11, 1)) +>p1 : Symbol(p1, Decl(typeGuardFunction.ts, 13, 21)) +>A : Symbol(A, Decl(typeGuardFunction.ts, 0, 0)) + +declare function isB(p1: any): p1 is B; +>isB : Symbol(isB, Decl(typeGuardFunction.ts, 13, 39)) +>p1 : Symbol(p1, Decl(typeGuardFunction.ts, 14, 21)) +>B : Symbol(B, Decl(typeGuardFunction.ts, 3, 1)) + +declare function isC(p1: any): p1 is C; +>isC : Symbol(isC, Decl(typeGuardFunction.ts, 14, 39)) +>p1 : Symbol(p1, Decl(typeGuardFunction.ts, 15, 21)) +>C : Symbol(C, Decl(typeGuardFunction.ts, 7, 1)) + +declare function retC(): C; +>retC : Symbol(retC, Decl(typeGuardFunction.ts, 15, 39)) +>C : Symbol(C, Decl(typeGuardFunction.ts, 7, 1)) + +var a: A; +>a : Symbol(a, Decl(typeGuardFunction.ts, 19, 3)) +>A : Symbol(A, Decl(typeGuardFunction.ts, 0, 0)) + +var b: B; +>b : Symbol(b, Decl(typeGuardFunction.ts, 20, 3)) +>B : Symbol(B, Decl(typeGuardFunction.ts, 3, 1)) + +// Basic +if (isC(a)) { +>isC : Symbol(isC, Decl(typeGuardFunction.ts, 14, 39)) +>a : Symbol(a, Decl(typeGuardFunction.ts, 19, 3)) + + a.propC; +>a.propC : Symbol(C.propC, Decl(typeGuardFunction.ts, 9, 19)) +>a : Symbol(a, Decl(typeGuardFunction.ts, 19, 3)) +>propC : Symbol(C.propC, Decl(typeGuardFunction.ts, 9, 19)) +} + +// Sub type +var subType: C; +>subType : Symbol(subType, Decl(typeGuardFunction.ts, 28, 3)) +>C : Symbol(C, Decl(typeGuardFunction.ts, 7, 1)) + +if(isA(subType)) { +>isA : Symbol(isA, Decl(typeGuardFunction.ts, 11, 1)) +>subType : Symbol(subType, Decl(typeGuardFunction.ts, 28, 3)) + + subType.propC; +>subType.propC : Symbol(C.propC, Decl(typeGuardFunction.ts, 9, 19)) +>subType : Symbol(subType, Decl(typeGuardFunction.ts, 28, 3)) +>propC : Symbol(C.propC, Decl(typeGuardFunction.ts, 9, 19)) +} + +// Union type +var union: A | B; +>union : Symbol(union, Decl(typeGuardFunction.ts, 34, 3)) +>A : Symbol(A, Decl(typeGuardFunction.ts, 0, 0)) +>B : Symbol(B, Decl(typeGuardFunction.ts, 3, 1)) + +if(isA(union)) { +>isA : Symbol(isA, Decl(typeGuardFunction.ts, 11, 1)) +>union : Symbol(union, Decl(typeGuardFunction.ts, 34, 3)) + + union.propA; +>union.propA : Symbol(A.propA, Decl(typeGuardFunction.ts, 1, 9)) +>union : Symbol(union, Decl(typeGuardFunction.ts, 34, 3)) +>propA : Symbol(A.propA, Decl(typeGuardFunction.ts, 1, 9)) +} + +// Call signature +interface I1 { +>I1 : Symbol(I1, Decl(typeGuardFunction.ts, 37, 1)) + + (p1: A): p1 is C; +>p1 : Symbol(p1, Decl(typeGuardFunction.ts, 41, 5)) +>A : Symbol(A, Decl(typeGuardFunction.ts, 0, 0)) +>C : Symbol(C, Decl(typeGuardFunction.ts, 7, 1)) +} + +// The parameter index and argument index for the type guard target is matching. +// The type predicate type is assignable to the parameter type. +declare function isC_multipleParams(p1, p2): p1 is C; +>isC_multipleParams : Symbol(isC_multipleParams, Decl(typeGuardFunction.ts, 42, 1)) +>p1 : Symbol(p1, Decl(typeGuardFunction.ts, 46, 36)) +>p2 : Symbol(p2, Decl(typeGuardFunction.ts, 46, 39)) +>C : Symbol(C, Decl(typeGuardFunction.ts, 7, 1)) + +if (isC_multipleParams(a, 0)) { +>isC_multipleParams : Symbol(isC_multipleParams, Decl(typeGuardFunction.ts, 42, 1)) +>a : Symbol(a, Decl(typeGuardFunction.ts, 19, 3)) + + a.propC; +>a.propC : Symbol(C.propC, Decl(typeGuardFunction.ts, 9, 19)) +>a : Symbol(a, Decl(typeGuardFunction.ts, 19, 3)) +>propC : Symbol(C.propC, Decl(typeGuardFunction.ts, 9, 19)) +} + +// Methods +var obj: { +>obj : Symbol(obj, Decl(typeGuardFunction.ts, 52, 3)) + + func1(p1: A): p1 is C; +>func1 : Symbol(func1, Decl(typeGuardFunction.ts, 52, 10)) +>p1 : Symbol(p1, Decl(typeGuardFunction.ts, 53, 10)) +>A : Symbol(A, Decl(typeGuardFunction.ts, 0, 0)) +>C : Symbol(C, Decl(typeGuardFunction.ts, 7, 1)) +} +class D { +>D : Symbol(D, Decl(typeGuardFunction.ts, 54, 1)) + + method1(p1: A): p1 is C { +>method1 : Symbol(method1, Decl(typeGuardFunction.ts, 55, 9)) +>p1 : Symbol(p1, Decl(typeGuardFunction.ts, 56, 12)) +>A : Symbol(A, Decl(typeGuardFunction.ts, 0, 0)) +>C : Symbol(C, Decl(typeGuardFunction.ts, 7, 1)) + + return true; + } +} + +// Arrow function +let f1 = (p1: A): p1 is C => false; +>f1 : Symbol(f1, Decl(typeGuardFunction.ts, 62, 3)) +>p1 : Symbol(p1, Decl(typeGuardFunction.ts, 62, 10)) +>A : Symbol(A, Decl(typeGuardFunction.ts, 0, 0)) +>C : Symbol(C, Decl(typeGuardFunction.ts, 7, 1)) + +// Function type +declare function f2(p1: (p1: A) => p1 is C); +>f2 : Symbol(f2, Decl(typeGuardFunction.ts, 62, 35)) +>p1 : Symbol(p1, Decl(typeGuardFunction.ts, 65, 20)) +>p1 : Symbol(p1, Decl(typeGuardFunction.ts, 65, 25)) +>A : Symbol(A, Decl(typeGuardFunction.ts, 0, 0)) +>C : Symbol(C, Decl(typeGuardFunction.ts, 7, 1)) + +// Function expressions +f2(function(p1: A): p1 is C { +>f2 : Symbol(f2, Decl(typeGuardFunction.ts, 62, 35)) +>p1 : Symbol(p1, Decl(typeGuardFunction.ts, 68, 12)) +>A : Symbol(A, Decl(typeGuardFunction.ts, 0, 0)) +>C : Symbol(C, Decl(typeGuardFunction.ts, 7, 1)) + + return true; +}); + +// Evaluations are asssignable to boolean. +declare function acceptingBoolean(a: boolean); +>acceptingBoolean : Symbol(acceptingBoolean, Decl(typeGuardFunction.ts, 70, 3)) +>a : Symbol(a, Decl(typeGuardFunction.ts, 73, 34)) + +acceptingBoolean(isA(a)); +>acceptingBoolean : Symbol(acceptingBoolean, Decl(typeGuardFunction.ts, 70, 3)) +>isA : Symbol(isA, Decl(typeGuardFunction.ts, 11, 1)) +>a : Symbol(a, Decl(typeGuardFunction.ts, 19, 3)) + +// Type predicates with different parameter name. +declare function acceptingTypeGuardFunction(p1: (item) => item is A); +>acceptingTypeGuardFunction : Symbol(acceptingTypeGuardFunction, Decl(typeGuardFunction.ts, 74, 25)) +>p1 : Symbol(p1, Decl(typeGuardFunction.ts, 77, 44)) +>item : Symbol(item, Decl(typeGuardFunction.ts, 77, 49)) +>A : Symbol(A, Decl(typeGuardFunction.ts, 0, 0)) + +acceptingTypeGuardFunction(isA); +>acceptingTypeGuardFunction : Symbol(acceptingTypeGuardFunction, Decl(typeGuardFunction.ts, 74, 25)) +>isA : Symbol(isA, Decl(typeGuardFunction.ts, 11, 1)) + +// Binary expressions +let union2: C | B; +>union2 : Symbol(union2, Decl(typeGuardFunction.ts, 81, 3)) +>C : Symbol(C, Decl(typeGuardFunction.ts, 7, 1)) +>B : Symbol(B, Decl(typeGuardFunction.ts, 3, 1)) + +let union3: boolean | B = isA(union2) || union2; +>union3 : Symbol(union3, Decl(typeGuardFunction.ts, 82, 3)) +>B : Symbol(B, Decl(typeGuardFunction.ts, 3, 1)) +>isA : Symbol(isA, Decl(typeGuardFunction.ts, 11, 1)) +>union2 : Symbol(union2, Decl(typeGuardFunction.ts, 81, 3)) +>union2 : Symbol(union2, Decl(typeGuardFunction.ts, 81, 3)) + diff --git a/tests/baselines/reference/typeGuardFunction.types b/tests/baselines/reference/typeGuardFunction.types new file mode 100644 index 00000000000..cf673f965f9 --- /dev/null +++ b/tests/baselines/reference/typeGuardFunction.types @@ -0,0 +1,231 @@ +=== tests/cases/conformance/expressions/typeGuards/typeGuardFunction.ts === + +class A { +>A : A + + propA: number; +>propA : number +} + +class B { +>B : B + + propB: number; +>propB : number +} + +class C extends A { +>C : C +>A : A + + propC: number; +>propC : number +} + +declare function isA(p1: any): p1 is A; +>isA : (p1: any) => boolean +>p1 : any +>p1 : any +>A : A + +declare function isB(p1: any): p1 is B; +>isB : (p1: any) => boolean +>p1 : any +>p1 : any +>B : B + +declare function isC(p1: any): p1 is C; +>isC : (p1: any) => boolean +>p1 : any +>p1 : any +>C : C + +declare function retC(): C; +>retC : () => C +>C : C + +var a: A; +>a : A +>A : A + +var b: B; +>b : B +>B : B + +// Basic +if (isC(a)) { +>isC(a) : boolean +>isC : (p1: any) => boolean +>a : A + + a.propC; +>a.propC : number +>a : C +>propC : number +} + +// Sub type +var subType: C; +>subType : C +>C : C + +if(isA(subType)) { +>isA(subType) : boolean +>isA : (p1: any) => boolean +>subType : C + + subType.propC; +>subType.propC : number +>subType : C +>propC : number +} + +// Union type +var union: A | B; +>union : A | B +>A : A +>B : B + +if(isA(union)) { +>isA(union) : boolean +>isA : (p1: any) => boolean +>union : A | B + + union.propA; +>union.propA : number +>union : A +>propA : number +} + +// Call signature +interface I1 { +>I1 : I1 + + (p1: A): p1 is C; +>p1 : A +>A : A +>p1 : any +>C : C +} + +// The parameter index and argument index for the type guard target is matching. +// The type predicate type is assignable to the parameter type. +declare function isC_multipleParams(p1, p2): p1 is C; +>isC_multipleParams : (p1: any, p2: any) => boolean +>p1 : any +>p2 : any +>p1 : any +>C : C + +if (isC_multipleParams(a, 0)) { +>isC_multipleParams(a, 0) : boolean +>isC_multipleParams : (p1: any, p2: any) => boolean +>a : A +>0 : number + + a.propC; +>a.propC : number +>a : C +>propC : number +} + +// Methods +var obj: { +>obj : { func1(p1: A): boolean; } + + func1(p1: A): p1 is C; +>func1 : (p1: A) => boolean +>p1 : A +>A : A +>p1 : any +>C : C +} +class D { +>D : D + + method1(p1: A): p1 is C { +>method1 : (p1: A) => boolean +>p1 : A +>A : A +>p1 : any +>C : C + + return true; +>true : boolean + } +} + +// Arrow function +let f1 = (p1: A): p1 is C => false; +>f1 : (p1: A) => boolean +>(p1: A): p1 is C => false : (p1: A) => boolean +>p1 : A +>A : A +>p1 : any +>C : C +>false : boolean + +// Function type +declare function f2(p1: (p1: A) => p1 is C); +>f2 : (p1: (p1: A) => boolean) => any +>p1 : (p1: A) => boolean +>p1 : A +>A : A +>p1 : any +>C : C + +// Function expressions +f2(function(p1: A): p1 is C { +>f2(function(p1: A): p1 is C { return true;}) : any +>f2 : (p1: (p1: A) => boolean) => any +>function(p1: A): p1 is C { return true;} : (p1: A) => boolean +>p1 : A +>A : A +>p1 : any +>C : C + + return true; +>true : boolean + +}); + +// Evaluations are asssignable to boolean. +declare function acceptingBoolean(a: boolean); +>acceptingBoolean : (a: boolean) => any +>a : boolean + +acceptingBoolean(isA(a)); +>acceptingBoolean(isA(a)) : any +>acceptingBoolean : (a: boolean) => any +>isA(a) : boolean +>isA : (p1: any) => boolean +>a : A + +// Type predicates with different parameter name. +declare function acceptingTypeGuardFunction(p1: (item) => item is A); +>acceptingTypeGuardFunction : (p1: (item: any) => boolean) => any +>p1 : (item: any) => boolean +>item : any +>item : any +>A : A + +acceptingTypeGuardFunction(isA); +>acceptingTypeGuardFunction(isA) : any +>acceptingTypeGuardFunction : (p1: (item: any) => boolean) => any +>isA : (p1: any) => boolean + +// Binary expressions +let union2: C | B; +>union2 : B | C +>C : C +>B : B + +let union3: boolean | B = isA(union2) || union2; +>union3 : boolean | B +>B : B +>isA(union2) || union2 : boolean | B +>isA(union2) : boolean +>isA : (p1: any) => boolean +>union2 : B | C +>union2 : B + diff --git a/tests/baselines/reference/typeGuardFunctionErrors.errors.txt b/tests/baselines/reference/typeGuardFunctionErrors.errors.txt new file mode 100644 index 00000000000..1542bbe0fee --- /dev/null +++ b/tests/baselines/reference/typeGuardFunctionErrors.errors.txt @@ -0,0 +1,240 @@ +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(22,33): error TS2304: Cannot find name 'x'. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(26,10): error TS2391: Function implementation is missing or not immediately following the declaration. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(27,5): error TS1131: Property or signature expected. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(28,1): error TS1128: Declaration or statement expected. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(30,38): error TS1225: Cannot find parameter 'x'. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(34,51): error TS2322: Type 'B' is not assignable to type 'A'. + Property 'propA' is missing in type 'B'. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(38,56): error TS2322: Type 'number' is not assignable to type 'string'. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(42,56): error TS2322: Type 'T[]' is not assignable to type 'string'. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(56,7): error TS2339: Property 'propB' does not exist on type 'A'. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(61,7): error TS2339: Property 'propB' does not exist on type 'A'. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(66,7): error TS2339: Property 'propB' does not exist on type 'A'. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(71,46): error TS2345: Argument of type '(p1: any) => boolean' is not assignable to parameter of type '(p1: any) => boolean'. + 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(75,1): error TS2322: Type '(p1: any, p2: any) => boolean' is not assignable to type '(p1: any, p2: any) => boolean'. + Signature '(p1: any, p2: any): boolean' must have a type predicate. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(81,1): error TS2322: Type '(p1: any, p2: any) => boolean' is not assignable to type '(p1: any, p2: any) => boolean'. + Type predicate 'p2 is A' is not assignable to 'p1 is A'. + Parameter 'p2' is not in the same position as parameter 'p1'. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(87,1): error TS2322: Type '(p1: any, p2: any, p3: any) => boolean' is not assignable to type '(p1: any, p2: any) => boolean'. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(92,9): error TS1228: A type predicate is only allowed in return type position for functions and methods. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(93,16): error TS1228: A type predicate is only allowed in return type position for functions and methods. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(94,20): error TS1228: A type predicate is only allowed in return type position for functions and methods. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(100,25): error TS1228: A type predicate is only allowed in return type position for functions and methods. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(101,16): error TS2409: Return type of constructor signature must be assignable to the instance type of the class +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(103,20): error TS1228: A type predicate is only allowed in return type position for functions and methods. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(106,20): error TS1228: A type predicate is only allowed in return type position for functions and methods. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(107,16): error TS2408: Setters cannot return a value. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(112,18): error TS1228: A type predicate is only allowed in return type position for functions and methods. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(116,22): error TS1228: A type predicate is only allowed in return type position for functions and methods. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(120,20): error TS1229: A type predicate cannot reference a rest parameter. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(125,34): error TS1230: A type predicate cannot reference element 'p1' in a binding pattern. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(129,34): error TS1230: A type predicate cannot reference element 'p1' in a binding pattern. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(133,39): error TS1230: A type predicate cannot reference element 'p1' in a binding pattern. + + +==== tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts (30 errors) ==== + + class A { + propA: number; + } + + class B { + propB: number; + } + + class C extends A { + propC: number; + } + + function hasANonBooleanReturnStatement(x): x is A { + return ''; + ~~ +!!! error TS2322: Type 'string' is not assignable to type 'boolean'. + } + + function hasTypeGuardTypeInsideTypeGuardType(x): x is x is A { + return true; + } + + function hasMissingIsKeyword(): x { + ~ +!!! error TS2304: Cannot find name 'x'. + return true; + } + + function hasMissingTypeInTypeGuardType(x): x is { + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2391: Function implementation is missing or not immediately following the declaration. + return true; + ~~~~~~ +!!! error TS1131: Property or signature expected. + } + ~ +!!! error TS1128: Declaration or statement expected. + + function hasNonMatchingParameter(y): x is A { + ~ +!!! error TS1225: Cannot find parameter 'x'. + return true; + } + + function hasNonMatchingParameterType1(x: A): x is B { + ~ +!!! error TS2322: Type 'B' is not assignable to type 'A'. +!!! error TS2322: Property 'propA' is missing in type 'B'. + return true; + } + + function hasNonMatchingParameterType2(x: string): x is number { + ~~~~~~ +!!! error TS2322: Type 'number' is not assignable to type 'string'. + return true; + } + + function hasNonMathcingGenericType(a: string): a is T[] { + ~~~ +!!! error TS2322: Type 'T[]' is not assignable to type 'string'. + return true; + } + + let a: A; + let b: B; + + declare function isB(p1): p1 is B; + declare function isC(p1): p1 is C; + declare function funA(p1: any, p2: any): p1 is B; + declare function hasNoTypeGuard(x); + + // Passed argument is not the same as the one being guarded. + if (isB(b)) { + a.propB; + ~~~~~ +!!! error TS2339: Property 'propB' does not exist on type 'A'. + } + + // Parameter index and argument index for the type guard target is not matching. + if (funA(0, a)) { + a.propB; // Error + ~~~~~ +!!! error TS2339: Property 'propB' does not exist on type 'A'. + } + + // No type guard in if statement + if (hasNoTypeGuard(a)) { + a.propB; + ~~~~~ +!!! error TS2339: Property 'propB' does not exist on type 'A'. + } + + // Type predicate type is not assignable + declare function acceptingDifferentSignatureTypeGuardFunction(p1: (p1) => p1 is B); + acceptingDifferentSignatureTypeGuardFunction(isC); + ~~~ +!!! error TS2345: Argument of type '(p1: any) => boolean' is not assignable to parameter of type '(p1: any) => boolean'. +!!! error TS2345: Type predicate 'p1 is C' is not assignable to 'p1 is B'. +!!! error TS2345: Type 'C' is not assignable to type 'B'. + + // 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) => boolean'. +!!! error TS2322: Signature '(p1: any, p2: any): boolean' must have a type predicate. + return true; + }; + + // Must have matching parameter index + var assign2: (p1, p2) => p1 is A; + assign2 = function(p1, p2): p2 is A { + ~~~~~~~ +!!! error TS2322: Type '(p1: any, p2: any) => boolean' is not assignable to type '(p1: any, p2: any) => boolean'. +!!! error TS2322: Type predicate 'p2 is A' is not assignable to 'p1 is A'. +!!! error TS2322: Parameter 'p2' is not in the same position as parameter 'p1'. + return true; + }; + + // No matching signature + var assign3: (p1, p2) => p1 is A; + assign3 = function(p1, p2, p3): p1 is A { + ~~~~~~~ +!!! error TS2322: Type '(p1: any, p2: any, p3: any) => boolean' is not assignable to type '(p1: any, p2: any) => boolean'. + return true; + }; + + // Type predicates in non-return type positions + var b1: b is A; + ~~~~~~ +!!! error TS1228: A type predicate is only allowed in return type position for functions and methods. + function b2(a: b is A) {}; + ~~~~~~ +!!! error TS1228: A type predicate is only allowed in return type position for functions and methods. + function b3(): A | b is A { + ~~~~~~ +!!! error TS1228: A type predicate is only allowed in return type position for functions and methods. + return true; + }; + + // 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 TS2409: Return type of constructor signature must be assignable to the instance type of the class + } + get m1(p1: A): p1 is C { + ~~~~~~~ +!!! error TS1228: A type predicate is only allowed in return type position for functions and methods. + return true; + } + set m2(p1: A): p1 is C { + ~~~~~~~ +!!! error TS1228: A type predicate is only allowed in return type position for functions and methods. + return true; + ~~~~ +!!! error TS2408: Setters cannot return a value. + } + } + + interface I1 { + new (p1: A): p1 is C; + ~~~~~~~ +!!! error TS1228: A type predicate is only allowed in return type position for functions and methods. + } + + interface I2 { + [index: number]: p1 is C; + ~~~~~~~ +!!! error TS1228: A type predicate is only allowed in return type position for functions and methods. + } + + // Reference to rest parameter + function b4(...a): a is A { + ~ +!!! error TS1229: A type predicate cannot reference a rest parameter. + return true; + } + + // Reference to binding pattern + function b5({a, b, p1}, p2, p3): p1 is A { + ~~ +!!! error TS1230: A type predicate cannot reference element 'p1' in a binding pattern. + return true; + } + + function b6([a, b, p1], p2, p3): p1 is A { + ~~ +!!! error TS1230: A type predicate cannot reference element 'p1' in a binding pattern. + return true; + } + + function b7({a, b, c: {p1}}, p2, p3): p1 is A { + ~~ +!!! error TS1230: A type predicate cannot reference element 'p1' in a binding pattern. + return true; + } \ No newline at end of file diff --git a/tests/baselines/reference/typeGuardFunctionErrors.js b/tests/baselines/reference/typeGuardFunctionErrors.js new file mode 100644 index 00000000000..179a3b80cf0 --- /dev/null +++ b/tests/baselines/reference/typeGuardFunctionErrors.js @@ -0,0 +1,263 @@ +//// [typeGuardFunctionErrors.ts] + +class A { + propA: number; +} + +class B { + propB: number; +} + +class C extends A { + propC: number; +} + +function hasANonBooleanReturnStatement(x): x is A { + return ''; +} + +function hasTypeGuardTypeInsideTypeGuardType(x): x is x is A { + return true; +} + +function hasMissingIsKeyword(): x { + return true; +} + +function hasMissingTypeInTypeGuardType(x): x is { + return true; +} + +function hasNonMatchingParameter(y): x is A { + return true; +} + +function hasNonMatchingParameterType1(x: A): x is B { + return true; +} + +function hasNonMatchingParameterType2(x: string): x is number { + return true; +} + +function hasNonMathcingGenericType(a: string): a is T[] { + return true; +} + +let a: A; +let b: B; + +declare function isB(p1): p1 is B; +declare function isC(p1): p1 is C; +declare function funA(p1: any, p2: any): p1 is B; +declare function hasNoTypeGuard(x); + +// Passed argument is not the same as the one being guarded. +if (isB(b)) { + a.propB; +} + +// Parameter index and argument index for the type guard target is not matching. +if (funA(0, a)) { + a.propB; // Error +} + +// No type guard in if statement +if (hasNoTypeGuard(a)) { + a.propB; +} + +// Type predicate type is not assignable +declare function acceptingDifferentSignatureTypeGuardFunction(p1: (p1) => p1 is B); +acceptingDifferentSignatureTypeGuardFunction(isC); + +// Boolean not assignable to type guard +var assign1: (p1, p2) => p1 is A; +assign1 = function(p1, p2): boolean { + return true; +}; + +// Must have matching parameter index +var assign2: (p1, p2) => p1 is A; +assign2 = function(p1, p2): p2 is A { + return true; +}; + +// No matching signature +var assign3: (p1, p2) => p1 is A; +assign3 = function(p1, p2, p3): p1 is A { + return true; +}; + +// Type predicates in non-return type positions +var b1: b is A; +function b2(a: b is A) {}; +function b3(): A | b is A { + return true; +}; + +// Non-compatiable type predicate positions for signature declarations +class D { + constructor(p1: A): p1 is C { + return true; + } + get m1(p1: A): p1 is C { + return true; + } + set m2(p1: A): p1 is C { + return true; + } +} + +interface I1 { + new (p1: A): p1 is C; +} + +interface I2 { + [index: number]: p1 is C; +} + +// Reference to rest parameter +function b4(...a): a is A { + return true; +} + +// Reference to binding pattern +function b5({a, b, p1}, p2, p3): p1 is A { + return true; +} + +function b6([a, b, p1], p2, p3): p1 is A { + return true; +} + +function b7({a, b, c: {p1}}, p2, p3): p1 is A { + return true; +} + +//// [typeGuardFunctionErrors.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; } + __.prototype = b.prototype; + d.prototype = new __(); +}; +var A = (function () { + function A() { + } + return A; +})(); +var B = (function () { + function B() { + } + return B; +})(); +var C = (function (_super) { + __extends(C, _super); + function C() { + _super.apply(this, arguments); + } + return C; +})(A); +function hasANonBooleanReturnStatement(x) { + return ''; +} +function hasTypeGuardTypeInsideTypeGuardType(x) { + return true; +} +function hasMissingIsKeyword() { + return true; +} +return true; +function hasNonMatchingParameter(y) { + return true; +} +function hasNonMatchingParameterType1(x) { + return true; +} +function hasNonMatchingParameterType2(x) { + return true; +} +function hasNonMathcingGenericType(a) { + return true; +} +var a; +var b; +// Passed argument is not the same as the one being guarded. +if (isB(b)) { + a.propB; +} +// Parameter index and argument index for the type guard target is not matching. +if (funA(0, a)) { + a.propB; // Error +} +// No type guard in if statement +if (hasNoTypeGuard(a)) { + a.propB; +} +acceptingDifferentSignatureTypeGuardFunction(isC); +// Boolean not assignable to type guard +var assign1; +assign1 = function (p1, p2) { + return true; +}; +// Must have matching parameter index +var assign2; +assign2 = function (p1, p2) { + return true; +}; +// No matching signature +var assign3; +assign3 = function (p1, p2, p3) { + return true; +}; +// Type predicates in non-return type positions +var b1; +function b2(a) { } +; +function b3() { + return true; +} +; +// Non-compatiable type predicate positions for signature declarations +var D = (function () { + function D(p1) { + return true; + } + Object.defineProperty(D.prototype, "m1", { + get: function (p1) { + return true; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(D.prototype, "m2", { + set: function (p1) { + return true; + }, + enumerable: true, + configurable: true + }); + return D; +})(); +// Reference to rest parameter +function b4() { + var a = []; + for (var _i = 0; _i < arguments.length; _i++) { + a[_i - 0] = arguments[_i]; + } + return true; +} +// Reference to binding pattern +function b5(_a, p2, p3) { + var a = _a.a, b = _a.b, p1 = _a.p1; + return true; +} +function b6(_a, p2, p3) { + var a = _a[0], b = _a[1], p1 = _a[2]; + return true; +} +function b7(_a, p2, p3) { + var a = _a.a, b = _a.b, p1 = _a.c.p1; + return true; +} diff --git a/tests/baselines/reference/typeGuardFunctionGenerics.js b/tests/baselines/reference/typeGuardFunctionGenerics.js new file mode 100644 index 00000000000..6704225a0d0 --- /dev/null +++ b/tests/baselines/reference/typeGuardFunctionGenerics.js @@ -0,0 +1,69 @@ +//// [typeGuardFunctionGenerics.ts] + +class A { + propA: number; +} + +class B { + propB: number; +} + +class C extends A { + propC: number; +} + +declare function isB(p1): p1 is B; +declare function isC(p1): p1 is C; +declare function retC(x): C; + +declare function funA(p1: (p1) => T): T; +declare function funB(p1: (p1) => T, p2: any): p2 is T; +declare function funC(p1: (p1) => p1 is T): T; +declare function funD(p1: (p1) => p1 is T, p2: any): p2 is T; +declare function funE(p1: (p1) => p1 is T, p2: U): T; + +let a: A; +let test1: boolean = funA(isB); +if (funB(retC, a)) { + a.propC; +} +let test2: B = funC(isB); +if (funD(isC, a)) { + a.propC; +} +let test3: B = funE(isB, 1); + +//// [typeGuardFunctionGenerics.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; } + __.prototype = b.prototype; + d.prototype = new __(); +}; +var A = (function () { + function A() { + } + return A; +})(); +var B = (function () { + function B() { + } + return B; +})(); +var C = (function (_super) { + __extends(C, _super); + function C() { + _super.apply(this, arguments); + } + return C; +})(A); +var a; +var test1 = funA(isB); +if (funB(retC, a)) { + a.propC; +} +var test2 = funC(isB); +if (funD(isC, a)) { + a.propC; +} +var test3 = funE(isB, 1); diff --git a/tests/baselines/reference/typeGuardFunctionGenerics.symbols b/tests/baselines/reference/typeGuardFunctionGenerics.symbols new file mode 100644 index 00000000000..0ad8fab2fdb --- /dev/null +++ b/tests/baselines/reference/typeGuardFunctionGenerics.symbols @@ -0,0 +1,125 @@ +=== tests/cases/conformance/expressions/typeGuards/typeGuardFunctionGenerics.ts === + +class A { +>A : Symbol(A, Decl(typeGuardFunctionGenerics.ts, 0, 0)) + + propA: number; +>propA : Symbol(propA, Decl(typeGuardFunctionGenerics.ts, 1, 9)) +} + +class B { +>B : Symbol(B, Decl(typeGuardFunctionGenerics.ts, 3, 1)) + + propB: number; +>propB : Symbol(propB, Decl(typeGuardFunctionGenerics.ts, 5, 9)) +} + +class C extends A { +>C : Symbol(C, Decl(typeGuardFunctionGenerics.ts, 7, 1)) +>A : Symbol(A, Decl(typeGuardFunctionGenerics.ts, 0, 0)) + + propC: number; +>propC : Symbol(propC, Decl(typeGuardFunctionGenerics.ts, 9, 19)) +} + +declare function isB(p1): p1 is B; +>isB : Symbol(isB, Decl(typeGuardFunctionGenerics.ts, 11, 1)) +>p1 : Symbol(p1, Decl(typeGuardFunctionGenerics.ts, 13, 21)) +>B : Symbol(B, Decl(typeGuardFunctionGenerics.ts, 3, 1)) + +declare function isC(p1): p1 is C; +>isC : Symbol(isC, Decl(typeGuardFunctionGenerics.ts, 13, 34)) +>p1 : Symbol(p1, Decl(typeGuardFunctionGenerics.ts, 14, 21)) +>C : Symbol(C, Decl(typeGuardFunctionGenerics.ts, 7, 1)) + +declare function retC(x): C; +>retC : Symbol(retC, Decl(typeGuardFunctionGenerics.ts, 14, 34)) +>x : Symbol(x, Decl(typeGuardFunctionGenerics.ts, 15, 22)) +>C : Symbol(C, Decl(typeGuardFunctionGenerics.ts, 7, 1)) + +declare function funA(p1: (p1) => T): T; +>funA : Symbol(funA, Decl(typeGuardFunctionGenerics.ts, 15, 28)) +>T : Symbol(T, Decl(typeGuardFunctionGenerics.ts, 17, 22)) +>p1 : Symbol(p1, Decl(typeGuardFunctionGenerics.ts, 17, 25)) +>p1 : Symbol(p1, Decl(typeGuardFunctionGenerics.ts, 17, 30)) +>T : Symbol(T, Decl(typeGuardFunctionGenerics.ts, 17, 22)) +>T : Symbol(T, Decl(typeGuardFunctionGenerics.ts, 17, 22)) + +declare function funB(p1: (p1) => T, p2: any): p2 is T; +>funB : Symbol(funB, Decl(typeGuardFunctionGenerics.ts, 17, 43)) +>T : Symbol(T, Decl(typeGuardFunctionGenerics.ts, 18, 22)) +>p1 : Symbol(p1, Decl(typeGuardFunctionGenerics.ts, 18, 25)) +>p1 : Symbol(p1, Decl(typeGuardFunctionGenerics.ts, 18, 30)) +>T : Symbol(T, Decl(typeGuardFunctionGenerics.ts, 18, 22)) +>p2 : Symbol(p2, Decl(typeGuardFunctionGenerics.ts, 18, 39)) +>T : Symbol(T, Decl(typeGuardFunctionGenerics.ts, 18, 22)) + +declare function funC(p1: (p1) => p1 is T): T; +>funC : Symbol(funC, Decl(typeGuardFunctionGenerics.ts, 18, 58)) +>T : Symbol(T, Decl(typeGuardFunctionGenerics.ts, 19, 22)) +>p1 : Symbol(p1, Decl(typeGuardFunctionGenerics.ts, 19, 25)) +>p1 : Symbol(p1, Decl(typeGuardFunctionGenerics.ts, 19, 30)) +>T : Symbol(T, Decl(typeGuardFunctionGenerics.ts, 19, 22)) +>T : Symbol(T, Decl(typeGuardFunctionGenerics.ts, 19, 22)) + +declare function funD(p1: (p1) => p1 is T, p2: any): p2 is T; +>funD : Symbol(funD, Decl(typeGuardFunctionGenerics.ts, 19, 49)) +>T : Symbol(T, Decl(typeGuardFunctionGenerics.ts, 20, 22)) +>p1 : Symbol(p1, Decl(typeGuardFunctionGenerics.ts, 20, 25)) +>p1 : Symbol(p1, Decl(typeGuardFunctionGenerics.ts, 20, 30)) +>T : Symbol(T, Decl(typeGuardFunctionGenerics.ts, 20, 22)) +>p2 : Symbol(p2, Decl(typeGuardFunctionGenerics.ts, 20, 45)) +>T : Symbol(T, Decl(typeGuardFunctionGenerics.ts, 20, 22)) + +declare function funE(p1: (p1) => p1 is T, p2: U): T; +>funE : Symbol(funE, Decl(typeGuardFunctionGenerics.ts, 20, 64)) +>T : Symbol(T, Decl(typeGuardFunctionGenerics.ts, 21, 22)) +>U : Symbol(U, Decl(typeGuardFunctionGenerics.ts, 21, 24)) +>p1 : Symbol(p1, Decl(typeGuardFunctionGenerics.ts, 21, 28)) +>p1 : Symbol(p1, Decl(typeGuardFunctionGenerics.ts, 21, 33)) +>T : Symbol(T, Decl(typeGuardFunctionGenerics.ts, 21, 22)) +>p2 : Symbol(p2, Decl(typeGuardFunctionGenerics.ts, 21, 48)) +>U : Symbol(U, Decl(typeGuardFunctionGenerics.ts, 21, 24)) +>T : Symbol(T, Decl(typeGuardFunctionGenerics.ts, 21, 22)) + +let a: A; +>a : Symbol(a, Decl(typeGuardFunctionGenerics.ts, 23, 3)) +>A : Symbol(A, Decl(typeGuardFunctionGenerics.ts, 0, 0)) + +let test1: boolean = funA(isB); +>test1 : Symbol(test1, Decl(typeGuardFunctionGenerics.ts, 24, 3)) +>funA : Symbol(funA, Decl(typeGuardFunctionGenerics.ts, 15, 28)) +>isB : Symbol(isB, Decl(typeGuardFunctionGenerics.ts, 11, 1)) + +if (funB(retC, a)) { +>funB : Symbol(funB, Decl(typeGuardFunctionGenerics.ts, 17, 43)) +>retC : Symbol(retC, Decl(typeGuardFunctionGenerics.ts, 14, 34)) +>a : Symbol(a, Decl(typeGuardFunctionGenerics.ts, 23, 3)) + + a.propC; +>a.propC : Symbol(C.propC, Decl(typeGuardFunctionGenerics.ts, 9, 19)) +>a : Symbol(a, Decl(typeGuardFunctionGenerics.ts, 23, 3)) +>propC : Symbol(C.propC, Decl(typeGuardFunctionGenerics.ts, 9, 19)) +} +let test2: B = funC(isB); +>test2 : Symbol(test2, Decl(typeGuardFunctionGenerics.ts, 28, 3)) +>B : Symbol(B, Decl(typeGuardFunctionGenerics.ts, 3, 1)) +>funC : Symbol(funC, Decl(typeGuardFunctionGenerics.ts, 18, 58)) +>isB : Symbol(isB, Decl(typeGuardFunctionGenerics.ts, 11, 1)) + +if (funD(isC, a)) { +>funD : Symbol(funD, Decl(typeGuardFunctionGenerics.ts, 19, 49)) +>isC : Symbol(isC, Decl(typeGuardFunctionGenerics.ts, 13, 34)) +>a : Symbol(a, Decl(typeGuardFunctionGenerics.ts, 23, 3)) + + a.propC; +>a.propC : Symbol(C.propC, Decl(typeGuardFunctionGenerics.ts, 9, 19)) +>a : Symbol(a, Decl(typeGuardFunctionGenerics.ts, 23, 3)) +>propC : Symbol(C.propC, Decl(typeGuardFunctionGenerics.ts, 9, 19)) +} +let test3: B = funE(isB, 1); +>test3 : Symbol(test3, Decl(typeGuardFunctionGenerics.ts, 32, 3)) +>B : Symbol(B, Decl(typeGuardFunctionGenerics.ts, 3, 1)) +>funE : Symbol(funE, Decl(typeGuardFunctionGenerics.ts, 20, 64)) +>isB : Symbol(isB, Decl(typeGuardFunctionGenerics.ts, 11, 1)) + diff --git a/tests/baselines/reference/typeGuardFunctionGenerics.types b/tests/baselines/reference/typeGuardFunctionGenerics.types new file mode 100644 index 00000000000..77162e55a40 --- /dev/null +++ b/tests/baselines/reference/typeGuardFunctionGenerics.types @@ -0,0 +1,138 @@ +=== tests/cases/conformance/expressions/typeGuards/typeGuardFunctionGenerics.ts === + +class A { +>A : A + + propA: number; +>propA : number +} + +class B { +>B : B + + propB: number; +>propB : number +} + +class C extends A { +>C : C +>A : A + + propC: number; +>propC : number +} + +declare function isB(p1): p1 is B; +>isB : (p1: any) => boolean +>p1 : any +>p1 : any +>B : B + +declare function isC(p1): p1 is C; +>isC : (p1: any) => boolean +>p1 : any +>p1 : any +>C : C + +declare function retC(x): C; +>retC : (x: any) => C +>x : any +>C : C + +declare function funA(p1: (p1) => T): T; +>funA : (p1: (p1: any) => T) => T +>T : T +>p1 : (p1: any) => T +>p1 : any +>T : T +>T : T + +declare function funB(p1: (p1) => T, p2: any): p2 is T; +>funB : (p1: (p1: any) => T, p2: any) => boolean +>T : T +>p1 : (p1: any) => T +>p1 : any +>T : T +>p2 : any +>p2 : any +>T : T + +declare function funC(p1: (p1) => p1 is T): T; +>funC : (p1: (p1: any) => boolean) => T +>T : T +>p1 : (p1: any) => boolean +>p1 : any +>p1 : any +>T : T +>T : T + +declare function funD(p1: (p1) => p1 is T, p2: any): p2 is T; +>funD : (p1: (p1: any) => boolean, p2: any) => boolean +>T : T +>p1 : (p1: any) => boolean +>p1 : any +>p1 : any +>T : T +>p2 : any +>p2 : any +>T : T + +declare function funE(p1: (p1) => p1 is T, p2: U): T; +>funE : (p1: (p1: any) => boolean, p2: U) => T +>T : T +>U : U +>p1 : (p1: any) => boolean +>p1 : any +>p1 : any +>T : T +>p2 : U +>U : U +>T : T + +let a: A; +>a : A +>A : A + +let test1: boolean = funA(isB); +>test1 : boolean +>funA(isB) : boolean +>funA : (p1: (p1: any) => T) => T +>isB : (p1: any) => boolean + +if (funB(retC, a)) { +>funB(retC, a) : boolean +>funB : (p1: (p1: any) => T, p2: any) => boolean +>retC : (x: any) => C +>a : A + + a.propC; +>a.propC : number +>a : C +>propC : number +} +let test2: B = funC(isB); +>test2 : B +>B : B +>funC(isB) : B +>funC : (p1: (p1: any) => boolean) => T +>isB : (p1: any) => boolean + +if (funD(isC, a)) { +>funD(isC, a) : boolean +>funD : (p1: (p1: any) => boolean, p2: any) => boolean +>isC : (p1: any) => boolean +>a : A + + a.propC; +>a.propC : number +>a : C +>propC : number +} +let test3: B = funE(isB, 1); +>test3 : B +>B : B +>funE(isB, 1) : B +>funE : (p1: (p1: any) => boolean, p2: U) => T +>isB : (p1: any) => boolean +>1 : number + diff --git a/tests/baselines/reference/typeGuardOfFormIsType.js b/tests/baselines/reference/typeGuardOfFormIsType.js new file mode 100644 index 00000000000..65d99319d1e --- /dev/null +++ b/tests/baselines/reference/typeGuardOfFormIsType.js @@ -0,0 +1,85 @@ +//// [typeGuardOfFormIsType.ts] + +class C1 { + p1: string; +} +class C2 { + p2: number; +} +class D1 extends C1 { + p3: number; +} +var str: string; +var num: number; +var strOrNum: string | number; + +function isC1(x: any): x is C1 { + return true; +} + +function isC2(x: any): x is C2 { + return true; +} + +function isD1(x: any): x is D1 { + return true; +} + +var c1Orc2: C1 | C2; +str = isC1(c1Orc2) && c1Orc2.p1; // C1 +num = isC2(c1Orc2) && c1Orc2.p2; // C2 +str = isD1(c1Orc2) && c1Orc2.p1; // D1 +num = isD1(c1Orc2) && c1Orc2.p3; // D1 + +var c2Ord1: C2 | D1; +num = isC2(c2Ord1) && c2Ord1.p2; // C2 +num = isD1(c2Ord1) && c2Ord1.p3; // D1 +str = isD1(c2Ord1) && c2Ord1.p1; // D1 +var r2: C2 | D1 = isC1(c2Ord1) && c2Ord1; // C2 | D1 + +//// [typeGuardOfFormIsType.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; } + __.prototype = b.prototype; + d.prototype = new __(); +}; +var C1 = (function () { + function C1() { + } + return C1; +})(); +var C2 = (function () { + function C2() { + } + return C2; +})(); +var D1 = (function (_super) { + __extends(D1, _super); + function D1() { + _super.apply(this, arguments); + } + return D1; +})(C1); +var str; +var num; +var strOrNum; +function isC1(x) { + return true; +} +function isC2(x) { + return true; +} +function isD1(x) { + return true; +} +var c1Orc2; +str = isC1(c1Orc2) && c1Orc2.p1; // C1 +num = isC2(c1Orc2) && c1Orc2.p2; // C2 +str = isD1(c1Orc2) && c1Orc2.p1; // D1 +num = isD1(c1Orc2) && c1Orc2.p3; // D1 +var c2Ord1; +num = isC2(c2Ord1) && c2Ord1.p2; // C2 +num = isD1(c2Ord1) && c2Ord1.p3; // D1 +str = isD1(c2Ord1) && c2Ord1.p1; // D1 +var r2 = isC1(c2Ord1) && c2Ord1; // C2 | D1 diff --git a/tests/baselines/reference/typeGuardOfFormIsType.symbols b/tests/baselines/reference/typeGuardOfFormIsType.symbols new file mode 100644 index 00000000000..a7bd0f4c165 --- /dev/null +++ b/tests/baselines/reference/typeGuardOfFormIsType.symbols @@ -0,0 +1,128 @@ +=== tests/cases/conformance/expressions/typeGuards/typeGuardOfFormIsType.ts === + +class C1 { +>C1 : Symbol(C1, Decl(typeGuardOfFormIsType.ts, 0, 0)) + + p1: string; +>p1 : Symbol(p1, Decl(typeGuardOfFormIsType.ts, 1, 10)) +} +class C2 { +>C2 : Symbol(C2, Decl(typeGuardOfFormIsType.ts, 3, 1)) + + p2: number; +>p2 : Symbol(p2, Decl(typeGuardOfFormIsType.ts, 4, 10)) +} +class D1 extends C1 { +>D1 : Symbol(D1, Decl(typeGuardOfFormIsType.ts, 6, 1)) +>C1 : Symbol(C1, Decl(typeGuardOfFormIsType.ts, 0, 0)) + + p3: number; +>p3 : Symbol(p3, Decl(typeGuardOfFormIsType.ts, 7, 21)) +} +var str: string; +>str : Symbol(str, Decl(typeGuardOfFormIsType.ts, 10, 3)) + +var num: number; +>num : Symbol(num, Decl(typeGuardOfFormIsType.ts, 11, 3)) + +var strOrNum: string | number; +>strOrNum : Symbol(strOrNum, Decl(typeGuardOfFormIsType.ts, 12, 3)) + +function isC1(x: any): x is C1 { +>isC1 : Symbol(isC1, Decl(typeGuardOfFormIsType.ts, 12, 30)) +>x : Symbol(x, Decl(typeGuardOfFormIsType.ts, 14, 14)) +>C1 : Symbol(C1, Decl(typeGuardOfFormIsType.ts, 0, 0)) + + return true; +} + +function isC2(x: any): x is C2 { +>isC2 : Symbol(isC2, Decl(typeGuardOfFormIsType.ts, 16, 1)) +>x : Symbol(x, Decl(typeGuardOfFormIsType.ts, 18, 14)) +>C2 : Symbol(C2, Decl(typeGuardOfFormIsType.ts, 3, 1)) + + return true; +} + +function isD1(x: any): x is D1 { +>isD1 : Symbol(isD1, Decl(typeGuardOfFormIsType.ts, 20, 1)) +>x : Symbol(x, Decl(typeGuardOfFormIsType.ts, 22, 14)) +>D1 : Symbol(D1, Decl(typeGuardOfFormIsType.ts, 6, 1)) + + return true; +} + +var c1Orc2: C1 | C2; +>c1Orc2 : Symbol(c1Orc2, Decl(typeGuardOfFormIsType.ts, 26, 3)) +>C1 : Symbol(C1, Decl(typeGuardOfFormIsType.ts, 0, 0)) +>C2 : Symbol(C2, Decl(typeGuardOfFormIsType.ts, 3, 1)) + +str = isC1(c1Orc2) && c1Orc2.p1; // C1 +>str : Symbol(str, Decl(typeGuardOfFormIsType.ts, 10, 3)) +>isC1 : Symbol(isC1, Decl(typeGuardOfFormIsType.ts, 12, 30)) +>c1Orc2 : Symbol(c1Orc2, Decl(typeGuardOfFormIsType.ts, 26, 3)) +>c1Orc2.p1 : Symbol(C1.p1, Decl(typeGuardOfFormIsType.ts, 1, 10)) +>c1Orc2 : Symbol(c1Orc2, Decl(typeGuardOfFormIsType.ts, 26, 3)) +>p1 : Symbol(C1.p1, Decl(typeGuardOfFormIsType.ts, 1, 10)) + +num = isC2(c1Orc2) && c1Orc2.p2; // C2 +>num : Symbol(num, Decl(typeGuardOfFormIsType.ts, 11, 3)) +>isC2 : Symbol(isC2, Decl(typeGuardOfFormIsType.ts, 16, 1)) +>c1Orc2 : Symbol(c1Orc2, Decl(typeGuardOfFormIsType.ts, 26, 3)) +>c1Orc2.p2 : Symbol(C2.p2, Decl(typeGuardOfFormIsType.ts, 4, 10)) +>c1Orc2 : Symbol(c1Orc2, Decl(typeGuardOfFormIsType.ts, 26, 3)) +>p2 : Symbol(C2.p2, Decl(typeGuardOfFormIsType.ts, 4, 10)) + +str = isD1(c1Orc2) && c1Orc2.p1; // D1 +>str : Symbol(str, Decl(typeGuardOfFormIsType.ts, 10, 3)) +>isD1 : Symbol(isD1, Decl(typeGuardOfFormIsType.ts, 20, 1)) +>c1Orc2 : Symbol(c1Orc2, Decl(typeGuardOfFormIsType.ts, 26, 3)) +>c1Orc2.p1 : Symbol(C1.p1, Decl(typeGuardOfFormIsType.ts, 1, 10)) +>c1Orc2 : Symbol(c1Orc2, Decl(typeGuardOfFormIsType.ts, 26, 3)) +>p1 : Symbol(C1.p1, Decl(typeGuardOfFormIsType.ts, 1, 10)) + +num = isD1(c1Orc2) && c1Orc2.p3; // D1 +>num : Symbol(num, Decl(typeGuardOfFormIsType.ts, 11, 3)) +>isD1 : Symbol(isD1, Decl(typeGuardOfFormIsType.ts, 20, 1)) +>c1Orc2 : Symbol(c1Orc2, Decl(typeGuardOfFormIsType.ts, 26, 3)) +>c1Orc2.p3 : Symbol(D1.p3, Decl(typeGuardOfFormIsType.ts, 7, 21)) +>c1Orc2 : Symbol(c1Orc2, Decl(typeGuardOfFormIsType.ts, 26, 3)) +>p3 : Symbol(D1.p3, Decl(typeGuardOfFormIsType.ts, 7, 21)) + +var c2Ord1: C2 | D1; +>c2Ord1 : Symbol(c2Ord1, Decl(typeGuardOfFormIsType.ts, 32, 3)) +>C2 : Symbol(C2, Decl(typeGuardOfFormIsType.ts, 3, 1)) +>D1 : Symbol(D1, Decl(typeGuardOfFormIsType.ts, 6, 1)) + +num = isC2(c2Ord1) && c2Ord1.p2; // C2 +>num : Symbol(num, Decl(typeGuardOfFormIsType.ts, 11, 3)) +>isC2 : Symbol(isC2, Decl(typeGuardOfFormIsType.ts, 16, 1)) +>c2Ord1 : Symbol(c2Ord1, Decl(typeGuardOfFormIsType.ts, 32, 3)) +>c2Ord1.p2 : Symbol(C2.p2, Decl(typeGuardOfFormIsType.ts, 4, 10)) +>c2Ord1 : Symbol(c2Ord1, Decl(typeGuardOfFormIsType.ts, 32, 3)) +>p2 : Symbol(C2.p2, Decl(typeGuardOfFormIsType.ts, 4, 10)) + +num = isD1(c2Ord1) && c2Ord1.p3; // D1 +>num : Symbol(num, Decl(typeGuardOfFormIsType.ts, 11, 3)) +>isD1 : Symbol(isD1, Decl(typeGuardOfFormIsType.ts, 20, 1)) +>c2Ord1 : Symbol(c2Ord1, Decl(typeGuardOfFormIsType.ts, 32, 3)) +>c2Ord1.p3 : Symbol(D1.p3, Decl(typeGuardOfFormIsType.ts, 7, 21)) +>c2Ord1 : Symbol(c2Ord1, Decl(typeGuardOfFormIsType.ts, 32, 3)) +>p3 : Symbol(D1.p3, Decl(typeGuardOfFormIsType.ts, 7, 21)) + +str = isD1(c2Ord1) && c2Ord1.p1; // D1 +>str : Symbol(str, Decl(typeGuardOfFormIsType.ts, 10, 3)) +>isD1 : Symbol(isD1, Decl(typeGuardOfFormIsType.ts, 20, 1)) +>c2Ord1 : Symbol(c2Ord1, Decl(typeGuardOfFormIsType.ts, 32, 3)) +>c2Ord1.p1 : Symbol(C1.p1, Decl(typeGuardOfFormIsType.ts, 1, 10)) +>c2Ord1 : Symbol(c2Ord1, Decl(typeGuardOfFormIsType.ts, 32, 3)) +>p1 : Symbol(C1.p1, Decl(typeGuardOfFormIsType.ts, 1, 10)) + +var r2: C2 | D1 = isC1(c2Ord1) && c2Ord1; // C2 | D1 +>r2 : Symbol(r2, Decl(typeGuardOfFormIsType.ts, 36, 3)) +>C2 : Symbol(C2, Decl(typeGuardOfFormIsType.ts, 3, 1)) +>D1 : Symbol(D1, Decl(typeGuardOfFormIsType.ts, 6, 1)) +>isC1 : Symbol(isC1, Decl(typeGuardOfFormIsType.ts, 12, 30)) +>c2Ord1 : Symbol(c2Ord1, Decl(typeGuardOfFormIsType.ts, 32, 3)) +>c2Ord1 : Symbol(c2Ord1, Decl(typeGuardOfFormIsType.ts, 32, 3)) + diff --git a/tests/baselines/reference/typeGuardOfFormIsType.types b/tests/baselines/reference/typeGuardOfFormIsType.types new file mode 100644 index 00000000000..b14e5e22910 --- /dev/null +++ b/tests/baselines/reference/typeGuardOfFormIsType.types @@ -0,0 +1,157 @@ +=== tests/cases/conformance/expressions/typeGuards/typeGuardOfFormIsType.ts === + +class C1 { +>C1 : C1 + + p1: string; +>p1 : string +} +class C2 { +>C2 : C2 + + p2: number; +>p2 : number +} +class D1 extends C1 { +>D1 : D1 +>C1 : C1 + + p3: number; +>p3 : number +} +var str: string; +>str : string + +var num: number; +>num : number + +var strOrNum: string | number; +>strOrNum : string | number + +function isC1(x: any): x is C1 { +>isC1 : (x: any) => boolean +>x : any +>x : any +>C1 : C1 + + return true; +>true : boolean +} + +function isC2(x: any): x is C2 { +>isC2 : (x: any) => boolean +>x : any +>x : any +>C2 : C2 + + return true; +>true : boolean +} + +function isD1(x: any): x is D1 { +>isD1 : (x: any) => boolean +>x : any +>x : any +>D1 : D1 + + return true; +>true : boolean +} + +var c1Orc2: C1 | C2; +>c1Orc2 : C1 | C2 +>C1 : C1 +>C2 : C2 + +str = isC1(c1Orc2) && c1Orc2.p1; // C1 +>str = isC1(c1Orc2) && c1Orc2.p1 : string +>str : string +>isC1(c1Orc2) && c1Orc2.p1 : string +>isC1(c1Orc2) : boolean +>isC1 : (x: any) => boolean +>c1Orc2 : C1 | C2 +>c1Orc2.p1 : string +>c1Orc2 : C1 +>p1 : string + +num = isC2(c1Orc2) && c1Orc2.p2; // C2 +>num = isC2(c1Orc2) && c1Orc2.p2 : number +>num : number +>isC2(c1Orc2) && c1Orc2.p2 : number +>isC2(c1Orc2) : boolean +>isC2 : (x: any) => boolean +>c1Orc2 : C1 | C2 +>c1Orc2.p2 : number +>c1Orc2 : C2 +>p2 : number + +str = isD1(c1Orc2) && c1Orc2.p1; // D1 +>str = isD1(c1Orc2) && c1Orc2.p1 : string +>str : string +>isD1(c1Orc2) && c1Orc2.p1 : string +>isD1(c1Orc2) : boolean +>isD1 : (x: any) => boolean +>c1Orc2 : C1 | C2 +>c1Orc2.p1 : string +>c1Orc2 : D1 +>p1 : string + +num = isD1(c1Orc2) && c1Orc2.p3; // D1 +>num = isD1(c1Orc2) && c1Orc2.p3 : number +>num : number +>isD1(c1Orc2) && c1Orc2.p3 : number +>isD1(c1Orc2) : boolean +>isD1 : (x: any) => boolean +>c1Orc2 : C1 | C2 +>c1Orc2.p3 : number +>c1Orc2 : D1 +>p3 : number + +var c2Ord1: C2 | D1; +>c2Ord1 : C2 | D1 +>C2 : C2 +>D1 : D1 + +num = isC2(c2Ord1) && c2Ord1.p2; // C2 +>num = isC2(c2Ord1) && c2Ord1.p2 : number +>num : number +>isC2(c2Ord1) && c2Ord1.p2 : number +>isC2(c2Ord1) : boolean +>isC2 : (x: any) => boolean +>c2Ord1 : C2 | D1 +>c2Ord1.p2 : number +>c2Ord1 : C2 +>p2 : number + +num = isD1(c2Ord1) && c2Ord1.p3; // D1 +>num = isD1(c2Ord1) && c2Ord1.p3 : number +>num : number +>isD1(c2Ord1) && c2Ord1.p3 : number +>isD1(c2Ord1) : boolean +>isD1 : (x: any) => boolean +>c2Ord1 : C2 | D1 +>c2Ord1.p3 : number +>c2Ord1 : D1 +>p3 : number + +str = isD1(c2Ord1) && c2Ord1.p1; // D1 +>str = isD1(c2Ord1) && c2Ord1.p1 : string +>str : string +>isD1(c2Ord1) && c2Ord1.p1 : string +>isD1(c2Ord1) : boolean +>isD1 : (x: any) => boolean +>c2Ord1 : C2 | D1 +>c2Ord1.p1 : string +>c2Ord1 : D1 +>p1 : string + +var r2: C2 | D1 = isC1(c2Ord1) && c2Ord1; // C2 | D1 +>r2 : C2 | D1 +>C2 : C2 +>D1 : D1 +>isC1(c2Ord1) && c2Ord1 : D1 +>isC1(c2Ord1) : boolean +>isC1 : (x: any) => boolean +>c2Ord1 : C2 | D1 +>c2Ord1 : D1 + diff --git a/tests/baselines/reference/typeGuardOfFormIsTypeOnInterfaces.js b/tests/baselines/reference/typeGuardOfFormIsTypeOnInterfaces.js new file mode 100644 index 00000000000..d5faee96e8b --- /dev/null +++ b/tests/baselines/reference/typeGuardOfFormIsTypeOnInterfaces.js @@ -0,0 +1,74 @@ +//// [typeGuardOfFormIsTypeOnInterfaces.ts] + +interface C1 { + (): C1; + prototype: C1; + p1: string; +} +interface C2 { + (): C2; + prototype: C2; + p2: number; +} +interface D1 extends C1 { + prototype: D1; + p3: number; +} +var str: string; +var num: number; +var strOrNum: string | number; + + +function isC1(x: any): x is C1 { + return true; +} + +function isC2(x: any): x is C2 { + return true; +} + +function isD1(x: any): x is D1 { + return true; +} + +var c1: C1; +var c2: C2; +var d1: D1; +var c1Orc2: C1 | C2; +str = isC1(c1Orc2) && c1Orc2.p1; // C1 +num = isC2(c1Orc2) && c1Orc2.p2; // C2 +str = isD1(c1Orc2) && c1Orc2.p1; // D1 +num = isD1(c1Orc2) && c1Orc2.p3; // D1 + +var c2Ord1: C2 | D1; +num = isC2(c2Ord1) && c2Ord1.p2; // C2 +num = isD1(c2Ord1) && c2Ord1.p3; // D1 +str = isD1(c2Ord1) && c2Ord1.p1; // D1 +var r2: C2 | D1 = isC1(c2Ord1) && c2Ord1; // C2 | D1 + +//// [typeGuardOfFormIsTypeOnInterfaces.js] +var str; +var num; +var strOrNum; +function isC1(x) { + return true; +} +function isC2(x) { + return true; +} +function isD1(x) { + return true; +} +var c1; +var c2; +var d1; +var c1Orc2; +str = isC1(c1Orc2) && c1Orc2.p1; // C1 +num = isC2(c1Orc2) && c1Orc2.p2; // C2 +str = isD1(c1Orc2) && c1Orc2.p1; // D1 +num = isD1(c1Orc2) && c1Orc2.p3; // D1 +var c2Ord1; +num = isC2(c2Ord1) && c2Ord1.p2; // C2 +num = isD1(c2Ord1) && c2Ord1.p3; // D1 +str = isD1(c2Ord1) && c2Ord1.p1; // D1 +var r2 = isC1(c2Ord1) && c2Ord1; // C2 | D1 diff --git a/tests/baselines/reference/typeGuardOfFormIsTypeOnInterfaces.symbols b/tests/baselines/reference/typeGuardOfFormIsTypeOnInterfaces.symbols new file mode 100644 index 00000000000..37249ef7659 --- /dev/null +++ b/tests/baselines/reference/typeGuardOfFormIsTypeOnInterfaces.symbols @@ -0,0 +1,159 @@ +=== tests/cases/conformance/expressions/typeGuards/typeGuardOfFormIsTypeOnInterfaces.ts === + +interface C1 { +>C1 : Symbol(C1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 0, 0)) + + (): C1; +>C1 : Symbol(C1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 0, 0)) + + prototype: C1; +>prototype : Symbol(prototype, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 2, 11)) +>C1 : Symbol(C1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 0, 0)) + + p1: string; +>p1 : Symbol(p1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 3, 18)) +} +interface C2 { +>C2 : Symbol(C2, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 5, 1)) + + (): C2; +>C2 : Symbol(C2, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 5, 1)) + + prototype: C2; +>prototype : Symbol(prototype, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 7, 11)) +>C2 : Symbol(C2, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 5, 1)) + + p2: number; +>p2 : Symbol(p2, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 8, 18)) +} +interface D1 extends C1 { +>D1 : Symbol(D1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 10, 1)) +>C1 : Symbol(C1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 0, 0)) + + prototype: D1; +>prototype : Symbol(prototype, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 11, 25)) +>D1 : Symbol(D1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 10, 1)) + + p3: number; +>p3 : Symbol(p3, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 12, 18)) +} +var str: string; +>str : Symbol(str, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 15, 3)) + +var num: number; +>num : Symbol(num, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 16, 3)) + +var strOrNum: string | number; +>strOrNum : Symbol(strOrNum, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 17, 3)) + + +function isC1(x: any): x is C1 { +>isC1 : Symbol(isC1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 17, 30)) +>x : Symbol(x, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 20, 14)) +>C1 : Symbol(C1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 0, 0)) + + return true; +} + +function isC2(x: any): x is C2 { +>isC2 : Symbol(isC2, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 22, 1)) +>x : Symbol(x, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 24, 14)) +>C2 : Symbol(C2, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 5, 1)) + + return true; +} + +function isD1(x: any): x is D1 { +>isD1 : Symbol(isD1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 26, 1)) +>x : Symbol(x, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 28, 14)) +>D1 : Symbol(D1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 10, 1)) + + return true; +} + +var c1: C1; +>c1 : Symbol(c1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 32, 3)) +>C1 : Symbol(C1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 0, 0)) + +var c2: C2; +>c2 : Symbol(c2, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 33, 3)) +>C2 : Symbol(C2, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 5, 1)) + +var d1: D1; +>d1 : Symbol(d1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 34, 3)) +>D1 : Symbol(D1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 10, 1)) + +var c1Orc2: C1 | C2; +>c1Orc2 : Symbol(c1Orc2, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 35, 3)) +>C1 : Symbol(C1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 0, 0)) +>C2 : Symbol(C2, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 5, 1)) + +str = isC1(c1Orc2) && c1Orc2.p1; // C1 +>str : Symbol(str, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 15, 3)) +>isC1 : Symbol(isC1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 17, 30)) +>c1Orc2 : Symbol(c1Orc2, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 35, 3)) +>c1Orc2.p1 : Symbol(C1.p1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 3, 18)) +>c1Orc2 : Symbol(c1Orc2, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 35, 3)) +>p1 : Symbol(C1.p1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 3, 18)) + +num = isC2(c1Orc2) && c1Orc2.p2; // C2 +>num : Symbol(num, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 16, 3)) +>isC2 : Symbol(isC2, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 22, 1)) +>c1Orc2 : Symbol(c1Orc2, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 35, 3)) +>c1Orc2.p2 : Symbol(C2.p2, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 8, 18)) +>c1Orc2 : Symbol(c1Orc2, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 35, 3)) +>p2 : Symbol(C2.p2, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 8, 18)) + +str = isD1(c1Orc2) && c1Orc2.p1; // D1 +>str : Symbol(str, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 15, 3)) +>isD1 : Symbol(isD1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 26, 1)) +>c1Orc2 : Symbol(c1Orc2, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 35, 3)) +>c1Orc2.p1 : Symbol(C1.p1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 3, 18)) +>c1Orc2 : Symbol(c1Orc2, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 35, 3)) +>p1 : Symbol(C1.p1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 3, 18)) + +num = isD1(c1Orc2) && c1Orc2.p3; // D1 +>num : Symbol(num, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 16, 3)) +>isD1 : Symbol(isD1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 26, 1)) +>c1Orc2 : Symbol(c1Orc2, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 35, 3)) +>c1Orc2.p3 : Symbol(D1.p3, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 12, 18)) +>c1Orc2 : Symbol(c1Orc2, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 35, 3)) +>p3 : Symbol(D1.p3, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 12, 18)) + +var c2Ord1: C2 | D1; +>c2Ord1 : Symbol(c2Ord1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 41, 3)) +>C2 : Symbol(C2, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 5, 1)) +>D1 : Symbol(D1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 10, 1)) + +num = isC2(c2Ord1) && c2Ord1.p2; // C2 +>num : Symbol(num, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 16, 3)) +>isC2 : Symbol(isC2, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 22, 1)) +>c2Ord1 : Symbol(c2Ord1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 41, 3)) +>c2Ord1.p2 : Symbol(C2.p2, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 8, 18)) +>c2Ord1 : Symbol(c2Ord1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 41, 3)) +>p2 : Symbol(C2.p2, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 8, 18)) + +num = isD1(c2Ord1) && c2Ord1.p3; // D1 +>num : Symbol(num, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 16, 3)) +>isD1 : Symbol(isD1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 26, 1)) +>c2Ord1 : Symbol(c2Ord1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 41, 3)) +>c2Ord1.p3 : Symbol(D1.p3, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 12, 18)) +>c2Ord1 : Symbol(c2Ord1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 41, 3)) +>p3 : Symbol(D1.p3, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 12, 18)) + +str = isD1(c2Ord1) && c2Ord1.p1; // D1 +>str : Symbol(str, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 15, 3)) +>isD1 : Symbol(isD1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 26, 1)) +>c2Ord1 : Symbol(c2Ord1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 41, 3)) +>c2Ord1.p1 : Symbol(C1.p1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 3, 18)) +>c2Ord1 : Symbol(c2Ord1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 41, 3)) +>p1 : Symbol(C1.p1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 3, 18)) + +var r2: C2 | D1 = isC1(c2Ord1) && c2Ord1; // C2 | D1 +>r2 : Symbol(r2, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 45, 3)) +>C2 : Symbol(C2, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 5, 1)) +>D1 : Symbol(D1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 10, 1)) +>isC1 : Symbol(isC1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 17, 30)) +>c2Ord1 : Symbol(c2Ord1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 41, 3)) +>c2Ord1 : Symbol(c2Ord1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 41, 3)) + diff --git a/tests/baselines/reference/typeGuardOfFormIsTypeOnInterfaces.types b/tests/baselines/reference/typeGuardOfFormIsTypeOnInterfaces.types new file mode 100644 index 00000000000..3a659d71163 --- /dev/null +++ b/tests/baselines/reference/typeGuardOfFormIsTypeOnInterfaces.types @@ -0,0 +1,188 @@ +=== tests/cases/conformance/expressions/typeGuards/typeGuardOfFormIsTypeOnInterfaces.ts === + +interface C1 { +>C1 : C1 + + (): C1; +>C1 : C1 + + prototype: C1; +>prototype : C1 +>C1 : C1 + + p1: string; +>p1 : string +} +interface C2 { +>C2 : C2 + + (): C2; +>C2 : C2 + + prototype: C2; +>prototype : C2 +>C2 : C2 + + p2: number; +>p2 : number +} +interface D1 extends C1 { +>D1 : D1 +>C1 : C1 + + prototype: D1; +>prototype : D1 +>D1 : D1 + + p3: number; +>p3 : number +} +var str: string; +>str : string + +var num: number; +>num : number + +var strOrNum: string | number; +>strOrNum : string | number + + +function isC1(x: any): x is C1 { +>isC1 : (x: any) => boolean +>x : any +>x : any +>C1 : C1 + + return true; +>true : boolean +} + +function isC2(x: any): x is C2 { +>isC2 : (x: any) => boolean +>x : any +>x : any +>C2 : C2 + + return true; +>true : boolean +} + +function isD1(x: any): x is D1 { +>isD1 : (x: any) => boolean +>x : any +>x : any +>D1 : D1 + + return true; +>true : boolean +} + +var c1: C1; +>c1 : C1 +>C1 : C1 + +var c2: C2; +>c2 : C2 +>C2 : C2 + +var d1: D1; +>d1 : D1 +>D1 : D1 + +var c1Orc2: C1 | C2; +>c1Orc2 : C1 | C2 +>C1 : C1 +>C2 : C2 + +str = isC1(c1Orc2) && c1Orc2.p1; // C1 +>str = isC1(c1Orc2) && c1Orc2.p1 : string +>str : string +>isC1(c1Orc2) && c1Orc2.p1 : string +>isC1(c1Orc2) : boolean +>isC1 : (x: any) => boolean +>c1Orc2 : C1 | C2 +>c1Orc2.p1 : string +>c1Orc2 : C1 +>p1 : string + +num = isC2(c1Orc2) && c1Orc2.p2; // C2 +>num = isC2(c1Orc2) && c1Orc2.p2 : number +>num : number +>isC2(c1Orc2) && c1Orc2.p2 : number +>isC2(c1Orc2) : boolean +>isC2 : (x: any) => boolean +>c1Orc2 : C1 | C2 +>c1Orc2.p2 : number +>c1Orc2 : C2 +>p2 : number + +str = isD1(c1Orc2) && c1Orc2.p1; // D1 +>str = isD1(c1Orc2) && c1Orc2.p1 : string +>str : string +>isD1(c1Orc2) && c1Orc2.p1 : string +>isD1(c1Orc2) : boolean +>isD1 : (x: any) => boolean +>c1Orc2 : C1 | C2 +>c1Orc2.p1 : string +>c1Orc2 : D1 +>p1 : string + +num = isD1(c1Orc2) && c1Orc2.p3; // D1 +>num = isD1(c1Orc2) && c1Orc2.p3 : number +>num : number +>isD1(c1Orc2) && c1Orc2.p3 : number +>isD1(c1Orc2) : boolean +>isD1 : (x: any) => boolean +>c1Orc2 : C1 | C2 +>c1Orc2.p3 : number +>c1Orc2 : D1 +>p3 : number + +var c2Ord1: C2 | D1; +>c2Ord1 : C2 | D1 +>C2 : C2 +>D1 : D1 + +num = isC2(c2Ord1) && c2Ord1.p2; // C2 +>num = isC2(c2Ord1) && c2Ord1.p2 : number +>num : number +>isC2(c2Ord1) && c2Ord1.p2 : number +>isC2(c2Ord1) : boolean +>isC2 : (x: any) => boolean +>c2Ord1 : C2 | D1 +>c2Ord1.p2 : number +>c2Ord1 : C2 +>p2 : number + +num = isD1(c2Ord1) && c2Ord1.p3; // D1 +>num = isD1(c2Ord1) && c2Ord1.p3 : number +>num : number +>isD1(c2Ord1) && c2Ord1.p3 : number +>isD1(c2Ord1) : boolean +>isD1 : (x: any) => boolean +>c2Ord1 : C2 | D1 +>c2Ord1.p3 : number +>c2Ord1 : D1 +>p3 : number + +str = isD1(c2Ord1) && c2Ord1.p1; // D1 +>str = isD1(c2Ord1) && c2Ord1.p1 : string +>str : string +>isD1(c2Ord1) && c2Ord1.p1 : string +>isD1(c2Ord1) : boolean +>isD1 : (x: any) => boolean +>c2Ord1 : C2 | D1 +>c2Ord1.p1 : string +>c2Ord1 : D1 +>p1 : string + +var r2: C2 | D1 = isC1(c2Ord1) && c2Ord1; // C2 | D1 +>r2 : C2 | D1 +>C2 : C2 +>D1 : D1 +>isC1(c2Ord1) && c2Ord1 : D1 +>isC1(c2Ord1) : boolean +>isC1 : (x: any) => boolean +>c2Ord1 : C2 | D1 +>c2Ord1 : D1 + diff --git a/tests/baselines/reference/typePredicateASI.js b/tests/baselines/reference/typePredicateASI.js new file mode 100644 index 00000000000..887ce121c0b --- /dev/null +++ b/tests/baselines/reference/typePredicateASI.js @@ -0,0 +1,7 @@ +//// [typePredicateASI.ts] +interface I { + foo(callback: (a: any, b: any) => void): I + is(): boolean; +} + +//// [typePredicateASI.js] diff --git a/tests/baselines/reference/typePredicateASI.symbols b/tests/baselines/reference/typePredicateASI.symbols new file mode 100644 index 00000000000..c451c4caf06 --- /dev/null +++ b/tests/baselines/reference/typePredicateASI.symbols @@ -0,0 +1,14 @@ +=== tests/cases/conformance/expressions/typeGuards/typePredicateASI.ts === +interface I { +>I : Symbol(I, Decl(typePredicateASI.ts, 0, 0)) + + foo(callback: (a: any, b: any) => void): I +>foo : Symbol(foo, Decl(typePredicateASI.ts, 0, 13)) +>callback : Symbol(callback, Decl(typePredicateASI.ts, 1, 8)) +>a : Symbol(a, Decl(typePredicateASI.ts, 1, 19)) +>b : Symbol(b, Decl(typePredicateASI.ts, 1, 26)) +>I : Symbol(I, Decl(typePredicateASI.ts, 0, 0)) + + is(): boolean; +>is : Symbol(is, Decl(typePredicateASI.ts, 1, 46)) +} diff --git a/tests/baselines/reference/typePredicateASI.types b/tests/baselines/reference/typePredicateASI.types new file mode 100644 index 00000000000..2be5e4c755b --- /dev/null +++ b/tests/baselines/reference/typePredicateASI.types @@ -0,0 +1,14 @@ +=== tests/cases/conformance/expressions/typeGuards/typePredicateASI.ts === +interface I { +>I : I + + foo(callback: (a: any, b: any) => void): I +>foo : (callback: (a: any, b: any) => void) => I +>callback : (a: any, b: any) => void +>a : any +>b : any +>I : I + + is(): boolean; +>is : () => boolean +} diff --git a/tests/cases/conformance/expressions/typeGuards/typeGuardFunction.ts b/tests/cases/conformance/expressions/typeGuards/typeGuardFunction.ts new file mode 100644 index 00000000000..57d56ccc3b6 --- /dev/null +++ b/tests/cases/conformance/expressions/typeGuards/typeGuardFunction.ts @@ -0,0 +1,83 @@ + +class A { + propA: number; +} + +class B { + propB: number; +} + +class C extends A { + propC: number; +} + +declare function isA(p1: any): p1 is A; +declare function isB(p1: any): p1 is B; +declare function isC(p1: any): p1 is C; + +declare function retC(): C; + +var a: A; +var b: B; + +// Basic +if (isC(a)) { + a.propC; +} + +// Sub type +var subType: C; +if(isA(subType)) { + subType.propC; +} + +// Union type +var union: A | B; +if(isA(union)) { + union.propA; +} + +// Call signature +interface I1 { + (p1: A): p1 is C; +} + +// The parameter index and argument index for the type guard target is matching. +// The type predicate type is assignable to the parameter type. +declare function isC_multipleParams(p1, p2): p1 is C; +if (isC_multipleParams(a, 0)) { + a.propC; +} + +// Methods +var obj: { + func1(p1: A): p1 is C; +} +class D { + method1(p1: A): p1 is C { + return true; + } +} + +// Arrow function +let f1 = (p1: A): p1 is C => false; + +// Function type +declare function f2(p1: (p1: A) => p1 is C); + +// Function expressions +f2(function(p1: A): p1 is C { + return true; +}); + +// Evaluations are asssignable to boolean. +declare function acceptingBoolean(a: boolean); +acceptingBoolean(isA(a)); + +// Type predicates with different parameter name. +declare function acceptingTypeGuardFunction(p1: (item) => item is A); +acceptingTypeGuardFunction(isA); + +// Binary expressions +let union2: C | B; +let union3: boolean | B = isA(union2) || union2; \ No newline at end of file diff --git a/tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts b/tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts new file mode 100644 index 00000000000..e157b2afe36 --- /dev/null +++ b/tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts @@ -0,0 +1,135 @@ + +class A { + propA: number; +} + +class B { + propB: number; +} + +class C extends A { + propC: number; +} + +function hasANonBooleanReturnStatement(x): x is A { + return ''; +} + +function hasTypeGuardTypeInsideTypeGuardType(x): x is x is A { + return true; +} + +function hasMissingIsKeyword(): x { + return true; +} + +function hasMissingTypeInTypeGuardType(x): x is { + return true; +} + +function hasNonMatchingParameter(y): x is A { + return true; +} + +function hasNonMatchingParameterType1(x: A): x is B { + return true; +} + +function hasNonMatchingParameterType2(x: string): x is number { + return true; +} + +function hasNonMathcingGenericType(a: string): a is T[] { + return true; +} + +let a: A; +let b: B; + +declare function isB(p1): p1 is B; +declare function isC(p1): p1 is C; +declare function funA(p1: any, p2: any): p1 is B; +declare function hasNoTypeGuard(x); + +// Passed argument is not the same as the one being guarded. +if (isB(b)) { + a.propB; +} + +// Parameter index and argument index for the type guard target is not matching. +if (funA(0, a)) { + a.propB; // Error +} + +// No type guard in if statement +if (hasNoTypeGuard(a)) { + a.propB; +} + +// Type predicate type is not assignable +declare function acceptingDifferentSignatureTypeGuardFunction(p1: (p1) => p1 is B); +acceptingDifferentSignatureTypeGuardFunction(isC); + +// Boolean not assignable to type guard +var assign1: (p1, p2) => p1 is A; +assign1 = function(p1, p2): boolean { + return true; +}; + +// Must have matching parameter index +var assign2: (p1, p2) => p1 is A; +assign2 = function(p1, p2): p2 is A { + return true; +}; + +// No matching signature +var assign3: (p1, p2) => p1 is A; +assign3 = function(p1, p2, p3): p1 is A { + return true; +}; + +// Type predicates in non-return type positions +var b1: b is A; +function b2(a: b is A) {}; +function b3(): A | b is A { + return true; +}; + +// Non-compatiable type predicate positions for signature declarations +class D { + constructor(p1: A): p1 is C { + return true; + } + get m1(p1: A): p1 is C { + return true; + } + set m2(p1: A): p1 is C { + return true; + } +} + +interface I1 { + new (p1: A): p1 is C; +} + +interface I2 { + [index: number]: p1 is C; +} + +// Reference to rest parameter +function b4(...a): a is A { + return true; +} + +// Reference to binding pattern +function b5({a, b, p1}, p2, p3): p1 is A { + return true; +} + +function b6([a, b, p1], p2, p3): p1 is A { + return true; +} + +function b7({a, b, c: {p1}}, p2, p3): p1 is A { + return true; +} \ No newline at end of file diff --git a/tests/cases/conformance/expressions/typeGuards/typeGuardFunctionGenerics.ts b/tests/cases/conformance/expressions/typeGuards/typeGuardFunctionGenerics.ts new file mode 100644 index 00000000000..d0e108b5735 --- /dev/null +++ b/tests/cases/conformance/expressions/typeGuards/typeGuardFunctionGenerics.ts @@ -0,0 +1,33 @@ + +class A { + propA: number; +} + +class B { + propB: number; +} + +class C extends A { + propC: number; +} + +declare function isB(p1): p1 is B; +declare function isC(p1): p1 is C; +declare function retC(x): C; + +declare function funA(p1: (p1) => T): T; +declare function funB(p1: (p1) => T, p2: any): p2 is T; +declare function funC(p1: (p1) => p1 is T): T; +declare function funD(p1: (p1) => p1 is T, p2: any): p2 is T; +declare function funE(p1: (p1) => p1 is T, p2: U): T; + +let a: A; +let test1: boolean = funA(isB); +if (funB(retC, a)) { + a.propC; +} +let test2: B = funC(isB); +if (funD(isC, a)) { + a.propC; +} +let test3: B = funE(isB, 1); \ No newline at end of file diff --git a/tests/cases/conformance/expressions/typeGuards/typeGuardOfFormIsType.ts b/tests/cases/conformance/expressions/typeGuards/typeGuardOfFormIsType.ts new file mode 100644 index 00000000000..9f5ca611ee9 --- /dev/null +++ b/tests/cases/conformance/expressions/typeGuards/typeGuardOfFormIsType.ts @@ -0,0 +1,37 @@ + +class C1 { + p1: string; +} +class C2 { + p2: number; +} +class D1 extends C1 { + p3: number; +} +var str: string; +var num: number; +var strOrNum: string | number; + +function isC1(x: any): x is C1 { + return true; +} + +function isC2(x: any): x is C2 { + return true; +} + +function isD1(x: any): x is D1 { + return true; +} + +var c1Orc2: C1 | C2; +str = isC1(c1Orc2) && c1Orc2.p1; // C1 +num = isC2(c1Orc2) && c1Orc2.p2; // C2 +str = isD1(c1Orc2) && c1Orc2.p1; // D1 +num = isD1(c1Orc2) && c1Orc2.p3; // D1 + +var c2Ord1: C2 | D1; +num = isC2(c2Ord1) && c2Ord1.p2; // C2 +num = isD1(c2Ord1) && c2Ord1.p3; // D1 +str = isD1(c2Ord1) && c2Ord1.p1; // D1 +var r2: C2 | D1 = isC1(c2Ord1) && c2Ord1; // C2 | D1 \ No newline at end of file diff --git a/tests/cases/conformance/expressions/typeGuards/typeGuardOfFormIsTypeOnInterfaces.ts b/tests/cases/conformance/expressions/typeGuards/typeGuardOfFormIsTypeOnInterfaces.ts new file mode 100644 index 00000000000..a199aeb1e68 --- /dev/null +++ b/tests/cases/conformance/expressions/typeGuards/typeGuardOfFormIsTypeOnInterfaces.ts @@ -0,0 +1,46 @@ + +interface C1 { + (): C1; + prototype: C1; + p1: string; +} +interface C2 { + (): C2; + prototype: C2; + p2: number; +} +interface D1 extends C1 { + prototype: D1; + p3: number; +} +var str: string; +var num: number; +var strOrNum: string | number; + + +function isC1(x: any): x is C1 { + return true; +} + +function isC2(x: any): x is C2 { + return true; +} + +function isD1(x: any): x is D1 { + return true; +} + +var c1: C1; +var c2: C2; +var d1: D1; +var c1Orc2: C1 | C2; +str = isC1(c1Orc2) && c1Orc2.p1; // C1 +num = isC2(c1Orc2) && c1Orc2.p2; // C2 +str = isD1(c1Orc2) && c1Orc2.p1; // D1 +num = isD1(c1Orc2) && c1Orc2.p3; // D1 + +var c2Ord1: C2 | D1; +num = isC2(c2Ord1) && c2Ord1.p2; // C2 +num = isD1(c2Ord1) && c2Ord1.p3; // D1 +str = isD1(c2Ord1) && c2Ord1.p1; // D1 +var r2: C2 | D1 = isC1(c2Ord1) && c2Ord1; // C2 | D1 \ No newline at end of file diff --git a/tests/cases/conformance/expressions/typeGuards/typePredicateASI.ts b/tests/cases/conformance/expressions/typeGuards/typePredicateASI.ts new file mode 100644 index 00000000000..60174710690 --- /dev/null +++ b/tests/cases/conformance/expressions/typeGuards/typePredicateASI.ts @@ -0,0 +1,4 @@ +interface I { + foo(callback: (a: any, b: any) => void): I + is(): boolean; +} \ No newline at end of file diff --git a/tests/cases/conformance/types/specifyingTypes/typeReferences/nonGenericTypeReferenceWithTypeArguments.ts b/tests/cases/conformance/types/specifyingTypes/typeReferences/nonGenericTypeReferenceWithTypeArguments.ts new file mode 100644 index 00000000000..0d84fe7ae51 --- /dev/null +++ b/tests/cases/conformance/types/specifyingTypes/typeReferences/nonGenericTypeReferenceWithTypeArguments.ts @@ -0,0 +1,22 @@ +// Check that errors are reported for non-generic types with type arguments + +class C { } +interface I { } +enum E { } +type T = { }; +var v1: C; +var v2: I; +var v3: E; +var v4: T; + +function f() { + class C { } + interface I { } + enum E { } + type T = {}; + var v1: C; + var v2: I; + var v3: E; + var v4: T; + var v5: U; +} diff --git a/tests/cases/conformance/types/typeAliases/genericTypeAliases.ts b/tests/cases/conformance/types/typeAliases/genericTypeAliases.ts new file mode 100644 index 00000000000..e26279a8a41 --- /dev/null +++ b/tests/cases/conformance/types/typeAliases/genericTypeAliases.ts @@ -0,0 +1,73 @@ +type Tree = T | { left: Tree, right: Tree }; + +var tree: Tree = { + left: { + left: 0, + right: { + left: 1, + right: 2 + }, + }, + right: 3 +}; + +type Lazy = T | (() => T); + +var ls: Lazy; +ls = "eager"; +ls = () => "lazy"; + +type Foo = T | { x: Foo }; +type Bar = U | { x: Bar }; + +// Deeply instantiated generics +var x: Foo; +var y: Bar; +x = y; +y = x; + +x = "string"; +x = { x: "hello" }; +x = { x: { x: "world" } }; + +var z: Foo; +z = 42; +z = { x: 42 }; +z = { x: { x: 42 } }; + +type Strange = string; // Type parameter not used +var s: Strange; +s = "hello"; + +interface Tuple { + a: A; + b: B; +} + +type Pair = Tuple; + +interface TaggedPair extends Pair { + tag: string; +} + +var p: TaggedPair; +p.a = 1; +p.b = 2; +p.tag = "test"; + +function f() { + type Foo = T | { x: Foo }; + var x: Foo; + return x; +} + +function g() { + type Bar = U | { x: Bar }; + var x: Bar; + return x; +} + +// Deeply instantiated generics +var a = f(); +var b = g(); +a = b; diff --git a/tests/cases/fourslash/commentsMultiModuleMultiFile.ts b/tests/cases/fourslash/commentsMultiModuleMultiFile.ts index 40d7b6d9bc4..9516ddc9abb 100644 --- a/tests/cases/fourslash/commentsMultiModuleMultiFile.ts +++ b/tests/cases/fourslash/commentsMultiModuleMultiFile.ts @@ -28,7 +28,6 @@ // this line triggers a semantic/syntactic error check, remove line when 788570 is fixed edit.insert(''); -debugger; goTo.marker('1'); verify.completionListContains("multiM", "namespace multiM", "this is multi declare namespace\nthi is multi namespace 2\nthis is multi namespace 3 comment"); diff --git a/tests/cases/fourslash/completionListWithAmbientDeclaration.ts b/tests/cases/fourslash/completionListWithAmbientDeclaration.ts index 9fb4ffef90e..5839608b099 100644 --- a/tests/cases/fourslash/completionListWithAmbientDeclaration.ts +++ b/tests/cases/fourslash/completionListWithAmbientDeclaration.ts @@ -7,7 +7,6 @@ //// declare module 'https' { //// } //// /*2*/ -debugger; goTo.marker("1"); verify.not.completionListContains("http"); goTo.marker("2"); diff --git a/tests/cases/fourslash/definitionNameOnEnumMember.ts b/tests/cases/fourslash/definitionNameOnEnumMember.ts index 3844d4a46f3..d88e1ef688e 100644 --- a/tests/cases/fourslash/definitionNameOnEnumMember.ts +++ b/tests/cases/fourslash/definitionNameOnEnumMember.ts @@ -7,6 +7,5 @@ ////} ////var enumMember = e./*1*/thirdMember; -debugger; goTo.marker("1"); verify.verifyDefinitionsName("thirdMember", "e"); \ No newline at end of file diff --git a/tests/cases/fourslash/deleteModifierBeforeVarStatement1.ts b/tests/cases/fourslash/deleteModifierBeforeVarStatement1.ts index a929e67687f..1775075f68e 100644 --- a/tests/cases/fourslash/deleteModifierBeforeVarStatement1.ts +++ b/tests/cases/fourslash/deleteModifierBeforeVarStatement1.ts @@ -34,7 +34,6 @@ goTo.position(0); // : |--- delete "\n\n///..." // 1: // 2: -debugger; edit.deleteAtCaret(100); diff --git a/tests/cases/fourslash/formattingSkippedTokens.ts b/tests/cases/fourslash/formattingSkippedTokens.ts index 3b8ec47bf38..d3e76e97354 100644 --- a/tests/cases/fourslash/formattingSkippedTokens.ts +++ b/tests/cases/fourslash/formattingSkippedTokens.ts @@ -8,7 +8,6 @@ /////*4*/ : T) { } ////} /////*5*/var x = -debugger; format.document(); goTo.marker('1'); verify.currentLineContentIs('foo(): Bar { }'); diff --git a/tests/cases/fourslash/getEmitOutputWithDeclarationFile3.ts b/tests/cases/fourslash/getEmitOutputWithDeclarationFile3.ts index 60f7b433149..dfcf49c0e1f 100644 --- a/tests/cases/fourslash/getEmitOutputWithDeclarationFile3.ts +++ b/tests/cases/fourslash/getEmitOutputWithDeclarationFile3.ts @@ -18,5 +18,4 @@ // @Filename: inputFile5.js //// var x2 = 1000; -debugger; verify.baselineGetEmitOutput(); \ No newline at end of file diff --git a/tests/cases/fourslash/getEmitOutputWithSemanticErrorsForMultipleFiles.ts b/tests/cases/fourslash/getEmitOutputWithSemanticErrorsForMultipleFiles.ts index d24bcfbf504..0c6f4786c25 100644 --- a/tests/cases/fourslash/getEmitOutputWithSemanticErrorsForMultipleFiles.ts +++ b/tests/cases/fourslash/getEmitOutputWithSemanticErrorsForMultipleFiles.ts @@ -12,5 +12,4 @@ // @Filename: inputFile2.ts //// // File not emitted, and contains semantic errors //// var semanticError: boolean = "string"; -debugger; verify.baselineGetEmitOutput(); \ No newline at end of file diff --git a/tests/cases/fourslash/getOccurrencesTryCatchFinally.ts b/tests/cases/fourslash/getOccurrencesTryCatchFinally.ts index db0f792880e..4b9a47cfe5c 100644 --- a/tests/cases/fourslash/getOccurrencesTryCatchFinally.ts +++ b/tests/cases/fourslash/getOccurrencesTryCatchFinally.ts @@ -16,7 +16,6 @@ ////[|fina/*3*/lly|] { ////} -debugger; for (var i = 1; i <= test.markers().length; i++) { goTo.marker("" + i); verify.occurrencesAtPositionCount(3); diff --git a/tests/cases/fourslash/navigateItemsLet.ts b/tests/cases/fourslash/navigateItemsLet.ts index 8a82d042738..8d6886ceb69 100644 --- a/tests/cases/fourslash/navigateItemsLet.ts +++ b/tests/cases/fourslash/navigateItemsLet.ts @@ -4,7 +4,7 @@ ////function foo() { //// {| "itemName": "d", "kind": "let", "parentName": "foo" |}let d = 10; ////} -debugger; + test.markers().forEach(marker => { verify.navigationItemsListContains( marker.data.itemName, diff --git a/tests/cases/fourslash/navigationItemsExactMatch2.ts b/tests/cases/fourslash/navigationItemsExactMatch2.ts index e96d4f65ed4..1bf4552a49b 100644 --- a/tests/cases/fourslash/navigationItemsExactMatch2.ts +++ b/tests/cases/fourslash/navigationItemsExactMatch2.ts @@ -17,7 +17,7 @@ ////function distance2(distanceParam1): void { //// var distanceLocal1; ////} -debugger; + goTo.marker("file1"); verify.navigationItemsListCount(2, "point", "exact"); verify.navigationItemsListCount(5, "distance", "prefix"); diff --git a/tests/cases/fourslash/navigationItemsOverloads2.ts b/tests/cases/fourslash/navigationItemsOverloads2.ts index 98908c84e98..2c33ef65f0d 100644 --- a/tests/cases/fourslash/navigationItemsOverloads2.ts +++ b/tests/cases/fourslash/navigationItemsOverloads2.ts @@ -8,5 +8,5 @@ ////interface I { //// interfaceMethodSignature(b: boolean): boolean; ////} -debugger; + verify.navigationItemsListCount(2, "interfaceMethodSignature", "exact"); diff --git a/tests/cases/fourslash/navigationItemsSubStringMatch.ts b/tests/cases/fourslash/navigationItemsSubStringMatch.ts index 4be74953142..071a1ae212f 100644 --- a/tests/cases/fourslash/navigationItemsSubStringMatch.ts +++ b/tests/cases/fourslash/navigationItemsSubStringMatch.ts @@ -17,7 +17,6 @@ ////// Local variables ////{| "itemName": "MymyPointThatIJustInitiated", "kind": "var", "parentName": "", "matchKind": "substring"|}var MymyPointThatIJustInitiated = new Shapes.Point(); -debugger; test.markers().forEach((marker) => { if (marker.data) { var name = marker.data.itemName; diff --git a/tests/cases/fourslash/navigationItemsSubStringMatch2.ts b/tests/cases/fourslash/navigationItemsSubStringMatch2.ts index 7ea901c9de3..5c7e3e5d202 100644 --- a/tests/cases/fourslash/navigationItemsSubStringMatch2.ts +++ b/tests/cases/fourslash/navigationItemsSubStringMatch2.ts @@ -17,7 +17,6 @@ //// INITIATED123; //// public horizon(): void; ////} -debugger; var notFoundSearchValue = "mPointThatIJustInitiated wrongKeyWord"; goTo.marker("file1"); diff --git a/tests/cases/fourslash/quickInfoDisplayPartsConst.ts b/tests/cases/fourslash/quickInfoDisplayPartsConst.ts index b3d601368b9..1e600e82775 100644 --- a/tests/cases/fourslash/quickInfoDisplayPartsConst.ts +++ b/tests/cases/fourslash/quickInfoDisplayPartsConst.ts @@ -22,7 +22,6 @@ /////*15*/h(10); /////*16*/h("hello"); -debugger; var marker = 0; function verifyConst(name: string, typeDisplay: ts.SymbolDisplayPart[], optionalNameDisplay?: ts.SymbolDisplayPart[], optionalKindModifiers?: string) { marker++; diff --git a/tests/cases/fourslash/quickInfoDisplayPartsVar.ts b/tests/cases/fourslash/quickInfoDisplayPartsVar.ts index a1f150d2457..d7666bace34 100644 --- a/tests/cases/fourslash/quickInfoDisplayPartsVar.ts +++ b/tests/cases/fourslash/quickInfoDisplayPartsVar.ts @@ -15,7 +15,6 @@ ////var /*11*/i = /*12*/h; /////*13*/h(10); /////*14*/h("hello"); -debugger; var marker = 0; function verifyVar(name: string, typeDisplay: ts.SymbolDisplayPart[], optionalNameDisplay?: ts.SymbolDisplayPart[], optionalKindModifiers?: string) { marker++; diff --git a/tests/cases/unittests/services/colorization.ts b/tests/cases/unittests/services/colorization.ts index 4351f0ccb1d..da1fa91036c 100644 --- a/tests/cases/unittests/services/colorization.ts +++ b/tests/cases/unittests/services/colorization.ts @@ -66,7 +66,6 @@ describe('Colorization', function () { describe("test getClassifications", function () { it("Returns correct token classes", function () { - debugger; testLexicalClassification("var x: string = \"foo\"; //Hello", ts.EndOfLineState.None, keyword("var"), @@ -138,7 +137,6 @@ describe('Colorization', function () { }); it("correctly classifies the continuing line of a multi-line string ending in one backslash", function () { - debugger; testLexicalClassification("\\", ts.EndOfLineState.InDoubleQuoteStringLiteral, stringLiteral("\\"),