From 07a696f7857b11c7e4c1e3caae8df9ab1adc8ca1 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 26 May 2018 08:07:25 -0700 Subject: [PATCH 01/24] Rename existing unknownType to errorType --- src/compiler/checker.ts | 296 ++++++++++++++++++++-------------------- 1 file changed, 148 insertions(+), 148 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 769cde5dcc0a2..ebabed818183d 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -99,7 +99,7 @@ namespace ts { getGlobalDiagnostics, getTypeOfSymbolAtLocation: (symbol, location) => { location = getParseTreeNode(location); - return location ? getTypeOfSymbolAtLocation(symbol, location) : unknownType; + return location ? getTypeOfSymbolAtLocation(symbol, location) : errorType; }, getSymbolsOfParameterPropertyDeclaration: (parameterIn, parameterName) => { const parameter = getParseTreeNode(parameterIn, isParameter); @@ -117,7 +117,7 @@ namespace ts { getWidenedType, getTypeFromTypeNode: nodeIn => { const node = getParseTreeNode(nodeIn, isTypeNode); - return node ? getTypeFromTypeNode(node) : unknownType; + return node ? getTypeFromTypeNode(node) : errorType; }, getParameterType: getTypeAtPosition, getReturnTypeOfSignature, @@ -152,7 +152,7 @@ namespace ts { }, getTypeAtLocation: node => { node = getParseTreeNode(node); - return node ? getTypeOfNode(node) : unknownType; + return node ? getTypeOfNode(node) : errorType; }, getPropertySymbolOfDestructuringAssignment: locationIn => { const location = getParseTreeNode(locationIn, isIdentifier); @@ -353,7 +353,7 @@ namespace ts { const anyType = createIntrinsicType(TypeFlags.Any, "any"); const autoType = createIntrinsicType(TypeFlags.Any, "any"); const wildcardType = createIntrinsicType(TypeFlags.Any, "any"); - const unknownType = createIntrinsicType(TypeFlags.Any, "unknown"); + const errorType = createIntrinsicType(TypeFlags.Any, "error"); const undefinedType = createIntrinsicType(TypeFlags.Undefined, "undefined"); const undefinedWideningType = strictNullChecks ? undefinedType : createIntrinsicType(TypeFlags.Undefined | TypeFlags.ContainsWideningType, "undefined"); const nullType = createIntrinsicType(TypeFlags.Null, "null"); @@ -398,7 +398,7 @@ namespace ts { const noTypePredicate = createIdentifierTypePredicate("<>", 0, anyType); const anySignature = createSignature(undefined, undefined, undefined, emptyArray, anyType, /*resolvedTypePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false); - const unknownSignature = createSignature(undefined, undefined, undefined, emptyArray, unknownType, /*resolvedTypePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false); + const unknownSignature = createSignature(undefined, undefined, undefined, emptyArray, errorType, /*resolvedTypePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false); const resolvingSignature = createSignature(undefined, undefined, undefined, emptyArray, anyType, /*resolvedTypePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false); const silentNeverSignature = createSignature(undefined, undefined, undefined, emptyArray, silentNeverType, /*resolvedTypePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false); const resolvingSignaturesArray = [resolvingSignature]; @@ -4377,8 +4377,8 @@ namespace ts { const pattern = declaration.parent; let parentType = getTypeForBindingElementParent(pattern.parent); // If parent has the unknown (error) type, then so does this binding element - if (parentType === unknownType) { - return unknownType; + if (parentType === errorType) { + return errorType; } // If no type was specified or inferred for parent, // infer from the initializer of the binding element if one is present. @@ -4395,7 +4395,7 @@ namespace ts { if (declaration.dotDotDotToken) { if (!isValidSpreadType(parentType)) { error(declaration, Diagnostics.Rest_types_may_only_be_created_from_object_types); - return unknownType; + return errorType; } const literalMembers: PropertyName[] = []; for (const element of pattern.elements) { @@ -4453,7 +4453,7 @@ namespace ts { getIndexTypeOfType(parentType, IndexKind.String); if (!type) { error(name, Diagnostics.Type_0_has_no_property_1_and_no_string_index_signature, typeToString(parentType), declarationNameToString(name)); - return unknownType; + return errorType; } } } @@ -4479,7 +4479,7 @@ namespace ts { else { error(declaration, Diagnostics.Type_0_has_no_property_1, typeToString(parentType), propName); } - return unknownType; + return errorType; } } } @@ -4631,7 +4631,7 @@ namespace ts { undefined; if (!expression) { - return unknownType; + return errorType; } const special = getSpecialPropertyAssignmentKind(expression); @@ -4657,7 +4657,7 @@ namespace ts { if (!jsDocType) { jsDocType = declarationType; } - else if (jsDocType !== unknownType && declarationType !== unknownType && + else if (jsDocType !== errorType && declarationType !== errorType && !isTypeIdenticalTo(jsDocType, declarationType) && !(symbol.flags & SymbolFlags.JSContainer)) { errorNextVariableOrPropertyDeclarationMustHaveSameType(jsDocType, declaration, declarationType); @@ -4900,7 +4900,7 @@ namespace ts { } // Handle variable, parameter or property if (!pushTypeResolution(symbol, TypeSystemPropertyName.Type)) { - return unknownType; + return errorType; } let type: Type; @@ -4993,7 +4993,7 @@ namespace ts { } if (!pushTypeResolution(symbol, TypeSystemPropertyName.Type)) { - return unknownType; + return errorType; } let type: Type; @@ -5090,7 +5090,7 @@ namespace ts { // up recursively calling getTypeOfAlias, causing a stack overflow. links.type = targetSymbol.flags & SymbolFlags.Value ? getTypeOfSymbol(targetSymbol) - : unknownType; + : errorType; } return links.type; } @@ -5100,11 +5100,11 @@ namespace ts { if (!links.type) { if (symbolInstantiationDepth === 100) { error(symbol.valueDeclaration, Diagnostics.Generic_type_instantiation_is_excessively_deep_and_possibly_infinite); - links.type = unknownType; + links.type = errorType; } else { if (!pushTypeResolution(symbol, TypeSystemPropertyName.Type)) { - return unknownType; + return errorType; } symbolInstantiationDepth++; let type = instantiateType(getTypeOfSymbol(links.target!), links.mapper!); @@ -5123,7 +5123,7 @@ namespace ts { if (getEffectiveTypeAnnotationNode(symbol.valueDeclaration)) { error(symbol.valueDeclaration, Diagnostics._0_is_referenced_directly_or_indirectly_in_its_own_type_annotation, symbolToString(symbol)); - return unknownType; + return errorType; } // Otherwise variable has initializer that circularly references the variable itself if (noImplicitAny) { @@ -5155,7 +5155,7 @@ namespace ts { if (symbol.flags & SymbolFlags.Alias) { return getTypeOfAlias(symbol); } - return unknownType; + return errorType; } function isReferenceToType(type: Type, target: Type) { @@ -5330,7 +5330,7 @@ namespace ts { return type.resolvedBaseConstructorType = undefinedType; } if (!pushTypeResolution(type, TypeSystemPropertyName.ResolvedBaseConstructorType)) { - return unknownType; + return errorType; } const baseConstructorType = checkExpression(baseTypeNode.expression); if (extended && baseTypeNode !== extended) { @@ -5344,11 +5344,11 @@ namespace ts { } if (!popTypeResolution()) { error(type.symbol.valueDeclaration, Diagnostics._0_is_referenced_directly_or_indirectly_in_its_own_base_expression, symbolToString(type.symbol)); - return type.resolvedBaseConstructorType = unknownType; + return type.resolvedBaseConstructorType = errorType; } if (!(baseConstructorType.flags & TypeFlags.Any) && baseConstructorType !== nullWideningType && !isConstructorType(baseConstructorType)) { error(baseTypeNode.expression, Diagnostics.Type_0_is_not_a_constructor_function_type, typeToString(baseConstructorType)); - return type.resolvedBaseConstructorType = unknownType; + return type.resolvedBaseConstructorType = errorType; } type.resolvedBaseConstructorType = baseConstructorType; } @@ -5407,7 +5407,7 @@ namespace ts { baseType = getReturnTypeOfSignature(constructors[0]); } - if (baseType === unknownType) { + if (baseType === errorType) { return type.resolvedBaseTypes = emptyArray; } if (!isValidBaseType(baseType)) { @@ -5454,7 +5454,7 @@ namespace ts { if (declaration.kind === SyntaxKind.InterfaceDeclaration && getInterfaceBaseTypeNodes(declaration)) { for (const node of getInterfaceBaseTypeNodes(declaration)!) { const baseType = getTypeFromTypeNode(node); - if (baseType !== unknownType) { + if (baseType !== errorType) { if (isValidBaseType(baseType)) { if (type !== baseType && !hasBaseType(baseType, type)) { if (type.resolvedBaseTypes === emptyArray) { @@ -5542,14 +5542,14 @@ namespace ts { // Note that we use the links object as the target here because the symbol object is used as the unique // identity for resolution of the 'type' property in SymbolLinks. if (!pushTypeResolution(symbol, TypeSystemPropertyName.DeclaredType)) { - return unknownType; + return errorType; } const declaration = find(symbol.declarations, d => isJSDocTypeAlias(d) || d.kind === SyntaxKind.TypeAliasDeclaration); const typeNode = isJSDocTypeAlias(declaration) ? declaration.typeExpression : declaration.type; // If typeNode is missing, we will error in checkJSDocTypedefTag. - let type = typeNode ? getTypeFromTypeNode(typeNode) : unknownType; + let type = typeNode ? getTypeFromTypeNode(typeNode) : errorType; if (popTypeResolution()) { const typeParameters = getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol); @@ -5562,7 +5562,7 @@ namespace ts { } } else { - type = unknownType; + type = errorType; error(declaration.name, Diagnostics.Type_alias_0_circularly_references_itself, symbolToString(symbol)); } links.declaredType = type; @@ -5687,7 +5687,7 @@ namespace ts { } function getDeclaredTypeOfSymbol(symbol: Symbol): Type { - return tryGetDeclaredTypeOfSymbol(symbol) || unknownType; + return tryGetDeclaredTypeOfSymbol(symbol) || errorType; } function tryGetDeclaredTypeOfSymbol(symbol: Symbol): Type | undefined { @@ -6486,14 +6486,14 @@ namespace ts { function getConstraintTypeFromMappedType(type: MappedType) { return type.constraintType || - (type.constraintType = instantiateType(getConstraintOfTypeParameter(getTypeParameterFromMappedType(type)), type.mapper || identityMapper) || unknownType); + (type.constraintType = instantiateType(getConstraintOfTypeParameter(getTypeParameterFromMappedType(type)), type.mapper || identityMapper) || errorType); } function getTemplateTypeFromMappedType(type: MappedType) { return type.templateType || (type.templateType = type.declaration.type ? instantiateType(addOptionality(getTypeFromTypeNode(type.declaration.type), !!(getMappedTypeModifiers(type) & MappedTypeModifiers.IncludeOptional)), type.mapper || identityMapper) : - unknownType); + errorType); } function getConstraintDeclarationForMappedType(type: MappedType) { @@ -6666,7 +6666,7 @@ namespace ts { const objectType = getBaseConstraintOfType(type.objectType) || type.objectType; const indexType = getBaseConstraintOfType(type.indexType) || type.indexType; const constraint = !isGenericObjectType(objectType) && !isGenericIndexType(indexType) ? getIndexedAccessType(objectType, indexType) : undefined; - return constraint && constraint !== unknownType ? constraint : undefined; + return constraint && constraint !== errorType ? constraint : undefined; } function getDefaultConstraintOfConditionalType(type: ConditionalType) { @@ -6824,7 +6824,7 @@ namespace ts { const baseObjectType = getBaseConstraint((t).objectType); const baseIndexType = getBaseConstraint((t).indexType); const baseIndexedAccess = baseObjectType && baseIndexType ? getIndexedAccessType(baseObjectType, baseIndexType) : undefined; - return baseIndexedAccess && baseIndexedAccess !== unknownType ? getBaseConstraint(baseIndexedAccess) : undefined; + return baseIndexedAccess && baseIndexedAccess !== errorType ? getBaseConstraint(baseIndexedAccess) : undefined; } if (t.flags & TypeFlags.Conditional) { const constraint = getConstraintOfConditionalType(t); @@ -6918,7 +6918,7 @@ namespace ts { let checkFlags = 0; for (const current of containingType.types) { const type = getApparentType(current); - if (type !== unknownType) { + if (type !== errorType) { const prop = getPropertyOfType(type, name); const modifiers = prop ? getDeclarationModifierFlagsFromSymbol(prop) : 0; if (prop && !(modifiers & excludeModifiers)) { @@ -7456,7 +7456,7 @@ namespace ts { function getReturnTypeOfSignature(signature: Signature): Type { if (!signature.resolvedReturnType) { if (!pushTypeResolution(signature, TypeSystemPropertyName.ResolvedReturnType)) { - return unknownType; + return errorType; } let type: Type; if (signature.target) { @@ -7759,7 +7759,7 @@ namespace ts { error(node, diag, typeStr, minTypeArgumentCount, typeParameters.length); if (!isJs) { // TODO: Adopt same permissive behavior in TS as in JS to reduce follow-on editing experience failures (requires editing fillMissingTypeArguments) - return unknownType; + return errorType; } } // In a type reference, the outer type parameters of the referenced class or interface are automatically @@ -7768,7 +7768,7 @@ namespace ts { const typeArguments = concatenate(type.outerTypeParameters, fillMissingTypeArguments(typeArgs, typeParameters, minTypeArgumentCount, isJs)); return createTypeReference(type, typeArguments); } - return checkNoTypeArguments(node, symbol) ? type : unknownType; + return checkNoTypeArguments(node, symbol) ? type : errorType; } function getTypeAliasInstantiation(symbol: Symbol, typeArguments: Type[] | undefined): Type { @@ -7802,11 +7802,11 @@ namespace ts { symbolToString(symbol), minTypeArgumentCount, typeParameters.length); - return unknownType; + return errorType; } return getTypeAliasInstantiation(symbol, typeArguments); } - return checkNoTypeArguments(node, symbol) ? type : unknownType; + return checkNoTypeArguments(node, symbol) ? type : errorType; } function getTypeReferenceName(node: TypeReferenceType): EntityNameOrEntityNameExpression | undefined { @@ -7837,7 +7837,7 @@ namespace ts { function getTypeReferenceType(node: NodeWithTypeArguments, symbol: Symbol): Type { const typeArguments = typeArgumentsFromTypeReferenceNode(node); // Do unconditionally so we mark type arguments as referenced. if (symbol === unknownSymbol) { - return unknownType; + return errorType; } const type = getTypeReferenceTypeWorker(node, symbol, typeArguments); @@ -7850,11 +7850,11 @@ namespace ts { if (res) { return checkNoTypeArguments(node, symbol) ? res.flags & TypeFlags.TypeParameter ? getConstrainedTypeVariable(res, node) : res : - unknownType; + errorType; } if (!(symbol.flags & SymbolFlags.Value && isJSDocTypeReference(node))) { - return unknownType; + return errorType; } const jsdocType = getJSDocTypeReference(node, symbol, typeArguments); @@ -8712,7 +8712,7 @@ namespace ts { case SyntaxKind.UniqueKeyword: links.resolvedType = node.type.kind === SyntaxKind.SymbolKeyword ? getESSymbolLikeTypeForNode(walkUpParenthesizedTypes(node.parent)) - : unknownType; + : errorType; break; } } @@ -8739,7 +8739,7 @@ namespace ts { markPropertyAsReferenced(prop, accessExpression, /*isThisAccess*/ accessExpression.expression.kind === SyntaxKind.ThisKeyword); if (isAssignmentTarget(accessExpression) && (isReferenceToReadonlyEntity(accessExpression, prop) || isReferenceThroughNamespaceImport(accessExpression))) { error(accessExpression.argumentExpression, Diagnostics.Cannot_assign_to_0_because_it_is_a_constant_or_a_read_only_property, symbolToString(prop)); - return unknownType; + return errorType; } if (cacheSymbol) { getNodeLinks(accessNode!).resolvedSymbol = prop; @@ -8792,7 +8792,7 @@ namespace ts { error(indexNode, Diagnostics.Type_0_cannot_be_used_as_an_index_type, typeToString(indexType)); } } - return unknownType; + return errorType; } function isGenericObjectType(type: Type): boolean { @@ -8912,8 +8912,8 @@ namespace ts { const propTypes: Type[] = []; for (const t of (indexType).types) { const propType = getPropertyTypeForIndexType(apparentObjectType, t, accessNode, /*cacheSymbol*/ false); - if (propType === unknownType) { - return unknownType; + if (propType === errorType) { + return errorType; } propTypes.push(propType); } @@ -9099,12 +9099,12 @@ namespace ts { if (node.isTypeOf && node.typeArguments) { // Only the non-typeof form can make use of type arguments error(node, Diagnostics.Type_arguments_cannot_be_used_here); links.resolvedSymbol = unknownSymbol; - return links.resolvedType = unknownType; + return links.resolvedType = errorType; } if (!isLiteralImportTypeNode(node)) { error(node.argument, Diagnostics.String_literal_expected); links.resolvedSymbol = unknownSymbol; - return links.resolvedType = unknownType; + return links.resolvedType = errorType; } const argumentType = getTypeFromTypeNode(node.argument); const targetMeaning = node.isTypeOf ? SymbolFlags.Value : SymbolFlags.Type; @@ -9113,7 +9113,7 @@ namespace ts { const innerModuleSymbol = resolveExternalModule(node, moduleName, Diagnostics.Cannot_find_module_0, node, /*isForAugmentation*/ false); if (!innerModuleSymbol) { links.resolvedSymbol = unknownSymbol; - return links.resolvedType = unknownType; + return links.resolvedType = errorType; } const moduleSymbol = resolveExternalModuleSymbol(innerModuleSymbol, /*dontResolveAlias*/ false); if (!nodeIsMissing(node.qualifier)) { @@ -9125,7 +9125,7 @@ namespace ts { const next = getSymbol(getExportsOfSymbol(getMergedSymbol(resolveSymbol(currentNamespace))), current.escapedText, meaning); if (!next) { error(current, Diagnostics.Namespace_0_has_no_exported_member_1, getFullyQualifiedName(currentNamespace), declarationNameToString(current)); - return links.resolvedType = unknownType; + return links.resolvedType = errorType; } getNodeLinks(current).resolvedSymbol = next; getNodeLinks(current.parent).resolvedSymbol = next; @@ -9140,7 +9140,7 @@ namespace ts { else { error(node, targetMeaning === SymbolFlags.Value ? Diagnostics.Module_0_does_not_refer_to_a_value_but_is_used_as_a_value_here : Diagnostics.Module_0_does_not_refer_to_a_type_but_is_used_as_a_type_here, moduleName); links.resolvedSymbol = unknownSymbol; - links.resolvedType = unknownType; + links.resolvedType = errorType; } } } @@ -9371,7 +9371,7 @@ namespace ts { } } error(node, Diagnostics.A_this_type_is_available_only_in_a_non_static_member_of_a_class_or_interface); - return unknownType; + return errorType; } function getTypeFromThisTypeNode(node: ThisExpression | ThisTypeNode): Type { @@ -9463,7 +9463,7 @@ namespace ts { const symbol = getSymbolAtLocation(node); return (symbol && getDeclaredTypeOfSymbol(symbol))!; // TODO: GH#18217 default: - return unknownType; + return errorType; } } @@ -13216,17 +13216,17 @@ namespace ts { return getConstraintForLocation(getTypeOfPropertyOfType(type, text), name) || isNumericLiteralName(text) && getIndexTypeOfType(type, IndexKind.Number) || getIndexTypeOfType(type, IndexKind.String) || - unknownType; + errorType; } function getTypeOfDestructuredArrayElement(type: Type, index: number) { return isTupleLikeType(type) && getTypeOfPropertyOfType(type, "" + index as __String) || checkIteratedTypeOrElementType(type, /*errorNode*/ undefined, /*allowStringInput*/ false, /*allowAsyncIterables*/ false) || - unknownType; + errorType; } function getTypeOfDestructuredSpreadExpression(type: Type) { - return createArrayType(checkIteratedTypeOrElementType(type, /*errorNode*/ undefined, /*allowStringInput*/ false, /*allowAsyncIterables*/ false) || unknownType); + return createArrayType(checkIteratedTypeOrElementType(type, /*errorNode*/ undefined, /*allowStringInput*/ false, /*allowAsyncIterables*/ false) || errorType); } function getAssignedTypeOfBinaryExpression(node: BinaryExpression): Type { @@ -13265,7 +13265,7 @@ namespace ts { case SyntaxKind.ForInStatement: return stringType; case SyntaxKind.ForOfStatement: - return checkRightHandSideOfForOf((parent).expression, (parent).awaitModifier) || unknownType; + return checkRightHandSideOfForOf((parent).expression, (parent).awaitModifier) || errorType; case SyntaxKind.BinaryExpression: return getAssignedTypeOfBinaryExpression(parent); case SyntaxKind.DeleteExpression: @@ -13279,7 +13279,7 @@ namespace ts { case SyntaxKind.ShorthandPropertyAssignment: return getAssignedTypeOfShorthandPropertyAssignment(parent); } - return unknownType; + return errorType; } function getInitialTypeOfBindingElement(node: BindingElement): Type { @@ -13309,9 +13309,9 @@ namespace ts { return stringType; } if (node.parent.parent.kind === SyntaxKind.ForOfStatement) { - return checkRightHandSideOfForOf(node.parent.parent.expression, node.parent.parent.awaitModifier) || unknownType; + return checkRightHandSideOfForOf(node.parent.parent.expression, node.parent.parent.awaitModifier) || errorType; } - return unknownType; + return errorType; } function getInitialType(node: VariableDeclaration | BindingElement) { @@ -13568,7 +13568,7 @@ namespace ts { const funcType = checkNonNullExpression(node.expression); if (funcType !== silentNeverType) { const apparentType = getApparentType(funcType); - return apparentType !== unknownType && some(getSignaturesOfType(apparentType, SignatureKind.Call), signatureHasTypePredicate); + return apparentType !== errorType && some(getSignaturesOfType(apparentType, SignatureKind.Call), signatureHasTypePredicate); } } return false; @@ -13585,7 +13585,7 @@ namespace ts { let key: string | undefined; let flowDepth = 0; if (flowAnalysisDisabled) { - return unknownType; + return errorType; } if (!reference.flowNode || !couldBeUninitialized && !(declaredType.flags & TypeFlags.Narrowable)) { return declaredType; @@ -13609,7 +13609,7 @@ namespace ts { // and disable further control flow analysis in the containing function or module body. flowAnalysisDisabled = true; reportFlowControlError(reference); - return unknownType; + return errorType; } flowDepth++; while (true) { @@ -14341,7 +14341,7 @@ namespace ts { function checkIdentifier(node: Identifier): Type { const symbol = getResolvedSymbol(node); if (symbol === unknownSymbol) { - return unknownType; + return errorType; } // As noted in ECMAScript 6 language spec, arrow functions never have an arguments objects. @@ -14419,11 +14419,11 @@ namespace ts { if (!(localOrExportSymbol.flags & SymbolFlags.Variable) && !(isInJavaScriptFile(node) && localOrExportSymbol.flags & SymbolFlags.ValueModule)) { error(node, Diagnostics.Cannot_assign_to_0_because_it_is_not_a_variable, symbolToString(symbol)); - return unknownType; + return errorType; } if (isReadonlySymbol(localOrExportSymbol)) { error(node, Diagnostics.Cannot_assign_to_0_because_it_is_a_constant_or_a_read_only_property, symbolToString(symbol)); - return unknownType; + return errorType; } } @@ -14740,7 +14740,7 @@ namespace ts { if (isInJavaScriptFile(node)) { const type = getTypeForThisExpressionFromJSDoc(container); - if (type && type !== unknownType) { + if (type && type !== errorType) { return getFlowTypeOfReference(node, type); } } @@ -14798,7 +14798,7 @@ namespace ts { else { error(node, Diagnostics.super_property_access_is_permitted_only_in_a_constructor_member_function_or_member_accessor_of_a_derived_class); } - return unknownType; + return errorType; } if (!isCallExpression && container.kind === SyntaxKind.Constructor) { @@ -14889,7 +14889,7 @@ namespace ts { if (container.parent.kind === SyntaxKind.ObjectLiteralExpression) { if (languageVersion < ScriptTarget.ES2015) { error(node, Diagnostics.super_is_only_allowed_in_members_of_object_literal_expressions_when_option_target_is_ES2015_or_higher); - return unknownType; + return errorType; } else { // for object literal assume that type of 'super' is 'any' @@ -14901,19 +14901,19 @@ namespace ts { const classLikeDeclaration = container.parent; if (!getClassExtendsHeritageClauseElement(classLikeDeclaration)) { error(node, Diagnostics.super_can_only_be_referenced_in_a_derived_class); - return unknownType; + return errorType; } const classType = getDeclaredTypeOfSymbol(getSymbolOfNode(classLikeDeclaration)); const baseClassType = classType && getBaseTypes(classType)[0]; if (!baseClassType) { - return unknownType; + return errorType; } if (container.kind === SyntaxKind.Constructor && isInConstructorArgumentInitializer(node, container)) { // issue custom error message for super property access in constructor arguments (to be aligned with old compiler) error(node, Diagnostics.super_cannot_be_referenced_in_constructor_arguments); - return unknownType; + return errorType; } return nodeCheckFlag === NodeCheckFlags.SuperStatic @@ -15517,7 +15517,7 @@ namespace ts { // var CustomTag: "h1" = "h1"; // Hello World const intrinsicElementsType = getJsxType(JsxNames.IntrinsicElements, context); - if (intrinsicElementsType !== unknownType) { + if (intrinsicElementsType !== errorType) { const stringLiteralTypeName = (valueType).value; const intrinsicProp = getPropertyOfType(intrinsicElementsType, escapeLeadingUnderscores(stringLiteralTypeName)); if (intrinsicProp) { @@ -15540,7 +15540,7 @@ namespace ts { ctor = false; if (signatures.length === 0) { // We found no signatures at all, which is an error - return unknownType; + return errorType; } } @@ -15564,7 +15564,7 @@ namespace ts { function getJsxPropsTypeFromCallSignature(sig: Signature, context: Node) { let propsType = getTypeOfFirstParameterOfSignatureWithFallback(sig, emptyObjectType); const intrinsicAttribs = getJsxType(JsxNames.IntrinsicAttributes, context); - if (intrinsicAttribs !== unknownType) { + if (intrinsicAttribs !== errorType) { propsType = intersectTypes(intrinsicAttribs, propsType); } return propsType; @@ -15601,7 +15601,7 @@ namespace ts { // Normal case -- add in IntrinsicClassElements and IntrinsicElements let apparentAttributesType = attributesType; const intrinsicClassAttribs = getJsxType(JsxNames.IntrinsicClassAttributes, context); - if (intrinsicClassAttribs !== unknownType) { + if (intrinsicClassAttribs !== errorType) { const typeParams = getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(intrinsicClassAttribs.symbol); const hostClassType = getReturnTypeOfSignature(sig); apparentAttributesType = intersectTypes( @@ -15613,7 +15613,7 @@ namespace ts { } const intrinsicAttribs = getJsxType(JsxNames.IntrinsicAttributes, context); - if (intrinsicAttribs !== unknownType) { + if (intrinsicAttribs !== errorType) { apparentAttributesType = intersectTypes(intrinsicAttribs, apparentAttributesType); } @@ -15991,7 +15991,7 @@ namespace ts { const type = checkExpression(memberDecl.expression); if (!isValidSpreadType(type)) { error(memberDecl, Diagnostics.Spread_types_may_only_be_created_from_object_types); - return unknownType; + return errorType; } spread = getSpreadType(spread, type, node.symbol, propagatedFlags, /*objectFlags*/ 0); offset = i + 1; @@ -16278,7 +16278,7 @@ namespace ts { const namespace = getJsxNamespaceAt(location); const exports = namespace && getExportsOfSymbol(namespace); const typeSymbol = exports && getSymbol(exports, name, SymbolFlags.Type); - return typeSymbol ? getDeclaredTypeOfSymbol(typeSymbol) : unknownType; + return typeSymbol ? getDeclaredTypeOfSymbol(typeSymbol) : errorType; } /** @@ -16291,7 +16291,7 @@ namespace ts { const links = getNodeLinks(node); if (!links.resolvedSymbol) { const intrinsicElementsType = getJsxType(JsxNames.IntrinsicElements, node); - if (intrinsicElementsType !== unknownType) { + if (intrinsicElementsType !== errorType) { // Property case if (!isIdentifier(node.tagName)) return Debug.fail(); const intrinsicProp = getPropertyOfType(intrinsicElementsType, node.tagName.escapedText); @@ -16468,7 +16468,7 @@ namespace ts { if (callReturnType && isTypeAssignableTo(callReturnType, jsxStatelessElementType)) { // Intersect in JSX.IntrinsicAttributes if it exists const intrinsicAttributes = getJsxType(JsxNames.IntrinsicAttributes, openingLikeElement); - if (intrinsicAttributes !== unknownType) { + if (intrinsicAttributes !== errorType) { paramType = intersectTypes(intrinsicAttributes, paramType); } return paramType; @@ -16528,7 +16528,7 @@ namespace ts { } // Intersect in JSX.IntrinsicAttributes if it exists const intrinsicAttributes = getJsxType(JsxNames.IntrinsicAttributes, openingLikeElement); - if (intrinsicAttributes !== unknownType) { + if (intrinsicAttributes !== errorType) { result = intersectTypes(intrinsicAttributes, result); } return result; @@ -16615,7 +16615,7 @@ namespace ts { // var CustomTag: "h1" = "h1"; // Hello World const intrinsicElementsType = getJsxType(JsxNames.IntrinsicElements, openingLikeElement); - if (intrinsicElementsType !== unknownType) { + if (intrinsicElementsType !== errorType) { const stringLiteralTypeName = (elementType).value; const intrinsicProp = getPropertyOfType(intrinsicElementsType, escapeLeadingUnderscores(stringLiteralTypeName)); if (intrinsicProp) { @@ -16635,7 +16635,7 @@ namespace ts { const instantiatedSignatures = getInstantiatedJsxSignatures(openingLikeElement, elementType, /*reportErrors*/ true); if (!length(instantiatedSignatures)) { - return unknownType; + return errorType; } const elemInstanceType = getUnionType(instantiatedSignatures!.map(getReturnTypeOfSignature), UnionReduction.Subtype); @@ -16675,7 +16675,7 @@ namespace ts { return links.resolvedJsxElementAttributesType = getIndexInfoOfSymbol(symbol, IndexKind.String)!.type; } else { - return links.resolvedJsxElementAttributesType = unknownType; + return links.resolvedJsxElementAttributesType = errorType; } } return links.resolvedJsxElementAttributesType; @@ -16734,7 +16734,7 @@ namespace ts { function getJsxElementClassTypeAt(location: Node): Type | undefined { const type = getJsxType(JsxNames.ElementClass, location); - if (type === unknownType) return undefined; + if (type === errorType) return undefined; return type; } @@ -16915,7 +16915,7 @@ namespace ts { return type; } else { - return unknownType; + return errorType; } } @@ -17086,7 +17086,7 @@ namespace ts { (nullDiagnostic || Diagnostics.Object_is_possibly_null) ); const t = getNonNullableType(type); - return t.flags & (TypeFlags.Nullable | TypeFlags.Never) ? unknownType : t; + return t.flags & (TypeFlags.Nullable | TypeFlags.Never) ? errorType : t; } return type; } @@ -17121,7 +17121,7 @@ namespace ts { if (right.escapedText && !checkAndReportErrorForExtendingInterface(node)) { reportNonexistentProperty(right, leftType.flags & TypeFlags.TypeParameter && (leftType as TypeParameter).isThisType ? apparentType : leftType); } - return unknownType; + return errorType; } if (indexInfo.isReadonly && (isAssignmentTarget(node) || isDeleteTarget(node))) { error(node, Diagnostics.Index_signature_in_type_0_only_permits_reading, typeToString(apparentType)); @@ -17136,7 +17136,7 @@ namespace ts { if (assignmentKind) { if (isReferenceToReadonlyEntity(node, prop) || isReferenceThroughNamespaceImport(node)) { error(right, Diagnostics.Cannot_assign_to_0_because_it_is_a_constant_or_a_read_only_property, idText(right)); - return unknownType; + return errorType; } } propType = getConstraintForLocation(getTypeOfSymbol(prop), node); @@ -17441,7 +17441,7 @@ namespace ts { propertyName: __String, type: Type): boolean { - if (type === unknownType || isTypeAny(type)) { + if (type === errorType || isTypeAny(type)) { return true; } const prop = getPropertyOfType(type, propertyName); @@ -17516,25 +17516,25 @@ namespace ts { const end = node.end; grammarErrorAtPos(sourceFile, start, end - start, Diagnostics.Expression_expected); } - return unknownType; + return errorType; } const indexType = isForInVariableForNumericPropertyNames(indexExpression) ? numberType : checkExpression(indexExpression); - if (objectType === unknownType || objectType === silentNeverType) { + if (objectType === errorType || objectType === silentNeverType) { return objectType; } if (isConstEnumObjectType(objectType) && indexExpression.kind !== SyntaxKind.StringLiteral) { error(indexExpression, Diagnostics.A_const_enum_member_can_only_be_accessed_using_a_string_literal); - return unknownType; + return errorType; } return checkIndexedAccessIndexType(getIndexedAccessType(objectType, indexType, node), node); } function checkThatExpressionIsProperSymbolReference(expression: Expression, expressionType: Type, reportError: boolean): boolean { - if (expressionType === unknownType) { + if (expressionType === errorType) { // There is already an error, so no need to report one. return false; } @@ -18133,7 +18133,7 @@ namespace ts { } Debug.fail("Unsupported decorator target."); - return unknownType; + return errorType; } /** @@ -18155,7 +18155,7 @@ namespace ts { // The second argument to a decorator is its `propertyKey` if (node.kind === SyntaxKind.ClassDeclaration) { Debug.fail("Class decorators should not have a second synthetic argument."); - return unknownType; + return errorType; } if (node.kind === SyntaxKind.Parameter) { @@ -18197,12 +18197,12 @@ namespace ts { default: Debug.fail("Unsupported property name."); - return unknownType; + return errorType; } } Debug.fail("Unsupported decorator target."); - return unknownType; + return errorType; } /** @@ -18217,7 +18217,7 @@ namespace ts { // or its `parameterIndex` for a parameter decorator if (node.kind === SyntaxKind.ClassDeclaration) { Debug.fail("Class decorators should not have a third synthetic argument."); - return unknownType; + return errorType; } if (node.kind === SyntaxKind.Parameter) { @@ -18227,7 +18227,7 @@ namespace ts { if (node.kind === SyntaxKind.PropertyDeclaration) { Debug.fail("Property decorators should not have a third synthetic argument."); - return unknownType; + return errorType; } if (node.kind === SyntaxKind.MethodDeclaration || @@ -18240,7 +18240,7 @@ namespace ts { } Debug.fail("Unsupported decorator target."); - return unknownType; + return errorType; } /** @@ -18258,7 +18258,7 @@ namespace ts { } Debug.fail("Decorators should not have a fourth synthetic argument."); - return unknownType; + return errorType; } /** @@ -18602,7 +18602,7 @@ namespace ts { if (isTypeAny(superType)) { return anySignature; } - if (superType !== unknownType) { + if (superType !== errorType) { // In super call, the candidate signatures are the matching arity signatures of the base constructor function instantiated // with the type arguments specified in the extends clause. const baseTypeNode = getClassExtendsHeritageClauseElement(getContainingClass(node)!); @@ -18626,7 +18626,7 @@ namespace ts { } const apparentType = getApparentType(funcType); - if (apparentType === unknownType) { + if (apparentType === errorType) { // Another error has already been reported return resolveErrorCall(node); } @@ -18644,7 +18644,7 @@ namespace ts { if (isUntypedFunctionCall(funcType, apparentType, callSignatures.length, constructSignatures.length)) { // The unknownType indicates that an error already occurred (and was reported). No // need to report another error in this case. - if (funcType !== unknownType && node.typeArguments) { + if (funcType !== errorType && node.typeArguments) { error(node, Diagnostics.Untyped_function_calls_may_not_accept_type_arguments); } return resolveUntypedCall(node); @@ -18694,7 +18694,7 @@ namespace ts { // signatures for overload resolution. The result type of the function call becomes // the result type of the operation. expressionType = getApparentType(expressionType); - if (expressionType === unknownType) { + if (expressionType === errorType) { // Another error has already been reported return resolveErrorCall(node); } @@ -18820,7 +18820,7 @@ namespace ts { const tagType = checkExpression(node.tag); const apparentType = getApparentType(tagType); - if (apparentType === unknownType) { + if (apparentType === errorType) { // Another error has already been reported return resolveErrorCall(node); } @@ -18871,7 +18871,7 @@ namespace ts { function resolveDecorator(node: Decorator, candidatesOutArray: Signature[] | undefined): Signature { const funcType = checkExpression(node.expression); const apparentType = getApparentType(funcType); - if (apparentType === unknownType) { + if (apparentType === errorType) { return resolveErrorCall(node); } @@ -19173,7 +19173,7 @@ namespace ts { } function getTypeWithSyntheticDefaultImportType(type: Type, symbol: Symbol, originalSymbol: Symbol): Type { - if (allowSyntheticDefaultImports && type && type !== unknownType) { + if (allowSyntheticDefaultImports && type && type !== errorType) { const synthType = type as SyntheticDefaultModuleType; if (!synthType.syntheticType) { const file = find(originalSymbol.declarations, isSourceFile); @@ -19244,7 +19244,7 @@ namespace ts { checkSourceElement(type); const targetType = getTypeFromTypeNode(type); - if (produceDiagnostics && targetType !== unknownType) { + if (produceDiagnostics && targetType !== errorType) { const widenedType = getWidenedType(exprType); if (!isTypeComparableTo(targetType, widenedType)) { checkTypeComparableTo(exprType, targetType, errNode, Diagnostics.Type_0_cannot_be_converted_to_type_1); @@ -19275,7 +19275,7 @@ namespace ts { const container = getNewTargetContainer(node); if (!container) { error(node, Diagnostics.Meta_property_0_is_only_allowed_in_the_body_of_a_function_declaration_function_expression_or_constructor, "new.target"); - return unknownType; + return errorType; } else if (container.kind === SyntaxKind.Constructor) { const symbol = getSymbolOfNode(container.parent as ClassLikeDeclaration); @@ -19294,7 +19294,7 @@ namespace ts { const file = getSourceFileOfNode(node); Debug.assert(!!(file.flags & NodeFlags.PossiblyContainsImportMeta), "Containing file is missing import meta node flag."); Debug.assert(!!file.externalModuleIndicator, "Containing file should be a module."); - return node.name.escapedText === "meta" ? getGlobalImportMetaType() : unknownType; + return node.name.escapedText === "meta" ? getGlobalImportMetaType() : errorType; } function getTypeOfParameter(symbol: Symbol) { @@ -19413,7 +19413,7 @@ namespace ts { error(func, isImportCall(func) ? Diagnostics.A_dynamic_import_call_returns_a_Promise_Make_sure_you_have_a_declaration_for_Promise_or_include_ES2015_in_your_lib_option : Diagnostics.An_async_function_or_method_must_return_a_Promise_Make_sure_you_have_a_declaration_for_Promise_or_include_ES2015_in_your_lib_option); - return unknownType; + return errorType; } else if (!getGlobalPromiseConstructorSymbol(/*reportErrors*/ true)) { error(func, isImportCall(func) ? @@ -19426,7 +19426,7 @@ namespace ts { function getReturnTypeFromBody(func: FunctionLikeDeclaration, checkMode?: CheckMode): Type { if (!func.body) { - return unknownType; + return errorType; } const functionFlags = getFunctionFlags(func); @@ -19912,7 +19912,7 @@ namespace ts { } return numberType; } - return unknownType; + return errorType; } function checkPostfixUnaryExpression(node: PostfixUnaryExpression): Type { @@ -20089,7 +20089,7 @@ namespace ts { // This elementType will be used if the specific property corresponding to this index is not // present (aka the tuple element property). This call also checks that the parentType is in // fact an iterable or array (depending on target language). - const elementType = checkIteratedTypeOrElementType(sourceType, node, /*allowStringInput*/ false, /*allowAsyncIterables*/ false) || unknownType; + const elementType = checkIteratedTypeOrElementType(sourceType, node, /*allowStringInput*/ false, /*allowAsyncIterables*/ false) || errorType; for (let i = 0; i < elements.length; i++) { checkArrayLiteralDestructuringElementAssignment(node, sourceType, i, elementType, checkMode); } @@ -20340,7 +20340,7 @@ namespace ts { else if (isTypeAny(leftType) || isTypeAny(rightType)) { // Otherwise, the result is of type Any. // NOTE: unknown type here denotes error type. Old compiler treated this case as any type so do we. - resultType = leftType === unknownType || rightType === unknownType ? unknownType : anyType; + resultType = leftType === errorType || rightType === errorType ? errorType : anyType; } // Symbols are not allowed at all in arithmetic expressions @@ -20888,7 +20888,7 @@ namespace ts { case SyntaxKind.JsxOpeningElement: Debug.fail("Shouldn't ever directly check a JsxOpeningElement"); } - return unknownType; + return errorType; } // DECLARATION AND STATEMENT TYPE CHECKING @@ -21501,7 +21501,7 @@ namespace ts { function getTypeParametersForTypeReference(node: TypeReferenceNode | ExpressionWithTypeArguments) { const type = getTypeFromTypeReference(node); - if (type !== unknownType) { + if (type !== errorType) { const symbol = getNodeLinks(node).resolvedSymbol; if (symbol) { return symbol.flags & SymbolFlags.TypeAlias && getSymbolLinks(symbol).typeParameters || @@ -21517,7 +21517,7 @@ namespace ts { grammarErrorAtPos(node, node.typeName.jsdocDotPos, 1, Diagnostics.JSDoc_types_can_only_be_used_inside_documentation_comments); } const type = getTypeFromTypeReference(node); - if (type !== unknownType) { + if (type !== errorType) { if (node.typeArguments) { // Do type argument local checks only if referenced type is successfully resolved forEach(node.typeArguments, checkSourceElement); @@ -22057,7 +22057,7 @@ namespace ts { * The runtime behavior of the `await` keyword. */ function checkAwaitedType(type: Type, errorNode: Node, diagnosticMessage: DiagnosticMessage): Type { - return getAwaitedType(type, errorNode, diagnosticMessage) || unknownType; + return getAwaitedType(type, errorNode, diagnosticMessage) || errorType; } function getAwaitedType(type: Type, errorNode?: Node, diagnosticMessage?: DiagnosticMessage): Type | undefined { @@ -22206,41 +22206,41 @@ namespace ts { const returnType = getTypeFromTypeNode(returnTypeNode); if (languageVersion >= ScriptTarget.ES2015) { - if (returnType === unknownType) { - return unknownType; + if (returnType === errorType) { + return errorType; } const globalPromiseType = getGlobalPromiseType(/*reportErrors*/ true); if (globalPromiseType !== emptyGenericType && !isReferenceToType(returnType, globalPromiseType)) { // The promise type was not a valid type reference to the global promise type, so we // report an error and return the unknown type. error(returnTypeNode, Diagnostics.The_return_type_of_an_async_function_or_method_must_be_the_global_Promise_T_type); - return unknownType; + return errorType; } } else { // Always mark the type node as referenced if it points to a value markTypeNodeAsReferenced(returnTypeNode); - if (returnType === unknownType) { - return unknownType; + if (returnType === errorType) { + return errorType; } const promiseConstructorName = getEntityNameFromTypeNode(returnTypeNode); if (promiseConstructorName === undefined) { error(returnTypeNode, Diagnostics.Type_0_is_not_a_valid_async_function_return_type_in_ES5_SlashES3_because_it_does_not_refer_to_a_Promise_compatible_constructor_value, typeToString(returnType)); - return unknownType; + return errorType; } const promiseConstructorSymbol = resolveEntityName(promiseConstructorName, SymbolFlags.Value, /*ignoreErrors*/ true); - const promiseConstructorType = promiseConstructorSymbol ? getTypeOfSymbol(promiseConstructorSymbol) : unknownType; - if (promiseConstructorType === unknownType) { + const promiseConstructorType = promiseConstructorSymbol ? getTypeOfSymbol(promiseConstructorSymbol) : errorType; + if (promiseConstructorType === errorType) { if (promiseConstructorName.kind === SyntaxKind.Identifier && promiseConstructorName.escapedText === "Promise" && getTargetType(returnType) === getGlobalPromiseType(/*reportErrors*/ false)) { error(returnTypeNode, Diagnostics.An_async_function_or_method_in_ES5_SlashES3_requires_the_Promise_constructor_Make_sure_you_have_a_declaration_for_the_Promise_constructor_or_include_ES2015_in_your_lib_option); } else { error(returnTypeNode, Diagnostics.Type_0_is_not_a_valid_async_function_return_type_in_ES5_SlashES3_because_it_does_not_refer_to_a_Promise_compatible_constructor_value, entityNameToString(promiseConstructorName)); } - return unknownType; + return errorType; } const globalPromiseConstructorLikeType = getGlobalPromiseConstructorLikeType(/*reportErrors*/ true); @@ -22248,12 +22248,12 @@ namespace ts { // If we couldn't resolve the global PromiseConstructorLike type we cannot verify // compatibility with __awaiter. error(returnTypeNode, Diagnostics.Type_0_is_not_a_valid_async_function_return_type_in_ES5_SlashES3_because_it_does_not_refer_to_a_Promise_compatible_constructor_value, entityNameToString(promiseConstructorName)); - return unknownType; + return errorType; } if (!checkTypeAssignableTo(promiseConstructorType, globalPromiseConstructorLikeType, returnTypeNode, Diagnostics.Type_0_is_not_a_valid_async_function_return_type_in_ES5_SlashES3_because_it_does_not_refer_to_a_Promise_compatible_constructor_value)) { - return unknownType; + return errorType; } // Verify there is no local declaration that could collide with the promise constructor. @@ -22263,7 +22263,7 @@ namespace ts { error(collidingSymbol.valueDeclaration, Diagnostics.Duplicate_identifier_0_Compiler_uses_declaration_1_to_support_async_functions, idText(rootName), entityNameToString(promiseConstructorName)); - return unknownType; + return errorType; } } @@ -23260,7 +23260,7 @@ namespace ts { // initializer is consistent with type associated with the node const declarationType = convertAutoToAny(getWidenedTypeForVariableLikeDeclaration(node)); - if (type !== unknownType && declarationType !== unknownType && + if (type !== errorType && declarationType !== errorType && !isTypeIdenticalTo(type, declarationType) && !(symbol.flags & SymbolFlags.JSContainer)) { errorNextVariableOrPropertyDeclarationMustHaveSameType(type, node, declarationType); @@ -23428,7 +23428,7 @@ namespace ts { // iteratedType may be undefined. In this case, we still want to check the structure of // varExpr, in particular making sure it's a valid LeftHandSideExpression. But we'd like // to short circuit the type relation checking as much as possible, so we pass the unknownType. - checkDestructuringAssignment(varExpr, iteratedType || unknownType); + checkDestructuringAssignment(varExpr, iteratedType || errorType); } else { const leftType = checkExpression(varExpr); @@ -24348,7 +24348,7 @@ namespace ts { checkTypeReferenceNode(typeRefNode); if (produceDiagnostics) { const t = getTypeFromTypeNode(typeRefNode); - if (t !== unknownType) { + if (t !== errorType) { if (isValidBaseType(t)) { const genericDiag = t.symbol && t.symbol.flags & SymbolFlags.Class ? Diagnostics.Class_0_incorrectly_implements_class_1_Did_you_mean_to_extend_1_and_inherit_its_members_as_a_subclass : @@ -26211,7 +26211,7 @@ namespace ts { function getTypeOfNode(node: Node): Type | undefined { if (node.flags & NodeFlags.InWithStatement) { // We cannot answer semantic questions within a with block, do not proceed any further - return unknownType; + return errorType; } if (isPartOfTypeNode(node)) { @@ -26269,11 +26269,11 @@ namespace ts { const symbol = getSymbolAtLocation(node); if (symbol) { const declaredType = getDeclaredTypeOfSymbol(symbol); - return declaredType !== unknownType ? declaredType : getTypeOfSymbol(symbol); + return declaredType !== errorType ? declaredType : getTypeOfSymbol(symbol); } } - return unknownType; + return errorType; } // Gets the type of object literal or array literal of destructuring assignment. @@ -26289,27 +26289,27 @@ namespace ts { // } if (expr.parent.kind === SyntaxKind.ForOfStatement) { const iteratedType = checkRightHandSideOfForOf((expr.parent).expression, (expr.parent).awaitModifier); - return checkDestructuringAssignment(expr, iteratedType || unknownType); + return checkDestructuringAssignment(expr, iteratedType || errorType); } // If this is from "for" initializer // for ({a } = elems[0];.....) { } if (expr.parent.kind === SyntaxKind.BinaryExpression) { const iteratedType = getTypeOfExpression((expr.parent).right); - return checkDestructuringAssignment(expr, iteratedType || unknownType); + return checkDestructuringAssignment(expr, iteratedType || errorType); } // If this is from nested object binding pattern // for ({ skills: { primary, secondary } } = multiRobot, i = 0; i < 1; i++) { if (expr.parent.kind === SyntaxKind.PropertyAssignment) { const typeOfParentObjectLiteral = getTypeOfArrayLiteralOrObjectLiteralDestructuringAssignment(expr.parent.parent); - return checkObjectLiteralDestructuringPropertyAssignment(typeOfParentObjectLiteral || unknownType, expr.parent)!; // TODO: GH#18217 + return checkObjectLiteralDestructuringPropertyAssignment(typeOfParentObjectLiteral || errorType, expr.parent)!; // TODO: GH#18217 } // Array literal assignment - array destructuring pattern Debug.assert(expr.parent.kind === SyntaxKind.ArrayLiteralExpression); // [{ property1: p1, property2 }] = elems; const typeOfArrayLiteral = getTypeOfArrayLiteralOrObjectLiteralDestructuringAssignment(expr.parent); - const elementType = checkIteratedTypeOrElementType(typeOfArrayLiteral || unknownType, expr.parent, /*allowStringInput*/ false, /*allowAsyncIterables*/ false) || unknownType; + const elementType = checkIteratedTypeOrElementType(typeOfArrayLiteral || errorType, expr.parent, /*allowStringInput*/ false, /*allowAsyncIterables*/ false) || errorType; return checkArrayLiteralDestructuringElementAssignment(expr.parent, typeOfArrayLiteral, - (expr.parent).elements.indexOf(expr), elementType || unknownType)!; // TODO: GH#18217 + (expr.parent).elements.indexOf(expr), elementType || errorType)!; // TODO: GH#18217 } // Gets the property symbol corresponding to the property in destructuring assignment @@ -26732,7 +26732,7 @@ namespace ts { return TypeReferenceSerializationKind.Unknown; } const type = getDeclaredTypeOfSymbol(typeSymbol); - if (type === unknownType) { + if (type === errorType) { return TypeReferenceSerializationKind.Unknown; } else if (type.flags & TypeFlags.Any) { @@ -26776,7 +26776,7 @@ namespace ts { const symbol = getSymbolOfNode(declaration); let type = symbol && !(symbol.flags & (SymbolFlags.TypeLiteral | SymbolFlags.Signature)) ? getWidenedLiteralType(getTypeOfSymbol(symbol)) - : unknownType; + : errorType; if (type.flags & TypeFlags.UniqueESSymbol && type.symbol === symbol) { flags |= NodeBuilderFlags.AllowUniqueESSymbolType; @@ -27087,7 +27087,7 @@ namespace ts { getSymbolLinks(undefinedSymbol).type = undefinedWideningType; getSymbolLinks(argumentsSymbol).type = getGlobalType("IArguments" as __String, /*arity*/ 0, /*reportErrors*/ true); - getSymbolLinks(unknownSymbol).type = unknownType; + getSymbolLinks(unknownSymbol).type = errorType; // Initialize special types globalArrayType = getGlobalType("Array" as __String, /*arity*/ 1, /*reportErrors*/ true); From 8f193b40ee3a55eb3ed6cc410a30717c04b21ed0 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 26 May 2018 08:29:30 -0700 Subject: [PATCH 02/24] Free up one bit in TypeFlags --- src/compiler/checker.ts | 2 +- src/compiler/types.ts | 19 ++++++++++--------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ebabed818183d..322db0768792e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -19934,7 +19934,7 @@ namespace ts { // Return true if type might be of the given kind. A union or intersection type might be of a given // kind if at least one constituent type is of the given kind. function maybeTypeOfKind(type: Type, kind: TypeFlags): boolean { - if (type.flags & kind || kind & TypeFlags.GenericMappedType && isGenericMappedType(type)) { + if (type.flags & kind & ~TypeFlags.GenericMappedType || kind & TypeFlags.GenericMappedType && isGenericMappedType(type)) { return true; } if (type.flags & TypeFlags.UnionOrIntersection) { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index a3cdb32df0702..daccfd282822e 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3687,19 +3687,17 @@ namespace ts { IndexedAccess = 1 << 20, // T[K] Conditional = 1 << 21, // T extends U ? X : Y Substitution = 1 << 22, // Type parameter substitution + NonPrimitive = 1 << 23, // intrinsic object type /* @internal */ - FreshLiteral = 1 << 23, // Fresh literal or unique type + FreshLiteral = 1 << 24, // Fresh literal or unique type /* @internal */ - ContainsWideningType = 1 << 24, // Type is or contains undefined or null widening type + UnionOfUnitTypes = 1 << 25, // Type is union of unit types /* @internal */ - ContainsObjectLiteral = 1 << 25, // Type is or contains object literal type + ContainsWideningType = 1 << 26, // Type is or contains undefined or null widening type /* @internal */ - ContainsAnyFunctionType = 1 << 26, // Type is or contains the anyFunctionType - NonPrimitive = 1 << 27, // intrinsic object type + ContainsObjectLiteral = 1 << 27, // Type is or contains object literal type /* @internal */ - UnionOfUnitTypes = 1 << 28, // Type is union of unit types - /* @internal */ - GenericMappedType = 1 << 29, // Flag used by maybeTypeOfKind + ContainsAnyFunctionType = 1 << 28, // Type is or contains the anyFunctionType /* @internal */ Nullable = Undefined | Null, @@ -3749,7 +3747,10 @@ namespace ts { /* @internal */ EmptyObject = ContainsAnyFunctionType, /* @internal */ - ConstructionFlags = NonWideningType | Wildcard | EmptyObject + ConstructionFlags = NonWideningType | Wildcard | EmptyObject, + // The following flag is used for different purposes by maybeTypeOfKind + /* @internal */ + GenericMappedType = ContainsWideningType } export type DestructuringPattern = BindingPattern | ObjectLiteralExpression | ArrayLiteralExpression; From 8b2149ecc8bc2f7861eace18eb3dfc983f6d5489 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 26 May 2018 08:30:36 -0700 Subject: [PATCH 03/24] Accept new baselines --- tests/baselines/reference/api/tsserverlibrary.d.ts | 6 +++--- tests/baselines/reference/api/typescript.d.ts | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 3adc0f014b696..703102d39fd52 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -2150,7 +2150,7 @@ declare namespace ts { IndexedAccess = 1048576, Conditional = 2097152, Substitution = 4194304, - NonPrimitive = 134217728, + NonPrimitive = 8388608, Literal = 224, Unit = 13536, StringOrNumberLiteral = 96, @@ -2168,8 +2168,8 @@ declare namespace ts { InstantiablePrimitive = 524288, Instantiable = 7897088, StructuredOrInstantiable = 8355840, - Narrowable = 142575359, - NotUnionOrUnit = 134283777 + Narrowable = 16746239, + NotUnionOrUnit = 8454657 } type DestructuringPattern = BindingPattern | ObjectLiteralExpression | ArrayLiteralExpression; interface Type { diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 70f2e0d0cdbf5..bf73813d2d0c4 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -2150,7 +2150,7 @@ declare namespace ts { IndexedAccess = 1048576, Conditional = 2097152, Substitution = 4194304, - NonPrimitive = 134217728, + NonPrimitive = 8388608, Literal = 224, Unit = 13536, StringOrNumberLiteral = 96, @@ -2168,8 +2168,8 @@ declare namespace ts { InstantiablePrimitive = 524288, Instantiable = 7897088, StructuredOrInstantiable = 8355840, - Narrowable = 142575359, - NotUnionOrUnit = 134283777 + Narrowable = 16746239, + NotUnionOrUnit = 8454657 } type DestructuringPattern = BindingPattern | ObjectLiteralExpression | ArrayLiteralExpression; interface Type { From 03f464f433af05d77c0f3afb6c9674a3bcb3da2c Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 26 May 2018 08:51:09 -0700 Subject: [PATCH 04/24] Add 'unknown' keyword to scanner/parser/emitter --- src/compiler/parser.ts | 2 + src/compiler/scanner.ts | 1 + src/compiler/transformers/ts.ts | 2 + src/compiler/types.ts | 67 ++++++++++++++++++--------------- src/compiler/utilities.ts | 2 + 5 files changed, 43 insertions(+), 31 deletions(-) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 03a8934304511..ea5a2a339372a 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -2850,6 +2850,7 @@ namespace ts { function parseNonArrayType(): TypeNode { switch (token()) { case SyntaxKind.AnyKeyword: + case SyntaxKind.UnknownKeyword: case SyntaxKind.StringKeyword: case SyntaxKind.NumberKeyword: case SyntaxKind.SymbolKeyword: @@ -2907,6 +2908,7 @@ namespace ts { function isStartOfType(inStartOfParameter?: boolean): boolean { switch (token()) { case SyntaxKind.AnyKeyword: + case SyntaxKind.UnknownKeyword: case SyntaxKind.StringKeyword: case SyntaxKind.NumberKeyword: case SyntaxKind.BooleanKeyword: diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts index 41b65c678647a..af74d69ceefbb 100644 --- a/src/compiler/scanner.ts +++ b/src/compiler/scanner.ts @@ -124,6 +124,7 @@ namespace ts { "typeof": SyntaxKind.TypeOfKeyword, "undefined": SyntaxKind.UndefinedKeyword, "unique": SyntaxKind.UniqueKeyword, + "unknown": SyntaxKind.UnknownKeyword, "var": SyntaxKind.VarKeyword, "void": SyntaxKind.VoidKeyword, "while": SyntaxKind.WhileKeyword, diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index 5ae6bcb8b3234..cc244d9220413 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -384,6 +384,7 @@ namespace ts { case SyntaxKind.TypePredicate: case SyntaxKind.TypeParameter: case SyntaxKind.AnyKeyword: + case SyntaxKind.UnknownKeyword: case SyntaxKind.BooleanKeyword: case SyntaxKind.StringKeyword: case SyntaxKind.NumberKeyword: @@ -1907,6 +1908,7 @@ namespace ts { case SyntaxKind.MappedType: case SyntaxKind.TypeLiteral: case SyntaxKind.AnyKeyword: + case SyntaxKind.UnknownKeyword: case SyntaxKind.ThisType: break; diff --git a/src/compiler/types.ts b/src/compiler/types.ts index daccfd282822e..b13f4aea61308 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -241,6 +241,7 @@ namespace ts { TypeKeyword, UndefinedKeyword, UniqueKeyword, + UnknownKeyword, FromKeyword, GlobalKeyword, OfKeyword, // LastKeyword and LastToken and LastContextualKeyword @@ -1068,6 +1069,7 @@ namespace ts { export interface KeywordTypeNode extends TypeNode { kind: SyntaxKind.AnyKeyword + | SyntaxKind.UnknownKeyword | SyntaxKind.NumberKeyword | SyntaxKind.ObjectKeyword | SyntaxKind.BooleanKeyword @@ -3665,40 +3667,43 @@ namespace ts { export const enum TypeFlags { Any = 1 << 0, - String = 1 << 1, - Number = 1 << 2, - Boolean = 1 << 3, - Enum = 1 << 4, - StringLiteral = 1 << 5, - NumberLiteral = 1 << 6, - BooleanLiteral = 1 << 7, - EnumLiteral = 1 << 8, // Always combined with StringLiteral, NumberLiteral, or Union - ESSymbol = 1 << 9, // Type of symbol primitive introduced in ES6 - UniqueESSymbol = 1 << 10, // unique symbol - Void = 1 << 11, - Undefined = 1 << 12, - Null = 1 << 13, - Never = 1 << 14, // Never type - TypeParameter = 1 << 15, // Type parameter - Object = 1 << 16, // Object type - Union = 1 << 17, // Union (T | U) - Intersection = 1 << 18, // Intersection (T & U) - Index = 1 << 19, // keyof T - IndexedAccess = 1 << 20, // T[K] - Conditional = 1 << 21, // T extends U ? X : Y - Substitution = 1 << 22, // Type parameter substitution - NonPrimitive = 1 << 23, // intrinsic object type + Unknown = 1 << 1, + String = 1 << 2, + Number = 1 << 3, + Boolean = 1 << 4, + Enum = 1 << 5, + StringLiteral = 1 << 6, + NumberLiteral = 1 << 7, + BooleanLiteral = 1 << 8, + EnumLiteral = 1 << 9, // Always combined with StringLiteral, NumberLiteral, or Union + ESSymbol = 1 << 10, // Type of symbol primitive introduced in ES6 + UniqueESSymbol = 1 << 11, // unique symbol + Void = 1 << 12, + Undefined = 1 << 13, + Null = 1 << 14, + Never = 1 << 15, // Never type + TypeParameter = 1 << 16, // Type parameter + Object = 1 << 17, // Object type + Union = 1 << 18, // Union (T | U) + Intersection = 1 << 19, // Intersection (T & U) + Index = 1 << 20, // keyof T + IndexedAccess = 1 << 21, // T[K] + Conditional = 1 << 22, // T extends U ? X : Y + Substitution = 1 << 23, // Type parameter substitution + NonPrimitive = 1 << 24, // intrinsic object type /* @internal */ - FreshLiteral = 1 << 24, // Fresh literal or unique type + FreshLiteral = 1 << 25, // Fresh literal or unique type /* @internal */ - UnionOfUnitTypes = 1 << 25, // Type is union of unit types + UnionOfUnitTypes = 1 << 26, // Type is union of unit types /* @internal */ - ContainsWideningType = 1 << 26, // Type is or contains undefined or null widening type + ContainsWideningType = 1 << 27, // Type is or contains undefined or null widening type /* @internal */ - ContainsObjectLiteral = 1 << 27, // Type is or contains object literal type + ContainsObjectLiteral = 1 << 28, // Type is or contains object literal type /* @internal */ - ContainsAnyFunctionType = 1 << 28, // Type is or contains the anyFunctionType + ContainsAnyFunctionType = 1 << 29, // Type is or contains the anyFunctionType + /* @internal */ + AnyOrUnknown = Any | Unknown, /* @internal */ Nullable = Undefined | Null, Literal = StringLiteral | NumberLiteral | BooleanLiteral, @@ -3710,7 +3715,7 @@ namespace ts { DefinitelyFalsy = StringLiteral | NumberLiteral | BooleanLiteral | Void | Undefined | Null, PossiblyFalsy = DefinitelyFalsy | String | Number | Boolean, /* @internal */ - Intrinsic = Any | String | Number | Boolean | BooleanLiteral | ESSymbol | Void | Undefined | Null | Never | NonPrimitive, + Intrinsic = Any | Unknown | String | Number | Boolean | BooleanLiteral | ESSymbol | Void | Undefined | Null | Never | NonPrimitive, /* @internal */ Primitive = String | Number | Boolean | Enum | EnumLiteral | ESSymbol | Void | Undefined | Null | Literal | UniqueESSymbol, StringLike = String | StringLiteral, @@ -3731,8 +3736,8 @@ namespace ts { // 'Narrowable' types are types where narrowing actually narrows. // This *should* be every type other than null, undefined, void, and never - Narrowable = Any | StructuredOrInstantiable | StringLike | NumberLike | BooleanLike | ESSymbol | UniqueESSymbol | NonPrimitive, - NotUnionOrUnit = Any | ESSymbol | Object | NonPrimitive, + Narrowable = Any | Unknown | StructuredOrInstantiable | StringLike | NumberLike | BooleanLike | ESSymbol | UniqueESSymbol | NonPrimitive, + NotUnionOrUnit = Any | Unknown | ESSymbol | Object | NonPrimitive, /* @internal */ NotUnit = Any | String | Number | Boolean | Enum | ESSymbol | Void | Never | StructuredOrInstantiable, /* @internal */ diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index a3da44c5b1fea..2cc3c645ebedb 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -810,6 +810,7 @@ namespace ts { switch (node.kind) { case SyntaxKind.AnyKeyword: + case SyntaxKind.UnknownKeyword: case SyntaxKind.NumberKeyword: case SyntaxKind.StringKeyword: case SyntaxKind.BooleanKeyword: @@ -5777,6 +5778,7 @@ namespace ts { function isTypeNodeKind(kind: SyntaxKind) { return (kind >= SyntaxKind.FirstTypeNode && kind <= SyntaxKind.LastTypeNode) || kind === SyntaxKind.AnyKeyword + || kind === SyntaxKind.UnknownKeyword || kind === SyntaxKind.NumberKeyword || kind === SyntaxKind.ObjectKeyword || kind === SyntaxKind.BooleanKeyword From d225065cf4008848226156fd205e5c0b7c89ca4a Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 26 May 2018 08:51:18 -0700 Subject: [PATCH 05/24] Accept new baselines --- .../reference/api/tsserverlibrary.d.ts | 432 +++++++++--------- tests/baselines/reference/api/typescript.d.ts | 432 +++++++++--------- 2 files changed, 434 insertions(+), 430 deletions(-) diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 703102d39fd52..df8fa0f21dfe6 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -204,169 +204,170 @@ declare namespace ts { TypeKeyword = 139, UndefinedKeyword = 140, UniqueKeyword = 141, - FromKeyword = 142, - GlobalKeyword = 143, - OfKeyword = 144, - QualifiedName = 145, - ComputedPropertyName = 146, - TypeParameter = 147, - Parameter = 148, - Decorator = 149, - PropertySignature = 150, - PropertyDeclaration = 151, - MethodSignature = 152, - MethodDeclaration = 153, - Constructor = 154, - GetAccessor = 155, - SetAccessor = 156, - CallSignature = 157, - ConstructSignature = 158, - IndexSignature = 159, - TypePredicate = 160, - TypeReference = 161, - FunctionType = 162, - ConstructorType = 163, - TypeQuery = 164, - TypeLiteral = 165, - ArrayType = 166, - TupleType = 167, - UnionType = 168, - IntersectionType = 169, - ConditionalType = 170, - InferType = 171, - ParenthesizedType = 172, - ThisType = 173, - TypeOperator = 174, - IndexedAccessType = 175, - MappedType = 176, - LiteralType = 177, - ImportType = 178, - ObjectBindingPattern = 179, - ArrayBindingPattern = 180, - BindingElement = 181, - ArrayLiteralExpression = 182, - ObjectLiteralExpression = 183, - PropertyAccessExpression = 184, - ElementAccessExpression = 185, - CallExpression = 186, - NewExpression = 187, - TaggedTemplateExpression = 188, - TypeAssertionExpression = 189, - ParenthesizedExpression = 190, - FunctionExpression = 191, - ArrowFunction = 192, - DeleteExpression = 193, - TypeOfExpression = 194, - VoidExpression = 195, - AwaitExpression = 196, - PrefixUnaryExpression = 197, - PostfixUnaryExpression = 198, - BinaryExpression = 199, - ConditionalExpression = 200, - TemplateExpression = 201, - YieldExpression = 202, - SpreadElement = 203, - ClassExpression = 204, - OmittedExpression = 205, - ExpressionWithTypeArguments = 206, - AsExpression = 207, - NonNullExpression = 208, - MetaProperty = 209, - TemplateSpan = 210, - SemicolonClassElement = 211, - Block = 212, - VariableStatement = 213, - EmptyStatement = 214, - ExpressionStatement = 215, - IfStatement = 216, - DoStatement = 217, - WhileStatement = 218, - ForStatement = 219, - ForInStatement = 220, - ForOfStatement = 221, - ContinueStatement = 222, - BreakStatement = 223, - ReturnStatement = 224, - WithStatement = 225, - SwitchStatement = 226, - LabeledStatement = 227, - ThrowStatement = 228, - TryStatement = 229, - DebuggerStatement = 230, - VariableDeclaration = 231, - VariableDeclarationList = 232, - FunctionDeclaration = 233, - ClassDeclaration = 234, - InterfaceDeclaration = 235, - TypeAliasDeclaration = 236, - EnumDeclaration = 237, - ModuleDeclaration = 238, - ModuleBlock = 239, - CaseBlock = 240, - NamespaceExportDeclaration = 241, - ImportEqualsDeclaration = 242, - ImportDeclaration = 243, - ImportClause = 244, - NamespaceImport = 245, - NamedImports = 246, - ImportSpecifier = 247, - ExportAssignment = 248, - ExportDeclaration = 249, - NamedExports = 250, - ExportSpecifier = 251, - MissingDeclaration = 252, - ExternalModuleReference = 253, - JsxElement = 254, - JsxSelfClosingElement = 255, - JsxOpeningElement = 256, - JsxClosingElement = 257, - JsxFragment = 258, - JsxOpeningFragment = 259, - JsxClosingFragment = 260, - JsxAttribute = 261, - JsxAttributes = 262, - JsxSpreadAttribute = 263, - JsxExpression = 264, - CaseClause = 265, - DefaultClause = 266, - HeritageClause = 267, - CatchClause = 268, - PropertyAssignment = 269, - ShorthandPropertyAssignment = 270, - SpreadAssignment = 271, - EnumMember = 272, - SourceFile = 273, - Bundle = 274, - UnparsedSource = 275, - InputFiles = 276, - JSDocTypeExpression = 277, - JSDocAllType = 278, - JSDocUnknownType = 279, - JSDocNullableType = 280, - JSDocNonNullableType = 281, - JSDocOptionalType = 282, - JSDocFunctionType = 283, - JSDocVariadicType = 284, - JSDocComment = 285, - JSDocTypeLiteral = 286, - JSDocSignature = 287, - JSDocTag = 288, - JSDocAugmentsTag = 289, - JSDocClassTag = 290, - JSDocCallbackTag = 291, - JSDocParameterTag = 292, - JSDocReturnTag = 293, - JSDocTypeTag = 294, - JSDocTemplateTag = 295, - JSDocTypedefTag = 296, - JSDocPropertyTag = 297, - SyntaxList = 298, - NotEmittedStatement = 299, - PartiallyEmittedExpression = 300, - CommaListExpression = 301, - MergeDeclarationMarker = 302, - EndOfDeclarationMarker = 303, - Count = 304, + UnknownKeyword = 142, + FromKeyword = 143, + GlobalKeyword = 144, + OfKeyword = 145, + QualifiedName = 146, + ComputedPropertyName = 147, + TypeParameter = 148, + Parameter = 149, + Decorator = 150, + PropertySignature = 151, + PropertyDeclaration = 152, + MethodSignature = 153, + MethodDeclaration = 154, + Constructor = 155, + GetAccessor = 156, + SetAccessor = 157, + CallSignature = 158, + ConstructSignature = 159, + IndexSignature = 160, + TypePredicate = 161, + TypeReference = 162, + FunctionType = 163, + ConstructorType = 164, + TypeQuery = 165, + TypeLiteral = 166, + ArrayType = 167, + TupleType = 168, + UnionType = 169, + IntersectionType = 170, + ConditionalType = 171, + InferType = 172, + ParenthesizedType = 173, + ThisType = 174, + TypeOperator = 175, + IndexedAccessType = 176, + MappedType = 177, + LiteralType = 178, + ImportType = 179, + ObjectBindingPattern = 180, + ArrayBindingPattern = 181, + BindingElement = 182, + ArrayLiteralExpression = 183, + ObjectLiteralExpression = 184, + PropertyAccessExpression = 185, + ElementAccessExpression = 186, + CallExpression = 187, + NewExpression = 188, + TaggedTemplateExpression = 189, + TypeAssertionExpression = 190, + ParenthesizedExpression = 191, + FunctionExpression = 192, + ArrowFunction = 193, + DeleteExpression = 194, + TypeOfExpression = 195, + VoidExpression = 196, + AwaitExpression = 197, + PrefixUnaryExpression = 198, + PostfixUnaryExpression = 199, + BinaryExpression = 200, + ConditionalExpression = 201, + TemplateExpression = 202, + YieldExpression = 203, + SpreadElement = 204, + ClassExpression = 205, + OmittedExpression = 206, + ExpressionWithTypeArguments = 207, + AsExpression = 208, + NonNullExpression = 209, + MetaProperty = 210, + TemplateSpan = 211, + SemicolonClassElement = 212, + Block = 213, + VariableStatement = 214, + EmptyStatement = 215, + ExpressionStatement = 216, + IfStatement = 217, + DoStatement = 218, + WhileStatement = 219, + ForStatement = 220, + ForInStatement = 221, + ForOfStatement = 222, + ContinueStatement = 223, + BreakStatement = 224, + ReturnStatement = 225, + WithStatement = 226, + SwitchStatement = 227, + LabeledStatement = 228, + ThrowStatement = 229, + TryStatement = 230, + DebuggerStatement = 231, + VariableDeclaration = 232, + VariableDeclarationList = 233, + FunctionDeclaration = 234, + ClassDeclaration = 235, + InterfaceDeclaration = 236, + TypeAliasDeclaration = 237, + EnumDeclaration = 238, + ModuleDeclaration = 239, + ModuleBlock = 240, + CaseBlock = 241, + NamespaceExportDeclaration = 242, + ImportEqualsDeclaration = 243, + ImportDeclaration = 244, + ImportClause = 245, + NamespaceImport = 246, + NamedImports = 247, + ImportSpecifier = 248, + ExportAssignment = 249, + ExportDeclaration = 250, + NamedExports = 251, + ExportSpecifier = 252, + MissingDeclaration = 253, + ExternalModuleReference = 254, + JsxElement = 255, + JsxSelfClosingElement = 256, + JsxOpeningElement = 257, + JsxClosingElement = 258, + JsxFragment = 259, + JsxOpeningFragment = 260, + JsxClosingFragment = 261, + JsxAttribute = 262, + JsxAttributes = 263, + JsxSpreadAttribute = 264, + JsxExpression = 265, + CaseClause = 266, + DefaultClause = 267, + HeritageClause = 268, + CatchClause = 269, + PropertyAssignment = 270, + ShorthandPropertyAssignment = 271, + SpreadAssignment = 272, + EnumMember = 273, + SourceFile = 274, + Bundle = 275, + UnparsedSource = 276, + InputFiles = 277, + JSDocTypeExpression = 278, + JSDocAllType = 279, + JSDocUnknownType = 280, + JSDocNullableType = 281, + JSDocNonNullableType = 282, + JSDocOptionalType = 283, + JSDocFunctionType = 284, + JSDocVariadicType = 285, + JSDocComment = 286, + JSDocTypeLiteral = 287, + JSDocSignature = 288, + JSDocTag = 289, + JSDocAugmentsTag = 290, + JSDocClassTag = 291, + JSDocCallbackTag = 292, + JSDocParameterTag = 293, + JSDocReturnTag = 294, + JSDocTypeTag = 295, + JSDocTemplateTag = 296, + JSDocTypedefTag = 297, + JSDocPropertyTag = 298, + SyntaxList = 299, + NotEmittedStatement = 300, + PartiallyEmittedExpression = 301, + CommaListExpression = 302, + MergeDeclarationMarker = 303, + EndOfDeclarationMarker = 304, + Count = 305, FirstAssignment = 58, LastAssignment = 70, FirstCompoundAssignment = 59, @@ -374,15 +375,15 @@ declare namespace ts { FirstReservedWord = 72, LastReservedWord = 107, FirstKeyword = 72, - LastKeyword = 144, + LastKeyword = 145, FirstFutureReservedWord = 108, LastFutureReservedWord = 116, - FirstTypeNode = 160, - LastTypeNode = 178, + FirstTypeNode = 161, + LastTypeNode = 179, FirstPunctuation = 17, LastPunctuation = 70, FirstToken = 0, - LastToken = 144, + LastToken = 145, FirstTriviaToken = 2, LastTriviaToken = 7, FirstLiteralToken = 8, @@ -391,11 +392,11 @@ declare namespace ts { LastTemplateToken = 16, FirstBinaryOperator = 27, LastBinaryOperator = 70, - FirstNode = 145, - FirstJSDocNode = 277, - LastJSDocNode = 297, - FirstJSDocTagNode = 288, - LastJSDocTagNode = 297 + FirstNode = 146, + FirstJSDocNode = 278, + LastJSDocNode = 298, + FirstJSDocTagNode = 289, + LastJSDocTagNode = 298 } enum NodeFlags { None = 0, @@ -702,7 +703,7 @@ declare namespace ts { _typeNodeBrand: any; } interface KeywordTypeNode extends TypeNode { - kind: SyntaxKind.AnyKeyword | SyntaxKind.NumberKeyword | SyntaxKind.ObjectKeyword | SyntaxKind.BooleanKeyword | SyntaxKind.StringKeyword | SyntaxKind.SymbolKeyword | SyntaxKind.ThisKeyword | SyntaxKind.VoidKeyword | SyntaxKind.UndefinedKeyword | SyntaxKind.NullKeyword | SyntaxKind.NeverKeyword; + kind: SyntaxKind.AnyKeyword | SyntaxKind.UnknownKeyword | SyntaxKind.NumberKeyword | SyntaxKind.ObjectKeyword | SyntaxKind.BooleanKeyword | SyntaxKind.StringKeyword | SyntaxKind.SymbolKeyword | SyntaxKind.ThisKeyword | SyntaxKind.VoidKeyword | SyntaxKind.UndefinedKeyword | SyntaxKind.NullKeyword | SyntaxKind.NeverKeyword; } interface ImportTypeNode extends NodeWithTypeArguments { kind: SyntaxKind.ImportType; @@ -2128,48 +2129,49 @@ declare namespace ts { type SymbolTable = UnderscoreEscapedMap; enum TypeFlags { Any = 1, - String = 2, - Number = 4, - Boolean = 8, - Enum = 16, - StringLiteral = 32, - NumberLiteral = 64, - BooleanLiteral = 128, - EnumLiteral = 256, - ESSymbol = 512, - UniqueESSymbol = 1024, - Void = 2048, - Undefined = 4096, - Null = 8192, - Never = 16384, - TypeParameter = 32768, - Object = 65536, - Union = 131072, - Intersection = 262144, - Index = 524288, - IndexedAccess = 1048576, - Conditional = 2097152, - Substitution = 4194304, - NonPrimitive = 8388608, - Literal = 224, - Unit = 13536, - StringOrNumberLiteral = 96, - PossiblyFalsy = 14574, - StringLike = 34, - NumberLike = 84, - BooleanLike = 136, - EnumLike = 272, - ESSymbolLike = 1536, - VoidLike = 6144, - UnionOrIntersection = 393216, - StructuredType = 458752, - TypeVariable = 1081344, - InstantiableNonPrimitive = 7372800, - InstantiablePrimitive = 524288, - Instantiable = 7897088, - StructuredOrInstantiable = 8355840, - Narrowable = 16746239, - NotUnionOrUnit = 8454657 + Unknown = 2, + String = 4, + Number = 8, + Boolean = 16, + Enum = 32, + StringLiteral = 64, + NumberLiteral = 128, + BooleanLiteral = 256, + EnumLiteral = 512, + ESSymbol = 1024, + UniqueESSymbol = 2048, + Void = 4096, + Undefined = 8192, + Null = 16384, + Never = 32768, + TypeParameter = 65536, + Object = 131072, + Union = 262144, + Intersection = 524288, + Index = 1048576, + IndexedAccess = 2097152, + Conditional = 4194304, + Substitution = 8388608, + NonPrimitive = 16777216, + Literal = 448, + Unit = 27072, + StringOrNumberLiteral = 192, + PossiblyFalsy = 29148, + StringLike = 68, + NumberLike = 168, + BooleanLike = 272, + EnumLike = 544, + ESSymbolLike = 3072, + VoidLike = 12288, + UnionOrIntersection = 786432, + StructuredType = 917504, + TypeVariable = 2162688, + InstantiableNonPrimitive = 14745600, + InstantiablePrimitive = 1048576, + Instantiable = 15794176, + StructuredOrInstantiable = 16711680, + Narrowable = 33492479, + NotUnionOrUnit = 16909315 } type DestructuringPattern = BindingPattern | ObjectLiteralExpression | ArrayLiteralExpression; interface Type { diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index bf73813d2d0c4..b830a55802518 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -204,169 +204,170 @@ declare namespace ts { TypeKeyword = 139, UndefinedKeyword = 140, UniqueKeyword = 141, - FromKeyword = 142, - GlobalKeyword = 143, - OfKeyword = 144, - QualifiedName = 145, - ComputedPropertyName = 146, - TypeParameter = 147, - Parameter = 148, - Decorator = 149, - PropertySignature = 150, - PropertyDeclaration = 151, - MethodSignature = 152, - MethodDeclaration = 153, - Constructor = 154, - GetAccessor = 155, - SetAccessor = 156, - CallSignature = 157, - ConstructSignature = 158, - IndexSignature = 159, - TypePredicate = 160, - TypeReference = 161, - FunctionType = 162, - ConstructorType = 163, - TypeQuery = 164, - TypeLiteral = 165, - ArrayType = 166, - TupleType = 167, - UnionType = 168, - IntersectionType = 169, - ConditionalType = 170, - InferType = 171, - ParenthesizedType = 172, - ThisType = 173, - TypeOperator = 174, - IndexedAccessType = 175, - MappedType = 176, - LiteralType = 177, - ImportType = 178, - ObjectBindingPattern = 179, - ArrayBindingPattern = 180, - BindingElement = 181, - ArrayLiteralExpression = 182, - ObjectLiteralExpression = 183, - PropertyAccessExpression = 184, - ElementAccessExpression = 185, - CallExpression = 186, - NewExpression = 187, - TaggedTemplateExpression = 188, - TypeAssertionExpression = 189, - ParenthesizedExpression = 190, - FunctionExpression = 191, - ArrowFunction = 192, - DeleteExpression = 193, - TypeOfExpression = 194, - VoidExpression = 195, - AwaitExpression = 196, - PrefixUnaryExpression = 197, - PostfixUnaryExpression = 198, - BinaryExpression = 199, - ConditionalExpression = 200, - TemplateExpression = 201, - YieldExpression = 202, - SpreadElement = 203, - ClassExpression = 204, - OmittedExpression = 205, - ExpressionWithTypeArguments = 206, - AsExpression = 207, - NonNullExpression = 208, - MetaProperty = 209, - TemplateSpan = 210, - SemicolonClassElement = 211, - Block = 212, - VariableStatement = 213, - EmptyStatement = 214, - ExpressionStatement = 215, - IfStatement = 216, - DoStatement = 217, - WhileStatement = 218, - ForStatement = 219, - ForInStatement = 220, - ForOfStatement = 221, - ContinueStatement = 222, - BreakStatement = 223, - ReturnStatement = 224, - WithStatement = 225, - SwitchStatement = 226, - LabeledStatement = 227, - ThrowStatement = 228, - TryStatement = 229, - DebuggerStatement = 230, - VariableDeclaration = 231, - VariableDeclarationList = 232, - FunctionDeclaration = 233, - ClassDeclaration = 234, - InterfaceDeclaration = 235, - TypeAliasDeclaration = 236, - EnumDeclaration = 237, - ModuleDeclaration = 238, - ModuleBlock = 239, - CaseBlock = 240, - NamespaceExportDeclaration = 241, - ImportEqualsDeclaration = 242, - ImportDeclaration = 243, - ImportClause = 244, - NamespaceImport = 245, - NamedImports = 246, - ImportSpecifier = 247, - ExportAssignment = 248, - ExportDeclaration = 249, - NamedExports = 250, - ExportSpecifier = 251, - MissingDeclaration = 252, - ExternalModuleReference = 253, - JsxElement = 254, - JsxSelfClosingElement = 255, - JsxOpeningElement = 256, - JsxClosingElement = 257, - JsxFragment = 258, - JsxOpeningFragment = 259, - JsxClosingFragment = 260, - JsxAttribute = 261, - JsxAttributes = 262, - JsxSpreadAttribute = 263, - JsxExpression = 264, - CaseClause = 265, - DefaultClause = 266, - HeritageClause = 267, - CatchClause = 268, - PropertyAssignment = 269, - ShorthandPropertyAssignment = 270, - SpreadAssignment = 271, - EnumMember = 272, - SourceFile = 273, - Bundle = 274, - UnparsedSource = 275, - InputFiles = 276, - JSDocTypeExpression = 277, - JSDocAllType = 278, - JSDocUnknownType = 279, - JSDocNullableType = 280, - JSDocNonNullableType = 281, - JSDocOptionalType = 282, - JSDocFunctionType = 283, - JSDocVariadicType = 284, - JSDocComment = 285, - JSDocTypeLiteral = 286, - JSDocSignature = 287, - JSDocTag = 288, - JSDocAugmentsTag = 289, - JSDocClassTag = 290, - JSDocCallbackTag = 291, - JSDocParameterTag = 292, - JSDocReturnTag = 293, - JSDocTypeTag = 294, - JSDocTemplateTag = 295, - JSDocTypedefTag = 296, - JSDocPropertyTag = 297, - SyntaxList = 298, - NotEmittedStatement = 299, - PartiallyEmittedExpression = 300, - CommaListExpression = 301, - MergeDeclarationMarker = 302, - EndOfDeclarationMarker = 303, - Count = 304, + UnknownKeyword = 142, + FromKeyword = 143, + GlobalKeyword = 144, + OfKeyword = 145, + QualifiedName = 146, + ComputedPropertyName = 147, + TypeParameter = 148, + Parameter = 149, + Decorator = 150, + PropertySignature = 151, + PropertyDeclaration = 152, + MethodSignature = 153, + MethodDeclaration = 154, + Constructor = 155, + GetAccessor = 156, + SetAccessor = 157, + CallSignature = 158, + ConstructSignature = 159, + IndexSignature = 160, + TypePredicate = 161, + TypeReference = 162, + FunctionType = 163, + ConstructorType = 164, + TypeQuery = 165, + TypeLiteral = 166, + ArrayType = 167, + TupleType = 168, + UnionType = 169, + IntersectionType = 170, + ConditionalType = 171, + InferType = 172, + ParenthesizedType = 173, + ThisType = 174, + TypeOperator = 175, + IndexedAccessType = 176, + MappedType = 177, + LiteralType = 178, + ImportType = 179, + ObjectBindingPattern = 180, + ArrayBindingPattern = 181, + BindingElement = 182, + ArrayLiteralExpression = 183, + ObjectLiteralExpression = 184, + PropertyAccessExpression = 185, + ElementAccessExpression = 186, + CallExpression = 187, + NewExpression = 188, + TaggedTemplateExpression = 189, + TypeAssertionExpression = 190, + ParenthesizedExpression = 191, + FunctionExpression = 192, + ArrowFunction = 193, + DeleteExpression = 194, + TypeOfExpression = 195, + VoidExpression = 196, + AwaitExpression = 197, + PrefixUnaryExpression = 198, + PostfixUnaryExpression = 199, + BinaryExpression = 200, + ConditionalExpression = 201, + TemplateExpression = 202, + YieldExpression = 203, + SpreadElement = 204, + ClassExpression = 205, + OmittedExpression = 206, + ExpressionWithTypeArguments = 207, + AsExpression = 208, + NonNullExpression = 209, + MetaProperty = 210, + TemplateSpan = 211, + SemicolonClassElement = 212, + Block = 213, + VariableStatement = 214, + EmptyStatement = 215, + ExpressionStatement = 216, + IfStatement = 217, + DoStatement = 218, + WhileStatement = 219, + ForStatement = 220, + ForInStatement = 221, + ForOfStatement = 222, + ContinueStatement = 223, + BreakStatement = 224, + ReturnStatement = 225, + WithStatement = 226, + SwitchStatement = 227, + LabeledStatement = 228, + ThrowStatement = 229, + TryStatement = 230, + DebuggerStatement = 231, + VariableDeclaration = 232, + VariableDeclarationList = 233, + FunctionDeclaration = 234, + ClassDeclaration = 235, + InterfaceDeclaration = 236, + TypeAliasDeclaration = 237, + EnumDeclaration = 238, + ModuleDeclaration = 239, + ModuleBlock = 240, + CaseBlock = 241, + NamespaceExportDeclaration = 242, + ImportEqualsDeclaration = 243, + ImportDeclaration = 244, + ImportClause = 245, + NamespaceImport = 246, + NamedImports = 247, + ImportSpecifier = 248, + ExportAssignment = 249, + ExportDeclaration = 250, + NamedExports = 251, + ExportSpecifier = 252, + MissingDeclaration = 253, + ExternalModuleReference = 254, + JsxElement = 255, + JsxSelfClosingElement = 256, + JsxOpeningElement = 257, + JsxClosingElement = 258, + JsxFragment = 259, + JsxOpeningFragment = 260, + JsxClosingFragment = 261, + JsxAttribute = 262, + JsxAttributes = 263, + JsxSpreadAttribute = 264, + JsxExpression = 265, + CaseClause = 266, + DefaultClause = 267, + HeritageClause = 268, + CatchClause = 269, + PropertyAssignment = 270, + ShorthandPropertyAssignment = 271, + SpreadAssignment = 272, + EnumMember = 273, + SourceFile = 274, + Bundle = 275, + UnparsedSource = 276, + InputFiles = 277, + JSDocTypeExpression = 278, + JSDocAllType = 279, + JSDocUnknownType = 280, + JSDocNullableType = 281, + JSDocNonNullableType = 282, + JSDocOptionalType = 283, + JSDocFunctionType = 284, + JSDocVariadicType = 285, + JSDocComment = 286, + JSDocTypeLiteral = 287, + JSDocSignature = 288, + JSDocTag = 289, + JSDocAugmentsTag = 290, + JSDocClassTag = 291, + JSDocCallbackTag = 292, + JSDocParameterTag = 293, + JSDocReturnTag = 294, + JSDocTypeTag = 295, + JSDocTemplateTag = 296, + JSDocTypedefTag = 297, + JSDocPropertyTag = 298, + SyntaxList = 299, + NotEmittedStatement = 300, + PartiallyEmittedExpression = 301, + CommaListExpression = 302, + MergeDeclarationMarker = 303, + EndOfDeclarationMarker = 304, + Count = 305, FirstAssignment = 58, LastAssignment = 70, FirstCompoundAssignment = 59, @@ -374,15 +375,15 @@ declare namespace ts { FirstReservedWord = 72, LastReservedWord = 107, FirstKeyword = 72, - LastKeyword = 144, + LastKeyword = 145, FirstFutureReservedWord = 108, LastFutureReservedWord = 116, - FirstTypeNode = 160, - LastTypeNode = 178, + FirstTypeNode = 161, + LastTypeNode = 179, FirstPunctuation = 17, LastPunctuation = 70, FirstToken = 0, - LastToken = 144, + LastToken = 145, FirstTriviaToken = 2, LastTriviaToken = 7, FirstLiteralToken = 8, @@ -391,11 +392,11 @@ declare namespace ts { LastTemplateToken = 16, FirstBinaryOperator = 27, LastBinaryOperator = 70, - FirstNode = 145, - FirstJSDocNode = 277, - LastJSDocNode = 297, - FirstJSDocTagNode = 288, - LastJSDocTagNode = 297 + FirstNode = 146, + FirstJSDocNode = 278, + LastJSDocNode = 298, + FirstJSDocTagNode = 289, + LastJSDocTagNode = 298 } enum NodeFlags { None = 0, @@ -702,7 +703,7 @@ declare namespace ts { _typeNodeBrand: any; } interface KeywordTypeNode extends TypeNode { - kind: SyntaxKind.AnyKeyword | SyntaxKind.NumberKeyword | SyntaxKind.ObjectKeyword | SyntaxKind.BooleanKeyword | SyntaxKind.StringKeyword | SyntaxKind.SymbolKeyword | SyntaxKind.ThisKeyword | SyntaxKind.VoidKeyword | SyntaxKind.UndefinedKeyword | SyntaxKind.NullKeyword | SyntaxKind.NeverKeyword; + kind: SyntaxKind.AnyKeyword | SyntaxKind.UnknownKeyword | SyntaxKind.NumberKeyword | SyntaxKind.ObjectKeyword | SyntaxKind.BooleanKeyword | SyntaxKind.StringKeyword | SyntaxKind.SymbolKeyword | SyntaxKind.ThisKeyword | SyntaxKind.VoidKeyword | SyntaxKind.UndefinedKeyword | SyntaxKind.NullKeyword | SyntaxKind.NeverKeyword; } interface ImportTypeNode extends NodeWithTypeArguments { kind: SyntaxKind.ImportType; @@ -2128,48 +2129,49 @@ declare namespace ts { type SymbolTable = UnderscoreEscapedMap; enum TypeFlags { Any = 1, - String = 2, - Number = 4, - Boolean = 8, - Enum = 16, - StringLiteral = 32, - NumberLiteral = 64, - BooleanLiteral = 128, - EnumLiteral = 256, - ESSymbol = 512, - UniqueESSymbol = 1024, - Void = 2048, - Undefined = 4096, - Null = 8192, - Never = 16384, - TypeParameter = 32768, - Object = 65536, - Union = 131072, - Intersection = 262144, - Index = 524288, - IndexedAccess = 1048576, - Conditional = 2097152, - Substitution = 4194304, - NonPrimitive = 8388608, - Literal = 224, - Unit = 13536, - StringOrNumberLiteral = 96, - PossiblyFalsy = 14574, - StringLike = 34, - NumberLike = 84, - BooleanLike = 136, - EnumLike = 272, - ESSymbolLike = 1536, - VoidLike = 6144, - UnionOrIntersection = 393216, - StructuredType = 458752, - TypeVariable = 1081344, - InstantiableNonPrimitive = 7372800, - InstantiablePrimitive = 524288, - Instantiable = 7897088, - StructuredOrInstantiable = 8355840, - Narrowable = 16746239, - NotUnionOrUnit = 8454657 + Unknown = 2, + String = 4, + Number = 8, + Boolean = 16, + Enum = 32, + StringLiteral = 64, + NumberLiteral = 128, + BooleanLiteral = 256, + EnumLiteral = 512, + ESSymbol = 1024, + UniqueESSymbol = 2048, + Void = 4096, + Undefined = 8192, + Null = 16384, + Never = 32768, + TypeParameter = 65536, + Object = 131072, + Union = 262144, + Intersection = 524288, + Index = 1048576, + IndexedAccess = 2097152, + Conditional = 4194304, + Substitution = 8388608, + NonPrimitive = 16777216, + Literal = 448, + Unit = 27072, + StringOrNumberLiteral = 192, + PossiblyFalsy = 29148, + StringLike = 68, + NumberLike = 168, + BooleanLike = 272, + EnumLike = 544, + ESSymbolLike = 3072, + VoidLike = 12288, + UnionOrIntersection = 786432, + StructuredType = 917504, + TypeVariable = 2162688, + InstantiableNonPrimitive = 14745600, + InstantiablePrimitive = 1048576, + Instantiable = 15794176, + StructuredOrInstantiable = 16711680, + Narrowable = 33492479, + NotUnionOrUnit = 16909315 } type DestructuringPattern = BindingPattern | ObjectLiteralExpression | ArrayLiteralExpression; interface Type { From 2003b2a3e29e2319d1ed9fa9f38e28135e207929 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 26 May 2018 09:53:07 -0700 Subject: [PATCH 06/24] Implement 'unknown' type in checker --- src/compiler/checker.ts | 54 ++++++++++++++++++++++++++--------------- 1 file changed, 34 insertions(+), 20 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 322db0768792e..cadf4edcdcd6a 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -354,6 +354,7 @@ namespace ts { const autoType = createIntrinsicType(TypeFlags.Any, "any"); const wildcardType = createIntrinsicType(TypeFlags.Any, "any"); const errorType = createIntrinsicType(TypeFlags.Any, "error"); + const unknownType = createIntrinsicType(TypeFlags.Unknown, "unknown"); const undefinedType = createIntrinsicType(TypeFlags.Undefined, "undefined"); const undefinedWideningType = strictNullChecks ? undefinedType : createIntrinsicType(TypeFlags.Undefined | TypeFlags.ContainsWideningType, "undefined"); const nullType = createIntrinsicType(TypeFlags.Null, "null"); @@ -3099,6 +3100,9 @@ namespace ts { if (type.flags & TypeFlags.Any) { return createKeywordTypeNode(SyntaxKind.AnyKeyword); } + if (type.flags & TypeFlags.Unknown) { + return createKeywordTypeNode(SyntaxKind.UnknownKeyword); + } if (type.flags & TypeFlags.String) { return createKeywordTypeNode(SyntaxKind.StringKeyword); } @@ -5720,6 +5724,7 @@ namespace ts { function isThislessType(node: TypeNode): boolean { switch (node.kind) { case SyntaxKind.AnyKeyword: + case SyntaxKind.UnknownKeyword: case SyntaxKind.StringKeyword: case SyntaxKind.NumberKeyword: case SyntaxKind.BooleanKeyword: @@ -8293,7 +8298,7 @@ namespace ts { // easier to reason about their origin. if (!(flags & TypeFlags.Never || flags & TypeFlags.Intersection && isEmptyIntersectionType(type))) { includes |= flags & ~TypeFlags.ConstructionFlags; - if (flags & TypeFlags.Any) { + if (flags & TypeFlags.AnyOrUnknown) { if (type === wildcardType) includes |= TypeFlags.Wildcard; } else if (!strictNullChecks && flags & TypeFlags.Nullable) { @@ -8404,8 +8409,8 @@ namespace ts { } const typeSet: Type[] = []; const includes = addTypesToUnion(typeSet, 0, types); - if (includes & TypeFlags.Any) { - return includes & TypeFlags.Wildcard ? wildcardType : anyType; + if (includes & TypeFlags.AnyOrUnknown) { + return includes & TypeFlags.Any ? includes & TypeFlags.Wildcard ? wildcardType : anyType : unknownType; } switch (unionReduction) { case UnionReduction.Literal: @@ -8508,7 +8513,7 @@ namespace ts { } else { includes |= flags & ~TypeFlags.ConstructionFlags; - if (flags & TypeFlags.Any) { + if (flags & TypeFlags.AnyOrUnknown) { if (type === wildcardType) includes |= TypeFlags.Wildcard; } else if ((strictNullChecks || !(flags & TypeFlags.Nullable)) && !contains(typeSet, type) && @@ -8579,9 +8584,6 @@ namespace ts { // Also, unlike union types, the order of the constituent types is preserved in order that overload resolution // for intersections of types with signatures can be deterministic. function getIntersectionType(types: Type[], aliasSymbol?: Symbol, aliasTypeArguments?: Type[]): Type { - if (types.length === 0) { - return emptyObjectType; - } const typeSet: Type[] = []; const includes = addTypesToIntersection(typeSet, 0, types); if (includes & TypeFlags.Never) { @@ -8598,6 +8600,9 @@ namespace ts { if (includes & TypeFlags.EmptyObject && !(includes & TypeFlags.Object)) { typeSet.push(emptyObjectType); } + if (typeSet.length === 0) { + return unknownType; + } if (typeSet.length === 1) { return typeSet[0]; } @@ -8893,7 +8898,7 @@ namespace ts { // an expression. This is to preserve backwards compatibility. For example, an element access 'this["foo"]' // has always been resolved eagerly using the constraint type of 'this' at the given location. if (isGenericIndexType(indexType) || !(accessNode && accessNode.kind === SyntaxKind.ElementAccessExpression) && isGenericObjectType(objectType)) { - if (objectType.flags & TypeFlags.Any) { + if (objectType.flags & TypeFlags.AnyOrUnknown) { return objectType; } // Defer the operation by creating an indexed access type. @@ -8961,6 +8966,9 @@ namespace ts { if (checkType === wildcardType || extendsType === wildcardType) { return wildcardType; } + if (extendsType.flags & TypeFlags.AnyOrUnknown) { + return instantiateType(root.trueType, mapper); + } // If this is a distributive conditional type and the check type is generic we need to defer // resolution of the conditional type such that a later instantiation will properly distribute // over union types. @@ -9195,6 +9203,9 @@ namespace ts { if (left.flags & TypeFlags.Any || right.flags & TypeFlags.Any) { return anyType; } + if (left.flags & TypeFlags.Unknown || right.flags & TypeFlags.Unknown) { + return unknownType; + } if (left.flags & TypeFlags.Never) { return right; } @@ -9388,6 +9399,8 @@ namespace ts { case SyntaxKind.JSDocAllType: case SyntaxKind.JSDocUnknownType: return anyType; + case SyntaxKind.UnknownKeyword: + return unknownType; case SyntaxKind.StringKeyword: return stringType; case SyntaxKind.NumberKeyword: @@ -9756,7 +9769,7 @@ namespace ts { } function isMappableType(type: Type) { - return type.flags & (TypeFlags.Any | TypeFlags.InstantiableNonPrimitive | TypeFlags.Object | TypeFlags.Intersection); + return type.flags & (TypeFlags.AnyOrUnknown | TypeFlags.InstantiableNonPrimitive | TypeFlags.Object | TypeFlags.Intersection); } function instantiateAnonymousType(type: AnonymousType, mapper: TypeMapper): AnonymousType { @@ -9855,7 +9868,7 @@ namespace ts { } function getWildcardInstantiation(type: Type) { - return type.flags & (TypeFlags.Primitive | TypeFlags.Any | TypeFlags.Never) ? type : + return type.flags & (TypeFlags.Primitive | TypeFlags.AnyOrUnknown | TypeFlags.Never) ? type : type.wildcardInstantiation || (type.wildcardInstantiation = instantiateType(type, wildcardMapper)); } @@ -10269,7 +10282,7 @@ namespace ts { function isSimpleTypeRelatedTo(source: Type, target: Type, relation: Map, errorReporter?: ErrorReporter) { const s = source.flags; const t = target.flags; - if (t & TypeFlags.Any || s & TypeFlags.Never || source === wildcardType) return true; + if (t & TypeFlags.AnyOrUnknown || s & TypeFlags.Never || source === wildcardType) return true; if (t & TypeFlags.Never) return false; if (s & TypeFlags.StringLike && t & TypeFlags.String) return true; if (s & TypeFlags.StringLiteral && s & TypeFlags.EnumLiteral && @@ -10995,7 +11008,7 @@ namespace ts { } } const constraint = getConstraintForRelation(source); - if (!constraint || (source.flags & TypeFlags.TypeParameter && constraint.flags & TypeFlags.Any)) { + if (!constraint || (source.flags & TypeFlags.TypeParameter && constraint.flags & TypeFlags.AnyOrUnknown)) { // A type variable with no constraint is not related to the non-primitive object type. if (result = isRelatedTo(emptyObjectType, extractTypesOfKind(target, ~TypeFlags.NonPrimitive))) { errorInfo = saveErrorInfo; @@ -11438,7 +11451,7 @@ namespace ts { return indexTypesIdenticalTo(source, target, kind); } const targetInfo = getIndexInfoOfType(target, kind); - if (!targetInfo || targetInfo.type.flags & TypeFlags.Any && !sourceIsPrimitive) { + if (!targetInfo || targetInfo.type.flags & TypeFlags.AnyOrUnknown && !sourceIsPrimitive) { // Index signature of type any permits assignment from everything but primitives return Ternary.True; } @@ -14467,7 +14480,7 @@ namespace ts { // the entire control flow graph from the variable's declaration (i.e. when the flow container and // declaration container are the same). const assumeInitialized = isParameter || isAlias || isOuterVariable || isSpreadDestructuringAsignmentTarget || - type !== autoType && type !== autoArrayType && (!strictNullChecks || (type.flags & TypeFlags.Any) !== 0 || + type !== autoType && type !== autoArrayType && (!strictNullChecks || (type.flags & TypeFlags.AnyOrUnknown) !== 0 || isInTypeQuery(node) || node.parent.kind === SyntaxKind.ExportSpecifier) || node.parent.kind === SyntaxKind.NonNullExpression || declaration.kind === SyntaxKind.VariableDeclaration && (declaration).exclamationToken || @@ -16071,7 +16084,7 @@ namespace ts { } function isValidSpreadType(type: Type): boolean { - return !!(type.flags & (TypeFlags.Any | TypeFlags.NonPrimitive) || + return !!(type.flags & (TypeFlags.AnyOrUnknown | TypeFlags.NonPrimitive) || getFalsyFlags(type) & TypeFlags.DefinitelyFalsy && isValidSpreadType(removeDefinitelyFalsyTypes(type)) || type.flags & TypeFlags.Object && !isGenericMappedType(type) || type.flags & TypeFlags.UnionOrIntersection && !forEach((type).types, t => !isValidSpreadType(t))); @@ -19624,7 +19637,7 @@ namespace ts { } // Functions with with an explicitly specified 'void' or 'any' return type don't need any return expressions. - if (returnType && maybeTypeOfKind(returnType, TypeFlags.Any | TypeFlags.Void)) { + if (returnType && maybeTypeOfKind(returnType, TypeFlags.AnyOrUnknown | TypeFlags.Void)) { return; } @@ -19952,7 +19965,7 @@ namespace ts { if (source.flags & kind) { return true; } - if (strict && source.flags & (TypeFlags.Any | TypeFlags.Void | TypeFlags.Undefined | TypeFlags.Null)) { + if (strict && source.flags & (TypeFlags.AnyOrUnknown | TypeFlags.Void | TypeFlags.Undefined | TypeFlags.Null)) { return false; } return !!(kind & TypeFlags.NumberLike) && isTypeAssignableTo(source, numberType) || @@ -23849,7 +23862,7 @@ namespace ts { const unwrappedReturnType = (getFunctionFlags(func) & FunctionFlags.AsyncGenerator) === FunctionFlags.Async ? getPromisedTypeOfPromise(returnType) // Async function : returnType; // AsyncGenerator function, Generator function, or normal function - return !!unwrappedReturnType && maybeTypeOfKind(unwrappedReturnType, TypeFlags.Void | TypeFlags.Any); + return !!unwrappedReturnType && maybeTypeOfKind(unwrappedReturnType, TypeFlags.Void | TypeFlags.AnyOrUnknown); } function checkReturnStatement(node: ReturnStatement) { @@ -24143,6 +24156,7 @@ namespace ts { // The predefined type keywords are reserved and cannot be used as names of user defined types. switch (name.escapedText) { case "any": + case "unknown": case "number": case "boolean": case "string": @@ -24563,7 +24577,7 @@ namespace ts { const propName = (member).name; if (isIdentifier(propName)) { const type = getTypeOfSymbol(getSymbolOfNode(member)); - if (!(type.flags & TypeFlags.Any || getFalsyFlags(type) & TypeFlags.Undefined)) { + if (!(type.flags & TypeFlags.AnyOrUnknown || getFalsyFlags(type) & TypeFlags.Undefined)) { if (!constructor || !isPropertyInitializedInConstructor(propName, type, constructor)) { error(member.name, Diagnostics.Property_0_has_no_initializer_and_is_not_definitely_assigned_in_the_constructor, declarationNameToString(propName)); } @@ -26735,7 +26749,7 @@ namespace ts { if (type === errorType) { return TypeReferenceSerializationKind.Unknown; } - else if (type.flags & TypeFlags.Any) { + else if (type.flags & TypeFlags.AnyOrUnknown) { return TypeReferenceSerializationKind.ObjectType; } else if (isTypeAssignableToKind(type, TypeFlags.Void | TypeFlags.Nullable | TypeFlags.Never)) { From 5a0910a67547628eba2510d4352d9f83a9969917 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 26 May 2018 09:53:32 -0700 Subject: [PATCH 07/24] Accept new baselines --- tests/baselines/reference/conditionalTypes2.types | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/baselines/reference/conditionalTypes2.types b/tests/baselines/reference/conditionalTypes2.types index 906bc7e27df28..451529d19f251 100644 --- a/tests/baselines/reference/conditionalTypes2.types +++ b/tests/baselines/reference/conditionalTypes2.types @@ -403,7 +403,7 @@ interface B1 extends A1 { >T : T boom: T extends any ? true : true ->boom : T extends any ? true : true +>boom : true >T : T >true : true >true : true From b20925ad40838217cdc0c4d1224966a84ba72e2a Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 26 May 2018 12:09:18 -0700 Subject: [PATCH 08/24] 'null' and 'undefined' are bottom types in non-strictNullChecks mode --- src/compiler/checker.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index cadf4edcdcd6a..33f39293b7ef8 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -8592,6 +8592,9 @@ namespace ts { if (includes & TypeFlags.Any) { return includes & TypeFlags.Wildcard ? wildcardType : anyType; } + if (!strictNullChecks && includes & TypeFlags.Nullable) { + return includes & TypeFlags.Undefined ? undefinedType : nullType; + } if (includes & TypeFlags.String && includes & TypeFlags.StringLiteral || includes & TypeFlags.Number && includes & TypeFlags.NumberLiteral || includes & TypeFlags.ESSymbol && includes & TypeFlags.UniqueESSymbol) { From 9e4d19f2efe9844d82805f17c29d373b5b42e639 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 26 May 2018 18:18:08 -0700 Subject: [PATCH 09/24] Fixes to keyof and narrowing by typeof check --- src/compiler/checker.ts | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 33f39293b7ef8..57427cab1b3d6 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -569,7 +569,9 @@ namespace ts { number: numberType, boolean: booleanType, symbol: esSymbolType, - undefined: undefinedType + undefined: undefinedType, + object: nonPrimitiveType, + function: nonPrimitiveType }); const typeofType = createTypeofType(); @@ -8690,7 +8692,7 @@ namespace ts { maybeTypeOfKind(type, TypeFlags.InstantiableNonPrimitive) ? getIndexTypeForGenericType(type, stringsOnly) : getObjectFlags(type) & ObjectFlags.Mapped ? getConstraintTypeFromMappedType(type) : type === wildcardType ? wildcardType : - type.flags & TypeFlags.Any ? keyofConstraintType : + type.flags & TypeFlags.AnyOrUnknown ? keyofConstraintType : stringsOnly ? getIndexInfoOfType(type, IndexKind.String) ? stringType : getLiteralTypeFromPropertyNames(type, TypeFlags.StringLiteral) : getIndexInfoOfType(type, IndexKind.String) ? getUnionType([stringType, numberType, getLiteralTypeFromPropertyNames(type, TypeFlags.UniqueESSymbol)]) : getNonEnumNumberIndexInfo(type) ? getUnionType([numberType, getLiteralTypeFromPropertyNames(type, TypeFlags.StringLiteral | TypeFlags.UniqueESSymbol)]) : @@ -14062,9 +14064,11 @@ namespace ts { if (assumeTrue && !(type.flags & TypeFlags.Union)) { // We narrow a non-union type to an exact primitive type if the non-union type // is a supertype of that primitive type. For example, type 'any' can be narrowed - // to one of the primitive types. + // to one of the primitive types. Only 'unknown' and type parameters narrow to the + // 'object' type since those are the only types for which this narrowing provides + // additional capabilities. const targetType = typeofTypesByName.get(literal.text); - if (targetType) { + if (targetType && (type.flags & (TypeFlags.Unknown | TypeFlags.Instantiable) || targetType !== nonPrimitiveType)) { if (isTypeSubtypeOf(targetType, type)) { return targetType; } From f63b61c3f66a079f561ed0e2f7c7ed95c7c581d1 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 26 May 2018 18:30:17 -0700 Subject: [PATCH 10/24] Accept new baselines --- tests/baselines/reference/mappedTypes4.types | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/baselines/reference/mappedTypes4.types b/tests/baselines/reference/mappedTypes4.types index 7292e143b42b0..8a5b6af5319c4 100644 --- a/tests/baselines/reference/mappedTypes4.types +++ b/tests/baselines/reference/mappedTypes4.types @@ -41,17 +41,17 @@ function boxify(obj: T): Boxified { for (let k in obj) { >k : Extract ->obj : T +>obj : T & object result[k] = { value: obj[k] }; ->result[k] = { value: obj[k] } : { value: T[Extract]; } +>result[k] = { value: obj[k] } : { value: (T & object)[Extract]; } >result[k] : Boxified[Extract] >result : Boxified >k : Extract ->{ value: obj[k] } : { value: T[Extract]; } ->value : T[Extract] ->obj[k] : T[Extract] ->obj : T +>{ value: obj[k] } : { value: (T & object)[Extract]; } +>value : (T & object)[Extract] +>obj[k] : (T & object)[Extract] +>obj : T & object >k : Extract } return result; From 79e7700c6ba8ae7ca32094aea5a00932cb1e7a10 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sun, 27 May 2018 10:25:13 -0700 Subject: [PATCH 11/24] { [P in unknown]: XXX } should resolve to { [x: string]: XXX } --- src/compiler/checker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 57427cab1b3d6..b4e25c740da77 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -6431,7 +6431,7 @@ namespace ts { for (const prop of getPropertiesOfType(modifiersType)) { addMemberForKeyType(getLiteralTypeFromPropertyName(prop, include), /*_index*/ undefined, prop); } - if (modifiersType.flags & TypeFlags.Any || getIndexInfoOfType(modifiersType, IndexKind.String)) { + if (modifiersType.flags & TypeFlags.AnyOrUnknown || getIndexInfoOfType(modifiersType, IndexKind.String)) { addMemberForKeyType(stringType); } if (!keyofStringsOnly && getIndexInfoOfType(modifiersType, IndexKind.Number)) { From 73af0adcf04678111edaff704153039ceb26bc72 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sun, 27 May 2018 10:37:59 -0700 Subject: [PATCH 12/24] Add tests --- .../conformance/types/unknown/unknownType1.ts | 137 ++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 tests/cases/conformance/types/unknown/unknownType1.ts diff --git a/tests/cases/conformance/types/unknown/unknownType1.ts b/tests/cases/conformance/types/unknown/unknownType1.ts new file mode 100644 index 0000000000000..ae2ae80dfa04c --- /dev/null +++ b/tests/cases/conformance/types/unknown/unknownType1.ts @@ -0,0 +1,137 @@ +// @strict: true + +// In an intersection everything absorbs unknown + +type T00 = unknown & null; // null +type T01 = unknown & undefined; // undefined +type T02 = unknown & null & undefined; // null & undefined (which becomes never in union) +type T03 = unknown & string; // string +type T04 = unknown & string[]; // string[] +type T05 = unknown & unknown; // unknown +type T06 = unknown & any; // any + +// In a union an unknown absorbs everything + +type T10 = unknown | null; // unknown +type T11 = unknown | undefined; // unknown +type T12 = unknown | null | undefined; // unknown +type T13 = unknown | string; // unknown +type T14 = unknown | string[]; // unknown +type T15 = unknown | unknown; // unknown +type T16 = unknown | any; // any + +// Type variable and unknown in union and intersection + +type T20 = T & {}; // T & {} +type T21 = T | {}; // T | {} +type T22 = T & unknown; // T +type T23 = T | unknown; // unknown + +// unknown in conditional types + +type T30 = unknown extends T ? true : false; // Deferred +type T31 = T extends unknown ? true : false; // true +type T32 = never extends T ? true : false; // true +type T33 = T extends never ? true : false; // Deferred + +// keyof unknown + +type T40 = keyof any; // string | number | symbol +type T41 = keyof unknown; // string | number | symbol + +// typeof, instanceof, and user defined type predicates + +declare function isFunction(x: unknown): x is Function; + +function f1(x: unknown) { + if (typeof x === "string" || typeof x === "number") { + x; // string | number + } + if (typeof x === "object") { + x; // object + } + if (typeof x === "function") { + x; // object + } + if (x instanceof Error) { + x; // Error + } + if (isFunction(x)) { + x; // Function + } +} + +// Homomorphic mapped type over unknown + +type T50 = { [P in keyof T]: number }; +type T51 = T50; // { [x: string]: number } +type T52 = T50; // { [x: string]: number } + +// Anything is assignable to unknown + +function f2(pAny: any, pNever: never, pT: T) { + let x: unknown; + x = 123; + x = "hello"; + x = [1, 2, 3]; + x = new Error(); + x = x; + x = pAny; + x = pNever; + x = pT; +} + +// unknown assignable only to itself and any + +function f3(x: unknown) { + let v1: any = x; + let v2: unknown = x; + let v3: object = x; // Error + let v4: string = x; // Error + let v5: string[] = x; // Error + let v6: {} = x; // Error + let v7: {} | null | undefined = x; // Error +} + +// Type parameter 'T extends unknown' not related to object + +function f4(x: T) { + let y: object = x; // Error +} + +// Anything but primitive assignable to { [x: string]: unknown } + +function f5(x: { [x: string]: unknown }) { + x = {}; + x = { a: 5 }; + x = [1, 2, 3]; + x = 123; // Error +} + +// Locals of type unknown always considered initialized + +function f6() { + let x: unknown; + let y = x; +} + +// Spread of unknown causes result to be unknown + +function f7(x: {}, y: unknown, z: any) { + let o1 = { a: 42, ...x }; // { a: number } + let o2 = { a: 42, ...x, ...y }; // unknown + let o3 = { a: 42, ...x, ...y, ...z }; // any +} + +// Functions with unknown return type don't need return expressions + +function f8(): unknown { +} + +// Class properties of type unknown don't need definite assignment + +class C1 { + a: string; // Error + b: unknown; + c: any; +} From 5da063f9c15539964c197a60cc649a8ca5e25fe4 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sun, 27 May 2018 10:38:08 -0700 Subject: [PATCH 13/24] Accept new baselines --- .../reference/unknownType1.errors.txt | 165 ++++++++ tests/baselines/reference/unknownType1.js | 219 ++++++++++ .../baselines/reference/unknownType1.symbols | 335 +++++++++++++++ tests/baselines/reference/unknownType1.types | 396 ++++++++++++++++++ 4 files changed, 1115 insertions(+) create mode 100644 tests/baselines/reference/unknownType1.errors.txt create mode 100644 tests/baselines/reference/unknownType1.js create mode 100644 tests/baselines/reference/unknownType1.symbols create mode 100644 tests/baselines/reference/unknownType1.types diff --git a/tests/baselines/reference/unknownType1.errors.txt b/tests/baselines/reference/unknownType1.errors.txt new file mode 100644 index 0000000000000..a2118726b8bc7 --- /dev/null +++ b/tests/baselines/reference/unknownType1.errors.txt @@ -0,0 +1,165 @@ +tests/cases/conformance/types/unknown/unknownType1.ts(87,9): error TS2322: Type 'unknown' is not assignable to type 'object'. +tests/cases/conformance/types/unknown/unknownType1.ts(88,9): error TS2322: Type 'unknown' is not assignable to type 'string'. +tests/cases/conformance/types/unknown/unknownType1.ts(89,9): error TS2322: Type 'unknown' is not assignable to type 'string[]'. +tests/cases/conformance/types/unknown/unknownType1.ts(90,9): error TS2322: Type 'unknown' is not assignable to type '{}'. +tests/cases/conformance/types/unknown/unknownType1.ts(91,9): error TS2322: Type 'unknown' is not assignable to type '{} | null | undefined'. + Type 'unknown' is not assignable to type '{}'. +tests/cases/conformance/types/unknown/unknownType1.ts(97,9): error TS2322: Type 'T' is not assignable to type 'object'. +tests/cases/conformance/types/unknown/unknownType1.ts(106,5): error TS2322: Type '123' is not assignable to type '{ [x: string]: unknown; }'. +tests/cases/conformance/types/unknown/unknownType1.ts(132,5): error TS2564: Property 'a' has no initializer and is not definitely assigned in the constructor. + + +==== tests/cases/conformance/types/unknown/unknownType1.ts (8 errors) ==== + // In an intersection everything absorbs unknown + + type T00 = unknown & null; // null + type T01 = unknown & undefined; // undefined + type T02 = unknown & null & undefined; // null & undefined (which becomes never in union) + type T03 = unknown & string; // string + type T04 = unknown & string[]; // string[] + type T05 = unknown & unknown; // unknown + type T06 = unknown & any; // any + + // In a union an unknown absorbs everything + + type T10 = unknown | null; // unknown + type T11 = unknown | undefined; // unknown + type T12 = unknown | null | undefined; // unknown + type T13 = unknown | string; // unknown + type T14 = unknown | string[]; // unknown + type T15 = unknown | unknown; // unknown + type T16 = unknown | any; // any + + // Type variable and unknown in union and intersection + + type T20 = T & {}; // T & {} + type T21 = T | {}; // T | {} + type T22 = T & unknown; // T + type T23 = T | unknown; // unknown + + // unknown in conditional types + + type T30 = unknown extends T ? true : false; // Deferred + type T31 = T extends unknown ? true : false; // true + type T32 = never extends T ? true : false; // true + type T33 = T extends never ? true : false; // Deferred + + // keyof unknown + + type T40 = keyof any; // string | number | symbol + type T41 = keyof unknown; // string | number | symbol + + // typeof, instanceof, and user defined type predicates + + declare function isFunction(x: unknown): x is Function; + + function f1(x: unknown) { + if (typeof x === "string" || typeof x === "number") { + x; // string | number + } + if (typeof x === "object") { + x; // object + } + if (typeof x === "function") { + x; // object + } + if (x instanceof Error) { + x; // Error + } + if (isFunction(x)) { + x; // Function + } + } + + // Homomorphic mapped type over unknown + + type T50 = { [P in keyof T]: number }; + type T51 = T50; // { [x: string]: number } + type T52 = T50; // { [x: string]: number } + + // Anything is assignable to unknown + + function f2(pAny: any, pNever: never, pT: T) { + let x: unknown; + x = 123; + x = "hello"; + x = [1, 2, 3]; + x = new Error(); + x = x; + x = pAny; + x = pNever; + x = pT; + } + + // unknown assignable only to itself and any + + function f3(x: unknown) { + let v1: any = x; + let v2: unknown = x; + let v3: object = x; // Error + ~~ +!!! error TS2322: Type 'unknown' is not assignable to type 'object'. + let v4: string = x; // Error + ~~ +!!! error TS2322: Type 'unknown' is not assignable to type 'string'. + let v5: string[] = x; // Error + ~~ +!!! error TS2322: Type 'unknown' is not assignable to type 'string[]'. + let v6: {} = x; // Error + ~~ +!!! error TS2322: Type 'unknown' is not assignable to type '{}'. + let v7: {} | null | undefined = x; // Error + ~~ +!!! error TS2322: Type 'unknown' is not assignable to type '{} | null | undefined'. +!!! error TS2322: Type 'unknown' is not assignable to type '{}'. + } + + // Type parameter 'T extends unknown' not related to object + + function f4(x: T) { + let y: object = x; // Error + ~ +!!! error TS2322: Type 'T' is not assignable to type 'object'. + } + + // Anything but primitive assignable to { [x: string]: unknown } + + function f5(x: { [x: string]: unknown }) { + x = {}; + x = { a: 5 }; + x = [1, 2, 3]; + x = 123; // Error + ~ +!!! error TS2322: Type '123' is not assignable to type '{ [x: string]: unknown; }'. + } + + // Locals of type unknown always considered initialized + + function f6() { + let x: unknown; + let y = x; + } + + // Spread of unknown causes result to be unknown + + function f7(x: {}, y: unknown, z: any) { + let o1 = { a: 42, ...x }; // { a: number } + let o2 = { a: 42, ...x, ...y }; // unknown + let o3 = { a: 42, ...x, ...y, ...z }; // any + } + + // Functions with unknown return type don't need return expressions + + function f8(): unknown { + } + + // Class properties of type unknown don't need definite assignment + + class C1 { + a: string; // Error + ~ +!!! error TS2564: Property 'a' has no initializer and is not definitely assigned in the constructor. + b: unknown; + c: any; + } + \ No newline at end of file diff --git a/tests/baselines/reference/unknownType1.js b/tests/baselines/reference/unknownType1.js new file mode 100644 index 0000000000000..b722ef2006b10 --- /dev/null +++ b/tests/baselines/reference/unknownType1.js @@ -0,0 +1,219 @@ +//// [unknownType1.ts] +// In an intersection everything absorbs unknown + +type T00 = unknown & null; // null +type T01 = unknown & undefined; // undefined +type T02 = unknown & null & undefined; // null & undefined (which becomes never in union) +type T03 = unknown & string; // string +type T04 = unknown & string[]; // string[] +type T05 = unknown & unknown; // unknown +type T06 = unknown & any; // any + +// In a union an unknown absorbs everything + +type T10 = unknown | null; // unknown +type T11 = unknown | undefined; // unknown +type T12 = unknown | null | undefined; // unknown +type T13 = unknown | string; // unknown +type T14 = unknown | string[]; // unknown +type T15 = unknown | unknown; // unknown +type T16 = unknown | any; // any + +// Type variable and unknown in union and intersection + +type T20 = T & {}; // T & {} +type T21 = T | {}; // T | {} +type T22 = T & unknown; // T +type T23 = T | unknown; // unknown + +// unknown in conditional types + +type T30 = unknown extends T ? true : false; // Deferred +type T31 = T extends unknown ? true : false; // true +type T32 = never extends T ? true : false; // true +type T33 = T extends never ? true : false; // Deferred + +// keyof unknown + +type T40 = keyof any; // string | number | symbol +type T41 = keyof unknown; // string | number | symbol + +// typeof, instanceof, and user defined type predicates + +declare function isFunction(x: unknown): x is Function; + +function f1(x: unknown) { + if (typeof x === "string" || typeof x === "number") { + x; // string | number + } + if (typeof x === "object") { + x; // object + } + if (typeof x === "function") { + x; // object + } + if (x instanceof Error) { + x; // Error + } + if (isFunction(x)) { + x; // Function + } +} + +// Homomorphic mapped type over unknown + +type T50 = { [P in keyof T]: number }; +type T51 = T50; // { [x: string]: number } +type T52 = T50; // { [x: string]: number } + +// Anything is assignable to unknown + +function f2(pAny: any, pNever: never, pT: T) { + let x: unknown; + x = 123; + x = "hello"; + x = [1, 2, 3]; + x = new Error(); + x = x; + x = pAny; + x = pNever; + x = pT; +} + +// unknown assignable only to itself and any + +function f3(x: unknown) { + let v1: any = x; + let v2: unknown = x; + let v3: object = x; // Error + let v4: string = x; // Error + let v5: string[] = x; // Error + let v6: {} = x; // Error + let v7: {} | null | undefined = x; // Error +} + +// Type parameter 'T extends unknown' not related to object + +function f4(x: T) { + let y: object = x; // Error +} + +// Anything but primitive assignable to { [x: string]: unknown } + +function f5(x: { [x: string]: unknown }) { + x = {}; + x = { a: 5 }; + x = [1, 2, 3]; + x = 123; // Error +} + +// Locals of type unknown always considered initialized + +function f6() { + let x: unknown; + let y = x; +} + +// Spread of unknown causes result to be unknown + +function f7(x: {}, y: unknown, z: any) { + let o1 = { a: 42, ...x }; // { a: number } + let o2 = { a: 42, ...x, ...y }; // unknown + let o3 = { a: 42, ...x, ...y, ...z }; // any +} + +// Functions with unknown return type don't need return expressions + +function f8(): unknown { +} + +// Class properties of type unknown don't need definite assignment + +class C1 { + a: string; // Error + b: unknown; + c: any; +} + + +//// [unknownType1.js] +"use strict"; +// In an intersection everything absorbs unknown +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +function f1(x) { + if (typeof x === "string" || typeof x === "number") { + x; // string | number + } + if (typeof x === "object") { + x; // object + } + if (typeof x === "function") { + x; // object + } + if (x instanceof Error) { + x; // Error + } + if (isFunction(x)) { + x; // Function + } +} +// Anything is assignable to unknown +function f2(pAny, pNever, pT) { + var x; + x = 123; + x = "hello"; + x = [1, 2, 3]; + x = new Error(); + x = x; + x = pAny; + x = pNever; + x = pT; +} +// unknown assignable only to itself and any +function f3(x) { + var v1 = x; + var v2 = x; + var v3 = x; // Error + var v4 = x; // Error + var v5 = x; // Error + var v6 = x; // Error + var v7 = x; // Error +} +// Type parameter 'T extends unknown' not related to object +function f4(x) { + var y = x; // Error +} +// Anything but primitive assignable to { [x: string]: unknown } +function f5(x) { + x = {}; + x = { a: 5 }; + x = [1, 2, 3]; + x = 123; // Error +} +// Locals of type unknown always considered initialized +function f6() { + var x; + var y = x; +} +// Spread of unknown causes result to be unknown +function f7(x, y, z) { + var o1 = __assign({ a: 42 }, x); // { a: number } + var o2 = __assign({ a: 42 }, x, y); // unknown + var o3 = __assign({ a: 42 }, x, y, z); // any +} +// Functions with unknown return type don't need return expressions +function f8() { +} +// Class properties of type unknown don't need definite assignment +var C1 = /** @class */ (function () { + function C1() { + } + return C1; +}()); diff --git a/tests/baselines/reference/unknownType1.symbols b/tests/baselines/reference/unknownType1.symbols new file mode 100644 index 0000000000000..007cae242b3ca --- /dev/null +++ b/tests/baselines/reference/unknownType1.symbols @@ -0,0 +1,335 @@ +=== tests/cases/conformance/types/unknown/unknownType1.ts === +// In an intersection everything absorbs unknown + +type T00 = unknown & null; // null +>T00 : Symbol(T00, Decl(unknownType1.ts, 0, 0)) + +type T01 = unknown & undefined; // undefined +>T01 : Symbol(T01, Decl(unknownType1.ts, 2, 26)) + +type T02 = unknown & null & undefined; // null & undefined (which becomes never in union) +>T02 : Symbol(T02, Decl(unknownType1.ts, 3, 31)) + +type T03 = unknown & string; // string +>T03 : Symbol(T03, Decl(unknownType1.ts, 4, 38)) + +type T04 = unknown & string[]; // string[] +>T04 : Symbol(T04, Decl(unknownType1.ts, 5, 28)) + +type T05 = unknown & unknown; // unknown +>T05 : Symbol(T05, Decl(unknownType1.ts, 6, 30)) + +type T06 = unknown & any; // any +>T06 : Symbol(T06, Decl(unknownType1.ts, 7, 29)) + +// In a union an unknown absorbs everything + +type T10 = unknown | null; // unknown +>T10 : Symbol(T10, Decl(unknownType1.ts, 8, 25)) + +type T11 = unknown | undefined; // unknown +>T11 : Symbol(T11, Decl(unknownType1.ts, 12, 26)) + +type T12 = unknown | null | undefined; // unknown +>T12 : Symbol(T12, Decl(unknownType1.ts, 13, 31)) + +type T13 = unknown | string; // unknown +>T13 : Symbol(T13, Decl(unknownType1.ts, 14, 38)) + +type T14 = unknown | string[]; // unknown +>T14 : Symbol(T14, Decl(unknownType1.ts, 15, 28)) + +type T15 = unknown | unknown; // unknown +>T15 : Symbol(T15, Decl(unknownType1.ts, 16, 30)) + +type T16 = unknown | any; // any +>T16 : Symbol(T16, Decl(unknownType1.ts, 17, 29)) + +// Type variable and unknown in union and intersection + +type T20 = T & {}; // T & {} +>T20 : Symbol(T20, Decl(unknownType1.ts, 18, 25)) +>T : Symbol(T, Decl(unknownType1.ts, 22, 9)) +>T : Symbol(T, Decl(unknownType1.ts, 22, 9)) + +type T21 = T | {}; // T | {} +>T21 : Symbol(T21, Decl(unknownType1.ts, 22, 21)) +>T : Symbol(T, Decl(unknownType1.ts, 23, 9)) +>T : Symbol(T, Decl(unknownType1.ts, 23, 9)) + +type T22 = T & unknown; // T +>T22 : Symbol(T22, Decl(unknownType1.ts, 23, 21)) +>T : Symbol(T, Decl(unknownType1.ts, 24, 9)) +>T : Symbol(T, Decl(unknownType1.ts, 24, 9)) + +type T23 = T | unknown; // unknown +>T23 : Symbol(T23, Decl(unknownType1.ts, 24, 26)) +>T : Symbol(T, Decl(unknownType1.ts, 25, 9)) +>T : Symbol(T, Decl(unknownType1.ts, 25, 9)) + +// unknown in conditional types + +type T30 = unknown extends T ? true : false; // Deferred +>T30 : Symbol(T30, Decl(unknownType1.ts, 25, 26)) +>T : Symbol(T, Decl(unknownType1.ts, 29, 9)) +>T : Symbol(T, Decl(unknownType1.ts, 29, 9)) + +type T31 = T extends unknown ? true : false; // true +>T31 : Symbol(T31, Decl(unknownType1.ts, 29, 47)) +>T : Symbol(T, Decl(unknownType1.ts, 30, 9)) +>T : Symbol(T, Decl(unknownType1.ts, 30, 9)) + +type T32 = never extends T ? true : false; // true +>T32 : Symbol(T32, Decl(unknownType1.ts, 30, 47)) +>T : Symbol(T, Decl(unknownType1.ts, 31, 9)) +>T : Symbol(T, Decl(unknownType1.ts, 31, 9)) + +type T33 = T extends never ? true : false; // Deferred +>T33 : Symbol(T33, Decl(unknownType1.ts, 31, 45)) +>T : Symbol(T, Decl(unknownType1.ts, 32, 9)) +>T : Symbol(T, Decl(unknownType1.ts, 32, 9)) + +// keyof unknown + +type T40 = keyof any; // string | number | symbol +>T40 : Symbol(T40, Decl(unknownType1.ts, 32, 45)) + +type T41 = keyof unknown; // string | number | symbol +>T41 : Symbol(T41, Decl(unknownType1.ts, 36, 21)) + +// typeof, instanceof, and user defined type predicates + +declare function isFunction(x: unknown): x is Function; +>isFunction : Symbol(isFunction, Decl(unknownType1.ts, 37, 25)) +>x : Symbol(x, Decl(unknownType1.ts, 41, 28)) +>x : Symbol(x, Decl(unknownType1.ts, 41, 28)) +>Function : Symbol(Function, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) + +function f1(x: unknown) { +>f1 : Symbol(f1, Decl(unknownType1.ts, 41, 55)) +>x : Symbol(x, Decl(unknownType1.ts, 43, 12)) + + if (typeof x === "string" || typeof x === "number") { +>x : Symbol(x, Decl(unknownType1.ts, 43, 12)) +>x : Symbol(x, Decl(unknownType1.ts, 43, 12)) + + x; // string | number +>x : Symbol(x, Decl(unknownType1.ts, 43, 12)) + } + if (typeof x === "object") { +>x : Symbol(x, Decl(unknownType1.ts, 43, 12)) + + x; // object +>x : Symbol(x, Decl(unknownType1.ts, 43, 12)) + } + if (typeof x === "function") { +>x : Symbol(x, Decl(unknownType1.ts, 43, 12)) + + x; // object +>x : Symbol(x, Decl(unknownType1.ts, 43, 12)) + } + if (x instanceof Error) { +>x : Symbol(x, Decl(unknownType1.ts, 43, 12)) +>Error : Symbol(Error, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) + + x; // Error +>x : Symbol(x, Decl(unknownType1.ts, 43, 12)) + } + if (isFunction(x)) { +>isFunction : Symbol(isFunction, Decl(unknownType1.ts, 37, 25)) +>x : Symbol(x, Decl(unknownType1.ts, 43, 12)) + + x; // Function +>x : Symbol(x, Decl(unknownType1.ts, 43, 12)) + } +} + +// Homomorphic mapped type over unknown + +type T50 = { [P in keyof T]: number }; +>T50 : Symbol(T50, Decl(unknownType1.ts, 59, 1)) +>T : Symbol(T, Decl(unknownType1.ts, 63, 9)) +>P : Symbol(P, Decl(unknownType1.ts, 63, 17)) +>T : Symbol(T, Decl(unknownType1.ts, 63, 9)) + +type T51 = T50; // { [x: string]: number } +>T51 : Symbol(T51, Decl(unknownType1.ts, 63, 41)) +>T50 : Symbol(T50, Decl(unknownType1.ts, 59, 1)) + +type T52 = T50; // { [x: string]: number } +>T52 : Symbol(T52, Decl(unknownType1.ts, 64, 24)) +>T50 : Symbol(T50, Decl(unknownType1.ts, 59, 1)) + +// Anything is assignable to unknown + +function f2(pAny: any, pNever: never, pT: T) { +>f2 : Symbol(f2, Decl(unknownType1.ts, 65, 20)) +>T : Symbol(T, Decl(unknownType1.ts, 69, 12)) +>pAny : Symbol(pAny, Decl(unknownType1.ts, 69, 15)) +>pNever : Symbol(pNever, Decl(unknownType1.ts, 69, 25)) +>pT : Symbol(pT, Decl(unknownType1.ts, 69, 40)) +>T : Symbol(T, Decl(unknownType1.ts, 69, 12)) + + let x: unknown; +>x : Symbol(x, Decl(unknownType1.ts, 70, 7)) + + x = 123; +>x : Symbol(x, Decl(unknownType1.ts, 70, 7)) + + x = "hello"; +>x : Symbol(x, Decl(unknownType1.ts, 70, 7)) + + x = [1, 2, 3]; +>x : Symbol(x, Decl(unknownType1.ts, 70, 7)) + + x = new Error(); +>x : Symbol(x, Decl(unknownType1.ts, 70, 7)) +>Error : Symbol(Error, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) + + x = x; +>x : Symbol(x, Decl(unknownType1.ts, 70, 7)) +>x : Symbol(x, Decl(unknownType1.ts, 70, 7)) + + x = pAny; +>x : Symbol(x, Decl(unknownType1.ts, 70, 7)) +>pAny : Symbol(pAny, Decl(unknownType1.ts, 69, 15)) + + x = pNever; +>x : Symbol(x, Decl(unknownType1.ts, 70, 7)) +>pNever : Symbol(pNever, Decl(unknownType1.ts, 69, 25)) + + x = pT; +>x : Symbol(x, Decl(unknownType1.ts, 70, 7)) +>pT : Symbol(pT, Decl(unknownType1.ts, 69, 40)) +} + +// unknown assignable only to itself and any + +function f3(x: unknown) { +>f3 : Symbol(f3, Decl(unknownType1.ts, 79, 1)) +>x : Symbol(x, Decl(unknownType1.ts, 83, 12)) + + let v1: any = x; +>v1 : Symbol(v1, Decl(unknownType1.ts, 84, 7)) +>x : Symbol(x, Decl(unknownType1.ts, 83, 12)) + + let v2: unknown = x; +>v2 : Symbol(v2, Decl(unknownType1.ts, 85, 7)) +>x : Symbol(x, Decl(unknownType1.ts, 83, 12)) + + let v3: object = x; // Error +>v3 : Symbol(v3, Decl(unknownType1.ts, 86, 7)) +>x : Symbol(x, Decl(unknownType1.ts, 83, 12)) + + let v4: string = x; // Error +>v4 : Symbol(v4, Decl(unknownType1.ts, 87, 7)) +>x : Symbol(x, Decl(unknownType1.ts, 83, 12)) + + let v5: string[] = x; // Error +>v5 : Symbol(v5, Decl(unknownType1.ts, 88, 7)) +>x : Symbol(x, Decl(unknownType1.ts, 83, 12)) + + let v6: {} = x; // Error +>v6 : Symbol(v6, Decl(unknownType1.ts, 89, 7)) +>x : Symbol(x, Decl(unknownType1.ts, 83, 12)) + + let v7: {} | null | undefined = x; // Error +>v7 : Symbol(v7, Decl(unknownType1.ts, 90, 7)) +>x : Symbol(x, Decl(unknownType1.ts, 83, 12)) +} + +// Type parameter 'T extends unknown' not related to object + +function f4(x: T) { +>f4 : Symbol(f4, Decl(unknownType1.ts, 91, 1)) +>T : Symbol(T, Decl(unknownType1.ts, 95, 12)) +>x : Symbol(x, Decl(unknownType1.ts, 95, 31)) +>T : Symbol(T, Decl(unknownType1.ts, 95, 12)) + + let y: object = x; // Error +>y : Symbol(y, Decl(unknownType1.ts, 96, 7)) +>x : Symbol(x, Decl(unknownType1.ts, 95, 31)) +} + +// Anything but primitive assignable to { [x: string]: unknown } + +function f5(x: { [x: string]: unknown }) { +>f5 : Symbol(f5, Decl(unknownType1.ts, 97, 1)) +>x : Symbol(x, Decl(unknownType1.ts, 101, 12)) +>x : Symbol(x, Decl(unknownType1.ts, 101, 18)) + + x = {}; +>x : Symbol(x, Decl(unknownType1.ts, 101, 12)) + + x = { a: 5 }; +>x : Symbol(x, Decl(unknownType1.ts, 101, 12)) +>a : Symbol(a, Decl(unknownType1.ts, 103, 9)) + + x = [1, 2, 3]; +>x : Symbol(x, Decl(unknownType1.ts, 101, 12)) + + x = 123; // Error +>x : Symbol(x, Decl(unknownType1.ts, 101, 12)) +} + +// Locals of type unknown always considered initialized + +function f6() { +>f6 : Symbol(f6, Decl(unknownType1.ts, 106, 1)) + + let x: unknown; +>x : Symbol(x, Decl(unknownType1.ts, 111, 7)) + + let y = x; +>y : Symbol(y, Decl(unknownType1.ts, 112, 7)) +>x : Symbol(x, Decl(unknownType1.ts, 111, 7)) +} + +// Spread of unknown causes result to be unknown + +function f7(x: {}, y: unknown, z: any) { +>f7 : Symbol(f7, Decl(unknownType1.ts, 113, 1)) +>x : Symbol(x, Decl(unknownType1.ts, 117, 12)) +>y : Symbol(y, Decl(unknownType1.ts, 117, 18)) +>z : Symbol(z, Decl(unknownType1.ts, 117, 30)) + + let o1 = { a: 42, ...x }; // { a: number } +>o1 : Symbol(o1, Decl(unknownType1.ts, 118, 7)) +>a : Symbol(a, Decl(unknownType1.ts, 118, 14)) +>x : Symbol(x, Decl(unknownType1.ts, 117, 12)) + + let o2 = { a: 42, ...x, ...y }; // unknown +>o2 : Symbol(o2, Decl(unknownType1.ts, 119, 7)) +>a : Symbol(a, Decl(unknownType1.ts, 119, 14)) +>x : Symbol(x, Decl(unknownType1.ts, 117, 12)) +>y : Symbol(y, Decl(unknownType1.ts, 117, 18)) + + let o3 = { a: 42, ...x, ...y, ...z }; // any +>o3 : Symbol(o3, Decl(unknownType1.ts, 120, 7)) +>a : Symbol(a, Decl(unknownType1.ts, 120, 14)) +>x : Symbol(x, Decl(unknownType1.ts, 117, 12)) +>y : Symbol(y, Decl(unknownType1.ts, 117, 18)) +>z : Symbol(z, Decl(unknownType1.ts, 117, 30)) +} + +// Functions with unknown return type don't need return expressions + +function f8(): unknown { +>f8 : Symbol(f8, Decl(unknownType1.ts, 121, 1)) +} + +// Class properties of type unknown don't need definite assignment + +class C1 { +>C1 : Symbol(C1, Decl(unknownType1.ts, 126, 1)) + + a: string; // Error +>a : Symbol(C1.a, Decl(unknownType1.ts, 130, 10)) + + b: unknown; +>b : Symbol(C1.b, Decl(unknownType1.ts, 131, 14)) + + c: any; +>c : Symbol(C1.c, Decl(unknownType1.ts, 132, 15)) +} + diff --git a/tests/baselines/reference/unknownType1.types b/tests/baselines/reference/unknownType1.types new file mode 100644 index 0000000000000..f92ff19867c4a --- /dev/null +++ b/tests/baselines/reference/unknownType1.types @@ -0,0 +1,396 @@ +=== tests/cases/conformance/types/unknown/unknownType1.ts === +// In an intersection everything absorbs unknown + +type T00 = unknown & null; // null +>T00 : null +>null : null + +type T01 = unknown & undefined; // undefined +>T01 : undefined + +type T02 = unknown & null & undefined; // null & undefined (which becomes never in union) +>T02 : T02 +>null : null + +type T03 = unknown & string; // string +>T03 : string + +type T04 = unknown & string[]; // string[] +>T04 : string[] + +type T05 = unknown & unknown; // unknown +>T05 : unknown + +type T06 = unknown & any; // any +>T06 : any + +// In a union an unknown absorbs everything + +type T10 = unknown | null; // unknown +>T10 : unknown +>null : null + +type T11 = unknown | undefined; // unknown +>T11 : unknown + +type T12 = unknown | null | undefined; // unknown +>T12 : unknown +>null : null + +type T13 = unknown | string; // unknown +>T13 : unknown + +type T14 = unknown | string[]; // unknown +>T14 : unknown + +type T15 = unknown | unknown; // unknown +>T15 : unknown + +type T16 = unknown | any; // any +>T16 : any + +// Type variable and unknown in union and intersection + +type T20 = T & {}; // T & {} +>T20 : T20 +>T : T +>T : T + +type T21 = T | {}; // T | {} +>T21 : T21 +>T : T +>T : T + +type T22 = T & unknown; // T +>T22 : T +>T : T +>T : T + +type T23 = T | unknown; // unknown +>T23 : unknown +>T : T +>T : T + +// unknown in conditional types + +type T30 = unknown extends T ? true : false; // Deferred +>T30 : T30 +>T : T +>T : T +>true : true +>false : false + +type T31 = T extends unknown ? true : false; // true +>T31 : true +>T : T +>T : T +>true : true +>false : false + +type T32 = never extends T ? true : false; // true +>T32 : true +>T : T +>T : T +>true : true +>false : false + +type T33 = T extends never ? true : false; // Deferred +>T33 : T33 +>T : T +>T : T +>true : true +>false : false + +// keyof unknown + +type T40 = keyof any; // string | number | symbol +>T40 : string | number | symbol + +type T41 = keyof unknown; // string | number | symbol +>T41 : string | number | symbol + +// typeof, instanceof, and user defined type predicates + +declare function isFunction(x: unknown): x is Function; +>isFunction : (x: unknown) => x is Function +>x : unknown +>x : any +>Function : Function + +function f1(x: unknown) { +>f1 : (x: unknown) => void +>x : unknown + + if (typeof x === "string" || typeof x === "number") { +>typeof x === "string" || typeof x === "number" : boolean +>typeof x === "string" : boolean +>typeof x : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function" +>x : unknown +>"string" : "string" +>typeof x === "number" : boolean +>typeof x : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function" +>x : unknown +>"number" : "number" + + x; // string | number +>x : string | number + } + if (typeof x === "object") { +>typeof x === "object" : boolean +>typeof x : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function" +>x : unknown +>"object" : "object" + + x; // object +>x : object + } + if (typeof x === "function") { +>typeof x === "function" : boolean +>typeof x : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function" +>x : unknown +>"function" : "function" + + x; // object +>x : object + } + if (x instanceof Error) { +>x instanceof Error : boolean +>x : unknown +>Error : ErrorConstructor + + x; // Error +>x : Error + } + if (isFunction(x)) { +>isFunction(x) : boolean +>isFunction : (x: unknown) => x is Function +>x : unknown + + x; // Function +>x : Function + } +} + +// Homomorphic mapped type over unknown + +type T50 = { [P in keyof T]: number }; +>T50 : T50 +>T : T +>P : P +>T : T + +type T51 = T50; // { [x: string]: number } +>T51 : T50 +>T50 : T50 + +type T52 = T50; // { [x: string]: number } +>T52 : T50 +>T50 : T50 + +// Anything is assignable to unknown + +function f2(pAny: any, pNever: never, pT: T) { +>f2 : (pAny: any, pNever: never, pT: T) => void +>T : T +>pAny : any +>pNever : never +>pT : T +>T : T + + let x: unknown; +>x : unknown + + x = 123; +>x = 123 : 123 +>x : unknown +>123 : 123 + + x = "hello"; +>x = "hello" : "hello" +>x : unknown +>"hello" : "hello" + + x = [1, 2, 3]; +>x = [1, 2, 3] : number[] +>x : unknown +>[1, 2, 3] : number[] +>1 : 1 +>2 : 2 +>3 : 3 + + x = new Error(); +>x = new Error() : Error +>x : unknown +>new Error() : Error +>Error : ErrorConstructor + + x = x; +>x = x : unknown +>x : unknown +>x : unknown + + x = pAny; +>x = pAny : any +>x : unknown +>pAny : any + + x = pNever; +>x = pNever : never +>x : unknown +>pNever : never + + x = pT; +>x = pT : T +>x : unknown +>pT : T +} + +// unknown assignable only to itself and any + +function f3(x: unknown) { +>f3 : (x: unknown) => void +>x : unknown + + let v1: any = x; +>v1 : any +>x : unknown + + let v2: unknown = x; +>v2 : unknown +>x : unknown + + let v3: object = x; // Error +>v3 : object +>x : unknown + + let v4: string = x; // Error +>v4 : string +>x : unknown + + let v5: string[] = x; // Error +>v5 : string[] +>x : unknown + + let v6: {} = x; // Error +>v6 : {} +>x : unknown + + let v7: {} | null | undefined = x; // Error +>v7 : {} | null | undefined +>null : null +>x : unknown +} + +// Type parameter 'T extends unknown' not related to object + +function f4(x: T) { +>f4 : (x: T) => void +>T : T +>x : T +>T : T + + let y: object = x; // Error +>y : object +>x : T +} + +// Anything but primitive assignable to { [x: string]: unknown } + +function f5(x: { [x: string]: unknown }) { +>f5 : (x: { [x: string]: unknown; }) => void +>x : { [x: string]: unknown; } +>x : string + + x = {}; +>x = {} : {} +>x : { [x: string]: unknown; } +>{} : {} + + x = { a: 5 }; +>x = { a: 5 } : { a: number; } +>x : { [x: string]: unknown; } +>{ a: 5 } : { a: number; } +>a : number +>5 : 5 + + x = [1, 2, 3]; +>x = [1, 2, 3] : number[] +>x : { [x: string]: unknown; } +>[1, 2, 3] : number[] +>1 : 1 +>2 : 2 +>3 : 3 + + x = 123; // Error +>x = 123 : 123 +>x : { [x: string]: unknown; } +>123 : 123 +} + +// Locals of type unknown always considered initialized + +function f6() { +>f6 : () => void + + let x: unknown; +>x : unknown + + let y = x; +>y : unknown +>x : unknown +} + +// Spread of unknown causes result to be unknown + +function f7(x: {}, y: unknown, z: any) { +>f7 : (x: {}, y: unknown, z: any) => void +>x : {} +>y : unknown +>z : any + + let o1 = { a: 42, ...x }; // { a: number } +>o1 : { a: number; } +>{ a: 42, ...x } : { a: number; } +>a : number +>42 : 42 +>x : {} + + let o2 = { a: 42, ...x, ...y }; // unknown +>o2 : unknown +>{ a: 42, ...x, ...y } : unknown +>a : number +>42 : 42 +>x : {} +>y : unknown + + let o3 = { a: 42, ...x, ...y, ...z }; // any +>o3 : any +>{ a: 42, ...x, ...y, ...z } : any +>a : number +>42 : 42 +>x : {} +>y : unknown +>z : any +} + +// Functions with unknown return type don't need return expressions + +function f8(): unknown { +>f8 : () => unknown +} + +// Class properties of type unknown don't need definite assignment + +class C1 { +>C1 : C1 + + a: string; // Error +>a : string + + b: unknown; +>b : unknown + + c: any; +>c : any +} + From 353802c140db1c8860ec0851b4a26a24a396aab1 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sun, 27 May 2018 15:43:31 -0700 Subject: [PATCH 14/24] Check we have non-unknown where we require non-nullable --- src/compiler/checker.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index b4e25c740da77..5a75bd47dfc10 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -569,9 +569,7 @@ namespace ts { number: numberType, boolean: booleanType, symbol: esSymbolType, - undefined: undefinedType, - object: nonPrimitiveType, - function: nonPrimitiveType + undefined: undefinedType }); const typeofType = createTypeofType(); @@ -4399,7 +4397,7 @@ namespace ts { let type: Type | undefined; if (pattern.kind === SyntaxKind.ObjectBindingPattern) { if (declaration.dotDotDotToken) { - if (!isValidSpreadType(parentType)) { + if (parentType.flags & TypeFlags.Unknown || !isValidSpreadType(parentType)) { error(declaration, Diagnostics.Rest_types_may_only_be_created_from_object_types); return errorType; } @@ -14064,11 +14062,9 @@ namespace ts { if (assumeTrue && !(type.flags & TypeFlags.Union)) { // We narrow a non-union type to an exact primitive type if the non-union type // is a supertype of that primitive type. For example, type 'any' can be narrowed - // to one of the primitive types. Only 'unknown' and type parameters narrow to the - // 'object' type since those are the only types for which this narrowing provides - // additional capabilities. + // to one of the primitive types. const targetType = typeofTypesByName.get(literal.text); - if (targetType && (type.flags & (TypeFlags.Unknown | TypeFlags.Instantiable) || targetType !== nonPrimitiveType)) { + if (targetType) { if (isTypeSubtypeOf(targetType, type)) { return targetType; } @@ -17098,6 +17094,10 @@ namespace ts { undefinedDiagnostic?: DiagnosticMessage, nullOrUndefinedDiagnostic?: DiagnosticMessage ): Type { + if (type.flags & TypeFlags.Unknown) { + error(node, Diagnostics.Object_is_of_type_unknown); + return errorType; + } const kind = (strictNullChecks ? getFalsyFlags(type) : type.flags) & TypeFlags.Nullable; if (kind) { error(node, kind & TypeFlags.Undefined ? kind & TypeFlags.Null ? From a83653ed99516af7b5ba2c1443b648603cc0c706 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sun, 27 May 2018 15:43:44 -0700 Subject: [PATCH 15/24] Add new diagnostic --- src/compiler/diagnosticMessages.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index be96d3de07dd8..03d0170ec613f 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -2024,6 +2024,10 @@ "category": "Error", "code": 2570 }, + "Object is of type 'unknown'.": { + "category": "Error", + "code": 2571 + }, "JSX element attributes type '{0}' may not be a union type.": { "category": "Error", "code": 2600 From 31c73defa745ab202b7adcf5ca222090de4f7abc Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sun, 27 May 2018 15:44:01 -0700 Subject: [PATCH 16/24] Update tests --- .../conformance/types/unknown/unknownType1.ts | 52 ++++++++++++++----- 1 file changed, 38 insertions(+), 14 deletions(-) diff --git a/tests/cases/conformance/types/unknown/unknownType1.ts b/tests/cases/conformance/types/unknown/unknownType1.ts index ae2ae80dfa04c..dfd1c18693eed 100644 --- a/tests/cases/conformance/types/unknown/unknownType1.ts +++ b/tests/cases/conformance/types/unknown/unknownType1.ts @@ -39,20 +39,38 @@ type T33 = T extends never ? true : false; // Deferred type T40 = keyof any; // string | number | symbol type T41 = keyof unknown; // string | number | symbol +// Only equality operators are allowed with unknown + +function f10(x: unknown) { + x == 5; + x !== 10; + x >= 0; // Error + x.foo; // Error + x[10]; // Error + x(); // Error + x + 1; // Error + x * 2; // Error + -x; // Error + +x; // Error +} + +// No property accesses, element accesses, or function calls + +function f11(x: unknown) { + x.foo; // Error + x[5]; // Error + x(); // Error + new x(); // Error +} + // typeof, instanceof, and user defined type predicates declare function isFunction(x: unknown): x is Function; -function f1(x: unknown) { +function f20(x: unknown) { if (typeof x === "string" || typeof x === "number") { x; // string | number } - if (typeof x === "object") { - x; // object - } - if (typeof x === "function") { - x; // object - } if (x instanceof Error) { x; // Error } @@ -69,7 +87,7 @@ type T52 = T50; // { [x: string]: number } // Anything is assignable to unknown -function f2(pAny: any, pNever: never, pT: T) { +function f21(pAny: any, pNever: never, pT: T) { let x: unknown; x = 123; x = "hello"; @@ -83,7 +101,7 @@ function f2(pAny: any, pNever: never, pT: T) { // unknown assignable only to itself and any -function f3(x: unknown) { +function f22(x: unknown) { let v1: any = x; let v2: unknown = x; let v3: object = x; // Error @@ -95,13 +113,13 @@ function f3(x: unknown) { // Type parameter 'T extends unknown' not related to object -function f4(x: T) { +function f23(x: T) { let y: object = x; // Error } // Anything but primitive assignable to { [x: string]: unknown } -function f5(x: { [x: string]: unknown }) { +function f24(x: { [x: string]: unknown }) { x = {}; x = { a: 5 }; x = [1, 2, 3]; @@ -110,14 +128,14 @@ function f5(x: { [x: string]: unknown }) { // Locals of type unknown always considered initialized -function f6() { +function f25() { let x: unknown; let y = x; } // Spread of unknown causes result to be unknown -function f7(x: {}, y: unknown, z: any) { +function f26(x: {}, y: unknown, z: any) { let o1 = { a: 42, ...x }; // { a: number } let o2 = { a: 42, ...x, ...y }; // unknown let o3 = { a: 42, ...x, ...y, ...z }; // any @@ -125,7 +143,13 @@ function f7(x: {}, y: unknown, z: any) { // Functions with unknown return type don't need return expressions -function f8(): unknown { +function f27(): unknown { +} + +// Rest type cannot be created from unknown + +function f28(x: unknown) { + let { ...a } = x; // Error } // Class properties of type unknown don't need definite assignment From a4a73df839cc6c7ed5f68aad69002ee5c03ab5e3 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sun, 27 May 2018 15:44:08 -0700 Subject: [PATCH 17/24] Accept new baselines --- tests/baselines/reference/mappedTypes4.types | 12 +- .../reference/unknownType1.errors.txt | 109 +++++-- tests/baselines/reference/unknownType1.js | 107 +++++-- .../baselines/reference/unknownType1.symbols | 285 +++++++++++------- tests/baselines/reference/unknownType1.types | 140 ++++++--- 5 files changed, 447 insertions(+), 206 deletions(-) diff --git a/tests/baselines/reference/mappedTypes4.types b/tests/baselines/reference/mappedTypes4.types index 8a5b6af5319c4..7292e143b42b0 100644 --- a/tests/baselines/reference/mappedTypes4.types +++ b/tests/baselines/reference/mappedTypes4.types @@ -41,17 +41,17 @@ function boxify(obj: T): Boxified { for (let k in obj) { >k : Extract ->obj : T & object +>obj : T result[k] = { value: obj[k] }; ->result[k] = { value: obj[k] } : { value: (T & object)[Extract]; } +>result[k] = { value: obj[k] } : { value: T[Extract]; } >result[k] : Boxified[Extract] >result : Boxified >k : Extract ->{ value: obj[k] } : { value: (T & object)[Extract]; } ->value : (T & object)[Extract] ->obj[k] : (T & object)[Extract] ->obj : T & object +>{ value: obj[k] } : { value: T[Extract]; } +>value : T[Extract] +>obj[k] : T[Extract] +>obj : T >k : Extract } return result; diff --git a/tests/baselines/reference/unknownType1.errors.txt b/tests/baselines/reference/unknownType1.errors.txt index a2118726b8bc7..26030e138319b 100644 --- a/tests/baselines/reference/unknownType1.errors.txt +++ b/tests/baselines/reference/unknownType1.errors.txt @@ -1,15 +1,28 @@ -tests/cases/conformance/types/unknown/unknownType1.ts(87,9): error TS2322: Type 'unknown' is not assignable to type 'object'. -tests/cases/conformance/types/unknown/unknownType1.ts(88,9): error TS2322: Type 'unknown' is not assignable to type 'string'. -tests/cases/conformance/types/unknown/unknownType1.ts(89,9): error TS2322: Type 'unknown' is not assignable to type 'string[]'. -tests/cases/conformance/types/unknown/unknownType1.ts(90,9): error TS2322: Type 'unknown' is not assignable to type '{}'. -tests/cases/conformance/types/unknown/unknownType1.ts(91,9): error TS2322: Type 'unknown' is not assignable to type '{} | null | undefined'. +tests/cases/conformance/types/unknown/unknownType1.ts(45,5): error TS2571: Object is of type 'unknown'. +tests/cases/conformance/types/unknown/unknownType1.ts(46,5): error TS2571: Object is of type 'unknown'. +tests/cases/conformance/types/unknown/unknownType1.ts(47,5): error TS2571: Object is of type 'unknown'. +tests/cases/conformance/types/unknown/unknownType1.ts(48,5): error TS2571: Object is of type 'unknown'. +tests/cases/conformance/types/unknown/unknownType1.ts(49,5): error TS2571: Object is of type 'unknown'. +tests/cases/conformance/types/unknown/unknownType1.ts(50,5): error TS2571: Object is of type 'unknown'. +tests/cases/conformance/types/unknown/unknownType1.ts(51,6): error TS2571: Object is of type 'unknown'. +tests/cases/conformance/types/unknown/unknownType1.ts(52,6): error TS2571: Object is of type 'unknown'. +tests/cases/conformance/types/unknown/unknownType1.ts(58,5): error TS2571: Object is of type 'unknown'. +tests/cases/conformance/types/unknown/unknownType1.ts(59,5): error TS2571: Object is of type 'unknown'. +tests/cases/conformance/types/unknown/unknownType1.ts(60,5): error TS2571: Object is of type 'unknown'. +tests/cases/conformance/types/unknown/unknownType1.ts(61,9): error TS2571: Object is of type 'unknown'. +tests/cases/conformance/types/unknown/unknownType1.ts(105,9): error TS2322: Type 'unknown' is not assignable to type 'object'. +tests/cases/conformance/types/unknown/unknownType1.ts(106,9): error TS2322: Type 'unknown' is not assignable to type 'string'. +tests/cases/conformance/types/unknown/unknownType1.ts(107,9): error TS2322: Type 'unknown' is not assignable to type 'string[]'. +tests/cases/conformance/types/unknown/unknownType1.ts(108,9): error TS2322: Type 'unknown' is not assignable to type '{}'. +tests/cases/conformance/types/unknown/unknownType1.ts(109,9): error TS2322: Type 'unknown' is not assignable to type '{} | null | undefined'. Type 'unknown' is not assignable to type '{}'. -tests/cases/conformance/types/unknown/unknownType1.ts(97,9): error TS2322: Type 'T' is not assignable to type 'object'. -tests/cases/conformance/types/unknown/unknownType1.ts(106,5): error TS2322: Type '123' is not assignable to type '{ [x: string]: unknown; }'. -tests/cases/conformance/types/unknown/unknownType1.ts(132,5): error TS2564: Property 'a' has no initializer and is not definitely assigned in the constructor. +tests/cases/conformance/types/unknown/unknownType1.ts(115,9): error TS2322: Type 'T' is not assignable to type 'object'. +tests/cases/conformance/types/unknown/unknownType1.ts(124,5): error TS2322: Type '123' is not assignable to type '{ [x: string]: unknown; }'. +tests/cases/conformance/types/unknown/unknownType1.ts(150,14): error TS2700: Rest types may only be created from object types. +tests/cases/conformance/types/unknown/unknownType1.ts(156,5): error TS2564: Property 'a' has no initializer and is not definitely assigned in the constructor. -==== tests/cases/conformance/types/unknown/unknownType1.ts (8 errors) ==== +==== tests/cases/conformance/types/unknown/unknownType1.ts (21 errors) ==== // In an intersection everything absorbs unknown type T00 = unknown & null; // null @@ -49,20 +62,62 @@ tests/cases/conformance/types/unknown/unknownType1.ts(132,5): error TS2564: Prop type T40 = keyof any; // string | number | symbol type T41 = keyof unknown; // string | number | symbol + // Only equality operators are allowed with unknown + + function f10(x: unknown) { + x == 5; + x !== 10; + x >= 0; // Error + ~ +!!! error TS2571: Object is of type 'unknown'. + x.foo; // Error + ~ +!!! error TS2571: Object is of type 'unknown'. + x[10]; // Error + ~ +!!! error TS2571: Object is of type 'unknown'. + x(); // Error + ~ +!!! error TS2571: Object is of type 'unknown'. + x + 1; // Error + ~ +!!! error TS2571: Object is of type 'unknown'. + x * 2; // Error + ~ +!!! error TS2571: Object is of type 'unknown'. + -x; // Error + ~ +!!! error TS2571: Object is of type 'unknown'. + +x; // Error + ~ +!!! error TS2571: Object is of type 'unknown'. + } + + // No property accesses, element accesses, or function calls + + function f11(x: unknown) { + x.foo; // Error + ~ +!!! error TS2571: Object is of type 'unknown'. + x[5]; // Error + ~ +!!! error TS2571: Object is of type 'unknown'. + x(); // Error + ~ +!!! error TS2571: Object is of type 'unknown'. + new x(); // Error + ~ +!!! error TS2571: Object is of type 'unknown'. + } + // typeof, instanceof, and user defined type predicates declare function isFunction(x: unknown): x is Function; - function f1(x: unknown) { + function f20(x: unknown) { if (typeof x === "string" || typeof x === "number") { x; // string | number } - if (typeof x === "object") { - x; // object - } - if (typeof x === "function") { - x; // object - } if (x instanceof Error) { x; // Error } @@ -79,7 +134,7 @@ tests/cases/conformance/types/unknown/unknownType1.ts(132,5): error TS2564: Prop // Anything is assignable to unknown - function f2(pAny: any, pNever: never, pT: T) { + function f21(pAny: any, pNever: never, pT: T) { let x: unknown; x = 123; x = "hello"; @@ -93,7 +148,7 @@ tests/cases/conformance/types/unknown/unknownType1.ts(132,5): error TS2564: Prop // unknown assignable only to itself and any - function f3(x: unknown) { + function f22(x: unknown) { let v1: any = x; let v2: unknown = x; let v3: object = x; // Error @@ -116,7 +171,7 @@ tests/cases/conformance/types/unknown/unknownType1.ts(132,5): error TS2564: Prop // Type parameter 'T extends unknown' not related to object - function f4(x: T) { + function f23(x: T) { let y: object = x; // Error ~ !!! error TS2322: Type 'T' is not assignable to type 'object'. @@ -124,7 +179,7 @@ tests/cases/conformance/types/unknown/unknownType1.ts(132,5): error TS2564: Prop // Anything but primitive assignable to { [x: string]: unknown } - function f5(x: { [x: string]: unknown }) { + function f24(x: { [x: string]: unknown }) { x = {}; x = { a: 5 }; x = [1, 2, 3]; @@ -135,14 +190,14 @@ tests/cases/conformance/types/unknown/unknownType1.ts(132,5): error TS2564: Prop // Locals of type unknown always considered initialized - function f6() { + function f25() { let x: unknown; let y = x; } // Spread of unknown causes result to be unknown - function f7(x: {}, y: unknown, z: any) { + function f26(x: {}, y: unknown, z: any) { let o1 = { a: 42, ...x }; // { a: number } let o2 = { a: 42, ...x, ...y }; // unknown let o3 = { a: 42, ...x, ...y, ...z }; // any @@ -150,7 +205,15 @@ tests/cases/conformance/types/unknown/unknownType1.ts(132,5): error TS2564: Prop // Functions with unknown return type don't need return expressions - function f8(): unknown { + function f27(): unknown { + } + + // Rest type cannot be created from unknown + + function f28(x: unknown) { + let { ...a } = x; // Error + ~ +!!! error TS2700: Rest types may only be created from object types. } // Class properties of type unknown don't need definite assignment diff --git a/tests/baselines/reference/unknownType1.js b/tests/baselines/reference/unknownType1.js index b722ef2006b10..2481f0691862e 100644 --- a/tests/baselines/reference/unknownType1.js +++ b/tests/baselines/reference/unknownType1.js @@ -38,20 +38,38 @@ type T33 = T extends never ? true : false; // Deferred type T40 = keyof any; // string | number | symbol type T41 = keyof unknown; // string | number | symbol +// Only equality operators are allowed with unknown + +function f10(x: unknown) { + x == 5; + x !== 10; + x >= 0; // Error + x.foo; // Error + x[10]; // Error + x(); // Error + x + 1; // Error + x * 2; // Error + -x; // Error + +x; // Error +} + +// No property accesses, element accesses, or function calls + +function f11(x: unknown) { + x.foo; // Error + x[5]; // Error + x(); // Error + new x(); // Error +} + // typeof, instanceof, and user defined type predicates declare function isFunction(x: unknown): x is Function; -function f1(x: unknown) { +function f20(x: unknown) { if (typeof x === "string" || typeof x === "number") { x; // string | number } - if (typeof x === "object") { - x; // object - } - if (typeof x === "function") { - x; // object - } if (x instanceof Error) { x; // Error } @@ -68,7 +86,7 @@ type T52 = T50; // { [x: string]: number } // Anything is assignable to unknown -function f2(pAny: any, pNever: never, pT: T) { +function f21(pAny: any, pNever: never, pT: T) { let x: unknown; x = 123; x = "hello"; @@ -82,7 +100,7 @@ function f2(pAny: any, pNever: never, pT: T) { // unknown assignable only to itself and any -function f3(x: unknown) { +function f22(x: unknown) { let v1: any = x; let v2: unknown = x; let v3: object = x; // Error @@ -94,13 +112,13 @@ function f3(x: unknown) { // Type parameter 'T extends unknown' not related to object -function f4(x: T) { +function f23(x: T) { let y: object = x; // Error } // Anything but primitive assignable to { [x: string]: unknown } -function f5(x: { [x: string]: unknown }) { +function f24(x: { [x: string]: unknown }) { x = {}; x = { a: 5 }; x = [1, 2, 3]; @@ -109,14 +127,14 @@ function f5(x: { [x: string]: unknown }) { // Locals of type unknown always considered initialized -function f6() { +function f25() { let x: unknown; let y = x; } // Spread of unknown causes result to be unknown -function f7(x: {}, y: unknown, z: any) { +function f26(x: {}, y: unknown, z: any) { let o1 = { a: 42, ...x }; // { a: number } let o2 = { a: 42, ...x, ...y }; // unknown let o3 = { a: 42, ...x, ...y, ...z }; // any @@ -124,7 +142,13 @@ function f7(x: {}, y: unknown, z: any) { // Functions with unknown return type don't need return expressions -function f8(): unknown { +function f27(): unknown { +} + +// Rest type cannot be created from unknown + +function f28(x: unknown) { + let { ...a } = x; // Error } // Class properties of type unknown don't need definite assignment @@ -147,16 +171,39 @@ var __assign = (this && this.__assign) || Object.assign || function(t) { } return t; }; -function f1(x) { +var __rest = (this && this.__rest) || function (s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0) + t[p[i]] = s[p[i]]; + return t; +}; +// Only equality operators are allowed with unknown +function f10(x) { + x == 5; + x !== 10; + x >= 0; // Error + x.foo; // Error + x[10]; // Error + x(); // Error + x + 1; // Error + x * 2; // Error + -x; // Error + +x; // Error +} +// No property accesses, element accesses, or function calls +function f11(x) { + x.foo; // Error + x[5]; // Error + x(); // Error + new x(); // Error +} +function f20(x) { if (typeof x === "string" || typeof x === "number") { x; // string | number } - if (typeof x === "object") { - x; // object - } - if (typeof x === "function") { - x; // object - } if (x instanceof Error) { x; // Error } @@ -165,7 +212,7 @@ function f1(x) { } } // Anything is assignable to unknown -function f2(pAny, pNever, pT) { +function f21(pAny, pNever, pT) { var x; x = 123; x = "hello"; @@ -177,7 +224,7 @@ function f2(pAny, pNever, pT) { x = pT; } // unknown assignable only to itself and any -function f3(x) { +function f22(x) { var v1 = x; var v2 = x; var v3 = x; // Error @@ -187,29 +234,33 @@ function f3(x) { var v7 = x; // Error } // Type parameter 'T extends unknown' not related to object -function f4(x) { +function f23(x) { var y = x; // Error } // Anything but primitive assignable to { [x: string]: unknown } -function f5(x) { +function f24(x) { x = {}; x = { a: 5 }; x = [1, 2, 3]; x = 123; // Error } // Locals of type unknown always considered initialized -function f6() { +function f25() { var x; var y = x; } // Spread of unknown causes result to be unknown -function f7(x, y, z) { +function f26(x, y, z) { var o1 = __assign({ a: 42 }, x); // { a: number } var o2 = __assign({ a: 42 }, x, y); // unknown var o3 = __assign({ a: 42 }, x, y, z); // any } // Functions with unknown return type don't need return expressions -function f8() { +function f27() { +} +// Rest type cannot be created from unknown +function f28(x) { + var a = __rest(x, []); // Error } // Class properties of type unknown don't need definite assignment var C1 = /** @class */ (function () { diff --git a/tests/baselines/reference/unknownType1.symbols b/tests/baselines/reference/unknownType1.symbols index 007cae242b3ca..5c36e3d662603 100644 --- a/tests/baselines/reference/unknownType1.symbols +++ b/tests/baselines/reference/unknownType1.symbols @@ -97,239 +97,294 @@ type T40 = keyof any; // string | number | symbol type T41 = keyof unknown; // string | number | symbol >T41 : Symbol(T41, Decl(unknownType1.ts, 36, 21)) +// Only equality operators are allowed with unknown + +function f10(x: unknown) { +>f10 : Symbol(f10, Decl(unknownType1.ts, 37, 25)) +>x : Symbol(x, Decl(unknownType1.ts, 41, 13)) + + x == 5; +>x : Symbol(x, Decl(unknownType1.ts, 41, 13)) + + x !== 10; +>x : Symbol(x, Decl(unknownType1.ts, 41, 13)) + + x >= 0; // Error +>x : Symbol(x, Decl(unknownType1.ts, 41, 13)) + + x.foo; // Error +>x : Symbol(x, Decl(unknownType1.ts, 41, 13)) + + x[10]; // Error +>x : Symbol(x, Decl(unknownType1.ts, 41, 13)) + + x(); // Error +>x : Symbol(x, Decl(unknownType1.ts, 41, 13)) + + x + 1; // Error +>x : Symbol(x, Decl(unknownType1.ts, 41, 13)) + + x * 2; // Error +>x : Symbol(x, Decl(unknownType1.ts, 41, 13)) + + -x; // Error +>x : Symbol(x, Decl(unknownType1.ts, 41, 13)) + + +x; // Error +>x : Symbol(x, Decl(unknownType1.ts, 41, 13)) +} + +// No property accesses, element accesses, or function calls + +function f11(x: unknown) { +>f11 : Symbol(f11, Decl(unknownType1.ts, 52, 1)) +>x : Symbol(x, Decl(unknownType1.ts, 56, 13)) + + x.foo; // Error +>x : Symbol(x, Decl(unknownType1.ts, 56, 13)) + + x[5]; // Error +>x : Symbol(x, Decl(unknownType1.ts, 56, 13)) + + x(); // Error +>x : Symbol(x, Decl(unknownType1.ts, 56, 13)) + + new x(); // Error +>x : Symbol(x, Decl(unknownType1.ts, 56, 13)) +} + // typeof, instanceof, and user defined type predicates declare function isFunction(x: unknown): x is Function; ->isFunction : Symbol(isFunction, Decl(unknownType1.ts, 37, 25)) ->x : Symbol(x, Decl(unknownType1.ts, 41, 28)) ->x : Symbol(x, Decl(unknownType1.ts, 41, 28)) +>isFunction : Symbol(isFunction, Decl(unknownType1.ts, 61, 1)) +>x : Symbol(x, Decl(unknownType1.ts, 65, 28)) +>x : Symbol(x, Decl(unknownType1.ts, 65, 28)) >Function : Symbol(Function, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) -function f1(x: unknown) { ->f1 : Symbol(f1, Decl(unknownType1.ts, 41, 55)) ->x : Symbol(x, Decl(unknownType1.ts, 43, 12)) +function f20(x: unknown) { +>f20 : Symbol(f20, Decl(unknownType1.ts, 65, 55)) +>x : Symbol(x, Decl(unknownType1.ts, 67, 13)) if (typeof x === "string" || typeof x === "number") { ->x : Symbol(x, Decl(unknownType1.ts, 43, 12)) ->x : Symbol(x, Decl(unknownType1.ts, 43, 12)) +>x : Symbol(x, Decl(unknownType1.ts, 67, 13)) +>x : Symbol(x, Decl(unknownType1.ts, 67, 13)) x; // string | number ->x : Symbol(x, Decl(unknownType1.ts, 43, 12)) - } - if (typeof x === "object") { ->x : Symbol(x, Decl(unknownType1.ts, 43, 12)) - - x; // object ->x : Symbol(x, Decl(unknownType1.ts, 43, 12)) - } - if (typeof x === "function") { ->x : Symbol(x, Decl(unknownType1.ts, 43, 12)) - - x; // object ->x : Symbol(x, Decl(unknownType1.ts, 43, 12)) +>x : Symbol(x, Decl(unknownType1.ts, 67, 13)) } if (x instanceof Error) { ->x : Symbol(x, Decl(unknownType1.ts, 43, 12)) +>x : Symbol(x, Decl(unknownType1.ts, 67, 13)) >Error : Symbol(Error, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) x; // Error ->x : Symbol(x, Decl(unknownType1.ts, 43, 12)) +>x : Symbol(x, Decl(unknownType1.ts, 67, 13)) } if (isFunction(x)) { ->isFunction : Symbol(isFunction, Decl(unknownType1.ts, 37, 25)) ->x : Symbol(x, Decl(unknownType1.ts, 43, 12)) +>isFunction : Symbol(isFunction, Decl(unknownType1.ts, 61, 1)) +>x : Symbol(x, Decl(unknownType1.ts, 67, 13)) x; // Function ->x : Symbol(x, Decl(unknownType1.ts, 43, 12)) +>x : Symbol(x, Decl(unknownType1.ts, 67, 13)) } } // Homomorphic mapped type over unknown type T50 = { [P in keyof T]: number }; ->T50 : Symbol(T50, Decl(unknownType1.ts, 59, 1)) ->T : Symbol(T, Decl(unknownType1.ts, 63, 9)) ->P : Symbol(P, Decl(unknownType1.ts, 63, 17)) ->T : Symbol(T, Decl(unknownType1.ts, 63, 9)) +>T50 : Symbol(T50, Decl(unknownType1.ts, 77, 1)) +>T : Symbol(T, Decl(unknownType1.ts, 81, 9)) +>P : Symbol(P, Decl(unknownType1.ts, 81, 17)) +>T : Symbol(T, Decl(unknownType1.ts, 81, 9)) type T51 = T50; // { [x: string]: number } ->T51 : Symbol(T51, Decl(unknownType1.ts, 63, 41)) ->T50 : Symbol(T50, Decl(unknownType1.ts, 59, 1)) +>T51 : Symbol(T51, Decl(unknownType1.ts, 81, 41)) +>T50 : Symbol(T50, Decl(unknownType1.ts, 77, 1)) type T52 = T50; // { [x: string]: number } ->T52 : Symbol(T52, Decl(unknownType1.ts, 64, 24)) ->T50 : Symbol(T50, Decl(unknownType1.ts, 59, 1)) +>T52 : Symbol(T52, Decl(unknownType1.ts, 82, 24)) +>T50 : Symbol(T50, Decl(unknownType1.ts, 77, 1)) // Anything is assignable to unknown -function f2(pAny: any, pNever: never, pT: T) { ->f2 : Symbol(f2, Decl(unknownType1.ts, 65, 20)) ->T : Symbol(T, Decl(unknownType1.ts, 69, 12)) ->pAny : Symbol(pAny, Decl(unknownType1.ts, 69, 15)) ->pNever : Symbol(pNever, Decl(unknownType1.ts, 69, 25)) ->pT : Symbol(pT, Decl(unknownType1.ts, 69, 40)) ->T : Symbol(T, Decl(unknownType1.ts, 69, 12)) +function f21(pAny: any, pNever: never, pT: T) { +>f21 : Symbol(f21, Decl(unknownType1.ts, 83, 20)) +>T : Symbol(T, Decl(unknownType1.ts, 87, 13)) +>pAny : Symbol(pAny, Decl(unknownType1.ts, 87, 16)) +>pNever : Symbol(pNever, Decl(unknownType1.ts, 87, 26)) +>pT : Symbol(pT, Decl(unknownType1.ts, 87, 41)) +>T : Symbol(T, Decl(unknownType1.ts, 87, 13)) let x: unknown; ->x : Symbol(x, Decl(unknownType1.ts, 70, 7)) +>x : Symbol(x, Decl(unknownType1.ts, 88, 7)) x = 123; ->x : Symbol(x, Decl(unknownType1.ts, 70, 7)) +>x : Symbol(x, Decl(unknownType1.ts, 88, 7)) x = "hello"; ->x : Symbol(x, Decl(unknownType1.ts, 70, 7)) +>x : Symbol(x, Decl(unknownType1.ts, 88, 7)) x = [1, 2, 3]; ->x : Symbol(x, Decl(unknownType1.ts, 70, 7)) +>x : Symbol(x, Decl(unknownType1.ts, 88, 7)) x = new Error(); ->x : Symbol(x, Decl(unknownType1.ts, 70, 7)) +>x : Symbol(x, Decl(unknownType1.ts, 88, 7)) >Error : Symbol(Error, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) x = x; ->x : Symbol(x, Decl(unknownType1.ts, 70, 7)) ->x : Symbol(x, Decl(unknownType1.ts, 70, 7)) +>x : Symbol(x, Decl(unknownType1.ts, 88, 7)) +>x : Symbol(x, Decl(unknownType1.ts, 88, 7)) x = pAny; ->x : Symbol(x, Decl(unknownType1.ts, 70, 7)) ->pAny : Symbol(pAny, Decl(unknownType1.ts, 69, 15)) +>x : Symbol(x, Decl(unknownType1.ts, 88, 7)) +>pAny : Symbol(pAny, Decl(unknownType1.ts, 87, 16)) x = pNever; ->x : Symbol(x, Decl(unknownType1.ts, 70, 7)) ->pNever : Symbol(pNever, Decl(unknownType1.ts, 69, 25)) +>x : Symbol(x, Decl(unknownType1.ts, 88, 7)) +>pNever : Symbol(pNever, Decl(unknownType1.ts, 87, 26)) x = pT; ->x : Symbol(x, Decl(unknownType1.ts, 70, 7)) ->pT : Symbol(pT, Decl(unknownType1.ts, 69, 40)) +>x : Symbol(x, Decl(unknownType1.ts, 88, 7)) +>pT : Symbol(pT, Decl(unknownType1.ts, 87, 41)) } // unknown assignable only to itself and any -function f3(x: unknown) { ->f3 : Symbol(f3, Decl(unknownType1.ts, 79, 1)) ->x : Symbol(x, Decl(unknownType1.ts, 83, 12)) +function f22(x: unknown) { +>f22 : Symbol(f22, Decl(unknownType1.ts, 97, 1)) +>x : Symbol(x, Decl(unknownType1.ts, 101, 13)) let v1: any = x; ->v1 : Symbol(v1, Decl(unknownType1.ts, 84, 7)) ->x : Symbol(x, Decl(unknownType1.ts, 83, 12)) +>v1 : Symbol(v1, Decl(unknownType1.ts, 102, 7)) +>x : Symbol(x, Decl(unknownType1.ts, 101, 13)) let v2: unknown = x; ->v2 : Symbol(v2, Decl(unknownType1.ts, 85, 7)) ->x : Symbol(x, Decl(unknownType1.ts, 83, 12)) +>v2 : Symbol(v2, Decl(unknownType1.ts, 103, 7)) +>x : Symbol(x, Decl(unknownType1.ts, 101, 13)) let v3: object = x; // Error ->v3 : Symbol(v3, Decl(unknownType1.ts, 86, 7)) ->x : Symbol(x, Decl(unknownType1.ts, 83, 12)) +>v3 : Symbol(v3, Decl(unknownType1.ts, 104, 7)) +>x : Symbol(x, Decl(unknownType1.ts, 101, 13)) let v4: string = x; // Error ->v4 : Symbol(v4, Decl(unknownType1.ts, 87, 7)) ->x : Symbol(x, Decl(unknownType1.ts, 83, 12)) +>v4 : Symbol(v4, Decl(unknownType1.ts, 105, 7)) +>x : Symbol(x, Decl(unknownType1.ts, 101, 13)) let v5: string[] = x; // Error ->v5 : Symbol(v5, Decl(unknownType1.ts, 88, 7)) ->x : Symbol(x, Decl(unknownType1.ts, 83, 12)) +>v5 : Symbol(v5, Decl(unknownType1.ts, 106, 7)) +>x : Symbol(x, Decl(unknownType1.ts, 101, 13)) let v6: {} = x; // Error ->v6 : Symbol(v6, Decl(unknownType1.ts, 89, 7)) ->x : Symbol(x, Decl(unknownType1.ts, 83, 12)) +>v6 : Symbol(v6, Decl(unknownType1.ts, 107, 7)) +>x : Symbol(x, Decl(unknownType1.ts, 101, 13)) let v7: {} | null | undefined = x; // Error ->v7 : Symbol(v7, Decl(unknownType1.ts, 90, 7)) ->x : Symbol(x, Decl(unknownType1.ts, 83, 12)) +>v7 : Symbol(v7, Decl(unknownType1.ts, 108, 7)) +>x : Symbol(x, Decl(unknownType1.ts, 101, 13)) } // Type parameter 'T extends unknown' not related to object -function f4(x: T) { ->f4 : Symbol(f4, Decl(unknownType1.ts, 91, 1)) ->T : Symbol(T, Decl(unknownType1.ts, 95, 12)) ->x : Symbol(x, Decl(unknownType1.ts, 95, 31)) ->T : Symbol(T, Decl(unknownType1.ts, 95, 12)) +function f23(x: T) { +>f23 : Symbol(f23, Decl(unknownType1.ts, 109, 1)) +>T : Symbol(T, Decl(unknownType1.ts, 113, 13)) +>x : Symbol(x, Decl(unknownType1.ts, 113, 32)) +>T : Symbol(T, Decl(unknownType1.ts, 113, 13)) let y: object = x; // Error ->y : Symbol(y, Decl(unknownType1.ts, 96, 7)) ->x : Symbol(x, Decl(unknownType1.ts, 95, 31)) +>y : Symbol(y, Decl(unknownType1.ts, 114, 7)) +>x : Symbol(x, Decl(unknownType1.ts, 113, 32)) } // Anything but primitive assignable to { [x: string]: unknown } -function f5(x: { [x: string]: unknown }) { ->f5 : Symbol(f5, Decl(unknownType1.ts, 97, 1)) ->x : Symbol(x, Decl(unknownType1.ts, 101, 12)) ->x : Symbol(x, Decl(unknownType1.ts, 101, 18)) +function f24(x: { [x: string]: unknown }) { +>f24 : Symbol(f24, Decl(unknownType1.ts, 115, 1)) +>x : Symbol(x, Decl(unknownType1.ts, 119, 13)) +>x : Symbol(x, Decl(unknownType1.ts, 119, 19)) x = {}; ->x : Symbol(x, Decl(unknownType1.ts, 101, 12)) +>x : Symbol(x, Decl(unknownType1.ts, 119, 13)) x = { a: 5 }; ->x : Symbol(x, Decl(unknownType1.ts, 101, 12)) ->a : Symbol(a, Decl(unknownType1.ts, 103, 9)) +>x : Symbol(x, Decl(unknownType1.ts, 119, 13)) +>a : Symbol(a, Decl(unknownType1.ts, 121, 9)) x = [1, 2, 3]; ->x : Symbol(x, Decl(unknownType1.ts, 101, 12)) +>x : Symbol(x, Decl(unknownType1.ts, 119, 13)) x = 123; // Error ->x : Symbol(x, Decl(unknownType1.ts, 101, 12)) +>x : Symbol(x, Decl(unknownType1.ts, 119, 13)) } // Locals of type unknown always considered initialized -function f6() { ->f6 : Symbol(f6, Decl(unknownType1.ts, 106, 1)) +function f25() { +>f25 : Symbol(f25, Decl(unknownType1.ts, 124, 1)) let x: unknown; ->x : Symbol(x, Decl(unknownType1.ts, 111, 7)) +>x : Symbol(x, Decl(unknownType1.ts, 129, 7)) let y = x; ->y : Symbol(y, Decl(unknownType1.ts, 112, 7)) ->x : Symbol(x, Decl(unknownType1.ts, 111, 7)) +>y : Symbol(y, Decl(unknownType1.ts, 130, 7)) +>x : Symbol(x, Decl(unknownType1.ts, 129, 7)) } // Spread of unknown causes result to be unknown -function f7(x: {}, y: unknown, z: any) { ->f7 : Symbol(f7, Decl(unknownType1.ts, 113, 1)) ->x : Symbol(x, Decl(unknownType1.ts, 117, 12)) ->y : Symbol(y, Decl(unknownType1.ts, 117, 18)) ->z : Symbol(z, Decl(unknownType1.ts, 117, 30)) +function f26(x: {}, y: unknown, z: any) { +>f26 : Symbol(f26, Decl(unknownType1.ts, 131, 1)) +>x : Symbol(x, Decl(unknownType1.ts, 135, 13)) +>y : Symbol(y, Decl(unknownType1.ts, 135, 19)) +>z : Symbol(z, Decl(unknownType1.ts, 135, 31)) let o1 = { a: 42, ...x }; // { a: number } ->o1 : Symbol(o1, Decl(unknownType1.ts, 118, 7)) ->a : Symbol(a, Decl(unknownType1.ts, 118, 14)) ->x : Symbol(x, Decl(unknownType1.ts, 117, 12)) +>o1 : Symbol(o1, Decl(unknownType1.ts, 136, 7)) +>a : Symbol(a, Decl(unknownType1.ts, 136, 14)) +>x : Symbol(x, Decl(unknownType1.ts, 135, 13)) let o2 = { a: 42, ...x, ...y }; // unknown ->o2 : Symbol(o2, Decl(unknownType1.ts, 119, 7)) ->a : Symbol(a, Decl(unknownType1.ts, 119, 14)) ->x : Symbol(x, Decl(unknownType1.ts, 117, 12)) ->y : Symbol(y, Decl(unknownType1.ts, 117, 18)) +>o2 : Symbol(o2, Decl(unknownType1.ts, 137, 7)) +>a : Symbol(a, Decl(unknownType1.ts, 137, 14)) +>x : Symbol(x, Decl(unknownType1.ts, 135, 13)) +>y : Symbol(y, Decl(unknownType1.ts, 135, 19)) let o3 = { a: 42, ...x, ...y, ...z }; // any ->o3 : Symbol(o3, Decl(unknownType1.ts, 120, 7)) ->a : Symbol(a, Decl(unknownType1.ts, 120, 14)) ->x : Symbol(x, Decl(unknownType1.ts, 117, 12)) ->y : Symbol(y, Decl(unknownType1.ts, 117, 18)) ->z : Symbol(z, Decl(unknownType1.ts, 117, 30)) +>o3 : Symbol(o3, Decl(unknownType1.ts, 138, 7)) +>a : Symbol(a, Decl(unknownType1.ts, 138, 14)) +>x : Symbol(x, Decl(unknownType1.ts, 135, 13)) +>y : Symbol(y, Decl(unknownType1.ts, 135, 19)) +>z : Symbol(z, Decl(unknownType1.ts, 135, 31)) } // Functions with unknown return type don't need return expressions -function f8(): unknown { ->f8 : Symbol(f8, Decl(unknownType1.ts, 121, 1)) +function f27(): unknown { +>f27 : Symbol(f27, Decl(unknownType1.ts, 139, 1)) +} + +// Rest type cannot be created from unknown + +function f28(x: unknown) { +>f28 : Symbol(f28, Decl(unknownType1.ts, 144, 1)) +>x : Symbol(x, Decl(unknownType1.ts, 148, 13)) + + let { ...a } = x; // Error +>a : Symbol(a, Decl(unknownType1.ts, 149, 9)) +>x : Symbol(x, Decl(unknownType1.ts, 148, 13)) } // Class properties of type unknown don't need definite assignment class C1 { ->C1 : Symbol(C1, Decl(unknownType1.ts, 126, 1)) +>C1 : Symbol(C1, Decl(unknownType1.ts, 150, 1)) a: string; // Error ->a : Symbol(C1.a, Decl(unknownType1.ts, 130, 10)) +>a : Symbol(C1.a, Decl(unknownType1.ts, 154, 10)) b: unknown; ->b : Symbol(C1.b, Decl(unknownType1.ts, 131, 14)) +>b : Symbol(C1.b, Decl(unknownType1.ts, 155, 14)) c: any; ->c : Symbol(C1.c, Decl(unknownType1.ts, 132, 15)) +>c : Symbol(C1.c, Decl(unknownType1.ts, 156, 15)) } diff --git a/tests/baselines/reference/unknownType1.types b/tests/baselines/reference/unknownType1.types index f92ff19867c4a..a922e8f43bd2a 100644 --- a/tests/baselines/reference/unknownType1.types +++ b/tests/baselines/reference/unknownType1.types @@ -109,6 +109,85 @@ type T40 = keyof any; // string | number | symbol type T41 = keyof unknown; // string | number | symbol >T41 : string | number | symbol +// Only equality operators are allowed with unknown + +function f10(x: unknown) { +>f10 : (x: unknown) => void +>x : unknown + + x == 5; +>x == 5 : boolean +>x : unknown +>5 : 5 + + x !== 10; +>x !== 10 : boolean +>x : unknown +>10 : 10 + + x >= 0; // Error +>x >= 0 : boolean +>x : unknown +>0 : 0 + + x.foo; // Error +>x.foo : any +>x : unknown +>foo : any + + x[10]; // Error +>x[10] : any +>x : unknown +>10 : 10 + + x(); // Error +>x() : any +>x : unknown + + x + 1; // Error +>x + 1 : any +>x : unknown +>1 : 1 + + x * 2; // Error +>x * 2 : number +>x : unknown +>2 : 2 + + -x; // Error +>-x : number +>x : unknown + + +x; // Error +>+x : number +>x : unknown +} + +// No property accesses, element accesses, or function calls + +function f11(x: unknown) { +>f11 : (x: unknown) => void +>x : unknown + + x.foo; // Error +>x.foo : any +>x : unknown +>foo : any + + x[5]; // Error +>x[5] : any +>x : unknown +>5 : 5 + + x(); // Error +>x() : any +>x : unknown + + new x(); // Error +>new x() : any +>x : unknown +} + // typeof, instanceof, and user defined type predicates declare function isFunction(x: unknown): x is Function; @@ -117,8 +196,8 @@ declare function isFunction(x: unknown): x is Function; >x : any >Function : Function -function f1(x: unknown) { ->f1 : (x: unknown) => void +function f20(x: unknown) { +>f20 : (x: unknown) => void >x : unknown if (typeof x === "string" || typeof x === "number") { @@ -134,24 +213,6 @@ function f1(x: unknown) { x; // string | number >x : string | number - } - if (typeof x === "object") { ->typeof x === "object" : boolean ->typeof x : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function" ->x : unknown ->"object" : "object" - - x; // object ->x : object - } - if (typeof x === "function") { ->typeof x === "function" : boolean ->typeof x : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function" ->x : unknown ->"function" : "function" - - x; // object ->x : object } if (x instanceof Error) { >x instanceof Error : boolean @@ -189,8 +250,8 @@ type T52 = T50; // { [x: string]: number } // Anything is assignable to unknown -function f2(pAny: any, pNever: never, pT: T) { ->f2 : (pAny: any, pNever: never, pT: T) => void +function f21(pAny: any, pNever: never, pT: T) { +>f21 : (pAny: any, pNever: never, pT: T) => void >T : T >pAny : any >pNever : never @@ -247,8 +308,8 @@ function f2(pAny: any, pNever: never, pT: T) { // unknown assignable only to itself and any -function f3(x: unknown) { ->f3 : (x: unknown) => void +function f22(x: unknown) { +>f22 : (x: unknown) => void >x : unknown let v1: any = x; @@ -283,8 +344,8 @@ function f3(x: unknown) { // Type parameter 'T extends unknown' not related to object -function f4(x: T) { ->f4 : (x: T) => void +function f23(x: T) { +>f23 : (x: T) => void >T : T >x : T >T : T @@ -296,8 +357,8 @@ function f4(x: T) { // Anything but primitive assignable to { [x: string]: unknown } -function f5(x: { [x: string]: unknown }) { ->f5 : (x: { [x: string]: unknown; }) => void +function f24(x: { [x: string]: unknown }) { +>f24 : (x: { [x: string]: unknown; }) => void >x : { [x: string]: unknown; } >x : string @@ -329,8 +390,8 @@ function f5(x: { [x: string]: unknown }) { // Locals of type unknown always considered initialized -function f6() { ->f6 : () => void +function f25() { +>f25 : () => void let x: unknown; >x : unknown @@ -342,8 +403,8 @@ function f6() { // Spread of unknown causes result to be unknown -function f7(x: {}, y: unknown, z: any) { ->f7 : (x: {}, y: unknown, z: any) => void +function f26(x: {}, y: unknown, z: any) { +>f26 : (x: {}, y: unknown, z: any) => void >x : {} >y : unknown >z : any @@ -375,8 +436,19 @@ function f7(x: {}, y: unknown, z: any) { // Functions with unknown return type don't need return expressions -function f8(): unknown { ->f8 : () => unknown +function f27(): unknown { +>f27 : () => unknown +} + +// Rest type cannot be created from unknown + +function f28(x: unknown) { +>f28 : (x: unknown) => void +>x : unknown + + let { ...a } = x; // Error +>a : any +>x : unknown } // Class properties of type unknown don't need definite assignment From 074961f303128271581e7d0a633a85d4651e6646 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 29 May 2018 12:54:00 -0700 Subject: [PATCH 18/24] keyof unknown should be never --- src/compiler/checker.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 5a75bd47dfc10..f562bd629987d 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -6429,7 +6429,7 @@ namespace ts { for (const prop of getPropertiesOfType(modifiersType)) { addMemberForKeyType(getLiteralTypeFromPropertyName(prop, include), /*_index*/ undefined, prop); } - if (modifiersType.flags & TypeFlags.AnyOrUnknown || getIndexInfoOfType(modifiersType, IndexKind.String)) { + if (modifiersType.flags & TypeFlags.Any || getIndexInfoOfType(modifiersType, IndexKind.String)) { addMemberForKeyType(stringType); } if (!keyofStringsOnly && getIndexInfoOfType(modifiersType, IndexKind.Number)) { @@ -8690,7 +8690,7 @@ namespace ts { maybeTypeOfKind(type, TypeFlags.InstantiableNonPrimitive) ? getIndexTypeForGenericType(type, stringsOnly) : getObjectFlags(type) & ObjectFlags.Mapped ? getConstraintTypeFromMappedType(type) : type === wildcardType ? wildcardType : - type.flags & TypeFlags.AnyOrUnknown ? keyofConstraintType : + type.flags & TypeFlags.Any ? keyofConstraintType : stringsOnly ? getIndexInfoOfType(type, IndexKind.String) ? stringType : getLiteralTypeFromPropertyNames(type, TypeFlags.StringLiteral) : getIndexInfoOfType(type, IndexKind.String) ? getUnionType([stringType, numberType, getLiteralTypeFromPropertyNames(type, TypeFlags.UniqueESSymbol)]) : getNonEnumNumberIndexInfo(type) ? getUnionType([numberType, getLiteralTypeFromPropertyNames(type, TypeFlags.StringLiteral | TypeFlags.UniqueESSymbol)]) : From c694ffe7a588008c6400b607ed8d5877acbcc1f7 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 29 May 2018 12:54:12 -0700 Subject: [PATCH 19/24] Update tests --- tests/cases/conformance/types/unknown/unknownType1.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/cases/conformance/types/unknown/unknownType1.ts b/tests/cases/conformance/types/unknown/unknownType1.ts index dfd1c18693eed..b7a9e71723114 100644 --- a/tests/cases/conformance/types/unknown/unknownType1.ts +++ b/tests/cases/conformance/types/unknown/unknownType1.ts @@ -37,7 +37,7 @@ type T33 = T extends never ? true : false; // Deferred // keyof unknown type T40 = keyof any; // string | number | symbol -type T41 = keyof unknown; // string | number | symbol +type T41 = keyof unknown; // never // Only equality operators are allowed with unknown @@ -82,8 +82,8 @@ function f20(x: unknown) { // Homomorphic mapped type over unknown type T50 = { [P in keyof T]: number }; -type T51 = T50; // { [x: string]: number } -type T52 = T50; // { [x: string]: number } +type T51 = T50; // { [x: string]: number } +type T52 = T50; // {} // Anything is assignable to unknown From e98f9a699f1191a452a164d2a27c9a427413763e Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 29 May 2018 12:54:18 -0700 Subject: [PATCH 20/24] Accept new baselines --- tests/baselines/reference/unknownType1.errors.txt | 6 +++--- tests/baselines/reference/unknownType1.js | 6 +++--- tests/baselines/reference/unknownType1.symbols | 10 +++++----- tests/baselines/reference/unknownType1.types | 12 ++++++------ 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/tests/baselines/reference/unknownType1.errors.txt b/tests/baselines/reference/unknownType1.errors.txt index 26030e138319b..afaf35b4d07ed 100644 --- a/tests/baselines/reference/unknownType1.errors.txt +++ b/tests/baselines/reference/unknownType1.errors.txt @@ -60,7 +60,7 @@ tests/cases/conformance/types/unknown/unknownType1.ts(156,5): error TS2564: Prop // keyof unknown type T40 = keyof any; // string | number | symbol - type T41 = keyof unknown; // string | number | symbol + type T41 = keyof unknown; // never // Only equality operators are allowed with unknown @@ -129,8 +129,8 @@ tests/cases/conformance/types/unknown/unknownType1.ts(156,5): error TS2564: Prop // Homomorphic mapped type over unknown type T50 = { [P in keyof T]: number }; - type T51 = T50; // { [x: string]: number } - type T52 = T50; // { [x: string]: number } + type T51 = T50; // { [x: string]: number } + type T52 = T50; // {} // Anything is assignable to unknown diff --git a/tests/baselines/reference/unknownType1.js b/tests/baselines/reference/unknownType1.js index 2481f0691862e..76224ef18ca2b 100644 --- a/tests/baselines/reference/unknownType1.js +++ b/tests/baselines/reference/unknownType1.js @@ -36,7 +36,7 @@ type T33 = T extends never ? true : false; // Deferred // keyof unknown type T40 = keyof any; // string | number | symbol -type T41 = keyof unknown; // string | number | symbol +type T41 = keyof unknown; // never // Only equality operators are allowed with unknown @@ -81,8 +81,8 @@ function f20(x: unknown) { // Homomorphic mapped type over unknown type T50 = { [P in keyof T]: number }; -type T51 = T50; // { [x: string]: number } -type T52 = T50; // { [x: string]: number } +type T51 = T50; // { [x: string]: number } +type T52 = T50; // {} // Anything is assignable to unknown diff --git a/tests/baselines/reference/unknownType1.symbols b/tests/baselines/reference/unknownType1.symbols index 5c36e3d662603..8067312f72834 100644 --- a/tests/baselines/reference/unknownType1.symbols +++ b/tests/baselines/reference/unknownType1.symbols @@ -94,7 +94,7 @@ type T33 = T extends never ? true : false; // Deferred type T40 = keyof any; // string | number | symbol >T40 : Symbol(T40, Decl(unknownType1.ts, 32, 45)) -type T41 = keyof unknown; // string | number | symbol +type T41 = keyof unknown; // never >T41 : Symbol(T41, Decl(unknownType1.ts, 36, 21)) // Only equality operators are allowed with unknown @@ -196,18 +196,18 @@ type T50 = { [P in keyof T]: number }; >P : Symbol(P, Decl(unknownType1.ts, 81, 17)) >T : Symbol(T, Decl(unknownType1.ts, 81, 9)) -type T51 = T50; // { [x: string]: number } +type T51 = T50; // { [x: string]: number } >T51 : Symbol(T51, Decl(unknownType1.ts, 81, 41)) >T50 : Symbol(T50, Decl(unknownType1.ts, 77, 1)) -type T52 = T50; // { [x: string]: number } ->T52 : Symbol(T52, Decl(unknownType1.ts, 82, 24)) +type T52 = T50; // {} +>T52 : Symbol(T52, Decl(unknownType1.ts, 82, 20)) >T50 : Symbol(T50, Decl(unknownType1.ts, 77, 1)) // Anything is assignable to unknown function f21(pAny: any, pNever: never, pT: T) { ->f21 : Symbol(f21, Decl(unknownType1.ts, 83, 20)) +>f21 : Symbol(f21, Decl(unknownType1.ts, 83, 24)) >T : Symbol(T, Decl(unknownType1.ts, 87, 13)) >pAny : Symbol(pAny, Decl(unknownType1.ts, 87, 16)) >pNever : Symbol(pNever, Decl(unknownType1.ts, 87, 26)) diff --git a/tests/baselines/reference/unknownType1.types b/tests/baselines/reference/unknownType1.types index a922e8f43bd2a..dec3acaaebcd7 100644 --- a/tests/baselines/reference/unknownType1.types +++ b/tests/baselines/reference/unknownType1.types @@ -106,8 +106,8 @@ type T33 = T extends never ? true : false; // Deferred type T40 = keyof any; // string | number | symbol >T40 : string | number | symbol -type T41 = keyof unknown; // string | number | symbol ->T41 : string | number | symbol +type T41 = keyof unknown; // never +>T41 : never // Only equality operators are allowed with unknown @@ -240,12 +240,12 @@ type T50 = { [P in keyof T]: number }; >P : P >T : T -type T51 = T50; // { [x: string]: number } ->T51 : T50 +type T51 = T50; // { [x: string]: number } +>T51 : T50 >T50 : T50 -type T52 = T50; // { [x: string]: number } ->T52 : T50 +type T52 = T50; // {} +>T52 : T50 >T50 : T50 // Anything is assignable to unknown From 6b1c84e84a51031034d7db12f35f809a054abe32 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 29 May 2018 17:55:31 -0700 Subject: [PATCH 21/24] Remove eager resolution of distributive conditional types --- src/compiler/checker.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index f562bd629987d..712eb182e914d 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -8969,9 +8969,6 @@ namespace ts { if (checkType === wildcardType || extendsType === wildcardType) { return wildcardType; } - if (extendsType.flags & TypeFlags.AnyOrUnknown) { - return instantiateType(root.trueType, mapper); - } // If this is a distributive conditional type and the check type is generic we need to defer // resolution of the conditional type such that a later instantiation will properly distribute // over union types. @@ -8988,6 +8985,9 @@ namespace ts { combinedMapper = combineTypeMappers(mapper, context); } if (!isDeferred) { + if (extendsType.flags & TypeFlags.AnyOrUnknown) { + return instantiateType(root.trueType, mapper); + } // Return union of trueType and falseType for 'any' since it matches anything if (checkType.flags & TypeFlags.Any) { return getUnionType([instantiateType(root.trueType, combinedMapper || mapper), instantiateType(root.falseType, mapper)]); From 577662de428f7574a671fdef48e9675fc9123578 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 29 May 2018 17:55:57 -0700 Subject: [PATCH 22/24] Update tests --- tests/cases/conformance/types/unknown/unknownType1.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/cases/conformance/types/unknown/unknownType1.ts b/tests/cases/conformance/types/unknown/unknownType1.ts index b7a9e71723114..3307f5c44810f 100644 --- a/tests/cases/conformance/types/unknown/unknownType1.ts +++ b/tests/cases/conformance/types/unknown/unknownType1.ts @@ -30,10 +30,15 @@ type T23 = T | unknown; // unknown // unknown in conditional types type T30 = unknown extends T ? true : false; // Deferred -type T31 = T extends unknown ? true : false; // true +type T31 = T extends unknown ? true : false; // Deferred (so it distributes) type T32 = never extends T ? true : false; // true type T33 = T extends never ? true : false; // Deferred +type T35 = T extends unknown ? { x: T } : false; +type T36 = T35; // { x: string } | { x: number } +type T37 = T35; // { x: any } +type T38 = T35; // { x: unknown } + // keyof unknown type T40 = keyof any; // string | number | symbol From 41ef7a7e8861f51d8e0c21cee56b6586ee5cf804 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 29 May 2018 17:56:05 -0700 Subject: [PATCH 23/24] Accept new baselines --- .../reference/conditionalTypes2.types | 2 +- .../reference/unknownType1.errors.txt | 47 ++-- tests/baselines/reference/unknownType1.js | 7 +- .../baselines/reference/unknownType1.symbols | 259 ++++++++++-------- tests/baselines/reference/unknownType1.types | 24 +- 5 files changed, 194 insertions(+), 145 deletions(-) diff --git a/tests/baselines/reference/conditionalTypes2.types b/tests/baselines/reference/conditionalTypes2.types index 451529d19f251..906bc7e27df28 100644 --- a/tests/baselines/reference/conditionalTypes2.types +++ b/tests/baselines/reference/conditionalTypes2.types @@ -403,7 +403,7 @@ interface B1 extends A1 { >T : T boom: T extends any ? true : true ->boom : true +>boom : T extends any ? true : true >T : T >true : true >true : true diff --git a/tests/baselines/reference/unknownType1.errors.txt b/tests/baselines/reference/unknownType1.errors.txt index afaf35b4d07ed..37d0cd010e7a0 100644 --- a/tests/baselines/reference/unknownType1.errors.txt +++ b/tests/baselines/reference/unknownType1.errors.txt @@ -1,25 +1,25 @@ -tests/cases/conformance/types/unknown/unknownType1.ts(45,5): error TS2571: Object is of type 'unknown'. -tests/cases/conformance/types/unknown/unknownType1.ts(46,5): error TS2571: Object is of type 'unknown'. -tests/cases/conformance/types/unknown/unknownType1.ts(47,5): error TS2571: Object is of type 'unknown'. -tests/cases/conformance/types/unknown/unknownType1.ts(48,5): error TS2571: Object is of type 'unknown'. -tests/cases/conformance/types/unknown/unknownType1.ts(49,5): error TS2571: Object is of type 'unknown'. tests/cases/conformance/types/unknown/unknownType1.ts(50,5): error TS2571: Object is of type 'unknown'. -tests/cases/conformance/types/unknown/unknownType1.ts(51,6): error TS2571: Object is of type 'unknown'. -tests/cases/conformance/types/unknown/unknownType1.ts(52,6): error TS2571: Object is of type 'unknown'. -tests/cases/conformance/types/unknown/unknownType1.ts(58,5): error TS2571: Object is of type 'unknown'. -tests/cases/conformance/types/unknown/unknownType1.ts(59,5): error TS2571: Object is of type 'unknown'. -tests/cases/conformance/types/unknown/unknownType1.ts(60,5): error TS2571: Object is of type 'unknown'. -tests/cases/conformance/types/unknown/unknownType1.ts(61,9): error TS2571: Object is of type 'unknown'. -tests/cases/conformance/types/unknown/unknownType1.ts(105,9): error TS2322: Type 'unknown' is not assignable to type 'object'. -tests/cases/conformance/types/unknown/unknownType1.ts(106,9): error TS2322: Type 'unknown' is not assignable to type 'string'. -tests/cases/conformance/types/unknown/unknownType1.ts(107,9): error TS2322: Type 'unknown' is not assignable to type 'string[]'. -tests/cases/conformance/types/unknown/unknownType1.ts(108,9): error TS2322: Type 'unknown' is not assignable to type '{}'. -tests/cases/conformance/types/unknown/unknownType1.ts(109,9): error TS2322: Type 'unknown' is not assignable to type '{} | null | undefined'. +tests/cases/conformance/types/unknown/unknownType1.ts(51,5): error TS2571: Object is of type 'unknown'. +tests/cases/conformance/types/unknown/unknownType1.ts(52,5): error TS2571: Object is of type 'unknown'. +tests/cases/conformance/types/unknown/unknownType1.ts(53,5): error TS2571: Object is of type 'unknown'. +tests/cases/conformance/types/unknown/unknownType1.ts(54,5): error TS2571: Object is of type 'unknown'. +tests/cases/conformance/types/unknown/unknownType1.ts(55,5): error TS2571: Object is of type 'unknown'. +tests/cases/conformance/types/unknown/unknownType1.ts(56,6): error TS2571: Object is of type 'unknown'. +tests/cases/conformance/types/unknown/unknownType1.ts(57,6): error TS2571: Object is of type 'unknown'. +tests/cases/conformance/types/unknown/unknownType1.ts(63,5): error TS2571: Object is of type 'unknown'. +tests/cases/conformance/types/unknown/unknownType1.ts(64,5): error TS2571: Object is of type 'unknown'. +tests/cases/conformance/types/unknown/unknownType1.ts(65,5): error TS2571: Object is of type 'unknown'. +tests/cases/conformance/types/unknown/unknownType1.ts(66,9): error TS2571: Object is of type 'unknown'. +tests/cases/conformance/types/unknown/unknownType1.ts(110,9): error TS2322: Type 'unknown' is not assignable to type 'object'. +tests/cases/conformance/types/unknown/unknownType1.ts(111,9): error TS2322: Type 'unknown' is not assignable to type 'string'. +tests/cases/conformance/types/unknown/unknownType1.ts(112,9): error TS2322: Type 'unknown' is not assignable to type 'string[]'. +tests/cases/conformance/types/unknown/unknownType1.ts(113,9): error TS2322: Type 'unknown' is not assignable to type '{}'. +tests/cases/conformance/types/unknown/unknownType1.ts(114,9): error TS2322: Type 'unknown' is not assignable to type '{} | null | undefined'. Type 'unknown' is not assignable to type '{}'. -tests/cases/conformance/types/unknown/unknownType1.ts(115,9): error TS2322: Type 'T' is not assignable to type 'object'. -tests/cases/conformance/types/unknown/unknownType1.ts(124,5): error TS2322: Type '123' is not assignable to type '{ [x: string]: unknown; }'. -tests/cases/conformance/types/unknown/unknownType1.ts(150,14): error TS2700: Rest types may only be created from object types. -tests/cases/conformance/types/unknown/unknownType1.ts(156,5): error TS2564: Property 'a' has no initializer and is not definitely assigned in the constructor. +tests/cases/conformance/types/unknown/unknownType1.ts(120,9): error TS2322: Type 'T' is not assignable to type 'object'. +tests/cases/conformance/types/unknown/unknownType1.ts(129,5): error TS2322: Type '123' is not assignable to type '{ [x: string]: unknown; }'. +tests/cases/conformance/types/unknown/unknownType1.ts(155,14): error TS2700: Rest types may only be created from object types. +tests/cases/conformance/types/unknown/unknownType1.ts(161,5): error TS2564: Property 'a' has no initializer and is not definitely assigned in the constructor. ==== tests/cases/conformance/types/unknown/unknownType1.ts (21 errors) ==== @@ -53,10 +53,15 @@ tests/cases/conformance/types/unknown/unknownType1.ts(156,5): error TS2564: Prop // unknown in conditional types type T30 = unknown extends T ? true : false; // Deferred - type T31 = T extends unknown ? true : false; // true + type T31 = T extends unknown ? true : false; // Deferred (so it distributes) type T32 = never extends T ? true : false; // true type T33 = T extends never ? true : false; // Deferred + type T35 = T extends unknown ? { x: T } : false; + type T36 = T35; // { x: string } | { x: number } + type T37 = T35; // { x: any } + type T38 = T35; // { x: unknown } + // keyof unknown type T40 = keyof any; // string | number | symbol diff --git a/tests/baselines/reference/unknownType1.js b/tests/baselines/reference/unknownType1.js index 76224ef18ca2b..633972dfe69c2 100644 --- a/tests/baselines/reference/unknownType1.js +++ b/tests/baselines/reference/unknownType1.js @@ -29,10 +29,15 @@ type T23 = T | unknown; // unknown // unknown in conditional types type T30 = unknown extends T ? true : false; // Deferred -type T31 = T extends unknown ? true : false; // true +type T31 = T extends unknown ? true : false; // Deferred (so it distributes) type T32 = never extends T ? true : false; // true type T33 = T extends never ? true : false; // Deferred +type T35 = T extends unknown ? { x: T } : false; +type T36 = T35; // { x: string } | { x: number } +type T37 = T35; // { x: any } +type T38 = T35; // { x: unknown } + // keyof unknown type T40 = keyof any; // string | number | symbol diff --git a/tests/baselines/reference/unknownType1.symbols b/tests/baselines/reference/unknownType1.symbols index 8067312f72834..c73308df51206 100644 --- a/tests/baselines/reference/unknownType1.symbols +++ b/tests/baselines/reference/unknownType1.symbols @@ -74,7 +74,7 @@ type T30 = unknown extends T ? true : false; // Deferred >T : Symbol(T, Decl(unknownType1.ts, 29, 9)) >T : Symbol(T, Decl(unknownType1.ts, 29, 9)) -type T31 = T extends unknown ? true : false; // true +type T31 = T extends unknown ? true : false; // Deferred (so it distributes) >T31 : Symbol(T31, Decl(unknownType1.ts, 29, 47)) >T : Symbol(T, Decl(unknownType1.ts, 30, 9)) >T : Symbol(T, Decl(unknownType1.ts, 30, 9)) @@ -89,302 +89,321 @@ type T33 = T extends never ? true : false; // Deferred >T : Symbol(T, Decl(unknownType1.ts, 32, 9)) >T : Symbol(T, Decl(unknownType1.ts, 32, 9)) +type T35 = T extends unknown ? { x: T } : false; +>T35 : Symbol(T35, Decl(unknownType1.ts, 32, 45)) +>T : Symbol(T, Decl(unknownType1.ts, 34, 9)) +>T : Symbol(T, Decl(unknownType1.ts, 34, 9)) +>x : Symbol(x, Decl(unknownType1.ts, 34, 35)) +>T : Symbol(T, Decl(unknownType1.ts, 34, 9)) + +type T36 = T35; // { x: string } | { x: number } +>T36 : Symbol(T36, Decl(unknownType1.ts, 34, 51)) +>T35 : Symbol(T35, Decl(unknownType1.ts, 32, 45)) + +type T37 = T35; // { x: any } +>T37 : Symbol(T37, Decl(unknownType1.ts, 35, 32)) +>T35 : Symbol(T35, Decl(unknownType1.ts, 32, 45)) + +type T38 = T35; // { x: unknown } +>T38 : Symbol(T38, Decl(unknownType1.ts, 36, 20)) +>T35 : Symbol(T35, Decl(unknownType1.ts, 32, 45)) + // keyof unknown type T40 = keyof any; // string | number | symbol ->T40 : Symbol(T40, Decl(unknownType1.ts, 32, 45)) +>T40 : Symbol(T40, Decl(unknownType1.ts, 37, 24)) type T41 = keyof unknown; // never ->T41 : Symbol(T41, Decl(unknownType1.ts, 36, 21)) +>T41 : Symbol(T41, Decl(unknownType1.ts, 41, 21)) // Only equality operators are allowed with unknown function f10(x: unknown) { ->f10 : Symbol(f10, Decl(unknownType1.ts, 37, 25)) ->x : Symbol(x, Decl(unknownType1.ts, 41, 13)) +>f10 : Symbol(f10, Decl(unknownType1.ts, 42, 25)) +>x : Symbol(x, Decl(unknownType1.ts, 46, 13)) x == 5; ->x : Symbol(x, Decl(unknownType1.ts, 41, 13)) +>x : Symbol(x, Decl(unknownType1.ts, 46, 13)) x !== 10; ->x : Symbol(x, Decl(unknownType1.ts, 41, 13)) +>x : Symbol(x, Decl(unknownType1.ts, 46, 13)) x >= 0; // Error ->x : Symbol(x, Decl(unknownType1.ts, 41, 13)) +>x : Symbol(x, Decl(unknownType1.ts, 46, 13)) x.foo; // Error ->x : Symbol(x, Decl(unknownType1.ts, 41, 13)) +>x : Symbol(x, Decl(unknownType1.ts, 46, 13)) x[10]; // Error ->x : Symbol(x, Decl(unknownType1.ts, 41, 13)) +>x : Symbol(x, Decl(unknownType1.ts, 46, 13)) x(); // Error ->x : Symbol(x, Decl(unknownType1.ts, 41, 13)) +>x : Symbol(x, Decl(unknownType1.ts, 46, 13)) x + 1; // Error ->x : Symbol(x, Decl(unknownType1.ts, 41, 13)) +>x : Symbol(x, Decl(unknownType1.ts, 46, 13)) x * 2; // Error ->x : Symbol(x, Decl(unknownType1.ts, 41, 13)) +>x : Symbol(x, Decl(unknownType1.ts, 46, 13)) -x; // Error ->x : Symbol(x, Decl(unknownType1.ts, 41, 13)) +>x : Symbol(x, Decl(unknownType1.ts, 46, 13)) +x; // Error ->x : Symbol(x, Decl(unknownType1.ts, 41, 13)) +>x : Symbol(x, Decl(unknownType1.ts, 46, 13)) } // No property accesses, element accesses, or function calls function f11(x: unknown) { ->f11 : Symbol(f11, Decl(unknownType1.ts, 52, 1)) ->x : Symbol(x, Decl(unknownType1.ts, 56, 13)) +>f11 : Symbol(f11, Decl(unknownType1.ts, 57, 1)) +>x : Symbol(x, Decl(unknownType1.ts, 61, 13)) x.foo; // Error ->x : Symbol(x, Decl(unknownType1.ts, 56, 13)) +>x : Symbol(x, Decl(unknownType1.ts, 61, 13)) x[5]; // Error ->x : Symbol(x, Decl(unknownType1.ts, 56, 13)) +>x : Symbol(x, Decl(unknownType1.ts, 61, 13)) x(); // Error ->x : Symbol(x, Decl(unknownType1.ts, 56, 13)) +>x : Symbol(x, Decl(unknownType1.ts, 61, 13)) new x(); // Error ->x : Symbol(x, Decl(unknownType1.ts, 56, 13)) +>x : Symbol(x, Decl(unknownType1.ts, 61, 13)) } // typeof, instanceof, and user defined type predicates declare function isFunction(x: unknown): x is Function; ->isFunction : Symbol(isFunction, Decl(unknownType1.ts, 61, 1)) ->x : Symbol(x, Decl(unknownType1.ts, 65, 28)) ->x : Symbol(x, Decl(unknownType1.ts, 65, 28)) +>isFunction : Symbol(isFunction, Decl(unknownType1.ts, 66, 1)) +>x : Symbol(x, Decl(unknownType1.ts, 70, 28)) +>x : Symbol(x, Decl(unknownType1.ts, 70, 28)) >Function : Symbol(Function, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) function f20(x: unknown) { ->f20 : Symbol(f20, Decl(unknownType1.ts, 65, 55)) ->x : Symbol(x, Decl(unknownType1.ts, 67, 13)) +>f20 : Symbol(f20, Decl(unknownType1.ts, 70, 55)) +>x : Symbol(x, Decl(unknownType1.ts, 72, 13)) if (typeof x === "string" || typeof x === "number") { ->x : Symbol(x, Decl(unknownType1.ts, 67, 13)) ->x : Symbol(x, Decl(unknownType1.ts, 67, 13)) +>x : Symbol(x, Decl(unknownType1.ts, 72, 13)) +>x : Symbol(x, Decl(unknownType1.ts, 72, 13)) x; // string | number ->x : Symbol(x, Decl(unknownType1.ts, 67, 13)) +>x : Symbol(x, Decl(unknownType1.ts, 72, 13)) } if (x instanceof Error) { ->x : Symbol(x, Decl(unknownType1.ts, 67, 13)) +>x : Symbol(x, Decl(unknownType1.ts, 72, 13)) >Error : Symbol(Error, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) x; // Error ->x : Symbol(x, Decl(unknownType1.ts, 67, 13)) +>x : Symbol(x, Decl(unknownType1.ts, 72, 13)) } if (isFunction(x)) { ->isFunction : Symbol(isFunction, Decl(unknownType1.ts, 61, 1)) ->x : Symbol(x, Decl(unknownType1.ts, 67, 13)) +>isFunction : Symbol(isFunction, Decl(unknownType1.ts, 66, 1)) +>x : Symbol(x, Decl(unknownType1.ts, 72, 13)) x; // Function ->x : Symbol(x, Decl(unknownType1.ts, 67, 13)) +>x : Symbol(x, Decl(unknownType1.ts, 72, 13)) } } // Homomorphic mapped type over unknown type T50 = { [P in keyof T]: number }; ->T50 : Symbol(T50, Decl(unknownType1.ts, 77, 1)) ->T : Symbol(T, Decl(unknownType1.ts, 81, 9)) ->P : Symbol(P, Decl(unknownType1.ts, 81, 17)) ->T : Symbol(T, Decl(unknownType1.ts, 81, 9)) +>T50 : Symbol(T50, Decl(unknownType1.ts, 82, 1)) +>T : Symbol(T, Decl(unknownType1.ts, 86, 9)) +>P : Symbol(P, Decl(unknownType1.ts, 86, 17)) +>T : Symbol(T, Decl(unknownType1.ts, 86, 9)) type T51 = T50; // { [x: string]: number } ->T51 : Symbol(T51, Decl(unknownType1.ts, 81, 41)) ->T50 : Symbol(T50, Decl(unknownType1.ts, 77, 1)) +>T51 : Symbol(T51, Decl(unknownType1.ts, 86, 41)) +>T50 : Symbol(T50, Decl(unknownType1.ts, 82, 1)) type T52 = T50; // {} ->T52 : Symbol(T52, Decl(unknownType1.ts, 82, 20)) ->T50 : Symbol(T50, Decl(unknownType1.ts, 77, 1)) +>T52 : Symbol(T52, Decl(unknownType1.ts, 87, 20)) +>T50 : Symbol(T50, Decl(unknownType1.ts, 82, 1)) // Anything is assignable to unknown function f21(pAny: any, pNever: never, pT: T) { ->f21 : Symbol(f21, Decl(unknownType1.ts, 83, 24)) ->T : Symbol(T, Decl(unknownType1.ts, 87, 13)) ->pAny : Symbol(pAny, Decl(unknownType1.ts, 87, 16)) ->pNever : Symbol(pNever, Decl(unknownType1.ts, 87, 26)) ->pT : Symbol(pT, Decl(unknownType1.ts, 87, 41)) ->T : Symbol(T, Decl(unknownType1.ts, 87, 13)) +>f21 : Symbol(f21, Decl(unknownType1.ts, 88, 24)) +>T : Symbol(T, Decl(unknownType1.ts, 92, 13)) +>pAny : Symbol(pAny, Decl(unknownType1.ts, 92, 16)) +>pNever : Symbol(pNever, Decl(unknownType1.ts, 92, 26)) +>pT : Symbol(pT, Decl(unknownType1.ts, 92, 41)) +>T : Symbol(T, Decl(unknownType1.ts, 92, 13)) let x: unknown; ->x : Symbol(x, Decl(unknownType1.ts, 88, 7)) +>x : Symbol(x, Decl(unknownType1.ts, 93, 7)) x = 123; ->x : Symbol(x, Decl(unknownType1.ts, 88, 7)) +>x : Symbol(x, Decl(unknownType1.ts, 93, 7)) x = "hello"; ->x : Symbol(x, Decl(unknownType1.ts, 88, 7)) +>x : Symbol(x, Decl(unknownType1.ts, 93, 7)) x = [1, 2, 3]; ->x : Symbol(x, Decl(unknownType1.ts, 88, 7)) +>x : Symbol(x, Decl(unknownType1.ts, 93, 7)) x = new Error(); ->x : Symbol(x, Decl(unknownType1.ts, 88, 7)) +>x : Symbol(x, Decl(unknownType1.ts, 93, 7)) >Error : Symbol(Error, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) x = x; ->x : Symbol(x, Decl(unknownType1.ts, 88, 7)) ->x : Symbol(x, Decl(unknownType1.ts, 88, 7)) +>x : Symbol(x, Decl(unknownType1.ts, 93, 7)) +>x : Symbol(x, Decl(unknownType1.ts, 93, 7)) x = pAny; ->x : Symbol(x, Decl(unknownType1.ts, 88, 7)) ->pAny : Symbol(pAny, Decl(unknownType1.ts, 87, 16)) +>x : Symbol(x, Decl(unknownType1.ts, 93, 7)) +>pAny : Symbol(pAny, Decl(unknownType1.ts, 92, 16)) x = pNever; ->x : Symbol(x, Decl(unknownType1.ts, 88, 7)) ->pNever : Symbol(pNever, Decl(unknownType1.ts, 87, 26)) +>x : Symbol(x, Decl(unknownType1.ts, 93, 7)) +>pNever : Symbol(pNever, Decl(unknownType1.ts, 92, 26)) x = pT; ->x : Symbol(x, Decl(unknownType1.ts, 88, 7)) ->pT : Symbol(pT, Decl(unknownType1.ts, 87, 41)) +>x : Symbol(x, Decl(unknownType1.ts, 93, 7)) +>pT : Symbol(pT, Decl(unknownType1.ts, 92, 41)) } // unknown assignable only to itself and any function f22(x: unknown) { ->f22 : Symbol(f22, Decl(unknownType1.ts, 97, 1)) ->x : Symbol(x, Decl(unknownType1.ts, 101, 13)) +>f22 : Symbol(f22, Decl(unknownType1.ts, 102, 1)) +>x : Symbol(x, Decl(unknownType1.ts, 106, 13)) let v1: any = x; ->v1 : Symbol(v1, Decl(unknownType1.ts, 102, 7)) ->x : Symbol(x, Decl(unknownType1.ts, 101, 13)) +>v1 : Symbol(v1, Decl(unknownType1.ts, 107, 7)) +>x : Symbol(x, Decl(unknownType1.ts, 106, 13)) let v2: unknown = x; ->v2 : Symbol(v2, Decl(unknownType1.ts, 103, 7)) ->x : Symbol(x, Decl(unknownType1.ts, 101, 13)) +>v2 : Symbol(v2, Decl(unknownType1.ts, 108, 7)) +>x : Symbol(x, Decl(unknownType1.ts, 106, 13)) let v3: object = x; // Error ->v3 : Symbol(v3, Decl(unknownType1.ts, 104, 7)) ->x : Symbol(x, Decl(unknownType1.ts, 101, 13)) +>v3 : Symbol(v3, Decl(unknownType1.ts, 109, 7)) +>x : Symbol(x, Decl(unknownType1.ts, 106, 13)) let v4: string = x; // Error ->v4 : Symbol(v4, Decl(unknownType1.ts, 105, 7)) ->x : Symbol(x, Decl(unknownType1.ts, 101, 13)) +>v4 : Symbol(v4, Decl(unknownType1.ts, 110, 7)) +>x : Symbol(x, Decl(unknownType1.ts, 106, 13)) let v5: string[] = x; // Error ->v5 : Symbol(v5, Decl(unknownType1.ts, 106, 7)) ->x : Symbol(x, Decl(unknownType1.ts, 101, 13)) +>v5 : Symbol(v5, Decl(unknownType1.ts, 111, 7)) +>x : Symbol(x, Decl(unknownType1.ts, 106, 13)) let v6: {} = x; // Error ->v6 : Symbol(v6, Decl(unknownType1.ts, 107, 7)) ->x : Symbol(x, Decl(unknownType1.ts, 101, 13)) +>v6 : Symbol(v6, Decl(unknownType1.ts, 112, 7)) +>x : Symbol(x, Decl(unknownType1.ts, 106, 13)) let v7: {} | null | undefined = x; // Error ->v7 : Symbol(v7, Decl(unknownType1.ts, 108, 7)) ->x : Symbol(x, Decl(unknownType1.ts, 101, 13)) +>v7 : Symbol(v7, Decl(unknownType1.ts, 113, 7)) +>x : Symbol(x, Decl(unknownType1.ts, 106, 13)) } // Type parameter 'T extends unknown' not related to object function f23(x: T) { ->f23 : Symbol(f23, Decl(unknownType1.ts, 109, 1)) ->T : Symbol(T, Decl(unknownType1.ts, 113, 13)) ->x : Symbol(x, Decl(unknownType1.ts, 113, 32)) ->T : Symbol(T, Decl(unknownType1.ts, 113, 13)) +>f23 : Symbol(f23, Decl(unknownType1.ts, 114, 1)) +>T : Symbol(T, Decl(unknownType1.ts, 118, 13)) +>x : Symbol(x, Decl(unknownType1.ts, 118, 32)) +>T : Symbol(T, Decl(unknownType1.ts, 118, 13)) let y: object = x; // Error ->y : Symbol(y, Decl(unknownType1.ts, 114, 7)) ->x : Symbol(x, Decl(unknownType1.ts, 113, 32)) +>y : Symbol(y, Decl(unknownType1.ts, 119, 7)) +>x : Symbol(x, Decl(unknownType1.ts, 118, 32)) } // Anything but primitive assignable to { [x: string]: unknown } function f24(x: { [x: string]: unknown }) { ->f24 : Symbol(f24, Decl(unknownType1.ts, 115, 1)) ->x : Symbol(x, Decl(unknownType1.ts, 119, 13)) ->x : Symbol(x, Decl(unknownType1.ts, 119, 19)) +>f24 : Symbol(f24, Decl(unknownType1.ts, 120, 1)) +>x : Symbol(x, Decl(unknownType1.ts, 124, 13)) +>x : Symbol(x, Decl(unknownType1.ts, 124, 19)) x = {}; ->x : Symbol(x, Decl(unknownType1.ts, 119, 13)) +>x : Symbol(x, Decl(unknownType1.ts, 124, 13)) x = { a: 5 }; ->x : Symbol(x, Decl(unknownType1.ts, 119, 13)) ->a : Symbol(a, Decl(unknownType1.ts, 121, 9)) +>x : Symbol(x, Decl(unknownType1.ts, 124, 13)) +>a : Symbol(a, Decl(unknownType1.ts, 126, 9)) x = [1, 2, 3]; ->x : Symbol(x, Decl(unknownType1.ts, 119, 13)) +>x : Symbol(x, Decl(unknownType1.ts, 124, 13)) x = 123; // Error ->x : Symbol(x, Decl(unknownType1.ts, 119, 13)) +>x : Symbol(x, Decl(unknownType1.ts, 124, 13)) } // Locals of type unknown always considered initialized function f25() { ->f25 : Symbol(f25, Decl(unknownType1.ts, 124, 1)) +>f25 : Symbol(f25, Decl(unknownType1.ts, 129, 1)) let x: unknown; ->x : Symbol(x, Decl(unknownType1.ts, 129, 7)) +>x : Symbol(x, Decl(unknownType1.ts, 134, 7)) let y = x; ->y : Symbol(y, Decl(unknownType1.ts, 130, 7)) ->x : Symbol(x, Decl(unknownType1.ts, 129, 7)) +>y : Symbol(y, Decl(unknownType1.ts, 135, 7)) +>x : Symbol(x, Decl(unknownType1.ts, 134, 7)) } // Spread of unknown causes result to be unknown function f26(x: {}, y: unknown, z: any) { ->f26 : Symbol(f26, Decl(unknownType1.ts, 131, 1)) ->x : Symbol(x, Decl(unknownType1.ts, 135, 13)) ->y : Symbol(y, Decl(unknownType1.ts, 135, 19)) ->z : Symbol(z, Decl(unknownType1.ts, 135, 31)) +>f26 : Symbol(f26, Decl(unknownType1.ts, 136, 1)) +>x : Symbol(x, Decl(unknownType1.ts, 140, 13)) +>y : Symbol(y, Decl(unknownType1.ts, 140, 19)) +>z : Symbol(z, Decl(unknownType1.ts, 140, 31)) let o1 = { a: 42, ...x }; // { a: number } ->o1 : Symbol(o1, Decl(unknownType1.ts, 136, 7)) ->a : Symbol(a, Decl(unknownType1.ts, 136, 14)) ->x : Symbol(x, Decl(unknownType1.ts, 135, 13)) +>o1 : Symbol(o1, Decl(unknownType1.ts, 141, 7)) +>a : Symbol(a, Decl(unknownType1.ts, 141, 14)) +>x : Symbol(x, Decl(unknownType1.ts, 140, 13)) let o2 = { a: 42, ...x, ...y }; // unknown ->o2 : Symbol(o2, Decl(unknownType1.ts, 137, 7)) ->a : Symbol(a, Decl(unknownType1.ts, 137, 14)) ->x : Symbol(x, Decl(unknownType1.ts, 135, 13)) ->y : Symbol(y, Decl(unknownType1.ts, 135, 19)) +>o2 : Symbol(o2, Decl(unknownType1.ts, 142, 7)) +>a : Symbol(a, Decl(unknownType1.ts, 142, 14)) +>x : Symbol(x, Decl(unknownType1.ts, 140, 13)) +>y : Symbol(y, Decl(unknownType1.ts, 140, 19)) let o3 = { a: 42, ...x, ...y, ...z }; // any ->o3 : Symbol(o3, Decl(unknownType1.ts, 138, 7)) ->a : Symbol(a, Decl(unknownType1.ts, 138, 14)) ->x : Symbol(x, Decl(unknownType1.ts, 135, 13)) ->y : Symbol(y, Decl(unknownType1.ts, 135, 19)) ->z : Symbol(z, Decl(unknownType1.ts, 135, 31)) +>o3 : Symbol(o3, Decl(unknownType1.ts, 143, 7)) +>a : Symbol(a, Decl(unknownType1.ts, 143, 14)) +>x : Symbol(x, Decl(unknownType1.ts, 140, 13)) +>y : Symbol(y, Decl(unknownType1.ts, 140, 19)) +>z : Symbol(z, Decl(unknownType1.ts, 140, 31)) } // Functions with unknown return type don't need return expressions function f27(): unknown { ->f27 : Symbol(f27, Decl(unknownType1.ts, 139, 1)) +>f27 : Symbol(f27, Decl(unknownType1.ts, 144, 1)) } // Rest type cannot be created from unknown function f28(x: unknown) { ->f28 : Symbol(f28, Decl(unknownType1.ts, 144, 1)) ->x : Symbol(x, Decl(unknownType1.ts, 148, 13)) +>f28 : Symbol(f28, Decl(unknownType1.ts, 149, 1)) +>x : Symbol(x, Decl(unknownType1.ts, 153, 13)) let { ...a } = x; // Error ->a : Symbol(a, Decl(unknownType1.ts, 149, 9)) ->x : Symbol(x, Decl(unknownType1.ts, 148, 13)) +>a : Symbol(a, Decl(unknownType1.ts, 154, 9)) +>x : Symbol(x, Decl(unknownType1.ts, 153, 13)) } // Class properties of type unknown don't need definite assignment class C1 { ->C1 : Symbol(C1, Decl(unknownType1.ts, 150, 1)) +>C1 : Symbol(C1, Decl(unknownType1.ts, 155, 1)) a: string; // Error ->a : Symbol(C1.a, Decl(unknownType1.ts, 154, 10)) +>a : Symbol(C1.a, Decl(unknownType1.ts, 159, 10)) b: unknown; ->b : Symbol(C1.b, Decl(unknownType1.ts, 155, 14)) +>b : Symbol(C1.b, Decl(unknownType1.ts, 160, 14)) c: any; ->c : Symbol(C1.c, Decl(unknownType1.ts, 156, 15)) +>c : Symbol(C1.c, Decl(unknownType1.ts, 161, 15)) } diff --git a/tests/baselines/reference/unknownType1.types b/tests/baselines/reference/unknownType1.types index dec3acaaebcd7..41c969bc95e4d 100644 --- a/tests/baselines/reference/unknownType1.types +++ b/tests/baselines/reference/unknownType1.types @@ -80,8 +80,8 @@ type T30 = unknown extends T ? true : false; // Deferred >true : true >false : false -type T31 = T extends unknown ? true : false; // true ->T31 : true +type T31 = T extends unknown ? true : false; // Deferred (so it distributes) +>T31 : T31 >T : T >T : T >true : true @@ -101,6 +101,26 @@ type T33 = T extends never ? true : false; // Deferred >true : true >false : false +type T35 = T extends unknown ? { x: T } : false; +>T35 : T35 +>T : T +>T : T +>x : T +>T : T +>false : false + +type T36 = T35; // { x: string } | { x: number } +>T36 : { x: string; } | { x: number; } +>T35 : T35 + +type T37 = T35; // { x: any } +>T37 : { x: any; } +>T35 : T35 + +type T38 = T35; // { x: unknown } +>T38 : { x: unknown; } +>T35 : T35 + // keyof unknown type T40 = keyof any; // string | number | symbol From 86643902b29cee041d2bef419deb1e80ebd0f8f1 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 30 May 2018 08:17:09 -0700 Subject: [PATCH 24/24] Rename unknownType to errorType in merged code --- src/compiler/checker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index b1a129376629b..b21e238a729e6 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -10612,7 +10612,7 @@ namespace ts { const targetTypes = (target as IntersectionType).types; const intrinsicAttributes = getJsxType(JsxNames.IntrinsicAttributes, errorNode); const intrinsicClassAttributes = getJsxType(JsxNames.IntrinsicClassAttributes, errorNode); - if (intrinsicAttributes !== unknownType && intrinsicClassAttributes !== unknownType && + if (intrinsicAttributes !== errorType && intrinsicClassAttributes !== errorType && (contains(targetTypes, intrinsicAttributes) || contains(targetTypes, intrinsicClassAttributes))) { // do not report top error return result;