diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 4555f247980df..b21e238a729e6 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,8 @@ 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 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"); @@ -398,7 +399,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]; @@ -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); } @@ -4377,8 +4381,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. @@ -4393,9 +4397,9 @@ 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 unknownType; + return errorType; } const literalMembers: PropertyName[] = []; for (const element of pattern.elements) { @@ -4453,7 +4457,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 +4483,7 @@ namespace ts { else { error(declaration, Diagnostics.Type_0_has_no_property_1, typeToString(parentType), propName); } - return unknownType; + return errorType; } } } @@ -4631,7 +4635,7 @@ namespace ts { undefined; if (!expression) { - return unknownType; + return errorType; } const special = getSpecialPropertyAssignmentKind(expression); @@ -4657,7 +4661,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 +4904,7 @@ namespace ts { } // Handle variable, parameter or property if (!pushTypeResolution(symbol, TypeSystemPropertyName.Type)) { - return unknownType; + return errorType; } let type: Type; @@ -4993,7 +4997,7 @@ namespace ts { } if (!pushTypeResolution(symbol, TypeSystemPropertyName.Type)) { - return unknownType; + return errorType; } let type: Type; @@ -5090,7 +5094,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 +5104,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 +5127,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 +5159,7 @@ namespace ts { if (symbol.flags & SymbolFlags.Alias) { return getTypeOfAlias(symbol); } - return unknownType; + return errorType; } function isReferenceToType(type: Type, target: Type) { @@ -5330,7 +5334,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 +5348,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 +5411,7 @@ namespace ts { baseType = getReturnTypeOfSignature(constructors[0]); } - if (baseType === unknownType) { + if (baseType === errorType) { return type.resolvedBaseTypes = emptyArray; } if (!isValidBaseType(baseType)) { @@ -5454,7 +5458,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 +5546,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 +5566,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 +5691,7 @@ namespace ts { } function getDeclaredTypeOfSymbol(symbol: Symbol): Type { - return tryGetDeclaredTypeOfSymbol(symbol) || unknownType; + return tryGetDeclaredTypeOfSymbol(symbol) || errorType; } function tryGetDeclaredTypeOfSymbol(symbol: Symbol): Type | undefined { @@ -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: @@ -6486,14 +6491,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 +6671,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 +6829,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 +6923,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 +7461,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 +7764,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 +7773,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 +7807,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 +7842,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 +7855,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); @@ -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) { @@ -8590,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) { @@ -8598,6 +8603,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]; } @@ -8712,7 +8720,7 @@ namespace ts { case SyntaxKind.UniqueKeyword: links.resolvedType = node.type.kind === SyntaxKind.SymbolKeyword ? getESSymbolLikeTypeForNode(walkUpParenthesizedTypes(node.parent)) - : unknownType; + : errorType; break; } } @@ -8739,7 +8747,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 +8800,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 { @@ -8893,7 +8901,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. @@ -8912,8 +8920,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); } @@ -8977,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)]); @@ -9099,12 +9110,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 +9124,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 +9136,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 +9151,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; } } } @@ -9195,6 +9206,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; } @@ -9371,7 +9385,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 { @@ -9388,6 +9402,8 @@ namespace ts { case SyntaxKind.JSDocAllType: case SyntaxKind.JSDocUnknownType: return anyType; + case SyntaxKind.UnknownKeyword: + return unknownType; case SyntaxKind.StringKeyword: return stringType; case SyntaxKind.NumberKeyword: @@ -9463,7 +9479,7 @@ namespace ts { const symbol = getSymbolAtLocation(node); return (symbol && getDeclaredTypeOfSymbol(symbol))!; // TODO: GH#18217 default: - return unknownType; + return errorType; } } @@ -9756,7 +9772,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 +9871,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 +10285,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 && @@ -10596,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; @@ -11005,7 +11021,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; @@ -11448,7 +11464,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; } @@ -13226,17 +13242,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 { @@ -13275,7 +13291,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: @@ -13289,7 +13305,7 @@ namespace ts { case SyntaxKind.ShorthandPropertyAssignment: return getAssignedTypeOfShorthandPropertyAssignment(parent); } - return unknownType; + return errorType; } function getInitialTypeOfBindingElement(node: BindingElement): Type { @@ -13319,9 +13335,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) { @@ -13578,7 +13594,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; @@ -13595,7 +13611,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; @@ -13619,7 +13635,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) { @@ -14351,7 +14367,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. @@ -14429,11 +14445,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; } } @@ -14477,7 +14493,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 || @@ -14750,7 +14766,7 @@ namespace ts { if (isInJavaScriptFile(node)) { const type = getTypeForThisExpressionFromJSDoc(container); - if (type && type !== unknownType) { + if (type && type !== errorType) { return getFlowTypeOfReference(node, type); } } @@ -14808,7 +14824,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) { @@ -14899,7 +14915,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' @@ -14911,19 +14927,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 @@ -15527,7 +15543,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) { @@ -15550,7 +15566,7 @@ namespace ts { ctor = false; if (signatures.length === 0) { // We found no signatures at all, which is an error - return unknownType; + return errorType; } } @@ -15574,7 +15590,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; @@ -15611,7 +15627,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( @@ -15623,7 +15639,7 @@ namespace ts { } const intrinsicAttribs = getJsxType(JsxNames.IntrinsicAttributes, context); - if (intrinsicAttribs !== unknownType) { + if (intrinsicAttribs !== errorType) { apparentAttributesType = intersectTypes(intrinsicAttribs, apparentAttributesType); } @@ -16001,7 +16017,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; @@ -16081,7 +16097,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))); @@ -16288,7 +16304,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; } /** @@ -16301,7 +16317,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); @@ -16478,7 +16494,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; @@ -16538,7 +16554,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; @@ -16625,7 +16641,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) { @@ -16645,7 +16661,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); @@ -16685,7 +16701,7 @@ namespace ts { return links.resolvedJsxElementAttributesType = getIndexInfoOfSymbol(symbol, IndexKind.String)!.type; } else { - return links.resolvedJsxElementAttributesType = unknownType; + return links.resolvedJsxElementAttributesType = errorType; } } return links.resolvedJsxElementAttributesType; @@ -16744,7 +16760,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; } @@ -16925,7 +16941,7 @@ namespace ts { return type; } else { - return unknownType; + return errorType; } } @@ -17088,6 +17104,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 ? @@ -17096,7 +17116,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; } @@ -17131,7 +17151,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)); @@ -17146,7 +17166,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); @@ -17451,7 +17471,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); @@ -17526,25 +17546,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; } @@ -18143,7 +18163,7 @@ namespace ts { } Debug.fail("Unsupported decorator target."); - return unknownType; + return errorType; } /** @@ -18165,7 +18185,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) { @@ -18207,12 +18227,12 @@ namespace ts { default: Debug.fail("Unsupported property name."); - return unknownType; + return errorType; } } Debug.fail("Unsupported decorator target."); - return unknownType; + return errorType; } /** @@ -18227,7 +18247,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) { @@ -18237,7 +18257,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 || @@ -18250,7 +18270,7 @@ namespace ts { } Debug.fail("Unsupported decorator target."); - return unknownType; + return errorType; } /** @@ -18268,7 +18288,7 @@ namespace ts { } Debug.fail("Decorators should not have a fourth synthetic argument."); - return unknownType; + return errorType; } /** @@ -18612,7 +18632,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)!); @@ -18636,7 +18656,7 @@ namespace ts { } const apparentType = getApparentType(funcType); - if (apparentType === unknownType) { + if (apparentType === errorType) { // Another error has already been reported return resolveErrorCall(node); } @@ -18654,7 +18674,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); @@ -18704,7 +18724,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); } @@ -18830,7 +18850,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); } @@ -18881,7 +18901,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); } @@ -19183,7 +19203,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); @@ -19254,7 +19274,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); @@ -19285,7 +19305,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); @@ -19304,7 +19324,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) { @@ -19423,7 +19443,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) ? @@ -19436,7 +19456,7 @@ namespace ts { function getReturnTypeFromBody(func: FunctionLikeDeclaration, checkMode?: CheckMode): Type { if (!func.body) { - return unknownType; + return errorType; } const functionFlags = getFunctionFlags(func); @@ -19634,7 +19654,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; } @@ -19922,7 +19942,7 @@ namespace ts { } return numberType; } - return unknownType; + return errorType; } function checkPostfixUnaryExpression(node: PostfixUnaryExpression): Type { @@ -19944,7 +19964,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) { @@ -19962,7 +19982,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) || @@ -20099,7 +20119,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); } @@ -20350,7 +20370,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 @@ -20898,7 +20918,7 @@ namespace ts { case SyntaxKind.JsxOpeningElement: Debug.fail("Shouldn't ever directly check a JsxOpeningElement"); } - return unknownType; + return errorType; } // DECLARATION AND STATEMENT TYPE CHECKING @@ -21511,7 +21531,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 || @@ -21527,7 +21547,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); @@ -22067,7 +22087,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 { @@ -22216,41 +22236,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); @@ -22258,12 +22278,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. @@ -22273,7 +22293,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; } } @@ -23270,7 +23290,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); @@ -23438,7 +23458,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); @@ -23859,7 +23879,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) { @@ -24153,6 +24173,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": @@ -24371,7 +24392,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 : @@ -24586,7 +24607,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)); } @@ -26234,7 +26255,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)) { @@ -26292,11 +26313,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. @@ -26312,27 +26333,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 @@ -26755,10 +26776,10 @@ namespace ts { return TypeReferenceSerializationKind.Unknown; } const type = getDeclaredTypeOfSymbol(typeSymbol); - if (type === unknownType) { + 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)) { @@ -26799,7 +26820,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; @@ -27110,7 +27131,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); diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index f0bb5e5ed7d5d..95c258f06ceaa 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 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 a3cdb32df0702..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,42 +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 + 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 << 23, // Fresh literal or unique type + FreshLiteral = 1 << 25, // Fresh literal or unique type /* @internal */ - ContainsWideningType = 1 << 24, // Type is or contains undefined or null widening type + UnionOfUnitTypes = 1 << 26, // Type is union of unit types /* @internal */ - ContainsObjectLiteral = 1 << 25, // Type is or contains object literal type + ContainsWideningType = 1 << 27, // 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 << 28, // 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 << 29, // Type is or contains the anyFunctionType + /* @internal */ + AnyOrUnknown = Any | Unknown, /* @internal */ Nullable = Undefined | Null, Literal = StringLiteral | NumberLiteral | BooleanLiteral, @@ -3712,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, @@ -3733,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 */ @@ -3749,7 +3752,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; 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 diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 3adc0f014b696..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 = 134217728, - 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 = 142575359, - NotUnionOrUnit = 134283777 + 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 70f2e0d0cdbf5..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 = 134217728, - 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 = 142575359, - NotUnionOrUnit = 134283777 + 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/unknownType1.errors.txt b/tests/baselines/reference/unknownType1.errors.txt new file mode 100644 index 0000000000000..37d0cd010e7a0 --- /dev/null +++ b/tests/baselines/reference/unknownType1.errors.txt @@ -0,0 +1,233 @@ +tests/cases/conformance/types/unknown/unknownType1.ts(50,5): error TS2571: Object is of type 'unknown'. +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(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) ==== + // 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; // 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 + type T41 = keyof unknown; // never + + // 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 f20(x: unknown) { + if (typeof x === "string" || typeof x === "number") { + x; // string | number + } + 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; // {} + + // Anything is assignable to unknown + + function f21(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 f22(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 f23(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 f24(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 f25() { + let x: unknown; + let y = x; + } + + // Spread of unknown causes result to be unknown + + 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 + } + + // Functions with unknown return type don't need return expressions + + 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 + + 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..633972dfe69c2 --- /dev/null +++ b/tests/baselines/reference/unknownType1.js @@ -0,0 +1,275 @@ +//// [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; // 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 +type T41 = keyof unknown; // never + +// 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 f20(x: unknown) { + if (typeof x === "string" || typeof x === "number") { + x; // string | number + } + 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; // {} + +// Anything is assignable to unknown + +function f21(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 f22(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 f23(x: T) { + let y: object = x; // Error +} + +// Anything but primitive assignable to { [x: string]: unknown } + +function f24(x: { [x: string]: unknown }) { + x = {}; + x = { a: 5 }; + x = [1, 2, 3]; + x = 123; // Error +} + +// Locals of type unknown always considered initialized + +function f25() { + let x: unknown; + let y = x; +} + +// Spread of unknown causes result to be unknown + +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 +} + +// Functions with unknown return type don't need return expressions + +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 + +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; +}; +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 (x instanceof Error) { + x; // Error + } + if (isFunction(x)) { + x; // Function + } +} +// Anything is assignable to unknown +function f21(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 f22(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 f23(x) { + var y = x; // Error +} +// Anything but primitive assignable to { [x: string]: unknown } +function f24(x) { + x = {}; + x = { a: 5 }; + x = [1, 2, 3]; + x = 123; // Error +} +// Locals of type unknown always considered initialized +function f25() { + var x; + var y = x; +} +// Spread of unknown causes result to be unknown +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 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 () { + function C1() { + } + return C1; +}()); diff --git a/tests/baselines/reference/unknownType1.symbols b/tests/baselines/reference/unknownType1.symbols new file mode 100644 index 0000000000000..c73308df51206 --- /dev/null +++ b/tests/baselines/reference/unknownType1.symbols @@ -0,0 +1,409 @@ +=== 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; // 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)) + +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)) + +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, 37, 24)) + +type T41 = keyof unknown; // never +>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, 42, 25)) +>x : Symbol(x, Decl(unknownType1.ts, 46, 13)) + + x == 5; +>x : Symbol(x, Decl(unknownType1.ts, 46, 13)) + + x !== 10; +>x : Symbol(x, Decl(unknownType1.ts, 46, 13)) + + x >= 0; // Error +>x : Symbol(x, Decl(unknownType1.ts, 46, 13)) + + x.foo; // Error +>x : Symbol(x, Decl(unknownType1.ts, 46, 13)) + + x[10]; // Error +>x : Symbol(x, Decl(unknownType1.ts, 46, 13)) + + x(); // Error +>x : Symbol(x, Decl(unknownType1.ts, 46, 13)) + + x + 1; // Error +>x : Symbol(x, Decl(unknownType1.ts, 46, 13)) + + x * 2; // Error +>x : Symbol(x, Decl(unknownType1.ts, 46, 13)) + + -x; // Error +>x : Symbol(x, Decl(unknownType1.ts, 46, 13)) + + +x; // Error +>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, 57, 1)) +>x : Symbol(x, Decl(unknownType1.ts, 61, 13)) + + x.foo; // Error +>x : Symbol(x, Decl(unknownType1.ts, 61, 13)) + + x[5]; // Error +>x : Symbol(x, Decl(unknownType1.ts, 61, 13)) + + x(); // Error +>x : Symbol(x, Decl(unknownType1.ts, 61, 13)) + + new x(); // Error +>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, 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, 70, 55)) +>x : Symbol(x, Decl(unknownType1.ts, 72, 13)) + + if (typeof x === "string" || typeof x === "number") { +>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, 72, 13)) + } + if (x instanceof Error) { +>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, 72, 13)) + } + if (isFunction(x)) { +>isFunction : Symbol(isFunction, Decl(unknownType1.ts, 66, 1)) +>x : Symbol(x, Decl(unknownType1.ts, 72, 13)) + + x; // Function +>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, 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, 86, 41)) +>T50 : Symbol(T50, Decl(unknownType1.ts, 82, 1)) + +type T52 = T50; // {} +>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, 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, 93, 7)) + + x = 123; +>x : Symbol(x, Decl(unknownType1.ts, 93, 7)) + + x = "hello"; +>x : Symbol(x, Decl(unknownType1.ts, 93, 7)) + + x = [1, 2, 3]; +>x : Symbol(x, Decl(unknownType1.ts, 93, 7)) + + x = new Error(); +>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, 93, 7)) +>x : Symbol(x, Decl(unknownType1.ts, 93, 7)) + + x = pAny; +>x : Symbol(x, Decl(unknownType1.ts, 93, 7)) +>pAny : Symbol(pAny, Decl(unknownType1.ts, 92, 16)) + + x = pNever; +>x : Symbol(x, Decl(unknownType1.ts, 93, 7)) +>pNever : Symbol(pNever, Decl(unknownType1.ts, 92, 26)) + + x = pT; +>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, 102, 1)) +>x : Symbol(x, Decl(unknownType1.ts, 106, 13)) + + let v1: any = x; +>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, 108, 7)) +>x : Symbol(x, Decl(unknownType1.ts, 106, 13)) + + let v3: object = x; // Error +>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, 110, 7)) +>x : Symbol(x, Decl(unknownType1.ts, 106, 13)) + + let v5: string[] = x; // Error +>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, 112, 7)) +>x : Symbol(x, Decl(unknownType1.ts, 106, 13)) + + let v7: {} | null | undefined = x; // Error +>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, 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, 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, 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, 124, 13)) + + x = { a: 5 }; +>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, 124, 13)) + + x = 123; // Error +>x : Symbol(x, Decl(unknownType1.ts, 124, 13)) +} + +// Locals of type unknown always considered initialized + +function f25() { +>f25 : Symbol(f25, Decl(unknownType1.ts, 129, 1)) + + let x: unknown; +>x : Symbol(x, Decl(unknownType1.ts, 134, 7)) + + let y = x; +>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, 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, 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, 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, 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, 144, 1)) +} + +// Rest type cannot be created from unknown + +function f28(x: unknown) { +>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, 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, 155, 1)) + + a: string; // Error +>a : Symbol(C1.a, Decl(unknownType1.ts, 159, 10)) + + b: unknown; +>b : Symbol(C1.b, Decl(unknownType1.ts, 160, 14)) + + c: any; +>c : Symbol(C1.c, Decl(unknownType1.ts, 161, 15)) +} + diff --git a/tests/baselines/reference/unknownType1.types b/tests/baselines/reference/unknownType1.types new file mode 100644 index 0000000000000..41c969bc95e4d --- /dev/null +++ b/tests/baselines/reference/unknownType1.types @@ -0,0 +1,488 @@ +=== 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; // Deferred (so it distributes) +>T31 : T31 +>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 + +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 +>T40 : string | number | symbol + +type T41 = keyof unknown; // never +>T41 : never + +// 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; +>isFunction : (x: unknown) => x is Function +>x : unknown +>x : any +>Function : Function + +function f20(x: unknown) { +>f20 : (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 (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; // {} +>T52 : T50 +>T50 : T50 + +// Anything is assignable to unknown + +function f21(pAny: any, pNever: never, pT: T) { +>f21 : (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 f22(x: unknown) { +>f22 : (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 f23(x: T) { +>f23 : (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 f24(x: { [x: string]: unknown }) { +>f24 : (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 f25() { +>f25 : () => void + + let x: unknown; +>x : unknown + + let y = x; +>y : unknown +>x : unknown +} + +// Spread of unknown causes result to be unknown + +function f26(x: {}, y: unknown, z: any) { +>f26 : (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 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 + +class C1 { +>C1 : C1 + + a: string; // Error +>a : string + + b: unknown; +>b : unknown + + c: any; +>c : any +} + diff --git a/tests/cases/conformance/types/unknown/unknownType1.ts b/tests/cases/conformance/types/unknown/unknownType1.ts new file mode 100644 index 0000000000000..3307f5c44810f --- /dev/null +++ b/tests/cases/conformance/types/unknown/unknownType1.ts @@ -0,0 +1,166 @@ +// @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; // 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 +type T41 = keyof unknown; // never + +// 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 f20(x: unknown) { + if (typeof x === "string" || typeof x === "number") { + x; // string | number + } + 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; // {} + +// Anything is assignable to unknown + +function f21(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 f22(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 f23(x: T) { + let y: object = x; // Error +} + +// Anything but primitive assignable to { [x: string]: unknown } + +function f24(x: { [x: string]: unknown }) { + x = {}; + x = { a: 5 }; + x = [1, 2, 3]; + x = 123; // Error +} + +// Locals of type unknown always considered initialized + +function f25() { + let x: unknown; + let y = x; +} + +// Spread of unknown causes result to be unknown + +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 +} + +// Functions with unknown return type don't need return expressions + +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 + +class C1 { + a: string; // Error + b: unknown; + c: any; +}