From 913e68b503283375d26fda8c5b2aac548d842384 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Wed, 6 Jul 2022 15:57:27 -0700 Subject: [PATCH 01/24] Parsing for per-file options, WIP WIP 2 Less WIP - Only exactOptionalPropertyTypes and strictNullChecks left Pragmas are case-insensitive Fix harness types Fixup baselines File-local support for exactOptionalPropertyTypes Fix lints Cache getSourceFileOfNode within the checker --- src/compiler/binder.ts | 2 +- src/compiler/checker.ts | 284 ++++++++++-------- src/compiler/commandLineParser.ts | 208 ++++++++++--- src/compiler/core.ts | 6 +- src/compiler/parser.ts | 46 ++- src/compiler/program.ts | 12 +- src/compiler/transformers/module/module.ts | 2 +- src/compiler/transformers/module/system.ts | 2 +- src/compiler/transformers/ts.ts | 2 +- src/compiler/transformers/typeSerializer.ts | 3 +- src/compiler/tsbuildPublic.ts | 2 +- src/compiler/types.ts | 57 +--- src/compiler/utilities.ts | 19 +- src/executeCommandLine/executeCommandLine.ts | 2 +- src/harness/harnessIO.ts | 28 +- src/server/editorServices.ts | 2 +- src/services/transpile.ts | 2 +- ...eralsContextuallyTypedFromUnion.errors.txt | 31 -- ...dexTypesNoConstraintElaboration.errors.txt | 5 +- ...SpreadOverwritesAttributeStrict.errors.txt | 2 - .../declarationDir-is-specified.js | 12 +- ...-outDir-and-declarationDir-is-specified.js | 12 +- .../when-outDir-is-specified.js | 12 +- .../with-outFile.js | 12 +- ...e-is-specified-with-declaration-enabled.js | 12 +- .../without-outDir-or-outFile-is-specified.js | 12 +- 26 files changed, 442 insertions(+), 347 deletions(-) delete mode 100644 tests/baselines/reference/booleanLiteralsContextuallyTypedFromUnion.errors.txt diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 6ffe3a7ef526e..a5bb023ac0798 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -285,7 +285,7 @@ namespace ts { return bindSourceFile; function bindInStrictMode(file: SourceFile, opts: CompilerOptions): boolean { - if (getStrictOptionValue(opts, "alwaysStrict") && !file.isDeclarationFile) { + if (getStrictOptionValue(file, opts, "alwaysStrict") && !file.isDeclarationFile) { // bind in strict mode source files with alwaysStrict option return true; } diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 8472c8b38e7e5..07e11b75eea24 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -359,16 +359,16 @@ namespace ts { const moduleKind = getEmitModuleKind(compilerOptions); const useDefineForClassFields = getUseDefineForClassFields(compilerOptions); const allowSyntheticDefaultImports = getAllowSyntheticDefaultImports(compilerOptions); - const strictNullChecks = getStrictOptionValue(compilerOptions, "strictNullChecks"); - const strictFunctionTypes = getStrictOptionValue(compilerOptions, "strictFunctionTypes"); - const strictBindCallApply = getStrictOptionValue(compilerOptions, "strictBindCallApply"); - const strictPropertyInitialization = getStrictOptionValue(compilerOptions, "strictPropertyInitialization"); - const noImplicitAny = getStrictOptionValue(compilerOptions, "noImplicitAny"); - const noImplicitThis = getStrictOptionValue(compilerOptions, "noImplicitThis"); - const useUnknownInCatchVariables = getStrictOptionValue(compilerOptions, "useUnknownInCatchVariables"); + const strictNullChecks = getStrictOptionValue(/*file*/ undefined, compilerOptions, "strictNullChecks"); // TODO: file-local-ness + const strictFunctionTypes = (file: SourceFile | undefined) => getStrictOptionValue(file, compilerOptions, "strictFunctionTypes"); + const strictBindCallApply = (file: SourceFile | undefined) => getStrictOptionValue(file, compilerOptions, "strictBindCallApply"); + const strictPropertyInitialization = (file: SourceFile) => getStrictOptionValue(file, compilerOptions, "strictPropertyInitialization"); + const noImplicitAny = (context: Node | undefined) => getStrictOptionValue(context && getSourceFileOfNode(context), compilerOptions, "noImplicitAny"); + const noImplicitThis = (file: SourceFile) => getStrictOptionValue(file, compilerOptions, "noImplicitThis"); + const useUnknownInCatchVariables = (file: SourceFile) => getStrictOptionValue(file, compilerOptions, "useUnknownInCatchVariables"); const keyofStringsOnly = !!compilerOptions.keyofStringsOnly; const freshObjectLiteralFlag = compilerOptions.suppressExcessPropertyErrors ? 0 : ObjectFlags.FreshLiteral; - const exactOptionalPropertyTypes = compilerOptions.exactOptionalPropertyTypes; + const exactOptionalPropertyTypes = (context: Node | undefined) => getFileLocalCompilerOption(context && getSourceFileOfNode(context), compilerOptions, "exactOptionalPropertyTypes"); const checkBinaryExpression = createCheckBinaryExpression(); const emitResolver = createResolver(); @@ -699,7 +699,7 @@ namespace ts { diagnostics = addRange(diagnostics, suggestionDiagnostics.getDiagnostics(file.fileName)); checkUnusedIdentifiers(getPotentiallyUnusedIdentifiers(file), (containingNode, kind, diag) => { - if (!containsParseError(containingNode) && !unusedIsError(kind, !!(containingNode.flags & NodeFlags.Ambient))) { + if (!containsParseError(containingNode) && !unusedIsError(kind, !!(containingNode.flags & NodeFlags.Ambient), file)) { (diagnostics || (diagnostics = [])).push({ ...diag, category: DiagnosticCategory.Suggestion }); } }); @@ -795,7 +795,8 @@ namespace ts { const undefinedType = createIntrinsicType(TypeFlags.Undefined, "undefined"); const undefinedWideningType = strictNullChecks ? undefinedType : createIntrinsicType(TypeFlags.Undefined, "undefined", ObjectFlags.ContainsWideningType); const optionalType = createIntrinsicType(TypeFlags.Undefined, "undefined"); - const missingType = exactOptionalPropertyTypes ? createIntrinsicType(TypeFlags.Undefined, "undefined") : undefinedType; + const missingType = createIntrinsicType(TypeFlags.Undefined, "undefined"); + const getMissingOrUndefinedType = (context: Node | undefined) => exactOptionalPropertyTypes(context) ? missingType : undefinedType; const nullType = createIntrinsicType(TypeFlags.Null, "null"); const nullWideningType = strictNullChecks ? nullType : createIntrinsicType(TypeFlags.Null, "null", ObjectFlags.ContainsWideningType); const stringType = createIntrinsicType(TypeFlags.String, "string"); @@ -951,8 +952,8 @@ namespace ts { let globalObjectType: ObjectType; let globalFunctionType: ObjectType; - let globalCallableFunctionType: ObjectType; - let globalNewableFunctionType: ObjectType; + let globalCallableFunctionType: (file: SourceFile | undefined) => ObjectType; + let globalNewableFunctionType: (file: SourceFile | undefined) => ObjectType; let globalArrayType: GenericType; let globalReadonlyArrayType: GenericType; let globalStringType: ObjectType; @@ -1072,6 +1073,17 @@ namespace ts { return checker; + function getSourceFileOfNode(node: Node): SourceFile; + function getSourceFileOfNode(node: Node | undefined): SourceFile | undefined; + function getSourceFileOfNode(node: Node | undefined) { + if (!node) return node; + const links = getNodeLinks(node); + if (!hasProperty(links, "sourceFile")) { + links.sourceFile = ts.getSourceFileOfNode(node); + } + return links.sourceFile; + } + function getCachedType(key: string | undefined) { return key ? cachedTypes.get(key) : undefined; } @@ -3596,7 +3608,7 @@ namespace ts { (isLiteralImportTypeNode(location) ? location : undefined)?.argument.literal; const mode = contextSpecifier && isStringLiteralLike(contextSpecifier) ? getModeForUsageLocation(currentSourceFile, contextSpecifier) : currentSourceFile.impliedNodeFormat; const resolvedModule = getResolvedModule(currentSourceFile, moduleReference, mode); - const resolutionDiagnostic = resolvedModule && getResolutionDiagnostic(compilerOptions, resolvedModule); + const resolutionDiagnostic = resolvedModule && getResolutionDiagnostic(currentSourceFile, compilerOptions, resolvedModule); const sourceFile = resolvedModule && (!resolutionDiagnostic || resolutionDiagnostic === Diagnostics.Module_0_was_resolved_to_1_but_jsx_is_not_set) && host.getSourceFile(resolvedModule.resolvedFileName); @@ -3695,7 +3707,7 @@ namespace ts { error(errorNode, diag, moduleReference, resolvedModule!.resolvedFileName); } else { - errorOnImplicitAnyModule(/*isError*/ noImplicitAny && !!moduleNotFoundError, errorNode, resolvedModule!, moduleReference); + errorOnImplicitAnyModule(/*isError*/ noImplicitAny(errorNode) && !!moduleNotFoundError, errorNode, resolvedModule!, moduleReference); } // Failed imports and untyped modules are both treated in an untyped manner; only difference is whether we give a diagnostic first. return undefined; @@ -9031,7 +9043,7 @@ namespace ts { return expr.kind === SyntaxKind.ArrayLiteralExpression && (expr as ArrayLiteralExpression).elements.length === 0; } - function addOptionality(type: Type, isProperty = false, isOptional = true): Type { + function addOptionality(type: Type, isProperty: Node | undefined = undefined, isOptional = true): Type { return strictNullChecks && isOptional ? getOptionalType(type, isProperty) : type; } @@ -9070,10 +9082,10 @@ namespace ts { // Use type from type annotation if one is present const declaredType = tryGetTypeFromEffectiveTypeNode(declaration); if (declaredType) { - return addOptionality(declaredType, isProperty, isOptional); + return addOptionality(declaredType, isProperty ? declaration : undefined, isOptional); } - if ((noImplicitAny || isInJSFile(declaration)) && + if ((noImplicitAny(declaration) || isInJSFile(declaration)) && isVariableDeclaration(declaration) && !isBindingPattern(declaration.name) && !(getCombinedModifierFlags(declaration) & ModifierFlags.Export) && !(declaration.flags & NodeFlags.Ambient)) { // If --noImplicitAny is on or the declaration is in a Javascript file, @@ -9110,7 +9122,7 @@ namespace ts { // Use contextual parameter type if one is available const type = declaration.symbol.escapedName === InternalSymbolName.This ? getContextualThisParameterType(func) : getContextuallyTypedParameterType(declaration); if (type) { - return addOptionality(type, /*isProperty*/ false, isOptional); + return addOptionality(type, /*isProperty*/ undefined, isOptional); } } @@ -9124,10 +9136,10 @@ namespace ts { } } const type = widenTypeInferredFromInitializer(declaration, checkDeclarationInitializer(declaration, checkMode)); - return addOptionality(type, isProperty, isOptional); + return addOptionality(type, isProperty ? declaration : undefined, isOptional); } - if (isPropertyDeclaration(declaration) && (noImplicitAny || isInJSFile(declaration))) { + if (isPropertyDeclaration(declaration) && (noImplicitAny(declaration) || isInJSFile(declaration))) { // We have a property declaration with no type annotation or initializer, in noImplicitAny mode or a .js file. // Use control flow analysis of this.xxx assignments in the constructor or static block to determine the type of the property. if (!hasStaticModifier(declaration)) { @@ -9135,14 +9147,14 @@ namespace ts { const type = constructor ? getFlowTypeInConstructor(declaration.symbol, constructor) : getEffectiveModifierFlags(declaration) & ModifierFlags.Ambient ? getTypeOfPropertyInBaseClass(declaration.symbol) : undefined; - return type && addOptionality(type, /*isProperty*/ true, isOptional); + return type && addOptionality(type, declaration, isOptional); } else { const staticBlocks = filter(declaration.parent.members, isClassStaticBlockDeclaration); const type = staticBlocks.length ? getFlowTypeInStaticBlocks(declaration.symbol, staticBlocks) : getEffectiveModifierFlags(declaration) & ModifierFlags.Ambient ? getTypeOfPropertyInBaseClass(declaration.symbol) : undefined; - return type && addOptionality(type, /*isProperty*/ true, isOptional); + return type && addOptionality(type, declaration, isOptional); } } @@ -9186,7 +9198,7 @@ namespace ts { // noImplicitAny mode or a .js file. const declaration = symbol.valueDeclaration; return declaration && isPropertyDeclaration(declaration) && !getEffectiveTypeAnnotationNode(declaration) && - !declaration.initializer && (noImplicitAny || isInJSFile(declaration)); + !declaration.initializer && (noImplicitAny(declaration) || isInJSFile(declaration)); } function getDeclaringConstructor(symbol: Symbol) { @@ -9228,7 +9240,7 @@ namespace ts { setParent(reference, staticBlock); reference.flowNode = staticBlock.returnFlowNode; const flowType = getFlowTypeOfProperty(reference, symbol); - if (noImplicitAny && (flowType === autoType || flowType === autoArrayType)) { + if (noImplicitAny(reference) && (flowType === autoType || flowType === autoArrayType)) { error(symbol.valueDeclaration, Diagnostics.Member_0_implicitly_has_an_1_type, symbolToString(symbol), typeToString(flowType)); } // We don't infer a type if assignments are only null or undefined. @@ -9248,7 +9260,7 @@ namespace ts { setParent(reference, constructor); reference.flowNode = constructor.returnFlowNode; const flowType = getFlowTypeOfProperty(reference, symbol); - if (noImplicitAny && (flowType === autoType || flowType === autoArrayType)) { + if (noImplicitAny(reference) && (flowType === autoType || flowType === autoArrayType)) { error(symbol.valueDeclaration, Diagnostics.Member_0_implicitly_has_an_1_type, symbolToString(symbol), typeToString(flowType)); } // We don't infer a type if assignments are only null or undefined. @@ -9331,7 +9343,7 @@ namespace ts { type = getUnionType(sourceTypes!); } } - const widened = getWidenedType(addOptionality(type, /*isProperty*/ false, definedInMethod && !definedInConstructor)); + const widened = getWidenedType(addOptionality(type, /*isProperty*/ undefined, definedInMethod && !definedInConstructor)); if (symbol.valueDeclaration && filterType(widened, t => !!(t.flags & ~TypeFlags.Nullable)) === neverType) { reportImplicitAny(symbol.valueDeclaration, anyType); return anyType; @@ -9712,7 +9724,7 @@ namespace ts { if (isCatchClauseVariableDeclarationOrBindingElement(declaration)) { const typeNode = getEffectiveTypeAnnotationNode(declaration); if (typeNode === undefined) { - return useUnknownInCatchVariables ? unknownType : anyType; + return useUnknownInCatchVariables(getSourceFileOfNode(declaration)) ? unknownType : anyType; } const type = getTypeOfNode(typeNode); // an errorType will make `checkTryStatement` issue an error @@ -9853,10 +9865,10 @@ namespace ts { getter && getter.body && getReturnTypeFromBody(getter); if (!type) { if (setter && !isPrivateWithinAmbient(setter)) { - errorOrSuggestion(noImplicitAny, setter, Diagnostics.Property_0_implicitly_has_type_any_because_its_set_accessor_lacks_a_parameter_type_annotation, symbolToString(symbol)); + errorOrSuggestion(noImplicitAny(setter), setter, Diagnostics.Property_0_implicitly_has_type_any_because_its_set_accessor_lacks_a_parameter_type_annotation, symbolToString(symbol)); } else if (getter && !isPrivateWithinAmbient(getter)) { - errorOrSuggestion(noImplicitAny, getter, Diagnostics.Property_0_implicitly_has_type_any_because_its_get_accessor_lacks_a_return_type_annotation, symbolToString(symbol)); + errorOrSuggestion(noImplicitAny(getter), getter, Diagnostics.Property_0_implicitly_has_type_any_because_its_get_accessor_lacks_a_return_type_annotation, symbolToString(symbol)); } type = anyType; } @@ -9867,7 +9879,7 @@ namespace ts { else if (getAnnotatedAccessorTypeNode(setter)) { error(setter, Diagnostics._0_is_referenced_directly_or_indirectly_in_its_own_type_annotation, symbolToString(symbol)); } - else if (getter && noImplicitAny) { + else if (getter && noImplicitAny(getter)) { error(getter, Diagnostics._0_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_referenced_directly_or_indirectly_in_one_of_its_return_expressions, symbolToString(symbol)); } type = anyType; @@ -9999,7 +10011,7 @@ namespace ts { return errorType; } // Check if variable has initializer that circularly references the variable itself - if (noImplicitAny && (declaration.kind !== SyntaxKind.Parameter || (declaration as HasInitializer).initializer)) { + if (noImplicitAny(declaration) && (declaration.kind !== SyntaxKind.Parameter || (declaration as HasInitializer).initializer)) { error(symbol.valueDeclaration, Diagnostics._0_implicitly_has_type_any_because_it_does_not_have_a_type_annotation_and_is_referenced_directly_or_indirectly_in_its_own_initializer, symbolToString(symbol)); } @@ -11871,8 +11883,8 @@ namespace ts { // When creating an optional property in strictNullChecks mode, if 'undefined' isn't assignable to the // type, we include 'undefined' in the type. Similarly, when creating a non-optional property in strictNullChecks // mode, if the underlying property is optional we remove 'undefined' from the type. - let type = strictNullChecks && symbol.flags & SymbolFlags.Optional && !maybeTypeOfKind(propType, TypeFlags.Undefined | TypeFlags.Void) ? getOptionalType(propType, /*isProperty*/ true) : - symbol.checkFlags & CheckFlags.StripOptional ? removeMissingOrUndefinedType(propType) : + let type = strictNullChecks && symbol.flags & SymbolFlags.Optional && !maybeTypeOfKind(propType, TypeFlags.Undefined | TypeFlags.Void) ? getOptionalType(propType, mappedType.declaration) : + symbol.checkFlags & CheckFlags.StripOptional ? removeMissingOrUndefinedType(propType, mappedType.declaration) : propType; if (!popTypeResolution()) { error(currentNode, Diagnostics.Type_of_property_0_circularly_references_itself_in_mapped_type_1, symbolToString(symbol), typeToString(mappedType)); @@ -11902,7 +11914,7 @@ namespace ts { function getTemplateTypeFromMappedType(type: MappedType) { return type.templateType || (type.templateType = type.declaration.type ? - instantiateType(addOptionality(getTypeFromTypeNode(type.declaration.type), /*isProperty*/ true, !!(getMappedTypeModifiers(type) & MappedTypeModifiers.IncludeOptional)), type.mapper) : + instantiateType(addOptionality(getTypeFromTypeNode(type.declaration.type), type.declaration, !!(getMappedTypeModifiers(type) & MappedTypeModifiers.IncludeOptional)), type.mapper) : errorType); } @@ -12722,9 +12734,10 @@ namespace ts { return symbol; } if (skipObjectFunctionPropertyAugment) return undefined; + const file = symbol?.valueDeclaration && getSourceFileOfNode(symbol.valueDeclaration); const functionType = resolved === anyFunctionType ? globalFunctionType : - resolved.callSignatures.length ? globalCallableFunctionType : - resolved.constructSignatures.length ? globalNewableFunctionType : + resolved.callSignatures.length ? globalCallableFunctionType(file) : + resolved.constructSignatures.length ? globalNewableFunctionType(file) : undefined; if (functionType) { const symbol = getPropertyOfObjectType(functionType, name); @@ -13246,7 +13259,7 @@ namespace ts { if (typeNode) { error(typeNode, Diagnostics.Return_type_annotation_circularly_references_itself); } - else if (noImplicitAny) { + else if (noImplicitAny(signature.declaration)) { const declaration = signature.declaration as Declaration; const name = getNameOfDeclaration(declaration); if (name) { @@ -13682,7 +13695,7 @@ namespace ts { const numTypeArguments = length(node.typeArguments); const minTypeArgumentCount = getMinTypeArgumentCount(typeParameters); const isJs = isInJSFile(node); - const isJsImplicitAny = !noImplicitAny && isJs; + const isJsImplicitAny = !noImplicitAny(node) && isJs; if (!isJsImplicitAny && (numTypeArguments < minTypeArgumentCount || numTypeArguments > typeParameters.length)) { const missingAugmentsTag = isJs && isExpressionWithTypeArguments(node) && !isJSDocAugmentsTag(node.parent); const diag = minTypeArgumentCount === typeParameters.length ? @@ -13983,9 +13996,9 @@ namespace ts { checkNoTypeArguments(node); return globalFunctionType; case "array": - return (!typeArgs || !typeArgs.length) && !noImplicitAny ? anyArrayType : undefined; + return (!typeArgs || !typeArgs.length) && !noImplicitAny(node) ? anyArrayType : undefined; case "promise": - return (!typeArgs || !typeArgs.length) && !noImplicitAny ? createPromiseType(anyType) : undefined; + return (!typeArgs || !typeArgs.length) && !noImplicitAny(node) ? createPromiseType(anyType) : undefined; case "Object": if (typeArgs && typeArgs.length === 2) { if (isJSDocIndexSignature(node)) { @@ -13997,7 +14010,7 @@ namespace ts { return anyType; } checkNoTypeArguments(node); - return !noImplicitAny ? anyType : undefined; + return !noImplicitAny(node) ? anyType : undefined; } } } @@ -14603,7 +14616,7 @@ namespace ts { } function getTypeFromOptionalTypeNode(node: OptionalTypeNode): Type { - return addOptionality(getTypeFromTypeNode(node.type), /*isProperty*/ true); + return addOptionality(getTypeFromTypeNode(node.type), node); } function getTypeId(type: Type): TypeId { @@ -14801,7 +14814,7 @@ namespace ts { includes & TypeFlags.IncludesWildcard ? wildcardType : anyType : includes & TypeFlags.Null || containsType(typeSet, unknownType) ? unknownType : nonNullUnknownType; } - if (exactOptionalPropertyTypes && includes & TypeFlags.Undefined) { + if (includes & TypeFlags.Undefined) { const missingIndex = binarySearch(typeSet, missingType, getTypeId, compareValues); if (missingIndex >= 0 && containsType(typeSet, undefinedType)) { orderedRemoveItemAt(typeSet, missingIndex); @@ -14945,7 +14958,7 @@ namespace ts { if (type === wildcardType) includes |= TypeFlags.IncludesWildcard; } else if (strictNullChecks || !(flags & TypeFlags.Nullable)) { - if (exactOptionalPropertyTypes && type === missingType) { + if (type === missingType) { includes |= TypeFlags.IncludesMissingType; type = undefinedType; } @@ -15169,7 +15182,7 @@ namespace ts { result = getIntersectionType(typeSet, aliasSymbol, aliasTypeArguments); } else if (eachIsUnionContaining(typeSet, TypeFlags.Undefined)) { - const undefinedOrMissingType = exactOptionalPropertyTypes && some(typeSet, t => containsType((t as UnionType).types, missingType)) ? missingType : undefinedType; + const undefinedOrMissingType = some(typeSet, t => containsType((t as UnionType).types, missingType)) ? missingType : undefinedType; removeFromEach(typeSet, TypeFlags.Undefined); result = getUnionType([getIntersectionType(typeSet), undefinedOrMissingType], UnionReduction.Literal, aliasSymbol, aliasTypeArguments); } @@ -15603,15 +15616,15 @@ namespace ts { * Should all count as literals and not print errors on access or assignment of possibly existing properties. * This mirrors the behavior of the index signature propagation, to which this behaves similarly (but doesn't affect assignability or inference). */ - function isJSLiteralType(type: Type): boolean { - if (noImplicitAny) { + function isJSLiteralType(type: Type, context?: Node): boolean { + if (noImplicitAny(getSourceFileOfNode(context))) { return false; // Flag is meaningless under `noImplicitAny` mode } if (getObjectFlags(type) & ObjectFlags.JSLiteral) { return true; } if (type.flags & TypeFlags.Union) { - return every((type as UnionType).types, isJSLiteralType); + return every((type as UnionType).types, t => isJSLiteralType(t)); } if (type.flags & TypeFlags.Intersection) { return some((type as IntersectionType).types, isJSLiteralType); @@ -15725,12 +15738,12 @@ namespace ts { if (indexType.flags & TypeFlags.Never) { return neverType; } - if (isJSLiteralType(objectType)) { + if (isJSLiteralType(objectType, accessNode)) { return anyType; } if (accessExpression && !isConstEnumObjectType(objectType)) { if (isObjectLiteralType(objectType)) { - if (noImplicitAny && indexType.flags & (TypeFlags.StringLiteral | TypeFlags.NumberLiteral)) { + if (noImplicitAny(accessNode) && indexType.flags & (TypeFlags.StringLiteral | TypeFlags.NumberLiteral)) { diagnostics.add(createDiagnosticForNode(accessExpression, Diagnostics.Property_0_does_not_exist_on_type_1, (indexType as StringLiteralType).value, typeToString(objectType))); return undefinedType; } @@ -15745,7 +15758,7 @@ namespace ts { if (objectType.symbol === globalThisSymbol && propName !== undefined && globalThisSymbol.exports!.has(propName) && (globalThisSymbol.exports!.get(propName)!.flags & SymbolFlags.BlockScoped)) { error(accessExpression, Diagnostics.Property_0_does_not_exist_on_type_1, unescapeLeadingUnderscores(propName), typeToString(objectType)); } - else if (noImplicitAny && !compilerOptions.suppressImplicitAnyIndexErrors && !(accessFlags & AccessFlags.SuppressNoImplicitAnyError)) { + else if (noImplicitAny(accessExpression) && !compilerOptions.suppressImplicitAnyIndexErrors && !(accessFlags & AccessFlags.SuppressNoImplicitAnyError)) { if (propName !== undefined && typeHasStaticProperty(propName, objectType)) { const typeName = typeToString(objectType); error(accessExpression, Diagnostics.Property_0_does_not_exist_on_type_1_Did_you_mean_to_access_the_static_member_2_instead, propName as string, typeName, typeName + "[" + getTextOfNode(accessExpression.argumentExpression) + "]"); @@ -15796,7 +15809,7 @@ namespace ts { return undefined; } } - if (isJSLiteralType(objectType)) { + if (isJSLiteralType(objectType, accessNode)) { return anyType; } if (accessNode) { @@ -16013,7 +16026,7 @@ namespace ts { } // In noUncheckedIndexedAccess mode, indexed access operations that occur in an expression in a read position and resolve to // an index signature have 'undefined' included in their type. - if (compilerOptions.noUncheckedIndexedAccess && accessFlags & AccessFlags.ExpressionPosition) accessFlags |= AccessFlags.IncludeUndefined; + if (getFileLocalCompilerOption(getSourceFileOfNode(accessNode), compilerOptions, "noUncheckedIndexedAccess") && accessFlags & AccessFlags.ExpressionPosition) accessFlags |= AccessFlags.IncludeUndefined; // If the index type is generic, or if the object type is generic and doesn't originate in an expression and // the operation isn't exclusively indexing the fixed (non-variadic) portion of a tuple type, we are performing // a higher-order index access where we cannot meaningfully access the properties of the object type. Note that @@ -16508,7 +16521,7 @@ namespace ts { const isSetonlyAccessor = prop.flags & SymbolFlags.SetAccessor && !(prop.flags & SymbolFlags.GetAccessor); const flags = SymbolFlags.Property | SymbolFlags.Optional; const result = createSymbol(flags, prop.escapedName, getIsLateCheckFlag(prop) | (readonly ? CheckFlags.Readonly : 0)); - result.type = isSetonlyAccessor ? undefinedType : addOptionality(getTypeOfSymbol(prop), /*isProperty*/ true); + result.type = isSetonlyAccessor ? undefinedType : addOptionality(getTypeOfSymbol(prop), prop.valueDeclaration || factory.createEmptyStatement()); result.declarations = prop.declarations; result.nameType = getSymbolLinks(prop).nameType; result.syntheticOrigin = prop; @@ -16596,7 +16609,7 @@ namespace ts { const declarations = concatenate(leftProp.declarations, rightProp.declarations); const flags = SymbolFlags.Property | (leftProp.flags & SymbolFlags.Optional); const result = createSymbol(flags, leftProp.escapedName); - result.type = getUnionType([getTypeOfSymbol(leftProp), removeMissingOrUndefinedType(rightType)], UnionReduction.Subtype); + result.type = getUnionType([getTypeOfSymbol(leftProp), removeMissingOrUndefinedType(rightType, rightProp.valueDeclaration)], UnionReduction.Subtype); result.leftSpread = leftProp; result.rightSpread = rightProp; result.declarations = declarations; @@ -16788,7 +16801,7 @@ namespace ts { const links = getNodeLinks(node); return links.resolvedType || (links.resolvedType = node.dotDotDotToken ? getTypeFromRestTypeNode(node) : - addOptionality(getTypeFromTypeNode(node.type), /*isProperty*/ true, !!node.questionToken)); + addOptionality(getTypeFromTypeNode(node.type), node, !!node.questionToken)); } function getTypeFromTypeNode(node: TypeNode): Type { @@ -16823,7 +16836,7 @@ namespace ts { case SyntaxKind.NeverKeyword: return neverType; case SyntaxKind.ObjectKeyword: - return node.flags & NodeFlags.JavaScriptFile && !noImplicitAny ? anyType : nonPrimitiveType; + return node.flags & NodeFlags.JavaScriptFile && !noImplicitAny(node) ? anyType : nonPrimitiveType; case SyntaxKind.IntrinsicKeyword: return intrinsicMarkerType; case SyntaxKind.ThisType: @@ -17277,7 +17290,7 @@ namespace ts { const templateMapper = appendTypeMapping(mapper, getTypeParameterFromMappedType(type), key); const propType = instantiateType(getTemplateTypeFromMappedType(type.target as MappedType || type), templateMapper); const modifiers = getMappedTypeModifiers(type); - return strictNullChecks && modifiers & MappedTypeModifiers.IncludeOptional && !maybeTypeOfKind(propType, TypeFlags.Undefined | TypeFlags.Void) ? getOptionalType(propType, /*isProperty*/ true) : + return strictNullChecks && modifiers & MappedTypeModifiers.IncludeOptional && !maybeTypeOfKind(propType, TypeFlags.Undefined | TypeFlags.Void) ? getOptionalType(propType, type.declaration) : strictNullChecks && modifiers & MappedTypeModifiers.ExcludeOptional && isOptional ? getTypeWithFacts(propType, TypeFacts.NEUndefined) : propType; } @@ -17819,7 +17832,7 @@ namespace ts { const resultObj: { errors?: Diagnostic[] } = errorOutputContainer || {}; // Use the expression type, if available const specificSource = next ? checkExpressionForMutableLocationWithContextualType(next, sourcePropType) : sourcePropType; - if (exactOptionalPropertyTypes && isExactOptionalPropertyMismatch(specificSource, targetPropType)) { + if (exactOptionalPropertyTypes(prop) && isExactOptionalPropertyMismatch(specificSource, targetPropType)) { const diag = createDiagnosticForNode(prop, Diagnostics.Type_0_is_not_assignable_to_type_1_with_exactOptionalPropertyTypes_Colon_true_Consider_adding_undefined_to_the_type_of_the_target, typeToString(specificSource), typeToString(targetPropType)); diagnostics.add(diag); resultObj.errors = [diag]; @@ -18144,7 +18157,10 @@ namespace ts { } const kind = target.declaration ? target.declaration.kind : SyntaxKind.Unknown; - const strictVariance = !(checkMode & SignatureCheckMode.Callback) && strictFunctionTypes && kind !== SyntaxKind.MethodDeclaration && + const sourceFile = source.declaration && getSourceFileOfNode(source.declaration); + const targetFile = target.declaration && getSourceFileOfNode(target.declaration); + const strictSignatureComparison = strictFunctionTypes(sourceFile) || strictFunctionTypes(targetFile); + const strictVariance = !(checkMode & SignatureCheckMode.Callback) && strictSignatureComparison && kind !== SyntaxKind.MethodDeclaration && kind !== SyntaxKind.MethodSignature && kind !== SyntaxKind.Constructor; let result = Ternary.True; @@ -18756,7 +18772,7 @@ namespace ts { else if (sourceType === targetType) { message = Diagnostics.Type_0_is_not_assignable_to_type_1_Two_different_types_with_this_name_exist_but_they_are_unrelated; } - else if (exactOptionalPropertyTypes && getExactOptionalUnassignableProperties(source, target).length) { + else if (getExactOptionalUnassignableProperties(source, target).length) { message = Diagnostics.Type_0_is_not_assignable_to_type_1_with_exactOptionalPropertyTypes_Colon_true_Consider_adding_undefined_to_the_types_of_the_target_s_properties; } else { @@ -18771,7 +18787,6 @@ namespace ts { } } else if (message === Diagnostics.Argument_of_type_0_is_not_assignable_to_parameter_of_type_1 - && exactOptionalPropertyTypes && getExactOptionalUnassignableProperties(source, target).length) { message = Diagnostics.Argument_of_type_0_is_not_assignable_to_parameter_of_type_1_with_exactOptionalPropertyTypes_Colon_true_Consider_adding_undefined_to_the_types_of_the_target_s_properties; } @@ -19055,7 +19070,9 @@ namespace ts { } function hasExcessProperties(source: FreshObjectLiteralType, target: Type, reportErrors: boolean): boolean { - if (!isExcessPropertyCheckTarget(target) || !noImplicitAny && getObjectFlags(target) & ObjectFlags.JSLiteral) { + const sourceNoImplicitAny = noImplicitAny(source.symbol?.valueDeclaration); + const targetNoImplicitAny = noImplicitAny(target.symbol?.valueDeclaration); + if (!isExcessPropertyCheckTarget(target) || !(sourceNoImplicitAny || targetNoImplicitAny) && getObjectFlags(target) & ObjectFlags.JSLiteral) { return false; // Disable excess property checks on JS literals to simulate having an implicit "index signature" - but only outside of noImplicitAny } const isComparingJsxAttributes = !!(getObjectFlags(source) & ObjectFlags.JsxAttributes); @@ -20205,7 +20222,7 @@ namespace ts { function isPropertySymbolTypeRelated(sourceProp: Symbol, targetProp: Symbol, getTypeOfSourceProperty: (sym: Symbol) => Type, reportErrors: boolean, intersectionState: IntersectionState): Ternary { const targetIsOptional = strictNullChecks && !!(getCheckFlags(targetProp) & CheckFlags.Partial); - const effectiveTarget = addOptionality(getNonMissingTypeOfSymbol(targetProp), /*isProperty*/ false, targetIsOptional); + const effectiveTarget = addOptionality(getNonMissingTypeOfSymbol(targetProp), /*isProperty*/ undefined, targetIsOptional); const effectiveSource = getTypeOfSourceProperty(sourceProp); return isRelatedTo(effectiveSource, effectiveTarget, RecursionFlags.Both, reportErrors, /*headMessage*/ undefined, intersectionState); } @@ -20659,7 +20676,7 @@ namespace ts { } if (isApplicableIndexType(getLiteralTypeFromProperty(prop, TypeFlags.StringOrNumberLiteralOrUnique), keyType)) { const propType = getNonMissingTypeOfSymbol(prop); - const type = exactOptionalPropertyTypes || propType.flags & TypeFlags.Undefined || keyType === numberType || !(prop.flags & SymbolFlags.Optional) + const type = exactOptionalPropertyTypes(prop.valueDeclaration) || propType.flags & TypeFlags.Undefined || keyType === numberType || !(prop.flags & SymbolFlags.Optional) ? propType : getTypeWithFacts(propType, TypeFacts.NEUndefined); const related = isRelatedTo(type, targetInfo.type, RecursionFlags.Both, reportErrors); @@ -21582,9 +21599,9 @@ namespace ts { getUnionType([type, undefinedType, nullType]); } - function getOptionalType(type: Type, isProperty = false): Type { + function getOptionalType(type: Type, property: Node | undefined = undefined): Type { Debug.assert(strictNullChecks); - return type.flags & TypeFlags.Undefined ? type : getUnionType([type, isProperty ? missingType : undefinedType]); + return type.flags & TypeFlags.Undefined ? type : getUnionType([type, property ? getMissingOrUndefinedType(property) : undefinedType]); } function getGlobalNonNullableTypeInstantiation(type: Type) { @@ -21619,15 +21636,15 @@ namespace ts { } function removeMissingType(type: Type, isOptional: boolean) { - return exactOptionalPropertyTypes && isOptional ? removeType(type, missingType) : type; + return isOptional ? removeType(type, missingType) : type; } function containsMissingType(type: Type) { - return exactOptionalPropertyTypes && (type === missingType || type.flags & TypeFlags.Union && containsType((type as UnionType).types, missingType)); + return (type === missingType || type.flags & TypeFlags.Union && containsType((type as UnionType).types, missingType)); } - function removeMissingOrUndefinedType(type: Type): Type { - return exactOptionalPropertyTypes ? removeType(type, missingType) : getTypeWithFacts(type, TypeFacts.NEUndefined); + function removeMissingOrUndefinedType(type: Type, context: Node | undefined): Type { + return exactOptionalPropertyTypes(context) ? removeType(type, missingType) : getTypeWithFacts(type, TypeFacts.NEUndefined); } /** @@ -21776,7 +21793,7 @@ namespace ts { if (cached) { return cached; } - const result = createSymbolWithType(prop, missingType); + const result = createSymbolWithType(prop, getMissingOrUndefinedType(prop.valueDeclaration)); result.flags |= SymbolFlags.Optional; undefinedProperties.set(prop.escapedName, result); return result; @@ -21897,7 +21914,7 @@ namespace ts { case SyntaxKind.BinaryExpression: case SyntaxKind.PropertyDeclaration: case SyntaxKind.PropertySignature: - diagnostic = noImplicitAny ? Diagnostics.Member_0_implicitly_has_an_1_type : Diagnostics.Member_0_implicitly_has_an_1_type_but_a_better_type_may_be_inferred_from_usage; + diagnostic = noImplicitAny(declaration) ? Diagnostics.Member_0_implicitly_has_an_1_type : Diagnostics.Member_0_implicitly_has_an_1_type_but_a_better_type_may_be_inferred_from_usage; break; case SyntaxKind.Parameter: const param = declaration as ParameterDeclaration; @@ -21908,16 +21925,16 @@ namespace ts { param.name.originalKeywordKind && isTypeNodeKind(param.name.originalKeywordKind))) { const newName = "arg" + param.parent.parameters.indexOf(param); const typeName = declarationNameToString(param.name) + (param.dotDotDotToken ? "[]" : ""); - errorOrSuggestion(noImplicitAny, declaration, Diagnostics.Parameter_has_a_name_but_no_type_Did_you_mean_0_Colon_1, newName, typeName); + errorOrSuggestion(noImplicitAny(declaration), declaration, Diagnostics.Parameter_has_a_name_but_no_type_Did_you_mean_0_Colon_1, newName, typeName); return; } diagnostic = (declaration as ParameterDeclaration).dotDotDotToken ? - noImplicitAny ? Diagnostics.Rest_parameter_0_implicitly_has_an_any_type : Diagnostics.Rest_parameter_0_implicitly_has_an_any_type_but_a_better_type_may_be_inferred_from_usage : - noImplicitAny ? Diagnostics.Parameter_0_implicitly_has_an_1_type : Diagnostics.Parameter_0_implicitly_has_an_1_type_but_a_better_type_may_be_inferred_from_usage; + noImplicitAny(declaration) ? Diagnostics.Rest_parameter_0_implicitly_has_an_any_type : Diagnostics.Rest_parameter_0_implicitly_has_an_any_type_but_a_better_type_may_be_inferred_from_usage : + noImplicitAny(declaration) ? Diagnostics.Parameter_0_implicitly_has_an_1_type : Diagnostics.Parameter_0_implicitly_has_an_1_type_but_a_better_type_may_be_inferred_from_usage; break; case SyntaxKind.BindingElement: diagnostic = Diagnostics.Binding_element_0_implicitly_has_an_1_type; - if (!noImplicitAny) { + if (!noImplicitAny(declaration)) { // Don't issue a suggestion for binding elements since the codefix doesn't yet support them. return; } @@ -21932,7 +21949,7 @@ namespace ts { case SyntaxKind.SetAccessor: case SyntaxKind.FunctionExpression: case SyntaxKind.ArrowFunction: - if (noImplicitAny && !(declaration as NamedDeclaration).name) { + if (noImplicitAny(declaration) && !(declaration as NamedDeclaration).name) { if (wideningKind === WideningKind.GeneratorYield) { error(declaration, Diagnostics.Generator_implicitly_has_yield_type_0_because_it_does_not_yield_any_values_Consider_supplying_a_return_type_annotation, typeAsString); } @@ -21941,24 +21958,24 @@ namespace ts { } return; } - diagnostic = !noImplicitAny ? Diagnostics._0_implicitly_has_an_1_return_type_but_a_better_type_may_be_inferred_from_usage : + diagnostic = !noImplicitAny(declaration) ? Diagnostics._0_implicitly_has_an_1_return_type_but_a_better_type_may_be_inferred_from_usage : wideningKind === WideningKind.GeneratorYield ? Diagnostics._0_which_lacks_return_type_annotation_implicitly_has_an_1_yield_type : Diagnostics._0_which_lacks_return_type_annotation_implicitly_has_an_1_return_type; break; case SyntaxKind.MappedType: - if (noImplicitAny) { + if (noImplicitAny(declaration)) { error(declaration, Diagnostics.Mapped_object_type_implicitly_has_an_any_template_type); } return; default: - diagnostic = noImplicitAny ? Diagnostics.Variable_0_implicitly_has_an_1_type : Diagnostics.Variable_0_implicitly_has_an_1_type_but_a_better_type_may_be_inferred_from_usage; + diagnostic = noImplicitAny(declaration) ? Diagnostics.Variable_0_implicitly_has_an_1_type : Diagnostics.Variable_0_implicitly_has_an_1_type_but_a_better_type_may_be_inferred_from_usage; } - errorOrSuggestion(noImplicitAny, declaration, diagnostic, declarationNameToString(getNameOfDeclaration(declaration)), typeAsString); + errorOrSuggestion(noImplicitAny(declaration), declaration, diagnostic, declarationNameToString(getNameOfDeclaration(declaration)), typeAsString); } function reportErrorsFromWidening(declaration: Declaration, type: Type, wideningKind?: WideningKind) { addLazyDiagnostic(() => { - if (noImplicitAny && getObjectFlags(type) & ObjectFlags.ContainsWideningType && (!wideningKind || !getContextualSignatureForFunctionLikeDeclaration(declaration as FunctionLikeDeclaration))) { + if (noImplicitAny(declaration) && getObjectFlags(type) & ObjectFlags.ContainsWideningType && (!wideningKind || !getContextualSignatureForFunctionLikeDeclaration(declaration as FunctionLikeDeclaration))) { // Report implicit any error within type if possible, otherwise report error on declaration if (!reportWideningErrorsInType(type)) { reportImplicitAny(declaration, type, wideningKind); @@ -22811,7 +22828,10 @@ namespace ts { } function inferFromContravariantTypesIfStrictFunctionTypes(source: Type, target: Type) { - if (strictFunctionTypes || priority & InferencePriority.AlwaysStrict) { + const sourceFile = source.symbol?.valueDeclaration && getSourceFileOfNode(source.symbol?.valueDeclaration); + const targetFile = target.symbol?.valueDeclaration && getSourceFileOfNode(target.symbol?.valueDeclaration); + const strictSignatureComparison = strictFunctionTypes(sourceFile) || strictFunctionTypes(targetFile); + if (strictSignatureComparison || priority & InferencePriority.AlwaysStrict) { inferFromContravariantTypes(source, target); } else { @@ -23186,7 +23206,7 @@ namespace ts { for (const prop of getPropertiesOfType(source)) { if (isApplicableIndexType(getLiteralTypeFromProperty(prop, TypeFlags.StringOrNumberLiteralOrUnique), targetInfo.keyType)) { const propType = getTypeOfSymbol(prop); - propTypes.push(prop.flags & SymbolFlags.Optional ? removeMissingOrUndefinedType(propType) : propType); + propTypes.push(prop.flags & SymbolFlags.Optional ? removeMissingOrUndefinedType(propType, prop.valueDeclaration) : propType); } } for (const info of getIndexInfosOfType(source)) { @@ -23209,7 +23229,7 @@ namespace ts { } function isTypeOrBaseIdenticalTo(s: Type, t: Type) { - return exactOptionalPropertyTypes && t === missingType ? s === t : + return t === missingType ? s === t : (isTypeIdenticalTo(s, t) || !!(t.flags & TypeFlags.String && s.flags & TypeFlags.StringLiteral || t.flags & TypeFlags.Number && s.flags & TypeFlags.NumberLiteral)); } @@ -23876,18 +23896,18 @@ namespace ts { const nameType = getLiteralTypeFromPropertyName(name); if (!isTypeUsableAsPropertyName(nameType)) return errorType; const text = getPropertyNameFromType(nameType); - return getTypeOfPropertyOfType(type, text) || includeUndefinedInIndexSignature(getApplicableIndexInfoForName(type, text)?.type) || errorType; + return getTypeOfPropertyOfType(type, text) || includeUndefinedInIndexSignature(getApplicableIndexInfoForName(type, text)?.type, type) || errorType; } function getTypeOfDestructuredArrayElement(type: Type, index: number) { return everyType(type, isTupleLikeType) && getTupleElementType(type, index) || - includeUndefinedInIndexSignature(checkIteratedTypeOrElementType(IterationUse.Destructuring, type, undefinedType, /*errorNode*/ undefined)) || + includeUndefinedInIndexSignature(checkIteratedTypeOrElementType(IterationUse.Destructuring, type, undefinedType, /*errorNode*/ undefined), type) || errorType; } - function includeUndefinedInIndexSignature(type: Type | undefined): Type | undefined { + function includeUndefinedInIndexSignature(type: Type | undefined, parentType: Type): Type | undefined { if (!type) return type; - return compilerOptions.noUncheckedIndexedAccess ? + return getFileLocalCompilerOption(getSourceFileOfNode(parentType.symbol?.valueDeclaration), compilerOptions, "noUncheckedIndexedAccess") ? getUnionType([type, undefinedType]) : type; } @@ -26080,7 +26100,7 @@ namespace ts { // control flow based type does include undefined. if (!isEvolvingArrayOperationTarget(node) && (type === autoType || type === autoArrayType)) { if (flowType === autoType || flowType === autoArrayType) { - if (noImplicitAny) { + if (noImplicitAny(node)) { error(getNameOfDeclaration(declaration), Diagnostics.Variable_0_implicitly_has_type_1_in_some_locations_where_its_type_cannot_be_determined, symbolToString(symbol), typeToString(flowType)); error(node, Diagnostics.Variable_0_implicitly_has_an_1_type, symbolToString(symbol), typeToString(flowType)); } @@ -26315,7 +26335,7 @@ namespace ts { } const type = tryGetThisTypeAt(node, /*includeGlobalThis*/ true, container); - if (noImplicitThis) { + if (noImplicitThis(getSourceFileOfNode(node))) { const globalThisType = getTypeOfSymbol(globalThisSymbol); if (type === globalThisType && capturedByArrowFunction) { error(node, Diagnostics.The_containing_arrow_function_captures_the_global_value_of_this); @@ -26717,7 +26737,7 @@ namespace ts { } } const inJs = isInJSFile(func); - if (noImplicitThis || inJs) { + if (noImplicitThis(getSourceFileOfNode(func)) || inJs) { const containingLiteral = getContainingObjectLiteral(func); if (containingLiteral) { // We have an object literal method. Check if the containing object literal has a contextual type @@ -27650,7 +27670,7 @@ namespace ts { } function getIntersectedSignatures(signatures: readonly Signature[]) { - return getStrictOptionValue(compilerOptions, "noImplicitAny") + return some(signatures, s => noImplicitAny(s.declaration)) ? reduceLeft( signatures, (left, right) => @@ -27881,7 +27901,7 @@ namespace ts { elementFlags.push(ElementFlags.Rest); } } - else if (exactOptionalPropertyTypes && e.kind === SyntaxKind.OmittedExpression) { + else if (exactOptionalPropertyTypes(e) && e.kind === SyntaxKind.OmittedExpression) { hasOmittedExpression = true; elementTypes.push(missingType); elementFlags.push(ElementFlags.Optional); @@ -27889,7 +27909,7 @@ namespace ts { else { const elementContextualType = getContextualTypeForElementExpression(contextualType, elementTypes.length); const type = checkExpressionForMutableLocation(e, checkMode, elementContextualType, forceTuple); - elementTypes.push(addOptionality(type, /*isProperty*/ true, hasOmittedExpression)); + elementTypes.push(addOptionality(type, e, hasOmittedExpression)); elementFlags.push(hasOmittedExpression ? ElementFlags.Optional : ElementFlags.Required); if (contextualType && someType(contextualType, isTupleLikeType) && checkMode && checkMode & CheckMode.Inferential && !(checkMode & CheckMode.SkipContextSensitive) && isContextSensitive(e)) { const inferenceContext = getInferenceContext(node); @@ -28526,7 +28546,7 @@ namespace ts { return links.resolvedSymbol = unknownSymbol; } else { - if (noImplicitAny) { + if (noImplicitAny(node)) { error(node, Diagnostics.JSX_element_implicitly_has_type_any_because_no_interface_JSX_0_exists, unescapeLeadingUnderscores(JsxNames.IntrinsicElements)); } return links.resolvedSymbol = unknownSymbol; @@ -28781,7 +28801,7 @@ namespace ts { } if (getJsxElementTypeAt(errorNode) === undefined) { - if (noImplicitAny) { + if (noImplicitAny(errorNode)) { error(errorNode, Diagnostics.JSX_element_implicitly_has_type_any_because_the_global_type_JSX_Element_does_not_exist); } } @@ -29362,14 +29382,14 @@ namespace ts { getApplicableIndexInfoForName(apparentType, right.escapedText) : undefined; if (!(indexInfo && indexInfo.type)) { const isUncheckedJS = isUncheckedJSSuggestion(node, leftType.symbol, /*excludeClasses*/ true); - if (!isUncheckedJS && isJSLiteralType(leftType)) { + if (!isUncheckedJS && isJSLiteralType(leftType, node)) { return anyType; } if (leftType.symbol === globalThisSymbol) { if (globalThisSymbol.exports!.has(right.escapedText) && (globalThisSymbol.exports!.get(right.escapedText)!.flags & SymbolFlags.BlockScoped)) { error(right, Diagnostics.Property_0_does_not_exist_on_type_1, unescapeLeadingUnderscores(right.escapedText), typeToString(leftType)); } - else if (noImplicitAny) { + else if (noImplicitAny(right)) { error(right, Diagnostics.Element_implicitly_has_an_any_type_because_type_0_has_no_index_signature, typeToString(leftType)); } return anyType; @@ -29383,8 +29403,8 @@ namespace ts { error(node, Diagnostics.Index_signature_in_type_0_only_permits_reading, typeToString(apparentType)); } - propType = (compilerOptions.noUncheckedIndexedAccess && !isAssignmentTarget(node)) ? getUnionType([indexInfo.type, undefinedType]) : indexInfo.type; - if (compilerOptions.noPropertyAccessFromIndexSignature && isPropertyAccessExpression(node)) { + propType = (getFileLocalCompilerOption(getSourceFileOfNode(node), compilerOptions, "noUncheckedIndexedAccess") && !isAssignmentTarget(node)) ? getUnionType([indexInfo.type, undefinedType]) : indexInfo.type; + if (getFileLocalCompilerOption(getSourceFileOfNode(node), compilerOptions, "noPropertyAccessFromIndexSignature") && isPropertyAccessExpression(node)) { error(right, Diagnostics.Property_0_comes_from_an_index_signature_so_it_must_be_accessed_with_0, unescapeLeadingUnderscores(right.escapedText)); } if (indexInfo.declaration && getCombinedNodeFlags(indexInfo.declaration) & NodeFlags.Deprecated) { @@ -29454,7 +29474,8 @@ namespace ts { // and if we are in a constructor of the same class as the property declaration, assume that // the property is uninitialized at the top of the control flow. let assumeUninitialized = false; - if (strictNullChecks && strictPropertyInitialization && isAccessExpression(node) && node.expression.kind === SyntaxKind.ThisKeyword) { + const file = getSourceFileOfNode(node); + if (strictNullChecks && strictPropertyInitialization(file) && isAccessExpression(node) && node.expression.kind === SyntaxKind.ThisKeyword) { const declaration = prop && prop.valueDeclaration; if (declaration && isPropertyWithoutInitializer(declaration)) { if (!isStatic(declaration)) { @@ -31497,7 +31518,7 @@ namespace ts { const callSignatures = getSignaturesOfType(expressionType, SignatureKind.Call); if (callSignatures.length) { const signature = resolveCall(node, callSignatures, candidatesOutArray, checkMode, SignatureFlags.None); - if (!noImplicitAny) { + if (!noImplicitAny(node)) { if (signature.declaration && !isJSConstructor(signature.declaration) && getReturnTypeOfSignature(signature) !== voidType) { error(node, Diagnostics.Only_a_void_function_can_be_called_with_the_new_keyword); } @@ -32059,7 +32080,7 @@ namespace ts { !isJSConstructor(declaration)) { // When resolved signature is a call signature (and not a construct signature) the result type is any - if (noImplicitAny) { + if (noImplicitAny(declaration)) { error(node, Diagnostics.new_expression_whose_target_lacks_a_construct_signature_implicitly_has_an_any_type); } return anyType; @@ -33148,7 +33169,7 @@ namespace ts { else if (type && strictNullChecks && !isTypeAssignableTo(undefinedType, type)) { error(errorNode, Diagnostics.Function_lacks_ending_return_statement_and_return_type_does_not_include_undefined); } - else if (compilerOptions.noImplicitReturns) { + else if (getFileLocalCompilerOption(getSourceFileOfNode(errorNode), compilerOptions, "noImplicitReturns")) { if (!type) { // If return type annotation is omitted check if function has any explicit return statements. // If it does not have any - its inferred return type is void - don't do any checks. @@ -33436,7 +33457,7 @@ namespace ts { const type = getTypeOfSymbol(symbol); if (strictNullChecks && !(type.flags & (TypeFlags.AnyOrUnknown | TypeFlags.Never)) && - !(exactOptionalPropertyTypes ? symbol.flags & SymbolFlags.Optional : getTypeFacts(type) & TypeFacts.IsUndefined)) { + !(exactOptionalPropertyTypes(expr) ? symbol.flags & SymbolFlags.Optional : getTypeFacts(type) & TypeFacts.IsUndefined)) { error(expr, Diagnostics.The_operand_of_a_delete_operator_must_be_optional); } } @@ -33816,7 +33837,7 @@ namespace ts { // 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 possiblyOutOfBoundsType = checkIteratedTypeOrElementType(IterationUse.Destructuring | IterationUse.PossiblyOutOfBounds, sourceType, undefinedType, node) || errorType; - let inBoundsType: Type | undefined = compilerOptions.noUncheckedIndexedAccess ? undefined: possiblyOutOfBoundsType; + let inBoundsType: Type | undefined = getFileLocalCompilerOption(getSourceFileOfNode(node), compilerOptions, "noUncheckedIndexedAccess") ? undefined: possiblyOutOfBoundsType; for (let i = 0; i < elements.length; i++) { let type = possiblyOutOfBoundsType; if (node.elements[i].kind === SyntaxKind.SpreadElement) { @@ -34467,7 +34488,7 @@ namespace ts { && (!isIdentifier(left) || unescapeLeadingUnderscores(left.escapedText) !== "exports")) { let headMessage: DiagnosticMessage | undefined; - if (exactOptionalPropertyTypes && isPropertyAccessExpression(left) && maybeTypeOfKind(valueType, TypeFlags.Undefined)) { + if (exactOptionalPropertyTypes(left) && isPropertyAccessExpression(left) && maybeTypeOfKind(valueType, TypeFlags.Undefined)) { const target = getTypeOfPropertyOfType(getTypeOfExpression(left.expression), left.name.escapedText); if (isExactOptionalPropertyMismatch(valueType, target)) { headMessage = Diagnostics.Type_0_is_not_assignable_to_type_1_with_exactOptionalPropertyTypes_Colon_true_Consider_adding_undefined_to_the_type_of_the_target; @@ -34626,7 +34647,7 @@ namespace ts { if (!type) { type = anyType; addLazyDiagnostic(() => { - if (noImplicitAny && !expressionResultIsUnused(node)) { + if (noImplicitAny(node) && !expressionResultIsUnused(node)) { const contextualType = getContextualType(node, /*contextFlags*/ undefined); if (!contextualType || isTypeAny(contextualType)) { error(node, Diagnostics.yield_expression_implicitly_results_in_an_any_type_because_its_containing_generator_lacks_a_return_type_annotation); @@ -35485,7 +35506,7 @@ namespace ts { function checkSignatureDeclarationDiagnostics() { checkCollisionWithArgumentsInGeneratedCode(node); const returnTypeNode = getEffectiveReturnTypeNode(node); - if (noImplicitAny && !returnTypeNode) { + if (noImplicitAny(node) && !returnTypeNode) { switch (node.kind) { case SyntaxKind.ConstructSignature: error(node, Diagnostics.Construct_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type); @@ -38677,7 +38698,7 @@ namespace ts { const uplevelIteration = languageVersion >= ScriptTarget.ES2015; const downlevelIteration = !uplevelIteration && compilerOptions.downlevelIteration; - const possibleOutOfBounds = compilerOptions.noUncheckedIndexedAccess && !!(use & IterationUse.PossiblyOutOfBounds); + const possibleOutOfBounds = getFileLocalCompilerOption(getSourceFileOfNode(errorNode), compilerOptions, "noUncheckedIndexedAccess") && !!(use & IterationUse.PossiblyOutOfBounds); // Get the iterated type of an `Iterable` or `IterableIterator` only in ES2015 // or higher, when inside of an async generator or for-await-if, or when @@ -38699,7 +38720,7 @@ namespace ts { } } if (iterationTypes || uplevelIteration) { - return possibleOutOfBounds ? includeUndefinedInIndexSignature(iterationTypes && iterationTypes.yieldType) : (iterationTypes && iterationTypes.yieldType); + return possibleOutOfBounds ? includeUndefinedInIndexSignature(iterationTypes && iterationTypes.yieldType, inputType) : (iterationTypes && iterationTypes.yieldType); } } @@ -38736,7 +38757,7 @@ namespace ts { // Now that we've removed all the StringLike types, if no constituents remain, then the entire // arrayOrStringType was a string. if (arrayType.flags & TypeFlags.Never) { - return possibleOutOfBounds ? includeUndefinedInIndexSignature(stringType) : stringType; + return possibleOutOfBounds ? includeUndefinedInIndexSignature(stringType, globalStringType) : stringType; } } } @@ -38756,20 +38777,20 @@ namespace ts { defaultDiagnostic, typeToString(arrayType)); } - return hasStringConstituent ? possibleOutOfBounds ? includeUndefinedInIndexSignature(stringType) : stringType : undefined; + return hasStringConstituent ? possibleOutOfBounds ? includeUndefinedInIndexSignature(stringType, globalStringType) : stringType : undefined; } const arrayElementType = getIndexTypeOfType(arrayType, numberType); if (hasStringConstituent && arrayElementType) { // This is just an optimization for the case where arrayOrStringType is string | string[] - if (arrayElementType.flags & TypeFlags.StringLike && !compilerOptions.noUncheckedIndexedAccess) { + if (arrayElementType.flags & TypeFlags.StringLike && !getFileLocalCompilerOption(getSourceFileOfNode(errorNode), compilerOptions, "noUncheckedIndexedAccess")) { return stringType; } return getUnionType(possibleOutOfBounds ? [arrayElementType, stringType, undefinedType] : [arrayElementType, stringType], UnionReduction.Subtype); } - return (use & IterationUse.PossiblyOutOfBounds) ? includeUndefinedInIndexSignature(arrayElementType) : arrayElementType; + return (use & IterationUse.PossiblyOutOfBounds) ? includeUndefinedInIndexSignature(arrayElementType, arrayType) : arrayElementType; function getIterationDiagnosticDetails(allowsStrings: boolean, downlevelIteration: boolean | undefined): [error: DiagnosticMessage, maybeMissingAwait: boolean] { if (downlevelIteration) { @@ -39535,7 +39556,7 @@ namespace ts { } } } - else if (container.kind !== SyntaxKind.Constructor && compilerOptions.noImplicitReturns && !isUnwrappedReturnTypeVoidOrAny(container, returnType)) { + else if (container.kind !== SyntaxKind.Constructor && getFileLocalCompilerOption(getSourceFileOfNode(node), compilerOptions, "noImplicitReturns") && !isUnwrappedReturnTypeVoidOrAny(container, returnType)) { // The function has a return type, but the return statement doesn't have an expression. error(node, Diagnostics.Not_all_code_paths_return_a_value); } @@ -39584,7 +39605,7 @@ namespace ts { addLazyDiagnostic(createLazyCaseClauseDiagnostics(clause)); } forEach(clause.statements, checkSourceElement); - if (compilerOptions.noFallthroughCasesInSwitch && clause.fallthroughFlowNode && isReachableFlowNode(clause.fallthroughFlowNode)) { + if (getFileLocalCompilerOption(getSourceFileOfNode(clause), compilerOptions, "noFallthroughCasesInSwitch") && clause.fallthroughFlowNode && isReachableFlowNode(clause.fallthroughFlowNode)) { error(clause, Diagnostics.Fallthrough_case_in_switch); } @@ -40202,7 +40223,7 @@ namespace ts { ): MemberOverrideStatus { const isJs = isInJSFile(node); const nodeInAmbientContext = !!(node.flags & NodeFlags.Ambient); - if (baseWithThis && (memberHasOverrideModifier || compilerOptions.noImplicitOverride)) { + if (baseWithThis && (memberHasOverrideModifier || getFileLocalCompilerOption(getSourceFileOfNode(node), compilerOptions, "noImplicitOverride"))) { const memberEscapedName = escapeLeadingUnderscores(memberName); const thisType = memberIsStatic ? staticType : typeWithThis; const baseType = memberIsStatic ? baseStaticType : baseWithThis; @@ -40230,7 +40251,7 @@ namespace ts { } return MemberOverrideStatus.HasInvalidOverride; } - else if (prop && baseProp?.declarations && compilerOptions.noImplicitOverride && !nodeInAmbientContext) { + else if (prop && baseProp?.declarations && getFileLocalCompilerOption(getSourceFileOfNode(node), compilerOptions, "noImplicitOverride") && !nodeInAmbientContext) { const baseHasAbstract = some(baseProp.declarations, hasAbstractModifier); if (memberHasOverrideModifier) { return MemberOverrideStatus.Ok; @@ -40579,7 +40600,7 @@ namespace ts { } function checkPropertyInitialization(node: ClassLikeDeclaration) { - if (!strictNullChecks || !strictPropertyInitialization || node.flags & NodeFlags.Ambient) { + if (!strictNullChecks || !strictPropertyInitialization(getSourceFileOfNode(node)) || node.flags & NodeFlags.Ambient) { return; } const constructor = findConstructorDeclaration(node); @@ -42085,15 +42106,15 @@ namespace ts { tracing?.pop(); } - function unusedIsError(kind: UnusedKind, isAmbient: boolean): boolean { + function unusedIsError(kind: UnusedKind, isAmbient: boolean, file: SourceFile): boolean { if (isAmbient) { return false; } switch (kind) { case UnusedKind.Local: - return !!compilerOptions.noUnusedLocals; + return !!getFileLocalCompilerOption(file, compilerOptions, "noUnusedLocals"); case UnusedKind.Parameter: - return !!compilerOptions.noUnusedParameters; + return !!getFileLocalCompilerOption(file, compilerOptions, "noUnusedParameters"); default: return Debug.assertNever(kind); } @@ -42131,9 +42152,9 @@ namespace ts { addLazyDiagnostic(() => { // This relies on the results of other lazy diagnostics, so must be computed after them - if (!node.isDeclarationFile && (compilerOptions.noUnusedLocals || compilerOptions.noUnusedParameters)) { + if (!node.isDeclarationFile && (getFileLocalCompilerOption(node, compilerOptions, "noUnusedLocals") || getFileLocalCompilerOption(node, compilerOptions, "noUnusedParameters"))) { checkUnusedIdentifiers(getPotentiallyUnusedIdentifiers(node), (containingNode, kind, diag) => { - if (!containsParseError(containingNode) && unusedIsError(kind, !!(containingNode.flags & NodeFlags.Ambient))) { + if (!containsParseError(containingNode) && unusedIsError(kind, !!(containingNode.flags & NodeFlags.Ambient), node)) { diagnostics.add(diag); } }); @@ -42977,8 +42998,9 @@ namespace ts { function getAugmentedPropertiesOfType(type: Type): Symbol[] { type = getApparentType(type); const propsByName = createSymbolTable(getPropertiesOfType(type)); - const functionType = getSignaturesOfType(type, SignatureKind.Call).length ? globalCallableFunctionType : - getSignaturesOfType(type, SignatureKind.Construct).length ? globalNewableFunctionType : + const file = type.symbol?.valueDeclaration && getSourceFileOfNode(type.symbol.valueDeclaration); + const functionType = getSignaturesOfType(type, SignatureKind.Call).length ? globalCallableFunctionType(file) : + getSignaturesOfType(type, SignatureKind.Construct).length ? globalNewableFunctionType(file) : undefined; if (functionType) { forEach(getPropertiesOfType(functionType), p => { @@ -43893,8 +43915,8 @@ namespace ts { globalArrayType = getGlobalType("Array" as __String, /*arity*/ 1, /*reportErrors*/ true); globalObjectType = getGlobalType("Object" as __String, /*arity*/ 0, /*reportErrors*/ true); globalFunctionType = getGlobalType("Function" as __String, /*arity*/ 0, /*reportErrors*/ true); - globalCallableFunctionType = strictBindCallApply && getGlobalType("CallableFunction" as __String, /*arity*/ 0, /*reportErrors*/ true) || globalFunctionType; - globalNewableFunctionType = strictBindCallApply && getGlobalType("NewableFunction" as __String, /*arity*/ 0, /*reportErrors*/ true) || globalFunctionType; + globalCallableFunctionType = (file: SourceFile | undefined) => strictBindCallApply(file) && getGlobalType("CallableFunction" as __String, /*arity*/ 0, /*reportErrors*/ true) || globalFunctionType; + globalNewableFunctionType = (file: SourceFile | undefined) => strictBindCallApply(file) && getGlobalType("NewableFunction" as __String, /*arity*/ 0, /*reportErrors*/ true) || globalFunctionType; globalStringType = getGlobalType("String" as __String, /*arity*/ 0, /*reportErrors*/ true); globalNumberType = getGlobalType("Number" as __String, /*arity*/ 0, /*reportErrors*/ true); globalBooleanType = getGlobalType("Boolean" as __String, /*arity*/ 0, /*reportErrors*/ true); diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 370461abd8559..c9ccc0ff0dd94 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -4,6 +4,7 @@ namespace ts { name: "compileOnSave", type: "boolean", defaultValueDescription: false, + category: Diagnostics.Editor_Support }; const jsxOptionMap = new Map(getEntries({ @@ -163,6 +164,7 @@ namespace ts { type: "list", element: { name: "excludeDirectory", + category: Diagnostics.Watch_and_Build_Modes, type: "string", isFilePath: true, extraValidation: specToDiagnostic @@ -175,6 +177,7 @@ namespace ts { type: "list", element: { name: "excludeFile", + category: Diagnostics.Watch_and_Build_Modes, type: "string", isFilePath: true, extraValidation: specToDiagnostic @@ -185,7 +188,7 @@ namespace ts { ]; /* @internal */ - export const commonOptionsWithBuild: CommandLineOption[] = [ + export const commonOptionsWithBuild = is()([ { name: "help", shortName: "h", @@ -200,6 +203,7 @@ namespace ts { shortName: "?", type: "boolean", defaultValueDescription: false, + category: Diagnostics.Command_line_Options, }, { name: "watch", @@ -314,10 +318,10 @@ namespace ts { description: Diagnostics.Set_the_language_of_the_messaging_from_TypeScript_This_does_not_affect_emit, defaultValueDescription: Diagnostics.Platform_specific }, - ]; + ] as const); /* @internal */ - export const targetOptionDeclaration: CommandLineOptionOfCustomType = { + export const targetOptionDeclaration = is()({ name: "target", shortName: "t", type: new Map(getEntries({ @@ -343,10 +347,10 @@ namespace ts { category: Diagnostics.Language_and_Environment, description: Diagnostics.Set_the_JavaScript_language_version_for_emitted_JavaScript_and_include_compatible_library_declarations, defaultValueDescription: ScriptTarget.ES3, - }; + } as const); /*@internal*/ - export const moduleOptionDeclaration: CommandLineOptionOfCustomType = { + export const moduleOptionDeclaration = is()({ name: "module", shortName: "m", type: new Map(getEntries({ @@ -371,9 +375,9 @@ namespace ts { category: Diagnostics.Modules, description: Diagnostics.Specify_what_module_code_is_generated, defaultValueDescription: undefined, - }; + }); - const commandOptionsWithoutBuild: CommandLineOption[] = [ + const commandOptionsWithoutBuild = is()([ // CommandLine only options { name: "all", @@ -449,6 +453,7 @@ namespace ts { element: { name: "lib", type: libMap, + category: Diagnostics.Language_and_Environment, defaultValueDescription: undefined, }, affectsProgramStructure: true, @@ -668,6 +673,7 @@ namespace ts { category: Diagnostics.Type_Checking, description: Diagnostics.Enable_all_strict_type_checking_options, defaultValueDescription: false, + allowedAsPragma: true, }, { name: "noImplicitAny", @@ -677,7 +683,8 @@ namespace ts { strictFlag: true, category: Diagnostics.Type_Checking, description: Diagnostics.Enable_error_reporting_for_expressions_and_declarations_with_an_implied_any_type, - defaultValueDescription: Diagnostics.false_unless_strict_is_set + defaultValueDescription: Diagnostics.false_unless_strict_is_set, + allowedAsPragma: true, }, { name: "strictNullChecks", @@ -687,7 +694,8 @@ namespace ts { strictFlag: true, category: Diagnostics.Type_Checking, description: Diagnostics.When_type_checking_take_into_account_null_and_undefined, - defaultValueDescription: Diagnostics.false_unless_strict_is_set + defaultValueDescription: Diagnostics.false_unless_strict_is_set, + allowedAsPragma: true, }, { name: "strictFunctionTypes", @@ -697,7 +705,8 @@ namespace ts { strictFlag: true, category: Diagnostics.Type_Checking, description: Diagnostics.When_assigning_functions_check_to_ensure_parameters_and_the_return_values_are_subtype_compatible, - defaultValueDescription: Diagnostics.false_unless_strict_is_set + defaultValueDescription: Diagnostics.false_unless_strict_is_set, + allowedAsPragma: true, }, { name: "strictBindCallApply", @@ -707,7 +716,8 @@ namespace ts { strictFlag: true, category: Diagnostics.Type_Checking, description: Diagnostics.Check_that_the_arguments_for_bind_call_and_apply_methods_match_the_original_function, - defaultValueDescription: Diagnostics.false_unless_strict_is_set + defaultValueDescription: Diagnostics.false_unless_strict_is_set, + allowedAsPragma: true, }, { name: "strictPropertyInitialization", @@ -717,7 +727,8 @@ namespace ts { strictFlag: true, category: Diagnostics.Type_Checking, description: Diagnostics.Check_for_class_properties_that_are_declared_but_not_set_in_the_constructor, - defaultValueDescription: Diagnostics.false_unless_strict_is_set + defaultValueDescription: Diagnostics.false_unless_strict_is_set, + allowedAsPragma: true, }, { name: "noImplicitThis", @@ -727,7 +738,8 @@ namespace ts { strictFlag: true, category: Diagnostics.Type_Checking, description: Diagnostics.Enable_error_reporting_when_this_is_given_the_type_any, - defaultValueDescription: Diagnostics.false_unless_strict_is_set + defaultValueDescription: Diagnostics.false_unless_strict_is_set, + allowedAsPragma: true, }, { name: "useUnknownInCatchVariables", @@ -738,6 +750,7 @@ namespace ts { category: Diagnostics.Type_Checking, description: Diagnostics.Default_catch_clause_variables_as_unknown_instead_of_any, defaultValueDescription: false, + allowedAsPragma: true, }, { name: "alwaysStrict", @@ -748,7 +761,8 @@ namespace ts { strictFlag: true, category: Diagnostics.Type_Checking, description: Diagnostics.Ensure_use_strict_is_always_emitted, - defaultValueDescription: Diagnostics.false_unless_strict_is_set + defaultValueDescription: Diagnostics.false_unless_strict_is_set, + allowedAsPragma: true, }, // Additional Checks @@ -760,6 +774,7 @@ namespace ts { category: Diagnostics.Type_Checking, description: Diagnostics.Enable_error_reporting_when_local_variables_aren_t_read, defaultValueDescription: false, + allowedAsPragma: true, }, { name: "noUnusedParameters", @@ -769,6 +784,7 @@ namespace ts { category: Diagnostics.Type_Checking, description: Diagnostics.Raise_an_error_when_a_function_parameter_isn_t_read, defaultValueDescription: false, + allowedAsPragma: true, }, { name: "exactOptionalPropertyTypes", @@ -778,6 +794,7 @@ namespace ts { category: Diagnostics.Type_Checking, description: Diagnostics.Interpret_optional_property_types_as_written_rather_than_adding_undefined, defaultValueDescription: false, + allowedAsPragma: true, }, { name: "noImplicitReturns", @@ -787,6 +804,7 @@ namespace ts { category: Diagnostics.Type_Checking, description: Diagnostics.Enable_error_reporting_for_codepaths_that_do_not_explicitly_return_in_a_function, defaultValueDescription: false, + allowedAsPragma: true, }, { name: "noFallthroughCasesInSwitch", @@ -797,6 +815,7 @@ namespace ts { category: Diagnostics.Type_Checking, description: Diagnostics.Enable_error_reporting_for_fallthrough_cases_in_switch_statements, defaultValueDescription: false, + allowedAsPragma: true, }, { name: "noUncheckedIndexedAccess", @@ -806,6 +825,7 @@ namespace ts { category: Diagnostics.Type_Checking, description: Diagnostics.Add_undefined_to_a_type_when_accessed_using_an_index, defaultValueDescription: false, + allowedAsPragma: true, }, { name: "noImplicitOverride", @@ -815,6 +835,7 @@ namespace ts { category: Diagnostics.Type_Checking, description: Diagnostics.Ensure_overriding_members_in_derived_classes_are_marked_with_an_override_modifier, defaultValueDescription: false, + allowedAsPragma: true, }, { name: "noPropertyAccessFromIndexSignature", @@ -825,6 +846,7 @@ namespace ts { category: Diagnostics.Type_Checking, description: Diagnostics.Enforces_using_indexed_accessors_for_keys_declared_using_an_indexed_type, defaultValueDescription: false, + allowedAsPragma: true, }, // Module Resolution @@ -870,6 +892,7 @@ namespace ts { element: { name: "rootDirs", type: "string", + category: Diagnostics.Modules, isFilePath: true }, affectsModuleResolution: true, @@ -884,6 +907,7 @@ namespace ts { element: { name: "typeRoots", type: "string", + category: Diagnostics.Modules, isFilePath: true }, affectsModuleResolution: true, @@ -895,6 +919,7 @@ namespace ts { type: "list", element: { name: "types", + category: Diagnostics.Modules, type: "string" }, affectsProgramStructure: true, @@ -944,6 +969,7 @@ namespace ts { type: "list", element: { name: "suffix", + category: Diagnostics.Modules, type: "string", }, listPreserveFalsyValues: true, @@ -1334,6 +1360,7 @@ namespace ts { isTSConfigOnly: true, element: { name: "plugin", + category: Diagnostics.Editor_Support, type: "object" }, description: Diagnostics.Specify_a_list_of_language_service_plugins_to_include, @@ -1352,37 +1379,129 @@ namespace ts { category: Diagnostics.Language_and_Environment, defaultValueDescription: Diagnostics.auto_Colon_Treat_files_with_imports_exports_import_meta_jsx_with_jsx_Colon_react_jsx_or_esm_format_with_module_Colon_node16_as_modules, } - ]; + ] as const); /* @internal */ - export const optionDeclarations: CommandLineOption[] = [ + export const optionDeclarations = is()([ ...commonOptionsWithBuild, ...commandOptionsWithoutBuild, - ]; + ] as const); + + /* @internal */ + type WithTrue = T extends unknown ? K extends unknown ? T[K] extends true ? T : never : never : never; + + function isAffectsSemanticDiagnosticsOption(option: T): option is WithTrue { + return !!option.affectsSemanticDiagnostics; + } + + /* @internal */ + export const semanticDiagnosticsOptionDeclarations = optionDeclarations.filter(isAffectsSemanticDiagnosticsOption); + + function isAffectsEmitOption(option: T): option is WithTrue { + return !!option.affectsEmit; + } + + /* @internal */ + export const affectsEmitOptionDeclarations = optionDeclarations.filter(isAffectsEmitOption); + + function isAffectsDeclarationPathOption(option: T): option is WithTrue { + return !!option.affectsDeclarationPath; + } + + /* @internal */ + export const affectsDeclarationPathOptionDeclarations = optionDeclarations.filter(isAffectsDeclarationPathOption); + + function isAffectsModuleResolutionOption(option: T): option is WithTrue { + return !!option.affectsModuleResolution; + } /* @internal */ - export const semanticDiagnosticsOptionDeclarations: readonly CommandLineOption[] = - optionDeclarations.filter(option => !!option.affectsSemanticDiagnostics); + export const moduleResolutionOptionDeclarations = optionDeclarations.filter(isAffectsModuleResolutionOption); + + function isSourceFileAffectingOptions(option: T): option is WithTrue { + return !!option.affectsSourceFile || !!option.affectsModuleResolution || !!option.affectsBindDiagnostics; + } /* @internal */ - export const affectsEmitOptionDeclarations: readonly CommandLineOption[] = - optionDeclarations.filter(option => !!option.affectsEmit); + export const sourceFileAffectingCompilerOptions = optionDeclarations.filter(isSourceFileAffectingOptions); + + function isAffectsProgramStructureOption(option: T): option is WithTrue { + return !!option.affectsProgramStructure; + } /* @internal */ - export const affectsDeclarationPathOptionDeclarations: readonly CommandLineOption[] = - optionDeclarations.filter(option => !!option.affectsDeclarationPath); + export const optionsAffectingProgramStructure = optionDeclarations.filter(isAffectsProgramStructureOption); /* @internal */ - export const moduleResolutionOptionDeclarations: readonly CommandLineOption[] = - optionDeclarations.filter(option => !!option.affectsModuleResolution); + export function isStrictOption(option: T): option is WithTrue { + return !!option.strictFlag === true; + } + + function isAllowedAsPragmaOption(option: T): option is WithTrue { + return !!option.allowedAsPragma; + } /* @internal */ - export const sourceFileAffectingCompilerOptions: readonly CommandLineOption[] = optionDeclarations.filter(option => - !!option.affectsSourceFile || !!option.affectsModuleResolution || !!option.affectsBindDiagnostics); + export const optionsAllowedAsPragmaOption = optionDeclarations.filter(isAllowedAsPragmaOption); /* @internal */ - export const optionsAffectingProgramStructure: readonly CommandLineOption[] = - optionDeclarations.filter(option => !!option.affectsProgramStructure); + type CompilerOptionsIntoPragmaDefinitions = UnionToIntersection}`]: { readonly kind: PragmaKindFlags, readonly args: readonly [{ readonly name: "value", readonly optional: true }] }} : never>; + + function convertCompilerOptionsIntoPragmasSpecs(options: T): CompilerOptionsIntoPragmaDefinitions { + const result = {} as CompilerOptionsIntoPragmaDefinitions; + for (const elem of options) { + result[`ts-${elem.name.toLowerCase()}` as keyof typeof result] = { + args: [{ name: "value", optional: true }], + kind: PragmaKindFlags.SingleLine | PragmaKindFlags.MultiLine + } as any; + } + return result; + } + + /* @internal */ + export const commentPragmas = { + "reference": { + args: [ + { name: "types", optional: true, captureSpan: true }, + { name: "lib", optional: true, captureSpan: true }, + { name: "path", optional: true, captureSpan: true }, + { name: "no-default-lib", optional: true }, + { name: "resolution-mode", optional: true } + ], + kind: PragmaKindFlags.TripleSlashXML + }, + "amd-dependency": { + args: [{ name: "path" }, { name: "name", optional: true }], + kind: PragmaKindFlags.TripleSlashXML + }, + "amd-module": { + args: [{ name: "name" }], + kind: PragmaKindFlags.TripleSlashXML + }, + "ts-check": { + kind: PragmaKindFlags.SingleLine + }, + "ts-nocheck": { + kind: PragmaKindFlags.SingleLine + }, + "jsx": { + args: [{ name: "factory" }], + kind: PragmaKindFlags.MultiLine + }, + "jsxfrag": { + args: [{ name: "factory" }], + kind: PragmaKindFlags.MultiLine + }, + "jsximportsource": { + args: [{ name: "factory" }], + kind: PragmaKindFlags.MultiLine + }, + "jsxruntime": { + args: [{ name: "factory" }], + kind: PragmaKindFlags.MultiLine + }, + ...convertCompilerOptionsIntoPragmasSpecs(optionsAllowedAsPragmaOption) + } as const; /* @internal */ export const transpileOptionValueCompilerOptions: readonly CommandLineOption[] = optionDeclarations.filter(option => @@ -1438,11 +1557,13 @@ namespace ts { */ name: "enableAutoDiscovery", type: "boolean", + category: Diagnostics.File_Management, defaultValueDescription: false, }, { name: "enable", type: "boolean", + category: Diagnostics.File_Management, defaultValueDescription: false, }, { @@ -1450,20 +1571,25 @@ namespace ts { type: "list", element: { name: "include", + category: Diagnostics.File_Management, type: "string" - } + }, + category: Diagnostics.File_Management, }, { name: "exclude", type: "list", element: { name: "exclude", + category: Diagnostics.File_Management, type: "string" - } + }, + category: Diagnostics.File_Management, }, { name: "disableFilenameBasedTypeAcquisition", type: "boolean", + category: Diagnostics.File_Management, defaultValueDescription: false, }, ]; @@ -1670,10 +1796,11 @@ namespace ts { } } - function parseOptionValue( + /* @internal */ + export function parseOptionValue( args: readonly string[], i: number, - diagnostics: ParseCommandLineWorkerDiagnostics, + diagnostics: ParseCommandLineWorkerDiagnostics | undefined, opt: CommandLineOption, options: OptionsBase, errors: Diagnostic[] @@ -1701,7 +1828,7 @@ namespace ts { } else { // Check to see if no argument was provided (e.g. "--locale" is the last command-line argument). - if (!args[i] && opt.type !== "boolean") { + if (!args[i] && opt.type !== "boolean" && diagnostics) { errors.push(createCompilerDiagnostic(diagnostics.optionTypeMismatchDiagnostic, opt.name, getCompilerOptionValueTypeString(opt))); } @@ -1977,30 +2104,35 @@ namespace ts { _tsconfigRootOptions = { name: undefined!, // should never be needed since this is root type: "object", + category: Diagnostics.Command_line_Options, elementOptions: commandLineOptionsToMap([ { name: "compilerOptions", type: "object", elementOptions: getCommandLineCompilerOptionsMap(), extraKeyDiagnostics: compilerOptionsDidYouMeanDiagnostics, + category: Diagnostics.Command_line_Options, }, { name: "watchOptions", type: "object", elementOptions: getCommandLineWatchOptionsMap(), extraKeyDiagnostics: watchOptionsDidYouMeanDiagnostics, + category: Diagnostics.Command_line_Options, }, { name: "typingOptions", type: "object", elementOptions: getCommandLineTypeAcquisitionMap(), extraKeyDiagnostics: typeAcquisitionDidYouMeanDiagnostics, + category: Diagnostics.Command_line_Options, }, { name: "typeAcquisition", type: "object", elementOptions: getCommandLineTypeAcquisitionMap(), - extraKeyDiagnostics: typeAcquisitionDidYouMeanDiagnostics + extraKeyDiagnostics: typeAcquisitionDidYouMeanDiagnostics, + category: Diagnostics.Command_line_Options, }, { name: "extends", @@ -2012,6 +2144,7 @@ namespace ts { type: "list", element: { name: "references", + category: Diagnostics.Projects, type: "object" }, category: Diagnostics.Projects, @@ -2021,6 +2154,7 @@ namespace ts { type: "list", element: { name: "files", + category: Diagnostics.File_Management, type: "string" }, category: Diagnostics.File_Management, @@ -2030,6 +2164,7 @@ namespace ts { type: "list", element: { name: "include", + category: Diagnostics.File_Management, type: "string" }, category: Diagnostics.File_Management, @@ -2040,6 +2175,7 @@ namespace ts { type: "list", element: { name: "exclude", + category: Diagnostics.File_Management, type: "string" }, category: Diagnostics.File_Management, @@ -2583,7 +2719,7 @@ namespace ts { const { category } = option; if (isAllowedOptionForOutput(option)) { - categorizedOptions.add(getLocaleSpecificMessage(category!), option); + categorizedOptions.add(getLocaleSpecificMessage(category), option); } } diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 934f5ace84990..41a2bd8198bb5 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -2121,7 +2121,7 @@ namespace ts { * (0.4 allows 1 substitution/transposition for every 5 characters, * and 1 insertion/deletion at 3 characters) */ - export function getSpellingSuggestion(name: string, candidates: T[], getName: (candidate: T) => string | undefined): T | undefined { + export function getSpellingSuggestion(name: string, candidates: readonly T[], getName: (candidate: T) => string | undefined): T | undefined { const maximumLengthDifference = Math.max(2, Math.floor(name.length * 0.34)); let bestDistance = Math.floor(name.length * 0.4) + 1; // If the best result is worse than this, don't bother. let bestCandidate: T | undefined; @@ -2527,4 +2527,8 @@ namespace ts { } return s.slice(0, end + 1); } + + export function is(): (arg: U) => U { + return identity; + } } diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 93939b6f4f2d1..43d055432c47c 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -9700,6 +9700,7 @@ namespace ts { export interface PragmaContext { languageVersion: ScriptTarget; pragmas?: PragmaMap; + localOptions?: CompilerOptions; checkJsDirective?: CheckJsDirective; referencedFiles: FileReference[]; typeReferenceDirectives: FileReference[]; @@ -9707,6 +9708,7 @@ namespace ts { amdDependencies: AmdDependency[]; hasNoDefaultLib?: boolean; moduleName?: string; + } function parseResolutionMode(mode: string | undefined, pos: number, end: number, reportDiagnostic: PragmaDiagnosticReporter): ModuleKind.ESNext | ModuleKind.CommonJS | undefined { @@ -9823,12 +9825,54 @@ namespace ts { }); break; } + case "ts-strict": + case "ts-noimplicitany": + case "ts-strictnullchecks": + case "ts-strictfunctiontypes": + case "ts-strictbindcallapply": + case "ts-noimplicitthis": + case "ts-strictpropertyinitialization": + case "ts-useunknownincatchvariables": + case "ts-alwaysstrict": + case "ts-nounusedlocals": + case "ts-nounusedparameters": + case "ts-exactoptionalpropertytypes": + case "ts-nopropertyaccessfromindexsignature": + case "ts-noimplicitreturns": + case "ts-nofallthroughcasesinswitch": + case "ts-nouncheckedindexedaccess": + case "ts-noimplicitoverride": { + const optName = key.slice(3); + const opt = find(optionsAllowedAsPragmaOption, o => o.name.toLowerCase() === optName)!; + const entry = (isArray(entryOrList) ? last(entryOrList) : entryOrList); + const unparsedValue = (entry.arguments as PragmaArgumentType<`ts-${Lowercase}`>).value; + const optContainer: OptionsBase = {}; + const errors: Diagnostic[] = []; + const parsedValue = unparsedValue === undefined ? true : (parseOptionValue([unparsedValue], 0, /*diagnostics*/ undefined, opt, optContainer, errors), optContainer[opt.name]); + if (unparsedValue === undefined && opt.type !== "boolean") { + errors.push(createCompilerDiagnostic(Diagnostics.Compiler_option_0_expects_an_argument, optName)); + } + for (const err of errors) { + reportDiagnostic(entry.range.pos, entry.range.end - entry.range.pos, { + category: err.category, + code: err.code, + message: err.messageText as string, + reportsDeprecated: err.reportsDeprecated, + reportsUnnecessary: err.reportsUnnecessary, + key: err.messageText as string + }); + } + if (!length(errors)) { + (context.localOptions ??= {})[opt.name as string] = parsedValue; + } + break; + } case "jsx": case "jsxfrag": case "jsximportsource": case "jsxruntime": return; // Accessed directly - default: Debug.fail("Unhandled pragma kind"); // Can this be made into an assertNever in the future? + default: Debug.assertNever(key, `Unhandled pragma kind: ${key}`); } }); } diff --git a/src/compiler/program.ts b/src/compiler/program.ts index e7c0f363ea8df..d7afe81bdaf4e 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -3282,7 +3282,7 @@ namespace ts { // Don't add the file if it has a bad extension (e.g. 'tsx' if we don't have '--allowJs') // This may still end up being an untyped module -- the file won't be included but imports will be allowed. const shouldAddFile = resolvedFileName - && !getResolutionDiagnostic(optionsForFile, resolution) + && !getResolutionDiagnostic(file, optionsForFile, resolution) && !optionsForFile.noResolve && index < file.imports.length && !elideImport @@ -3384,10 +3384,10 @@ namespace ts { } function verifyCompilerOptions() { - if (options.strictPropertyInitialization && !getStrictOptionValue(options, "strictNullChecks")) { + if (options.strictPropertyInitialization && !getStrictOptionValue(/*file*/ undefined, options, "strictNullChecks")) { createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "strictPropertyInitialization", "strictNullChecks"); } - if (options.exactOptionalPropertyTypes && !getStrictOptionValue(options, "strictNullChecks")) { + if (options.exactOptionalPropertyTypes && !getStrictOptionValue(/*file*/ undefined, options, "strictNullChecks")) { createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "exactOptionalPropertyTypes", "strictNullChecks"); } @@ -3516,7 +3516,7 @@ namespace ts { createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_with_option_1, "lib", "noLib"); } - if (options.noImplicitUseStrict && getStrictOptionValue(options, "alwaysStrict")) { + if (options.noImplicitUseStrict && getStrictOptionValue(/*file*/ undefined, options, "alwaysStrict")) { createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_with_option_1, "noImplicitUseStrict", "alwaysStrict"); } @@ -4316,7 +4316,7 @@ namespace ts { * The DiagnosticMessage's parameters are the imported module name, and the filename it resolved to. * This returns a diagnostic even if the module will be an untyped module. */ - export function getResolutionDiagnostic(options: CompilerOptions, { extension }: ResolvedModuleFull): DiagnosticMessage | undefined { + export function getResolutionDiagnostic(file: SourceFile, options: CompilerOptions, { extension }: ResolvedModuleFull): DiagnosticMessage | undefined { switch (extension) { case Extension.Ts: case Extension.Dts: @@ -4336,7 +4336,7 @@ namespace ts { return options.jsx ? undefined : Diagnostics.Module_0_was_resolved_to_1_but_jsx_is_not_set; } function needAllowJs() { - return getAllowJSCompilerOption(options) || !getStrictOptionValue(options, "noImplicitAny") ? undefined : Diagnostics.Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type; + return getAllowJSCompilerOption(options) || !getStrictOptionValue(file, options, "noImplicitAny") ? undefined : Diagnostics.Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type; } function needResolveJsonModule() { return options.resolveJsonModule ? undefined : Diagnostics.Module_0_was_resolved_to_1_but_resolveJsonModule_is_not_used; diff --git a/src/compiler/transformers/module/module.ts b/src/compiler/transformers/module/module.ts index 9b3b8e6ee1283..2e5dab06c085a 100644 --- a/src/compiler/transformers/module/module.ts +++ b/src/compiler/transformers/module/module.ts @@ -93,7 +93,7 @@ namespace ts { startLexicalEnvironment(); const statements: Statement[] = []; - const ensureUseStrict = getStrictOptionValue(compilerOptions, "alwaysStrict") || (!compilerOptions.noImplicitUseStrict && isExternalModule(currentSourceFile)); + const ensureUseStrict = getStrictOptionValue(node, compilerOptions, "alwaysStrict") || (!compilerOptions.noImplicitUseStrict && isExternalModule(currentSourceFile)); const statementOffset = factory.copyPrologue(node.statements, statements, ensureUseStrict && !isJsonSourceFile(node), topLevelVisitor); if (shouldEmitUnderscoreUnderscoreESModule()) { diff --git a/src/compiler/transformers/module/system.ts b/src/compiler/transformers/module/system.ts index d541c3d3ad26a..d6b79bb234c6e 100644 --- a/src/compiler/transformers/module/system.ts +++ b/src/compiler/transformers/module/system.ts @@ -222,7 +222,7 @@ namespace ts { startLexicalEnvironment(); // Add any prologue directives. - const ensureUseStrict = getStrictOptionValue(compilerOptions, "alwaysStrict") || (!compilerOptions.noImplicitUseStrict && isExternalModule(currentSourceFile)); + const ensureUseStrict = getStrictOptionValue(node, compilerOptions, "alwaysStrict") || (!compilerOptions.noImplicitUseStrict && isExternalModule(currentSourceFile)); const statementOffset = factory.copyPrologue(node.statements, statements, ensureUseStrict, topLevelVisitor); // var __moduleName = context_1 && context_1.id; diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index 61b982d7f2916..492540a5f25c3 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -574,7 +574,7 @@ namespace ts { } function visitSourceFile(node: SourceFile) { - const alwaysStrict = getStrictOptionValue(compilerOptions, "alwaysStrict") && + const alwaysStrict = getStrictOptionValue(node, compilerOptions, "alwaysStrict") && !(isExternalModule(node) && moduleKind >= ModuleKind.ES2015) && !isJsonSourceFile(node); diff --git a/src/compiler/transformers/typeSerializer.ts b/src/compiler/transformers/typeSerializer.ts index 9504bcde8864d..ceff03655be72 100644 --- a/src/compiler/transformers/typeSerializer.ts +++ b/src/compiler/transformers/typeSerializer.ts @@ -63,7 +63,6 @@ namespace ts { const resolver = context.getEmitResolver(); const compilerOptions = context.getCompilerOptions(); const languageVersion = getEmitScriptTarget(compilerOptions); - const strictNullChecks = getStrictOptionValue(compilerOptions, "strictNullChecks"); let currentLexicalScope: SourceFile | CaseBlock | ModuleBlock | Block; let currentNameScope: ClassLikeDeclaration | undefined; @@ -344,7 +343,7 @@ namespace ts { return factory.createIdentifier("Object"); // Reduce to `any` in a union or intersection } - if (!strictNullChecks && ((isLiteralTypeNode(typeNode) && typeNode.literal.kind === SyntaxKind.NullKeyword) || typeNode.kind === SyntaxKind.UndefinedKeyword)) { + if (!getStrictOptionValue(getSourceFileOfNode(currentLexicalScope), compilerOptions, "strictNullChecks") && ((isLiteralTypeNode(typeNode) && typeNode.literal.kind === SyntaxKind.NullKeyword) || typeNode.kind === SyntaxKind.UndefinedKeyword)) { continue; // Elide null and undefined from unions for metadata, just like what we did prior to the implementation of strict null checks } diff --git a/src/compiler/tsbuildPublic.ts b/src/compiler/tsbuildPublic.ts index 2b9d97f324ee2..bd685c4f0a42f 100644 --- a/src/compiler/tsbuildPublic.ts +++ b/src/compiler/tsbuildPublic.ts @@ -188,7 +188,7 @@ namespace ts { function getCompilerOptionsOfBuildOptions(buildOptions: BuildOptions): CompilerOptions { const result = {} as CompilerOptions; commonOptionsWithBuild.forEach(option => { - if (hasProperty(buildOptions, option.name)) result[option.name] = buildOptions[option.name]; + if (hasProperty(buildOptions, option.name)) result[option.name as string] = buildOptions[option.name]; }); return result; } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 461a750028356..11d69ec35a462 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -4047,6 +4047,7 @@ namespace ts { /* @internal */ checkJsDirective?: CheckJsDirective; /* @internal */ version: string; /* @internal */ pragmas: ReadonlyPragmaMap; + /* @internal */ localOptions?: CompilerOptions; /* @internal */ localJsxNamespace?: __String; /* @internal */ localJsxFragmentNamespace?: __String; /* @internal */ localJsxFactory?: EntityName; @@ -5526,6 +5527,7 @@ namespace ts { skipDirectInference?: true; // Flag set by the API `getContextualType` call on a node when `Completions` is passed to force the checker to skip making inferences to a node's type declarationRequiresScopeChange?: boolean; // Set by `useOuterVariableScopeInParameter` in checker when downlevel emit would change the name resolution scope inside of a parameter. serializedTypes?: ESMap; // Collection of types serialized at this location + sourceFile?: SourceFile | undefined; // Cached lookup result of `getSourceFileOfNode` } export const enum TypeFlags { @@ -6795,7 +6797,7 @@ namespace ts { isTSConfigOnly?: boolean; // True if option can only be specified via tsconfig.json file isCommandLineOnly?: boolean; showInSimplifiedHelpView?: boolean; - category?: DiagnosticMessage; + category: DiagnosticMessage; strictFlag?: true; // true if the option is one of the flag under strict affectsSourceFile?: true; // true if we should recreate SourceFiles after this option changes affectsModuleResolution?: true; // currently same effect as `affectsSourceFile` @@ -6808,6 +6810,7 @@ namespace ts { affectsBundleEmitBuildInfo?: true; // true if this options should be emitted in buildInfo with --out transpileOptionValue?: boolean | undefined; // If set this means that the option should be set to this value when transpiling extraValidation?: (value: CompilerOptionsValue) => [DiagnosticMessage, ...string[]] | undefined; // Additional validation to be performed for the value to be valid + allowedAsPragma?: boolean; // True if this option is allowed as a comment pragma to be toggled on a per-file basis (eg, `// @ts-strict false`) } /* @internal */ @@ -6843,7 +6846,7 @@ namespace ts { /* @internal */ export interface DidYouMeanOptionsDiagnostics { alternateMode?: AlternateModeDiagnostics; - optionDeclarations: CommandLineOption[]; + optionDeclarations: readonly CommandLineOption[]; unknownOptionDiagnostic: DiagnosticMessage, unknownDidYouMeanDiagnostic: DiagnosticMessage, } @@ -9053,52 +9056,6 @@ namespace ts { kind?: PragmaKindFlags; } - // While not strictly a type, this is here because `PragmaMap` needs to be here to be used with `SourceFile`, and we don't - // fancy effectively defining it twice, once in value-space and once in type-space - /* @internal */ - export const commentPragmas = { - "reference": { - args: [ - { name: "types", optional: true, captureSpan: true }, - { name: "lib", optional: true, captureSpan: true }, - { name: "path", optional: true, captureSpan: true }, - { name: "no-default-lib", optional: true }, - { name: "resolution-mode", optional: true } - ], - kind: PragmaKindFlags.TripleSlashXML - }, - "amd-dependency": { - args: [{ name: "path" }, { name: "name", optional: true }], - kind: PragmaKindFlags.TripleSlashXML - }, - "amd-module": { - args: [{ name: "name" }], - kind: PragmaKindFlags.TripleSlashXML - }, - "ts-check": { - kind: PragmaKindFlags.SingleLine - }, - "ts-nocheck": { - kind: PragmaKindFlags.SingleLine - }, - "jsx": { - args: [{ name: "factory" }], - kind: PragmaKindFlags.MultiLine - }, - "jsxfrag": { - args: [{ name: "factory" }], - kind: PragmaKindFlags.MultiLine - }, - "jsximportsource": { - args: [{ name: "factory" }], - kind: PragmaKindFlags.MultiLine - }, - "jsxruntime": { - args: [{ name: "factory" }], - kind: PragmaKindFlags.MultiLine - }, - } as const; - /* @internal */ type PragmaArgTypeMaybeCapture = TDesc extends {captureSpan: true} ? {value: string, pos: number, end: number} : string; @@ -9109,7 +9066,7 @@ namespace ts { : {[K in TName]: PragmaArgTypeMaybeCapture}; /* @internal */ - type UnionToIntersection = + export type UnionToIntersection = (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never; /* @internal */ @@ -9121,7 +9078,7 @@ namespace ts { * Maps a pragma definition into the desired shape for its arguments object */ /* @internal */ - type PragmaArgumentType = + export type PragmaArgumentType = ConcretePragmaSpecs[KPrag] extends { args: readonly PragmaArgumentSpecification[] } ? UnionToIntersection> : never; diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 62a941df1f79f..c3ed467d5ea76 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -835,7 +835,7 @@ namespace ts { return false; } // If `alwaysStrict` is set, then treat the file as strict. - if (getStrictOptionValue(compilerOptions, "alwaysStrict")) { + if (getStrictOptionValue(node, compilerOptions, "alwaysStrict")) { return true; } // Starting with a "use strict" directive indicates the file is strict. @@ -6446,6 +6446,17 @@ namespace ts { return !!(options.incremental || options.composite); } + export type FileLocalOptionName = (typeof optionsAllowedAsPragmaOption)[number]["name"]; + + export function getFileLocalCompilerOption(file: SourceFile | undefined, opts: CompilerOptions, name: T, isStrictFlag?: boolean): CompilerOptions[T] { + const localStrictValue = (file?.localOptions && hasProperty(file.localOptions, "strict")) ? file.localOptions.strict : undefined; + const strict = localStrictValue === undefined ? opts.strict : localStrictValue; + if (file?.localOptions && hasProperty(file.localOptions, name)) { + return file.localOptions[name] !== undefined ? file.localOptions[name] : opts[name] !== undefined ? opts[name] : isStrictFlag ? strict : undefined; + } + return opts[name] !== undefined ? opts[name] : isStrictFlag ? strict : undefined; + } + export type StrictOptionName = | "noImplicitAny" | "noImplicitThis" @@ -6457,8 +6468,8 @@ namespace ts { | "useUnknownInCatchVariables" ; - export function getStrictOptionValue(compilerOptions: CompilerOptions, flag: StrictOptionName): boolean { - return compilerOptions[flag] === undefined ? !!compilerOptions.strict : !!compilerOptions[flag]; + export function getStrictOptionValue(file: SourceFile | undefined, compilerOptions: CompilerOptions, flag: StrictOptionName): boolean { + return !!getFileLocalCompilerOption(file, compilerOptions, flag, /*isStrictFlag*/ true); } export function getAllowJSCompilerOption(compilerOptions: CompilerOptions): boolean { @@ -6482,7 +6493,7 @@ namespace ts { } export function getCompilerOptionValue(options: CompilerOptions, option: CommandLineOption): unknown { - return option.strictFlag ? getStrictOptionValue(options, option.name as StrictOptionName) : options[option.name]; + return option.strictFlag ? options[option.name] === undefined ? !!options.strict : !!options[option.name] : options[option.name]; } export function getJSXTransformEnabled(options: CompilerOptions): boolean { diff --git a/src/executeCommandLine/executeCommandLine.ts b/src/executeCommandLine/executeCommandLine.ts index cb3ba0575a146..063ac825cc89d 100644 --- a/src/executeCommandLine/executeCommandLine.ts +++ b/src/executeCommandLine/executeCommandLine.ts @@ -80,7 +80,7 @@ namespace ts { // Sort our options by their names, (e.g. "--noImplicitAny" comes before "--watch") return !!commandLine.options.all ? sort(optionDeclarations, (a, b) => compareStringsCaseInsensitive(a.name, b.name)) : - filter(optionDeclarations.slice(), v => !!v.showInSimplifiedHelpView); + filter(optionDeclarations.slice(), v => !!(v as CommandLineOption).showInSimplifiedHelpView); } function printVersion(sys: System) { diff --git a/src/harness/harnessIO.ts b/src/harness/harnessIO.ts index 2786498d41e1f..025ee7c9a9341 100644 --- a/src/harness/harnessIO.ts +++ b/src/harness/harnessIO.ts @@ -304,21 +304,21 @@ namespace Harness { // Additional options not already in ts.optionDeclarations const harnessOptionDeclarations: ts.CommandLineOption[] = [ - { name: "allowNonTsExtensions", type: "boolean", defaultValueDescription: false }, - { name: "useCaseSensitiveFileNames", type: "boolean", defaultValueDescription: false }, - { name: "baselineFile", type: "string" }, - { name: "includeBuiltFile", type: "string" }, - { name: "fileName", type: "string" }, - { name: "libFiles", type: "string" }, - { name: "noErrorTruncation", type: "boolean", defaultValueDescription: false }, - { name: "suppressOutputPathCheck", type: "boolean", defaultValueDescription: false }, - { name: "noImplicitReferences", type: "boolean", defaultValueDescription: false }, - { name: "currentDirectory", type: "string" }, - { name: "symlink", type: "string" }, - { name: "link", type: "string" }, - { name: "noTypesAndSymbols", type: "boolean", defaultValueDescription: false }, + { name: "allowNonTsExtensions", type: "boolean", defaultValueDescription: false, category: ts.Diagnostics.ALL_COMPILER_OPTIONS }, + { name: "useCaseSensitiveFileNames", type: "boolean", defaultValueDescription: false, category: ts.Diagnostics.ALL_COMPILER_OPTIONS }, + { name: "baselineFile", type: "string", category: ts.Diagnostics.ALL_COMPILER_OPTIONS }, + { name: "includeBuiltFile", type: "string", category: ts.Diagnostics.ALL_COMPILER_OPTIONS }, + { name: "fileName", type: "string", category: ts.Diagnostics.ALL_COMPILER_OPTIONS }, + { name: "libFiles", type: "string", category: ts.Diagnostics.ALL_COMPILER_OPTIONS }, + { name: "noErrorTruncation", type: "boolean", defaultValueDescription: false, category: ts.Diagnostics.ALL_COMPILER_OPTIONS }, + { name: "suppressOutputPathCheck", type: "boolean", defaultValueDescription: false, category: ts.Diagnostics.ALL_COMPILER_OPTIONS }, + { name: "noImplicitReferences", type: "boolean", defaultValueDescription: false, category: ts.Diagnostics.ALL_COMPILER_OPTIONS }, + { name: "currentDirectory", type: "string", category: ts.Diagnostics.ALL_COMPILER_OPTIONS }, + { name: "symlink", type: "string", category: ts.Diagnostics.ALL_COMPILER_OPTIONS }, + { name: "link", type: "string", category: ts.Diagnostics.ALL_COMPILER_OPTIONS }, + { name: "noTypesAndSymbols", type: "boolean", defaultValueDescription: false, category: ts.Diagnostics.ALL_COMPILER_OPTIONS }, // Emitted js baseline will print full paths for every output file - { name: "fullEmitPaths", type: "boolean", defaultValueDescription: false }, + { name: "fullEmitPaths", type: "boolean", defaultValueDescription: false, category: ts.Diagnostics.ALL_COMPILER_OPTIONS }, ]; let optionsIndex: ts.ESMap; diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index c6d1513c0771f..4a32fa0d3c917 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -157,7 +157,7 @@ namespace ts.server { [name: string]: { match: RegExp, exclude?: (string | number)[][], types?: string[] }; } - function prepareConvertersForEnumLikeCompilerOptions(commandLineOptions: CommandLineOption[]): ESMap> { + function prepareConvertersForEnumLikeCompilerOptions(commandLineOptions: readonly CommandLineOption[]): ESMap> { const map = new Map>(); for (const option of commandLineOptions) { if (typeof option.type === "object") { diff --git a/src/services/transpile.ts b/src/services/transpile.ts index b2d8951e43b7e..217664f79285b 100644 --- a/src/services/transpile.ts +++ b/src/services/transpile.ts @@ -125,7 +125,7 @@ namespace ts { export function fixupCompilerOptions(options: CompilerOptions, diagnostics: Diagnostic[]): CompilerOptions { // Lazily create this value to fix module loading errors. commandLineOptionsStringToEnum = commandLineOptionsStringToEnum || - filter(optionDeclarations, o => typeof o.type === "object" && !forEachEntry(o.type, v => typeof v !== "number")) as CommandLineOptionOfCustomType[]; + filter(optionDeclarations, o => typeof o.type === "object" && !forEachEntry((o as CommandLineOptionOfCustomType).type, v => typeof v !== "number")) as CommandLineOptionOfCustomType[]; options = cloneCompilerOptions(options); diff --git a/tests/baselines/reference/booleanLiteralsContextuallyTypedFromUnion.errors.txt b/tests/baselines/reference/booleanLiteralsContextuallyTypedFromUnion.errors.txt deleted file mode 100644 index 5b8fb9b0ea85d..0000000000000 --- a/tests/baselines/reference/booleanLiteralsContextuallyTypedFromUnion.errors.txt +++ /dev/null @@ -1,31 +0,0 @@ -error TS2318: Cannot find global type 'CallableFunction'. -error TS2318: Cannot find global type 'NewableFunction'. - - -!!! error TS2318: Cannot find global type 'CallableFunction'. -!!! error TS2318: Cannot find global type 'NewableFunction'. -==== tests/cases/compiler/booleanLiteralsContextuallyTypedFromUnion.tsx (0 errors) ==== - interface A { isIt: true; text: string; } - interface B { isIt: false; value: number; } - type C = A | B; - const isIt = Math.random() > 0.5; - const c: C = isIt ? { isIt, text: 'hey' } : { isIt, value: 123 }; - const cc: C = isIt ? { isIt: isIt, text: 'hey' } : { isIt: isIt, value: 123 }; - - type ComponentProps = - | { - optionalBool: true; - mandatoryFn: () => void; - } - | { - optionalBool: false; - }; - - let Funk = (_props: ComponentProps) =>
Hello
; - - let Fail1 = () => { }} optionalBool={true} /> - let Fail2 = () => { }} optionalBool={true as true} /> - let True = true as true; - let Fail3 = () => { }} optionalBool={True} /> - let attrs2 = { optionalBool: true as true, mandatoryFn: () => { } } - let Success = () => \ No newline at end of file diff --git a/tests/baselines/reference/errorInfoForRelatedIndexTypesNoConstraintElaboration.errors.txt b/tests/baselines/reference/errorInfoForRelatedIndexTypesNoConstraintElaboration.errors.txt index 1626db671f242..da0279d050d68 100644 --- a/tests/baselines/reference/errorInfoForRelatedIndexTypesNoConstraintElaboration.errors.txt +++ b/tests/baselines/reference/errorInfoForRelatedIndexTypesNoConstraintElaboration.errors.txt @@ -1,9 +1,10 @@ tests/cases/compiler/errorInfoForRelatedIndexTypesNoConstraintElaboration.ts(6,15): error TS2322: Type 'IntrinsicElements[T1]' is not assignable to type 'IntrinsicElements[T2]'. Type 'T1' is not assignable to type 'T2'. 'T1' is assignable to the constraint of type 'T2', but 'T2' could be instantiated with a different subtype of constraint 'keyof IntrinsicElements'. +tests/cases/compiler/errorInfoForRelatedIndexTypesNoConstraintElaboration.ts(6,15): error TS2590: Expression produces a union type that is too complex to represent. -==== tests/cases/compiler/errorInfoForRelatedIndexTypesNoConstraintElaboration.ts (1 errors) ==== +==== tests/cases/compiler/errorInfoForRelatedIndexTypesNoConstraintElaboration.ts (2 errors) ==== /// class I { @@ -14,5 +15,7 @@ tests/cases/compiler/errorInfoForRelatedIndexTypesNoConstraintElaboration.ts(6,1 !!! error TS2322: Type 'IntrinsicElements[T1]' is not assignable to type 'IntrinsicElements[T2]'. !!! error TS2322: Type 'T1' is not assignable to type 'T2'. !!! error TS2322: 'T1' is assignable to the constraint of type 'T2', but 'T2' could be instantiated with a different subtype of constraint 'keyof IntrinsicElements'. + ~~ +!!! error TS2590: Expression produces a union type that is too complex to represent. } } \ No newline at end of file diff --git a/tests/baselines/reference/jsxSpreadOverwritesAttributeStrict.errors.txt b/tests/baselines/reference/jsxSpreadOverwritesAttributeStrict.errors.txt index 9d751ce2216b4..cae31812d7e6c 100644 --- a/tests/baselines/reference/jsxSpreadOverwritesAttributeStrict.errors.txt +++ b/tests/baselines/reference/jsxSpreadOverwritesAttributeStrict.errors.txt @@ -1,4 +1,3 @@ -error TS2318: Cannot find global type 'CallableFunction'. error TS2318: Cannot find global type 'NewableFunction'. tests/cases/conformance/jsx/file.tsx(19,17): error TS2783: 'a' is specified more than once, so this usage will be overwritten. tests/cases/conformance/jsx/file.tsx(20,17): error TS2783: 'a' is specified more than once, so this usage will be overwritten. @@ -9,7 +8,6 @@ tests/cases/conformance/jsx/file.tsx(22,17): error TS2783: 'a' is specified more tests/cases/conformance/jsx/file.tsx(22,23): error TS2783: 'd' is specified more than once, so this usage will be overwritten. -!!! error TS2318: Cannot find global type 'CallableFunction'. !!! error TS2318: Cannot find global type 'NewableFunction'. ==== tests/cases/conformance/jsx/file.tsx (7 errors) ==== import React = require('react'); diff --git a/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/declarationDir-is-specified.js b/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/declarationDir-is-specified.js index e3fc789404c06..95dd4f1b18ce0 100644 --- a/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/declarationDir-is-specified.js +++ b/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/declarationDir-is-specified.js @@ -134,14 +134,10 @@ Output:: error TS2318: Cannot find global type 'Boolean'. -error TS2318: Cannot find global type 'CallableFunction'. - error TS2318: Cannot find global type 'Function'. error TS2318: Cannot find global type 'IArguments'. -error TS2318: Cannot find global type 'NewableFunction'. - error TS2318: Cannot find global type 'Number'. error TS2318: Cannot find global type 'Object'. @@ -159,7 +155,7 @@ Output::    ~~~~~~~~ File is default library for target specified here. -[12:00:40 AM] Found 11 errors. Watching for file changes. +[12:00:40 AM] Found 9 errors. Watching for file changes. @@ -269,14 +265,10 @@ Output:: error TS2318: Cannot find global type 'Boolean'. -error TS2318: Cannot find global type 'CallableFunction'. - error TS2318: Cannot find global type 'Function'. error TS2318: Cannot find global type 'IArguments'. -error TS2318: Cannot find global type 'NewableFunction'. - error TS2318: Cannot find global type 'Number'. error TS2318: Cannot find global type 'Object'. @@ -294,7 +286,7 @@ Output::    ~~~~~~~~ File is default library for target specified here. -[12:00:48 AM] Found 11 errors. Watching for file changes. +[12:00:48 AM] Found 9 errors. Watching for file changes. diff --git a/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/when-outDir-and-declarationDir-is-specified.js b/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/when-outDir-and-declarationDir-is-specified.js index 620c42fa2a32c..dddc59ba07bcc 100644 --- a/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/when-outDir-and-declarationDir-is-specified.js +++ b/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/when-outDir-and-declarationDir-is-specified.js @@ -134,14 +134,10 @@ Output:: error TS2318: Cannot find global type 'Boolean'. -error TS2318: Cannot find global type 'CallableFunction'. - error TS2318: Cannot find global type 'Function'. error TS2318: Cannot find global type 'IArguments'. -error TS2318: Cannot find global type 'NewableFunction'. - error TS2318: Cannot find global type 'Number'. error TS2318: Cannot find global type 'Object'. @@ -159,7 +155,7 @@ Output::    ~~~~~~~~ File is default library for target specified here. -[12:00:46 AM] Found 11 errors. Watching for file changes. +[12:00:46 AM] Found 9 errors. Watching for file changes. @@ -269,14 +265,10 @@ Output:: error TS2318: Cannot find global type 'Boolean'. -error TS2318: Cannot find global type 'CallableFunction'. - error TS2318: Cannot find global type 'Function'. error TS2318: Cannot find global type 'IArguments'. -error TS2318: Cannot find global type 'NewableFunction'. - error TS2318: Cannot find global type 'Number'. error TS2318: Cannot find global type 'Object'. @@ -294,7 +286,7 @@ Output::    ~~~~~~~~ File is default library for target specified here. -[12:00:54 AM] Found 11 errors. Watching for file changes. +[12:00:54 AM] Found 9 errors. Watching for file changes. diff --git a/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/when-outDir-is-specified.js b/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/when-outDir-is-specified.js index 6800711e1a42f..d20ab69c4d003 100644 --- a/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/when-outDir-is-specified.js +++ b/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/when-outDir-is-specified.js @@ -134,14 +134,10 @@ Output:: error TS2318: Cannot find global type 'Boolean'. -error TS2318: Cannot find global type 'CallableFunction'. - error TS2318: Cannot find global type 'Function'. error TS2318: Cannot find global type 'IArguments'. -error TS2318: Cannot find global type 'NewableFunction'. - error TS2318: Cannot find global type 'Number'. error TS2318: Cannot find global type 'Object'. @@ -159,7 +155,7 @@ Output::    ~~~~~~~~ File is default library for target specified here. -[12:00:36 AM] Found 11 errors. Watching for file changes. +[12:00:36 AM] Found 9 errors. Watching for file changes. @@ -261,14 +257,10 @@ Output:: error TS2318: Cannot find global type 'Boolean'. -error TS2318: Cannot find global type 'CallableFunction'. - error TS2318: Cannot find global type 'Function'. error TS2318: Cannot find global type 'IArguments'. -error TS2318: Cannot find global type 'NewableFunction'. - error TS2318: Cannot find global type 'Number'. error TS2318: Cannot find global type 'Object'. @@ -286,7 +278,7 @@ Output::    ~~~~~~~~ File is default library for target specified here. -[12:00:42 AM] Found 11 errors. Watching for file changes. +[12:00:42 AM] Found 9 errors. Watching for file changes. diff --git a/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/with-outFile.js b/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/with-outFile.js index 7b96140fceb23..0f5cdb5205d46 100644 --- a/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/with-outFile.js +++ b/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/with-outFile.js @@ -134,14 +134,10 @@ Output:: error TS2318: Cannot find global type 'Boolean'. -error TS2318: Cannot find global type 'CallableFunction'. - error TS2318: Cannot find global type 'Function'. error TS2318: Cannot find global type 'IArguments'. -error TS2318: Cannot find global type 'NewableFunction'. - error TS2318: Cannot find global type 'Number'. error TS2318: Cannot find global type 'Object'. @@ -159,7 +155,7 @@ Output::    ~~~~~~~~ File is default library for target specified here. -[12:00:31 AM] Found 11 errors. Watching for file changes. +[12:00:31 AM] Found 9 errors. Watching for file changes. @@ -256,14 +252,10 @@ Output:: error TS2318: Cannot find global type 'Boolean'. -error TS2318: Cannot find global type 'CallableFunction'. - error TS2318: Cannot find global type 'Function'. error TS2318: Cannot find global type 'IArguments'. -error TS2318: Cannot find global type 'NewableFunction'. - error TS2318: Cannot find global type 'Number'. error TS2318: Cannot find global type 'Object'. @@ -281,7 +273,7 @@ Output::    ~~~~~~~~ File is default library for target specified here. -[12:00:38 AM] Found 11 errors. Watching for file changes. +[12:00:38 AM] Found 9 errors. Watching for file changes. diff --git a/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/without-outDir-or-outFile-is-specified-with-declaration-enabled.js b/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/without-outDir-or-outFile-is-specified-with-declaration-enabled.js index 1b21f2ca83fcc..99fcffdb3d621 100644 --- a/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/without-outDir-or-outFile-is-specified-with-declaration-enabled.js +++ b/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/without-outDir-or-outFile-is-specified-with-declaration-enabled.js @@ -134,14 +134,10 @@ Output:: error TS2318: Cannot find global type 'Boolean'. -error TS2318: Cannot find global type 'CallableFunction'. - error TS2318: Cannot find global type 'Function'. error TS2318: Cannot find global type 'IArguments'. -error TS2318: Cannot find global type 'NewableFunction'. - error TS2318: Cannot find global type 'Number'. error TS2318: Cannot find global type 'Object'. @@ -159,7 +155,7 @@ Output::    ~~~~~~~~ File is default library for target specified here. -[12:00:34 AM] Found 11 errors. Watching for file changes. +[12:00:34 AM] Found 9 errors. Watching for file changes. @@ -269,14 +265,10 @@ Output:: error TS2318: Cannot find global type 'Boolean'. -error TS2318: Cannot find global type 'CallableFunction'. - error TS2318: Cannot find global type 'Function'. error TS2318: Cannot find global type 'IArguments'. -error TS2318: Cannot find global type 'NewableFunction'. - error TS2318: Cannot find global type 'Number'. error TS2318: Cannot find global type 'Object'. @@ -294,7 +286,7 @@ Output::    ~~~~~~~~ File is default library for target specified here. -[12:00:42 AM] Found 11 errors. Watching for file changes. +[12:00:42 AM] Found 9 errors. Watching for file changes. diff --git a/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/without-outDir-or-outFile-is-specified.js b/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/without-outDir-or-outFile-is-specified.js index 1b80ab46e46ad..1acfcafc944a2 100644 --- a/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/without-outDir-or-outFile-is-specified.js +++ b/tests/baselines/reference/tscWatch/programUpdates/should-not-trigger-recompilation-because-of-program-emit/without-outDir-or-outFile-is-specified.js @@ -134,14 +134,10 @@ Output:: error TS2318: Cannot find global type 'Boolean'. -error TS2318: Cannot find global type 'CallableFunction'. - error TS2318: Cannot find global type 'Function'. error TS2318: Cannot find global type 'IArguments'. -error TS2318: Cannot find global type 'NewableFunction'. - error TS2318: Cannot find global type 'Number'. error TS2318: Cannot find global type 'Object'. @@ -159,7 +155,7 @@ Output::    ~~~~~~~~ File is default library for target specified here. -[12:00:30 AM] Found 11 errors. Watching for file changes. +[12:00:30 AM] Found 9 errors. Watching for file changes. @@ -261,14 +257,10 @@ Output:: error TS2318: Cannot find global type 'Boolean'. -error TS2318: Cannot find global type 'CallableFunction'. - error TS2318: Cannot find global type 'Function'. error TS2318: Cannot find global type 'IArguments'. -error TS2318: Cannot find global type 'NewableFunction'. - error TS2318: Cannot find global type 'Number'. error TS2318: Cannot find global type 'Object'. @@ -286,7 +278,7 @@ Output::    ~~~~~~~~ File is default library for target specified here. -[12:00:36 AM] Found 11 errors. Watching for file changes. +[12:00:36 AM] Found 9 errors. Watching for file changes. From f5134a545c5ab657087828e92c3999dc02af037d Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Wed, 13 Jul 2022 15:55:46 -0700 Subject: [PATCH 02/24] Per-file strictNullChecks support --- src/compiler/checker.ts | 641 +++++++++++------- src/compiler/types.ts | 12 +- src/services/codefixes/inferFromUsage.ts | 92 ++- .../reference/api/tsserverlibrary.d.ts | 2 +- tests/baselines/reference/api/typescript.d.ts | 2 +- ...nalNoInfiniteInstantiationDepth.errors.txt | 146 ++-- .../reference/collectionPatternNoError.types | 2 +- .../reference/conditionalTypes2.errors.txt | 1 - ...peDistributivityPreservesConstraints.types | 2 +- ...ata_isolatedModules(module=commonjs).types | 2 +- ...adata_isolatedModules(module=esnext).types | 2 +- ...wnNotAssignableToConcreteObject.errors.txt | 5 +- .../inDoesNotOperateOnPrimitiveTypes.types | 4 +- .../reference/intersectionReduction.types | 20 +- .../localTypeParameterInferencePriority.types | 2 +- .../mappedTypeRelationships.errors.txt | 14 + .../reference/metadataOfUnionWithNull.types | 2 +- .../reference/noImplicitAnyForIn.types | 4 +- .../nonNullableReductionNonStrict.types | 16 +- ...nullishCoalescingOperator_not_strict.types | 8 +- ...teFieldAssignabilityFromUnknown.errors.txt | 5 +- ...sOnTypeParameterWithoutConstraints.symbols | 1 - ...ferredInferenceAllowsAssignment.errors.txt | 146 ++-- .../spellingSuggestionJSXAttribute.types | 8 +- .../reference/typeGuardTypeOfUndefined.types | 6 +- ...peParameterExplicitlyExtendsAny.errors.txt | 8 +- .../useUnknownInCatchVariables01.errors.txt | 4 +- .../codeFixInferFromUsageCallBodyBoth.ts | 2 +- ...efactorConvertToGetAccessAndSetAccess10.ts | 6 +- 29 files changed, 729 insertions(+), 436 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 07e11b75eea24..36dfec91d839f 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -359,7 +359,7 @@ namespace ts { const moduleKind = getEmitModuleKind(compilerOptions); const useDefineForClassFields = getUseDefineForClassFields(compilerOptions); const allowSyntheticDefaultImports = getAllowSyntheticDefaultImports(compilerOptions); - const strictNullChecks = getStrictOptionValue(/*file*/ undefined, compilerOptions, "strictNullChecks"); // TODO: file-local-ness + const strictNullChecks = (context: Node | undefined) => getStrictOptionValue(context && getSourceFileOfNode(context), compilerOptions, "strictNullChecks"); const strictFunctionTypes = (file: SourceFile | undefined) => getStrictOptionValue(file, compilerOptions, "strictFunctionTypes"); const strictBindCallApply = (file: SourceFile | undefined) => getStrictOptionValue(file, compilerOptions, "strictBindCallApply"); const strictPropertyInitialization = (file: SourceFile) => getStrictOptionValue(file, compilerOptions, "strictPropertyInitialization"); @@ -633,8 +633,8 @@ namespace ts { getFalseType: (fresh?) => fresh ? falseType : regularFalseType, getTrueType: (fresh?) => fresh ? trueType : regularTrueType, getVoidType: () => voidType, - getUndefinedType: () => undefinedType, - getNullType: () => nullType, + getUndefinedType: (widening?: boolean) => widening ? undefinedWideningType : undefinedType, + getNullType: (widening?: boolean) => widening ? nullWideningType : nullType, getESSymbolType: () => esSymbolType, getNeverType: () => neverType, getOptionalType: () => optionalType, @@ -793,12 +793,16 @@ namespace ts { const unknownType = createIntrinsicType(TypeFlags.Unknown, "unknown"); const nonNullUnknownType = createIntrinsicType(TypeFlags.Unknown, "unknown"); const undefinedType = createIntrinsicType(TypeFlags.Undefined, "undefined"); - const undefinedWideningType = strictNullChecks ? undefinedType : createIntrinsicType(TypeFlags.Undefined, "undefined", ObjectFlags.ContainsWideningType); + const undefinedPermissiveType = createIntrinsicType(TypeFlags.Undefined, "undefined"); + const undefinedWideningType = createIntrinsicType(TypeFlags.Undefined, "undefined", ObjectFlags.ContainsWideningType); + const getUndefinedWideningType = (context: Node | undefined) => strictNullChecks(context) ? undefinedType : undefinedWideningType; const optionalType = createIntrinsicType(TypeFlags.Undefined, "undefined"); const missingType = createIntrinsicType(TypeFlags.Undefined, "undefined"); const getMissingOrUndefinedType = (context: Node | undefined) => exactOptionalPropertyTypes(context) ? missingType : undefinedType; const nullType = createIntrinsicType(TypeFlags.Null, "null"); - const nullWideningType = strictNullChecks ? nullType : createIntrinsicType(TypeFlags.Null, "null", ObjectFlags.ContainsWideningType); + const nullWideningType = createIntrinsicType(TypeFlags.Null, "null", ObjectFlags.ContainsWideningType); + const nullPermissiveType = createIntrinsicType(TypeFlags.Null, "null"); + const getNullWideningType = (context: Node | undefined) => strictNullChecks(context) ? nullType : nullWideningType; const stringType = createIntrinsicType(TypeFlags.String, "string"); const numberType = createIntrinsicType(TypeFlags.Number, "number"); const bigintType = createIntrinsicType(TypeFlags.BigInt, "bigint"); @@ -855,7 +859,7 @@ namespace ts { emptyTypeLiteralSymbol.members = createSymbolTable(); const emptyTypeLiteralType = createAnonymousType(emptyTypeLiteralSymbol, emptySymbols, emptyArray, emptyArray, emptyArray); - const unknownUnionType = strictNullChecks ? getUnionType([undefinedType, nullType, createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, emptyArray)]) : unknownType; + const unknownUnionType = getUnionType([undefinedType, nullType, createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, emptyArray)]); const emptyGenericType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, emptyArray) as ObjectType as GenericType; emptyGenericType.instantiations = new Map(); @@ -6079,7 +6083,7 @@ namespace ts { let parameterType = getTypeOfSymbol(parameterSymbol); if (parameterDeclaration && isRequiredInitializedParameter(parameterDeclaration)) { - parameterType = getOptionalType(parameterType); + parameterType = getOptionalType(parameterType, context.enclosingDeclaration); } const parameterTypeNode = serializeTypeForDeclaration(context, parameterType, parameterSymbol, context.enclosingDeclaration, privateSymbolVisitor, bundledImports); @@ -6742,7 +6746,7 @@ namespace ts { return true; } if (isParameter(annotatedDeclaration) && annotatedDeclaration.questionToken) { - return getTypeWithFacts(type, TypeFacts.NEUndefined) === typeFromTypeNode; + return getTypeWithFacts(type, TypeFacts.NEUndefined, typeNode) === typeFromTypeNode; } return false; } @@ -8875,9 +8879,9 @@ namespace ts { return !!(type.flags & TypeFlags.Instantiable) && maybeTypeOfKind(getBaseConstraintOfType(type) || unknownType, TypeFlags.Undefined); } - function getNonUndefinedType(type: Type) { + function getNonUndefinedType(type: Type, context: Node) { const typeOrConstraint = someType(type, isGenericTypeWithUndefinedConstraint) ? mapType(type, t => t.flags & TypeFlags.Instantiable ? getBaseConstraintOrType(t) : t) : type; - return getTypeWithFacts(typeOrConstraint, TypeFacts.NEUndefined); + return getTypeWithFacts(typeOrConstraint, TypeFacts.NEUndefined, context); } // Determine the control flow type associated with a destructuring declaration or assignment. The following @@ -8958,19 +8962,19 @@ namespace ts { } const pattern = declaration.parent; // Relax null check on ambient destructuring parameters, since the parameters have no implementation and are just documentation - if (strictNullChecks && declaration.flags & NodeFlags.Ambient && isParameterDeclaration(declaration)) { - parentType = getNonNullableType(parentType); + if (strictNullChecks(declaration) && declaration.flags & NodeFlags.Ambient && isParameterDeclaration(declaration)) { + parentType = getNonNullableType(parentType, declaration); } // Filter `undefined` from the type we check against if the parent has an initializer and that initializer is not possibly `undefined` - else if (strictNullChecks && pattern.parent.initializer && !(getTypeFacts(getTypeOfInitializer(pattern.parent.initializer)) & TypeFacts.EQUndefined)) { - parentType = getTypeWithFacts(parentType, TypeFacts.NEUndefined); + else if (strictNullChecks(declaration) && pattern.parent.initializer && !(getTypeFacts(getTypeOfInitializer(pattern.parent.initializer), declaration) & TypeFacts.EQUndefined)) { + parentType = getTypeWithFacts(parentType, TypeFacts.NEUndefined, declaration); } let type: Type | undefined; if (pattern.kind === SyntaxKind.ObjectBindingPattern) { if (declaration.dotDotDotToken) { parentType = getReducedType(parentType); - if (parentType.flags & TypeFlags.Unknown || !isValidSpreadType(parentType)) { + if (parentType.flags & TypeFlags.Unknown || !isValidSpreadType(parentType, declaration)) { error(declaration, Diagnostics.Rest_types_may_only_be_created_from_object_types); return errorType; } @@ -9020,9 +9024,9 @@ namespace ts { if (getEffectiveTypeAnnotationNode(walkUpBindingElementsAndPatterns(declaration))) { // In strict null checking mode, if a default value of a non-undefined type is specified, remove // undefined from the final type. - return strictNullChecks && !(getTypeFacts(checkDeclarationInitializer(declaration, CheckMode.Normal)) & TypeFacts.IsUndefined) ? getNonUndefinedType(type) : type; + return strictNullChecks(declaration) && !(getTypeFacts(checkDeclarationInitializer(declaration, CheckMode.Normal), declaration) & TypeFacts.IsUndefined) ? getNonUndefinedType(type, declaration) : type; } - return widenTypeInferredFromInitializer(declaration, getUnionType([getNonUndefinedType(type), checkDeclarationInitializer(declaration, CheckMode.Normal)], UnionReduction.Subtype)); + return widenTypeInferredFromInitializer(declaration, getUnionType([getNonUndefinedType(type, declaration), checkDeclarationInitializer(declaration, CheckMode.Normal)], UnionReduction.Subtype)); } function getTypeForDeclarationFromJSDocComment(declaration: Node) { @@ -9043,8 +9047,8 @@ namespace ts { return expr.kind === SyntaxKind.ArrayLiteralExpression && (expr as ArrayLiteralExpression).elements.length === 0; } - function addOptionality(type: Type, isProperty: Node | undefined = undefined, isOptional = true): Type { - return strictNullChecks && isOptional ? getOptionalType(type, isProperty) : type; + function addOptionality(type: Type, context: Node | undefined, isProperty = false, isOptional = true): Type { + return strictNullChecks(context) && isOptional ? getOptionalType(type, context, isProperty) : type; } // Return the inferred type for a variable, parameter, or property declaration @@ -9056,7 +9060,7 @@ namespace ts { // A variable declared in a for..in statement is of type string, or of type keyof T when the // right hand expression is of a type parameter type. if (isVariableDeclaration(declaration) && declaration.parent.parent.kind === SyntaxKind.ForInStatement) { - const indexType = getIndexType(getNonNullableTypeIfNeeded(checkExpression(declaration.parent.parent.expression, /*checkMode*/ checkMode))); + const indexType = getIndexType(getNonNullableTypeIfNeeded(checkExpression(declaration.parent.parent.expression, /*checkMode*/ checkMode), declaration)); return indexType.flags & (TypeFlags.TypeParameter | TypeFlags.Index) ? getExtractStringType(indexType) : stringType; } @@ -9082,7 +9086,7 @@ namespace ts { // Use type from type annotation if one is present const declaredType = tryGetTypeFromEffectiveTypeNode(declaration); if (declaredType) { - return addOptionality(declaredType, isProperty ? declaration : undefined, isOptional); + return addOptionality(declaredType, declaration, isProperty, isOptional); } if ((noImplicitAny(declaration) || isInJSFile(declaration)) && @@ -9122,7 +9126,7 @@ namespace ts { // Use contextual parameter type if one is available const type = declaration.symbol.escapedName === InternalSymbolName.This ? getContextualThisParameterType(func) : getContextuallyTypedParameterType(declaration); if (type) { - return addOptionality(type, /*isProperty*/ undefined, isOptional); + return addOptionality(type, declaration, /*isProperty*/ undefined, isOptional); } } @@ -9136,7 +9140,7 @@ namespace ts { } } const type = widenTypeInferredFromInitializer(declaration, checkDeclarationInitializer(declaration, checkMode)); - return addOptionality(type, isProperty ? declaration : undefined, isOptional); + return addOptionality(type, declaration, isProperty, isOptional); } if (isPropertyDeclaration(declaration) && (noImplicitAny(declaration) || isInJSFile(declaration))) { @@ -9147,14 +9151,14 @@ namespace ts { const type = constructor ? getFlowTypeInConstructor(declaration.symbol, constructor) : getEffectiveModifierFlags(declaration) & ModifierFlags.Ambient ? getTypeOfPropertyInBaseClass(declaration.symbol) : undefined; - return type && addOptionality(type, declaration, isOptional); + return type && addOptionality(type, declaration, /*isProperty*/ true, isOptional); } else { const staticBlocks = filter(declaration.parent.members, isClassStaticBlockDeclaration); const type = staticBlocks.length ? getFlowTypeInStaticBlocks(declaration.symbol, staticBlocks) : getEffectiveModifierFlags(declaration) & ModifierFlags.Ambient ? getTypeOfPropertyInBaseClass(declaration.symbol) : undefined; - return type && addOptionality(type, declaration, isOptional); + return type && addOptionality(type, declaration, /*isProperty*/ true, isOptional); } } @@ -9244,7 +9248,7 @@ namespace ts { error(symbol.valueDeclaration, Diagnostics.Member_0_implicitly_has_an_1_type, symbolToString(symbol), typeToString(flowType)); } // We don't infer a type if assignments are only null or undefined. - if (everyType(flowType, isNullableType)) { + if (everyType(flowType, t => isNullableType(t, reference))) { continue; } return convertAutoToAny(flowType); @@ -9264,7 +9268,7 @@ namespace ts { error(symbol.valueDeclaration, Diagnostics.Member_0_implicitly_has_an_1_type, symbolToString(symbol), typeToString(flowType)); } // We don't infer a type if assignments are only null or undefined. - return everyType(flowType, isNullableType) ? undefined : convertAutoToAny(flowType); + return everyType(flowType, t => isNullableType(t, reference)) ? undefined : convertAutoToAny(flowType); } function getFlowTypeOfProperty(reference: Node, prop: Symbol | undefined) { @@ -9343,7 +9347,7 @@ namespace ts { type = getUnionType(sourceTypes!); } } - const widened = getWidenedType(addOptionality(type, /*isProperty*/ undefined, definedInMethod && !definedInConstructor)); + const widened = getWidenedType(addOptionality(type, container, /*isProperty*/ false, definedInMethod && !definedInConstructor)); if (symbol.valueDeclaration && filterType(widened, t => !!(t.flags & ~TypeFlags.Nullable)) === neverType) { reportImplicitAny(symbol.valueDeclaration, anyType); return anyType; @@ -9542,7 +9546,7 @@ namespace ts { // contextual type or, if the element itself is a binding pattern, with the type implied by that binding // pattern. const contextualType = isBindingPattern(element.name) ? getTypeFromBindingPattern(element.name, /*includePatternInType*/ true, /*reportErrors*/ false) : unknownType; - return addOptionality(widenTypeInferredFromInitializer(element, checkDeclarationInitializer(element, CheckMode.Normal, contextualType))); + return addOptionality(widenTypeInferredFromInitializer(element, checkDeclarationInitializer(element, CheckMode.Normal, contextualType)), element, /*isProperty*/ true); } if (isBindingPattern(element.name)) { return getTypeFromBindingPattern(element.name, includePatternInType, reportErrors); @@ -9963,7 +9967,7 @@ namespace ts { return baseTypeVariable ? getIntersectionType([type, baseTypeVariable]) : type; } else { - return strictNullChecks && symbol.flags & SymbolFlags.Optional ? getOptionalType(type) : type; + return strictNullChecks(declaration) && symbol.flags & SymbolFlags.Optional ? getOptionalType(type, declaration) : type; } } @@ -11843,7 +11847,7 @@ namespace ts { !(templateModifiers & MappedTypeModifiers.ExcludeOptional) && modifiersProp && modifiersProp.flags & SymbolFlags.Optional); const isReadonly = !!(templateModifiers & MappedTypeModifiers.IncludeReadonly || !(templateModifiers & MappedTypeModifiers.ExcludeReadonly) && modifiersProp && isReadonlySymbol(modifiersProp)); - const stripOptional = strictNullChecks && !isOptional && modifiersProp && modifiersProp.flags & SymbolFlags.Optional; + const stripOptional = strictNullChecks(type.declaration) && !isOptional && modifiersProp && modifiersProp.flags & SymbolFlags.Optional; const lateFlag: CheckFlags = modifiersProp ? getIsLateCheckFlag(modifiersProp) : 0; const prop = createSymbol(SymbolFlags.Property | (isOptional ? SymbolFlags.Optional : 0), propName, lateFlag | CheckFlags.Mapped | (isReadonly ? CheckFlags.Readonly : 0) | (stripOptional ? CheckFlags.StripOptional : 0)) as MappedSymbol; @@ -11883,7 +11887,7 @@ namespace ts { // When creating an optional property in strictNullChecks mode, if 'undefined' isn't assignable to the // type, we include 'undefined' in the type. Similarly, when creating a non-optional property in strictNullChecks // mode, if the underlying property is optional we remove 'undefined' from the type. - let type = strictNullChecks && symbol.flags & SymbolFlags.Optional && !maybeTypeOfKind(propType, TypeFlags.Undefined | TypeFlags.Void) ? getOptionalType(propType, mappedType.declaration) : + let type = strictNullChecks(mappedType.declaration) && symbol.flags & SymbolFlags.Optional && !maybeTypeOfKind(propType, TypeFlags.Undefined | TypeFlags.Void) ? getOptionalType(propType, mappedType.declaration, /*isProperty*/ true) : symbol.checkFlags & CheckFlags.StripOptional ? removeMissingOrUndefinedType(propType, mappedType.declaration) : propType; if (!popTypeResolution()) { @@ -11914,7 +11918,7 @@ namespace ts { function getTemplateTypeFromMappedType(type: MappedType) { return type.templateType || (type.templateType = type.declaration.type ? - instantiateType(addOptionality(getTypeFromTypeNode(type.declaration.type), type.declaration, !!(getMappedTypeModifiers(type) & MappedTypeModifiers.IncludeOptional)), type.mapper) : + instantiateType(addOptionality(getTypeFromTypeNode(type.declaration.type), type.declaration, /*isProperty*/ true, !!(getMappedTypeModifiers(type) & MappedTypeModifiers.IncludeOptional)), type.mapper) : errorType); } @@ -12107,6 +12111,10 @@ namespace ts { getBaseConstraintOfType(type); } + function getUnknownConstraintForType(type: Type): Type { + return !strictNullChecks(type.symbol?.declarations?.[0] || type.aliasSymbol?.declarations?.[0]) ? nonNullUnknownType : unknownType; + } + function getConstraintOfTypeParameter(typeParameter: TypeParameter): Type | undefined { return hasNonCircularBaseConstraint(typeParameter) ? getConstraintFromTypeParameter(typeParameter) : undefined; } @@ -12441,7 +12449,7 @@ namespace ts { * type itself. */ function getApparentType(type: Type): Type { - const t = !(type.flags & TypeFlags.Instantiable) ? type : getBaseConstraintOfType(type) || unknownType; + const t = !(type.flags & TypeFlags.Instantiable) ? type : getBaseConstraintOfType(type) || getUnknownConstraintForType(type); return getObjectFlags(t) & ObjectFlags.Mapped ? getApparentTypeOfMappedType(t as MappedType) : t.flags & TypeFlags.Intersection ? getApparentTypeOfIntersectionType(t as IntersectionType) : t.flags & TypeFlags.StringLike ? globalStringType : @@ -12451,7 +12459,7 @@ namespace ts { t.flags & TypeFlags.ESSymbolLike ? getGlobalESSymbolType() : t.flags & TypeFlags.NonPrimitive ? emptyObjectType : t.flags & TypeFlags.Index ? keyofConstraintType : - t.flags & TypeFlags.Unknown && !strictNullChecks ? emptyObjectType : + t === nonNullUnknownType ? emptyObjectType : t; } @@ -12528,11 +12536,11 @@ namespace ts { const indexInfo = !isLateBoundName(name) && getApplicableIndexInfoForName(type, name); if (indexInfo) { checkFlags |= CheckFlags.WritePartial | (indexInfo.isReadonly ? CheckFlags.Readonly : 0); - indexTypes = append(indexTypes, isTupleType(type) ? getRestTypeOfTupleType(type) || undefinedType : indexInfo.type); + indexTypes = append(indexTypes, isTupleType(type) ? getRestTypeOfTupleType(type) || (strictNullChecks(indexInfo.declaration) ? undefinedType : neverType) : indexInfo.type); } else if (isObjectLiteralType(type) && !(getObjectFlags(type) & ObjectFlags.ContainsSpread)) { checkFlags |= CheckFlags.WritePartial; - indexTypes = append(indexTypes, undefinedType); + indexTypes = append(indexTypes, strictNullChecks(type.symbol.valueDeclaration) ? undefinedType : neverType); } else { checkFlags |= CheckFlags.ReadPartial; @@ -13248,10 +13256,10 @@ namespace ts { getReturnTypeFromAnnotation(signature.declaration!) || (nodeIsMissing((signature.declaration as FunctionLikeDeclaration).body) ? anyType : getReturnTypeFromBody(signature.declaration as FunctionLikeDeclaration)); if (signature.flags & SignatureFlags.IsInnerCallChain) { - type = addOptionalTypeMarker(type); + type = addOptionalTypeMarker(type, signature.declaration); } else if (signature.flags & SignatureFlags.IsOuterCallChain) { - type = getOptionalType(type); + type = strictNullChecks(signature.declaration) ? getOptionalType(type, signature.declaration) : type; } if (!popTypeResolution()) { if (signature.declaration) { @@ -14017,7 +14025,7 @@ namespace ts { function getTypeFromJSDocNullableTypeNode(node: JSDocNullableType) { const type = getTypeFromTypeNode(node.type); - return strictNullChecks ? getNullableType(type, TypeFlags.Null) : type; + return strictNullChecks(node) ? getNullableType(type, TypeFlags.Null) : type; } function getTypeFromTypeReference(node: TypeReferenceType): Type { @@ -14616,7 +14624,7 @@ namespace ts { } function getTypeFromOptionalTypeNode(node: OptionalTypeNode): Type { - return addOptionality(getTypeFromTypeNode(node.type), node); + return addOptionality(getTypeFromTypeNode(node.type), node, /*isProperty*/ true); } function getTypeId(type: Type): TypeId { @@ -14636,37 +14644,64 @@ namespace ts { return false; } - function addTypeToUnion(typeSet: Type[], includes: TypeFlags, type: Type) { - const flags = type.flags; - if (flags & TypeFlags.Union) { - return addTypesToUnion(typeSet, includes | (isNamedUnionType(type) ? TypeFlags.Union : 0), (type as UnionType).types); - } - // We ignore 'never' types in unions - if (!(flags & TypeFlags.Never)) { - includes |= flags & TypeFlags.IncludesMask; - if (flags & TypeFlags.Instantiable) includes |= TypeFlags.IncludesInstantiable; - if (type === wildcardType) includes |= TypeFlags.IncludesWildcard; - if (!strictNullChecks && flags & TypeFlags.Nullable) { - if (!(getObjectFlags(type) & ObjectFlags.ContainsWideningType)) includes |= TypeFlags.IncludesNonWideningType; - } - else { - const len = typeSet.length; - const index = len && type.id > typeSet[len - 1].id ? ~len : binarySearch(typeSet, type, getTypeId, compareValues); - if (index < 0) { - typeSet.splice(~index, 0, type); - } - } + function addTypeToListSorted(typeSet: Type[], type: Type) { + const len = typeSet.length; + const index = len && type.id > typeSet[len - 1].id ? ~len : binarySearch(typeSet, type, getTypeId, compareValues); + if (index < 0) { + typeSet.splice(~index, 0, type); } - return includes; } // Add the given types to the given type set. Order is preserved, duplicates are removed, // and nested types of the given kind are flattened into the set. function addTypesToUnion(typeSet: Type[], includes: TypeFlags, types: readonly Type[]): TypeFlags { - for (const type of types) { - includes = addTypeToUnion(typeSet, includes, type); + let undefinedVariant: Type | undefined; + includes = addTypesToUnionWorker(typeSet, includes, types); + if (includes & TypeFlags.Null) { + if (includes & TypeFlags.IncludesNonWideningType) { + addTypeToListSorted(typeSet, includes & TypeFlags.IncludesNonWideningType ? nullType : nullWideningType); + } + } + if (includes & TypeFlags.Undefined) { + if (includes & TypeFlags.IncludesNonWideningType) { + addTypeToListSorted(typeSet, includes & TypeFlags.IncludesNonWideningType ? undefinedVariant || undefinedType : undefinedWideningType); + } } return includes; + + + function addTypeToUnion(typeSet: Type[], includes: TypeFlags, type: Type) { + const flags = type.flags; + if (flags & TypeFlags.Union) { + return addTypesToUnionWorker(typeSet, includes | (isNamedUnionType(type) ? TypeFlags.Union : 0), (type as UnionType).types); + } + // We ignore 'never' types in unions + if (!(flags & TypeFlags.Never)) { + includes |= flags & TypeFlags.IncludesMask; + if (flags & TypeFlags.Instantiable) includes |= TypeFlags.IncludesInstantiable; + if (type === wildcardType) includes |= TypeFlags.IncludesWildcard; + if (flags & TypeFlags.Nullable) { + if (!(getObjectFlags(type) & ObjectFlags.ContainsWideningType)) { + includes |= TypeFlags.IncludesNonWideningType; + if (flags & TypeFlags.Undefined) { + if (!undefinedVariant) undefinedVariant = type; + else undefinedVariant = undefinedType; // multiple of the missing, optional, or base undefined types combine to just normal undefined + } + } + } + else { + addTypeToListSorted(typeSet, type); + } + } + return includes; + } + + function addTypesToUnionWorker(typeSet: Type[], includes: TypeFlags, types: readonly Type[]): TypeFlags { + for (const type of types) { + includes = addTypeToUnion(typeSet, includes, type); + } + return includes; + } } function removeSubtypes(types: Type[], hasObjectTypes: boolean): Type[] | undefined { @@ -14936,12 +14971,25 @@ namespace ts { const links = getNodeLinks(node); if (!links.resolvedType) { const aliasSymbol = getAliasSymbolForTypeNode(node); - links.resolvedType = getUnionType(map(node.types, getTypeFromTypeNode), UnionReduction.Literal, + links.resolvedType = getUnionType(map(node.types, getTypeFromUnionMemberTypeNode), UnionReduction.Literal, aliasSymbol, getTypeArgumentsForAliasSymbol(aliasSymbol)); } return links.resolvedType; } + /** + * This is a syntactic approximation of the longstanding non-strictNullChecks behavior of unions with null/undefined + * eliminating the null/undefined upon construction. By doing it at type construction site, we can get per-file behavior. + * The downside is that a helper like `type Union = T | U` isn't affected by this, and so will preserve null/undefined + * arguments where it wouldn't have before. + */ + function getTypeFromUnionMemberTypeNode(node: TypeNode) { + if (strictNullChecks(node) || !((isLiteralTypeNode(node) && isNullOrUndefined(node.literal)) || isNullOrUndefined(node as Node as Expression) || node.kind === SyntaxKind.UndefinedKeyword)) { + return getTypeFromTypeNode(node); + } + return neverType; + } + function addTypeToIntersection(typeSet: ESMap, includes: TypeFlags, type: Type) { const flags = type.flags; if (flags & TypeFlags.Intersection) { @@ -14957,7 +15005,7 @@ namespace ts { if (flags & TypeFlags.AnyOrUnknown) { if (type === wildcardType) includes |= TypeFlags.IncludesWildcard; } - else if (strictNullChecks || !(flags & TypeFlags.Nullable)) { + else { if (type === missingType) { includes |= TypeFlags.IncludesMissingType; type = undefinedType; @@ -15132,17 +15180,19 @@ namespace ts { // a number-like type and a type known to be non-number-like, or // a symbol-like type and a type known to be non-symbol-like, or // a void-like type and a type known to be non-void-like, or - // a non-primitive type and a type known to be primitive. + // a non-primitive type and a type known to be primitive, or + // an index type and a nullable or bigint-like type. if (includes & TypeFlags.Never) { return contains(typeSet, silentNeverType) ? silentNeverType : neverType; } - if (strictNullChecks && includes & TypeFlags.Nullable && includes & (TypeFlags.Object | TypeFlags.NonPrimitive | TypeFlags.IncludesEmptyObject) || + if (includes & TypeFlags.Nullable && includes & (TypeFlags.Object | TypeFlags.NonPrimitive | TypeFlags.IncludesEmptyObject) || includes & TypeFlags.NonPrimitive && includes & (TypeFlags.DisjointDomains & ~TypeFlags.NonPrimitive) || includes & TypeFlags.StringLike && includes & (TypeFlags.DisjointDomains & ~TypeFlags.StringLike) || includes & TypeFlags.NumberLike && includes & (TypeFlags.DisjointDomains & ~TypeFlags.NumberLike) || includes & TypeFlags.BigIntLike && includes & (TypeFlags.DisjointDomains & ~TypeFlags.BigIntLike) || includes & TypeFlags.ESSymbolLike && includes & (TypeFlags.DisjointDomains & ~TypeFlags.ESSymbolLike) || - includes & TypeFlags.VoidLike && includes & (TypeFlags.DisjointDomains & ~TypeFlags.VoidLike)) { + includes & TypeFlags.VoidLike && includes & (TypeFlags.DisjointDomains & ~TypeFlags.VoidLike) || + includes & TypeFlags.Index && includes & (TypeFlags.Nullable | TypeFlags.BigIntLike)) { return neverType; } if (includes & TypeFlags.TemplateLiteral && includes & TypeFlags.StringLiteral && extractRedundantTemplateLiterals(typeSet)) { @@ -15151,9 +15201,6 @@ namespace ts { if (includes & TypeFlags.Any) { return includes & TypeFlags.IncludesWildcard ? wildcardType : anyType; } - if (!strictNullChecks && includes & TypeFlags.Nullable) { - return includes & TypeFlags.Undefined ? undefinedType : nullType; - } if (includes & TypeFlags.String && includes & (TypeFlags.StringLiteral | TypeFlags.TemplateLiteral | TypeFlags.StringMapping) || includes & TypeFlags.Number && includes & TypeFlags.NumberLiteral || includes & TypeFlags.BigInt && includes & TypeFlags.BigIntLiteral || @@ -16052,7 +16099,10 @@ namespace ts { // In the following we resolve T[K] to the type of the property in T selected by K. // We treat boolean as different from other unions to improve errors; // skipping straight to getPropertyTypeForIndexType gives errors with 'boolean' instead of 'true'. - const apparentObjectType = getReducedApparentType(objectType); + let apparentObjectType = getReducedApparentType(objectType); + if (!strictNullChecks(accessNode) && apparentObjectType.flags & TypeFlags.Unknown) { + apparentObjectType = emptyObjectType; + } if (indexType.flags & TypeFlags.Union && !(indexType.flags & TypeFlags.Boolean)) { const propTypes: Type[] = []; let wasMissingProp = false; @@ -16521,7 +16571,7 @@ namespace ts { const isSetonlyAccessor = prop.flags & SymbolFlags.SetAccessor && !(prop.flags & SymbolFlags.GetAccessor); const flags = SymbolFlags.Property | SymbolFlags.Optional; const result = createSymbol(flags, prop.escapedName, getIsLateCheckFlag(prop) | (readonly ? CheckFlags.Readonly : 0)); - result.type = isSetonlyAccessor ? undefinedType : addOptionality(getTypeOfSymbol(prop), prop.valueDeclaration || factory.createEmptyStatement()); + result.type = isSetonlyAccessor ? undefinedType : addOptionality(getTypeOfSymbol(prop), prop.declarations?.[0], /*isProperty*/ true); result.declarations = prop.declarations; result.nameType = getSymbolLinks(prop).nameType; result.syntheticOrigin = prop; @@ -16712,7 +16762,7 @@ namespace ts { function getTypeFromLiteralTypeNode(node: LiteralTypeNode): Type { if (node.literal.kind === SyntaxKind.NullKeyword) { - return nullType; + return strictNullChecks(node) ? nullType : nullPermissiveType; } const links = getNodeLinks(node); if (!links.resolvedType) { @@ -16801,7 +16851,7 @@ namespace ts { const links = getNodeLinks(node); return links.resolvedType || (links.resolvedType = node.dotDotDotToken ? getTypeFromRestTypeNode(node) : - addOptionality(getTypeFromTypeNode(node.type), node, !!node.questionToken)); + addOptionality(getTypeFromTypeNode(node.type), node, /*isProperty*/ true, !!node.questionToken)); } function getTypeFromTypeNode(node: TypeNode): Type { @@ -16829,10 +16879,10 @@ namespace ts { case SyntaxKind.VoidKeyword: return voidType; case SyntaxKind.UndefinedKeyword: - return undefinedType; + return strictNullChecks(node) ? undefinedType : undefinedPermissiveType; case SyntaxKind.NullKeyword as TypeNodeSyntaxKind: // TODO(rbuckton): `NullKeyword` is no longer a `TypeNode`, but we defensively allow it here because of incorrect casts in the Language Service. - return nullType; + return strictNullChecks(node) ? nullType : nullPermissiveType; case SyntaxKind.NeverKeyword: return neverType; case SyntaxKind.ObjectKeyword: @@ -16865,7 +16915,7 @@ namespace ts { case SyntaxKind.JSDocNullableType: return getTypeFromJSDocNullableTypeNode(node as JSDocNullableType); case SyntaxKind.JSDocOptionalType: - return addOptionality(getTypeFromTypeNode((node as JSDocOptionalType).type)); + return addOptionality(getTypeFromTypeNode((node as JSDocOptionalType).type), node); case SyntaxKind.NamedTupleMember: return getTypeFromNamedTupleTypeNode(node as NamedTupleMember); case SyntaxKind.ParenthesizedType: @@ -17290,8 +17340,8 @@ namespace ts { const templateMapper = appendTypeMapping(mapper, getTypeParameterFromMappedType(type), key); const propType = instantiateType(getTemplateTypeFromMappedType(type.target as MappedType || type), templateMapper); const modifiers = getMappedTypeModifiers(type); - return strictNullChecks && modifiers & MappedTypeModifiers.IncludeOptional && !maybeTypeOfKind(propType, TypeFlags.Undefined | TypeFlags.Void) ? getOptionalType(propType, type.declaration) : - strictNullChecks && modifiers & MappedTypeModifiers.ExcludeOptional && isOptional ? getTypeWithFacts(propType, TypeFacts.NEUndefined) : + return modifiers & MappedTypeModifiers.IncludeOptional && !maybeTypeOfKind(propType, TypeFlags.Undefined | TypeFlags.Void) ? getOptionalType(propType, type.declaration, /*isProperty*/ false) : + modifiers & MappedTypeModifiers.ExcludeOptional && isOptional ? getTypeWithFacts(propType, TypeFacts.NEUndefined, type.declaration) : propType; } @@ -18196,10 +18246,10 @@ namespace ts { // similar to return values, callback parameters are output positions. This means that a Promise, // where T is used only in callback parameter positions, will be co-variant (as opposed to bi-variant) // with respect to T. - const sourceSig = checkMode & SignatureCheckMode.Callback ? undefined : getSingleCallSignature(getNonNullableType(sourceType)); - const targetSig = checkMode & SignatureCheckMode.Callback ? undefined : getSingleCallSignature(getNonNullableType(targetType)); + const sourceSig = checkMode & SignatureCheckMode.Callback ? undefined : getSingleCallSignature(getNonNullableType(sourceType, sourceFile)); + const targetSig = checkMode & SignatureCheckMode.Callback ? undefined : getSingleCallSignature(getNonNullableType(targetType, targetFile)); const callbacks = sourceSig && targetSig && !getTypePredicateOfSignature(sourceSig) && !getTypePredicateOfSignature(targetSig) && - (getTypeFacts(sourceType) & TypeFacts.IsUndefinedOrNull) === (getTypeFacts(targetType) & TypeFacts.IsUndefinedOrNull); + (getTypeFacts(sourceType, sourceFile) & TypeFacts.IsUndefinedOrNull) === (getTypeFacts(targetType, targetFile) & TypeFacts.IsUndefinedOrNull); let related = callbacks ? compareSignaturesRelated(targetSig, sourceSig, (checkMode & SignatureCheckMode.StrictArity) | (strictVariance ? SignatureCheckMode.StrictCallback : SignatureCheckMode.BivariantCallback), reportErrors, errorReporter, incompatibleErrorReporter, compareTypes, reportUnreliableMarkers) : !(checkMode & SignatureCheckMode.Callback) && !strictVariance && compareTypes(sourceType, targetType, /*reportErrors*/ false) || compareTypes(targetType, sourceType, reportErrors); @@ -18335,7 +18385,7 @@ namespace ts { } function isUnknownLikeUnionType(type: Type) { - if (strictNullChecks && type.flags & TypeFlags.Union) { + if (type.flags & TypeFlags.Union) { if (!((type as UnionType).objectFlags & ObjectFlags.IsUnknownLikeUnionComputed)) { const types = (type as UnionType).types; (type as UnionType).objectFlags |= ObjectFlags.IsUnknownLikeUnionComputed | (types.length >= 3 && types[0].flags & TypeFlags.Undefined && @@ -18415,8 +18465,9 @@ namespace ts { } // In non-strictNullChecks mode, `undefined` and `null` are assignable to anything except `never`. // Since unions and intersections may reduce to `never`, we exclude them here. - if (s & TypeFlags.Undefined && (!strictNullChecks && !(t & TypeFlags.UnionOrIntersection) || t & (TypeFlags.Undefined | TypeFlags.Void))) return true; - if (s & TypeFlags.Null && (!strictNullChecks && !(t & TypeFlags.UnionOrIntersection) || t & TypeFlags.Null)) return true; + if ((source === undefinedWideningType || source === nullWideningType || source === undefinedPermissiveType || source === nullPermissiveType) && !(t & TypeFlags.UnionOrIntersection)) return true; + if (s & TypeFlags.Undefined && t & (TypeFlags.Undefined | TypeFlags.Void)) return true; + if (s & TypeFlags.Null && t & TypeFlags.Null) return true; if (s & TypeFlags.Object && t & TypeFlags.NonPrimitive && !(relation === strictSubtypeRelation && isEmptyAnonymousObjectType(source) && !(getObjectFlags(source) & ObjectFlags.FreshLiteral))) return true; if (relation === assignableRelation || relation === comparableRelation) { if (s & TypeFlags.Any) return true; @@ -18728,7 +18779,9 @@ namespace ts { relatedInfo = [info]; } else { - relatedInfo.push(info); + if (!some(relatedInfo, i => compareDiagnostics(i, info) === Comparison.EqualTo)) { + relatedInfo.push(info); + } } } @@ -19842,13 +19895,13 @@ namespace ts { if (sourceFlags & TypeFlags.TypeVariable) { // IndexedAccess comparisons are handled above in the `targetFlags & TypeFlage.IndexedAccess` branch if (!(sourceFlags & TypeFlags.IndexedAccess && targetFlags & TypeFlags.IndexedAccess)) { - const constraint = getConstraintOfType(source as TypeVariable) || unknownType; + const constraint = getConstraintOfType(source as TypeVariable) || getUnknownConstraintForType(source as TypeVariable); // hi-speed no-this-instantiation check (less accurate, but avoids costly `this`-instantiation when the constraint will suffice), see #28231 for report on why this is needed if (result = isRelatedTo(constraint, target, RecursionFlags.Source, /*reportErrors*/ false, /*headMessage*/ undefined, intersectionState)) { return result; } // slower, fuller, this-instantiated check (necessary when comparing raw `this` types from base classes), see `subclassWithPolymorphicThisIsAssignable.ts` test for example - else if (result = isRelatedTo(getTypeWithThisArgument(constraint, source), target, RecursionFlags.Source, reportErrors && constraint !== unknownType && !(targetFlags & sourceFlags & TypeFlags.TypeParameter), /*headMessage*/ undefined, intersectionState)) { + else if (result = isRelatedTo(getTypeWithThisArgument(constraint, source), target, RecursionFlags.Source, reportErrors && !(constraint.flags & TypeFlags.Unknown) && !(targetFlags & sourceFlags & TypeFlags.TypeParameter), /*headMessage*/ undefined, intersectionState)) { return result; } if (isMappedTypeGenericIndexedAccess(source)) { @@ -20164,7 +20217,7 @@ namespace ts { if (!targetProperty) continue outer; if (sourceProperty === targetProperty) continue; // We compare the source property to the target in the context of a single discriminant type. - const related = propertyRelatedTo(source, target, sourceProperty, targetProperty, _ => combination[i], /*reportErrors*/ false, IntersectionState.None, /*skipOptional*/ strictNullChecks || relation === comparableRelation); + const related = propertyRelatedTo(source, target, sourceProperty, targetProperty, _ => combination[i], /*reportErrors*/ false, IntersectionState.None, /*skipOptional*/ strictNullChecks(targetProperty.valueDeclaration) || relation === comparableRelation); // If the target property could not be found, or if the properties were not related, // then this constituent is not a match. if (!related) { @@ -20221,8 +20274,8 @@ namespace ts { } function isPropertySymbolTypeRelated(sourceProp: Symbol, targetProp: Symbol, getTypeOfSourceProperty: (sym: Symbol) => Type, reportErrors: boolean, intersectionState: IntersectionState): Ternary { - const targetIsOptional = strictNullChecks && !!(getCheckFlags(targetProp) & CheckFlags.Partial); - const effectiveTarget = addOptionality(getNonMissingTypeOfSymbol(targetProp), /*isProperty*/ undefined, targetIsOptional); + const targetIsOptional = strictNullChecks(targetProp.valueDeclaration) && !!(getCheckFlags(targetProp) & CheckFlags.Partial); + const effectiveTarget = addOptionality(getNonMissingTypeOfSymbol(targetProp), targetProp.valueDeclaration, /*isProperty*/ false, targetIsOptional); const effectiveSource = getTypeOfSourceProperty(sourceProp); return isRelatedTo(effectiveSource, effectiveTarget, RecursionFlags.Both, reportErrors, /*headMessage*/ undefined, intersectionState); } @@ -20678,7 +20731,7 @@ namespace ts { const propType = getNonMissingTypeOfSymbol(prop); const type = exactOptionalPropertyTypes(prop.valueDeclaration) || propType.flags & TypeFlags.Undefined || keyType === numberType || !(prop.flags & SymbolFlags.Optional) ? propType - : getTypeWithFacts(propType, TypeFacts.NEUndefined); + : getTypeWithFacts(propType, TypeFacts.NEUndefined, prop.valueDeclaration); const related = isRelatedTo(type, targetInfo.type, RecursionFlags.Both, reportErrors); if (!related) { if (reportErrors) { @@ -20835,7 +20888,8 @@ namespace ts { findMatchingTypeReferenceOrTypeAliasReference(source, target) || findBestTypeForObjectLiteral(source, target) || findBestTypeForInvokable(source, target) || - findMostOverlappyType(source, target); + findMostOverlappyType(source, target) || + (target.types.length === 2 && target.types[0].flags & TypeFlags.Nullable ? target.types[1] : undefined); } function discriminateTypeByDiscriminableItems(target: UnionType, discriminators: [() => Type, __String][], related: (source: Type, target: Type) => boolean | Ternary, defaultValue?: undefined, skipPartial?: boolean): Type | undefined; @@ -21330,12 +21384,12 @@ namespace ts { return reduceLeft(types, (flags, t) => flags | (t.flags & TypeFlags.Union ? getCombinedTypeFlags((t as UnionType).types) : t.flags), 0); } - function getCommonSupertype(types: Type[]): Type { + function getCommonSupertype(types: Type[], context: Node | undefined): Type { if (types.length === 1) { return types[0]; } // Remove nullable types from each of the candidates. - const primaryTypes = strictNullChecks ? sameMap(types, t => filterType(t, u => !(u.flags & TypeFlags.Nullable))) : types; + const primaryTypes = strictNullChecks(context) ? sameMap(types, t => filterType(t, u => !(u.flags & TypeFlags.Nullable))) : types; // When the candidate types are all literal types with the same base type, return a union // of those literal types. Otherwise, return the leftmost type for which no type to the // right is a supertype. @@ -21410,7 +21464,7 @@ namespace ts { } function isEmptyLiteralType(type: Type): boolean { - return strictNullChecks ? type === implicitNeverType : type === undefinedWideningType; + return type === implicitNeverType || type === undefinedWideningType; } function isEmptyArrayLiteralType(type: Type): boolean { @@ -21565,8 +21619,8 @@ namespace ts { return value.base10Value === "0"; } - function removeDefinitelyFalsyTypes(type: Type): Type { - return filterType(type, t => !!(getTypeFacts(t) & TypeFacts.Truthy)); + function removeDefinitelyFalsyTypes(type: Type, context: Node | undefined): Type { + return filterType(type, t => !!(getTypeFacts(t, context) & TypeFacts.Truthy)); } function extractDefinitelyFalsyTypes(type: Type): Type { @@ -21599,9 +21653,14 @@ namespace ts { getUnionType([type, undefinedType, nullType]); } - function getOptionalType(type: Type, property: Node | undefined = undefined): Type { - Debug.assert(strictNullChecks); - return type.flags & TypeFlags.Undefined ? type : getUnionType([type, property ? getMissingOrUndefinedType(property) : undefinedType]); + /** + * *Most* callers should only use this when `strictNullChecks` is known to be `true` for the given `context`, + * as it unconditionally introduces some form of `undefined` into the result. + * An important exception is control-flow-based initialization checking, which sometimes may want to use this + * outside `strictNullChecks` mode. + */ + function getOptionalType(type: Type, context: Node | undefined, isProperty = false): Type { + return type.flags & TypeFlags.Undefined ? type : getUnionType([type, isProperty ? getMissingOrUndefinedType(context) : undefinedType]); } function getGlobalNonNullableTypeInstantiation(type: Type) { @@ -21613,24 +21672,24 @@ namespace ts { getIntersectionType([type, emptyObjectType]); } - function getNonNullableType(type: Type): Type { - return strictNullChecks ? getAdjustedTypeWithFacts(type, TypeFacts.NEUndefinedOrNull) : type; + function getNonNullableType(type: Type, context: Node | undefined): Type { + return getAdjustedTypeWithFacts(type, TypeFacts.NEUndefinedOrNull, context); } - function addOptionalTypeMarker(type: Type) { - return strictNullChecks ? getUnionType([type, optionalType]) : type; + function addOptionalTypeMarker(type: Type, context: Node | undefined) { + return strictNullChecks(context) ? getUnionType([type, optionalType]) : type; } function removeOptionalTypeMarker(type: Type): Type { - return strictNullChecks ? removeType(type, optionalType) : type; + return removeType(type, optionalType); } function propagateOptionalTypeMarker(type: Type, node: OptionalChain, wasOptional: boolean) { - return wasOptional ? isOutermostOptionalChain(node) ? getOptionalType(type) : addOptionalTypeMarker(type) : type; + return wasOptional ? isOutermostOptionalChain(node) ? getOptionalType(type, node) : addOptionalTypeMarker(type, node) : type; } function getOptionalExpressionType(exprType: Type, expression: Expression) { - return isExpressionOfOptionalChainRoot(expression) ? getNonNullableType(exprType) : + return isExpressionOfOptionalChainRoot(expression) ? getNonNullableType(exprType, expression) : isOptionalChain(expression) ? removeOptionalTypeMarker(exprType) : exprType; } @@ -21644,7 +21703,7 @@ namespace ts { } function removeMissingOrUndefinedType(type: Type, context: Node | undefined): Type { - return exactOptionalPropertyTypes(context) ? removeType(type, missingType) : getTypeWithFacts(type, TypeFacts.NEUndefined); + return exactOptionalPropertyTypes(context) ? removeType(type, missingType) : getTypeWithFacts(type, TypeFacts.NEUndefined, context); } /** @@ -23283,7 +23342,7 @@ namespace ts { // Otherwise, infer a common supertype. const unwidenedType = inference.priority! & InferencePriority.PriorityImpliesCombination ? getUnionType(baseCandidates, UnionReduction.Subtype) : - getCommonSupertype(baseCandidates); + getCommonSupertype(baseCandidates, inference.typeParameter.symbol.declarations?.[0]); return getWidenedType(unwidenedType); } @@ -23767,52 +23826,52 @@ namespace ts { resolved.members.get("bind" as __String) && isTypeSubtypeOf(type, globalFunctionType)); } - function getTypeFacts(type: Type): TypeFacts { + function getTypeFacts(type: Type, context: Node | undefined): TypeFacts { if (type.flags & (TypeFlags.Intersection | TypeFlags.Instantiable)) { type = getBaseConstraintOfType(type) || unknownType; } const flags = type.flags; if (flags & (TypeFlags.String | TypeFlags.StringMapping)) { - return strictNullChecks ? TypeFacts.StringStrictFacts : TypeFacts.StringFacts; + return strictNullChecks(context) ? TypeFacts.StringStrictFacts : TypeFacts.StringFacts; } if (flags & (TypeFlags.StringLiteral | TypeFlags.TemplateLiteral)) { const isEmpty = flags & TypeFlags.StringLiteral && (type as StringLiteralType).value === ""; - return strictNullChecks ? + return strictNullChecks(context) ? isEmpty ? TypeFacts.EmptyStringStrictFacts : TypeFacts.NonEmptyStringStrictFacts : isEmpty ? TypeFacts.EmptyStringFacts : TypeFacts.NonEmptyStringFacts; } if (flags & (TypeFlags.Number | TypeFlags.Enum)) { - return strictNullChecks ? TypeFacts.NumberStrictFacts : TypeFacts.NumberFacts; + return strictNullChecks(context) ? TypeFacts.NumberStrictFacts : TypeFacts.NumberFacts; } if (flags & TypeFlags.NumberLiteral) { const isZero = (type as NumberLiteralType).value === 0; - return strictNullChecks ? + return strictNullChecks(context) ? isZero ? TypeFacts.ZeroNumberStrictFacts : TypeFacts.NonZeroNumberStrictFacts : isZero ? TypeFacts.ZeroNumberFacts : TypeFacts.NonZeroNumberFacts; } if (flags & TypeFlags.BigInt) { - return strictNullChecks ? TypeFacts.BigIntStrictFacts : TypeFacts.BigIntFacts; + return strictNullChecks(context) ? TypeFacts.BigIntStrictFacts : TypeFacts.BigIntFacts; } if (flags & TypeFlags.BigIntLiteral) { const isZero = isZeroBigInt(type as BigIntLiteralType); - return strictNullChecks ? + return strictNullChecks(context) ? isZero ? TypeFacts.ZeroBigIntStrictFacts : TypeFacts.NonZeroBigIntStrictFacts : isZero ? TypeFacts.ZeroBigIntFacts : TypeFacts.NonZeroBigIntFacts; } if (flags & TypeFlags.Boolean) { - return strictNullChecks ? TypeFacts.BooleanStrictFacts : TypeFacts.BooleanFacts; + return strictNullChecks(context) ? TypeFacts.BooleanStrictFacts : TypeFacts.BooleanFacts; } if (flags & TypeFlags.BooleanLike) { - return strictNullChecks ? + return strictNullChecks(context) ? (type === falseType || type === regularFalseType) ? TypeFacts.FalseStrictFacts : TypeFacts.TrueStrictFacts : (type === falseType || type === regularFalseType) ? TypeFacts.FalseFacts : TypeFacts.TrueFacts; } if (flags & TypeFlags.Object) { return getObjectFlags(type) & ObjectFlags.Anonymous && isEmptyObjectType(type as ObjectType) ? - strictNullChecks ? TypeFacts.EmptyObjectStrictFacts : TypeFacts.EmptyObjectFacts : + strictNullChecks(context) ? TypeFacts.EmptyObjectStrictFacts : TypeFacts.EmptyObjectFacts : isFunctionObjectType(type as ObjectType) ? - strictNullChecks ? TypeFacts.FunctionStrictFacts : TypeFacts.FunctionFacts : - strictNullChecks ? TypeFacts.ObjectStrictFacts : TypeFacts.ObjectFacts; + strictNullChecks(context) ? TypeFacts.FunctionStrictFacts : TypeFacts.FunctionFacts : + strictNullChecks(context) ? TypeFacts.ObjectStrictFacts : TypeFacts.ObjectFacts; } if (flags & TypeFlags.Void) { return TypeFacts.VoidFacts; @@ -23824,24 +23883,24 @@ namespace ts { return TypeFacts.NullFacts; } if (flags & TypeFlags.ESSymbolLike) { - return strictNullChecks ? TypeFacts.SymbolStrictFacts : TypeFacts.SymbolFacts; + return strictNullChecks(context) ? TypeFacts.SymbolStrictFacts : TypeFacts.SymbolFacts; } if (flags & TypeFlags.NonPrimitive) { - return strictNullChecks ? TypeFacts.ObjectStrictFacts : TypeFacts.ObjectFacts; + return strictNullChecks(context) ? TypeFacts.ObjectStrictFacts : TypeFacts.ObjectFacts; } if (flags & TypeFlags.Never) { return TypeFacts.None; } if (flags & TypeFlags.Union) { - return reduceLeft((type as UnionType).types, (facts, t) => facts | getTypeFacts(t), TypeFacts.None); + return reduceLeft((type as UnionType).types, (facts, t) => facts | getTypeFacts(t, context), TypeFacts.None); } if (flags & TypeFlags.Intersection) { - return getIntersectionTypeFacts(type as IntersectionType); + return getIntersectionTypeFacts(type as IntersectionType, context); } return TypeFacts.UnknownFacts; } - function getIntersectionTypeFacts(type: IntersectionType): TypeFacts { + function getIntersectionTypeFacts(type: IntersectionType, context: Node | undefined): TypeFacts { // When an intersection contains a primitive type we ignore object type constituents as they are // presumably type tags. For example, in string & { __kind__: "name" } we ignore the object type. const ignoreObjects = maybeTypeOfKind(type, TypeFlags.Primitive); @@ -23851,7 +23910,7 @@ namespace ts { let andedFacts = TypeFacts.All; for (const t of type.types) { if (!(ignoreObjects && t.flags & TypeFlags.Object)) { - const f = getTypeFacts(t); + const f = getTypeFacts(t, context); oredFacts |= f; andedFacts &= f; } @@ -23859,24 +23918,24 @@ namespace ts { return oredFacts & TypeFacts.OrFactsMask | andedFacts & TypeFacts.AndFactsMask; } - function getTypeWithFacts(type: Type, include: TypeFacts) { - return filterType(type, t => (getTypeFacts(t) & include) !== 0); + function getTypeWithFacts(type: Type, include: TypeFacts, context: Node | undefined) { + return filterType(type, t => (getTypeFacts(t, context) & include) !== 0); } // This function is similar to getTypeWithFacts, except that in strictNullChecks mode it replaces type // unknown with the union {} | null | undefined (and reduces that accordingly), and it intersects remaining // instantiable types with {}, {} | null, or {} | undefined in order to remove null and/or undefined. - function getAdjustedTypeWithFacts(type: Type, facts: TypeFacts) { - const reduced = recombineUnknownType(getTypeWithFacts(strictNullChecks && type.flags & TypeFlags.Unknown ? unknownUnionType : type, facts)); - if (strictNullChecks) { + function getAdjustedTypeWithFacts(type: Type, facts: TypeFacts, context: Node | undefined) { + const reduced = recombineUnknownType(getTypeWithFacts(strictNullChecks(context) && type.flags & TypeFlags.Unknown ? unknownUnionType : type, facts, context)); + if (strictNullChecks(context)) { switch (facts) { case TypeFacts.NEUndefined: - return mapType(reduced, t => getTypeFacts(t) & TypeFacts.EQUndefined ? getIntersectionType([t, getTypeFacts(t) & TypeFacts.EQNull && !maybeTypeOfKind(reduced, TypeFlags.Null) ? getUnionType([emptyObjectType, nullType]) : emptyObjectType]): t); + return mapType(reduced, t => getTypeFacts(t, context) & TypeFacts.EQUndefined ? getIntersectionType([t, getTypeFacts(t, context) & TypeFacts.EQNull && !maybeTypeOfKind(reduced, TypeFlags.Null) ? getUnionType([emptyObjectType, nullType]) : emptyObjectType]): t); case TypeFacts.NENull: - return mapType(reduced, t => getTypeFacts(t) & TypeFacts.EQNull ? getIntersectionType([t, getTypeFacts(t) & TypeFacts.EQUndefined && !maybeTypeOfKind(reduced, TypeFlags.Undefined) ? getUnionType([emptyObjectType, undefinedType]) : emptyObjectType]): t); + return mapType(reduced, t => getTypeFacts(t, context) & TypeFacts.EQNull ? getIntersectionType([t, getTypeFacts(t, context) & TypeFacts.EQUndefined && !maybeTypeOfKind(reduced, TypeFlags.Undefined) ? getUnionType([emptyObjectType, undefinedType]) : emptyObjectType]): t); case TypeFacts.NEUndefinedOrNull: case TypeFacts.Truthy: - return mapType(reduced, t => getTypeFacts(t) & TypeFacts.EQUndefinedOrNull ? getGlobalNonNullableTypeInstantiation(t): t); + return mapType(reduced, t => getTypeFacts(t, context) & TypeFacts.EQUndefinedOrNull ? getGlobalNonNullableTypeInstantiation(t): t); } } return reduced; @@ -23888,7 +23947,7 @@ namespace ts { function getTypeWithDefault(type: Type, defaultExpression: Expression) { return defaultExpression ? - getUnionType([getNonUndefinedType(type), getTypeOfExpression(defaultExpression)]) : + getUnionType([getNonUndefinedType(type, defaultExpression), getTypeOfExpression(defaultExpression)]) : type; } @@ -24582,7 +24641,7 @@ namespace ts { // on empty arrays are possible without implicit any errors and new element types can be inferred without // type mismatch errors. const resultType = getObjectFlags(evolvedType) & ObjectFlags.EvolvingArray && isEvolvingArrayOperationTarget(reference) ? autoArrayType : finalizeEvolvingArrayType(evolvedType); - if (resultType === unreachableNeverType || reference.parent && reference.parent.kind === SyntaxKind.NonNullExpression && !(resultType.flags & TypeFlags.Never) && getTypeWithFacts(resultType, TypeFacts.NEUndefinedOrNull).flags & TypeFlags.Never) { + if (resultType === unreachableNeverType || reference.parent && reference.parent.kind === SyntaxKind.NonNullExpression && !(resultType.flags & TypeFlags.Never) && getTypeWithFacts(resultType, TypeFacts.NEUndefinedOrNull, reference).flags & TypeFlags.Never) { return declaredType; } // The non-null unknown type should never escape control flow analysis. @@ -24745,7 +24804,7 @@ namespace ts { } // for (const _ in ref) acts as a nonnull on ref if (isVariableDeclaration(node) && node.parent.parent.kind === SyntaxKind.ForInStatement && isMatchingReference(reference, node.parent.parent.expression)) { - return getNonNullableTypeIfNeeded(finalizeEvolvingArrayType(getTypeFromFlowType(getTypeAtFlowNode(flow.antecedent)))); + return getNonNullableTypeIfNeeded(finalizeEvolvingArrayType(getTypeFromFlowType(getTypeAtFlowNode(flow.antecedent))), node); } // Assignment doesn't affect reference return undefined; @@ -24850,7 +24909,7 @@ namespace ts { type = narrowBySwitchOnTypeOf(type, flow.switchStatement, flow.clauseStart, flow.clauseEnd); } else { - if (strictNullChecks) { + if (strictNullChecks(expr)) { if (optionalChainContainsReference(expr, reference)) { type = narrowTypeBySwitchOptionalChainContainment(type, flow.switchStatement, flow.clauseStart, flow.clauseEnd, t => !(t.flags & (TypeFlags.Undefined | TypeFlags.Never))); @@ -25005,6 +25064,32 @@ namespace ts { return result; } + /** + * This function preserves the non-strict mode behavior of `undefined` and `null` evaporating on contact with a union + * It uses `filterType` rather than `getTypeWithFacts` because `getTypeWithFacts` would consider generic constraints, which + * the old non-strict union-creation behavior never did. + */ + function filterNullAndUndefinedFromUnionIfNotStrict(type: Type) { + if (strictNullChecks(reference)) { + return type; + } + if (!(type.flags & TypeFlags.Union)) { + return type; + } + let containedNull: Type | undefined; + const filtered = filterType(type, t => { + if (t.flags & TypeFlags.Null) { + containedNull = t; + } + return !(t.flags & TypeFlags.Nullable); + }); + if (!(filtered.flags & TypeFlags.Never)) { + return filtered; + } + // only null/undefined union members - if both are present, historically, this makes the union evaluate to `null` + return containedNull || type; + } + // At flow control branch or loop junctions, if the type along every antecedent code path // is an evolving array type, we construct a combined evolving array type. Otherwise we // finalize all evolving array types. @@ -25012,7 +25097,7 @@ namespace ts { if (isEvolvingArrayTypeList(types)) { return getEvolvingArrayType(getUnionType(map(types, getElementTypeOfEvolvingArrayType))); } - const result = recombineUnknownType(getUnionType(sameMap(types, finalizeEvolvingArrayType), subtypeReduction)); + const result = filterNullAndUndefinedFromUnionIfNotStrict(recombineUnknownType(getUnionType(sameMap(types, finalizeEvolvingArrayType), subtypeReduction))); if (result !== declaredType && result.flags & declaredType.flags & TypeFlags.Union && arraysEqual((result as UnionType).types, (declaredType as UnionType).types)) { return declaredType; } @@ -25079,12 +25164,12 @@ namespace ts { if (propName === undefined) { return type; } - const removeNullable = strictNullChecks && isOptionalChain(access) && maybeTypeOfKind(type, TypeFlags.Nullable); - let propType = getTypeOfPropertyOfType(removeNullable ? getTypeWithFacts(type, TypeFacts.NEUndefinedOrNull) : type, propName); + const removeNullable = strictNullChecks(access) && isOptionalChain(access) && maybeTypeOfKind(type, TypeFlags.Nullable); + let propType = getTypeOfPropertyOfType(removeNullable ? getTypeWithFacts(type, TypeFacts.NEUndefinedOrNull, access) : type, propName); if (!propType) { return type; } - propType = removeNullable ? getOptionalType(propType) : propType; + propType = removeNullable ? getOptionalType(propType, access) : propType; const narrowedPropType = narrowType(propType); return filterType(type, t => { const discriminantType = getTypeOfPropertyOrIndexSignature(t, propName); @@ -25120,14 +25205,14 @@ namespace ts { function narrowTypeByTruthiness(type: Type, expr: Expression, assumeTrue: boolean): Type { if (isMatchingReference(reference, expr)) { - return getAdjustedTypeWithFacts(type, assumeTrue ? TypeFacts.Truthy : TypeFacts.Falsy); + return getAdjustedTypeWithFacts(type, assumeTrue ? TypeFacts.Truthy : TypeFacts.Falsy, expr); } - if (strictNullChecks && assumeTrue && optionalChainContainsReference(expr, reference)) { - type = getAdjustedTypeWithFacts(type, TypeFacts.NEUndefinedOrNull); + if (strictNullChecks(expr) && assumeTrue && optionalChainContainsReference(expr, reference)) { + type = getAdjustedTypeWithFacts(type, TypeFacts.NEUndefinedOrNull, expr); } const access = getDiscriminantPropertyAccess(expr, type); if (access) { - return narrowTypeByDiscriminant(type, access, t => getTypeWithFacts(t, assumeTrue ? TypeFacts.Truthy : TypeFacts.Falsy)); + return narrowTypeByDiscriminant(type, access, t => getTypeWithFacts(t, assumeTrue ? TypeFacts.Truthy : TypeFacts.Falsy, expr)); } return type; } @@ -25176,7 +25261,7 @@ namespace ts { if (isMatchingReference(reference, right)) { return narrowTypeByEquality(type, operator, left, assumeTrue); } - if (strictNullChecks) { + if (strictNullChecks(expr)) { if (optionalChainContainsReference(left, reference)) { type = narrowTypeByOptionalChainContainment(type, operator, right, assumeTrue); } @@ -25211,7 +25296,7 @@ namespace ts { const name = escapeLeadingUnderscores((leftType as StringLiteralType).value); if (containsMissingType(type) && isAccessExpression(reference) && isMatchingReference(reference.expression, target) && getAccessedPropertyName(reference) === name) { - return getTypeWithFacts(type, assumeTrue ? TypeFacts.NEUndefined : TypeFacts.EQUndefined); + return getTypeWithFacts(type, assumeTrue ? TypeFacts.NEUndefined : TypeFacts.EQUndefined, expr); } if (isMatchingReference(reference, target)) { return narrowByInKeyword(type, name, assumeTrue); @@ -25269,7 +25354,7 @@ namespace ts { // Note that we include any and unknown in the exclusion test because their domain includes null and undefined. const removeNullable = equalsOperator !== assumeTrue && everyType(valueType, t => !!(t.flags & nullableFlags)) || equalsOperator === assumeTrue && everyType(valueType, t => !(t.flags & (TypeFlags.AnyOrUnknown | nullableFlags))); - return removeNullable ? getAdjustedTypeWithFacts(type, TypeFacts.NEUndefinedOrNull) : type; + return removeNullable ? getAdjustedTypeWithFacts(type, TypeFacts.NEUndefinedOrNull, value) : type; } function narrowTypeByEquality(type: Type, operator: SyntaxKind, value: Expression, assumeTrue: boolean): Type { @@ -25290,7 +25375,7 @@ namespace ts { return type; } if (valueType.flags & TypeFlags.Nullable) { - if (!strictNullChecks) { + if (!strictNullChecks(value)) { return type; } const doubleEquals = operator === SyntaxKind.EqualsEqualsToken || operator === SyntaxKind.ExclamationEqualsToken; @@ -25299,7 +25384,7 @@ namespace ts { valueType.flags & TypeFlags.Null ? assumeTrue ? TypeFacts.EQNull : TypeFacts.NENull : assumeTrue ? TypeFacts.EQUndefined : TypeFacts.NEUndefined; - return getAdjustedTypeWithFacts(type, facts); + return getAdjustedTypeWithFacts(type, facts, value); } if (assumeTrue) { const filterFn: (t: Type) => boolean = operator === SyntaxKind.EqualsEqualsToken ? @@ -25320,19 +25405,19 @@ namespace ts { } const target = getReferenceCandidate(typeOfExpr.expression); if (!isMatchingReference(reference, target)) { - if (strictNullChecks && optionalChainContainsReference(target, reference) && assumeTrue === (literal.text !== "undefined")) { - return getAdjustedTypeWithFacts(type, TypeFacts.NEUndefinedOrNull); + if (strictNullChecks(typeOfExpr) && optionalChainContainsReference(target, reference) && assumeTrue === (literal.text !== "undefined")) { + return getAdjustedTypeWithFacts(type, TypeFacts.NEUndefinedOrNull, typeOfExpr); } return type; } return assumeTrue ? narrowTypeByTypeName(type, literal.text) : - getTypeWithFacts(type, typeofNEFacts.get(literal.text) || TypeFacts.TypeofNEHostObject); + getTypeWithFacts(type, typeofNEFacts.get(literal.text) || TypeFacts.TypeofNEHostObject, typeOfExpr); } function narrowTypeBySwitchOptionalChainContainment(type: Type, switchStatement: SwitchStatement, clauseStart: number, clauseEnd: number, clauseCheck: (type: Type) => boolean) { const everyClauseChecks = clauseStart !== clauseEnd && every(getSwitchClauseTypes(switchStatement).slice(clauseStart, clauseEnd), clauseCheck); - return everyClauseChecks ? getTypeWithFacts(type, TypeFacts.NEUndefinedOrNull) : type; + return everyClauseChecks ? getTypeWithFacts(type, TypeFacts.NEUndefinedOrNull, switchStatement) : type; } function narrowTypeBySwitchOnDiscriminant(type: Type, switchStatement: SwitchStatement, clauseStart: number, clauseEnd: number) { @@ -25398,14 +25483,14 @@ namespace ts { // the constituent based on its type facts. We use the strict subtype relation because it treats `object` // as a subtype of `{}`, and we need the type facts check because function types are subtypes of `object`, // but are classified as "function" according to `typeof`. - isTypeRelatedTo(t, impliedType, strictSubtypeRelation) ? getTypeFacts(t) & facts ? t : neverType : + isTypeRelatedTo(t, impliedType, strictSubtypeRelation) ? getTypeFacts(t, reference) & facts ? t : neverType : // We next check if the consituent is a supertype of the implied type. If so, we substitute the implied // type. This handles top types like `unknown` and `{}`, and supertypes like `{ toString(): string }`. isTypeSubtypeOf(impliedType, t) ? impliedType : // Neither the constituent nor the implied type is a subtype of the other, however their domains may still // overlap. For example, an unconstrained type parameter and type `string`. If the type facts indicate // possible overlap, we form an intersection. Otherwise, we eliminate the constituent. - getTypeFacts(t) & facts ? getIntersectionType([t, impliedType]) : + getTypeFacts(t, reference) & facts ? getIntersectionType([t, impliedType]) : neverType); } @@ -25420,7 +25505,7 @@ namespace ts { if (hasDefaultClause) { // In the default clause we filter constituents down to those that are not-equal to all handled cases. const notEqualFacts = getNotEqualFactsFromTypeofSwitch(clauseStart, clauseEnd, witnesses); - return filterType(type, t => (getTypeFacts(t) & notEqualFacts) === notEqualFacts); + return filterType(type, t => (getTypeFacts(t, switchStatement) & notEqualFacts) === notEqualFacts); } // In the non-default cause we create a union of the type narrowed by each of the listed cases. const clauseWitnesses = witnesses.slice(clauseStart, clauseEnd); @@ -25484,8 +25569,8 @@ namespace ts { function narrowTypeByInstanceof(type: Type, expr: BinaryExpression, assumeTrue: boolean): Type { const left = getReferenceCandidate(expr.left); if (!isMatchingReference(reference, left)) { - if (assumeTrue && strictNullChecks && optionalChainContainsReference(left, reference)) { - return getAdjustedTypeWithFacts(type, TypeFacts.NEUndefinedOrNull); + if (assumeTrue && strictNullChecks(expr) && optionalChainContainsReference(left, reference)) { + return getAdjustedTypeWithFacts(type, TypeFacts.NEUndefinedOrNull, expr); } return type; } @@ -25583,7 +25668,7 @@ namespace ts { isIdentifier(callAccess.name) && callAccess.name.escapedText === "hasOwnProperty" && callExpression.arguments.length === 1) { const argument = callExpression.arguments[0]; if (isStringLiteralLike(argument) && getAccessedPropertyName(reference) === escapeLeadingUnderscores(argument.text)) { - return getTypeWithFacts(type, assumeTrue ? TypeFacts.NEUndefined : TypeFacts.EQUndefined); + return getTypeWithFacts(type, assumeTrue ? TypeFacts.NEUndefined : TypeFacts.EQUndefined, argument); } } } @@ -25598,9 +25683,9 @@ namespace ts { if (isMatchingReference(reference, predicateArgument)) { return getNarrowedType(type, predicate.type, assumeTrue, /*checkDerived*/ false); } - if (strictNullChecks && assumeTrue && optionalChainContainsReference(predicateArgument, reference) && - !(getTypeFacts(predicate.type) & TypeFacts.EQUndefined)) { - type = getAdjustedTypeWithFacts(type, TypeFacts.NEUndefinedOrNull); + if (strictNullChecks(callExpression) && assumeTrue && optionalChainContainsReference(predicateArgument, reference) && + !(getTypeFacts(predicate.type, callExpression) & TypeFacts.EQUndefined)) { + type = getAdjustedTypeWithFacts(type, TypeFacts.NEUndefinedOrNull, callExpression); } const access = getDiscriminantPropertyAccess(predicateArgument, type); if (access) { @@ -25659,11 +25744,11 @@ namespace ts { function narrowTypeByOptionality(type: Type, expr: Expression, assumePresent: boolean): Type { if (isMatchingReference(reference, expr)) { - return getAdjustedTypeWithFacts(type, assumePresent ? TypeFacts.NEUndefinedOrNull : TypeFacts.EQUndefinedOrNull); + return getAdjustedTypeWithFacts(type, assumePresent ? TypeFacts.NEUndefinedOrNull : TypeFacts.EQUndefinedOrNull, expr); } const access = getDiscriminantPropertyAccess(expr, type); if (access) { - return narrowTypeByDiscriminant(type, access, t => getTypeWithFacts(t, assumePresent ? TypeFacts.NEUndefinedOrNull : TypeFacts.EQUndefinedOrNull)); + return narrowTypeByDiscriminant(type, access, t => getTypeWithFacts(t, assumePresent ? TypeFacts.NEUndefinedOrNull : TypeFacts.EQUndefinedOrNull, expr)); } return type; } @@ -25748,14 +25833,14 @@ namespace ts { /** remove undefined from the annotated type of a parameter when there is an initializer (that doesn't include undefined) */ function removeOptionalityFromDeclaredType(declaredType: Type, declaration: VariableLikeDeclaration): Type { if (pushTypeResolution(declaration.symbol, TypeSystemPropertyName.DeclaredType)) { - const annotationIncludesUndefined = strictNullChecks && + const annotationIncludesUndefined = strictNullChecks(declaration) && declaration.kind === SyntaxKind.Parameter && declaration.initializer && - getTypeFacts(declaredType) & TypeFacts.IsUndefined && - !(getTypeFacts(checkExpression(declaration.initializer)) & TypeFacts.IsUndefined); + getTypeFacts(declaredType, declaration) & TypeFacts.IsUndefined && + !(getTypeFacts(checkExpression(declaration.initializer), declaration) & TypeFacts.IsUndefined); popTypeResolution(); - return annotationIncludesUndefined ? getTypeWithFacts(declaredType, TypeFacts.NEUndefined) : declaredType; + return annotationIncludesUndefined ? getTypeWithFacts(declaredType, TypeFacts.NEUndefined, declaration) : declaredType; } else { reportCircularityError(declaration.symbol); @@ -25941,6 +26026,19 @@ namespace ts { return errorType; } + if (symbol === undefinedSymbol) { + const assignmentKind = getAssignmentTargetKind(node); + if (assignmentKind) { + if (!(symbol.flags & SymbolFlags.Variable) && + !(isInJSFile(node) && symbol.flags & SymbolFlags.ValueModule)) { + const assignmentError = Diagnostics.Cannot_assign_to_0_because_it_is_not_a_variable; + error(node, assignmentError, symbolToString(symbol)); + return errorType; + } + } + return getUndefinedWideningType(node); + } + // As noted in ECMAScript 6 language spec, arrow functions never have an arguments objects. // Although in down-level emit of arrow function, we emit it using function expression which means that // arguments objects will be bound to the inner object; emitting arrow function natively in ES6, arguments objects @@ -26086,14 +26184,14 @@ 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 || isSpreadDestructuringAssignmentTarget || isModuleExports || isBindingElement(declaration) || - type !== autoType && type !== autoArrayType && (!strictNullChecks || (type.flags & (TypeFlags.AnyOrUnknown | TypeFlags.Void)) !== 0 || + type !== autoType && type !== autoArrayType && (!strictNullChecks(node) || (type.flags & (TypeFlags.AnyOrUnknown | TypeFlags.Void)) !== 0 || isInTypeQuery(node) || node.parent.kind === SyntaxKind.ExportSpecifier) || node.parent.kind === SyntaxKind.NonNullExpression || declaration.kind === SyntaxKind.VariableDeclaration && (declaration as VariableDeclaration).exclamationToken || declaration.flags & NodeFlags.Ambient; const initialType = assumeInitialized ? (isParameter ? removeOptionalityFromDeclaredType(type, declaration as VariableLikeDeclaration) : type) : type === autoType || type === autoArrayType ? undefinedType : - getOptionalType(type); + getOptionalType(type, node); const flowType = getFlowTypeOfReference(node, type, initialType, flowContainer); // A variable is considered uninitialized when it is possible to analyze the entire control flow graph // from declaration to use, and when the variable's declared type doesn't include undefined but the @@ -26760,7 +26858,7 @@ namespace ts { // There was no contextual ThisType for the containing object literal, so the contextual type // for 'this' is the non-null form of the contextual type for the containing object literal or // the type of the object literal itself. - return getWidenedType(contextualType ? getNonNullableType(contextualType) : checkExpressionCached(containingLiteral)); + return getWidenedType(contextualType ? getNonNullableType(contextualType, literal) : checkExpressionCached(containingLiteral)); } // In an assignment of the form 'obj.xxx = function(...)' or 'obj[xxx] = function(...)', the // contextual type for 'this' is 'obj'. @@ -26802,7 +26900,7 @@ namespace ts { links.resolvedSignature = anySignature; const type = indexOfParameter < args.length ? getWidenedLiteralType(checkExpression(args[indexOfParameter])) : - parameter.initializer ? undefined : undefinedWideningType; + parameter.initializer ? undefined : getUndefinedWideningType(parameter); links.resolvedSignature = cached; return type; } @@ -27909,7 +28007,7 @@ namespace ts { else { const elementContextualType = getContextualTypeForElementExpression(contextualType, elementTypes.length); const type = checkExpressionForMutableLocation(e, checkMode, elementContextualType, forceTuple); - elementTypes.push(addOptionality(type, e, hasOmittedExpression)); + elementTypes.push(addOptionality(type, e, /*isProperty*/ true, hasOmittedExpression)); elementFlags.push(hasOmittedExpression ? ElementFlags.Optional : ElementFlags.Required); if (contextualType && someType(contextualType, isTupleLikeType) && checkMode && checkMode & CheckMode.Inferential && !(checkMode & CheckMode.SkipContextSensitive) && isContextSensitive(e)) { const inferenceContext = getInferenceContext(node); @@ -27926,7 +28024,7 @@ namespace ts { } return createArrayLiteralType(createArrayType(elementTypes.length ? getUnionType(sameMap(elementTypes, (t, i) => elementFlags[i] & ElementFlags.Variadic ? getIndexedAccessTypeOrUndefined(t, numberType) || anyType : t), UnionReduction.Subtype) : - strictNullChecks ? implicitNeverType : undefinedWideningType, inConstContext)); + strictNullChecks(node) ? implicitNeverType : undefinedWideningType, inConstContext)); } function createArrayLiteralType(type: Type) { @@ -28038,7 +28136,7 @@ namespace ts { // Grammar checking checkGrammarObjectLiteralExpression(node, inDestructuringPattern); - const allPropertiesTable = strictNullChecks ? createSymbolTable() : undefined; + const allPropertiesTable = strictNullChecks(node) ? createSymbolTable() : undefined; let propertiesTable = createSymbolTable(); let propertiesArray: Symbol[] = []; let spread: Type = emptyObjectType; @@ -28155,7 +28253,7 @@ namespace ts { hasComputedSymbolProperty = false; } const type = getReducedType(checkExpression(memberDecl.expression)); - if (isValidSpreadType(type)) { + if (isValidSpreadType(type, memberDecl)) { const mergedType = tryMergeUnionOfObjectTypeAndEmptyObject(type, inConstContext); if (allPropertiesTable) { checkSpreadPropOverrides(mergedType, allPropertiesTable, memberDecl); @@ -28274,10 +28372,10 @@ namespace ts { } } - function isValidSpreadType(type: Type): boolean { - const t = removeDefinitelyFalsyTypes(mapType(type, getBaseConstraintOrType)); + function isValidSpreadType(type: Type, context: Node | undefined): boolean { + const t = removeDefinitelyFalsyTypes(mapType(type, getBaseConstraintOrType), context); return !!(t.flags & (TypeFlags.Any | TypeFlags.NonPrimitive | TypeFlags.Object | TypeFlags.InstantiableNonPrimitive) || - t.flags & TypeFlags.UnionOrIntersection && every((t as UnionOrIntersectionType).types, isValidSpreadType)); + t.flags & TypeFlags.UnionOrIntersection && every((t as UnionOrIntersectionType).types, t => isValidSpreadType(t, context))); } function checkJsxSelfClosingElementDeferred(node: JsxSelfClosingElement) { @@ -28355,7 +28453,7 @@ namespace ts { */ function createJsxAttributesTypeFromAttributesProperty(openingLikeElement: JsxOpeningLikeElement, checkMode: CheckMode | undefined) { const attributes = openingLikeElement.attributes; - const allAttributesTable = strictNullChecks ? createSymbolTable() : undefined; + const allAttributesTable = strictNullChecks(openingLikeElement) ? createSymbolTable() : undefined; let attributesTable = createSymbolTable(); let spread: Type = emptyJsxObjectType; let hasSpreadAnyType = false; @@ -28394,7 +28492,7 @@ namespace ts { if (isTypeAny(exprType)) { hasSpreadAnyType = true; } - if (isValidSpreadType(exprType)) { + if (isValidSpreadType(exprType, attributeDecl)) { spread = getSpreadType(spread, exprType, attributes.symbol, objectFlags, /*readonly*/ false); if (allAttributesTable) { checkSpreadPropOverrides(exprType, allAttributesTable, attributeDecl); @@ -29111,12 +29209,12 @@ namespace ts { return checkNonNullType(checkExpression(node), node); } - function isNullableType(type: Type) { - return !!(getTypeFacts(type) & TypeFacts.IsUndefinedOrNull); + function isNullableType(type: Type, context: Node | undefined) { + return !!(getTypeFacts(type, context) & TypeFacts.IsUndefinedOrNull); } - function getNonNullableTypeIfNeeded(type: Type) { - return isNullableType(type) ? getNonNullableType(type) : type; + function getNonNullableTypeIfNeeded(type: Type, context: Node | undefined) { + return isNullableType(type, context) ? getNonNullableType(type, context) : type; } function reportObjectPossiblyNullOrUndefinedError(node: Node, facts: TypeFacts) { @@ -29140,14 +29238,19 @@ namespace ts { node: Node, reportError: (node: Node, facts: TypeFacts) => void ): Type { - if (strictNullChecks && type.flags & TypeFlags.Unknown) { + if (strictNullChecks(node) && type.flags & TypeFlags.Unknown) { error(node, Diagnostics.Object_is_of_type_unknown); return errorType; } - const facts = getTypeFacts(type); + const facts = getTypeFacts(type, node); if (facts & TypeFacts.IsUndefinedOrNull) { - reportError(node, facts); - const t = getNonNullableType(type); + // In non-strict-null-checks mode, traditionally unions have evaporated null/undefined upon construction (thus type facts would never have included them) + // _However_, non-union'd null/undefined could still exist... and still threw this error. It's oddly redundant + // and odd given the usual 'ignore null/undefined' behavior of non-strictNullChecks mode, but it's what we've done. + if (strictNullChecks(node) || !(type.flags & TypeFlags.Union)) { + reportError(node, facts); + } + const t = getNonNullableType(type, node); return t.flags & (TypeFlags.Nullable | TypeFlags.Never) ? errorType : t; } return type; @@ -29313,7 +29416,10 @@ namespace ts { function checkPropertyAccessExpressionOrQualifiedName(node: PropertyAccessExpression | QualifiedName, left: Expression | QualifiedName, leftType: Type, right: Identifier | PrivateIdentifier, checkMode: CheckMode | undefined) { const parentSymbol = getNodeLinks(left).resolvedSymbol; const assignmentKind = getAssignmentTargetKind(node); - const apparentType = getApparentType(assignmentKind !== AssignmentKind.None || isMethodAccessForCall(node) ? getWidenedType(leftType) : leftType); + let apparentType = getApparentType(assignmentKind !== AssignmentKind.None || isMethodAccessForCall(node) ? getWidenedType(leftType) : leftType); + if (!strictNullChecks(node) && apparentType.flags & TypeFlags.Unknown) { + apparentType = emptyObjectType; + } const isAnyLike = isTypeAny(apparentType) || apparentType === silentNeverType; let prop: Symbol | undefined; if (isPrivateIdentifier(right)) { @@ -29475,7 +29581,7 @@ namespace ts { // the property is uninitialized at the top of the control flow. let assumeUninitialized = false; const file = getSourceFileOfNode(node); - if (strictNullChecks && strictPropertyInitialization(file) && isAccessExpression(node) && node.expression.kind === SyntaxKind.ThisKeyword) { + if (strictNullChecks(node) && strictPropertyInitialization(file) && isAccessExpression(node) && node.expression.kind === SyntaxKind.ThisKeyword) { const declaration = prop && prop.valueDeclaration; if (declaration && isPropertyWithoutInitializer(declaration)) { if (!isStatic(declaration)) { @@ -29486,13 +29592,13 @@ namespace ts { } } } - else if (strictNullChecks && prop && prop.valueDeclaration && + else if (strictNullChecks(node) && prop && prop.valueDeclaration && isPropertyAccessExpression(prop.valueDeclaration) && getAssignmentDeclarationPropertyAccessKind(prop.valueDeclaration) && getControlFlowContainer(node) === getControlFlowContainer(prop.valueDeclaration)) { assumeUninitialized = true; } - const flowType = getFlowTypeOfReference(node, propType, assumeUninitialized ? getOptionalType(propType) : propType); + const flowType = getFlowTypeOfReference(node, propType, assumeUninitialized ? getOptionalType(propType, node) : propType); if (assumeUninitialized && !containsUndefinedType(propType) && containsUndefinedType(flowType)) { error(errorNode, Diagnostics.Property_0_is_used_before_being_assigned, symbolToString(prop!)); // TODO: GH#18217 // Return the declared type to reduce follow-on errors @@ -30176,7 +30282,7 @@ namespace ts { } for (let i = argCount; i < effectiveMinimumArguments; i++) { const type = getTypeAtPosition(signature, i); - if (filterType(type, isInJSFile(node) && !strictNullChecks ? acceptsVoidUndefinedUnknownOrAny : acceptsVoid).flags & TypeFlags.Never) { + if (filterType(type, isInJSFile(node) && !strictNullChecks(node) ? acceptsVoidUndefinedUnknownOrAny : acceptsVoid).flags & TypeFlags.Never) { return false; } } @@ -30250,7 +30356,7 @@ namespace ts { return voidType; } const thisArgumentType = checkExpression(thisArgumentNode); - return isOptionalChainRoot(thisArgumentNode.parent) ? getNonNullableType(thisArgumentType) : + return isOptionalChainRoot(thisArgumentNode.parent) ? getNonNullableType(thisArgumentType, thisArgumentNode) : isOptionalChain(thisArgumentNode.parent) ? removeOptionalTypeMarker(thisArgumentType) : thisArgumentType; } @@ -32246,7 +32352,7 @@ namespace ts { const anonymousSymbol = createSymbol(SymbolFlags.TypeLiteral, InternalSymbolName.Type); const defaultContainingObject = createDefaultPropertyWrapperForModule(symbol, originalSymbol, anonymousSymbol); anonymousSymbol.type = defaultContainingObject; - synthType.syntheticType = isValidSpreadType(type) ? getSpreadType(type, defaultContainingObject, anonymousSymbol, /*objectFlags*/ 0, /*readonly*/ false) : defaultContainingObject; + synthType.syntheticType = isValidSpreadType(type, file) ? getSpreadType(type, defaultContainingObject, anonymousSymbol, /*objectFlags*/ 0, /*readonly*/ false) : defaultContainingObject; } else { synthType.syntheticType = type; @@ -32363,12 +32469,12 @@ namespace ts { function checkNonNullChain(node: NonNullChain) { const leftType = checkExpression(node.expression); const nonOptionalType = getOptionalExpressionType(leftType, node.expression); - return propagateOptionalTypeMarker(getNonNullableType(nonOptionalType), node, nonOptionalType !== leftType); + return propagateOptionalTypeMarker(getNonNullableType(nonOptionalType, node), node, nonOptionalType !== leftType); } function checkNonNullAssertion(node: NonNullExpression) { return node.flags & NodeFlags.OptionalChain ? checkNonNullChain(node as NonNullChain) : - getNonNullableType(checkExpression(node.expression)); + getNonNullableType(checkExpression(node.expression), node); } function checkExpressionWithTypeArguments(node: ExpressionWithTypeArguments | TypeQueryNode) { @@ -32499,10 +32605,10 @@ namespace ts { function getTypeOfParameter(symbol: Symbol) { const type = getTypeOfSymbol(symbol); - if (strictNullChecks) { + if (strictNullChecks(symbol.valueDeclaration)) { const declaration = symbol.valueDeclaration; if (declaration && hasInitializer(declaration)) { - return getOptionalType(type); + return getOptionalType(type, declaration); } } return type; @@ -32956,7 +33062,8 @@ namespace ts { yieldType || neverType, returnType || fallbackReturnType, nextType || getContextualIterationType(IterationTypeKind.Next, func) || unknownType, - isAsync); + isAsync, + strictNullChecks(func)); } else { // From within an async function you can return either a non-promise value or a promise. Any @@ -32968,7 +33075,7 @@ namespace ts { } } - function createGeneratorReturnType(yieldType: Type, returnType: Type, nextType: Type, isAsyncGenerator: boolean) { + function createGeneratorReturnType(yieldType: Type, returnType: Type, nextType: Type, isAsyncGenerator: boolean, isStrictNullChecks: boolean) { const resolver = isAsyncGenerator ? asyncIterationTypesResolver : syncIterationTypesResolver; const globalGeneratorType = resolver.getGlobalGeneratorType(/*reportErrors*/ false); yieldType = resolver.resolveIterationType(yieldType, /*errorNode*/ undefined) || unknownType; @@ -32981,7 +33088,7 @@ namespace ts { const globalType = resolver.getGlobalIterableIteratorType(/*reportErrors*/ false); const iterationTypes = globalType !== emptyGenericType ? getIterationTypesOfGlobalIterableType(globalType, resolver) : undefined; const iterableIteratorReturnType = iterationTypes ? iterationTypes.returnType : anyType; - const iterableIteratorNextType = iterationTypes ? iterationTypes.nextType : undefinedType; + const iterableIteratorNextType = iterationTypes ? iterationTypes.nextType : isStrictNullChecks ? undefinedType : undefinedPermissiveType; if (isTypeAssignableTo(returnType, iterableIteratorReturnType) && isTypeAssignableTo(iterableIteratorNextType, nextType)) { if (globalType !== emptyGenericType) { @@ -33006,7 +33113,7 @@ namespace ts { const nextTypes: Type[] = []; const isAsync = (getFunctionFlags(func) & FunctionFlags.Async) !== 0; forEachYieldExpression(func.body as Block, yieldExpression => { - const yieldExpressionType = yieldExpression.expression ? checkExpression(yieldExpression.expression, checkMode) : undefinedWideningType; + const yieldExpressionType = yieldExpression.expression ? checkExpression(yieldExpression.expression, checkMode) : getUndefinedWideningType(func); pushIfUnique(yieldTypes, getYieldedTypeOfYieldExpression(yieldExpression, yieldExpressionType, anyType, isAsync)); let nextType: Type | undefined; if (yieldExpression.asteriskToken) { @@ -33062,7 +33169,7 @@ namespace ts { return (TypeFacts.AllTypeofNE & notEqualFacts) === TypeFacts.AllTypeofNE; } // A missing not-equal flag indicates that the type wasn't handled by some case. - return !someType(operandConstraint, t => (getTypeFacts(t) & notEqualFacts) === notEqualFacts); + return !someType(operandConstraint, t => (getTypeFacts(t, node) & notEqualFacts) === notEqualFacts); } const type = getTypeOfExpression(node.expression); if (!isLiteralType(type)) { @@ -33108,7 +33215,7 @@ namespace ts { if (aggregatedTypes.length === 0 && !hasReturnWithNoExpression && (hasReturnOfTypeNever || mayReturnNever(func))) { return undefined; } - if (strictNullChecks && aggregatedTypes.length && hasReturnWithNoExpression && + if (strictNullChecks(func) && aggregatedTypes.length && hasReturnWithNoExpression && !(isJSConstructor(func) && aggregatedTypes.some(t => t.symbol === func.symbol))) { // Javascript "callable constructors", containing eg `if (!(this instanceof A)) return new A()` should not add undefined pushIfUnique(aggregatedTypes, undefinedType); @@ -33166,7 +33273,7 @@ namespace ts { // this function does not conform to the specification. error(errorNode, Diagnostics.A_function_whose_declared_type_is_neither_void_nor_any_must_return_a_value); } - else if (type && strictNullChecks && !isTypeAssignableTo(undefinedType, type)) { + else if (type && strictNullChecks(func) && !isTypeAssignableTo(undefinedType, type)) { error(errorNode, Diagnostics.Function_lacks_ending_return_statement_and_return_type_does_not_include_undefined); } else if (getFileLocalCompilerOption(getSourceFileOfNode(errorNode), compilerOptions, "noImplicitReturns")) { @@ -33455,9 +33562,9 @@ namespace ts { function checkDeleteExpressionMustBeOptional(expr: AccessExpression, symbol: Symbol) { const type = getTypeOfSymbol(symbol); - if (strictNullChecks && + if (strictNullChecks(expr) && !(type.flags & (TypeFlags.AnyOrUnknown | TypeFlags.Never)) && - !(exactOptionalPropertyTypes(expr) ? symbol.flags & SymbolFlags.Optional : getTypeFacts(type) & TypeFacts.IsUndefined)) { + !(exactOptionalPropertyTypes(expr) ? symbol.flags & SymbolFlags.Optional : getTypeFacts(type, expr) & TypeFacts.IsUndefined)) { error(expr, Diagnostics.The_operand_of_a_delete_operator_must_be_optional); } } @@ -33469,7 +33576,7 @@ namespace ts { function checkVoidExpression(node: VoidExpression): Type { checkExpression(node.expression); - return undefinedWideningType; + return getUndefinedWideningType(node); } function checkAwaitExpressionGrammar(node: AwaitExpression): void { @@ -33588,7 +33695,7 @@ namespace ts { return getUnaryResultType(operandType); case SyntaxKind.ExclamationToken: checkTruthinessExpression(node.operand); - const facts = getTypeFacts(operandType) & (TypeFacts.Truthy | TypeFacts.Falsy); + const facts = getTypeFacts(operandType, node) & (TypeFacts.Truthy | TypeFacts.Falsy); return facts === TypeFacts.Truthy ? falseType : facts === TypeFacts.Falsy ? trueType : booleanType; @@ -33774,7 +33881,7 @@ namespace ts { function checkObjectLiteralAssignment(node: ObjectLiteralExpression, sourceType: Type, rightIsThis?: boolean): Type { const properties = node.properties; - if (strictNullChecks && properties.length === 0) { + if (strictNullChecks(node) && properties.length === 0) { return checkNonNullType(sourceType, node); } for (let i = 0; i < properties.length; i++) { @@ -33860,7 +33967,7 @@ namespace ts { // when the element is a SyntaxKind.ElementAccessExpression. const accessFlags = AccessFlags.ExpressionPosition | (hasDefaultValue(element) ? AccessFlags.NoTupleBoundsCheck : 0); const elementType = getIndexedAccessTypeOrUndefined(sourceType, indexType, accessFlags, createSyntheticExpression(element, indexType)) || errorType; - const assignedType = hasDefaultValue(element) ? getTypeWithFacts(elementType, TypeFacts.NEUndefined) : elementType; + const assignedType = hasDefaultValue(element) ? getTypeWithFacts(elementType, TypeFacts.NEUndefined, node) : elementType; const type = getFlowTypeOfDestructuring(element, assignedType); return checkDestructuringAssignment(element, type, checkMode); } @@ -33893,9 +34000,9 @@ namespace ts { if (prop.objectAssignmentInitializer) { // In strict null checking mode, if a default value of a non-undefined type is specified, remove // undefined from the final type. - if (strictNullChecks && - !(getTypeFacts(checkExpression(prop.objectAssignmentInitializer)) & TypeFacts.IsUndefined)) { - sourceType = getTypeWithFacts(sourceType, TypeFacts.NEUndefined); + if (strictNullChecks(exprOrAssignment) && + !(getTypeFacts(checkExpression(prop.objectAssignmentInitializer), exprOrAssignment) & TypeFacts.IsUndefined)) { + sourceType = getTypeWithFacts(sourceType, TypeFacts.NEUndefined, exprOrAssignment); } checkBinaryLikeExpression(prop.name, prop.equalsToken!, prop.objectAssignmentInitializer, checkMode); } @@ -33909,8 +34016,8 @@ namespace ts { checkBinaryExpression(target as BinaryExpression, checkMode); target = (target as BinaryExpression).left; // A default value is specified, so remove undefined from the final type. - if (strictNullChecks) { - sourceType = getTypeWithFacts(sourceType, TypeFacts.NEUndefined); + if (strictNullChecks(exprOrAssignment)) { + sourceType = getTypeWithFacts(sourceType, TypeFacts.NEUndefined, exprOrAssignment); } } if (target.kind === SyntaxKind.ObjectLiteralExpression) { @@ -34350,8 +34457,8 @@ namespace ts { return checkInExpression(left, right, leftType, rightType); case SyntaxKind.AmpersandAmpersandToken: case SyntaxKind.AmpersandAmpersandEqualsToken: { - const resultType = getTypeFacts(leftType) & TypeFacts.Truthy ? - getUnionType([extractDefinitelyFalsyTypes(strictNullChecks ? leftType : getBaseTypeOfLiteralType(rightType)), rightType]) : + const resultType = getTypeFacts(leftType, left) & TypeFacts.Truthy ? + getUnionType([extractDefinitelyFalsyTypes(strictNullChecks(left) ? leftType : getBaseTypeOfLiteralType(rightType)), rightType]) : leftType; if (operator === SyntaxKind.AmpersandAmpersandEqualsToken) { checkAssignmentOperator(rightType); @@ -34360,8 +34467,8 @@ namespace ts { } case SyntaxKind.BarBarToken: case SyntaxKind.BarBarEqualsToken: { - const resultType = getTypeFacts(leftType) & TypeFacts.Falsy ? - getUnionType([getNonNullableType(removeDefinitelyFalsyTypes(leftType)), rightType], UnionReduction.Subtype) : + const resultType = getTypeFacts(leftType, left) & TypeFacts.Falsy ? + getUnionType([getNonNullableType(removeDefinitelyFalsyTypes(leftType, left), left), rightType], UnionReduction.Subtype) : leftType; if (operator === SyntaxKind.BarBarEqualsToken) { checkAssignmentOperator(rightType); @@ -34370,8 +34477,8 @@ namespace ts { } case SyntaxKind.QuestionQuestionToken: case SyntaxKind.QuestionQuestionEqualsToken: { - const resultType = getTypeFacts(leftType) & TypeFacts.EQUndefinedOrNull ? - getUnionType([getNonNullableType(leftType), rightType], UnionReduction.Subtype) : + const resultType = getTypeFacts(leftType, left) & TypeFacts.EQUndefinedOrNull ? + getUnionType([getNonNullableType(leftType, left), rightType], UnionReduction.Subtype) : leftType; if (operator === SyntaxKind.QuestionQuestionEqualsToken) { checkAssignmentOperator(rightType); @@ -34628,7 +34735,7 @@ namespace ts { const signatureYieldType = iterationTypes && iterationTypes.yieldType || anyType; const signatureNextType = iterationTypes && iterationTypes.nextType || anyType; const resolvedSignatureNextType = isAsync ? getAwaitedType(signatureNextType) || anyType : signatureNextType; - const yieldExpressionType = node.expression ? checkExpression(node.expression) : undefinedWideningType; + const yieldExpressionType = node.expression ? checkExpression(node.expression) : getUndefinedWideningType(node); const yieldedType = getYieldedTypeOfYieldExpression(node, yieldExpressionType, resolvedSignatureNextType, isAsync); if (returnType && yieldedType) { checkTypeAssignableToAndOptionallyElaborate(yieldedType, signatureYieldType, node.expression || node, node.expression); @@ -34888,7 +34995,7 @@ namespace ts { if (signature && signature.typeParameters) { const contextualType = getApparentTypeOfContextualType(node as Expression, ContextFlags.NoConstraints); if (contextualType) { - const contextualSignature = getSingleSignature(getNonNullableType(contextualType), callSignature ? SignatureKind.Call : SignatureKind.Construct, /*allowMembers*/ false); + const contextualSignature = getSingleSignature(getNonNullableType(contextualType, node), callSignature ? SignatureKind.Call : SignatureKind.Construct, /*allowMembers*/ false); if (contextualSignature && !contextualSignature.typeParameters) { if (checkMode & CheckMode.SkipGenericFunctions) { skippedGenericFunction(node, checkMode); @@ -35178,7 +35285,7 @@ namespace ts { case SyntaxKind.SuperKeyword: return checkSuperExpression(node); case SyntaxKind.NullKeyword: - return nullWideningType; + return getNullWideningType(node); case SyntaxKind.NoSubstitutionTemplateLiteral: case SyntaxKind.StringLiteral: return getFreshTypeOfLiteralType(getStringLiteralType((node as StringLiteralLike).text)); @@ -35253,7 +35360,7 @@ namespace ts { case SyntaxKind.SpreadElement: return checkSpreadExpression(node as SpreadElement, checkMode); case SyntaxKind.OmittedExpression: - return undefinedWideningType; + return getUndefinedWideningType(node); case SyntaxKind.YieldExpression: return checkYieldExpression(node as YieldExpression); case SyntaxKind.SyntheticExpression: @@ -35534,7 +35641,7 @@ namespace ts { const generatorYieldType = getIterationTypeOfGeneratorFunctionReturnType(IterationTypeKind.Yield, returnType, (functionFlags & FunctionFlags.Async) !== 0) || anyType; const generatorReturnType = getIterationTypeOfGeneratorFunctionReturnType(IterationTypeKind.Return, returnType, (functionFlags & FunctionFlags.Async) !== 0) || generatorYieldType; const generatorNextType = getIterationTypeOfGeneratorFunctionReturnType(IterationTypeKind.Next, returnType, (functionFlags & FunctionFlags.Async) !== 0) || unknownType; - const generatorInstantiation = createGeneratorReturnType(generatorYieldType, generatorReturnType, generatorNextType, !!(functionFlags & FunctionFlags.Async)); + const generatorInstantiation = createGeneratorReturnType(generatorYieldType, generatorReturnType, generatorNextType, !!(functionFlags & FunctionFlags.Async), strictNullChecks(node)); checkTypeAssignableTo(generatorInstantiation, returnType, returnTypeNode); } } @@ -36143,7 +36250,10 @@ namespace ts { } // Check if we're indexing with a numeric type and if either object or index types // is a generic type with a constraint that has a numeric index signature. - const apparentObjectType = getApparentType(objectType); + let apparentObjectType = getApparentType(objectType); + if (!strictNullChecks(accessNode) && apparentObjectType.flags & TypeFlags.Unknown) { + apparentObjectType = emptyObjectType; + } if (getIndexInfoOfType(apparentObjectType, numberType) && isTypeAssignableToKind(indexType, TypeFlags.NumberLike)) { return type; } @@ -36746,7 +36856,7 @@ namespace ts { return undefined; } - const onfulfilledParameterType = getTypeWithFacts(getUnionType(map(candidates, getTypeOfFirstParameterOfSignature)), TypeFacts.NEUndefinedOrNull); + const onfulfilledParameterType = getTypeWithFacts(getUnionType(map(candidates, getTypeOfFirstParameterOfSignature)), TypeFacts.NEUndefinedOrNull, errorNode); if (isTypeAny(onfulfilledParameterType)) { return undefined; } @@ -36780,14 +36890,14 @@ namespace ts { /** * Determines whether a type is an object with a callable `then` member. */ - function isThenableType(type: Type): boolean { + function isThenableType(type: Type, context: Node | undefined): boolean { if (allTypesAssignableToKind(type, TypeFlags.Primitive | TypeFlags.Never)) { // primitive types cannot be considered "thenable" since they are not objects. return false; } const thenFunction = getTypeOfPropertyOfType(type, "then" as __String); - return !!thenFunction && getSignaturesOfType(getTypeWithFacts(thenFunction, TypeFacts.NEUndefinedOrNull), SignatureKind.Call).length > 0; + return !!thenFunction && getSignaturesOfType(getTypeWithFacts(thenFunction, TypeFacts.NEUndefinedOrNull, context), SignatureKind.Call).length > 0; } interface AwaitedTypeInstantiation extends Type { @@ -36813,7 +36923,7 @@ namespace ts { type; } - function isAwaitedTypeNeeded(type: Type) { + function isAwaitedTypeNeeded(type: Type, context: Node | undefined) { // If this is already an `Awaited`, we shouldn't wrap it. This helps to avoid `Awaited>` in higher-order. if (isTypeAny(type) || isAwaitedTypeInstantiation(type)) { return false; @@ -36825,7 +36935,7 @@ namespace ts { // We only need `Awaited` if `T` is a type variable that has no base constraint, or the base constraint of `T` is `any`, `unknown`, `{}`, `object`, // or is promise-like. if (baseConstraint ? - baseConstraint.flags & TypeFlags.AnyOrUnknown || isEmptyObjectType(baseConstraint) || isThenableType(baseConstraint) : + baseConstraint.flags & TypeFlags.AnyOrUnknown || isEmptyObjectType(baseConstraint) || isThenableType(baseConstraint, context) : maybeTypeOfKind(type, TypeFlags.TypeVariable)) { return true; } @@ -36846,7 +36956,7 @@ namespace ts { return undefined; } - function createAwaitedTypeIfNeeded(type: Type): Type { + function createAwaitedTypeIfNeeded(type: Type, context: Node | undefined): Type { // We wrap type `T` in `Awaited` based on the following conditions: // - `T` is not already an `Awaited`, and // - `T` is generic, and @@ -36855,7 +36965,7 @@ namespace ts { // - The base constraint of `T` is `any`, `unknown`, `object`, or `{}`, or // - The base constraint of `T` is an object type with a callable `then` method. - if (isAwaitedTypeNeeded(type)) { + if (isAwaitedTypeNeeded(type, context)) { const awaitedType = tryCreateAwaitedType(type); if (awaitedType) { return awaitedType; @@ -36878,7 +36988,7 @@ namespace ts { */ function getAwaitedType(type: Type, errorNode?: Node, diagnosticMessage?: DiagnosticMessage, arg0?: string | number): Type | undefined { const awaitedType = getAwaitedTypeNoAlias(type, errorNode, diagnosticMessage, arg0); - return awaitedType && createAwaitedTypeIfNeeded(awaitedType); + return awaitedType && createAwaitedTypeIfNeeded(awaitedType, errorNode); } /** @@ -36921,7 +37031,7 @@ namespace ts { } // If `type` is generic and should be wrapped in `Awaited`, return it. - if (isAwaitedTypeNeeded(type)) { + if (isAwaitedTypeNeeded(type, errorNode)) { return typeAsAwaitable.awaitedTypeOfType = type; } @@ -36996,7 +37106,7 @@ namespace ts { // of a runtime problem. If the user wants to return this value from an async // function, they would need to wrap it in some other value. If they want it to // be treated as a promise, they can cast to . - if (isThenableType(type)) { + if (isThenableType(type, errorNode)) { if (errorNode) { Debug.assertIsDefined(diagnosticMessage); let chain: DiagnosticMessageChain | undefined; @@ -37237,7 +37347,7 @@ namespace ts { if (typeNode.kind === SyntaxKind.NeverKeyword) { continue; // Always elide `never` from the union/intersection if possible } - if (!strictNullChecks && (typeNode.kind === SyntaxKind.LiteralType && (typeNode as LiteralTypeNode).literal.kind === SyntaxKind.NullKeyword || typeNode.kind === SyntaxKind.UndefinedKeyword)) { + if (!strictNullChecks(typeNode) && (typeNode.kind === SyntaxKind.LiteralType && (typeNode as LiteralTypeNode).literal.kind === SyntaxKind.NullKeyword || typeNode.kind === SyntaxKind.UndefinedKeyword)) { continue; // Elide null and undefined from unions for metadata, just like what we did prior to the implementation of strict null checks } const individualEntityName = getEntityNameForDecoratorMetadata(typeNode); @@ -38231,7 +38341,7 @@ namespace ts { const widenedType = getWidenedTypeForVariableLikeDeclaration(node); if (needCheckInitializer) { const initializerType = checkExpressionCached(node.initializer); - if (strictNullChecks && needCheckWidenedType) { + if (strictNullChecks(node) && needCheckWidenedType) { checkNonNullNonVoidType(initializerType, node); } else { @@ -38243,7 +38353,7 @@ namespace ts { if (isArrayBindingPattern(node.name)) { checkIteratedTypeOrElementType(IterationUse.Destructuring, widenedType, undefinedType, node); } - else if (strictNullChecks) { + else if (strictNullChecks(node)) { checkNonNullNonVoidType(widenedType, node); } } @@ -38385,7 +38495,7 @@ namespace ts { } function checkTestingKnownTruthyCallableOrAwaitableType(condExpr: Expression, body?: Statement | Expression) { - if (!strictNullChecks) return; + if (!strictNullChecks(condExpr)) return; helper(condExpr, body); while (isBinaryExpression(condExpr) && condExpr.operatorToken.kind === SyntaxKind.BarBarToken) { @@ -38401,7 +38511,7 @@ namespace ts { if (isModuleExportsAccessExpression(location)) return; const type = checkTruthinessExpression(location); const isPropertyExpressionCast = isPropertyAccessExpression(location) && isTypeAssertion(location.expression); - if (!(getTypeFacts(type) & TypeFacts.Truthy) || isPropertyExpressionCast) return; + if (!(getTypeFacts(type, condExpr) & TypeFacts.Truthy) || isPropertyExpressionCast) return; // While it technically should be invalid for any known-truthy value // to be tested, we de-scope to functions and Promises unreferenced in @@ -38616,7 +38726,12 @@ namespace ts { // Grammar checking checkGrammarForInOrForOfStatement(node); - const rightType = getNonNullableTypeIfNeeded(checkExpression(node.expression)); + const exprType = checkExpression(node.expression); + // Previosuly, in non-strictNullChecks mode, `getNonNullableTypeIfNeeded` internally skipped doing work. + // Since `null` can manifest in non-strict mode, it unconditionally does work now, however at this location that + // difference is visible - an exact `null` is mapped into `never` (and could then issue an error), whereas before it would stay as `null`. + // To preserve that non-erroring behavior, we flag stripping null behind strict here. + const rightType = strictNullChecks(node) ? getNonNullableTypeIfNeeded(exprType, node) : exprType; // TypeScript 1.0 spec (April 2014): 5.4 // In a 'for-in' statement of the form // for (let VarDecl in Expr) Statement @@ -39341,7 +39456,7 @@ namespace ts { } const methodType = method && !(methodName === "next" && (method.flags & SymbolFlags.Optional)) - ? methodName === "next" ? getTypeOfSymbol(method) : getTypeWithFacts(getTypeOfSymbol(method), TypeFacts.NEUndefinedOrNull) + ? methodName === "next" ? getTypeOfSymbol(method) : getTypeWithFacts(getTypeOfSymbol(method), TypeFacts.NEUndefinedOrNull, errorNode || method.valueDeclaration) : undefined; if (isTypeAny(methodType)) { @@ -39531,7 +39646,7 @@ namespace ts { const signature = getSignatureFromDeclaration(container); const returnType = getReturnTypeOfSignature(signature); const functionFlags = getFunctionFlags(container); - if (strictNullChecks || node.expression || returnType.flags & TypeFlags.Never) { + if (strictNullChecks(node) || node.expression || returnType.flags & TypeFlags.Never) { const exprType = node.expression ? checkExpressionCached(node.expression) : undefinedType; if (container.kind === SyntaxKind.SetAccessor) { if (node.expression) { @@ -40500,7 +40615,7 @@ namespace ts { if ((uninitialized as PropertyDeclaration).exclamationToken || !constructor || !isIdentifier(propName) - || !strictNullChecks + || !strictNullChecks(propName) || !isPropertyInitializedInConstructor(propName, type, constructor)) { const errorMessage = Diagnostics.Property_0_will_overwrite_the_base_property_in_1_If_this_is_intentional_add_an_initializer_Otherwise_add_a_declare_modifier_or_remove_the_redundant_declaration; error(getNameOfDeclaration(derived.valueDeclaration) || derived.valueDeclaration, errorMessage, symbolToString(base), typeToString(baseType)); @@ -40600,7 +40715,7 @@ namespace ts { } function checkPropertyInitialization(node: ClassLikeDeclaration) { - if (!strictNullChecks || !strictPropertyInitialization(getSourceFileOfNode(node)) || node.flags & NodeFlags.Ambient) { + if (!strictNullChecks(node) || !strictPropertyInitialization(getSourceFileOfNode(node)) || node.flags & NodeFlags.Ambient) { return; } const constructor = findConstructorDeclaration(node); @@ -40637,7 +40752,7 @@ namespace ts { setParent(reference.expression, reference); setParent(reference, staticBlock); reference.flowNode = staticBlock.returnFlowNode; - const flowType = getFlowTypeOfReference(reference, propType, getOptionalType(propType)); + const flowType = getFlowTypeOfReference(reference, propType, getOptionalType(propType, reference)); if (!containsUndefinedType(flowType)) { return true; } @@ -40653,7 +40768,7 @@ namespace ts { setParent(reference.expression, reference); setParent(reference, constructor); reference.flowNode = constructor.returnFlowNode; - const flowType = getFlowTypeOfReference(reference, propType, getOptionalType(propType)); + const flowType = getFlowTypeOfReference(reference, propType, getOptionalType(propType, propName)); return !containsUndefinedType(flowType); } @@ -42026,7 +42141,7 @@ namespace ts { if (isParameter(parent) && isJSDocFunctionType(parent.parent)) { return createArrayType(type); } - return addOptionality(type); + return addOptionality(type, parent); } // Function and class expression bodies are checked after all statements in the enclosing body. This is @@ -43322,7 +43437,7 @@ namespace ts { } function isRequiredInitializedParameter(parameter: ParameterDeclaration | JSDocParameterTag): boolean { - return !!strictNullChecks && + return !!strictNullChecks(parameter) && !isOptionalParameter(parameter) && !isJSDocParameterTag(parameter) && !!parameter.initializer && @@ -43330,7 +43445,7 @@ namespace ts { } function isOptionalUninitializedParameterProperty(parameter: ParameterDeclaration) { - return strictNullChecks && + return strictNullChecks(parameter) && isOptionalParameter(parameter) && !parameter.initializer && hasSyntacticModifier(parameter, ModifierFlags.ParameterPropertyModifier); @@ -43491,7 +43606,7 @@ namespace ts { flags |= NodeBuilderFlags.AllowUniqueESSymbolType; } if (addUndefined) { - type = getOptionalType(type); + type = getOptionalType(type, declarationIn); } return nodeBuilder.typeToTypeNode(type, enclosingDeclaration, flags | NodeBuilderFlags.MultilineObjectLiterals, tracker); } @@ -43906,7 +44021,7 @@ namespace ts { // Setup global builtins addToSymbolTable(globals, builtinGlobals, Diagnostics.Declaration_name_conflicts_with_built_in_global_identifier_0); - getSymbolLinks(undefinedSymbol).type = undefinedWideningType; + getSymbolLinks(undefinedSymbol).type = undefinedType; // `checkIdentifier` overrides this with the widening type when relevant getSymbolLinks(argumentsSymbol).type = getGlobalType("IArguments" as __String, /*arity*/ 0, /*reportErrors*/ true); getSymbolLinks(unknownSymbol).type = errorType; getSymbolLinks(globalThisSymbol).type = createObjectType(ObjectFlags.Anonymous, globalThisSymbol); diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 11d69ec35a462..0b32d01b6119f 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -4576,9 +4576,9 @@ namespace ts { /* @internal */ getParameterType(signature: Signature, parameterIndex: number): Type; /* @internal */ getParameterIdentifierNameAtPosition(signature: Signature, parameterIndex: number): [parameterName: __String, isRestParameter: boolean] | undefined; getNullableType(type: Type, flags: TypeFlags): Type; - getNonNullableType(type: Type): Type; + getNonNullableType(type: Type, context?: Node | undefined): Type; /* @internal */ getNonOptionalType(type: Type): Type; - /* @internal */ isNullableType(type: Type): boolean; + /* @internal */ isNullableType(type: Type, context?: Node | undefined): boolean; getTypeArguments(type: TypeReference): readonly Type[]; // TODO: GH#18217 `xToDeclaration` calls are frequently asserted as defined. @@ -4710,8 +4710,8 @@ namespace ts { /* @internal */ getFalseType(fresh?: boolean): Type; /* @internal */ getTrueType(fresh?: boolean): Type; /* @internal */ getVoidType(): Type; - /* @internal */ getUndefinedType(): Type; - /* @internal */ getNullType(): Type; + /* @internal */ getUndefinedType(widening?: boolean): Type; + /* @internal */ getNullType(widening?: boolean): Type; /* @internal */ getESSymbolType(): Type; /* @internal */ getNeverType(): Type; /* @internal */ getOptionalType(): Type; @@ -5606,12 +5606,12 @@ namespace ts { Narrowable = Any | Unknown | StructuredOrInstantiable | StringLike | NumberLike | BigIntLike | BooleanLike | ESSymbol | UniqueESSymbol | NonPrimitive, // The following flags are aggregated during union and intersection type construction /* @internal */ - IncludesMask = Any | Unknown | Primitive | Never | Object | Union | Intersection | NonPrimitive | TemplateLiteral, + IncludesMask = Any | Unknown | Primitive | Never | Object | Union | Intersection | NonPrimitive | TemplateLiteral | Index | StringMapping, // The following flags are used for different purposes during union and intersection type construction /* @internal */ IncludesMissingType = TypeParameter, /* @internal */ - IncludesNonWideningType = Index, + IncludesNonWideningType = 1 << 29, // repurpose for true typeflag when needed /* @internal */ IncludesWildcard = IndexedAccess, /* @internal */ diff --git a/src/services/codefixes/inferFromUsage.ts b/src/services/codefixes/inferFromUsage.ts index 643d64f2c21af..0498476eff30b 100644 --- a/src/services/codefixes/inferFromUsage.ts +++ b/src/services/codefixes/inferFromUsage.ts @@ -113,6 +113,7 @@ namespace ts.codefix { return undefined; } + const isStrictNullChecks = getStrictOptionValue(sourceFile, program.getCompilerOptions(), "strictNullChecks"); const { parent } = token; const importAdder = createImportAdder(sourceFile, program, preferences, host); errorCode = mapSuggestionDiagnostic(errorCode); @@ -121,12 +122,12 @@ namespace ts.codefix { case Diagnostics.Member_0_implicitly_has_an_1_type.code: case Diagnostics.Variable_0_implicitly_has_type_1_in_some_locations_where_its_type_cannot_be_determined.code: if ((isVariableDeclaration(parent) && markSeen(parent)) || isPropertyDeclaration(parent) || isPropertySignature(parent)) { // handle bad location - annotateVariableDeclaration(changes, importAdder, sourceFile, parent, program, host, cancellationToken); + annotateVariableDeclaration(changes, importAdder, sourceFile, parent, program, host, cancellationToken, isStrictNullChecks); importAdder.writeFixes(changes); return parent; } if (isPropertyAccessExpression(parent)) { - const type = inferTypeForVariableFromUsage(parent.name, program, cancellationToken); + const type = inferTypeForVariableFromUsage(parent.name, program, cancellationToken, isStrictNullChecks); const typeNode = getTypeNodeIfAccessible(type, parent, program, host); if (typeNode) { // Note that the codefix will never fire with an existing `@type` tag, so there is no need to merge tags @@ -141,7 +142,7 @@ namespace ts.codefix { case Diagnostics.Variable_0_implicitly_has_an_1_type.code: { const symbol = program.getTypeChecker().getSymbolAtLocation(token); if (symbol && symbol.valueDeclaration && isVariableDeclaration(symbol.valueDeclaration) && markSeen(symbol.valueDeclaration)) { - annotateVariableDeclaration(changes, importAdder, getSourceFileOfNode(symbol.valueDeclaration), symbol.valueDeclaration, program, host, cancellationToken); + annotateVariableDeclaration(changes, importAdder, getSourceFileOfNode(symbol.valueDeclaration), symbol.valueDeclaration, program, host, cancellationToken, isStrictNullChecks); importAdder.writeFixes(changes); return symbol.valueDeclaration; } @@ -159,7 +160,7 @@ namespace ts.codefix { // Parameter declarations case Diagnostics.Parameter_0_implicitly_has_an_1_type.code: if (isSetAccessorDeclaration(containingFunction)) { - annotateSetAccessor(changes, importAdder, sourceFile, containingFunction, program, host, cancellationToken); + annotateSetAccessor(changes, importAdder, sourceFile, containingFunction, program, host, cancellationToken, isStrictNullChecks); declaration = containingFunction; break; } @@ -167,7 +168,7 @@ namespace ts.codefix { case Diagnostics.Rest_parameter_0_implicitly_has_an_any_type.code: if (markSeen(containingFunction)) { const param = cast(parent, isParameter); - annotateParameters(changes, importAdder, sourceFile, param, containingFunction, program, host, cancellationToken); + annotateParameters(changes, importAdder, sourceFile, param, containingFunction, program, host, cancellationToken, isStrictNullChecks); declaration = param; } break; @@ -176,7 +177,7 @@ namespace ts.codefix { case Diagnostics.Property_0_implicitly_has_type_any_because_its_get_accessor_lacks_a_return_type_annotation.code: case Diagnostics._0_which_lacks_return_type_annotation_implicitly_has_an_1_return_type.code: if (isGetAccessorDeclaration(containingFunction) && isIdentifier(containingFunction.name)) { - annotate(changes, importAdder, sourceFile, containingFunction, inferTypeForVariableFromUsage(containingFunction.name, program, cancellationToken), program, host); + annotate(changes, importAdder, sourceFile, containingFunction, inferTypeForVariableFromUsage(containingFunction.name, program, cancellationToken, isStrictNullChecks), program, host); declaration = containingFunction; } break; @@ -184,7 +185,7 @@ namespace ts.codefix { // Set Accessor declarations case Diagnostics.Property_0_implicitly_has_type_any_because_its_set_accessor_lacks_a_parameter_type_annotation.code: if (isSetAccessorDeclaration(containingFunction)) { - annotateSetAccessor(changes, importAdder, sourceFile, containingFunction, program, host, cancellationToken); + annotateSetAccessor(changes, importAdder, sourceFile, containingFunction, program, host, cancellationToken, isStrictNullChecks); declaration = containingFunction; } break; @@ -192,7 +193,7 @@ namespace ts.codefix { // Function 'this' case Diagnostics.this_implicitly_has_type_any_because_it_does_not_have_a_type_annotation.code: if (textChanges.isThisTypeAnnotatable(containingFunction) && markSeen(containingFunction)) { - annotateThis(changes, sourceFile, containingFunction, program, host, cancellationToken); + annotateThis(changes, sourceFile, containingFunction, program, host, cancellationToken, isStrictNullChecks); declaration = containingFunction; } break; @@ -213,9 +214,10 @@ namespace ts.codefix { program: Program, host: LanguageServiceHost, cancellationToken: CancellationToken, + isStrictNullChecks: boolean, ): void { if (isIdentifier(declaration.name)) { - annotate(changes, importAdder, sourceFile, declaration, inferTypeForVariableFromUsage(declaration.name, program, cancellationToken), program, host); + annotate(changes, importAdder, sourceFile, declaration, inferTypeForVariableFromUsage(declaration.name, program, cancellationToken, isStrictNullChecks), program, host); } } @@ -228,12 +230,13 @@ namespace ts.codefix { program: Program, host: LanguageServiceHost, cancellationToken: CancellationToken, + isStrictNullChecks: boolean, ): void { if (!isIdentifier(parameterDeclaration.name)) { return; } - const parameterInferences = inferTypeForParametersFromUsage(containingFunction, sourceFile, program, cancellationToken); + const parameterInferences = inferTypeForParametersFromUsage(containingFunction, sourceFile, program, cancellationToken, isStrictNullChecks); Debug.assert(containingFunction.parameters.length === parameterInferences.length, "Parameter count and inference count should match"); if (isInJSFile(containingFunction)) { @@ -251,12 +254,12 @@ namespace ts.codefix { } } - function annotateThis(changes: textChanges.ChangeTracker, sourceFile: SourceFile, containingFunction: textChanges.ThisTypeAnnotatable, program: Program, host: LanguageServiceHost, cancellationToken: CancellationToken) { + function annotateThis(changes: textChanges.ChangeTracker, sourceFile: SourceFile, containingFunction: textChanges.ThisTypeAnnotatable, program: Program, host: LanguageServiceHost, cancellationToken: CancellationToken, isStrictNullChecks: boolean) { const references = getFunctionReferences(containingFunction, sourceFile, program, cancellationToken); if (!references || !references.length) { return; } - const thisInference = inferTypeFromReferences(program, references, cancellationToken).thisParameter(); + const thisInference = inferTypeFromReferences(program, references, cancellationToken, isStrictNullChecks).thisParameter(); const typeNode = getTypeNodeIfAccessible(thisInference, containingFunction, program, host); if (!typeNode) { return; @@ -284,13 +287,13 @@ namespace ts.codefix { program: Program, host: LanguageServiceHost, cancellationToken: CancellationToken, - + isStrictNullChecks: boolean, ): void { const param = firstOrUndefined(setAccessorDeclaration.parameters); if (param && isIdentifier(setAccessorDeclaration.name) && isIdentifier(param.name)) { - let type = inferTypeForVariableFromUsage(setAccessorDeclaration.name, program, cancellationToken); + let type = inferTypeForVariableFromUsage(setAccessorDeclaration.name, program, cancellationToken, isStrictNullChecks); if (type === program.getTypeChecker().getAnyType()) { - type = inferTypeForVariableFromUsage(param.name, program, cancellationToken); + type = inferTypeForVariableFromUsage(param.name, program, cancellationToken, isStrictNullChecks); } if (isInJSFile(setAccessorDeclaration)) { annotateJSDocParameters(changes, sourceFile, [{ declaration: param, type }], program, host); @@ -388,17 +391,17 @@ namespace ts.codefix { entry.kind !== FindAllReferences.EntryKind.Span ? tryCast(entry.node, isIdentifier) : undefined); } - function inferTypeForVariableFromUsage(token: Identifier | PrivateIdentifier, program: Program, cancellationToken: CancellationToken): Type { + function inferTypeForVariableFromUsage(token: Identifier | PrivateIdentifier, program: Program, cancellationToken: CancellationToken, isStrictNullChecks: boolean): Type { const references = getReferences(token, program, cancellationToken); - return inferTypeFromReferences(program, references, cancellationToken).single(); + return inferTypeFromReferences(program, references, cancellationToken, isStrictNullChecks).single(); } - function inferTypeForParametersFromUsage(func: SignatureDeclaration, sourceFile: SourceFile, program: Program, cancellationToken: CancellationToken) { + function inferTypeForParametersFromUsage(func: SignatureDeclaration, sourceFile: SourceFile, program: Program, cancellationToken: CancellationToken, isStrictNullChecks: boolean) { const references = getFunctionReferences(func, sourceFile, program, cancellationToken); - return references && inferTypeFromReferences(program, references, cancellationToken).parameters(func) || + return references && inferTypeFromReferences(program, references, cancellationToken, isStrictNullChecks).parameters(func) || func.parameters.map(p => ({ declaration: p, - type: isIdentifier(p.name) ? inferTypeForVariableFromUsage(p.name, program, cancellationToken) : program.getTypeChecker().getAnyType() + type: isIdentifier(p.name) ? inferTypeForVariableFromUsage(p.name, program, cancellationToken, isStrictNullChecks) : program.getTypeChecker().getAnyType() })); } @@ -435,7 +438,7 @@ namespace ts.codefix { readonly isOptional?: boolean; } - function inferTypeFromReferences(program: Program, references: readonly Identifier[], cancellationToken: CancellationToken) { + function inferTypeFromReferences(program: Program, references: readonly Identifier[], cancellationToken: CancellationToken, isStrictNullChecks: boolean) { const checker = program.getTypeChecker(); const builtinConstructors: { [s: string]: (t: Type) => Type } = { string: () => checker.getStringType(), @@ -546,7 +549,9 @@ namespace ts.codefix { for (const call of calls) { if (call.argumentTypes.length <= parameterIndex) { isOptional = isInJSFile(declaration); - types.push(checker.getUndefinedType()); + if (isStrictNullChecks) { + types.push(checker.getUndefinedType(!isStrictNullChecks)); + } } else if (isRest) { for (let i = parameterIndex; i < call.argumentTypes.length; i++) { @@ -872,6 +877,45 @@ namespace ts.codefix { return combineTypes(inferTypes(usage)); } + function remapIntoWideningTypes(type: Type) { + if (isStrictNullChecks) { + return type; + } + if (type === checker.getNullType()) { + // in non-strict mode map bare `null` into the widening `null`, which historically is all that's existed until mixed-mode checking became a thing + return checker.getNullType(/*widening*/ true); + } + else if (type === checker.getUndefinedType()) { + // likewise, in non-strict mode map bare `undefined` into the widening `undefined` + return checker.getUndefinedType(/*widening*/ true); + } + return type; + } + + /** + * This function preserves the non-strict mode behavior of `undefined` and `null` evaporating on contact with a union + */ + function filterNullAndUndefinedFromUnionIfNotStrict(type: Type) { + if (isStrictNullChecks) { + return type; + } + if (!(type.flags & TypeFlags.Union)) { + return type; + } + let containedNull: Type | undefined; + const filtered = checker.getUnionType(filter((type as UnionType).types, t => { + if (t.flags & TypeFlags.Null) { + containedNull = t; + } + return !(t.flags & TypeFlags.Nullable); + })); + if (!(filtered.flags & TypeFlags.Never)) { + return filtered; + } + // only null/undefined union members - if both are present, historically, this makes the union evaluate to `null` + return containedNull || type; + } + function combineTypes(inferences: readonly Type[]): Type { if (!inferences.length) return checker.getAnyType(); @@ -898,7 +942,7 @@ namespace ts.codefix { good = good.filter(i => !(getObjectFlags(i) & ObjectFlags.Anonymous)); good.push(combineAnonymousTypes(anons)); } - return checker.getWidenedType(checker.getUnionType(good.map(checker.getBaseTypeOfLiteralType), UnionReduction.Subtype)); + return checker.getWidenedType(remapIntoWideningTypes(filterNullAndUndefinedFromUnionIfNotStrict(checker.getUnionType(good.map(checker.getBaseTypeOfLiteralType), UnionReduction.Subtype)))); } function combineAnonymousTypes(anons: AnonymousType[]) { @@ -1108,7 +1152,7 @@ namespace ts.codefix { const length = Math.max(...calls.map(c => c.argumentTypes.length)); for (let i = 0; i < length; i++) { const symbol = checker.createSymbol(SymbolFlags.FunctionScopedVariable, escapeLeadingUnderscores(`arg${i}`)); - symbol.type = combineTypes(calls.map(call => call.argumentTypes[i] || checker.getUndefinedType())); + symbol.type = combineTypes(calls.map(call => call.argumentTypes[i] || checker.getUndefinedType(!isStrictNullChecks))); if (calls.some(call => call.argumentTypes[i] === undefined)) { symbol.flags |= SymbolFlags.Optional; } diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 5f5edb8b2c10b..d37b5ea8496d4 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -2323,7 +2323,7 @@ declare namespace ts { getWidenedType(type: Type): Type; getReturnTypeOfSignature(signature: Signature): Type; getNullableType(type: Type, flags: TypeFlags): Type; - getNonNullableType(type: Type): Type; + getNonNullableType(type: Type, context?: Node | undefined): Type; getTypeArguments(type: TypeReference): readonly Type[]; /** Note that the resulting nodes cannot be checked. */ typeToTypeNode(type: Type, enclosingDeclaration: Node | undefined, flags: NodeBuilderFlags | undefined): TypeNode | undefined; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 85470b6407cbe..4accc66ff04c4 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -2323,7 +2323,7 @@ declare namespace ts { getWidenedType(type: Type): Type; getReturnTypeOfSignature(signature: Signature): Type; getNullableType(type: Type, flags: TypeFlags): Type; - getNonNullableType(type: Type): Type; + getNonNullableType(type: Type, context?: Node | undefined): Type; getTypeArguments(type: TypeReference): readonly Type[]; /** Note that the resulting nodes cannot be checked. */ typeToTypeNode(type: Type, enclosingDeclaration: Node | undefined, flags: NodeBuilderFlags | undefined): TypeNode | undefined; diff --git a/tests/baselines/reference/circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.errors.txt b/tests/baselines/reference/circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.errors.txt index 88ffa05ad4deb..500274bffda0a 100644 --- a/tests/baselines/reference/circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.errors.txt +++ b/tests/baselines/reference/circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.errors.txt @@ -5,27 +5,58 @@ tests/cases/compiler/circularlyConstrainedMappedTypeContainingConditionalNoInfin Type 'GetProps[P] | (TInjectedProps[P] extends GetProps[P] ? GetProps[P] : TInjectedProps[P])' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. Type 'GetProps[P]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. Type 'GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. - Type 'Extract> extends keyof TInjectedProps ? TInjectedProps[Extract>] extends GetProps[Extract>] ? GetProps[Extract>] : TInjectedProps[Extract>] : GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. - Type 'GetProps[Extract>] | (TInjectedProps[Extract>] extends GetProps[Extract>] ? GetProps[Extract>] : TInjectedProps[Extract>])' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. - Type 'GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. - Type 'GetProps[Extract>] | GetProps[Extract>] | GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. - Type 'GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. - Type 'GetProps[keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. - Type 'GetProps[string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. - Type '(Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>]) | (Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>]) | (Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>])' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. - Type 'Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. - Type '(TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>]) | GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. - Type 'TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. - Type 'GetProps[keyof TInjectedProps & Extract>] | TInjectedProps[keyof TInjectedProps & Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. - Type 'GetProps[keyof TInjectedProps & Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. - Type 'GetProps[string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. - Type 'keyof GetProps & string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string] : GetProps[keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. - Type '(TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string]) | GetProps[keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. - Type 'TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. - Type 'GetProps[keyof TInjectedProps & keyof GetProps & string] | TInjectedProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. - Type 'GetProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. - Type 'GetProps[string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. - Type 'string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & string] extends GetProps[keyof TInjectedProps & string] ? GetProps[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string] : GetProps[string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[P]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'Extract> extends keyof TInjectedProps ? TInjectedProps[Extract>] extends GetProps[Extract>] ? GetProps[Extract>] : TInjectedProps[Extract>] : GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[Extract>] | (TInjectedProps[Extract>] extends GetProps[Extract>] ? GetProps[Extract>] : TInjectedProps[Extract>])' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[Extract>] | GetProps[Extract>] | GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type '(Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>]) | (Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>]) | (Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>])' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type '(TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>]) | GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[keyof TInjectedProps & Extract>] | TInjectedProps[keyof TInjectedProps & Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[keyof TInjectedProps & Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[keyof TInjectedProps & Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'keyof GetProps & string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string] : GetProps[keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type '(TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string]) | GetProps[keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[keyof TInjectedProps & keyof GetProps & string] | TInjectedProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & string] extends GetProps[keyof TInjectedProps & string] ? GetProps[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string] : GetProps[string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'keyof GetProps & string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string] : GetProps[keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type '(TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string]) | GetProps[keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'GetProps[keyof TInjectedProps & keyof GetProps & string] | TInjectedProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'GetProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'GetProps[string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type '(TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>]) | GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'GetProps[keyof TInjectedProps & Extract>] | TInjectedProps[keyof TInjectedProps & Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'GetProps[keyof TInjectedProps & Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'GetProps[string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'Extract> extends keyof TInjectedProps ? TInjectedProps[Extract>] extends GetProps[Extract>] ? GetProps[Extract>] : TInjectedProps[Extract>] : GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'GetProps[Extract>] | (TInjectedProps[Extract>] extends GetProps[Extract>] ? GetProps[Extract>] : TInjectedProps[Extract>])' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'P extends keyof TInjectedProps ? TInjectedProps[P] extends GetProps[P] ? GetProps[P] : TInjectedProps[P] : GetProps[P]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'GetProps[P] | (TInjectedProps[P] extends GetProps[P] ? GetProps[P] : TInjectedProps[P])' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'GetProps[P]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'GetProps[Extract>] | GetProps[Extract>] | GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'GetProps[keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'GetProps[string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. ==== tests/cases/compiler/circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts (1 errors) ==== @@ -100,25 +131,56 @@ tests/cases/compiler/circularlyConstrainedMappedTypeContainingConditionalNoInfin !!! error TS2344: Type 'GetProps[P] | (TInjectedProps[P] extends GetProps[P] ? GetProps[P] : TInjectedProps[P])' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. !!! error TS2344: Type 'GetProps[P]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. !!! error TS2344: Type 'GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. -!!! error TS2344: Type 'Extract> extends keyof TInjectedProps ? TInjectedProps[Extract>] extends GetProps[Extract>] ? GetProps[Extract>] : TInjectedProps[Extract>] : GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. -!!! error TS2344: Type 'GetProps[Extract>] | (TInjectedProps[Extract>] extends GetProps[Extract>] ? GetProps[Extract>] : TInjectedProps[Extract>])' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. -!!! error TS2344: Type 'GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. -!!! error TS2344: Type 'GetProps[Extract>] | GetProps[Extract>] | GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. -!!! error TS2344: Type 'GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. -!!! error TS2344: Type 'GetProps[keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. -!!! error TS2344: Type 'GetProps[string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. -!!! error TS2344: Type '(Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>]) | (Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>]) | (Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>])' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. -!!! error TS2344: Type 'Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. -!!! error TS2344: Type '(TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>]) | GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. -!!! error TS2344: Type 'TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. -!!! error TS2344: Type 'GetProps[keyof TInjectedProps & Extract>] | TInjectedProps[keyof TInjectedProps & Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. -!!! error TS2344: Type 'GetProps[keyof TInjectedProps & Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. -!!! error TS2344: Type 'GetProps[string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. -!!! error TS2344: Type 'keyof GetProps & string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string] : GetProps[keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. -!!! error TS2344: Type '(TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string]) | GetProps[keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. -!!! error TS2344: Type 'TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. -!!! error TS2344: Type 'GetProps[keyof TInjectedProps & keyof GetProps & string] | TInjectedProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. -!!! error TS2344: Type 'GetProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. -!!! error TS2344: Type 'GetProps[string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. -!!! error TS2344: Type 'string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & string] extends GetProps[keyof TInjectedProps & string] ? GetProps[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string] : GetProps[string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[P]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'Extract> extends keyof TInjectedProps ? TInjectedProps[Extract>] extends GetProps[Extract>] ? GetProps[Extract>] : TInjectedProps[Extract>] : GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[Extract>] | (TInjectedProps[Extract>] extends GetProps[Extract>] ? GetProps[Extract>] : TInjectedProps[Extract>])' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[Extract>] | GetProps[Extract>] | GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type '(Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>]) | (Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>]) | (Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>])' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type '(TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>]) | GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[keyof TInjectedProps & Extract>] | TInjectedProps[keyof TInjectedProps & Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[keyof TInjectedProps & Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[keyof TInjectedProps & Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'keyof GetProps & string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string] : GetProps[keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type '(TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string]) | GetProps[keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[keyof TInjectedProps & keyof GetProps & string] | TInjectedProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & string] extends GetProps[keyof TInjectedProps & string] ? GetProps[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string] : GetProps[string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'keyof GetProps & string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string] : GetProps[keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type '(TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string]) | GetProps[keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'GetProps[keyof TInjectedProps & keyof GetProps & string] | TInjectedProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'GetProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'GetProps[string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type '(TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>]) | GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'GetProps[keyof TInjectedProps & Extract>] | TInjectedProps[keyof TInjectedProps & Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'GetProps[keyof TInjectedProps & Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'GetProps[string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'Extract> extends keyof TInjectedProps ? TInjectedProps[Extract>] extends GetProps[Extract>] ? GetProps[Extract>] : TInjectedProps[Extract>] : GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'GetProps[Extract>] | (TInjectedProps[Extract>] extends GetProps[Extract>] ? GetProps[Extract>] : TInjectedProps[Extract>])' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'P extends keyof TInjectedProps ? TInjectedProps[P] extends GetProps[P] ? GetProps[P] : TInjectedProps[P] : GetProps[P]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'GetProps[P] | (TInjectedProps[P] extends GetProps[P] ? GetProps[P] : TInjectedProps[P])' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'GetProps[P]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'GetProps[Extract>] | GetProps[Extract>] | GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'GetProps[keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'GetProps[string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. \ No newline at end of file diff --git a/tests/baselines/reference/collectionPatternNoError.types b/tests/baselines/reference/collectionPatternNoError.types index de8e960f095d1..fc42829c4d48e 100644 --- a/tests/baselines/reference/collectionPatternNoError.types +++ b/tests/baselines/reference/collectionPatternNoError.types @@ -23,7 +23,7 @@ function fetchMsg(protoCtor: MsgConstructor): V { >protoCtor : MsgConstructor return null!; ->null! : null +>null! : never >null : null } diff --git a/tests/baselines/reference/conditionalTypes2.errors.txt b/tests/baselines/reference/conditionalTypes2.errors.txt index a96ab6ac3a5d0..c42681790a53c 100644 --- a/tests/baselines/reference/conditionalTypes2.errors.txt +++ b/tests/baselines/reference/conditionalTypes2.errors.txt @@ -148,7 +148,6 @@ tests/cases/conformance/types/conditional/conditionalTypes2.ts(75,12): error TS2 !!! error TS2345: Property 'bat' is missing in type 'Bar & Foo' but required in type '{ foo: string; bat: string; }'. !!! error TS2345: Type 'Extract' is not assignable to type '{ foo: string; bat: string; }'. !!! error TS2345: Property 'bat' is missing in type 'Bar & Foo' but required in type '{ foo: string; bat: string; }'. -!!! related TS2728 tests/cases/conformance/types/conditional/conditionalTypes2.ts:62:43: 'bat' is declared here. !!! related TS2728 tests/cases/conformance/types/conditional/conditionalTypes2.ts:62:43: 'bat' is declared here. fooBat(y); // Error ~ diff --git a/tests/baselines/reference/declarationEmitMappedTypeDistributivityPreservesConstraints.types b/tests/baselines/reference/declarationEmitMappedTypeDistributivityPreservesConstraints.types index 41b6e4b4bd372..48949f0ba5971 100644 --- a/tests/baselines/reference/declarationEmitMappedTypeDistributivityPreservesConstraints.types +++ b/tests/baselines/reference/declarationEmitMappedTypeDistributivityPreservesConstraints.types @@ -15,7 +15,7 @@ function fn }>(sliceIndex: T): AllArg { >sliceIndex : T return null!; ->null! : null +>null! : never >null : null } diff --git a/tests/baselines/reference/emitDecoratorMetadata_isolatedModules(module=commonjs).types b/tests/baselines/reference/emitDecoratorMetadata_isolatedModules(module=commonjs).types index b2615eac81b73..95df13899c15e 100644 --- a/tests/baselines/reference/emitDecoratorMetadata_isolatedModules(module=commonjs).types +++ b/tests/baselines/reference/emitDecoratorMetadata_isolatedModules(module=commonjs).types @@ -80,7 +80,7 @@ class HelloWorld { handleEvent3(event: C3): T1 { return undefined! } // Ok, Error >handleEvent3 : (event: C3) => T1 >event : C3 ->undefined! : undefined +>undefined! : never >undefined : undefined } diff --git a/tests/baselines/reference/emitDecoratorMetadata_isolatedModules(module=esnext).types b/tests/baselines/reference/emitDecoratorMetadata_isolatedModules(module=esnext).types index b2615eac81b73..95df13899c15e 100644 --- a/tests/baselines/reference/emitDecoratorMetadata_isolatedModules(module=esnext).types +++ b/tests/baselines/reference/emitDecoratorMetadata_isolatedModules(module=esnext).types @@ -80,7 +80,7 @@ class HelloWorld { handleEvent3(event: C3): T1 { return undefined! } // Ok, Error >handleEvent3 : (event: C3) => T1 >event : C3 ->undefined! : undefined +>undefined! : never >undefined : undefined } diff --git a/tests/baselines/reference/genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.errors.txt b/tests/baselines/reference/genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.errors.txt index 2063b58b4e3dc..f14f6292a27b4 100644 --- a/tests/baselines/reference/genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.errors.txt +++ b/tests/baselines/reference/genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.errors.txt @@ -9,7 +9,7 @@ tests/cases/compiler/genericConditionalConstrainedToUnknownNotAssignableToConcre Type 'unknown' is not assignable to type 'A'. Type 'ReturnType[string]>' is not assignable to type 'A'. Type 'unknown' is not assignable to type 'A'. - Property 'x' is missing in type '{}' but required in type 'A'. + Type 'unknown' is not assignable to type 'A'. ==== tests/cases/compiler/genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.ts (1 errors) ==== @@ -38,8 +38,7 @@ tests/cases/compiler/genericConditionalConstrainedToUnknownNotAssignableToConcre !!! error TS2322: Type 'unknown' is not assignable to type 'A'. !!! error TS2322: Type 'ReturnType[string]>' is not assignable to type 'A'. !!! error TS2322: Type 'unknown' is not assignable to type 'A'. -!!! error TS2322: Property 'x' is missing in type '{}' but required in type 'A'. -!!! related TS2728 tests/cases/compiler/genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.ts:1:15: 'x' is declared here. +!!! error TS2322: Type 'unknown' is not assignable to type 'A'. } // Original CFA report of the above issue diff --git a/tests/baselines/reference/inDoesNotOperateOnPrimitiveTypes.types b/tests/baselines/reference/inDoesNotOperateOnPrimitiveTypes.types index f56bbf9395d40..047e1168a3479 100644 --- a/tests/baselines/reference/inDoesNotOperateOnPrimitiveTypes.types +++ b/tests/baselines/reference/inDoesNotOperateOnPrimitiveTypes.types @@ -79,7 +79,7 @@ function union2(thing: T | U) { "key" in thing; // Ok >"key" in thing : boolean >"key" : "key" ->thing : T +>thing : T | (T & null) | (U & null) } } @@ -146,7 +146,7 @@ function union5(p: T | U) "key" in p; >"key" in p : boolean >"key" : "key" ->p : (T & object) | (U & object) +>p : (T & object) | (U & object) | (T & null) | (U & null) } } diff --git a/tests/baselines/reference/intersectionReduction.types b/tests/baselines/reference/intersectionReduction.types index fc04d01441c43..69252142cb5ad 100644 --- a/tests/baselines/reference/intersectionReduction.types +++ b/tests/baselines/reference/intersectionReduction.types @@ -40,12 +40,12 @@ type N1 = 'a' & 'b'; >N1 : never type N2 = { a: string } & null; ->N2 : null +>N2 : never >a : string >null : null type N3 = { a: string } & undefined; ->N3 : undefined +>N3 : never >a : string type N4 = string & number; @@ -255,10 +255,10 @@ declare let s2: string & Tag2; >s2 : never declare let t1: string & Tag1 | undefined; ->t1 : undefined +>t1 : never declare let t2: string & Tag2 | undefined; ->t2 : undefined +>t2 : never s1 = s2; >s1 = s2 : never @@ -271,14 +271,14 @@ s2 = s1; >s1 : never t1 = t2; ->t1 = t2 : undefined ->t1 : undefined ->t2 : undefined +>t1 = t2 : never +>t1 : never +>t2 : never t2 = t1; ->t2 = t1 : undefined ->t2 : undefined ->t1 : undefined +>t2 = t1 : never +>t2 : never +>t1 : never // Repro from #36736 diff --git a/tests/baselines/reference/localTypeParameterInferencePriority.types b/tests/baselines/reference/localTypeParameterInferencePriority.types index 9834da9c9d92a..fada2121c42ce 100644 --- a/tests/baselines/reference/localTypeParameterInferencePriority.types +++ b/tests/baselines/reference/localTypeParameterInferencePriority.types @@ -20,7 +20,7 @@ class Table { >getRows : () => Array>> return null! ->null! : null +>null! : never >null : null } } diff --git a/tests/baselines/reference/mappedTypeRelationships.errors.txt b/tests/baselines/reference/mappedTypeRelationships.errors.txt index 33c20572d127c..20981577b6412 100644 --- a/tests/baselines/reference/mappedTypeRelationships.errors.txt +++ b/tests/baselines/reference/mappedTypeRelationships.errors.txt @@ -17,12 +17,18 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(40,5): error TS2 tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(41,5): error TS2322: Type 'T[keyof T]' is not assignable to type 'U[keyof T] | undefined'. Type 'T[string] | T[number] | T[symbol]' is not assignable to type 'U[keyof T] | undefined'. Type 'T[string]' is not assignable to type 'U[keyof T] | undefined'. + Type 'T[string]' is not assignable to type 'U[keyof T]'. + Type 'T' is not assignable to type 'U'. + 'U' could be instantiated with an arbitrary type which could be unrelated to 'T'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(45,5): error TS2322: Type 'U[K] | undefined' is not assignable to type 'T[K]'. Type 'undefined' is not assignable to type 'T[K]'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(46,5): error TS2322: Type 'T[K]' is not assignable to type 'U[K] | undefined'. Type 'T[keyof T]' is not assignable to type 'U[K] | undefined'. Type 'T[string] | T[number] | T[symbol]' is not assignable to type 'U[K] | undefined'. Type 'T[string]' is not assignable to type 'U[K] | undefined'. + Type 'T[string]' is not assignable to type 'U[K]'. + Type 'T' is not assignable to type 'U'. + 'U' could be instantiated with an arbitrary type which could be unrelated to 'T'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(51,5): error TS2542: Index signature in type 'Readonly' only permits reading. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(56,5): error TS2542: Index signature in type 'Readonly' only permits reading. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(61,5): error TS2322: Type 'T[keyof T]' is not assignable to type 'U[keyof T]'. @@ -146,6 +152,10 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(168,5): error TS !!! error TS2322: Type 'T[keyof T]' is not assignable to type 'U[keyof T] | undefined'. !!! error TS2322: Type 'T[string] | T[number] | T[symbol]' is not assignable to type 'U[keyof T] | undefined'. !!! error TS2322: Type 'T[string]' is not assignable to type 'U[keyof T] | undefined'. +!!! error TS2322: Type 'T[string]' is not assignable to type 'U[keyof T]'. +!!! error TS2322: Type 'T' is not assignable to type 'U'. +!!! error TS2322: 'U' could be instantiated with an arbitrary type which could be unrelated to 'T'. +!!! related TS2208 tests/cases/conformance/types/mapped/mappedTypeRelationships.ts:39:14: This type parameter might need an `extends U` constraint. } function f13(x: T, y: Partial, k: K) { @@ -159,6 +169,10 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(168,5): error TS !!! error TS2322: Type 'T[keyof T]' is not assignable to type 'U[K] | undefined'. !!! error TS2322: Type 'T[string] | T[number] | T[symbol]' is not assignable to type 'U[K] | undefined'. !!! error TS2322: Type 'T[string]' is not assignable to type 'U[K] | undefined'. +!!! error TS2322: Type 'T[string]' is not assignable to type 'U[K]'. +!!! error TS2322: Type 'T' is not assignable to type 'U'. +!!! error TS2322: 'U' could be instantiated with an arbitrary type which could be unrelated to 'T'. +!!! related TS2208 tests/cases/conformance/types/mapped/mappedTypeRelationships.ts:44:14: This type parameter might need an `extends U` constraint. } function f20(x: T, y: Readonly, k: keyof T) { diff --git a/tests/baselines/reference/metadataOfUnionWithNull.types b/tests/baselines/reference/metadataOfUnionWithNull.types index 588c21911202a..20c7af3323563 100644 --- a/tests/baselines/reference/metadataOfUnionWithNull.types +++ b/tests/baselines/reference/metadataOfUnionWithNull.types @@ -54,7 +54,7 @@ class B { >PropDeco : (target: Object, propKey: string | symbol) => void d: undefined | null; ->d : null +>d : never >null : null @PropDeco diff --git a/tests/baselines/reference/noImplicitAnyForIn.types b/tests/baselines/reference/noImplicitAnyForIn.types index bd8cb1c8c200c..6fcd13004a276 100644 --- a/tests/baselines/reference/noImplicitAnyForIn.types +++ b/tests/baselines/reference/noImplicitAnyForIn.types @@ -59,8 +59,8 @@ for (var a in x) { >b : any var c = a || b; ->c : string ->a || b : string +>c : string | undefined +>a || b : string | undefined >a : string >b : undefined } diff --git a/tests/baselines/reference/nonNullableReductionNonStrict.types b/tests/baselines/reference/nonNullableReductionNonStrict.types index 075ee5a41fd1b..6bb2f98177e4c 100644 --- a/tests/baselines/reference/nonNullableReductionNonStrict.types +++ b/tests/baselines/reference/nonNullableReductionNonStrict.types @@ -17,7 +17,7 @@ function test(f1: Transform1, f2: Transform2) { f1?.("hello"); >f1?.("hello") : T ->f1 : (value: string) => T +>f1 : ((value: string) => T) | undefined >"hello" : "hello" f2?.("hello"); @@ -28,23 +28,23 @@ function test(f1: Transform1, f2: Transform2) { function f1(x: T | (string extends T ? null | undefined : never)) { >f1 : (x: T | (string extends T ? null | undefined : never)) => void ->x : T | (string extends T ? null : never) +>x : T | (string extends T ? never : never) >null : null let z = x!; // NonNullable ->z : T | (string extends T ? null : never) ->x! : T | (string extends T ? null : never) ->x : T | (string extends T ? null : never) +>z : T +>x! : T +>x : T | (string extends T ? never : never) } function f2(x: T | U) { ->f2 : (x: T | U) => void +>f2 : (x: T | U) => void >null : null >x : T | U let z = x!; // NonNullable ->z : T | U ->x! : T | U +>z : T +>x! : T >x : T | U } diff --git a/tests/baselines/reference/nullishCoalescingOperator_not_strict.types b/tests/baselines/reference/nullishCoalescingOperator_not_strict.types index adfdce759dce5..c5f69d43819ad 100644 --- a/tests/baselines/reference/nullishCoalescingOperator_not_strict.types +++ b/tests/baselines/reference/nullishCoalescingOperator_not_strict.types @@ -30,7 +30,7 @@ declare const a7: unknown | null >null : null declare const a8: never | null ->a8 : null +>a8 : never >null : null declare const a9: any | null @@ -81,9 +81,9 @@ const aa7 = a7 ?? 'whatever' >'whatever' : "whatever" const aa8 = a8 ?? 'whatever' ->aa8 : "whatever" ->a8 ?? 'whatever' : "whatever" ->a8 : null +>aa8 : never +>a8 ?? 'whatever' : never +>a8 : never >'whatever' : "whatever" const aa9 = a9 ?? 'whatever' diff --git a/tests/baselines/reference/privateFieldAssignabilityFromUnknown.errors.txt b/tests/baselines/reference/privateFieldAssignabilityFromUnknown.errors.txt index 22f50eec6ff01..bdf2d4116dbee 100644 --- a/tests/baselines/reference/privateFieldAssignabilityFromUnknown.errors.txt +++ b/tests/baselines/reference/privateFieldAssignabilityFromUnknown.errors.txt @@ -1,5 +1,5 @@ tests/cases/compiler/privateFieldAssignabilityFromUnknown.ts(2,3): error TS18028: Private identifiers are only available when targeting ECMAScript 2015 and higher. -tests/cases/compiler/privateFieldAssignabilityFromUnknown.ts(5,7): error TS2741: Property '#field' is missing in type '{}' but required in type 'Class'. +tests/cases/compiler/privateFieldAssignabilityFromUnknown.ts(5,7): error TS2322: Type 'unknown' is not assignable to type 'Class'. ==== tests/cases/compiler/privateFieldAssignabilityFromUnknown.ts (2 errors) ==== @@ -11,6 +11,5 @@ tests/cases/compiler/privateFieldAssignabilityFromUnknown.ts(5,7): error TS2741: const task: Class = {} as unknown; ~~~~ -!!! error TS2741: Property '#field' is missing in type '{}' but required in type 'Class'. -!!! related TS2728 tests/cases/compiler/privateFieldAssignabilityFromUnknown.ts:2:3: '#field' is declared here. +!!! error TS2322: Type 'unknown' is not assignable to type 'Class'. \ No newline at end of file diff --git a/tests/baselines/reference/propertyAccessOnTypeParameterWithoutConstraints.symbols b/tests/baselines/reference/propertyAccessOnTypeParameterWithoutConstraints.symbols index fbbfb557ef6f1..b0531585c744a 100644 --- a/tests/baselines/reference/propertyAccessOnTypeParameterWithoutConstraints.symbols +++ b/tests/baselines/reference/propertyAccessOnTypeParameterWithoutConstraints.symbols @@ -72,7 +72,6 @@ var r3: string = a().toString(); var r3b: string = a()['toString'](); >r3b : Symbol(r3b, Decl(propertyAccessOnTypeParameterWithoutConstraints.ts, 21, 3)) >a : Symbol(a, Decl(propertyAccessOnTypeParameterWithoutConstraints.ts, 17, 3)) ->'toString' : Symbol(Object.toString, Decl(lib.es5.d.ts, --, --)) var b = { >b : Symbol(b, Decl(propertyAccessOnTypeParameterWithoutConstraints.ts, 23, 3)) diff --git a/tests/baselines/reference/reactReduxLikeDeferredInferenceAllowsAssignment.errors.txt b/tests/baselines/reference/reactReduxLikeDeferredInferenceAllowsAssignment.errors.txt index 9b6e0228efeaa..ef879e148dfc1 100644 --- a/tests/baselines/reference/reactReduxLikeDeferredInferenceAllowsAssignment.errors.txt +++ b/tests/baselines/reference/reactReduxLikeDeferredInferenceAllowsAssignment.errors.txt @@ -5,27 +5,58 @@ tests/cases/compiler/reactReduxLikeDeferredInferenceAllowsAssignment.ts(76,50): Type 'GetProps[P] | (TInjectedProps[P] extends GetProps[P] ? GetProps[P] : TInjectedProps[P])' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. Type 'GetProps[P]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. Type 'GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. - Type 'Extract> extends keyof TInjectedProps ? TInjectedProps[Extract>] extends GetProps[Extract>] ? GetProps[Extract>] : TInjectedProps[Extract>] : GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. - Type 'GetProps[Extract>] | (TInjectedProps[Extract>] extends GetProps[Extract>] ? GetProps[Extract>] : TInjectedProps[Extract>])' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. - Type 'GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. - Type 'GetProps[Extract>] | GetProps[Extract>] | GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. - Type 'GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. - Type 'GetProps[keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. - Type 'GetProps[string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. - Type '(Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>]) | (Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>]) | (Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>])' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. - Type 'Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. - Type '(TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>]) | GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. - Type 'TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. - Type 'GetProps[keyof TInjectedProps & Extract>] | TInjectedProps[keyof TInjectedProps & Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. - Type 'GetProps[keyof TInjectedProps & Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. - Type 'GetProps[string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. - Type 'keyof GetProps & string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string] : GetProps[keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. - Type '(TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string]) | GetProps[keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. - Type 'TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. - Type 'GetProps[keyof TInjectedProps & keyof GetProps & string] | TInjectedProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. - Type 'GetProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. - Type 'GetProps[string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. - Type 'string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & string] extends GetProps[keyof TInjectedProps & string] ? GetProps[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string] : GetProps[string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[P]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'Extract> extends keyof TInjectedProps ? TInjectedProps[Extract>] extends GetProps[Extract>] ? GetProps[Extract>] : TInjectedProps[Extract>] : GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[Extract>] | (TInjectedProps[Extract>] extends GetProps[Extract>] ? GetProps[Extract>] : TInjectedProps[Extract>])' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[Extract>] | GetProps[Extract>] | GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type '(Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>]) | (Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>]) | (Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>])' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type '(TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>]) | GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[keyof TInjectedProps & Extract>] | TInjectedProps[keyof TInjectedProps & Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[keyof TInjectedProps & Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[keyof TInjectedProps & Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'keyof GetProps & string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string] : GetProps[keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type '(TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string]) | GetProps[keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[keyof TInjectedProps & keyof GetProps & string] | TInjectedProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & string] extends GetProps[keyof TInjectedProps & string] ? GetProps[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string] : GetProps[string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'keyof GetProps & string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string] : GetProps[keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type '(TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string]) | GetProps[keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'GetProps[keyof TInjectedProps & keyof GetProps & string] | TInjectedProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'GetProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'GetProps[string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type '(TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>]) | GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'GetProps[keyof TInjectedProps & Extract>] | TInjectedProps[keyof TInjectedProps & Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'GetProps[keyof TInjectedProps & Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'GetProps[string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'Extract> extends keyof TInjectedProps ? TInjectedProps[Extract>] extends GetProps[Extract>] ? GetProps[Extract>] : TInjectedProps[Extract>] : GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'GetProps[Extract>] | (TInjectedProps[Extract>] extends GetProps[Extract>] ? GetProps[Extract>] : TInjectedProps[Extract>])' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'P extends keyof TInjectedProps ? TInjectedProps[P] extends GetProps[P] ? GetProps[P] : TInjectedProps[P] : GetProps[P]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'GetProps[P] | (TInjectedProps[P] extends GetProps[P] ? GetProps[P] : TInjectedProps[P])' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'GetProps[P]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'GetProps[Extract>] | GetProps[Extract>] | GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'GetProps[keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'GetProps[string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. ==== tests/cases/compiler/reactReduxLikeDeferredInferenceAllowsAssignment.ts (1 errors) ==== @@ -113,27 +144,58 @@ tests/cases/compiler/reactReduxLikeDeferredInferenceAllowsAssignment.ts(76,50): !!! error TS2344: Type 'GetProps[P] | (TInjectedProps[P] extends GetProps[P] ? GetProps[P] : TInjectedProps[P])' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. !!! error TS2344: Type 'GetProps[P]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. !!! error TS2344: Type 'GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. -!!! error TS2344: Type 'Extract> extends keyof TInjectedProps ? TInjectedProps[Extract>] extends GetProps[Extract>] ? GetProps[Extract>] : TInjectedProps[Extract>] : GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. -!!! error TS2344: Type 'GetProps[Extract>] | (TInjectedProps[Extract>] extends GetProps[Extract>] ? GetProps[Extract>] : TInjectedProps[Extract>])' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. -!!! error TS2344: Type 'GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. -!!! error TS2344: Type 'GetProps[Extract>] | GetProps[Extract>] | GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. -!!! error TS2344: Type 'GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. -!!! error TS2344: Type 'GetProps[keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. -!!! error TS2344: Type 'GetProps[string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. -!!! error TS2344: Type '(Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>]) | (Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>]) | (Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>])' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. -!!! error TS2344: Type 'Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. -!!! error TS2344: Type '(TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>]) | GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. -!!! error TS2344: Type 'TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. -!!! error TS2344: Type 'GetProps[keyof TInjectedProps & Extract>] | TInjectedProps[keyof TInjectedProps & Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. -!!! error TS2344: Type 'GetProps[keyof TInjectedProps & Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. -!!! error TS2344: Type 'GetProps[string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. -!!! error TS2344: Type 'keyof GetProps & string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string] : GetProps[keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. -!!! error TS2344: Type '(TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string]) | GetProps[keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. -!!! error TS2344: Type 'TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. -!!! error TS2344: Type 'GetProps[keyof TInjectedProps & keyof GetProps & string] | TInjectedProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. -!!! error TS2344: Type 'GetProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. -!!! error TS2344: Type 'GetProps[string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. -!!! error TS2344: Type 'string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & string] extends GetProps[keyof TInjectedProps & string] ? GetProps[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string] : GetProps[string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[P]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'Extract> extends keyof TInjectedProps ? TInjectedProps[Extract>] extends GetProps[Extract>] ? GetProps[Extract>] : TInjectedProps[Extract>] : GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[Extract>] | (TInjectedProps[Extract>] extends GetProps[Extract>] ? GetProps[Extract>] : TInjectedProps[Extract>])' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[Extract>] | GetProps[Extract>] | GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type '(Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>]) | (Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>]) | (Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>])' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type '(TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>]) | GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[keyof TInjectedProps & Extract>] | TInjectedProps[keyof TInjectedProps & Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[keyof TInjectedProps & Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[keyof TInjectedProps & Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'keyof GetProps & string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string] : GetProps[keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type '(TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string]) | GetProps[keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[keyof TInjectedProps & keyof GetProps & string] | TInjectedProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & string] extends GetProps[keyof TInjectedProps & string] ? GetProps[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string] : GetProps[string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'keyof GetProps & string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string] : GetProps[keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type '(TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string]) | GetProps[keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'GetProps[keyof TInjectedProps & keyof GetProps & string] | TInjectedProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'GetProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'GetProps[string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type '(TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>]) | GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'GetProps[keyof TInjectedProps & Extract>] | TInjectedProps[keyof TInjectedProps & Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'GetProps[keyof TInjectedProps & Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'GetProps[string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'Extract> extends keyof TInjectedProps ? TInjectedProps[Extract>] extends GetProps[Extract>] ? GetProps[Extract>] : TInjectedProps[Extract>] : GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'GetProps[Extract>] | (TInjectedProps[Extract>] extends GetProps[Extract>] ? GetProps[Extract>] : TInjectedProps[Extract>])' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'P extends keyof TInjectedProps ? TInjectedProps[P] extends GetProps[P] ? GetProps[P] : TInjectedProps[P] : GetProps[P]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'GetProps[P] | (TInjectedProps[P] extends GetProps[P] ? GetProps[P] : TInjectedProps[P])' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'GetProps[P]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'GetProps[Extract>] | GetProps[Extract>] | GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'GetProps[keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'GetProps[string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. >; declare const connect: { diff --git a/tests/baselines/reference/spellingSuggestionJSXAttribute.types b/tests/baselines/reference/spellingSuggestionJSXAttribute.types index 619ceb73e36ee..1a76683ef9961 100644 --- a/tests/baselines/reference/spellingSuggestionJSXAttribute.types +++ b/tests/baselines/reference/spellingSuggestionJSXAttribute.types @@ -4,13 +4,13 @@ import * as React from "react"; >React : typeof React function MyComp2(props: { className?: string, htmlFor?: string }) { ->MyComp2 : (props: { className?: string; htmlFor?: string;}) => any +>MyComp2 : (props: { className?: string; htmlFor?: string;}) => never >props : { className?: string; htmlFor?: string; } >className : string >htmlFor : string return null!; ->null! : null +>null! : never >null : null } class MyComp extends React.Component<{ className?: string, htmlFor?: string }> { } @@ -49,7 +49,7 @@ class MyComp extends React.Component<{ className?: string, htmlFor?: string }> { ; > : JSX.Element ->MyComp2 : (props: { className?: string; htmlFor?: string; }) => any +>MyComp2 : (props: { className?: string; htmlFor?: string; }) => never >class : string ; @@ -59,6 +59,6 @@ class MyComp extends React.Component<{ className?: string, htmlFor?: string }> { ; > : JSX.Element ->MyComp2 : (props: { className?: string; htmlFor?: string; }) => any +>MyComp2 : (props: { className?: string; htmlFor?: string; }) => never >for : string diff --git a/tests/baselines/reference/typeGuardTypeOfUndefined.types b/tests/baselines/reference/typeGuardTypeOfUndefined.types index 79f87e101caa8..ffc82e57e6693 100644 --- a/tests/baselines/reference/typeGuardTypeOfUndefined.types +++ b/tests/baselines/reference/typeGuardTypeOfUndefined.types @@ -242,7 +242,7 @@ function test9(a: boolean | number) { } else { a; ->a : undefined +>a : never } } @@ -259,7 +259,7 @@ function test10(a: boolean | number) { if (typeof a === "boolean") { >typeof a === "boolean" : boolean >typeof a : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function" ->a : undefined +>a : never >"boolean" : "boolean" a; @@ -267,7 +267,7 @@ function test10(a: boolean | number) { } else { a; ->a : undefined +>a : never } } else { diff --git a/tests/baselines/reference/typeParameterExplicitlyExtendsAny.errors.txt b/tests/baselines/reference/typeParameterExplicitlyExtendsAny.errors.txt index 07d7cee05f610..f646db7a2fcf4 100644 --- a/tests/baselines/reference/typeParameterExplicitlyExtendsAny.errors.txt +++ b/tests/baselines/reference/typeParameterExplicitlyExtendsAny.errors.txt @@ -2,9 +2,9 @@ tests/cases/compiler/typeParameterExplicitlyExtendsAny.ts(3,7): error TS2339: Pr tests/cases/compiler/typeParameterExplicitlyExtendsAny.ts(9,7): error TS2339: Property 'blah' does not exist on type 'T'. tests/cases/compiler/typeParameterExplicitlyExtendsAny.ts(14,7): error TS2339: Property 'children' does not exist on type 'T'. tests/cases/compiler/typeParameterExplicitlyExtendsAny.ts(15,5): error TS2349: This expression is not callable. - Type '{}' has no call signatures. + Type 'unknown' has no call signatures. tests/cases/compiler/typeParameterExplicitlyExtendsAny.ts(16,9): error TS2351: This expression is not constructable. - Type '{}' has no construct signatures. + Type 'unknown' has no construct signatures. tests/cases/compiler/typeParameterExplicitlyExtendsAny.ts(30,14): error TS2339: Property 'children' does not exist on type 'T'. @@ -32,11 +32,11 @@ tests/cases/compiler/typeParameterExplicitlyExtendsAny.ts(30,14): error TS2339: x(); ~ !!! error TS2349: This expression is not callable. -!!! error TS2349: Type '{}' has no call signatures. +!!! error TS2349: Type 'unknown' has no call signatures. new x(); ~ !!! error TS2351: This expression is not constructable. -!!! error TS2351: Type '{}' has no construct signatures. +!!! error TS2351: Type 'unknown' has no construct signatures. x[100]; x['hello']; } diff --git a/tests/baselines/reference/useUnknownInCatchVariables01.errors.txt b/tests/baselines/reference/useUnknownInCatchVariables01.errors.txt index 017c3ada88cd0..1217ddd0c4fa7 100644 --- a/tests/baselines/reference/useUnknownInCatchVariables01.errors.txt +++ b/tests/baselines/reference/useUnknownInCatchVariables01.errors.txt @@ -1,7 +1,7 @@ tests/cases/compiler/useUnknownInCatchVariables01.ts(6,12): error TS2339: Property 'toUpperCase' does not exist on type 'unknown'. tests/cases/compiler/useUnknownInCatchVariables01.ts(7,10): error TS2356: An arithmetic operand must be of type 'any', 'number', 'bigint' or an enum type. tests/cases/compiler/useUnknownInCatchVariables01.ts(8,10): error TS2349: This expression is not callable. - Type '{}' has no call signatures. + Type 'unknown' has no call signatures. ==== tests/cases/compiler/useUnknownInCatchVariables01.ts (3 errors) ==== @@ -19,7 +19,7 @@ tests/cases/compiler/useUnknownInCatchVariables01.ts(8,10): error TS2349: This e void e(); ~ !!! error TS2349: This expression is not callable. -!!! error TS2349: Type '{}' has no call signatures. +!!! error TS2349: Type 'unknown' has no call signatures. if (typeof e === "string") { // works! diff --git a/tests/cases/fourslash/codeFixInferFromUsageCallBodyBoth.ts b/tests/cases/fourslash/codeFixInferFromUsageCallBodyBoth.ts index f59d1bc190758..09c9cd83ff10a 100644 --- a/tests/cases/fourslash/codeFixInferFromUsageCallBodyBoth.ts +++ b/tests/cases/fourslash/codeFixInferFromUsageCallBodyBoth.ts @@ -13,4 +13,4 @@ ////f(new C()) -verify.rangeAfterCodeFix("x: number | C, y: undefined",/*includeWhiteSpace*/ undefined, /*errorCode*/ undefined, 0); +verify.rangeAfterCodeFix("x: number | C, y: any",/*includeWhiteSpace*/ undefined, /*errorCode*/ undefined, 0); diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess10.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess10.ts index 7161dd18d7cfa..1b565b5fa7bfd 100644 --- a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess10.ts +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess10.ts @@ -10,11 +10,11 @@ edit.applyRefactor({ actionName: "Generate 'get' and 'set' accessors", actionDescription: "Generate 'get' and 'set' accessors", newContent: `class A { - private /*RENAME*/_a?: string = "foo"; - public get a(): string { + private /*RENAME*/_a?: string | undefined = "foo"; + public get a(): string | undefined { return this._a; } - public set a(value: string) { + public set a(value: string | undefined) { this._a = value; } }`, From b45165d24eebf504bfe6c0f23ee92fd31305d1be Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Wed, 24 Aug 2022 10:48:23 -0700 Subject: [PATCH 03/24] strictNullChecks pragma tests, including cross-file type behavior --- .../strictNullChecksPragma1.errors.txt | 197 +++++++++ .../reference/strictNullChecksPragma1.js | 196 +++++++++ .../reference/strictNullChecksPragma1.symbols | 346 ++++++++++++++++ .../reference/strictNullChecksPragma1.types | 382 +++++++++++++++++ .../strictNullChecksPragma2.errors.txt | 195 +++++++++ .../reference/strictNullChecksPragma2.js | 194 +++++++++ .../reference/strictNullChecksPragma2.symbols | 344 ++++++++++++++++ .../reference/strictNullChecksPragma2.types | 380 +++++++++++++++++ .../strictNullChecksPragma3.errors.txt | 235 +++++++++++ .../reference/strictNullChecksPragma3.js | 198 +++++++++ .../reference/strictNullChecksPragma3.symbols | 350 ++++++++++++++++ .../reference/strictNullChecksPragma3.types | 388 ++++++++++++++++++ .../strictNullChecksPragma4.errors.txt | 233 +++++++++++ .../reference/strictNullChecksPragma4.js | 196 +++++++++ .../reference/strictNullChecksPragma4.symbols | 348 ++++++++++++++++ .../reference/strictNullChecksPragma4.types | 386 +++++++++++++++++ .../strictNullChecksPragma5.errors.txt | 207 ++++++++++ .../reference/strictNullChecksPragma5.js | 196 +++++++++ .../reference/strictNullChecksPragma5.symbols | 346 ++++++++++++++++ .../reference/strictNullChecksPragma5.types | 382 +++++++++++++++++ .../strictNullChecksPragma6.errors.txt | 205 +++++++++ .../reference/strictNullChecksPragma6.js | 194 +++++++++ .../reference/strictNullChecksPragma6.symbols | 344 ++++++++++++++++ .../reference/strictNullChecksPragma6.types | 380 +++++++++++++++++ .../strictNullChecksPragma1.ts | 122 ++++++ .../strictNullChecksPragma2.ts | 120 ++++++ .../strictNullChecksPragma3.ts | 122 ++++++ .../strictNullChecksPragma4.ts | 120 ++++++ .../strictNullChecksPragma5.ts | 122 ++++++ .../strictNullChecksPragma6.ts | 120 ++++++ 30 files changed, 7548 insertions(+) create mode 100644 tests/baselines/reference/strictNullChecksPragma1.errors.txt create mode 100644 tests/baselines/reference/strictNullChecksPragma1.js create mode 100644 tests/baselines/reference/strictNullChecksPragma1.symbols create mode 100644 tests/baselines/reference/strictNullChecksPragma1.types create mode 100644 tests/baselines/reference/strictNullChecksPragma2.errors.txt create mode 100644 tests/baselines/reference/strictNullChecksPragma2.js create mode 100644 tests/baselines/reference/strictNullChecksPragma2.symbols create mode 100644 tests/baselines/reference/strictNullChecksPragma2.types create mode 100644 tests/baselines/reference/strictNullChecksPragma3.errors.txt create mode 100644 tests/baselines/reference/strictNullChecksPragma3.js create mode 100644 tests/baselines/reference/strictNullChecksPragma3.symbols create mode 100644 tests/baselines/reference/strictNullChecksPragma3.types create mode 100644 tests/baselines/reference/strictNullChecksPragma4.errors.txt create mode 100644 tests/baselines/reference/strictNullChecksPragma4.js create mode 100644 tests/baselines/reference/strictNullChecksPragma4.symbols create mode 100644 tests/baselines/reference/strictNullChecksPragma4.types create mode 100644 tests/baselines/reference/strictNullChecksPragma5.errors.txt create mode 100644 tests/baselines/reference/strictNullChecksPragma5.js create mode 100644 tests/baselines/reference/strictNullChecksPragma5.symbols create mode 100644 tests/baselines/reference/strictNullChecksPragma5.types create mode 100644 tests/baselines/reference/strictNullChecksPragma6.errors.txt create mode 100644 tests/baselines/reference/strictNullChecksPragma6.js create mode 100644 tests/baselines/reference/strictNullChecksPragma6.symbols create mode 100644 tests/baselines/reference/strictNullChecksPragma6.types create mode 100644 tests/cases/conformance/pragma/strictNullChecks/strictNullChecksPragma1.ts create mode 100644 tests/cases/conformance/pragma/strictNullChecks/strictNullChecksPragma2.ts create mode 100644 tests/cases/conformance/pragma/strictNullChecks/strictNullChecksPragma3.ts create mode 100644 tests/cases/conformance/pragma/strictNullChecks/strictNullChecksPragma4.ts create mode 100644 tests/cases/conformance/pragma/strictNullChecks/strictNullChecksPragma5.ts create mode 100644 tests/cases/conformance/pragma/strictNullChecks/strictNullChecksPragma6.ts diff --git a/tests/baselines/reference/strictNullChecksPragma1.errors.txt b/tests/baselines/reference/strictNullChecksPragma1.errors.txt new file mode 100644 index 0000000000000..460e6d54d858b --- /dev/null +++ b/tests/baselines/reference/strictNullChecksPragma1.errors.txt @@ -0,0 +1,197 @@ +tests/cases/conformance/pragma/strictNullChecks/file1.ts(9,14): error TS2322: Type 'undefined' is not assignable to type 'string'. +tests/cases/conformance/pragma/strictNullChecks/file1.ts(11,1): error TS2322: Type 'B' is not assignable to type 'A'. +tests/cases/conformance/pragma/strictNullChecks/file1.ts(16,20): error TS2322: Type 'undefined' is not assignable to type 'string'. +tests/cases/conformance/pragma/strictNullChecks/file1.ts(25,1): error TS2322: Type 'import("tests/cases/conformance/pragma/strictNullChecks/file1").B' is not assignable to type 'import("tests/cases/conformance/pragma/strictNullChecks/file2").B'. +tests/cases/conformance/pragma/strictNullChecks/file1.ts(31,1): error TS2322: Type 'B' is not assignable to type 'A'. +tests/cases/conformance/pragma/strictNullChecks/file2.ts(18,1): error TS2322: Type 'B' is not assignable to type 'A'. + Types of property 'member' are incompatible. + Type 'string | undefined' is not assignable to type 'string'. + Type 'undefined' is not assignable to type 'string'. +tests/cases/conformance/pragma/strictNullChecks/file2.ts(24,1): error TS2322: Type 'import("tests/cases/conformance/pragma/strictNullChecks/file1").B' is not assignable to type 'import("tests/cases/conformance/pragma/strictNullChecks/file2").B'. + Types of property 'member' are incompatible. + Type 'string | undefined' is not assignable to type 'string'. + Type 'undefined' is not assignable to type 'string'. +tests/cases/conformance/pragma/strictNullChecks/file2.ts(27,1): error TS2322: Type 'B' is not assignable to type 'A'. + Types of property 'member' are incompatible. + Type 'string | undefined' is not assignable to type 'string'. + Type 'undefined' is not assignable to type 'string'. +tests/cases/conformance/pragma/strictNullChecks/file3.ts(5,14): error TS2322: Type 'undefined' is not assignable to type 'string'. +tests/cases/conformance/pragma/strictNullChecks/file3.ts(7,16): error TS2322: Type 'undefined' is not assignable to type 'string'. +tests/cases/conformance/pragma/strictNullChecks/file3.ts(8,16): error TS2322: Type 'undefined' is not assignable to type 'string'. +tests/cases/conformance/pragma/strictNullChecks/file3.ts(10,1): error TS2322: Type 'B' is not assignable to type 'A'. +tests/cases/conformance/pragma/strictNullChecks/file3.ts(20,1): error TS2322: Type 'import("tests/cases/conformance/pragma/strictNullChecks/file1").B' is not assignable to type 'import("tests/cases/conformance/pragma/strictNullChecks/file2").B'. +tests/cases/conformance/pragma/strictNullChecks/file3.ts(26,1): error TS2322: Type 'B' is not assignable to type 'A'. +tests/cases/conformance/pragma/strictNullChecks/file4.ts(10,1): error TS2322: Type 'B' is not assignable to type 'A'. +tests/cases/conformance/pragma/strictNullChecks/file4.ts(20,1): error TS2322: Type 'import("tests/cases/conformance/pragma/strictNullChecks/file1").B' is not assignable to type 'import("tests/cases/conformance/pragma/strictNullChecks/file2").B'. +tests/cases/conformance/pragma/strictNullChecks/file4.ts(26,1): error TS2322: Type 'B' is not assignable to type 'A'. + + +==== tests/cases/conformance/pragma/strictNullChecks/file1.ts (5 errors) ==== + // @ts-strictNullChecks + export interface A { + member: string; + } + export interface B { + member: string | undefined; + } + + let a: A = { member: undefined }; + ~~~~~~ +!!! error TS2322: Type 'undefined' is not assignable to type 'string'. +!!! related TS6500 tests/cases/conformance/pragma/strictNullChecks/file1.ts:3:5: The expected type comes from property 'member' which is declared here on type 'A' + declare var b: B; + a = b; + ~ +!!! error TS2322: Type 'B' is not assignable to type 'A'. + b = a; + + import {A as OtherA, B as OtherB} from "./file2"; + + let a2: OtherA = { member: undefined }; + ~~~~~~ +!!! error TS2322: Type 'undefined' is not assignable to type 'string'. +!!! related TS6500 /.src/tests/cases/conformance/pragma/strictNullChecks/file2.ts:3:5: The expected type comes from property 'member' which is declared here on type 'A' + declare var b2: OtherB; + a2 = b2; + b2 = a2; + + a = a2; + a2 = a; + + b = b2; + b2 = b; + ~~ +!!! error TS2322: Type 'import("tests/cases/conformance/pragma/strictNullChecks/file1").B' is not assignable to type 'import("tests/cases/conformance/pragma/strictNullChecks/file2").B'. + + a = b2; + b2 = a; + + b = a2; + a2 = b; + ~~ +!!! error TS2322: Type 'B' is not assignable to type 'A'. + +==== tests/cases/conformance/pragma/strictNullChecks/file2.ts (3 errors) ==== + // loose + export interface A { + member: string; + } + export interface B { + member: string | undefined; + } + + let a: A = { member: undefined }; + declare var b: B; + a = b; + b = a; + + import {A as OtherA, B as OtherB} from "./file1"; + + let a2: OtherA = { member: undefined }; + declare var b2: OtherB; + a2 = b2; + ~~ +!!! error TS2322: Type 'B' is not assignable to type 'A'. +!!! error TS2322: Types of property 'member' are incompatible. +!!! error TS2322: Type 'string | undefined' is not assignable to type 'string'. +!!! error TS2322: Type 'undefined' is not assignable to type 'string'. + b2 = a2; + + a = a2; + a2 = a; + + b = b2; + ~ +!!! error TS2322: Type 'import("tests/cases/conformance/pragma/strictNullChecks/file1").B' is not assignable to type 'import("tests/cases/conformance/pragma/strictNullChecks/file2").B'. +!!! error TS2322: Types of property 'member' are incompatible. +!!! error TS2322: Type 'string | undefined' is not assignable to type 'string'. +!!! error TS2322: Type 'undefined' is not assignable to type 'string'. + b2 = b; + + a = b2; + ~ +!!! error TS2322: Type 'B' is not assignable to type 'A'. +!!! error TS2322: Types of property 'member' are incompatible. +!!! error TS2322: Type 'string | undefined' is not assignable to type 'string'. +!!! error TS2322: Type 'undefined' is not assignable to type 'string'. + b2 = a; + + b = a2; + a2 = b; + +==== tests/cases/conformance/pragma/strictNullChecks/file3.ts (6 errors) ==== + // @ts-strictNullChecks + import {A, B} from "./file1"; + import {A as A2, B as B2} from "./file2"; + + let a: A = { member: undefined }; + ~~~~~~ +!!! error TS2322: Type 'undefined' is not assignable to type 'string'. +!!! related TS6500 tests/cases/conformance/pragma/strictNullChecks/file1.ts:3:5: The expected type comes from property 'member' which is declared here on type 'A' + let b: B = { member: undefined }; + let a2: A2 = { member: undefined }; + ~~~~~~ +!!! error TS2322: Type 'undefined' is not assignable to type 'string'. +!!! related TS6500 /.src/tests/cases/conformance/pragma/strictNullChecks/file2.ts:3:5: The expected type comes from property 'member' which is declared here on type 'A' + let b2: B2 = { member: undefined }; + ~~~~~~ +!!! error TS2322: Type 'undefined' is not assignable to type 'string'. +!!! related TS6500 /.src/tests/cases/conformance/pragma/strictNullChecks/file2.ts:6:5: The expected type comes from property 'member' which is declared here on type 'B' + + a = b; + ~ +!!! error TS2322: Type 'B' is not assignable to type 'A'. + b = a; + + a2 = b2; + b2 = a2; + + a = a2; + a2 = a; + + b = b2; + b2 = b; + ~~ +!!! error TS2322: Type 'import("tests/cases/conformance/pragma/strictNullChecks/file1").B' is not assignable to type 'import("tests/cases/conformance/pragma/strictNullChecks/file2").B'. + + a = b2; + b2 = a; + + b = a2; + a2 = b; + ~~ +!!! error TS2322: Type 'B' is not assignable to type 'A'. + +==== tests/cases/conformance/pragma/strictNullChecks/file4.ts (3 errors) ==== + // loose + import {A, B} from "./file1"; + import {A as A2, B as B2} from "./file2"; + + let a: A = { member: undefined }; + let b: B = { member: undefined }; + let a2: A2 = { member: undefined }; + let b2: B2 = { member: undefined }; + + a = b; + ~ +!!! error TS2322: Type 'B' is not assignable to type 'A'. + b = a; + + a2 = b2; + b2 = a2; + + a = a2; + a2 = a; + + b = b2; + b2 = b; + ~~ +!!! error TS2322: Type 'import("tests/cases/conformance/pragma/strictNullChecks/file1").B' is not assignable to type 'import("tests/cases/conformance/pragma/strictNullChecks/file2").B'. + + a = b2; + b2 = a; + + b = a2; + a2 = b; + ~~ +!!! error TS2322: Type 'B' is not assignable to type 'A'. \ No newline at end of file diff --git a/tests/baselines/reference/strictNullChecksPragma1.js b/tests/baselines/reference/strictNullChecksPragma1.js new file mode 100644 index 0000000000000..db7aedabdce21 --- /dev/null +++ b/tests/baselines/reference/strictNullChecksPragma1.js @@ -0,0 +1,196 @@ +//// [tests/cases/conformance/pragma/strictNullChecks/strictNullChecksPragma1.ts] //// + +//// [file1.ts] +// @ts-strictNullChecks +export interface A { + member: string; +} +export interface B { + member: string | undefined; +} + +let a: A = { member: undefined }; +declare var b: B; +a = b; +b = a; + +import {A as OtherA, B as OtherB} from "./file2"; + +let a2: OtherA = { member: undefined }; +declare var b2: OtherB; +a2 = b2; +b2 = a2; + +a = a2; +a2 = a; + +b = b2; +b2 = b; + +a = b2; +b2 = a; + +b = a2; +a2 = b; + +//// [file2.ts] +// loose +export interface A { + member: string; +} +export interface B { + member: string | undefined; +} + +let a: A = { member: undefined }; +declare var b: B; +a = b; +b = a; + +import {A as OtherA, B as OtherB} from "./file1"; + +let a2: OtherA = { member: undefined }; +declare var b2: OtherB; +a2 = b2; +b2 = a2; + +a = a2; +a2 = a; + +b = b2; +b2 = b; + +a = b2; +b2 = a; + +b = a2; +a2 = b; + +//// [file3.ts] +// @ts-strictNullChecks +import {A, B} from "./file1"; +import {A as A2, B as B2} from "./file2"; + +let a: A = { member: undefined }; +let b: B = { member: undefined }; +let a2: A2 = { member: undefined }; +let b2: B2 = { member: undefined }; + +a = b; +b = a; + +a2 = b2; +b2 = a2; + +a = a2; +a2 = a; + +b = b2; +b2 = b; + +a = b2; +b2 = a; + +b = a2; +a2 = b; + +//// [file4.ts] +// loose +import {A, B} from "./file1"; +import {A as A2, B as B2} from "./file2"; + +let a: A = { member: undefined }; +let b: B = { member: undefined }; +let a2: A2 = { member: undefined }; +let b2: B2 = { member: undefined }; + +a = b; +b = a; + +a2 = b2; +b2 = a2; + +a = a2; +a2 = a; + +b = b2; +b2 = b; + +a = b2; +b2 = a; + +b = a2; +a2 = b; + +//// [file2.js] +"use strict"; +exports.__esModule = true; +var a = { member: undefined }; +a = b; +b = a; +var a2 = { member: undefined }; +a2 = b2; +b2 = a2; +a = a2; +a2 = a; +b = b2; +b2 = b; +a = b2; +b2 = a; +b = a2; +a2 = b; +//// [file1.js] +"use strict"; +exports.__esModule = true; +var a = { member: undefined }; +a = b; +b = a; +var a2 = { member: undefined }; +a2 = b2; +b2 = a2; +a = a2; +a2 = a; +b = b2; +b2 = b; +a = b2; +b2 = a; +b = a2; +a2 = b; +//// [file3.js] +"use strict"; +exports.__esModule = true; +var a = { member: undefined }; +var b = { member: undefined }; +var a2 = { member: undefined }; +var b2 = { member: undefined }; +a = b; +b = a; +a2 = b2; +b2 = a2; +a = a2; +a2 = a; +b = b2; +b2 = b; +a = b2; +b2 = a; +b = a2; +a2 = b; +//// [file4.js] +"use strict"; +exports.__esModule = true; +var a = { member: undefined }; +var b = { member: undefined }; +var a2 = { member: undefined }; +var b2 = { member: undefined }; +a = b; +b = a; +a2 = b2; +b2 = a2; +a = a2; +a2 = a; +b = b2; +b2 = b; +a = b2; +b2 = a; +b = a2; +a2 = b; diff --git a/tests/baselines/reference/strictNullChecksPragma1.symbols b/tests/baselines/reference/strictNullChecksPragma1.symbols new file mode 100644 index 0000000000000..7b233d617d11b --- /dev/null +++ b/tests/baselines/reference/strictNullChecksPragma1.symbols @@ -0,0 +1,346 @@ +=== tests/cases/conformance/pragma/strictNullChecks/file1.ts === +// @ts-strictNullChecks +export interface A { +>A : Symbol(A, Decl(file1.ts, 0, 0)) + + member: string; +>member : Symbol(A.member, Decl(file1.ts, 1, 20)) +} +export interface B { +>B : Symbol(B, Decl(file1.ts, 3, 1)) + + member: string | undefined; +>member : Symbol(B.member, Decl(file1.ts, 4, 20)) +} + +let a: A = { member: undefined }; +>a : Symbol(a, Decl(file1.ts, 8, 3)) +>A : Symbol(A, Decl(file1.ts, 0, 0)) +>member : Symbol(member, Decl(file1.ts, 8, 12)) +>undefined : Symbol(undefined) + +declare var b: B; +>b : Symbol(b, Decl(file1.ts, 9, 11)) +>B : Symbol(B, Decl(file1.ts, 3, 1)) + +a = b; +>a : Symbol(a, Decl(file1.ts, 8, 3)) +>b : Symbol(b, Decl(file1.ts, 9, 11)) + +b = a; +>b : Symbol(b, Decl(file1.ts, 9, 11)) +>a : Symbol(a, Decl(file1.ts, 8, 3)) + +import {A as OtherA, B as OtherB} from "./file2"; +>A : Symbol(OtherA, Decl(file2.ts, 0, 0)) +>OtherA : Symbol(OtherA, Decl(file1.ts, 13, 8)) +>B : Symbol(OtherB, Decl(file2.ts, 3, 1)) +>OtherB : Symbol(OtherB, Decl(file1.ts, 13, 20)) + +let a2: OtherA = { member: undefined }; +>a2 : Symbol(a2, Decl(file1.ts, 15, 3)) +>OtherA : Symbol(OtherA, Decl(file1.ts, 13, 8)) +>member : Symbol(member, Decl(file1.ts, 15, 18)) +>undefined : Symbol(undefined) + +declare var b2: OtherB; +>b2 : Symbol(b2, Decl(file1.ts, 16, 11)) +>OtherB : Symbol(OtherB, Decl(file1.ts, 13, 20)) + +a2 = b2; +>a2 : Symbol(a2, Decl(file1.ts, 15, 3)) +>b2 : Symbol(b2, Decl(file1.ts, 16, 11)) + +b2 = a2; +>b2 : Symbol(b2, Decl(file1.ts, 16, 11)) +>a2 : Symbol(a2, Decl(file1.ts, 15, 3)) + +a = a2; +>a : Symbol(a, Decl(file1.ts, 8, 3)) +>a2 : Symbol(a2, Decl(file1.ts, 15, 3)) + +a2 = a; +>a2 : Symbol(a2, Decl(file1.ts, 15, 3)) +>a : Symbol(a, Decl(file1.ts, 8, 3)) + +b = b2; +>b : Symbol(b, Decl(file1.ts, 9, 11)) +>b2 : Symbol(b2, Decl(file1.ts, 16, 11)) + +b2 = b; +>b2 : Symbol(b2, Decl(file1.ts, 16, 11)) +>b : Symbol(b, Decl(file1.ts, 9, 11)) + +a = b2; +>a : Symbol(a, Decl(file1.ts, 8, 3)) +>b2 : Symbol(b2, Decl(file1.ts, 16, 11)) + +b2 = a; +>b2 : Symbol(b2, Decl(file1.ts, 16, 11)) +>a : Symbol(a, Decl(file1.ts, 8, 3)) + +b = a2; +>b : Symbol(b, Decl(file1.ts, 9, 11)) +>a2 : Symbol(a2, Decl(file1.ts, 15, 3)) + +a2 = b; +>a2 : Symbol(a2, Decl(file1.ts, 15, 3)) +>b : Symbol(b, Decl(file1.ts, 9, 11)) + +=== tests/cases/conformance/pragma/strictNullChecks/file2.ts === +// loose +export interface A { +>A : Symbol(A, Decl(file2.ts, 0, 0)) + + member: string; +>member : Symbol(A.member, Decl(file2.ts, 1, 20)) +} +export interface B { +>B : Symbol(B, Decl(file2.ts, 3, 1)) + + member: string | undefined; +>member : Symbol(B.member, Decl(file2.ts, 4, 20)) +} + +let a: A = { member: undefined }; +>a : Symbol(a, Decl(file2.ts, 8, 3)) +>A : Symbol(A, Decl(file2.ts, 0, 0)) +>member : Symbol(member, Decl(file2.ts, 8, 12)) +>undefined : Symbol(undefined) + +declare var b: B; +>b : Symbol(b, Decl(file2.ts, 9, 11)) +>B : Symbol(B, Decl(file2.ts, 3, 1)) + +a = b; +>a : Symbol(a, Decl(file2.ts, 8, 3)) +>b : Symbol(b, Decl(file2.ts, 9, 11)) + +b = a; +>b : Symbol(b, Decl(file2.ts, 9, 11)) +>a : Symbol(a, Decl(file2.ts, 8, 3)) + +import {A as OtherA, B as OtherB} from "./file1"; +>A : Symbol(OtherA, Decl(file1.ts, 0, 0)) +>OtherA : Symbol(OtherA, Decl(file2.ts, 13, 8)) +>B : Symbol(OtherB, Decl(file1.ts, 3, 1)) +>OtherB : Symbol(OtherB, Decl(file2.ts, 13, 20)) + +let a2: OtherA = { member: undefined }; +>a2 : Symbol(a2, Decl(file2.ts, 15, 3)) +>OtherA : Symbol(OtherA, Decl(file2.ts, 13, 8)) +>member : Symbol(member, Decl(file2.ts, 15, 18)) +>undefined : Symbol(undefined) + +declare var b2: OtherB; +>b2 : Symbol(b2, Decl(file2.ts, 16, 11)) +>OtherB : Symbol(OtherB, Decl(file2.ts, 13, 20)) + +a2 = b2; +>a2 : Symbol(a2, Decl(file2.ts, 15, 3)) +>b2 : Symbol(b2, Decl(file2.ts, 16, 11)) + +b2 = a2; +>b2 : Symbol(b2, Decl(file2.ts, 16, 11)) +>a2 : Symbol(a2, Decl(file2.ts, 15, 3)) + +a = a2; +>a : Symbol(a, Decl(file2.ts, 8, 3)) +>a2 : Symbol(a2, Decl(file2.ts, 15, 3)) + +a2 = a; +>a2 : Symbol(a2, Decl(file2.ts, 15, 3)) +>a : Symbol(a, Decl(file2.ts, 8, 3)) + +b = b2; +>b : Symbol(b, Decl(file2.ts, 9, 11)) +>b2 : Symbol(b2, Decl(file2.ts, 16, 11)) + +b2 = b; +>b2 : Symbol(b2, Decl(file2.ts, 16, 11)) +>b : Symbol(b, Decl(file2.ts, 9, 11)) + +a = b2; +>a : Symbol(a, Decl(file2.ts, 8, 3)) +>b2 : Symbol(b2, Decl(file2.ts, 16, 11)) + +b2 = a; +>b2 : Symbol(b2, Decl(file2.ts, 16, 11)) +>a : Symbol(a, Decl(file2.ts, 8, 3)) + +b = a2; +>b : Symbol(b, Decl(file2.ts, 9, 11)) +>a2 : Symbol(a2, Decl(file2.ts, 15, 3)) + +a2 = b; +>a2 : Symbol(a2, Decl(file2.ts, 15, 3)) +>b : Symbol(b, Decl(file2.ts, 9, 11)) + +=== tests/cases/conformance/pragma/strictNullChecks/file3.ts === +// @ts-strictNullChecks +import {A, B} from "./file1"; +>A : Symbol(A, Decl(file3.ts, 1, 8)) +>B : Symbol(B, Decl(file3.ts, 1, 10)) + +import {A as A2, B as B2} from "./file2"; +>A : Symbol(A2, Decl(file2.ts, 0, 0)) +>A2 : Symbol(A2, Decl(file3.ts, 2, 8)) +>B : Symbol(B2, Decl(file2.ts, 3, 1)) +>B2 : Symbol(B2, Decl(file3.ts, 2, 16)) + +let a: A = { member: undefined }; +>a : Symbol(a, Decl(file3.ts, 4, 3)) +>A : Symbol(A, Decl(file3.ts, 1, 8)) +>member : Symbol(member, Decl(file3.ts, 4, 12)) +>undefined : Symbol(undefined) + +let b: B = { member: undefined }; +>b : Symbol(b, Decl(file3.ts, 5, 3)) +>B : Symbol(B, Decl(file3.ts, 1, 10)) +>member : Symbol(member, Decl(file3.ts, 5, 12)) +>undefined : Symbol(undefined) + +let a2: A2 = { member: undefined }; +>a2 : Symbol(a2, Decl(file3.ts, 6, 3)) +>A2 : Symbol(A2, Decl(file3.ts, 2, 8)) +>member : Symbol(member, Decl(file3.ts, 6, 14)) +>undefined : Symbol(undefined) + +let b2: B2 = { member: undefined }; +>b2 : Symbol(b2, Decl(file3.ts, 7, 3)) +>B2 : Symbol(B2, Decl(file3.ts, 2, 16)) +>member : Symbol(member, Decl(file3.ts, 7, 14)) +>undefined : Symbol(undefined) + +a = b; +>a : Symbol(a, Decl(file3.ts, 4, 3)) +>b : Symbol(b, Decl(file3.ts, 5, 3)) + +b = a; +>b : Symbol(b, Decl(file3.ts, 5, 3)) +>a : Symbol(a, Decl(file3.ts, 4, 3)) + +a2 = b2; +>a2 : Symbol(a2, Decl(file3.ts, 6, 3)) +>b2 : Symbol(b2, Decl(file3.ts, 7, 3)) + +b2 = a2; +>b2 : Symbol(b2, Decl(file3.ts, 7, 3)) +>a2 : Symbol(a2, Decl(file3.ts, 6, 3)) + +a = a2; +>a : Symbol(a, Decl(file3.ts, 4, 3)) +>a2 : Symbol(a2, Decl(file3.ts, 6, 3)) + +a2 = a; +>a2 : Symbol(a2, Decl(file3.ts, 6, 3)) +>a : Symbol(a, Decl(file3.ts, 4, 3)) + +b = b2; +>b : Symbol(b, Decl(file3.ts, 5, 3)) +>b2 : Symbol(b2, Decl(file3.ts, 7, 3)) + +b2 = b; +>b2 : Symbol(b2, Decl(file3.ts, 7, 3)) +>b : Symbol(b, Decl(file3.ts, 5, 3)) + +a = b2; +>a : Symbol(a, Decl(file3.ts, 4, 3)) +>b2 : Symbol(b2, Decl(file3.ts, 7, 3)) + +b2 = a; +>b2 : Symbol(b2, Decl(file3.ts, 7, 3)) +>a : Symbol(a, Decl(file3.ts, 4, 3)) + +b = a2; +>b : Symbol(b, Decl(file3.ts, 5, 3)) +>a2 : Symbol(a2, Decl(file3.ts, 6, 3)) + +a2 = b; +>a2 : Symbol(a2, Decl(file3.ts, 6, 3)) +>b : Symbol(b, Decl(file3.ts, 5, 3)) + +=== tests/cases/conformance/pragma/strictNullChecks/file4.ts === +// loose +import {A, B} from "./file1"; +>A : Symbol(A, Decl(file4.ts, 1, 8)) +>B : Symbol(B, Decl(file4.ts, 1, 10)) + +import {A as A2, B as B2} from "./file2"; +>A : Symbol(A2, Decl(file2.ts, 0, 0)) +>A2 : Symbol(A2, Decl(file4.ts, 2, 8)) +>B : Symbol(B2, Decl(file2.ts, 3, 1)) +>B2 : Symbol(B2, Decl(file4.ts, 2, 16)) + +let a: A = { member: undefined }; +>a : Symbol(a, Decl(file4.ts, 4, 3)) +>A : Symbol(A, Decl(file4.ts, 1, 8)) +>member : Symbol(member, Decl(file4.ts, 4, 12)) +>undefined : Symbol(undefined) + +let b: B = { member: undefined }; +>b : Symbol(b, Decl(file4.ts, 5, 3)) +>B : Symbol(B, Decl(file4.ts, 1, 10)) +>member : Symbol(member, Decl(file4.ts, 5, 12)) +>undefined : Symbol(undefined) + +let a2: A2 = { member: undefined }; +>a2 : Symbol(a2, Decl(file4.ts, 6, 3)) +>A2 : Symbol(A2, Decl(file4.ts, 2, 8)) +>member : Symbol(member, Decl(file4.ts, 6, 14)) +>undefined : Symbol(undefined) + +let b2: B2 = { member: undefined }; +>b2 : Symbol(b2, Decl(file4.ts, 7, 3)) +>B2 : Symbol(B2, Decl(file4.ts, 2, 16)) +>member : Symbol(member, Decl(file4.ts, 7, 14)) +>undefined : Symbol(undefined) + +a = b; +>a : Symbol(a, Decl(file4.ts, 4, 3)) +>b : Symbol(b, Decl(file4.ts, 5, 3)) + +b = a; +>b : Symbol(b, Decl(file4.ts, 5, 3)) +>a : Symbol(a, Decl(file4.ts, 4, 3)) + +a2 = b2; +>a2 : Symbol(a2, Decl(file4.ts, 6, 3)) +>b2 : Symbol(b2, Decl(file4.ts, 7, 3)) + +b2 = a2; +>b2 : Symbol(b2, Decl(file4.ts, 7, 3)) +>a2 : Symbol(a2, Decl(file4.ts, 6, 3)) + +a = a2; +>a : Symbol(a, Decl(file4.ts, 4, 3)) +>a2 : Symbol(a2, Decl(file4.ts, 6, 3)) + +a2 = a; +>a2 : Symbol(a2, Decl(file4.ts, 6, 3)) +>a : Symbol(a, Decl(file4.ts, 4, 3)) + +b = b2; +>b : Symbol(b, Decl(file4.ts, 5, 3)) +>b2 : Symbol(b2, Decl(file4.ts, 7, 3)) + +b2 = b; +>b2 : Symbol(b2, Decl(file4.ts, 7, 3)) +>b : Symbol(b, Decl(file4.ts, 5, 3)) + +a = b2; +>a : Symbol(a, Decl(file4.ts, 4, 3)) +>b2 : Symbol(b2, Decl(file4.ts, 7, 3)) + +b2 = a; +>b2 : Symbol(b2, Decl(file4.ts, 7, 3)) +>a : Symbol(a, Decl(file4.ts, 4, 3)) + +b = a2; +>b : Symbol(b, Decl(file4.ts, 5, 3)) +>a2 : Symbol(a2, Decl(file4.ts, 6, 3)) + +a2 = b; +>a2 : Symbol(a2, Decl(file4.ts, 6, 3)) +>b : Symbol(b, Decl(file4.ts, 5, 3)) + diff --git a/tests/baselines/reference/strictNullChecksPragma1.types b/tests/baselines/reference/strictNullChecksPragma1.types new file mode 100644 index 0000000000000..f3024ac3034a9 --- /dev/null +++ b/tests/baselines/reference/strictNullChecksPragma1.types @@ -0,0 +1,382 @@ +=== tests/cases/conformance/pragma/strictNullChecks/file1.ts === +// @ts-strictNullChecks +export interface A { + member: string; +>member : string +} +export interface B { + member: string | undefined; +>member : string | undefined +} + +let a: A = { member: undefined }; +>a : A +>{ member: undefined } : { member: undefined; } +>member : undefined +>undefined : undefined + +declare var b: B; +>b : B + +a = b; +>a = b : B +>a : A +>b : B + +b = a; +>b = a : A +>b : B +>a : A + +import {A as OtherA, B as OtherB} from "./file2"; +>A : any +>OtherA : any +>B : any +>OtherB : any + +let a2: OtherA = { member: undefined }; +>a2 : OtherA +>{ member: undefined } : { member: undefined; } +>member : undefined +>undefined : undefined + +declare var b2: OtherB; +>b2 : OtherB + +a2 = b2; +>a2 = b2 : OtherB +>a2 : OtherA +>b2 : OtherB + +b2 = a2; +>b2 = a2 : OtherA +>b2 : OtherB +>a2 : OtherA + +a = a2; +>a = a2 : OtherA +>a : A +>a2 : OtherA + +a2 = a; +>a2 = a : A +>a2 : OtherA +>a : A + +b = b2; +>b = b2 : OtherB +>b : B +>b2 : OtherB + +b2 = b; +>b2 = b : B +>b2 : OtherB +>b : B + +a = b2; +>a = b2 : OtherB +>a : A +>b2 : OtherB + +b2 = a; +>b2 = a : A +>b2 : OtherB +>a : A + +b = a2; +>b = a2 : OtherA +>b : B +>a2 : OtherA + +a2 = b; +>a2 = b : B +>a2 : OtherA +>b : B + +=== tests/cases/conformance/pragma/strictNullChecks/file2.ts === +// loose +export interface A { + member: string; +>member : string +} +export interface B { + member: string | undefined; +>member : string +} + +let a: A = { member: undefined }; +>a : A +>{ member: undefined } : { member: undefined; } +>member : undefined +>undefined : undefined + +declare var b: B; +>b : B + +a = b; +>a = b : B +>a : A +>b : B + +b = a; +>b = a : A +>b : B +>a : A + +import {A as OtherA, B as OtherB} from "./file1"; +>A : any +>OtherA : any +>B : any +>OtherB : any + +let a2: OtherA = { member: undefined }; +>a2 : OtherA +>{ member: undefined } : { member: undefined; } +>member : undefined +>undefined : undefined + +declare var b2: OtherB; +>b2 : OtherB + +a2 = b2; +>a2 = b2 : OtherB +>a2 : OtherA +>b2 : OtherB + +b2 = a2; +>b2 = a2 : OtherA +>b2 : OtherB +>a2 : OtherA + +a = a2; +>a = a2 : OtherA +>a : A +>a2 : OtherA + +a2 = a; +>a2 = a : A +>a2 : OtherA +>a : A + +b = b2; +>b = b2 : OtherB +>b : B +>b2 : OtherB + +b2 = b; +>b2 = b : B +>b2 : OtherB +>b : B + +a = b2; +>a = b2 : OtherB +>a : A +>b2 : OtherB + +b2 = a; +>b2 = a : A +>b2 : OtherB +>a : A + +b = a2; +>b = a2 : OtherA +>b : B +>a2 : OtherA + +a2 = b; +>a2 = b : B +>a2 : OtherA +>b : B + +=== tests/cases/conformance/pragma/strictNullChecks/file3.ts === +// @ts-strictNullChecks +import {A, B} from "./file1"; +>A : any +>B : any + +import {A as A2, B as B2} from "./file2"; +>A : any +>A2 : any +>B : any +>B2 : any + +let a: A = { member: undefined }; +>a : A +>{ member: undefined } : { member: undefined; } +>member : undefined +>undefined : undefined + +let b: B = { member: undefined }; +>b : B +>{ member: undefined } : { member: undefined; } +>member : undefined +>undefined : undefined + +let a2: A2 = { member: undefined }; +>a2 : A2 +>{ member: undefined } : { member: undefined; } +>member : undefined +>undefined : undefined + +let b2: B2 = { member: undefined }; +>b2 : B2 +>{ member: undefined } : { member: undefined; } +>member : undefined +>undefined : undefined + +a = b; +>a = b : B +>a : A +>b : B + +b = a; +>b = a : A +>b : B +>a : A + +a2 = b2; +>a2 = b2 : B2 +>a2 : A2 +>b2 : B2 + +b2 = a2; +>b2 = a2 : A2 +>b2 : B2 +>a2 : A2 + +a = a2; +>a = a2 : A2 +>a : A +>a2 : A2 + +a2 = a; +>a2 = a : A +>a2 : A2 +>a : A + +b = b2; +>b = b2 : B2 +>b : B +>b2 : B2 + +b2 = b; +>b2 = b : B +>b2 : B2 +>b : B + +a = b2; +>a = b2 : B2 +>a : A +>b2 : B2 + +b2 = a; +>b2 = a : A +>b2 : B2 +>a : A + +b = a2; +>b = a2 : A2 +>b : B +>a2 : A2 + +a2 = b; +>a2 = b : B +>a2 : A2 +>b : B + +=== tests/cases/conformance/pragma/strictNullChecks/file4.ts === +// loose +import {A, B} from "./file1"; +>A : any +>B : any + +import {A as A2, B as B2} from "./file2"; +>A : any +>A2 : any +>B : any +>B2 : any + +let a: A = { member: undefined }; +>a : A +>{ member: undefined } : { member: undefined; } +>member : undefined +>undefined : undefined + +let b: B = { member: undefined }; +>b : B +>{ member: undefined } : { member: undefined; } +>member : undefined +>undefined : undefined + +let a2: A2 = { member: undefined }; +>a2 : A2 +>{ member: undefined } : { member: undefined; } +>member : undefined +>undefined : undefined + +let b2: B2 = { member: undefined }; +>b2 : B2 +>{ member: undefined } : { member: undefined; } +>member : undefined +>undefined : undefined + +a = b; +>a = b : B +>a : A +>b : B + +b = a; +>b = a : A +>b : B +>a : A + +a2 = b2; +>a2 = b2 : B2 +>a2 : A2 +>b2 : B2 + +b2 = a2; +>b2 = a2 : A2 +>b2 : B2 +>a2 : A2 + +a = a2; +>a = a2 : A2 +>a : A +>a2 : A2 + +a2 = a; +>a2 = a : A +>a2 : A2 +>a : A + +b = b2; +>b = b2 : B2 +>b : B +>b2 : B2 + +b2 = b; +>b2 = b : B +>b2 : B2 +>b : B + +a = b2; +>a = b2 : B2 +>a : A +>b2 : B2 + +b2 = a; +>b2 = a : A +>b2 : B2 +>a : A + +b = a2; +>b = a2 : A2 +>b : B +>a2 : A2 + +a2 = b; +>a2 = b : B +>a2 : A2 +>b : B + diff --git a/tests/baselines/reference/strictNullChecksPragma2.errors.txt b/tests/baselines/reference/strictNullChecksPragma2.errors.txt new file mode 100644 index 0000000000000..4706a4b4f9c34 --- /dev/null +++ b/tests/baselines/reference/strictNullChecksPragma2.errors.txt @@ -0,0 +1,195 @@ +tests/cases/conformance/pragma/strictNullChecks/file1.ts(8,14): error TS2322: Type 'undefined' is not assignable to type 'string'. +tests/cases/conformance/pragma/strictNullChecks/file1.ts(10,1): error TS2322: Type 'B' is not assignable to type 'A'. +tests/cases/conformance/pragma/strictNullChecks/file1.ts(15,20): error TS2322: Type 'undefined' is not assignable to type 'string'. +tests/cases/conformance/pragma/strictNullChecks/file1.ts(24,1): error TS2322: Type 'import("tests/cases/conformance/pragma/strictNullChecks/file1").B' is not assignable to type 'import("tests/cases/conformance/pragma/strictNullChecks/file2").B'. +tests/cases/conformance/pragma/strictNullChecks/file1.ts(30,1): error TS2322: Type 'B' is not assignable to type 'A'. +tests/cases/conformance/pragma/strictNullChecks/file2.ts(18,1): error TS2322: Type 'B' is not assignable to type 'A'. + Types of property 'member' are incompatible. + Type 'string | undefined' is not assignable to type 'string'. + Type 'undefined' is not assignable to type 'string'. +tests/cases/conformance/pragma/strictNullChecks/file2.ts(24,1): error TS2322: Type 'import("tests/cases/conformance/pragma/strictNullChecks/file1").B' is not assignable to type 'import("tests/cases/conformance/pragma/strictNullChecks/file2").B'. + Types of property 'member' are incompatible. + Type 'string | undefined' is not assignable to type 'string'. + Type 'undefined' is not assignable to type 'string'. +tests/cases/conformance/pragma/strictNullChecks/file2.ts(27,1): error TS2322: Type 'B' is not assignable to type 'A'. + Types of property 'member' are incompatible. + Type 'string | undefined' is not assignable to type 'string'. + Type 'undefined' is not assignable to type 'string'. +tests/cases/conformance/pragma/strictNullChecks/file3.ts(4,14): error TS2322: Type 'undefined' is not assignable to type 'string'. +tests/cases/conformance/pragma/strictNullChecks/file3.ts(6,16): error TS2322: Type 'undefined' is not assignable to type 'string'. +tests/cases/conformance/pragma/strictNullChecks/file3.ts(7,16): error TS2322: Type 'undefined' is not assignable to type 'string'. +tests/cases/conformance/pragma/strictNullChecks/file3.ts(9,1): error TS2322: Type 'B' is not assignable to type 'A'. +tests/cases/conformance/pragma/strictNullChecks/file3.ts(19,1): error TS2322: Type 'import("tests/cases/conformance/pragma/strictNullChecks/file1").B' is not assignable to type 'import("tests/cases/conformance/pragma/strictNullChecks/file2").B'. +tests/cases/conformance/pragma/strictNullChecks/file3.ts(25,1): error TS2322: Type 'B' is not assignable to type 'A'. +tests/cases/conformance/pragma/strictNullChecks/file4.ts(10,1): error TS2322: Type 'B' is not assignable to type 'A'. +tests/cases/conformance/pragma/strictNullChecks/file4.ts(20,1): error TS2322: Type 'import("tests/cases/conformance/pragma/strictNullChecks/file1").B' is not assignable to type 'import("tests/cases/conformance/pragma/strictNullChecks/file2").B'. +tests/cases/conformance/pragma/strictNullChecks/file4.ts(26,1): error TS2322: Type 'B' is not assignable to type 'A'. + + +==== tests/cases/conformance/pragma/strictNullChecks/file1.ts (5 errors) ==== + export interface A { + member: string; + } + export interface B { + member: string | undefined; + } + + let a: A = { member: undefined }; + ~~~~~~ +!!! error TS2322: Type 'undefined' is not assignable to type 'string'. +!!! related TS6500 tests/cases/conformance/pragma/strictNullChecks/file1.ts:2:5: The expected type comes from property 'member' which is declared here on type 'A' + declare var b: B; + a = b; + ~ +!!! error TS2322: Type 'B' is not assignable to type 'A'. + b = a; + + import {A as OtherA, B as OtherB} from "./file2"; + + let a2: OtherA = { member: undefined }; + ~~~~~~ +!!! error TS2322: Type 'undefined' is not assignable to type 'string'. +!!! related TS6500 /.src/tests/cases/conformance/pragma/strictNullChecks/file2.ts:3:5: The expected type comes from property 'member' which is declared here on type 'A' + declare var b2: OtherB; + a2 = b2; + b2 = a2; + + a = a2; + a2 = a; + + b = b2; + b2 = b; + ~~ +!!! error TS2322: Type 'import("tests/cases/conformance/pragma/strictNullChecks/file1").B' is not assignable to type 'import("tests/cases/conformance/pragma/strictNullChecks/file2").B'. + + a = b2; + b2 = a; + + b = a2; + a2 = b; + ~~ +!!! error TS2322: Type 'B' is not assignable to type 'A'. + +==== tests/cases/conformance/pragma/strictNullChecks/file2.ts (3 errors) ==== + // @ts-strictNullChecks false + export interface A { + member: string; + } + export interface B { + member: string | undefined; + } + + let a: A = { member: undefined }; + declare var b: B; + a = b; + b = a; + + import {A as OtherA, B as OtherB} from "./file1"; + + let a2: OtherA = { member: undefined }; + declare var b2: OtherB; + a2 = b2; + ~~ +!!! error TS2322: Type 'B' is not assignable to type 'A'. +!!! error TS2322: Types of property 'member' are incompatible. +!!! error TS2322: Type 'string | undefined' is not assignable to type 'string'. +!!! error TS2322: Type 'undefined' is not assignable to type 'string'. + b2 = a2; + + a = a2; + a2 = a; + + b = b2; + ~ +!!! error TS2322: Type 'import("tests/cases/conformance/pragma/strictNullChecks/file1").B' is not assignable to type 'import("tests/cases/conformance/pragma/strictNullChecks/file2").B'. +!!! error TS2322: Types of property 'member' are incompatible. +!!! error TS2322: Type 'string | undefined' is not assignable to type 'string'. +!!! error TS2322: Type 'undefined' is not assignable to type 'string'. + b2 = b; + + a = b2; + ~ +!!! error TS2322: Type 'B' is not assignable to type 'A'. +!!! error TS2322: Types of property 'member' are incompatible. +!!! error TS2322: Type 'string | undefined' is not assignable to type 'string'. +!!! error TS2322: Type 'undefined' is not assignable to type 'string'. + b2 = a; + + b = a2; + a2 = b; + +==== tests/cases/conformance/pragma/strictNullChecks/file3.ts (6 errors) ==== + import {A, B} from "./file1"; + import {A as A2, B as B2} from "./file2"; + + let a: A = { member: undefined }; + ~~~~~~ +!!! error TS2322: Type 'undefined' is not assignable to type 'string'. +!!! related TS6500 tests/cases/conformance/pragma/strictNullChecks/file1.ts:2:5: The expected type comes from property 'member' which is declared here on type 'A' + let b: B = { member: undefined }; + let a2: A2 = { member: undefined }; + ~~~~~~ +!!! error TS2322: Type 'undefined' is not assignable to type 'string'. +!!! related TS6500 /.src/tests/cases/conformance/pragma/strictNullChecks/file2.ts:3:5: The expected type comes from property 'member' which is declared here on type 'A' + let b2: B2 = { member: undefined }; + ~~~~~~ +!!! error TS2322: Type 'undefined' is not assignable to type 'string'. +!!! related TS6500 /.src/tests/cases/conformance/pragma/strictNullChecks/file2.ts:6:5: The expected type comes from property 'member' which is declared here on type 'B' + + a = b; + ~ +!!! error TS2322: Type 'B' is not assignable to type 'A'. + b = a; + + a2 = b2; + b2 = a2; + + a = a2; + a2 = a; + + b = b2; + b2 = b; + ~~ +!!! error TS2322: Type 'import("tests/cases/conformance/pragma/strictNullChecks/file1").B' is not assignable to type 'import("tests/cases/conformance/pragma/strictNullChecks/file2").B'. + + a = b2; + b2 = a; + + b = a2; + a2 = b; + ~~ +!!! error TS2322: Type 'B' is not assignable to type 'A'. + +==== tests/cases/conformance/pragma/strictNullChecks/file4.ts (3 errors) ==== + // @ts-strictNullChecks false + import {A, B} from "./file1"; + import {A as A2, B as B2} from "./file2"; + + let a: A = { member: undefined }; + let b: B = { member: undefined }; + let a2: A2 = { member: undefined }; + let b2: B2 = { member: undefined }; + + a = b; + ~ +!!! error TS2322: Type 'B' is not assignable to type 'A'. + b = a; + + a2 = b2; + b2 = a2; + + a = a2; + a2 = a; + + b = b2; + b2 = b; + ~~ +!!! error TS2322: Type 'import("tests/cases/conformance/pragma/strictNullChecks/file1").B' is not assignable to type 'import("tests/cases/conformance/pragma/strictNullChecks/file2").B'. + + a = b2; + b2 = a; + + b = a2; + a2 = b; + ~~ +!!! error TS2322: Type 'B' is not assignable to type 'A'. \ No newline at end of file diff --git a/tests/baselines/reference/strictNullChecksPragma2.js b/tests/baselines/reference/strictNullChecksPragma2.js new file mode 100644 index 0000000000000..86551ff590c7a --- /dev/null +++ b/tests/baselines/reference/strictNullChecksPragma2.js @@ -0,0 +1,194 @@ +//// [tests/cases/conformance/pragma/strictNullChecks/strictNullChecksPragma2.ts] //// + +//// [file1.ts] +export interface A { + member: string; +} +export interface B { + member: string | undefined; +} + +let a: A = { member: undefined }; +declare var b: B; +a = b; +b = a; + +import {A as OtherA, B as OtherB} from "./file2"; + +let a2: OtherA = { member: undefined }; +declare var b2: OtherB; +a2 = b2; +b2 = a2; + +a = a2; +a2 = a; + +b = b2; +b2 = b; + +a = b2; +b2 = a; + +b = a2; +a2 = b; + +//// [file2.ts] +// @ts-strictNullChecks false +export interface A { + member: string; +} +export interface B { + member: string | undefined; +} + +let a: A = { member: undefined }; +declare var b: B; +a = b; +b = a; + +import {A as OtherA, B as OtherB} from "./file1"; + +let a2: OtherA = { member: undefined }; +declare var b2: OtherB; +a2 = b2; +b2 = a2; + +a = a2; +a2 = a; + +b = b2; +b2 = b; + +a = b2; +b2 = a; + +b = a2; +a2 = b; + +//// [file3.ts] +import {A, B} from "./file1"; +import {A as A2, B as B2} from "./file2"; + +let a: A = { member: undefined }; +let b: B = { member: undefined }; +let a2: A2 = { member: undefined }; +let b2: B2 = { member: undefined }; + +a = b; +b = a; + +a2 = b2; +b2 = a2; + +a = a2; +a2 = a; + +b = b2; +b2 = b; + +a = b2; +b2 = a; + +b = a2; +a2 = b; + +//// [file4.ts] +// @ts-strictNullChecks false +import {A, B} from "./file1"; +import {A as A2, B as B2} from "./file2"; + +let a: A = { member: undefined }; +let b: B = { member: undefined }; +let a2: A2 = { member: undefined }; +let b2: B2 = { member: undefined }; + +a = b; +b = a; + +a2 = b2; +b2 = a2; + +a = a2; +a2 = a; + +b = b2; +b2 = b; + +a = b2; +b2 = a; + +b = a2; +a2 = b; + +//// [file2.js] +"use strict"; +exports.__esModule = true; +var a = { member: undefined }; +a = b; +b = a; +var a2 = { member: undefined }; +a2 = b2; +b2 = a2; +a = a2; +a2 = a; +b = b2; +b2 = b; +a = b2; +b2 = a; +b = a2; +a2 = b; +//// [file1.js] +"use strict"; +exports.__esModule = true; +var a = { member: undefined }; +a = b; +b = a; +var a2 = { member: undefined }; +a2 = b2; +b2 = a2; +a = a2; +a2 = a; +b = b2; +b2 = b; +a = b2; +b2 = a; +b = a2; +a2 = b; +//// [file3.js] +"use strict"; +exports.__esModule = true; +var a = { member: undefined }; +var b = { member: undefined }; +var a2 = { member: undefined }; +var b2 = { member: undefined }; +a = b; +b = a; +a2 = b2; +b2 = a2; +a = a2; +a2 = a; +b = b2; +b2 = b; +a = b2; +b2 = a; +b = a2; +a2 = b; +//// [file4.js] +"use strict"; +exports.__esModule = true; +var a = { member: undefined }; +var b = { member: undefined }; +var a2 = { member: undefined }; +var b2 = { member: undefined }; +a = b; +b = a; +a2 = b2; +b2 = a2; +a = a2; +a2 = a; +b = b2; +b2 = b; +a = b2; +b2 = a; +b = a2; +a2 = b; diff --git a/tests/baselines/reference/strictNullChecksPragma2.symbols b/tests/baselines/reference/strictNullChecksPragma2.symbols new file mode 100644 index 0000000000000..4dfacc433151f --- /dev/null +++ b/tests/baselines/reference/strictNullChecksPragma2.symbols @@ -0,0 +1,344 @@ +=== tests/cases/conformance/pragma/strictNullChecks/file1.ts === +export interface A { +>A : Symbol(A, Decl(file1.ts, 0, 0)) + + member: string; +>member : Symbol(A.member, Decl(file1.ts, 0, 20)) +} +export interface B { +>B : Symbol(B, Decl(file1.ts, 2, 1)) + + member: string | undefined; +>member : Symbol(B.member, Decl(file1.ts, 3, 20)) +} + +let a: A = { member: undefined }; +>a : Symbol(a, Decl(file1.ts, 7, 3)) +>A : Symbol(A, Decl(file1.ts, 0, 0)) +>member : Symbol(member, Decl(file1.ts, 7, 12)) +>undefined : Symbol(undefined) + +declare var b: B; +>b : Symbol(b, Decl(file1.ts, 8, 11)) +>B : Symbol(B, Decl(file1.ts, 2, 1)) + +a = b; +>a : Symbol(a, Decl(file1.ts, 7, 3)) +>b : Symbol(b, Decl(file1.ts, 8, 11)) + +b = a; +>b : Symbol(b, Decl(file1.ts, 8, 11)) +>a : Symbol(a, Decl(file1.ts, 7, 3)) + +import {A as OtherA, B as OtherB} from "./file2"; +>A : Symbol(OtherA, Decl(file2.ts, 0, 0)) +>OtherA : Symbol(OtherA, Decl(file1.ts, 12, 8)) +>B : Symbol(OtherB, Decl(file2.ts, 3, 1)) +>OtherB : Symbol(OtherB, Decl(file1.ts, 12, 20)) + +let a2: OtherA = { member: undefined }; +>a2 : Symbol(a2, Decl(file1.ts, 14, 3)) +>OtherA : Symbol(OtherA, Decl(file1.ts, 12, 8)) +>member : Symbol(member, Decl(file1.ts, 14, 18)) +>undefined : Symbol(undefined) + +declare var b2: OtherB; +>b2 : Symbol(b2, Decl(file1.ts, 15, 11)) +>OtherB : Symbol(OtherB, Decl(file1.ts, 12, 20)) + +a2 = b2; +>a2 : Symbol(a2, Decl(file1.ts, 14, 3)) +>b2 : Symbol(b2, Decl(file1.ts, 15, 11)) + +b2 = a2; +>b2 : Symbol(b2, Decl(file1.ts, 15, 11)) +>a2 : Symbol(a2, Decl(file1.ts, 14, 3)) + +a = a2; +>a : Symbol(a, Decl(file1.ts, 7, 3)) +>a2 : Symbol(a2, Decl(file1.ts, 14, 3)) + +a2 = a; +>a2 : Symbol(a2, Decl(file1.ts, 14, 3)) +>a : Symbol(a, Decl(file1.ts, 7, 3)) + +b = b2; +>b : Symbol(b, Decl(file1.ts, 8, 11)) +>b2 : Symbol(b2, Decl(file1.ts, 15, 11)) + +b2 = b; +>b2 : Symbol(b2, Decl(file1.ts, 15, 11)) +>b : Symbol(b, Decl(file1.ts, 8, 11)) + +a = b2; +>a : Symbol(a, Decl(file1.ts, 7, 3)) +>b2 : Symbol(b2, Decl(file1.ts, 15, 11)) + +b2 = a; +>b2 : Symbol(b2, Decl(file1.ts, 15, 11)) +>a : Symbol(a, Decl(file1.ts, 7, 3)) + +b = a2; +>b : Symbol(b, Decl(file1.ts, 8, 11)) +>a2 : Symbol(a2, Decl(file1.ts, 14, 3)) + +a2 = b; +>a2 : Symbol(a2, Decl(file1.ts, 14, 3)) +>b : Symbol(b, Decl(file1.ts, 8, 11)) + +=== tests/cases/conformance/pragma/strictNullChecks/file2.ts === +// @ts-strictNullChecks false +export interface A { +>A : Symbol(A, Decl(file2.ts, 0, 0)) + + member: string; +>member : Symbol(A.member, Decl(file2.ts, 1, 20)) +} +export interface B { +>B : Symbol(B, Decl(file2.ts, 3, 1)) + + member: string | undefined; +>member : Symbol(B.member, Decl(file2.ts, 4, 20)) +} + +let a: A = { member: undefined }; +>a : Symbol(a, Decl(file2.ts, 8, 3)) +>A : Symbol(A, Decl(file2.ts, 0, 0)) +>member : Symbol(member, Decl(file2.ts, 8, 12)) +>undefined : Symbol(undefined) + +declare var b: B; +>b : Symbol(b, Decl(file2.ts, 9, 11)) +>B : Symbol(B, Decl(file2.ts, 3, 1)) + +a = b; +>a : Symbol(a, Decl(file2.ts, 8, 3)) +>b : Symbol(b, Decl(file2.ts, 9, 11)) + +b = a; +>b : Symbol(b, Decl(file2.ts, 9, 11)) +>a : Symbol(a, Decl(file2.ts, 8, 3)) + +import {A as OtherA, B as OtherB} from "./file1"; +>A : Symbol(OtherA, Decl(file1.ts, 0, 0)) +>OtherA : Symbol(OtherA, Decl(file2.ts, 13, 8)) +>B : Symbol(OtherB, Decl(file1.ts, 2, 1)) +>OtherB : Symbol(OtherB, Decl(file2.ts, 13, 20)) + +let a2: OtherA = { member: undefined }; +>a2 : Symbol(a2, Decl(file2.ts, 15, 3)) +>OtherA : Symbol(OtherA, Decl(file2.ts, 13, 8)) +>member : Symbol(member, Decl(file2.ts, 15, 18)) +>undefined : Symbol(undefined) + +declare var b2: OtherB; +>b2 : Symbol(b2, Decl(file2.ts, 16, 11)) +>OtherB : Symbol(OtherB, Decl(file2.ts, 13, 20)) + +a2 = b2; +>a2 : Symbol(a2, Decl(file2.ts, 15, 3)) +>b2 : Symbol(b2, Decl(file2.ts, 16, 11)) + +b2 = a2; +>b2 : Symbol(b2, Decl(file2.ts, 16, 11)) +>a2 : Symbol(a2, Decl(file2.ts, 15, 3)) + +a = a2; +>a : Symbol(a, Decl(file2.ts, 8, 3)) +>a2 : Symbol(a2, Decl(file2.ts, 15, 3)) + +a2 = a; +>a2 : Symbol(a2, Decl(file2.ts, 15, 3)) +>a : Symbol(a, Decl(file2.ts, 8, 3)) + +b = b2; +>b : Symbol(b, Decl(file2.ts, 9, 11)) +>b2 : Symbol(b2, Decl(file2.ts, 16, 11)) + +b2 = b; +>b2 : Symbol(b2, Decl(file2.ts, 16, 11)) +>b : Symbol(b, Decl(file2.ts, 9, 11)) + +a = b2; +>a : Symbol(a, Decl(file2.ts, 8, 3)) +>b2 : Symbol(b2, Decl(file2.ts, 16, 11)) + +b2 = a; +>b2 : Symbol(b2, Decl(file2.ts, 16, 11)) +>a : Symbol(a, Decl(file2.ts, 8, 3)) + +b = a2; +>b : Symbol(b, Decl(file2.ts, 9, 11)) +>a2 : Symbol(a2, Decl(file2.ts, 15, 3)) + +a2 = b; +>a2 : Symbol(a2, Decl(file2.ts, 15, 3)) +>b : Symbol(b, Decl(file2.ts, 9, 11)) + +=== tests/cases/conformance/pragma/strictNullChecks/file3.ts === +import {A, B} from "./file1"; +>A : Symbol(A, Decl(file3.ts, 0, 8)) +>B : Symbol(B, Decl(file3.ts, 0, 10)) + +import {A as A2, B as B2} from "./file2"; +>A : Symbol(A2, Decl(file2.ts, 0, 0)) +>A2 : Symbol(A2, Decl(file3.ts, 1, 8)) +>B : Symbol(B2, Decl(file2.ts, 3, 1)) +>B2 : Symbol(B2, Decl(file3.ts, 1, 16)) + +let a: A = { member: undefined }; +>a : Symbol(a, Decl(file3.ts, 3, 3)) +>A : Symbol(A, Decl(file3.ts, 0, 8)) +>member : Symbol(member, Decl(file3.ts, 3, 12)) +>undefined : Symbol(undefined) + +let b: B = { member: undefined }; +>b : Symbol(b, Decl(file3.ts, 4, 3)) +>B : Symbol(B, Decl(file3.ts, 0, 10)) +>member : Symbol(member, Decl(file3.ts, 4, 12)) +>undefined : Symbol(undefined) + +let a2: A2 = { member: undefined }; +>a2 : Symbol(a2, Decl(file3.ts, 5, 3)) +>A2 : Symbol(A2, Decl(file3.ts, 1, 8)) +>member : Symbol(member, Decl(file3.ts, 5, 14)) +>undefined : Symbol(undefined) + +let b2: B2 = { member: undefined }; +>b2 : Symbol(b2, Decl(file3.ts, 6, 3)) +>B2 : Symbol(B2, Decl(file3.ts, 1, 16)) +>member : Symbol(member, Decl(file3.ts, 6, 14)) +>undefined : Symbol(undefined) + +a = b; +>a : Symbol(a, Decl(file3.ts, 3, 3)) +>b : Symbol(b, Decl(file3.ts, 4, 3)) + +b = a; +>b : Symbol(b, Decl(file3.ts, 4, 3)) +>a : Symbol(a, Decl(file3.ts, 3, 3)) + +a2 = b2; +>a2 : Symbol(a2, Decl(file3.ts, 5, 3)) +>b2 : Symbol(b2, Decl(file3.ts, 6, 3)) + +b2 = a2; +>b2 : Symbol(b2, Decl(file3.ts, 6, 3)) +>a2 : Symbol(a2, Decl(file3.ts, 5, 3)) + +a = a2; +>a : Symbol(a, Decl(file3.ts, 3, 3)) +>a2 : Symbol(a2, Decl(file3.ts, 5, 3)) + +a2 = a; +>a2 : Symbol(a2, Decl(file3.ts, 5, 3)) +>a : Symbol(a, Decl(file3.ts, 3, 3)) + +b = b2; +>b : Symbol(b, Decl(file3.ts, 4, 3)) +>b2 : Symbol(b2, Decl(file3.ts, 6, 3)) + +b2 = b; +>b2 : Symbol(b2, Decl(file3.ts, 6, 3)) +>b : Symbol(b, Decl(file3.ts, 4, 3)) + +a = b2; +>a : Symbol(a, Decl(file3.ts, 3, 3)) +>b2 : Symbol(b2, Decl(file3.ts, 6, 3)) + +b2 = a; +>b2 : Symbol(b2, Decl(file3.ts, 6, 3)) +>a : Symbol(a, Decl(file3.ts, 3, 3)) + +b = a2; +>b : Symbol(b, Decl(file3.ts, 4, 3)) +>a2 : Symbol(a2, Decl(file3.ts, 5, 3)) + +a2 = b; +>a2 : Symbol(a2, Decl(file3.ts, 5, 3)) +>b : Symbol(b, Decl(file3.ts, 4, 3)) + +=== tests/cases/conformance/pragma/strictNullChecks/file4.ts === +// @ts-strictNullChecks false +import {A, B} from "./file1"; +>A : Symbol(A, Decl(file4.ts, 1, 8)) +>B : Symbol(B, Decl(file4.ts, 1, 10)) + +import {A as A2, B as B2} from "./file2"; +>A : Symbol(A2, Decl(file2.ts, 0, 0)) +>A2 : Symbol(A2, Decl(file4.ts, 2, 8)) +>B : Symbol(B2, Decl(file2.ts, 3, 1)) +>B2 : Symbol(B2, Decl(file4.ts, 2, 16)) + +let a: A = { member: undefined }; +>a : Symbol(a, Decl(file4.ts, 4, 3)) +>A : Symbol(A, Decl(file4.ts, 1, 8)) +>member : Symbol(member, Decl(file4.ts, 4, 12)) +>undefined : Symbol(undefined) + +let b: B = { member: undefined }; +>b : Symbol(b, Decl(file4.ts, 5, 3)) +>B : Symbol(B, Decl(file4.ts, 1, 10)) +>member : Symbol(member, Decl(file4.ts, 5, 12)) +>undefined : Symbol(undefined) + +let a2: A2 = { member: undefined }; +>a2 : Symbol(a2, Decl(file4.ts, 6, 3)) +>A2 : Symbol(A2, Decl(file4.ts, 2, 8)) +>member : Symbol(member, Decl(file4.ts, 6, 14)) +>undefined : Symbol(undefined) + +let b2: B2 = { member: undefined }; +>b2 : Symbol(b2, Decl(file4.ts, 7, 3)) +>B2 : Symbol(B2, Decl(file4.ts, 2, 16)) +>member : Symbol(member, Decl(file4.ts, 7, 14)) +>undefined : Symbol(undefined) + +a = b; +>a : Symbol(a, Decl(file4.ts, 4, 3)) +>b : Symbol(b, Decl(file4.ts, 5, 3)) + +b = a; +>b : Symbol(b, Decl(file4.ts, 5, 3)) +>a : Symbol(a, Decl(file4.ts, 4, 3)) + +a2 = b2; +>a2 : Symbol(a2, Decl(file4.ts, 6, 3)) +>b2 : Symbol(b2, Decl(file4.ts, 7, 3)) + +b2 = a2; +>b2 : Symbol(b2, Decl(file4.ts, 7, 3)) +>a2 : Symbol(a2, Decl(file4.ts, 6, 3)) + +a = a2; +>a : Symbol(a, Decl(file4.ts, 4, 3)) +>a2 : Symbol(a2, Decl(file4.ts, 6, 3)) + +a2 = a; +>a2 : Symbol(a2, Decl(file4.ts, 6, 3)) +>a : Symbol(a, Decl(file4.ts, 4, 3)) + +b = b2; +>b : Symbol(b, Decl(file4.ts, 5, 3)) +>b2 : Symbol(b2, Decl(file4.ts, 7, 3)) + +b2 = b; +>b2 : Symbol(b2, Decl(file4.ts, 7, 3)) +>b : Symbol(b, Decl(file4.ts, 5, 3)) + +a = b2; +>a : Symbol(a, Decl(file4.ts, 4, 3)) +>b2 : Symbol(b2, Decl(file4.ts, 7, 3)) + +b2 = a; +>b2 : Symbol(b2, Decl(file4.ts, 7, 3)) +>a : Symbol(a, Decl(file4.ts, 4, 3)) + +b = a2; +>b : Symbol(b, Decl(file4.ts, 5, 3)) +>a2 : Symbol(a2, Decl(file4.ts, 6, 3)) + +a2 = b; +>a2 : Symbol(a2, Decl(file4.ts, 6, 3)) +>b : Symbol(b, Decl(file4.ts, 5, 3)) + diff --git a/tests/baselines/reference/strictNullChecksPragma2.types b/tests/baselines/reference/strictNullChecksPragma2.types new file mode 100644 index 0000000000000..d2fa7821a1a1c --- /dev/null +++ b/tests/baselines/reference/strictNullChecksPragma2.types @@ -0,0 +1,380 @@ +=== tests/cases/conformance/pragma/strictNullChecks/file1.ts === +export interface A { + member: string; +>member : string +} +export interface B { + member: string | undefined; +>member : string | undefined +} + +let a: A = { member: undefined }; +>a : A +>{ member: undefined } : { member: undefined; } +>member : undefined +>undefined : undefined + +declare var b: B; +>b : B + +a = b; +>a = b : B +>a : A +>b : B + +b = a; +>b = a : A +>b : B +>a : A + +import {A as OtherA, B as OtherB} from "./file2"; +>A : any +>OtherA : any +>B : any +>OtherB : any + +let a2: OtherA = { member: undefined }; +>a2 : OtherA +>{ member: undefined } : { member: undefined; } +>member : undefined +>undefined : undefined + +declare var b2: OtherB; +>b2 : OtherB + +a2 = b2; +>a2 = b2 : OtherB +>a2 : OtherA +>b2 : OtherB + +b2 = a2; +>b2 = a2 : OtherA +>b2 : OtherB +>a2 : OtherA + +a = a2; +>a = a2 : OtherA +>a : A +>a2 : OtherA + +a2 = a; +>a2 = a : A +>a2 : OtherA +>a : A + +b = b2; +>b = b2 : OtherB +>b : B +>b2 : OtherB + +b2 = b; +>b2 = b : B +>b2 : OtherB +>b : B + +a = b2; +>a = b2 : OtherB +>a : A +>b2 : OtherB + +b2 = a; +>b2 = a : A +>b2 : OtherB +>a : A + +b = a2; +>b = a2 : OtherA +>b : B +>a2 : OtherA + +a2 = b; +>a2 = b : B +>a2 : OtherA +>b : B + +=== tests/cases/conformance/pragma/strictNullChecks/file2.ts === +// @ts-strictNullChecks false +export interface A { + member: string; +>member : string +} +export interface B { + member: string | undefined; +>member : string +} + +let a: A = { member: undefined }; +>a : A +>{ member: undefined } : { member: undefined; } +>member : undefined +>undefined : undefined + +declare var b: B; +>b : B + +a = b; +>a = b : B +>a : A +>b : B + +b = a; +>b = a : A +>b : B +>a : A + +import {A as OtherA, B as OtherB} from "./file1"; +>A : any +>OtherA : any +>B : any +>OtherB : any + +let a2: OtherA = { member: undefined }; +>a2 : OtherA +>{ member: undefined } : { member: undefined; } +>member : undefined +>undefined : undefined + +declare var b2: OtherB; +>b2 : OtherB + +a2 = b2; +>a2 = b2 : OtherB +>a2 : OtherA +>b2 : OtherB + +b2 = a2; +>b2 = a2 : OtherA +>b2 : OtherB +>a2 : OtherA + +a = a2; +>a = a2 : OtherA +>a : A +>a2 : OtherA + +a2 = a; +>a2 = a : A +>a2 : OtherA +>a : A + +b = b2; +>b = b2 : OtherB +>b : B +>b2 : OtherB + +b2 = b; +>b2 = b : B +>b2 : OtherB +>b : B + +a = b2; +>a = b2 : OtherB +>a : A +>b2 : OtherB + +b2 = a; +>b2 = a : A +>b2 : OtherB +>a : A + +b = a2; +>b = a2 : OtherA +>b : B +>a2 : OtherA + +a2 = b; +>a2 = b : B +>a2 : OtherA +>b : B + +=== tests/cases/conformance/pragma/strictNullChecks/file3.ts === +import {A, B} from "./file1"; +>A : any +>B : any + +import {A as A2, B as B2} from "./file2"; +>A : any +>A2 : any +>B : any +>B2 : any + +let a: A = { member: undefined }; +>a : A +>{ member: undefined } : { member: undefined; } +>member : undefined +>undefined : undefined + +let b: B = { member: undefined }; +>b : B +>{ member: undefined } : { member: undefined; } +>member : undefined +>undefined : undefined + +let a2: A2 = { member: undefined }; +>a2 : A2 +>{ member: undefined } : { member: undefined; } +>member : undefined +>undefined : undefined + +let b2: B2 = { member: undefined }; +>b2 : B2 +>{ member: undefined } : { member: undefined; } +>member : undefined +>undefined : undefined + +a = b; +>a = b : B +>a : A +>b : B + +b = a; +>b = a : A +>b : B +>a : A + +a2 = b2; +>a2 = b2 : B2 +>a2 : A2 +>b2 : B2 + +b2 = a2; +>b2 = a2 : A2 +>b2 : B2 +>a2 : A2 + +a = a2; +>a = a2 : A2 +>a : A +>a2 : A2 + +a2 = a; +>a2 = a : A +>a2 : A2 +>a : A + +b = b2; +>b = b2 : B2 +>b : B +>b2 : B2 + +b2 = b; +>b2 = b : B +>b2 : B2 +>b : B + +a = b2; +>a = b2 : B2 +>a : A +>b2 : B2 + +b2 = a; +>b2 = a : A +>b2 : B2 +>a : A + +b = a2; +>b = a2 : A2 +>b : B +>a2 : A2 + +a2 = b; +>a2 = b : B +>a2 : A2 +>b : B + +=== tests/cases/conformance/pragma/strictNullChecks/file4.ts === +// @ts-strictNullChecks false +import {A, B} from "./file1"; +>A : any +>B : any + +import {A as A2, B as B2} from "./file2"; +>A : any +>A2 : any +>B : any +>B2 : any + +let a: A = { member: undefined }; +>a : A +>{ member: undefined } : { member: undefined; } +>member : undefined +>undefined : undefined + +let b: B = { member: undefined }; +>b : B +>{ member: undefined } : { member: undefined; } +>member : undefined +>undefined : undefined + +let a2: A2 = { member: undefined }; +>a2 : A2 +>{ member: undefined } : { member: undefined; } +>member : undefined +>undefined : undefined + +let b2: B2 = { member: undefined }; +>b2 : B2 +>{ member: undefined } : { member: undefined; } +>member : undefined +>undefined : undefined + +a = b; +>a = b : B +>a : A +>b : B + +b = a; +>b = a : A +>b : B +>a : A + +a2 = b2; +>a2 = b2 : B2 +>a2 : A2 +>b2 : B2 + +b2 = a2; +>b2 = a2 : A2 +>b2 : B2 +>a2 : A2 + +a = a2; +>a = a2 : A2 +>a : A +>a2 : A2 + +a2 = a; +>a2 = a : A +>a2 : A2 +>a : A + +b = b2; +>b = b2 : B2 +>b : B +>b2 : B2 + +b2 = b; +>b2 = b : B +>b2 : B2 +>b : B + +a = b2; +>a = b2 : B2 +>a : A +>b2 : B2 + +b2 = a; +>b2 = a : A +>b2 : B2 +>a : A + +b = a2; +>b = a2 : A2 +>b : B +>a2 : A2 + +a2 = b; +>a2 = b : B +>a2 : A2 +>b : B + diff --git a/tests/baselines/reference/strictNullChecksPragma3.errors.txt b/tests/baselines/reference/strictNullChecksPragma3.errors.txt new file mode 100644 index 0000000000000..00d2b880bb977 --- /dev/null +++ b/tests/baselines/reference/strictNullChecksPragma3.errors.txt @@ -0,0 +1,235 @@ +tests/cases/conformance/pragma/strictNullChecks/file1.ts(9,14): error TS2322: Type 'undefined' is not assignable to type 'number'. +tests/cases/conformance/pragma/strictNullChecks/file1.ts(11,1): error TS2322: Type 'B' is not assignable to type 'A'. +tests/cases/conformance/pragma/strictNullChecks/file1.ts(12,1): error TS2322: Type 'A' is not assignable to type 'B'. +tests/cases/conformance/pragma/strictNullChecks/file1.ts(16,20): error TS2322: Type 'undefined' is not assignable to type 'number'. +tests/cases/conformance/pragma/strictNullChecks/file1.ts(19,1): error TS2322: Type 'A' is not assignable to type 'B'. +tests/cases/conformance/pragma/strictNullChecks/file1.ts(28,1): error TS2322: Type 'A' is not assignable to type 'B'. +tests/cases/conformance/pragma/strictNullChecks/file1.ts(30,1): error TS2322: Type 'A' is not assignable to type 'B'. +tests/cases/conformance/pragma/strictNullChecks/file1.ts(31,1): error TS2322: Type 'B' is not assignable to type 'A'. +tests/cases/conformance/pragma/strictNullChecks/file2.ts(12,1): error TS2322: Type 'A' is not assignable to type 'B'. + Types of property 'member' are incompatible. + Type 'number' is not assignable to type 'undefined'. +tests/cases/conformance/pragma/strictNullChecks/file2.ts(18,1): error TS2322: Type 'B' is not assignable to type 'A'. + Types of property 'member' are incompatible. + Type 'undefined' is not assignable to type 'number'. +tests/cases/conformance/pragma/strictNullChecks/file2.ts(19,1): error TS2322: Type 'A' is not assignable to type 'B'. + Types of property 'member' are incompatible. + Type 'number' is not assignable to type 'undefined'. +tests/cases/conformance/pragma/strictNullChecks/file2.ts(27,1): error TS2322: Type 'B' is not assignable to type 'A'. + Types of property 'member' are incompatible. + Type 'undefined' is not assignable to type 'number'. +tests/cases/conformance/pragma/strictNullChecks/file2.ts(28,1): error TS2322: Type 'A' is not assignable to type 'B'. + Types of property 'member' are incompatible. + Type 'number' is not assignable to type 'undefined'. +tests/cases/conformance/pragma/strictNullChecks/file2.ts(30,1): error TS2322: Type 'A' is not assignable to type 'B'. + Types of property 'member' are incompatible. + Type 'number' is not assignable to type 'undefined'. +tests/cases/conformance/pragma/strictNullChecks/file3.ts(5,14): error TS2322: Type 'undefined' is not assignable to type 'number'. +tests/cases/conformance/pragma/strictNullChecks/file3.ts(7,16): error TS2322: Type 'undefined' is not assignable to type 'number'. +tests/cases/conformance/pragma/strictNullChecks/file3.ts(10,1): error TS2322: Type 'B' is not assignable to type 'A'. +tests/cases/conformance/pragma/strictNullChecks/file3.ts(11,1): error TS2322: Type 'A' is not assignable to type 'B'. +tests/cases/conformance/pragma/strictNullChecks/file3.ts(14,1): error TS2322: Type 'A' is not assignable to type 'B'. +tests/cases/conformance/pragma/strictNullChecks/file3.ts(23,1): error TS2322: Type 'A' is not assignable to type 'B'. +tests/cases/conformance/pragma/strictNullChecks/file3.ts(25,1): error TS2322: Type 'A' is not assignable to type 'B'. +tests/cases/conformance/pragma/strictNullChecks/file3.ts(26,1): error TS2322: Type 'B' is not assignable to type 'A'. +tests/cases/conformance/pragma/strictNullChecks/file4.ts(10,1): error TS2322: Type 'B' is not assignable to type 'A'. +tests/cases/conformance/pragma/strictNullChecks/file4.ts(11,1): error TS2322: Type 'A' is not assignable to type 'B'. +tests/cases/conformance/pragma/strictNullChecks/file4.ts(14,1): error TS2322: Type 'A' is not assignable to type 'B'. +tests/cases/conformance/pragma/strictNullChecks/file4.ts(23,1): error TS2322: Type 'A' is not assignable to type 'B'. +tests/cases/conformance/pragma/strictNullChecks/file4.ts(25,1): error TS2322: Type 'A' is not assignable to type 'B'. +tests/cases/conformance/pragma/strictNullChecks/file4.ts(26,1): error TS2322: Type 'B' is not assignable to type 'A'. + + +==== tests/cases/conformance/pragma/strictNullChecks/file1.ts (8 errors) ==== + // @ts-strictNullChecks + export interface A { + member: number; + } + export interface B { + member: undefined; + } + + let a: A = { member: undefined }; + ~~~~~~ +!!! error TS2322: Type 'undefined' is not assignable to type 'number'. +!!! related TS6500 tests/cases/conformance/pragma/strictNullChecks/file1.ts:3:5: The expected type comes from property 'member' which is declared here on type 'A' + let b: B = { member: undefined }; + a = b; + ~ +!!! error TS2322: Type 'B' is not assignable to type 'A'. + b = a; + ~ +!!! error TS2322: Type 'A' is not assignable to type 'B'. + + import {A as OtherA, B as OtherB} from "./file2"; + + let a2: OtherA = { member: undefined }; + ~~~~~~ +!!! error TS2322: Type 'undefined' is not assignable to type 'number'. +!!! related TS6500 /.src/tests/cases/conformance/pragma/strictNullChecks/file2.ts:3:5: The expected type comes from property 'member' which is declared here on type 'A' + declare var b2: OtherB; + a2 = b2; + b2 = a2; + ~~ +!!! error TS2322: Type 'A' is not assignable to type 'B'. + + a = a2; + a2 = a; + + b = b2; + b2 = b; + + a = b2; + b2 = a; + ~~ +!!! error TS2322: Type 'A' is not assignable to type 'B'. + + b = a2; + ~ +!!! error TS2322: Type 'A' is not assignable to type 'B'. + a2 = b; + ~~ +!!! error TS2322: Type 'B' is not assignable to type 'A'. + +==== tests/cases/conformance/pragma/strictNullChecks/file2.ts (6 errors) ==== + // loose + export interface A { + member: number; + } + export interface B { + member: undefined; + } + + let a: A = { member: undefined }; + let b: B = { member: undefined }; + a = b; + b = a; // Historic behavior is that most things aren't assignable to `undefined` when it doesn't evaporate, even outside `strict` mode - making it more like a special `never` than an `any`. + ~ +!!! error TS2322: Type 'A' is not assignable to type 'B'. +!!! error TS2322: Types of property 'member' are incompatible. +!!! error TS2322: Type 'number' is not assignable to type 'undefined'. + + import {A as OtherA, B as OtherB} from "./file1"; + + let a2: OtherA = { member: undefined }; + declare var b2: OtherB; + a2 = b2; + ~~ +!!! error TS2322: Type 'B' is not assignable to type 'A'. +!!! error TS2322: Types of property 'member' are incompatible. +!!! error TS2322: Type 'undefined' is not assignable to type 'number'. + b2 = a2; + ~~ +!!! error TS2322: Type 'A' is not assignable to type 'B'. +!!! error TS2322: Types of property 'member' are incompatible. +!!! error TS2322: Type 'number' is not assignable to type 'undefined'. + + a = a2; + a2 = a; + + b = b2; + b2 = b; + + a = b2; + ~ +!!! error TS2322: Type 'B' is not assignable to type 'A'. +!!! error TS2322: Types of property 'member' are incompatible. +!!! error TS2322: Type 'undefined' is not assignable to type 'number'. + b2 = a; + ~~ +!!! error TS2322: Type 'A' is not assignable to type 'B'. +!!! error TS2322: Types of property 'member' are incompatible. +!!! error TS2322: Type 'number' is not assignable to type 'undefined'. + + b = a2; + ~ +!!! error TS2322: Type 'A' is not assignable to type 'B'. +!!! error TS2322: Types of property 'member' are incompatible. +!!! error TS2322: Type 'number' is not assignable to type 'undefined'. + a2 = b; + +==== tests/cases/conformance/pragma/strictNullChecks/file3.ts (8 errors) ==== + // @ts-strictNullChecks + import {A, B} from "./file1"; + import {A as A2, B as B2} from "./file2"; + + let a: A = { member: undefined }; + ~~~~~~ +!!! error TS2322: Type 'undefined' is not assignable to type 'number'. +!!! related TS6500 tests/cases/conformance/pragma/strictNullChecks/file1.ts:3:5: The expected type comes from property 'member' which is declared here on type 'A' + let b: B = { member: undefined }; + let a2: A2 = { member: undefined }; + ~~~~~~ +!!! error TS2322: Type 'undefined' is not assignable to type 'number'. +!!! related TS6500 /.src/tests/cases/conformance/pragma/strictNullChecks/file2.ts:3:5: The expected type comes from property 'member' which is declared here on type 'A' + let b2: B2 = { member: undefined }; + + a = b; + ~ +!!! error TS2322: Type 'B' is not assignable to type 'A'. + b = a; + ~ +!!! error TS2322: Type 'A' is not assignable to type 'B'. + + a2 = b2; + b2 = a2; + ~~ +!!! error TS2322: Type 'A' is not assignable to type 'B'. + + a = a2; + a2 = a; + + b = b2; + b2 = b; + + a = b2; + b2 = a; + ~~ +!!! error TS2322: Type 'A' is not assignable to type 'B'. + + b = a2; + ~ +!!! error TS2322: Type 'A' is not assignable to type 'B'. + a2 = b; + ~~ +!!! error TS2322: Type 'B' is not assignable to type 'A'. + +==== tests/cases/conformance/pragma/strictNullChecks/file4.ts (6 errors) ==== + // loose + import {A, B} from "./file1"; + import {A as A2, B as B2} from "./file2"; + + let a: A = { member: undefined }; + let b: B = { member: undefined }; + let a2: A2 = { member: undefined }; + let b2: B2 = { member: undefined }; + + a = b; + ~ +!!! error TS2322: Type 'B' is not assignable to type 'A'. + b = a; + ~ +!!! error TS2322: Type 'A' is not assignable to type 'B'. + + a2 = b2; + b2 = a2; + ~~ +!!! error TS2322: Type 'A' is not assignable to type 'B'. + + a = a2; + a2 = a; + + b = b2; + b2 = b; + + a = b2; + b2 = a; + ~~ +!!! error TS2322: Type 'A' is not assignable to type 'B'. + + b = a2; + ~ +!!! error TS2322: Type 'A' is not assignable to type 'B'. + a2 = b; + ~~ +!!! error TS2322: Type 'B' is not assignable to type 'A'. \ No newline at end of file diff --git a/tests/baselines/reference/strictNullChecksPragma3.js b/tests/baselines/reference/strictNullChecksPragma3.js new file mode 100644 index 0000000000000..704c3cc5fa806 --- /dev/null +++ b/tests/baselines/reference/strictNullChecksPragma3.js @@ -0,0 +1,198 @@ +//// [tests/cases/conformance/pragma/strictNullChecks/strictNullChecksPragma3.ts] //// + +//// [file1.ts] +// @ts-strictNullChecks +export interface A { + member: number; +} +export interface B { + member: undefined; +} + +let a: A = { member: undefined }; +let b: B = { member: undefined }; +a = b; +b = a; + +import {A as OtherA, B as OtherB} from "./file2"; + +let a2: OtherA = { member: undefined }; +declare var b2: OtherB; +a2 = b2; +b2 = a2; + +a = a2; +a2 = a; + +b = b2; +b2 = b; + +a = b2; +b2 = a; + +b = a2; +a2 = b; + +//// [file2.ts] +// loose +export interface A { + member: number; +} +export interface B { + member: undefined; +} + +let a: A = { member: undefined }; +let b: B = { member: undefined }; +a = b; +b = a; // Historic behavior is that most things aren't assignable to `undefined` when it doesn't evaporate, even outside `strict` mode - making it more like a special `never` than an `any`. + +import {A as OtherA, B as OtherB} from "./file1"; + +let a2: OtherA = { member: undefined }; +declare var b2: OtherB; +a2 = b2; +b2 = a2; + +a = a2; +a2 = a; + +b = b2; +b2 = b; + +a = b2; +b2 = a; + +b = a2; +a2 = b; + +//// [file3.ts] +// @ts-strictNullChecks +import {A, B} from "./file1"; +import {A as A2, B as B2} from "./file2"; + +let a: A = { member: undefined }; +let b: B = { member: undefined }; +let a2: A2 = { member: undefined }; +let b2: B2 = { member: undefined }; + +a = b; +b = a; + +a2 = b2; +b2 = a2; + +a = a2; +a2 = a; + +b = b2; +b2 = b; + +a = b2; +b2 = a; + +b = a2; +a2 = b; + +//// [file4.ts] +// loose +import {A, B} from "./file1"; +import {A as A2, B as B2} from "./file2"; + +let a: A = { member: undefined }; +let b: B = { member: undefined }; +let a2: A2 = { member: undefined }; +let b2: B2 = { member: undefined }; + +a = b; +b = a; + +a2 = b2; +b2 = a2; + +a = a2; +a2 = a; + +b = b2; +b2 = b; + +a = b2; +b2 = a; + +b = a2; +a2 = b; + +//// [file2.js] +"use strict"; +exports.__esModule = true; +var a = { member: undefined }; +var b = { member: undefined }; +a = b; +b = a; // Historic behavior is that most things aren't assignable to `undefined` when it doesn't evaporate, even outside `strict` mode - making it more like a special `never` than an `any`. +var a2 = { member: undefined }; +a2 = b2; +b2 = a2; +a = a2; +a2 = a; +b = b2; +b2 = b; +a = b2; +b2 = a; +b = a2; +a2 = b; +//// [file1.js] +"use strict"; +exports.__esModule = true; +var a = { member: undefined }; +var b = { member: undefined }; +a = b; +b = a; +var a2 = { member: undefined }; +a2 = b2; +b2 = a2; +a = a2; +a2 = a; +b = b2; +b2 = b; +a = b2; +b2 = a; +b = a2; +a2 = b; +//// [file3.js] +"use strict"; +exports.__esModule = true; +var a = { member: undefined }; +var b = { member: undefined }; +var a2 = { member: undefined }; +var b2 = { member: undefined }; +a = b; +b = a; +a2 = b2; +b2 = a2; +a = a2; +a2 = a; +b = b2; +b2 = b; +a = b2; +b2 = a; +b = a2; +a2 = b; +//// [file4.js] +"use strict"; +exports.__esModule = true; +var a = { member: undefined }; +var b = { member: undefined }; +var a2 = { member: undefined }; +var b2 = { member: undefined }; +a = b; +b = a; +a2 = b2; +b2 = a2; +a = a2; +a2 = a; +b = b2; +b2 = b; +a = b2; +b2 = a; +b = a2; +a2 = b; diff --git a/tests/baselines/reference/strictNullChecksPragma3.symbols b/tests/baselines/reference/strictNullChecksPragma3.symbols new file mode 100644 index 0000000000000..e6b9a8cefce35 --- /dev/null +++ b/tests/baselines/reference/strictNullChecksPragma3.symbols @@ -0,0 +1,350 @@ +=== tests/cases/conformance/pragma/strictNullChecks/file1.ts === +// @ts-strictNullChecks +export interface A { +>A : Symbol(A, Decl(file1.ts, 0, 0)) + + member: number; +>member : Symbol(A.member, Decl(file1.ts, 1, 20)) +} +export interface B { +>B : Symbol(B, Decl(file1.ts, 3, 1)) + + member: undefined; +>member : Symbol(B.member, Decl(file1.ts, 4, 20)) +} + +let a: A = { member: undefined }; +>a : Symbol(a, Decl(file1.ts, 8, 3)) +>A : Symbol(A, Decl(file1.ts, 0, 0)) +>member : Symbol(member, Decl(file1.ts, 8, 12)) +>undefined : Symbol(undefined) + +let b: B = { member: undefined }; +>b : Symbol(b, Decl(file1.ts, 9, 3)) +>B : Symbol(B, Decl(file1.ts, 3, 1)) +>member : Symbol(member, Decl(file1.ts, 9, 12)) +>undefined : Symbol(undefined) + +a = b; +>a : Symbol(a, Decl(file1.ts, 8, 3)) +>b : Symbol(b, Decl(file1.ts, 9, 3)) + +b = a; +>b : Symbol(b, Decl(file1.ts, 9, 3)) +>a : Symbol(a, Decl(file1.ts, 8, 3)) + +import {A as OtherA, B as OtherB} from "./file2"; +>A : Symbol(OtherA, Decl(file2.ts, 0, 0)) +>OtherA : Symbol(OtherA, Decl(file1.ts, 13, 8)) +>B : Symbol(OtherB, Decl(file2.ts, 3, 1)) +>OtherB : Symbol(OtherB, Decl(file1.ts, 13, 20)) + +let a2: OtherA = { member: undefined }; +>a2 : Symbol(a2, Decl(file1.ts, 15, 3)) +>OtherA : Symbol(OtherA, Decl(file1.ts, 13, 8)) +>member : Symbol(member, Decl(file1.ts, 15, 18)) +>undefined : Symbol(undefined) + +declare var b2: OtherB; +>b2 : Symbol(b2, Decl(file1.ts, 16, 11)) +>OtherB : Symbol(OtherB, Decl(file1.ts, 13, 20)) + +a2 = b2; +>a2 : Symbol(a2, Decl(file1.ts, 15, 3)) +>b2 : Symbol(b2, Decl(file1.ts, 16, 11)) + +b2 = a2; +>b2 : Symbol(b2, Decl(file1.ts, 16, 11)) +>a2 : Symbol(a2, Decl(file1.ts, 15, 3)) + +a = a2; +>a : Symbol(a, Decl(file1.ts, 8, 3)) +>a2 : Symbol(a2, Decl(file1.ts, 15, 3)) + +a2 = a; +>a2 : Symbol(a2, Decl(file1.ts, 15, 3)) +>a : Symbol(a, Decl(file1.ts, 8, 3)) + +b = b2; +>b : Symbol(b, Decl(file1.ts, 9, 3)) +>b2 : Symbol(b2, Decl(file1.ts, 16, 11)) + +b2 = b; +>b2 : Symbol(b2, Decl(file1.ts, 16, 11)) +>b : Symbol(b, Decl(file1.ts, 9, 3)) + +a = b2; +>a : Symbol(a, Decl(file1.ts, 8, 3)) +>b2 : Symbol(b2, Decl(file1.ts, 16, 11)) + +b2 = a; +>b2 : Symbol(b2, Decl(file1.ts, 16, 11)) +>a : Symbol(a, Decl(file1.ts, 8, 3)) + +b = a2; +>b : Symbol(b, Decl(file1.ts, 9, 3)) +>a2 : Symbol(a2, Decl(file1.ts, 15, 3)) + +a2 = b; +>a2 : Symbol(a2, Decl(file1.ts, 15, 3)) +>b : Symbol(b, Decl(file1.ts, 9, 3)) + +=== tests/cases/conformance/pragma/strictNullChecks/file2.ts === +// loose +export interface A { +>A : Symbol(A, Decl(file2.ts, 0, 0)) + + member: number; +>member : Symbol(A.member, Decl(file2.ts, 1, 20)) +} +export interface B { +>B : Symbol(B, Decl(file2.ts, 3, 1)) + + member: undefined; +>member : Symbol(B.member, Decl(file2.ts, 4, 20)) +} + +let a: A = { member: undefined }; +>a : Symbol(a, Decl(file2.ts, 8, 3)) +>A : Symbol(A, Decl(file2.ts, 0, 0)) +>member : Symbol(member, Decl(file2.ts, 8, 12)) +>undefined : Symbol(undefined) + +let b: B = { member: undefined }; +>b : Symbol(b, Decl(file2.ts, 9, 3)) +>B : Symbol(B, Decl(file2.ts, 3, 1)) +>member : Symbol(member, Decl(file2.ts, 9, 12)) +>undefined : Symbol(undefined) + +a = b; +>a : Symbol(a, Decl(file2.ts, 8, 3)) +>b : Symbol(b, Decl(file2.ts, 9, 3)) + +b = a; // Historic behavior is that most things aren't assignable to `undefined` when it doesn't evaporate, even outside `strict` mode - making it more like a special `never` than an `any`. +>b : Symbol(b, Decl(file2.ts, 9, 3)) +>a : Symbol(a, Decl(file2.ts, 8, 3)) + +import {A as OtherA, B as OtherB} from "./file1"; +>A : Symbol(OtherA, Decl(file1.ts, 0, 0)) +>OtherA : Symbol(OtherA, Decl(file2.ts, 13, 8)) +>B : Symbol(OtherB, Decl(file1.ts, 3, 1)) +>OtherB : Symbol(OtherB, Decl(file2.ts, 13, 20)) + +let a2: OtherA = { member: undefined }; +>a2 : Symbol(a2, Decl(file2.ts, 15, 3)) +>OtherA : Symbol(OtherA, Decl(file2.ts, 13, 8)) +>member : Symbol(member, Decl(file2.ts, 15, 18)) +>undefined : Symbol(undefined) + +declare var b2: OtherB; +>b2 : Symbol(b2, Decl(file2.ts, 16, 11)) +>OtherB : Symbol(OtherB, Decl(file2.ts, 13, 20)) + +a2 = b2; +>a2 : Symbol(a2, Decl(file2.ts, 15, 3)) +>b2 : Symbol(b2, Decl(file2.ts, 16, 11)) + +b2 = a2; +>b2 : Symbol(b2, Decl(file2.ts, 16, 11)) +>a2 : Symbol(a2, Decl(file2.ts, 15, 3)) + +a = a2; +>a : Symbol(a, Decl(file2.ts, 8, 3)) +>a2 : Symbol(a2, Decl(file2.ts, 15, 3)) + +a2 = a; +>a2 : Symbol(a2, Decl(file2.ts, 15, 3)) +>a : Symbol(a, Decl(file2.ts, 8, 3)) + +b = b2; +>b : Symbol(b, Decl(file2.ts, 9, 3)) +>b2 : Symbol(b2, Decl(file2.ts, 16, 11)) + +b2 = b; +>b2 : Symbol(b2, Decl(file2.ts, 16, 11)) +>b : Symbol(b, Decl(file2.ts, 9, 3)) + +a = b2; +>a : Symbol(a, Decl(file2.ts, 8, 3)) +>b2 : Symbol(b2, Decl(file2.ts, 16, 11)) + +b2 = a; +>b2 : Symbol(b2, Decl(file2.ts, 16, 11)) +>a : Symbol(a, Decl(file2.ts, 8, 3)) + +b = a2; +>b : Symbol(b, Decl(file2.ts, 9, 3)) +>a2 : Symbol(a2, Decl(file2.ts, 15, 3)) + +a2 = b; +>a2 : Symbol(a2, Decl(file2.ts, 15, 3)) +>b : Symbol(b, Decl(file2.ts, 9, 3)) + +=== tests/cases/conformance/pragma/strictNullChecks/file3.ts === +// @ts-strictNullChecks +import {A, B} from "./file1"; +>A : Symbol(A, Decl(file3.ts, 1, 8)) +>B : Symbol(B, Decl(file3.ts, 1, 10)) + +import {A as A2, B as B2} from "./file2"; +>A : Symbol(A2, Decl(file2.ts, 0, 0)) +>A2 : Symbol(A2, Decl(file3.ts, 2, 8)) +>B : Symbol(B2, Decl(file2.ts, 3, 1)) +>B2 : Symbol(B2, Decl(file3.ts, 2, 16)) + +let a: A = { member: undefined }; +>a : Symbol(a, Decl(file3.ts, 4, 3)) +>A : Symbol(A, Decl(file3.ts, 1, 8)) +>member : Symbol(member, Decl(file3.ts, 4, 12)) +>undefined : Symbol(undefined) + +let b: B = { member: undefined }; +>b : Symbol(b, Decl(file3.ts, 5, 3)) +>B : Symbol(B, Decl(file3.ts, 1, 10)) +>member : Symbol(member, Decl(file3.ts, 5, 12)) +>undefined : Symbol(undefined) + +let a2: A2 = { member: undefined }; +>a2 : Symbol(a2, Decl(file3.ts, 6, 3)) +>A2 : Symbol(A2, Decl(file3.ts, 2, 8)) +>member : Symbol(member, Decl(file3.ts, 6, 14)) +>undefined : Symbol(undefined) + +let b2: B2 = { member: undefined }; +>b2 : Symbol(b2, Decl(file3.ts, 7, 3)) +>B2 : Symbol(B2, Decl(file3.ts, 2, 16)) +>member : Symbol(member, Decl(file3.ts, 7, 14)) +>undefined : Symbol(undefined) + +a = b; +>a : Symbol(a, Decl(file3.ts, 4, 3)) +>b : Symbol(b, Decl(file3.ts, 5, 3)) + +b = a; +>b : Symbol(b, Decl(file3.ts, 5, 3)) +>a : Symbol(a, Decl(file3.ts, 4, 3)) + +a2 = b2; +>a2 : Symbol(a2, Decl(file3.ts, 6, 3)) +>b2 : Symbol(b2, Decl(file3.ts, 7, 3)) + +b2 = a2; +>b2 : Symbol(b2, Decl(file3.ts, 7, 3)) +>a2 : Symbol(a2, Decl(file3.ts, 6, 3)) + +a = a2; +>a : Symbol(a, Decl(file3.ts, 4, 3)) +>a2 : Symbol(a2, Decl(file3.ts, 6, 3)) + +a2 = a; +>a2 : Symbol(a2, Decl(file3.ts, 6, 3)) +>a : Symbol(a, Decl(file3.ts, 4, 3)) + +b = b2; +>b : Symbol(b, Decl(file3.ts, 5, 3)) +>b2 : Symbol(b2, Decl(file3.ts, 7, 3)) + +b2 = b; +>b2 : Symbol(b2, Decl(file3.ts, 7, 3)) +>b : Symbol(b, Decl(file3.ts, 5, 3)) + +a = b2; +>a : Symbol(a, Decl(file3.ts, 4, 3)) +>b2 : Symbol(b2, Decl(file3.ts, 7, 3)) + +b2 = a; +>b2 : Symbol(b2, Decl(file3.ts, 7, 3)) +>a : Symbol(a, Decl(file3.ts, 4, 3)) + +b = a2; +>b : Symbol(b, Decl(file3.ts, 5, 3)) +>a2 : Symbol(a2, Decl(file3.ts, 6, 3)) + +a2 = b; +>a2 : Symbol(a2, Decl(file3.ts, 6, 3)) +>b : Symbol(b, Decl(file3.ts, 5, 3)) + +=== tests/cases/conformance/pragma/strictNullChecks/file4.ts === +// loose +import {A, B} from "./file1"; +>A : Symbol(A, Decl(file4.ts, 1, 8)) +>B : Symbol(B, Decl(file4.ts, 1, 10)) + +import {A as A2, B as B2} from "./file2"; +>A : Symbol(A2, Decl(file2.ts, 0, 0)) +>A2 : Symbol(A2, Decl(file4.ts, 2, 8)) +>B : Symbol(B2, Decl(file2.ts, 3, 1)) +>B2 : Symbol(B2, Decl(file4.ts, 2, 16)) + +let a: A = { member: undefined }; +>a : Symbol(a, Decl(file4.ts, 4, 3)) +>A : Symbol(A, Decl(file4.ts, 1, 8)) +>member : Symbol(member, Decl(file4.ts, 4, 12)) +>undefined : Symbol(undefined) + +let b: B = { member: undefined }; +>b : Symbol(b, Decl(file4.ts, 5, 3)) +>B : Symbol(B, Decl(file4.ts, 1, 10)) +>member : Symbol(member, Decl(file4.ts, 5, 12)) +>undefined : Symbol(undefined) + +let a2: A2 = { member: undefined }; +>a2 : Symbol(a2, Decl(file4.ts, 6, 3)) +>A2 : Symbol(A2, Decl(file4.ts, 2, 8)) +>member : Symbol(member, Decl(file4.ts, 6, 14)) +>undefined : Symbol(undefined) + +let b2: B2 = { member: undefined }; +>b2 : Symbol(b2, Decl(file4.ts, 7, 3)) +>B2 : Symbol(B2, Decl(file4.ts, 2, 16)) +>member : Symbol(member, Decl(file4.ts, 7, 14)) +>undefined : Symbol(undefined) + +a = b; +>a : Symbol(a, Decl(file4.ts, 4, 3)) +>b : Symbol(b, Decl(file4.ts, 5, 3)) + +b = a; +>b : Symbol(b, Decl(file4.ts, 5, 3)) +>a : Symbol(a, Decl(file4.ts, 4, 3)) + +a2 = b2; +>a2 : Symbol(a2, Decl(file4.ts, 6, 3)) +>b2 : Symbol(b2, Decl(file4.ts, 7, 3)) + +b2 = a2; +>b2 : Symbol(b2, Decl(file4.ts, 7, 3)) +>a2 : Symbol(a2, Decl(file4.ts, 6, 3)) + +a = a2; +>a : Symbol(a, Decl(file4.ts, 4, 3)) +>a2 : Symbol(a2, Decl(file4.ts, 6, 3)) + +a2 = a; +>a2 : Symbol(a2, Decl(file4.ts, 6, 3)) +>a : Symbol(a, Decl(file4.ts, 4, 3)) + +b = b2; +>b : Symbol(b, Decl(file4.ts, 5, 3)) +>b2 : Symbol(b2, Decl(file4.ts, 7, 3)) + +b2 = b; +>b2 : Symbol(b2, Decl(file4.ts, 7, 3)) +>b : Symbol(b, Decl(file4.ts, 5, 3)) + +a = b2; +>a : Symbol(a, Decl(file4.ts, 4, 3)) +>b2 : Symbol(b2, Decl(file4.ts, 7, 3)) + +b2 = a; +>b2 : Symbol(b2, Decl(file4.ts, 7, 3)) +>a : Symbol(a, Decl(file4.ts, 4, 3)) + +b = a2; +>b : Symbol(b, Decl(file4.ts, 5, 3)) +>a2 : Symbol(a2, Decl(file4.ts, 6, 3)) + +a2 = b; +>a2 : Symbol(a2, Decl(file4.ts, 6, 3)) +>b : Symbol(b, Decl(file4.ts, 5, 3)) + diff --git a/tests/baselines/reference/strictNullChecksPragma3.types b/tests/baselines/reference/strictNullChecksPragma3.types new file mode 100644 index 0000000000000..6fae0363f85f2 --- /dev/null +++ b/tests/baselines/reference/strictNullChecksPragma3.types @@ -0,0 +1,388 @@ +=== tests/cases/conformance/pragma/strictNullChecks/file1.ts === +// @ts-strictNullChecks +export interface A { + member: number; +>member : number +} +export interface B { + member: undefined; +>member : undefined +} + +let a: A = { member: undefined }; +>a : A +>{ member: undefined } : { member: undefined; } +>member : undefined +>undefined : undefined + +let b: B = { member: undefined }; +>b : B +>{ member: undefined } : { member: undefined; } +>member : undefined +>undefined : undefined + +a = b; +>a = b : B +>a : A +>b : B + +b = a; +>b = a : A +>b : B +>a : A + +import {A as OtherA, B as OtherB} from "./file2"; +>A : any +>OtherA : any +>B : any +>OtherB : any + +let a2: OtherA = { member: undefined }; +>a2 : OtherA +>{ member: undefined } : { member: undefined; } +>member : undefined +>undefined : undefined + +declare var b2: OtherB; +>b2 : OtherB + +a2 = b2; +>a2 = b2 : OtherB +>a2 : OtherA +>b2 : OtherB + +b2 = a2; +>b2 = a2 : OtherA +>b2 : OtherB +>a2 : OtherA + +a = a2; +>a = a2 : OtherA +>a : A +>a2 : OtherA + +a2 = a; +>a2 = a : A +>a2 : OtherA +>a : A + +b = b2; +>b = b2 : OtherB +>b : B +>b2 : OtherB + +b2 = b; +>b2 = b : B +>b2 : OtherB +>b : B + +a = b2; +>a = b2 : OtherB +>a : A +>b2 : OtherB + +b2 = a; +>b2 = a : A +>b2 : OtherB +>a : A + +b = a2; +>b = a2 : OtherA +>b : B +>a2 : OtherA + +a2 = b; +>a2 = b : B +>a2 : OtherA +>b : B + +=== tests/cases/conformance/pragma/strictNullChecks/file2.ts === +// loose +export interface A { + member: number; +>member : number +} +export interface B { + member: undefined; +>member : undefined +} + +let a: A = { member: undefined }; +>a : A +>{ member: undefined } : { member: undefined; } +>member : undefined +>undefined : undefined + +let b: B = { member: undefined }; +>b : B +>{ member: undefined } : { member: undefined; } +>member : undefined +>undefined : undefined + +a = b; +>a = b : B +>a : A +>b : B + +b = a; // Historic behavior is that most things aren't assignable to `undefined` when it doesn't evaporate, even outside `strict` mode - making it more like a special `never` than an `any`. +>b = a : A +>b : B +>a : A + +import {A as OtherA, B as OtherB} from "./file1"; +>A : any +>OtherA : any +>B : any +>OtherB : any + +let a2: OtherA = { member: undefined }; +>a2 : OtherA +>{ member: undefined } : { member: undefined; } +>member : undefined +>undefined : undefined + +declare var b2: OtherB; +>b2 : OtherB + +a2 = b2; +>a2 = b2 : OtherB +>a2 : OtherA +>b2 : OtherB + +b2 = a2; +>b2 = a2 : OtherA +>b2 : OtherB +>a2 : OtherA + +a = a2; +>a = a2 : OtherA +>a : A +>a2 : OtherA + +a2 = a; +>a2 = a : A +>a2 : OtherA +>a : A + +b = b2; +>b = b2 : OtherB +>b : B +>b2 : OtherB + +b2 = b; +>b2 = b : B +>b2 : OtherB +>b : B + +a = b2; +>a = b2 : OtherB +>a : A +>b2 : OtherB + +b2 = a; +>b2 = a : A +>b2 : OtherB +>a : A + +b = a2; +>b = a2 : OtherA +>b : B +>a2 : OtherA + +a2 = b; +>a2 = b : B +>a2 : OtherA +>b : B + +=== tests/cases/conformance/pragma/strictNullChecks/file3.ts === +// @ts-strictNullChecks +import {A, B} from "./file1"; +>A : any +>B : any + +import {A as A2, B as B2} from "./file2"; +>A : any +>A2 : any +>B : any +>B2 : any + +let a: A = { member: undefined }; +>a : A +>{ member: undefined } : { member: undefined; } +>member : undefined +>undefined : undefined + +let b: B = { member: undefined }; +>b : B +>{ member: undefined } : { member: undefined; } +>member : undefined +>undefined : undefined + +let a2: A2 = { member: undefined }; +>a2 : A2 +>{ member: undefined } : { member: undefined; } +>member : undefined +>undefined : undefined + +let b2: B2 = { member: undefined }; +>b2 : B2 +>{ member: undefined } : { member: undefined; } +>member : undefined +>undefined : undefined + +a = b; +>a = b : B +>a : A +>b : B + +b = a; +>b = a : A +>b : B +>a : A + +a2 = b2; +>a2 = b2 : B2 +>a2 : A2 +>b2 : B2 + +b2 = a2; +>b2 = a2 : A2 +>b2 : B2 +>a2 : A2 + +a = a2; +>a = a2 : A2 +>a : A +>a2 : A2 + +a2 = a; +>a2 = a : A +>a2 : A2 +>a : A + +b = b2; +>b = b2 : B2 +>b : B +>b2 : B2 + +b2 = b; +>b2 = b : B +>b2 : B2 +>b : B + +a = b2; +>a = b2 : B2 +>a : A +>b2 : B2 + +b2 = a; +>b2 = a : A +>b2 : B2 +>a : A + +b = a2; +>b = a2 : A2 +>b : B +>a2 : A2 + +a2 = b; +>a2 = b : B +>a2 : A2 +>b : B + +=== tests/cases/conformance/pragma/strictNullChecks/file4.ts === +// loose +import {A, B} from "./file1"; +>A : any +>B : any + +import {A as A2, B as B2} from "./file2"; +>A : any +>A2 : any +>B : any +>B2 : any + +let a: A = { member: undefined }; +>a : A +>{ member: undefined } : { member: undefined; } +>member : undefined +>undefined : undefined + +let b: B = { member: undefined }; +>b : B +>{ member: undefined } : { member: undefined; } +>member : undefined +>undefined : undefined + +let a2: A2 = { member: undefined }; +>a2 : A2 +>{ member: undefined } : { member: undefined; } +>member : undefined +>undefined : undefined + +let b2: B2 = { member: undefined }; +>b2 : B2 +>{ member: undefined } : { member: undefined; } +>member : undefined +>undefined : undefined + +a = b; +>a = b : B +>a : A +>b : B + +b = a; +>b = a : A +>b : B +>a : A + +a2 = b2; +>a2 = b2 : B2 +>a2 : A2 +>b2 : B2 + +b2 = a2; +>b2 = a2 : A2 +>b2 : B2 +>a2 : A2 + +a = a2; +>a = a2 : A2 +>a : A +>a2 : A2 + +a2 = a; +>a2 = a : A +>a2 : A2 +>a : A + +b = b2; +>b = b2 : B2 +>b : B +>b2 : B2 + +b2 = b; +>b2 = b : B +>b2 : B2 +>b : B + +a = b2; +>a = b2 : B2 +>a : A +>b2 : B2 + +b2 = a; +>b2 = a : A +>b2 : B2 +>a : A + +b = a2; +>b = a2 : A2 +>b : B +>a2 : A2 + +a2 = b; +>a2 = b : B +>a2 : A2 +>b : B + diff --git a/tests/baselines/reference/strictNullChecksPragma4.errors.txt b/tests/baselines/reference/strictNullChecksPragma4.errors.txt new file mode 100644 index 0000000000000..b9ba10ac52325 --- /dev/null +++ b/tests/baselines/reference/strictNullChecksPragma4.errors.txt @@ -0,0 +1,233 @@ +tests/cases/conformance/pragma/strictNullChecks/file1.ts(8,14): error TS2322: Type 'undefined' is not assignable to type 'number'. +tests/cases/conformance/pragma/strictNullChecks/file1.ts(10,1): error TS2322: Type 'B' is not assignable to type 'A'. +tests/cases/conformance/pragma/strictNullChecks/file1.ts(11,1): error TS2322: Type 'A' is not assignable to type 'B'. +tests/cases/conformance/pragma/strictNullChecks/file1.ts(15,20): error TS2322: Type 'undefined' is not assignable to type 'number'. +tests/cases/conformance/pragma/strictNullChecks/file1.ts(18,1): error TS2322: Type 'A' is not assignable to type 'B'. +tests/cases/conformance/pragma/strictNullChecks/file1.ts(27,1): error TS2322: Type 'A' is not assignable to type 'B'. +tests/cases/conformance/pragma/strictNullChecks/file1.ts(29,1): error TS2322: Type 'A' is not assignable to type 'B'. +tests/cases/conformance/pragma/strictNullChecks/file1.ts(30,1): error TS2322: Type 'B' is not assignable to type 'A'. +tests/cases/conformance/pragma/strictNullChecks/file2.ts(12,1): error TS2322: Type 'A' is not assignable to type 'B'. + Types of property 'member' are incompatible. + Type 'number' is not assignable to type 'undefined'. +tests/cases/conformance/pragma/strictNullChecks/file2.ts(18,1): error TS2322: Type 'B' is not assignable to type 'A'. + Types of property 'member' are incompatible. + Type 'undefined' is not assignable to type 'number'. +tests/cases/conformance/pragma/strictNullChecks/file2.ts(19,1): error TS2322: Type 'A' is not assignable to type 'B'. + Types of property 'member' are incompatible. + Type 'number' is not assignable to type 'undefined'. +tests/cases/conformance/pragma/strictNullChecks/file2.ts(27,1): error TS2322: Type 'B' is not assignable to type 'A'. + Types of property 'member' are incompatible. + Type 'undefined' is not assignable to type 'number'. +tests/cases/conformance/pragma/strictNullChecks/file2.ts(28,1): error TS2322: Type 'A' is not assignable to type 'B'. + Types of property 'member' are incompatible. + Type 'number' is not assignable to type 'undefined'. +tests/cases/conformance/pragma/strictNullChecks/file2.ts(30,1): error TS2322: Type 'A' is not assignable to type 'B'. + Types of property 'member' are incompatible. + Type 'number' is not assignable to type 'undefined'. +tests/cases/conformance/pragma/strictNullChecks/file3.ts(4,14): error TS2322: Type 'undefined' is not assignable to type 'number'. +tests/cases/conformance/pragma/strictNullChecks/file3.ts(6,16): error TS2322: Type 'undefined' is not assignable to type 'number'. +tests/cases/conformance/pragma/strictNullChecks/file3.ts(9,1): error TS2322: Type 'B' is not assignable to type 'A'. +tests/cases/conformance/pragma/strictNullChecks/file3.ts(10,1): error TS2322: Type 'A' is not assignable to type 'B'. +tests/cases/conformance/pragma/strictNullChecks/file3.ts(13,1): error TS2322: Type 'A' is not assignable to type 'B'. +tests/cases/conformance/pragma/strictNullChecks/file3.ts(22,1): error TS2322: Type 'A' is not assignable to type 'B'. +tests/cases/conformance/pragma/strictNullChecks/file3.ts(24,1): error TS2322: Type 'A' is not assignable to type 'B'. +tests/cases/conformance/pragma/strictNullChecks/file3.ts(25,1): error TS2322: Type 'B' is not assignable to type 'A'. +tests/cases/conformance/pragma/strictNullChecks/file4.ts(10,1): error TS2322: Type 'B' is not assignable to type 'A'. +tests/cases/conformance/pragma/strictNullChecks/file4.ts(11,1): error TS2322: Type 'A' is not assignable to type 'B'. +tests/cases/conformance/pragma/strictNullChecks/file4.ts(14,1): error TS2322: Type 'A' is not assignable to type 'B'. +tests/cases/conformance/pragma/strictNullChecks/file4.ts(23,1): error TS2322: Type 'A' is not assignable to type 'B'. +tests/cases/conformance/pragma/strictNullChecks/file4.ts(25,1): error TS2322: Type 'A' is not assignable to type 'B'. +tests/cases/conformance/pragma/strictNullChecks/file4.ts(26,1): error TS2322: Type 'B' is not assignable to type 'A'. + + +==== tests/cases/conformance/pragma/strictNullChecks/file1.ts (8 errors) ==== + export interface A { + member: number; + } + export interface B { + member: undefined; + } + + let a: A = { member: undefined }; + ~~~~~~ +!!! error TS2322: Type 'undefined' is not assignable to type 'number'. +!!! related TS6500 tests/cases/conformance/pragma/strictNullChecks/file1.ts:2:5: The expected type comes from property 'member' which is declared here on type 'A' + let b: B = { member: undefined }; + a = b; + ~ +!!! error TS2322: Type 'B' is not assignable to type 'A'. + b = a; + ~ +!!! error TS2322: Type 'A' is not assignable to type 'B'. + + import {A as OtherA, B as OtherB} from "./file2"; + + let a2: OtherA = { member: undefined }; + ~~~~~~ +!!! error TS2322: Type 'undefined' is not assignable to type 'number'. +!!! related TS6500 /.src/tests/cases/conformance/pragma/strictNullChecks/file2.ts:3:5: The expected type comes from property 'member' which is declared here on type 'A' + declare var b2: OtherB; + a2 = b2; + b2 = a2; + ~~ +!!! error TS2322: Type 'A' is not assignable to type 'B'. + + a = a2; + a2 = a; + + b = b2; + b2 = b; + + a = b2; + b2 = a; + ~~ +!!! error TS2322: Type 'A' is not assignable to type 'B'. + + b = a2; + ~ +!!! error TS2322: Type 'A' is not assignable to type 'B'. + a2 = b; + ~~ +!!! error TS2322: Type 'B' is not assignable to type 'A'. + +==== tests/cases/conformance/pragma/strictNullChecks/file2.ts (6 errors) ==== + // @ts-strictNullChecks false + export interface A { + member: number; + } + export interface B { + member: undefined; + } + + let a: A = { member: undefined }; + let b: B = { member: undefined }; + a = b; + b = a; // Historic behavior is that most things aren't assignable to `undefined` when it doesn't evaporate, even outside `strict` mode - making it more like a special `never` than an `any`. + ~ +!!! error TS2322: Type 'A' is not assignable to type 'B'. +!!! error TS2322: Types of property 'member' are incompatible. +!!! error TS2322: Type 'number' is not assignable to type 'undefined'. + + import {A as OtherA, B as OtherB} from "./file1"; + + let a2: OtherA = { member: undefined }; + declare var b2: OtherB; + a2 = b2; + ~~ +!!! error TS2322: Type 'B' is not assignable to type 'A'. +!!! error TS2322: Types of property 'member' are incompatible. +!!! error TS2322: Type 'undefined' is not assignable to type 'number'. + b2 = a2; + ~~ +!!! error TS2322: Type 'A' is not assignable to type 'B'. +!!! error TS2322: Types of property 'member' are incompatible. +!!! error TS2322: Type 'number' is not assignable to type 'undefined'. + + a = a2; + a2 = a; + + b = b2; + b2 = b; + + a = b2; + ~ +!!! error TS2322: Type 'B' is not assignable to type 'A'. +!!! error TS2322: Types of property 'member' are incompatible. +!!! error TS2322: Type 'undefined' is not assignable to type 'number'. + b2 = a; + ~~ +!!! error TS2322: Type 'A' is not assignable to type 'B'. +!!! error TS2322: Types of property 'member' are incompatible. +!!! error TS2322: Type 'number' is not assignable to type 'undefined'. + + b = a2; + ~ +!!! error TS2322: Type 'A' is not assignable to type 'B'. +!!! error TS2322: Types of property 'member' are incompatible. +!!! error TS2322: Type 'number' is not assignable to type 'undefined'. + a2 = b; + +==== tests/cases/conformance/pragma/strictNullChecks/file3.ts (8 errors) ==== + import {A, B} from "./file1"; + import {A as A2, B as B2} from "./file2"; + + let a: A = { member: undefined }; + ~~~~~~ +!!! error TS2322: Type 'undefined' is not assignable to type 'number'. +!!! related TS6500 tests/cases/conformance/pragma/strictNullChecks/file1.ts:2:5: The expected type comes from property 'member' which is declared here on type 'A' + let b: B = { member: undefined }; + let a2: A2 = { member: undefined }; + ~~~~~~ +!!! error TS2322: Type 'undefined' is not assignable to type 'number'. +!!! related TS6500 /.src/tests/cases/conformance/pragma/strictNullChecks/file2.ts:3:5: The expected type comes from property 'member' which is declared here on type 'A' + let b2: B2 = { member: undefined }; + + a = b; + ~ +!!! error TS2322: Type 'B' is not assignable to type 'A'. + b = a; + ~ +!!! error TS2322: Type 'A' is not assignable to type 'B'. + + a2 = b2; + b2 = a2; + ~~ +!!! error TS2322: Type 'A' is not assignable to type 'B'. + + a = a2; + a2 = a; + + b = b2; + b2 = b; + + a = b2; + b2 = a; + ~~ +!!! error TS2322: Type 'A' is not assignable to type 'B'. + + b = a2; + ~ +!!! error TS2322: Type 'A' is not assignable to type 'B'. + a2 = b; + ~~ +!!! error TS2322: Type 'B' is not assignable to type 'A'. + +==== tests/cases/conformance/pragma/strictNullChecks/file4.ts (6 errors) ==== + // @ts-strictNullChecks false + import {A, B} from "./file1"; + import {A as A2, B as B2} from "./file2"; + + let a: A = { member: undefined }; + let b: B = { member: undefined }; + let a2: A2 = { member: undefined }; + let b2: B2 = { member: undefined }; + + a = b; + ~ +!!! error TS2322: Type 'B' is not assignable to type 'A'. + b = a; + ~ +!!! error TS2322: Type 'A' is not assignable to type 'B'. + + a2 = b2; + b2 = a2; + ~~ +!!! error TS2322: Type 'A' is not assignable to type 'B'. + + a = a2; + a2 = a; + + b = b2; + b2 = b; + + a = b2; + b2 = a; + ~~ +!!! error TS2322: Type 'A' is not assignable to type 'B'. + + b = a2; + ~ +!!! error TS2322: Type 'A' is not assignable to type 'B'. + a2 = b; + ~~ +!!! error TS2322: Type 'B' is not assignable to type 'A'. \ No newline at end of file diff --git a/tests/baselines/reference/strictNullChecksPragma4.js b/tests/baselines/reference/strictNullChecksPragma4.js new file mode 100644 index 0000000000000..386b6baebe75c --- /dev/null +++ b/tests/baselines/reference/strictNullChecksPragma4.js @@ -0,0 +1,196 @@ +//// [tests/cases/conformance/pragma/strictNullChecks/strictNullChecksPragma4.ts] //// + +//// [file1.ts] +export interface A { + member: number; +} +export interface B { + member: undefined; +} + +let a: A = { member: undefined }; +let b: B = { member: undefined }; +a = b; +b = a; + +import {A as OtherA, B as OtherB} from "./file2"; + +let a2: OtherA = { member: undefined }; +declare var b2: OtherB; +a2 = b2; +b2 = a2; + +a = a2; +a2 = a; + +b = b2; +b2 = b; + +a = b2; +b2 = a; + +b = a2; +a2 = b; + +//// [file2.ts] +// @ts-strictNullChecks false +export interface A { + member: number; +} +export interface B { + member: undefined; +} + +let a: A = { member: undefined }; +let b: B = { member: undefined }; +a = b; +b = a; // Historic behavior is that most things aren't assignable to `undefined` when it doesn't evaporate, even outside `strict` mode - making it more like a special `never` than an `any`. + +import {A as OtherA, B as OtherB} from "./file1"; + +let a2: OtherA = { member: undefined }; +declare var b2: OtherB; +a2 = b2; +b2 = a2; + +a = a2; +a2 = a; + +b = b2; +b2 = b; + +a = b2; +b2 = a; + +b = a2; +a2 = b; + +//// [file3.ts] +import {A, B} from "./file1"; +import {A as A2, B as B2} from "./file2"; + +let a: A = { member: undefined }; +let b: B = { member: undefined }; +let a2: A2 = { member: undefined }; +let b2: B2 = { member: undefined }; + +a = b; +b = a; + +a2 = b2; +b2 = a2; + +a = a2; +a2 = a; + +b = b2; +b2 = b; + +a = b2; +b2 = a; + +b = a2; +a2 = b; + +//// [file4.ts] +// @ts-strictNullChecks false +import {A, B} from "./file1"; +import {A as A2, B as B2} from "./file2"; + +let a: A = { member: undefined }; +let b: B = { member: undefined }; +let a2: A2 = { member: undefined }; +let b2: B2 = { member: undefined }; + +a = b; +b = a; + +a2 = b2; +b2 = a2; + +a = a2; +a2 = a; + +b = b2; +b2 = b; + +a = b2; +b2 = a; + +b = a2; +a2 = b; + +//// [file2.js] +"use strict"; +exports.__esModule = true; +var a = { member: undefined }; +var b = { member: undefined }; +a = b; +b = a; // Historic behavior is that most things aren't assignable to `undefined` when it doesn't evaporate, even outside `strict` mode - making it more like a special `never` than an `any`. +var a2 = { member: undefined }; +a2 = b2; +b2 = a2; +a = a2; +a2 = a; +b = b2; +b2 = b; +a = b2; +b2 = a; +b = a2; +a2 = b; +//// [file1.js] +"use strict"; +exports.__esModule = true; +var a = { member: undefined }; +var b = { member: undefined }; +a = b; +b = a; +var a2 = { member: undefined }; +a2 = b2; +b2 = a2; +a = a2; +a2 = a; +b = b2; +b2 = b; +a = b2; +b2 = a; +b = a2; +a2 = b; +//// [file3.js] +"use strict"; +exports.__esModule = true; +var a = { member: undefined }; +var b = { member: undefined }; +var a2 = { member: undefined }; +var b2 = { member: undefined }; +a = b; +b = a; +a2 = b2; +b2 = a2; +a = a2; +a2 = a; +b = b2; +b2 = b; +a = b2; +b2 = a; +b = a2; +a2 = b; +//// [file4.js] +"use strict"; +exports.__esModule = true; +var a = { member: undefined }; +var b = { member: undefined }; +var a2 = { member: undefined }; +var b2 = { member: undefined }; +a = b; +b = a; +a2 = b2; +b2 = a2; +a = a2; +a2 = a; +b = b2; +b2 = b; +a = b2; +b2 = a; +b = a2; +a2 = b; diff --git a/tests/baselines/reference/strictNullChecksPragma4.symbols b/tests/baselines/reference/strictNullChecksPragma4.symbols new file mode 100644 index 0000000000000..497527c109735 --- /dev/null +++ b/tests/baselines/reference/strictNullChecksPragma4.symbols @@ -0,0 +1,348 @@ +=== tests/cases/conformance/pragma/strictNullChecks/file1.ts === +export interface A { +>A : Symbol(A, Decl(file1.ts, 0, 0)) + + member: number; +>member : Symbol(A.member, Decl(file1.ts, 0, 20)) +} +export interface B { +>B : Symbol(B, Decl(file1.ts, 2, 1)) + + member: undefined; +>member : Symbol(B.member, Decl(file1.ts, 3, 20)) +} + +let a: A = { member: undefined }; +>a : Symbol(a, Decl(file1.ts, 7, 3)) +>A : Symbol(A, Decl(file1.ts, 0, 0)) +>member : Symbol(member, Decl(file1.ts, 7, 12)) +>undefined : Symbol(undefined) + +let b: B = { member: undefined }; +>b : Symbol(b, Decl(file1.ts, 8, 3)) +>B : Symbol(B, Decl(file1.ts, 2, 1)) +>member : Symbol(member, Decl(file1.ts, 8, 12)) +>undefined : Symbol(undefined) + +a = b; +>a : Symbol(a, Decl(file1.ts, 7, 3)) +>b : Symbol(b, Decl(file1.ts, 8, 3)) + +b = a; +>b : Symbol(b, Decl(file1.ts, 8, 3)) +>a : Symbol(a, Decl(file1.ts, 7, 3)) + +import {A as OtherA, B as OtherB} from "./file2"; +>A : Symbol(OtherA, Decl(file2.ts, 0, 0)) +>OtherA : Symbol(OtherA, Decl(file1.ts, 12, 8)) +>B : Symbol(OtherB, Decl(file2.ts, 3, 1)) +>OtherB : Symbol(OtherB, Decl(file1.ts, 12, 20)) + +let a2: OtherA = { member: undefined }; +>a2 : Symbol(a2, Decl(file1.ts, 14, 3)) +>OtherA : Symbol(OtherA, Decl(file1.ts, 12, 8)) +>member : Symbol(member, Decl(file1.ts, 14, 18)) +>undefined : Symbol(undefined) + +declare var b2: OtherB; +>b2 : Symbol(b2, Decl(file1.ts, 15, 11)) +>OtherB : Symbol(OtherB, Decl(file1.ts, 12, 20)) + +a2 = b2; +>a2 : Symbol(a2, Decl(file1.ts, 14, 3)) +>b2 : Symbol(b2, Decl(file1.ts, 15, 11)) + +b2 = a2; +>b2 : Symbol(b2, Decl(file1.ts, 15, 11)) +>a2 : Symbol(a2, Decl(file1.ts, 14, 3)) + +a = a2; +>a : Symbol(a, Decl(file1.ts, 7, 3)) +>a2 : Symbol(a2, Decl(file1.ts, 14, 3)) + +a2 = a; +>a2 : Symbol(a2, Decl(file1.ts, 14, 3)) +>a : Symbol(a, Decl(file1.ts, 7, 3)) + +b = b2; +>b : Symbol(b, Decl(file1.ts, 8, 3)) +>b2 : Symbol(b2, Decl(file1.ts, 15, 11)) + +b2 = b; +>b2 : Symbol(b2, Decl(file1.ts, 15, 11)) +>b : Symbol(b, Decl(file1.ts, 8, 3)) + +a = b2; +>a : Symbol(a, Decl(file1.ts, 7, 3)) +>b2 : Symbol(b2, Decl(file1.ts, 15, 11)) + +b2 = a; +>b2 : Symbol(b2, Decl(file1.ts, 15, 11)) +>a : Symbol(a, Decl(file1.ts, 7, 3)) + +b = a2; +>b : Symbol(b, Decl(file1.ts, 8, 3)) +>a2 : Symbol(a2, Decl(file1.ts, 14, 3)) + +a2 = b; +>a2 : Symbol(a2, Decl(file1.ts, 14, 3)) +>b : Symbol(b, Decl(file1.ts, 8, 3)) + +=== tests/cases/conformance/pragma/strictNullChecks/file2.ts === +// @ts-strictNullChecks false +export interface A { +>A : Symbol(A, Decl(file2.ts, 0, 0)) + + member: number; +>member : Symbol(A.member, Decl(file2.ts, 1, 20)) +} +export interface B { +>B : Symbol(B, Decl(file2.ts, 3, 1)) + + member: undefined; +>member : Symbol(B.member, Decl(file2.ts, 4, 20)) +} + +let a: A = { member: undefined }; +>a : Symbol(a, Decl(file2.ts, 8, 3)) +>A : Symbol(A, Decl(file2.ts, 0, 0)) +>member : Symbol(member, Decl(file2.ts, 8, 12)) +>undefined : Symbol(undefined) + +let b: B = { member: undefined }; +>b : Symbol(b, Decl(file2.ts, 9, 3)) +>B : Symbol(B, Decl(file2.ts, 3, 1)) +>member : Symbol(member, Decl(file2.ts, 9, 12)) +>undefined : Symbol(undefined) + +a = b; +>a : Symbol(a, Decl(file2.ts, 8, 3)) +>b : Symbol(b, Decl(file2.ts, 9, 3)) + +b = a; // Historic behavior is that most things aren't assignable to `undefined` when it doesn't evaporate, even outside `strict` mode - making it more like a special `never` than an `any`. +>b : Symbol(b, Decl(file2.ts, 9, 3)) +>a : Symbol(a, Decl(file2.ts, 8, 3)) + +import {A as OtherA, B as OtherB} from "./file1"; +>A : Symbol(OtherA, Decl(file1.ts, 0, 0)) +>OtherA : Symbol(OtherA, Decl(file2.ts, 13, 8)) +>B : Symbol(OtherB, Decl(file1.ts, 2, 1)) +>OtherB : Symbol(OtherB, Decl(file2.ts, 13, 20)) + +let a2: OtherA = { member: undefined }; +>a2 : Symbol(a2, Decl(file2.ts, 15, 3)) +>OtherA : Symbol(OtherA, Decl(file2.ts, 13, 8)) +>member : Symbol(member, Decl(file2.ts, 15, 18)) +>undefined : Symbol(undefined) + +declare var b2: OtherB; +>b2 : Symbol(b2, Decl(file2.ts, 16, 11)) +>OtherB : Symbol(OtherB, Decl(file2.ts, 13, 20)) + +a2 = b2; +>a2 : Symbol(a2, Decl(file2.ts, 15, 3)) +>b2 : Symbol(b2, Decl(file2.ts, 16, 11)) + +b2 = a2; +>b2 : Symbol(b2, Decl(file2.ts, 16, 11)) +>a2 : Symbol(a2, Decl(file2.ts, 15, 3)) + +a = a2; +>a : Symbol(a, Decl(file2.ts, 8, 3)) +>a2 : Symbol(a2, Decl(file2.ts, 15, 3)) + +a2 = a; +>a2 : Symbol(a2, Decl(file2.ts, 15, 3)) +>a : Symbol(a, Decl(file2.ts, 8, 3)) + +b = b2; +>b : Symbol(b, Decl(file2.ts, 9, 3)) +>b2 : Symbol(b2, Decl(file2.ts, 16, 11)) + +b2 = b; +>b2 : Symbol(b2, Decl(file2.ts, 16, 11)) +>b : Symbol(b, Decl(file2.ts, 9, 3)) + +a = b2; +>a : Symbol(a, Decl(file2.ts, 8, 3)) +>b2 : Symbol(b2, Decl(file2.ts, 16, 11)) + +b2 = a; +>b2 : Symbol(b2, Decl(file2.ts, 16, 11)) +>a : Symbol(a, Decl(file2.ts, 8, 3)) + +b = a2; +>b : Symbol(b, Decl(file2.ts, 9, 3)) +>a2 : Symbol(a2, Decl(file2.ts, 15, 3)) + +a2 = b; +>a2 : Symbol(a2, Decl(file2.ts, 15, 3)) +>b : Symbol(b, Decl(file2.ts, 9, 3)) + +=== tests/cases/conformance/pragma/strictNullChecks/file3.ts === +import {A, B} from "./file1"; +>A : Symbol(A, Decl(file3.ts, 0, 8)) +>B : Symbol(B, Decl(file3.ts, 0, 10)) + +import {A as A2, B as B2} from "./file2"; +>A : Symbol(A2, Decl(file2.ts, 0, 0)) +>A2 : Symbol(A2, Decl(file3.ts, 1, 8)) +>B : Symbol(B2, Decl(file2.ts, 3, 1)) +>B2 : Symbol(B2, Decl(file3.ts, 1, 16)) + +let a: A = { member: undefined }; +>a : Symbol(a, Decl(file3.ts, 3, 3)) +>A : Symbol(A, Decl(file3.ts, 0, 8)) +>member : Symbol(member, Decl(file3.ts, 3, 12)) +>undefined : Symbol(undefined) + +let b: B = { member: undefined }; +>b : Symbol(b, Decl(file3.ts, 4, 3)) +>B : Symbol(B, Decl(file3.ts, 0, 10)) +>member : Symbol(member, Decl(file3.ts, 4, 12)) +>undefined : Symbol(undefined) + +let a2: A2 = { member: undefined }; +>a2 : Symbol(a2, Decl(file3.ts, 5, 3)) +>A2 : Symbol(A2, Decl(file3.ts, 1, 8)) +>member : Symbol(member, Decl(file3.ts, 5, 14)) +>undefined : Symbol(undefined) + +let b2: B2 = { member: undefined }; +>b2 : Symbol(b2, Decl(file3.ts, 6, 3)) +>B2 : Symbol(B2, Decl(file3.ts, 1, 16)) +>member : Symbol(member, Decl(file3.ts, 6, 14)) +>undefined : Symbol(undefined) + +a = b; +>a : Symbol(a, Decl(file3.ts, 3, 3)) +>b : Symbol(b, Decl(file3.ts, 4, 3)) + +b = a; +>b : Symbol(b, Decl(file3.ts, 4, 3)) +>a : Symbol(a, Decl(file3.ts, 3, 3)) + +a2 = b2; +>a2 : Symbol(a2, Decl(file3.ts, 5, 3)) +>b2 : Symbol(b2, Decl(file3.ts, 6, 3)) + +b2 = a2; +>b2 : Symbol(b2, Decl(file3.ts, 6, 3)) +>a2 : Symbol(a2, Decl(file3.ts, 5, 3)) + +a = a2; +>a : Symbol(a, Decl(file3.ts, 3, 3)) +>a2 : Symbol(a2, Decl(file3.ts, 5, 3)) + +a2 = a; +>a2 : Symbol(a2, Decl(file3.ts, 5, 3)) +>a : Symbol(a, Decl(file3.ts, 3, 3)) + +b = b2; +>b : Symbol(b, Decl(file3.ts, 4, 3)) +>b2 : Symbol(b2, Decl(file3.ts, 6, 3)) + +b2 = b; +>b2 : Symbol(b2, Decl(file3.ts, 6, 3)) +>b : Symbol(b, Decl(file3.ts, 4, 3)) + +a = b2; +>a : Symbol(a, Decl(file3.ts, 3, 3)) +>b2 : Symbol(b2, Decl(file3.ts, 6, 3)) + +b2 = a; +>b2 : Symbol(b2, Decl(file3.ts, 6, 3)) +>a : Symbol(a, Decl(file3.ts, 3, 3)) + +b = a2; +>b : Symbol(b, Decl(file3.ts, 4, 3)) +>a2 : Symbol(a2, Decl(file3.ts, 5, 3)) + +a2 = b; +>a2 : Symbol(a2, Decl(file3.ts, 5, 3)) +>b : Symbol(b, Decl(file3.ts, 4, 3)) + +=== tests/cases/conformance/pragma/strictNullChecks/file4.ts === +// @ts-strictNullChecks false +import {A, B} from "./file1"; +>A : Symbol(A, Decl(file4.ts, 1, 8)) +>B : Symbol(B, Decl(file4.ts, 1, 10)) + +import {A as A2, B as B2} from "./file2"; +>A : Symbol(A2, Decl(file2.ts, 0, 0)) +>A2 : Symbol(A2, Decl(file4.ts, 2, 8)) +>B : Symbol(B2, Decl(file2.ts, 3, 1)) +>B2 : Symbol(B2, Decl(file4.ts, 2, 16)) + +let a: A = { member: undefined }; +>a : Symbol(a, Decl(file4.ts, 4, 3)) +>A : Symbol(A, Decl(file4.ts, 1, 8)) +>member : Symbol(member, Decl(file4.ts, 4, 12)) +>undefined : Symbol(undefined) + +let b: B = { member: undefined }; +>b : Symbol(b, Decl(file4.ts, 5, 3)) +>B : Symbol(B, Decl(file4.ts, 1, 10)) +>member : Symbol(member, Decl(file4.ts, 5, 12)) +>undefined : Symbol(undefined) + +let a2: A2 = { member: undefined }; +>a2 : Symbol(a2, Decl(file4.ts, 6, 3)) +>A2 : Symbol(A2, Decl(file4.ts, 2, 8)) +>member : Symbol(member, Decl(file4.ts, 6, 14)) +>undefined : Symbol(undefined) + +let b2: B2 = { member: undefined }; +>b2 : Symbol(b2, Decl(file4.ts, 7, 3)) +>B2 : Symbol(B2, Decl(file4.ts, 2, 16)) +>member : Symbol(member, Decl(file4.ts, 7, 14)) +>undefined : Symbol(undefined) + +a = b; +>a : Symbol(a, Decl(file4.ts, 4, 3)) +>b : Symbol(b, Decl(file4.ts, 5, 3)) + +b = a; +>b : Symbol(b, Decl(file4.ts, 5, 3)) +>a : Symbol(a, Decl(file4.ts, 4, 3)) + +a2 = b2; +>a2 : Symbol(a2, Decl(file4.ts, 6, 3)) +>b2 : Symbol(b2, Decl(file4.ts, 7, 3)) + +b2 = a2; +>b2 : Symbol(b2, Decl(file4.ts, 7, 3)) +>a2 : Symbol(a2, Decl(file4.ts, 6, 3)) + +a = a2; +>a : Symbol(a, Decl(file4.ts, 4, 3)) +>a2 : Symbol(a2, Decl(file4.ts, 6, 3)) + +a2 = a; +>a2 : Symbol(a2, Decl(file4.ts, 6, 3)) +>a : Symbol(a, Decl(file4.ts, 4, 3)) + +b = b2; +>b : Symbol(b, Decl(file4.ts, 5, 3)) +>b2 : Symbol(b2, Decl(file4.ts, 7, 3)) + +b2 = b; +>b2 : Symbol(b2, Decl(file4.ts, 7, 3)) +>b : Symbol(b, Decl(file4.ts, 5, 3)) + +a = b2; +>a : Symbol(a, Decl(file4.ts, 4, 3)) +>b2 : Symbol(b2, Decl(file4.ts, 7, 3)) + +b2 = a; +>b2 : Symbol(b2, Decl(file4.ts, 7, 3)) +>a : Symbol(a, Decl(file4.ts, 4, 3)) + +b = a2; +>b : Symbol(b, Decl(file4.ts, 5, 3)) +>a2 : Symbol(a2, Decl(file4.ts, 6, 3)) + +a2 = b; +>a2 : Symbol(a2, Decl(file4.ts, 6, 3)) +>b : Symbol(b, Decl(file4.ts, 5, 3)) + diff --git a/tests/baselines/reference/strictNullChecksPragma4.types b/tests/baselines/reference/strictNullChecksPragma4.types new file mode 100644 index 0000000000000..377185aee8383 --- /dev/null +++ b/tests/baselines/reference/strictNullChecksPragma4.types @@ -0,0 +1,386 @@ +=== tests/cases/conformance/pragma/strictNullChecks/file1.ts === +export interface A { + member: number; +>member : number +} +export interface B { + member: undefined; +>member : undefined +} + +let a: A = { member: undefined }; +>a : A +>{ member: undefined } : { member: undefined; } +>member : undefined +>undefined : undefined + +let b: B = { member: undefined }; +>b : B +>{ member: undefined } : { member: undefined; } +>member : undefined +>undefined : undefined + +a = b; +>a = b : B +>a : A +>b : B + +b = a; +>b = a : A +>b : B +>a : A + +import {A as OtherA, B as OtherB} from "./file2"; +>A : any +>OtherA : any +>B : any +>OtherB : any + +let a2: OtherA = { member: undefined }; +>a2 : OtherA +>{ member: undefined } : { member: undefined; } +>member : undefined +>undefined : undefined + +declare var b2: OtherB; +>b2 : OtherB + +a2 = b2; +>a2 = b2 : OtherB +>a2 : OtherA +>b2 : OtherB + +b2 = a2; +>b2 = a2 : OtherA +>b2 : OtherB +>a2 : OtherA + +a = a2; +>a = a2 : OtherA +>a : A +>a2 : OtherA + +a2 = a; +>a2 = a : A +>a2 : OtherA +>a : A + +b = b2; +>b = b2 : OtherB +>b : B +>b2 : OtherB + +b2 = b; +>b2 = b : B +>b2 : OtherB +>b : B + +a = b2; +>a = b2 : OtherB +>a : A +>b2 : OtherB + +b2 = a; +>b2 = a : A +>b2 : OtherB +>a : A + +b = a2; +>b = a2 : OtherA +>b : B +>a2 : OtherA + +a2 = b; +>a2 = b : B +>a2 : OtherA +>b : B + +=== tests/cases/conformance/pragma/strictNullChecks/file2.ts === +// @ts-strictNullChecks false +export interface A { + member: number; +>member : number +} +export interface B { + member: undefined; +>member : undefined +} + +let a: A = { member: undefined }; +>a : A +>{ member: undefined } : { member: undefined; } +>member : undefined +>undefined : undefined + +let b: B = { member: undefined }; +>b : B +>{ member: undefined } : { member: undefined; } +>member : undefined +>undefined : undefined + +a = b; +>a = b : B +>a : A +>b : B + +b = a; // Historic behavior is that most things aren't assignable to `undefined` when it doesn't evaporate, even outside `strict` mode - making it more like a special `never` than an `any`. +>b = a : A +>b : B +>a : A + +import {A as OtherA, B as OtherB} from "./file1"; +>A : any +>OtherA : any +>B : any +>OtherB : any + +let a2: OtherA = { member: undefined }; +>a2 : OtherA +>{ member: undefined } : { member: undefined; } +>member : undefined +>undefined : undefined + +declare var b2: OtherB; +>b2 : OtherB + +a2 = b2; +>a2 = b2 : OtherB +>a2 : OtherA +>b2 : OtherB + +b2 = a2; +>b2 = a2 : OtherA +>b2 : OtherB +>a2 : OtherA + +a = a2; +>a = a2 : OtherA +>a : A +>a2 : OtherA + +a2 = a; +>a2 = a : A +>a2 : OtherA +>a : A + +b = b2; +>b = b2 : OtherB +>b : B +>b2 : OtherB + +b2 = b; +>b2 = b : B +>b2 : OtherB +>b : B + +a = b2; +>a = b2 : OtherB +>a : A +>b2 : OtherB + +b2 = a; +>b2 = a : A +>b2 : OtherB +>a : A + +b = a2; +>b = a2 : OtherA +>b : B +>a2 : OtherA + +a2 = b; +>a2 = b : B +>a2 : OtherA +>b : B + +=== tests/cases/conformance/pragma/strictNullChecks/file3.ts === +import {A, B} from "./file1"; +>A : any +>B : any + +import {A as A2, B as B2} from "./file2"; +>A : any +>A2 : any +>B : any +>B2 : any + +let a: A = { member: undefined }; +>a : A +>{ member: undefined } : { member: undefined; } +>member : undefined +>undefined : undefined + +let b: B = { member: undefined }; +>b : B +>{ member: undefined } : { member: undefined; } +>member : undefined +>undefined : undefined + +let a2: A2 = { member: undefined }; +>a2 : A2 +>{ member: undefined } : { member: undefined; } +>member : undefined +>undefined : undefined + +let b2: B2 = { member: undefined }; +>b2 : B2 +>{ member: undefined } : { member: undefined; } +>member : undefined +>undefined : undefined + +a = b; +>a = b : B +>a : A +>b : B + +b = a; +>b = a : A +>b : B +>a : A + +a2 = b2; +>a2 = b2 : B2 +>a2 : A2 +>b2 : B2 + +b2 = a2; +>b2 = a2 : A2 +>b2 : B2 +>a2 : A2 + +a = a2; +>a = a2 : A2 +>a : A +>a2 : A2 + +a2 = a; +>a2 = a : A +>a2 : A2 +>a : A + +b = b2; +>b = b2 : B2 +>b : B +>b2 : B2 + +b2 = b; +>b2 = b : B +>b2 : B2 +>b : B + +a = b2; +>a = b2 : B2 +>a : A +>b2 : B2 + +b2 = a; +>b2 = a : A +>b2 : B2 +>a : A + +b = a2; +>b = a2 : A2 +>b : B +>a2 : A2 + +a2 = b; +>a2 = b : B +>a2 : A2 +>b : B + +=== tests/cases/conformance/pragma/strictNullChecks/file4.ts === +// @ts-strictNullChecks false +import {A, B} from "./file1"; +>A : any +>B : any + +import {A as A2, B as B2} from "./file2"; +>A : any +>A2 : any +>B : any +>B2 : any + +let a: A = { member: undefined }; +>a : A +>{ member: undefined } : { member: undefined; } +>member : undefined +>undefined : undefined + +let b: B = { member: undefined }; +>b : B +>{ member: undefined } : { member: undefined; } +>member : undefined +>undefined : undefined + +let a2: A2 = { member: undefined }; +>a2 : A2 +>{ member: undefined } : { member: undefined; } +>member : undefined +>undefined : undefined + +let b2: B2 = { member: undefined }; +>b2 : B2 +>{ member: undefined } : { member: undefined; } +>member : undefined +>undefined : undefined + +a = b; +>a = b : B +>a : A +>b : B + +b = a; +>b = a : A +>b : B +>a : A + +a2 = b2; +>a2 = b2 : B2 +>a2 : A2 +>b2 : B2 + +b2 = a2; +>b2 = a2 : A2 +>b2 : B2 +>a2 : A2 + +a = a2; +>a = a2 : A2 +>a : A +>a2 : A2 + +a2 = a; +>a2 = a : A +>a2 : A2 +>a : A + +b = b2; +>b = b2 : B2 +>b : B +>b2 : B2 + +b2 = b; +>b2 = b : B +>b2 : B2 +>b : B + +a = b2; +>a = b2 : B2 +>a : A +>b2 : B2 + +b2 = a; +>b2 = a : A +>b2 : B2 +>a : A + +b = a2; +>b = a2 : A2 +>b : B +>a2 : A2 + +a2 = b; +>a2 = b : B +>a2 : A2 +>b : B + diff --git a/tests/baselines/reference/strictNullChecksPragma5.errors.txt b/tests/baselines/reference/strictNullChecksPragma5.errors.txt new file mode 100644 index 0000000000000..6aede13b519d3 --- /dev/null +++ b/tests/baselines/reference/strictNullChecksPragma5.errors.txt @@ -0,0 +1,207 @@ +tests/cases/conformance/pragma/strictNullChecks/file1.ts(16,20): error TS2322: Type 'undefined' is not assignable to type 'string'. +tests/cases/conformance/pragma/strictNullChecks/file1.ts(22,1): error TS2322: Type 'import("tests/cases/conformance/pragma/strictNullChecks/file1").A' is not assignable to type 'import("tests/cases/conformance/pragma/strictNullChecks/file2").A'. +tests/cases/conformance/pragma/strictNullChecks/file1.ts(25,1): error TS2322: Type 'import("tests/cases/conformance/pragma/strictNullChecks/file1").B' is not assignable to type 'import("tests/cases/conformance/pragma/strictNullChecks/file2").B'. +tests/cases/conformance/pragma/strictNullChecks/file1.ts(28,1): error TS2322: Type 'A' is not assignable to type 'B'. +tests/cases/conformance/pragma/strictNullChecks/file1.ts(31,1): error TS2322: Type 'B' is not assignable to type 'A'. +tests/cases/conformance/pragma/strictNullChecks/file2.ts(21,1): error TS2322: Type 'import("tests/cases/conformance/pragma/strictNullChecks/file1").A' is not assignable to type 'import("tests/cases/conformance/pragma/strictNullChecks/file2").A'. + Types of property 'member' are incompatible. + Type 'string | undefined' is not assignable to type 'string'. + Type 'undefined' is not assignable to type 'string'. +tests/cases/conformance/pragma/strictNullChecks/file2.ts(24,1): error TS2322: Type 'import("tests/cases/conformance/pragma/strictNullChecks/file1").B' is not assignable to type 'import("tests/cases/conformance/pragma/strictNullChecks/file2").B'. + Types of property 'member' are incompatible. + Type 'string | undefined' is not assignable to type 'string'. + Type 'undefined' is not assignable to type 'string'. +tests/cases/conformance/pragma/strictNullChecks/file2.ts(27,1): error TS2322: Type 'B' is not assignable to type 'A'. + Types of property 'member' are incompatible. + Type 'string | undefined' is not assignable to type 'string'. + Type 'undefined' is not assignable to type 'string'. +tests/cases/conformance/pragma/strictNullChecks/file2.ts(30,1): error TS2322: Type 'A' is not assignable to type 'B'. + Types of property 'member' are incompatible. + Type 'string | undefined' is not assignable to type 'string'. + Type 'undefined' is not assignable to type 'string'. +tests/cases/conformance/pragma/strictNullChecks/file3.ts(7,16): error TS2322: Type 'undefined' is not assignable to type 'string'. +tests/cases/conformance/pragma/strictNullChecks/file3.ts(8,16): error TS2322: Type 'undefined' is not assignable to type 'string'. +tests/cases/conformance/pragma/strictNullChecks/file3.ts(17,1): error TS2322: Type 'import("tests/cases/conformance/pragma/strictNullChecks/file1").A' is not assignable to type 'import("tests/cases/conformance/pragma/strictNullChecks/file2").A'. +tests/cases/conformance/pragma/strictNullChecks/file3.ts(20,1): error TS2322: Type 'import("tests/cases/conformance/pragma/strictNullChecks/file1").B' is not assignable to type 'import("tests/cases/conformance/pragma/strictNullChecks/file2").B'. +tests/cases/conformance/pragma/strictNullChecks/file3.ts(23,1): error TS2322: Type 'A' is not assignable to type 'B'. +tests/cases/conformance/pragma/strictNullChecks/file3.ts(26,1): error TS2322: Type 'B' is not assignable to type 'A'. +tests/cases/conformance/pragma/strictNullChecks/file4.ts(17,1): error TS2322: Type 'import("tests/cases/conformance/pragma/strictNullChecks/file1").A' is not assignable to type 'import("tests/cases/conformance/pragma/strictNullChecks/file2").A'. +tests/cases/conformance/pragma/strictNullChecks/file4.ts(20,1): error TS2322: Type 'import("tests/cases/conformance/pragma/strictNullChecks/file1").B' is not assignable to type 'import("tests/cases/conformance/pragma/strictNullChecks/file2").B'. +tests/cases/conformance/pragma/strictNullChecks/file4.ts(23,1): error TS2322: Type 'A' is not assignable to type 'B'. +tests/cases/conformance/pragma/strictNullChecks/file4.ts(26,1): error TS2322: Type 'B' is not assignable to type 'A'. + + +==== tests/cases/conformance/pragma/strictNullChecks/file1.ts (5 errors) ==== + // @ts-strictNullChecks + export interface A { + member?: string; + } + export interface B { + member?: string | undefined; + } + + let a: A = { member: undefined }; + declare var b: B; + a = b; + b = a; + + import {A as OtherA, B as OtherB} from "./file2"; + + let a2: OtherA = { member: undefined }; + ~~~~~~ +!!! error TS2322: Type 'undefined' is not assignable to type 'string'. +!!! related TS6500 /.src/tests/cases/conformance/pragma/strictNullChecks/file2.ts:3:5: The expected type comes from property 'member' which is declared here on type 'A' + declare var b2: OtherB; + a2 = b2; + b2 = a2; + + a = a2; + a2 = a; + ~~ +!!! error TS2322: Type 'import("tests/cases/conformance/pragma/strictNullChecks/file1").A' is not assignable to type 'import("tests/cases/conformance/pragma/strictNullChecks/file2").A'. + + b = b2; + b2 = b; + ~~ +!!! error TS2322: Type 'import("tests/cases/conformance/pragma/strictNullChecks/file1").B' is not assignable to type 'import("tests/cases/conformance/pragma/strictNullChecks/file2").B'. + + a = b2; + b2 = a; + ~~ +!!! error TS2322: Type 'A' is not assignable to type 'B'. + + b = a2; + a2 = b; + ~~ +!!! error TS2322: Type 'B' is not assignable to type 'A'. + +==== tests/cases/conformance/pragma/strictNullChecks/file2.ts (4 errors) ==== + // loose + export interface A { + member?: string; + } + export interface B { + member?: string | undefined; + } + + let a: A = { member: undefined }; + declare var b: B; + a = b; + b = a; + + import {A as OtherA, B as OtherB} from "./file1"; + + let a2: OtherA = { member: undefined }; + declare var b2: OtherB; + a2 = b2; + b2 = a2; + + a = a2; + ~ +!!! error TS2322: Type 'import("tests/cases/conformance/pragma/strictNullChecks/file1").A' is not assignable to type 'import("tests/cases/conformance/pragma/strictNullChecks/file2").A'. +!!! error TS2322: Types of property 'member' are incompatible. +!!! error TS2322: Type 'string | undefined' is not assignable to type 'string'. +!!! error TS2322: Type 'undefined' is not assignable to type 'string'. + a2 = a; + + b = b2; + ~ +!!! error TS2322: Type 'import("tests/cases/conformance/pragma/strictNullChecks/file1").B' is not assignable to type 'import("tests/cases/conformance/pragma/strictNullChecks/file2").B'. +!!! error TS2322: Types of property 'member' are incompatible. +!!! error TS2322: Type 'string | undefined' is not assignable to type 'string'. +!!! error TS2322: Type 'undefined' is not assignable to type 'string'. + b2 = b; + + a = b2; + ~ +!!! error TS2322: Type 'B' is not assignable to type 'A'. +!!! error TS2322: Types of property 'member' are incompatible. +!!! error TS2322: Type 'string | undefined' is not assignable to type 'string'. +!!! error TS2322: Type 'undefined' is not assignable to type 'string'. + b2 = a; + + b = a2; + ~ +!!! error TS2322: Type 'A' is not assignable to type 'B'. +!!! error TS2322: Types of property 'member' are incompatible. +!!! error TS2322: Type 'string | undefined' is not assignable to type 'string'. +!!! error TS2322: Type 'undefined' is not assignable to type 'string'. + a2 = b; + +==== tests/cases/conformance/pragma/strictNullChecks/file3.ts (6 errors) ==== + // @ts-strictNullChecks + import {A, B} from "./file1"; + import {A as A2, B as B2} from "./file2"; + + let a: A = { member: undefined }; + let b: B = { member: undefined }; + let a2: A2 = { member: undefined }; + ~~~~~~ +!!! error TS2322: Type 'undefined' is not assignable to type 'string'. +!!! related TS6500 /.src/tests/cases/conformance/pragma/strictNullChecks/file2.ts:3:5: The expected type comes from property 'member' which is declared here on type 'A' + let b2: B2 = { member: undefined }; + ~~~~~~ +!!! error TS2322: Type 'undefined' is not assignable to type 'string'. +!!! related TS6500 /.src/tests/cases/conformance/pragma/strictNullChecks/file2.ts:6:5: The expected type comes from property 'member' which is declared here on type 'B' + + a = b; + b = a; + + a2 = b2; + b2 = a2; + + a = a2; + a2 = a; + ~~ +!!! error TS2322: Type 'import("tests/cases/conformance/pragma/strictNullChecks/file1").A' is not assignable to type 'import("tests/cases/conformance/pragma/strictNullChecks/file2").A'. + + b = b2; + b2 = b; + ~~ +!!! error TS2322: Type 'import("tests/cases/conformance/pragma/strictNullChecks/file1").B' is not assignable to type 'import("tests/cases/conformance/pragma/strictNullChecks/file2").B'. + + a = b2; + b2 = a; + ~~ +!!! error TS2322: Type 'A' is not assignable to type 'B'. + + b = a2; + a2 = b; + ~~ +!!! error TS2322: Type 'B' is not assignable to type 'A'. + +==== tests/cases/conformance/pragma/strictNullChecks/file4.ts (4 errors) ==== + // loose + import {A, B} from "./file1"; + import {A as A2, B as B2} from "./file2"; + + let a: A = { member: undefined }; + let b: B = { member: undefined }; + let a2: A2 = { member: undefined }; + let b2: B2 = { member: undefined }; + + a = b; + b = a; + + a2 = b2; + b2 = a2; + + a = a2; + a2 = a; + ~~ +!!! error TS2322: Type 'import("tests/cases/conformance/pragma/strictNullChecks/file1").A' is not assignable to type 'import("tests/cases/conformance/pragma/strictNullChecks/file2").A'. + + b = b2; + b2 = b; + ~~ +!!! error TS2322: Type 'import("tests/cases/conformance/pragma/strictNullChecks/file1").B' is not assignable to type 'import("tests/cases/conformance/pragma/strictNullChecks/file2").B'. + + a = b2; + b2 = a; + ~~ +!!! error TS2322: Type 'A' is not assignable to type 'B'. + + b = a2; + a2 = b; + ~~ +!!! error TS2322: Type 'B' is not assignable to type 'A'. \ No newline at end of file diff --git a/tests/baselines/reference/strictNullChecksPragma5.js b/tests/baselines/reference/strictNullChecksPragma5.js new file mode 100644 index 0000000000000..10f744e8b013b --- /dev/null +++ b/tests/baselines/reference/strictNullChecksPragma5.js @@ -0,0 +1,196 @@ +//// [tests/cases/conformance/pragma/strictNullChecks/strictNullChecksPragma5.ts] //// + +//// [file1.ts] +// @ts-strictNullChecks +export interface A { + member?: string; +} +export interface B { + member?: string | undefined; +} + +let a: A = { member: undefined }; +declare var b: B; +a = b; +b = a; + +import {A as OtherA, B as OtherB} from "./file2"; + +let a2: OtherA = { member: undefined }; +declare var b2: OtherB; +a2 = b2; +b2 = a2; + +a = a2; +a2 = a; + +b = b2; +b2 = b; + +a = b2; +b2 = a; + +b = a2; +a2 = b; + +//// [file2.ts] +// loose +export interface A { + member?: string; +} +export interface B { + member?: string | undefined; +} + +let a: A = { member: undefined }; +declare var b: B; +a = b; +b = a; + +import {A as OtherA, B as OtherB} from "./file1"; + +let a2: OtherA = { member: undefined }; +declare var b2: OtherB; +a2 = b2; +b2 = a2; + +a = a2; +a2 = a; + +b = b2; +b2 = b; + +a = b2; +b2 = a; + +b = a2; +a2 = b; + +//// [file3.ts] +// @ts-strictNullChecks +import {A, B} from "./file1"; +import {A as A2, B as B2} from "./file2"; + +let a: A = { member: undefined }; +let b: B = { member: undefined }; +let a2: A2 = { member: undefined }; +let b2: B2 = { member: undefined }; + +a = b; +b = a; + +a2 = b2; +b2 = a2; + +a = a2; +a2 = a; + +b = b2; +b2 = b; + +a = b2; +b2 = a; + +b = a2; +a2 = b; + +//// [file4.ts] +// loose +import {A, B} from "./file1"; +import {A as A2, B as B2} from "./file2"; + +let a: A = { member: undefined }; +let b: B = { member: undefined }; +let a2: A2 = { member: undefined }; +let b2: B2 = { member: undefined }; + +a = b; +b = a; + +a2 = b2; +b2 = a2; + +a = a2; +a2 = a; + +b = b2; +b2 = b; + +a = b2; +b2 = a; + +b = a2; +a2 = b; + +//// [file2.js] +"use strict"; +exports.__esModule = true; +var a = { member: undefined }; +a = b; +b = a; +var a2 = { member: undefined }; +a2 = b2; +b2 = a2; +a = a2; +a2 = a; +b = b2; +b2 = b; +a = b2; +b2 = a; +b = a2; +a2 = b; +//// [file1.js] +"use strict"; +exports.__esModule = true; +var a = { member: undefined }; +a = b; +b = a; +var a2 = { member: undefined }; +a2 = b2; +b2 = a2; +a = a2; +a2 = a; +b = b2; +b2 = b; +a = b2; +b2 = a; +b = a2; +a2 = b; +//// [file3.js] +"use strict"; +exports.__esModule = true; +var a = { member: undefined }; +var b = { member: undefined }; +var a2 = { member: undefined }; +var b2 = { member: undefined }; +a = b; +b = a; +a2 = b2; +b2 = a2; +a = a2; +a2 = a; +b = b2; +b2 = b; +a = b2; +b2 = a; +b = a2; +a2 = b; +//// [file4.js] +"use strict"; +exports.__esModule = true; +var a = { member: undefined }; +var b = { member: undefined }; +var a2 = { member: undefined }; +var b2 = { member: undefined }; +a = b; +b = a; +a2 = b2; +b2 = a2; +a = a2; +a2 = a; +b = b2; +b2 = b; +a = b2; +b2 = a; +b = a2; +a2 = b; diff --git a/tests/baselines/reference/strictNullChecksPragma5.symbols b/tests/baselines/reference/strictNullChecksPragma5.symbols new file mode 100644 index 0000000000000..e3c487c46fc66 --- /dev/null +++ b/tests/baselines/reference/strictNullChecksPragma5.symbols @@ -0,0 +1,346 @@ +=== tests/cases/conformance/pragma/strictNullChecks/file1.ts === +// @ts-strictNullChecks +export interface A { +>A : Symbol(A, Decl(file1.ts, 0, 0)) + + member?: string; +>member : Symbol(A.member, Decl(file1.ts, 1, 20)) +} +export interface B { +>B : Symbol(B, Decl(file1.ts, 3, 1)) + + member?: string | undefined; +>member : Symbol(B.member, Decl(file1.ts, 4, 20)) +} + +let a: A = { member: undefined }; +>a : Symbol(a, Decl(file1.ts, 8, 3)) +>A : Symbol(A, Decl(file1.ts, 0, 0)) +>member : Symbol(member, Decl(file1.ts, 8, 12)) +>undefined : Symbol(undefined) + +declare var b: B; +>b : Symbol(b, Decl(file1.ts, 9, 11)) +>B : Symbol(B, Decl(file1.ts, 3, 1)) + +a = b; +>a : Symbol(a, Decl(file1.ts, 8, 3)) +>b : Symbol(b, Decl(file1.ts, 9, 11)) + +b = a; +>b : Symbol(b, Decl(file1.ts, 9, 11)) +>a : Symbol(a, Decl(file1.ts, 8, 3)) + +import {A as OtherA, B as OtherB} from "./file2"; +>A : Symbol(OtherA, Decl(file2.ts, 0, 0)) +>OtherA : Symbol(OtherA, Decl(file1.ts, 13, 8)) +>B : Symbol(OtherB, Decl(file2.ts, 3, 1)) +>OtherB : Symbol(OtherB, Decl(file1.ts, 13, 20)) + +let a2: OtherA = { member: undefined }; +>a2 : Symbol(a2, Decl(file1.ts, 15, 3)) +>OtherA : Symbol(OtherA, Decl(file1.ts, 13, 8)) +>member : Symbol(member, Decl(file1.ts, 15, 18)) +>undefined : Symbol(undefined) + +declare var b2: OtherB; +>b2 : Symbol(b2, Decl(file1.ts, 16, 11)) +>OtherB : Symbol(OtherB, Decl(file1.ts, 13, 20)) + +a2 = b2; +>a2 : Symbol(a2, Decl(file1.ts, 15, 3)) +>b2 : Symbol(b2, Decl(file1.ts, 16, 11)) + +b2 = a2; +>b2 : Symbol(b2, Decl(file1.ts, 16, 11)) +>a2 : Symbol(a2, Decl(file1.ts, 15, 3)) + +a = a2; +>a : Symbol(a, Decl(file1.ts, 8, 3)) +>a2 : Symbol(a2, Decl(file1.ts, 15, 3)) + +a2 = a; +>a2 : Symbol(a2, Decl(file1.ts, 15, 3)) +>a : Symbol(a, Decl(file1.ts, 8, 3)) + +b = b2; +>b : Symbol(b, Decl(file1.ts, 9, 11)) +>b2 : Symbol(b2, Decl(file1.ts, 16, 11)) + +b2 = b; +>b2 : Symbol(b2, Decl(file1.ts, 16, 11)) +>b : Symbol(b, Decl(file1.ts, 9, 11)) + +a = b2; +>a : Symbol(a, Decl(file1.ts, 8, 3)) +>b2 : Symbol(b2, Decl(file1.ts, 16, 11)) + +b2 = a; +>b2 : Symbol(b2, Decl(file1.ts, 16, 11)) +>a : Symbol(a, Decl(file1.ts, 8, 3)) + +b = a2; +>b : Symbol(b, Decl(file1.ts, 9, 11)) +>a2 : Symbol(a2, Decl(file1.ts, 15, 3)) + +a2 = b; +>a2 : Symbol(a2, Decl(file1.ts, 15, 3)) +>b : Symbol(b, Decl(file1.ts, 9, 11)) + +=== tests/cases/conformance/pragma/strictNullChecks/file2.ts === +// loose +export interface A { +>A : Symbol(A, Decl(file2.ts, 0, 0)) + + member?: string; +>member : Symbol(A.member, Decl(file2.ts, 1, 20)) +} +export interface B { +>B : Symbol(B, Decl(file2.ts, 3, 1)) + + member?: string | undefined; +>member : Symbol(B.member, Decl(file2.ts, 4, 20)) +} + +let a: A = { member: undefined }; +>a : Symbol(a, Decl(file2.ts, 8, 3)) +>A : Symbol(A, Decl(file2.ts, 0, 0)) +>member : Symbol(member, Decl(file2.ts, 8, 12)) +>undefined : Symbol(undefined) + +declare var b: B; +>b : Symbol(b, Decl(file2.ts, 9, 11)) +>B : Symbol(B, Decl(file2.ts, 3, 1)) + +a = b; +>a : Symbol(a, Decl(file2.ts, 8, 3)) +>b : Symbol(b, Decl(file2.ts, 9, 11)) + +b = a; +>b : Symbol(b, Decl(file2.ts, 9, 11)) +>a : Symbol(a, Decl(file2.ts, 8, 3)) + +import {A as OtherA, B as OtherB} from "./file1"; +>A : Symbol(OtherA, Decl(file1.ts, 0, 0)) +>OtherA : Symbol(OtherA, Decl(file2.ts, 13, 8)) +>B : Symbol(OtherB, Decl(file1.ts, 3, 1)) +>OtherB : Symbol(OtherB, Decl(file2.ts, 13, 20)) + +let a2: OtherA = { member: undefined }; +>a2 : Symbol(a2, Decl(file2.ts, 15, 3)) +>OtherA : Symbol(OtherA, Decl(file2.ts, 13, 8)) +>member : Symbol(member, Decl(file2.ts, 15, 18)) +>undefined : Symbol(undefined) + +declare var b2: OtherB; +>b2 : Symbol(b2, Decl(file2.ts, 16, 11)) +>OtherB : Symbol(OtherB, Decl(file2.ts, 13, 20)) + +a2 = b2; +>a2 : Symbol(a2, Decl(file2.ts, 15, 3)) +>b2 : Symbol(b2, Decl(file2.ts, 16, 11)) + +b2 = a2; +>b2 : Symbol(b2, Decl(file2.ts, 16, 11)) +>a2 : Symbol(a2, Decl(file2.ts, 15, 3)) + +a = a2; +>a : Symbol(a, Decl(file2.ts, 8, 3)) +>a2 : Symbol(a2, Decl(file2.ts, 15, 3)) + +a2 = a; +>a2 : Symbol(a2, Decl(file2.ts, 15, 3)) +>a : Symbol(a, Decl(file2.ts, 8, 3)) + +b = b2; +>b : Symbol(b, Decl(file2.ts, 9, 11)) +>b2 : Symbol(b2, Decl(file2.ts, 16, 11)) + +b2 = b; +>b2 : Symbol(b2, Decl(file2.ts, 16, 11)) +>b : Symbol(b, Decl(file2.ts, 9, 11)) + +a = b2; +>a : Symbol(a, Decl(file2.ts, 8, 3)) +>b2 : Symbol(b2, Decl(file2.ts, 16, 11)) + +b2 = a; +>b2 : Symbol(b2, Decl(file2.ts, 16, 11)) +>a : Symbol(a, Decl(file2.ts, 8, 3)) + +b = a2; +>b : Symbol(b, Decl(file2.ts, 9, 11)) +>a2 : Symbol(a2, Decl(file2.ts, 15, 3)) + +a2 = b; +>a2 : Symbol(a2, Decl(file2.ts, 15, 3)) +>b : Symbol(b, Decl(file2.ts, 9, 11)) + +=== tests/cases/conformance/pragma/strictNullChecks/file3.ts === +// @ts-strictNullChecks +import {A, B} from "./file1"; +>A : Symbol(A, Decl(file3.ts, 1, 8)) +>B : Symbol(B, Decl(file3.ts, 1, 10)) + +import {A as A2, B as B2} from "./file2"; +>A : Symbol(A2, Decl(file2.ts, 0, 0)) +>A2 : Symbol(A2, Decl(file3.ts, 2, 8)) +>B : Symbol(B2, Decl(file2.ts, 3, 1)) +>B2 : Symbol(B2, Decl(file3.ts, 2, 16)) + +let a: A = { member: undefined }; +>a : Symbol(a, Decl(file3.ts, 4, 3)) +>A : Symbol(A, Decl(file3.ts, 1, 8)) +>member : Symbol(member, Decl(file3.ts, 4, 12)) +>undefined : Symbol(undefined) + +let b: B = { member: undefined }; +>b : Symbol(b, Decl(file3.ts, 5, 3)) +>B : Symbol(B, Decl(file3.ts, 1, 10)) +>member : Symbol(member, Decl(file3.ts, 5, 12)) +>undefined : Symbol(undefined) + +let a2: A2 = { member: undefined }; +>a2 : Symbol(a2, Decl(file3.ts, 6, 3)) +>A2 : Symbol(A2, Decl(file3.ts, 2, 8)) +>member : Symbol(member, Decl(file3.ts, 6, 14)) +>undefined : Symbol(undefined) + +let b2: B2 = { member: undefined }; +>b2 : Symbol(b2, Decl(file3.ts, 7, 3)) +>B2 : Symbol(B2, Decl(file3.ts, 2, 16)) +>member : Symbol(member, Decl(file3.ts, 7, 14)) +>undefined : Symbol(undefined) + +a = b; +>a : Symbol(a, Decl(file3.ts, 4, 3)) +>b : Symbol(b, Decl(file3.ts, 5, 3)) + +b = a; +>b : Symbol(b, Decl(file3.ts, 5, 3)) +>a : Symbol(a, Decl(file3.ts, 4, 3)) + +a2 = b2; +>a2 : Symbol(a2, Decl(file3.ts, 6, 3)) +>b2 : Symbol(b2, Decl(file3.ts, 7, 3)) + +b2 = a2; +>b2 : Symbol(b2, Decl(file3.ts, 7, 3)) +>a2 : Symbol(a2, Decl(file3.ts, 6, 3)) + +a = a2; +>a : Symbol(a, Decl(file3.ts, 4, 3)) +>a2 : Symbol(a2, Decl(file3.ts, 6, 3)) + +a2 = a; +>a2 : Symbol(a2, Decl(file3.ts, 6, 3)) +>a : Symbol(a, Decl(file3.ts, 4, 3)) + +b = b2; +>b : Symbol(b, Decl(file3.ts, 5, 3)) +>b2 : Symbol(b2, Decl(file3.ts, 7, 3)) + +b2 = b; +>b2 : Symbol(b2, Decl(file3.ts, 7, 3)) +>b : Symbol(b, Decl(file3.ts, 5, 3)) + +a = b2; +>a : Symbol(a, Decl(file3.ts, 4, 3)) +>b2 : Symbol(b2, Decl(file3.ts, 7, 3)) + +b2 = a; +>b2 : Symbol(b2, Decl(file3.ts, 7, 3)) +>a : Symbol(a, Decl(file3.ts, 4, 3)) + +b = a2; +>b : Symbol(b, Decl(file3.ts, 5, 3)) +>a2 : Symbol(a2, Decl(file3.ts, 6, 3)) + +a2 = b; +>a2 : Symbol(a2, Decl(file3.ts, 6, 3)) +>b : Symbol(b, Decl(file3.ts, 5, 3)) + +=== tests/cases/conformance/pragma/strictNullChecks/file4.ts === +// loose +import {A, B} from "./file1"; +>A : Symbol(A, Decl(file4.ts, 1, 8)) +>B : Symbol(B, Decl(file4.ts, 1, 10)) + +import {A as A2, B as B2} from "./file2"; +>A : Symbol(A2, Decl(file2.ts, 0, 0)) +>A2 : Symbol(A2, Decl(file4.ts, 2, 8)) +>B : Symbol(B2, Decl(file2.ts, 3, 1)) +>B2 : Symbol(B2, Decl(file4.ts, 2, 16)) + +let a: A = { member: undefined }; +>a : Symbol(a, Decl(file4.ts, 4, 3)) +>A : Symbol(A, Decl(file4.ts, 1, 8)) +>member : Symbol(member, Decl(file4.ts, 4, 12)) +>undefined : Symbol(undefined) + +let b: B = { member: undefined }; +>b : Symbol(b, Decl(file4.ts, 5, 3)) +>B : Symbol(B, Decl(file4.ts, 1, 10)) +>member : Symbol(member, Decl(file4.ts, 5, 12)) +>undefined : Symbol(undefined) + +let a2: A2 = { member: undefined }; +>a2 : Symbol(a2, Decl(file4.ts, 6, 3)) +>A2 : Symbol(A2, Decl(file4.ts, 2, 8)) +>member : Symbol(member, Decl(file4.ts, 6, 14)) +>undefined : Symbol(undefined) + +let b2: B2 = { member: undefined }; +>b2 : Symbol(b2, Decl(file4.ts, 7, 3)) +>B2 : Symbol(B2, Decl(file4.ts, 2, 16)) +>member : Symbol(member, Decl(file4.ts, 7, 14)) +>undefined : Symbol(undefined) + +a = b; +>a : Symbol(a, Decl(file4.ts, 4, 3)) +>b : Symbol(b, Decl(file4.ts, 5, 3)) + +b = a; +>b : Symbol(b, Decl(file4.ts, 5, 3)) +>a : Symbol(a, Decl(file4.ts, 4, 3)) + +a2 = b2; +>a2 : Symbol(a2, Decl(file4.ts, 6, 3)) +>b2 : Symbol(b2, Decl(file4.ts, 7, 3)) + +b2 = a2; +>b2 : Symbol(b2, Decl(file4.ts, 7, 3)) +>a2 : Symbol(a2, Decl(file4.ts, 6, 3)) + +a = a2; +>a : Symbol(a, Decl(file4.ts, 4, 3)) +>a2 : Symbol(a2, Decl(file4.ts, 6, 3)) + +a2 = a; +>a2 : Symbol(a2, Decl(file4.ts, 6, 3)) +>a : Symbol(a, Decl(file4.ts, 4, 3)) + +b = b2; +>b : Symbol(b, Decl(file4.ts, 5, 3)) +>b2 : Symbol(b2, Decl(file4.ts, 7, 3)) + +b2 = b; +>b2 : Symbol(b2, Decl(file4.ts, 7, 3)) +>b : Symbol(b, Decl(file4.ts, 5, 3)) + +a = b2; +>a : Symbol(a, Decl(file4.ts, 4, 3)) +>b2 : Symbol(b2, Decl(file4.ts, 7, 3)) + +b2 = a; +>b2 : Symbol(b2, Decl(file4.ts, 7, 3)) +>a : Symbol(a, Decl(file4.ts, 4, 3)) + +b = a2; +>b : Symbol(b, Decl(file4.ts, 5, 3)) +>a2 : Symbol(a2, Decl(file4.ts, 6, 3)) + +a2 = b; +>a2 : Symbol(a2, Decl(file4.ts, 6, 3)) +>b : Symbol(b, Decl(file4.ts, 5, 3)) + diff --git a/tests/baselines/reference/strictNullChecksPragma5.types b/tests/baselines/reference/strictNullChecksPragma5.types new file mode 100644 index 0000000000000..4de7640ed50ff --- /dev/null +++ b/tests/baselines/reference/strictNullChecksPragma5.types @@ -0,0 +1,382 @@ +=== tests/cases/conformance/pragma/strictNullChecks/file1.ts === +// @ts-strictNullChecks +export interface A { + member?: string; +>member : string | undefined +} +export interface B { + member?: string | undefined; +>member : string | undefined +} + +let a: A = { member: undefined }; +>a : A +>{ member: undefined } : { member: undefined; } +>member : undefined +>undefined : undefined + +declare var b: B; +>b : B + +a = b; +>a = b : B +>a : A +>b : B + +b = a; +>b = a : A +>b : B +>a : A + +import {A as OtherA, B as OtherB} from "./file2"; +>A : any +>OtherA : any +>B : any +>OtherB : any + +let a2: OtherA = { member: undefined }; +>a2 : OtherA +>{ member: undefined } : { member: undefined; } +>member : undefined +>undefined : undefined + +declare var b2: OtherB; +>b2 : OtherB + +a2 = b2; +>a2 = b2 : OtherB +>a2 : OtherA +>b2 : OtherB + +b2 = a2; +>b2 = a2 : OtherA +>b2 : OtherB +>a2 : OtherA + +a = a2; +>a = a2 : OtherA +>a : A +>a2 : OtherA + +a2 = a; +>a2 = a : A +>a2 : OtherA +>a : A + +b = b2; +>b = b2 : OtherB +>b : B +>b2 : OtherB + +b2 = b; +>b2 = b : B +>b2 : OtherB +>b : B + +a = b2; +>a = b2 : OtherB +>a : A +>b2 : OtherB + +b2 = a; +>b2 = a : A +>b2 : OtherB +>a : A + +b = a2; +>b = a2 : OtherA +>b : B +>a2 : OtherA + +a2 = b; +>a2 = b : B +>a2 : OtherA +>b : B + +=== tests/cases/conformance/pragma/strictNullChecks/file2.ts === +// loose +export interface A { + member?: string; +>member : string +} +export interface B { + member?: string | undefined; +>member : string +} + +let a: A = { member: undefined }; +>a : A +>{ member: undefined } : { member: undefined; } +>member : undefined +>undefined : undefined + +declare var b: B; +>b : B + +a = b; +>a = b : B +>a : A +>b : B + +b = a; +>b = a : A +>b : B +>a : A + +import {A as OtherA, B as OtherB} from "./file1"; +>A : any +>OtherA : any +>B : any +>OtherB : any + +let a2: OtherA = { member: undefined }; +>a2 : OtherA +>{ member: undefined } : { member: undefined; } +>member : undefined +>undefined : undefined + +declare var b2: OtherB; +>b2 : OtherB + +a2 = b2; +>a2 = b2 : OtherB +>a2 : OtherA +>b2 : OtherB + +b2 = a2; +>b2 = a2 : OtherA +>b2 : OtherB +>a2 : OtherA + +a = a2; +>a = a2 : OtherA +>a : A +>a2 : OtherA + +a2 = a; +>a2 = a : A +>a2 : OtherA +>a : A + +b = b2; +>b = b2 : OtherB +>b : B +>b2 : OtherB + +b2 = b; +>b2 = b : B +>b2 : OtherB +>b : B + +a = b2; +>a = b2 : OtherB +>a : A +>b2 : OtherB + +b2 = a; +>b2 = a : A +>b2 : OtherB +>a : A + +b = a2; +>b = a2 : OtherA +>b : B +>a2 : OtherA + +a2 = b; +>a2 = b : B +>a2 : OtherA +>b : B + +=== tests/cases/conformance/pragma/strictNullChecks/file3.ts === +// @ts-strictNullChecks +import {A, B} from "./file1"; +>A : any +>B : any + +import {A as A2, B as B2} from "./file2"; +>A : any +>A2 : any +>B : any +>B2 : any + +let a: A = { member: undefined }; +>a : A +>{ member: undefined } : { member: undefined; } +>member : undefined +>undefined : undefined + +let b: B = { member: undefined }; +>b : B +>{ member: undefined } : { member: undefined; } +>member : undefined +>undefined : undefined + +let a2: A2 = { member: undefined }; +>a2 : A2 +>{ member: undefined } : { member: undefined; } +>member : undefined +>undefined : undefined + +let b2: B2 = { member: undefined }; +>b2 : B2 +>{ member: undefined } : { member: undefined; } +>member : undefined +>undefined : undefined + +a = b; +>a = b : B +>a : A +>b : B + +b = a; +>b = a : A +>b : B +>a : A + +a2 = b2; +>a2 = b2 : B2 +>a2 : A2 +>b2 : B2 + +b2 = a2; +>b2 = a2 : A2 +>b2 : B2 +>a2 : A2 + +a = a2; +>a = a2 : A2 +>a : A +>a2 : A2 + +a2 = a; +>a2 = a : A +>a2 : A2 +>a : A + +b = b2; +>b = b2 : B2 +>b : B +>b2 : B2 + +b2 = b; +>b2 = b : B +>b2 : B2 +>b : B + +a = b2; +>a = b2 : B2 +>a : A +>b2 : B2 + +b2 = a; +>b2 = a : A +>b2 : B2 +>a : A + +b = a2; +>b = a2 : A2 +>b : B +>a2 : A2 + +a2 = b; +>a2 = b : B +>a2 : A2 +>b : B + +=== tests/cases/conformance/pragma/strictNullChecks/file4.ts === +// loose +import {A, B} from "./file1"; +>A : any +>B : any + +import {A as A2, B as B2} from "./file2"; +>A : any +>A2 : any +>B : any +>B2 : any + +let a: A = { member: undefined }; +>a : A +>{ member: undefined } : { member: undefined; } +>member : undefined +>undefined : undefined + +let b: B = { member: undefined }; +>b : B +>{ member: undefined } : { member: undefined; } +>member : undefined +>undefined : undefined + +let a2: A2 = { member: undefined }; +>a2 : A2 +>{ member: undefined } : { member: undefined; } +>member : undefined +>undefined : undefined + +let b2: B2 = { member: undefined }; +>b2 : B2 +>{ member: undefined } : { member: undefined; } +>member : undefined +>undefined : undefined + +a = b; +>a = b : B +>a : A +>b : B + +b = a; +>b = a : A +>b : B +>a : A + +a2 = b2; +>a2 = b2 : B2 +>a2 : A2 +>b2 : B2 + +b2 = a2; +>b2 = a2 : A2 +>b2 : B2 +>a2 : A2 + +a = a2; +>a = a2 : A2 +>a : A +>a2 : A2 + +a2 = a; +>a2 = a : A +>a2 : A2 +>a : A + +b = b2; +>b = b2 : B2 +>b : B +>b2 : B2 + +b2 = b; +>b2 = b : B +>b2 : B2 +>b : B + +a = b2; +>a = b2 : B2 +>a : A +>b2 : B2 + +b2 = a; +>b2 = a : A +>b2 : B2 +>a : A + +b = a2; +>b = a2 : A2 +>b : B +>a2 : A2 + +a2 = b; +>a2 = b : B +>a2 : A2 +>b : B + diff --git a/tests/baselines/reference/strictNullChecksPragma6.errors.txt b/tests/baselines/reference/strictNullChecksPragma6.errors.txt new file mode 100644 index 0000000000000..8fcdb47dc7cb1 --- /dev/null +++ b/tests/baselines/reference/strictNullChecksPragma6.errors.txt @@ -0,0 +1,205 @@ +tests/cases/conformance/pragma/strictNullChecks/file1.ts(15,20): error TS2322: Type 'undefined' is not assignable to type 'string'. +tests/cases/conformance/pragma/strictNullChecks/file1.ts(21,1): error TS2322: Type 'import("tests/cases/conformance/pragma/strictNullChecks/file1").A' is not assignable to type 'import("tests/cases/conformance/pragma/strictNullChecks/file2").A'. +tests/cases/conformance/pragma/strictNullChecks/file1.ts(24,1): error TS2322: Type 'import("tests/cases/conformance/pragma/strictNullChecks/file1").B' is not assignable to type 'import("tests/cases/conformance/pragma/strictNullChecks/file2").B'. +tests/cases/conformance/pragma/strictNullChecks/file1.ts(27,1): error TS2322: Type 'A' is not assignable to type 'B'. +tests/cases/conformance/pragma/strictNullChecks/file1.ts(30,1): error TS2322: Type 'B' is not assignable to type 'A'. +tests/cases/conformance/pragma/strictNullChecks/file2.ts(21,1): error TS2322: Type 'import("tests/cases/conformance/pragma/strictNullChecks/file1").A' is not assignable to type 'import("tests/cases/conformance/pragma/strictNullChecks/file2").A'. + Types of property 'member' are incompatible. + Type 'string | undefined' is not assignable to type 'string'. + Type 'undefined' is not assignable to type 'string'. +tests/cases/conformance/pragma/strictNullChecks/file2.ts(24,1): error TS2322: Type 'import("tests/cases/conformance/pragma/strictNullChecks/file1").B' is not assignable to type 'import("tests/cases/conformance/pragma/strictNullChecks/file2").B'. + Types of property 'member' are incompatible. + Type 'string | undefined' is not assignable to type 'string'. + Type 'undefined' is not assignable to type 'string'. +tests/cases/conformance/pragma/strictNullChecks/file2.ts(27,1): error TS2322: Type 'B' is not assignable to type 'A'. + Types of property 'member' are incompatible. + Type 'string | undefined' is not assignable to type 'string'. + Type 'undefined' is not assignable to type 'string'. +tests/cases/conformance/pragma/strictNullChecks/file2.ts(30,1): error TS2322: Type 'A' is not assignable to type 'B'. + Types of property 'member' are incompatible. + Type 'string | undefined' is not assignable to type 'string'. + Type 'undefined' is not assignable to type 'string'. +tests/cases/conformance/pragma/strictNullChecks/file3.ts(6,16): error TS2322: Type 'undefined' is not assignable to type 'string'. +tests/cases/conformance/pragma/strictNullChecks/file3.ts(7,16): error TS2322: Type 'undefined' is not assignable to type 'string'. +tests/cases/conformance/pragma/strictNullChecks/file3.ts(16,1): error TS2322: Type 'import("tests/cases/conformance/pragma/strictNullChecks/file1").A' is not assignable to type 'import("tests/cases/conformance/pragma/strictNullChecks/file2").A'. +tests/cases/conformance/pragma/strictNullChecks/file3.ts(19,1): error TS2322: Type 'import("tests/cases/conformance/pragma/strictNullChecks/file1").B' is not assignable to type 'import("tests/cases/conformance/pragma/strictNullChecks/file2").B'. +tests/cases/conformance/pragma/strictNullChecks/file3.ts(22,1): error TS2322: Type 'A' is not assignable to type 'B'. +tests/cases/conformance/pragma/strictNullChecks/file3.ts(25,1): error TS2322: Type 'B' is not assignable to type 'A'. +tests/cases/conformance/pragma/strictNullChecks/file4.ts(17,1): error TS2322: Type 'import("tests/cases/conformance/pragma/strictNullChecks/file1").A' is not assignable to type 'import("tests/cases/conformance/pragma/strictNullChecks/file2").A'. +tests/cases/conformance/pragma/strictNullChecks/file4.ts(20,1): error TS2322: Type 'import("tests/cases/conformance/pragma/strictNullChecks/file1").B' is not assignable to type 'import("tests/cases/conformance/pragma/strictNullChecks/file2").B'. +tests/cases/conformance/pragma/strictNullChecks/file4.ts(23,1): error TS2322: Type 'A' is not assignable to type 'B'. +tests/cases/conformance/pragma/strictNullChecks/file4.ts(26,1): error TS2322: Type 'B' is not assignable to type 'A'. + + +==== tests/cases/conformance/pragma/strictNullChecks/file1.ts (5 errors) ==== + export interface A { + member?: string; + } + export interface B { + member?: string | undefined; + } + + let a: A = { member: undefined }; + declare var b: B; + a = b; + b = a; + + import {A as OtherA, B as OtherB} from "./file2"; + + let a2: OtherA = { member: undefined }; + ~~~~~~ +!!! error TS2322: Type 'undefined' is not assignable to type 'string'. +!!! related TS6500 /.src/tests/cases/conformance/pragma/strictNullChecks/file2.ts:3:5: The expected type comes from property 'member' which is declared here on type 'A' + declare var b2: OtherB; + a2 = b2; + b2 = a2; + + a = a2; + a2 = a; + ~~ +!!! error TS2322: Type 'import("tests/cases/conformance/pragma/strictNullChecks/file1").A' is not assignable to type 'import("tests/cases/conformance/pragma/strictNullChecks/file2").A'. + + b = b2; + b2 = b; + ~~ +!!! error TS2322: Type 'import("tests/cases/conformance/pragma/strictNullChecks/file1").B' is not assignable to type 'import("tests/cases/conformance/pragma/strictNullChecks/file2").B'. + + a = b2; + b2 = a; + ~~ +!!! error TS2322: Type 'A' is not assignable to type 'B'. + + b = a2; + a2 = b; + ~~ +!!! error TS2322: Type 'B' is not assignable to type 'A'. + +==== tests/cases/conformance/pragma/strictNullChecks/file2.ts (4 errors) ==== + // @ts-strictNullChecks false + export interface A { + member?: string; + } + export interface B { + member?: string | undefined; + } + + let a: A = { member: undefined }; + declare var b: B; + a = b; + b = a; + + import {A as OtherA, B as OtherB} from "./file1"; + + let a2: OtherA = { member: undefined }; + declare var b2: OtherB; + a2 = b2; + b2 = a2; + + a = a2; + ~ +!!! error TS2322: Type 'import("tests/cases/conformance/pragma/strictNullChecks/file1").A' is not assignable to type 'import("tests/cases/conformance/pragma/strictNullChecks/file2").A'. +!!! error TS2322: Types of property 'member' are incompatible. +!!! error TS2322: Type 'string | undefined' is not assignable to type 'string'. +!!! error TS2322: Type 'undefined' is not assignable to type 'string'. + a2 = a; + + b = b2; + ~ +!!! error TS2322: Type 'import("tests/cases/conformance/pragma/strictNullChecks/file1").B' is not assignable to type 'import("tests/cases/conformance/pragma/strictNullChecks/file2").B'. +!!! error TS2322: Types of property 'member' are incompatible. +!!! error TS2322: Type 'string | undefined' is not assignable to type 'string'. +!!! error TS2322: Type 'undefined' is not assignable to type 'string'. + b2 = b; + + a = b2; + ~ +!!! error TS2322: Type 'B' is not assignable to type 'A'. +!!! error TS2322: Types of property 'member' are incompatible. +!!! error TS2322: Type 'string | undefined' is not assignable to type 'string'. +!!! error TS2322: Type 'undefined' is not assignable to type 'string'. + b2 = a; + + b = a2; + ~ +!!! error TS2322: Type 'A' is not assignable to type 'B'. +!!! error TS2322: Types of property 'member' are incompatible. +!!! error TS2322: Type 'string | undefined' is not assignable to type 'string'. +!!! error TS2322: Type 'undefined' is not assignable to type 'string'. + a2 = b; + +==== tests/cases/conformance/pragma/strictNullChecks/file3.ts (6 errors) ==== + import {A, B} from "./file1"; + import {A as A2, B as B2} from "./file2"; + + let a: A = { member: undefined }; + let b: B = { member: undefined }; + let a2: A2 = { member: undefined }; + ~~~~~~ +!!! error TS2322: Type 'undefined' is not assignable to type 'string'. +!!! related TS6500 /.src/tests/cases/conformance/pragma/strictNullChecks/file2.ts:3:5: The expected type comes from property 'member' which is declared here on type 'A' + let b2: B2 = { member: undefined }; + ~~~~~~ +!!! error TS2322: Type 'undefined' is not assignable to type 'string'. +!!! related TS6500 /.src/tests/cases/conformance/pragma/strictNullChecks/file2.ts:6:5: The expected type comes from property 'member' which is declared here on type 'B' + + a = b; + b = a; + + a2 = b2; + b2 = a2; + + a = a2; + a2 = a; + ~~ +!!! error TS2322: Type 'import("tests/cases/conformance/pragma/strictNullChecks/file1").A' is not assignable to type 'import("tests/cases/conformance/pragma/strictNullChecks/file2").A'. + + b = b2; + b2 = b; + ~~ +!!! error TS2322: Type 'import("tests/cases/conformance/pragma/strictNullChecks/file1").B' is not assignable to type 'import("tests/cases/conformance/pragma/strictNullChecks/file2").B'. + + a = b2; + b2 = a; + ~~ +!!! error TS2322: Type 'A' is not assignable to type 'B'. + + b = a2; + a2 = b; + ~~ +!!! error TS2322: Type 'B' is not assignable to type 'A'. + +==== tests/cases/conformance/pragma/strictNullChecks/file4.ts (4 errors) ==== + // @ts-strictNullChecks false + import {A, B} from "./file1"; + import {A as A2, B as B2} from "./file2"; + + let a: A = { member: undefined }; + let b: B = { member: undefined }; + let a2: A2 = { member: undefined }; + let b2: B2 = { member: undefined }; + + a = b; + b = a; + + a2 = b2; + b2 = a2; + + a = a2; + a2 = a; + ~~ +!!! error TS2322: Type 'import("tests/cases/conformance/pragma/strictNullChecks/file1").A' is not assignable to type 'import("tests/cases/conformance/pragma/strictNullChecks/file2").A'. + + b = b2; + b2 = b; + ~~ +!!! error TS2322: Type 'import("tests/cases/conformance/pragma/strictNullChecks/file1").B' is not assignable to type 'import("tests/cases/conformance/pragma/strictNullChecks/file2").B'. + + a = b2; + b2 = a; + ~~ +!!! error TS2322: Type 'A' is not assignable to type 'B'. + + b = a2; + a2 = b; + ~~ +!!! error TS2322: Type 'B' is not assignable to type 'A'. \ No newline at end of file diff --git a/tests/baselines/reference/strictNullChecksPragma6.js b/tests/baselines/reference/strictNullChecksPragma6.js new file mode 100644 index 0000000000000..5d06eb2def00c --- /dev/null +++ b/tests/baselines/reference/strictNullChecksPragma6.js @@ -0,0 +1,194 @@ +//// [tests/cases/conformance/pragma/strictNullChecks/strictNullChecksPragma6.ts] //// + +//// [file1.ts] +export interface A { + member?: string; +} +export interface B { + member?: string | undefined; +} + +let a: A = { member: undefined }; +declare var b: B; +a = b; +b = a; + +import {A as OtherA, B as OtherB} from "./file2"; + +let a2: OtherA = { member: undefined }; +declare var b2: OtherB; +a2 = b2; +b2 = a2; + +a = a2; +a2 = a; + +b = b2; +b2 = b; + +a = b2; +b2 = a; + +b = a2; +a2 = b; + +//// [file2.ts] +// @ts-strictNullChecks false +export interface A { + member?: string; +} +export interface B { + member?: string | undefined; +} + +let a: A = { member: undefined }; +declare var b: B; +a = b; +b = a; + +import {A as OtherA, B as OtherB} from "./file1"; + +let a2: OtherA = { member: undefined }; +declare var b2: OtherB; +a2 = b2; +b2 = a2; + +a = a2; +a2 = a; + +b = b2; +b2 = b; + +a = b2; +b2 = a; + +b = a2; +a2 = b; + +//// [file3.ts] +import {A, B} from "./file1"; +import {A as A2, B as B2} from "./file2"; + +let a: A = { member: undefined }; +let b: B = { member: undefined }; +let a2: A2 = { member: undefined }; +let b2: B2 = { member: undefined }; + +a = b; +b = a; + +a2 = b2; +b2 = a2; + +a = a2; +a2 = a; + +b = b2; +b2 = b; + +a = b2; +b2 = a; + +b = a2; +a2 = b; + +//// [file4.ts] +// @ts-strictNullChecks false +import {A, B} from "./file1"; +import {A as A2, B as B2} from "./file2"; + +let a: A = { member: undefined }; +let b: B = { member: undefined }; +let a2: A2 = { member: undefined }; +let b2: B2 = { member: undefined }; + +a = b; +b = a; + +a2 = b2; +b2 = a2; + +a = a2; +a2 = a; + +b = b2; +b2 = b; + +a = b2; +b2 = a; + +b = a2; +a2 = b; + +//// [file2.js] +"use strict"; +exports.__esModule = true; +var a = { member: undefined }; +a = b; +b = a; +var a2 = { member: undefined }; +a2 = b2; +b2 = a2; +a = a2; +a2 = a; +b = b2; +b2 = b; +a = b2; +b2 = a; +b = a2; +a2 = b; +//// [file1.js] +"use strict"; +exports.__esModule = true; +var a = { member: undefined }; +a = b; +b = a; +var a2 = { member: undefined }; +a2 = b2; +b2 = a2; +a = a2; +a2 = a; +b = b2; +b2 = b; +a = b2; +b2 = a; +b = a2; +a2 = b; +//// [file3.js] +"use strict"; +exports.__esModule = true; +var a = { member: undefined }; +var b = { member: undefined }; +var a2 = { member: undefined }; +var b2 = { member: undefined }; +a = b; +b = a; +a2 = b2; +b2 = a2; +a = a2; +a2 = a; +b = b2; +b2 = b; +a = b2; +b2 = a; +b = a2; +a2 = b; +//// [file4.js] +"use strict"; +exports.__esModule = true; +var a = { member: undefined }; +var b = { member: undefined }; +var a2 = { member: undefined }; +var b2 = { member: undefined }; +a = b; +b = a; +a2 = b2; +b2 = a2; +a = a2; +a2 = a; +b = b2; +b2 = b; +a = b2; +b2 = a; +b = a2; +a2 = b; diff --git a/tests/baselines/reference/strictNullChecksPragma6.symbols b/tests/baselines/reference/strictNullChecksPragma6.symbols new file mode 100644 index 0000000000000..7997849a8fa95 --- /dev/null +++ b/tests/baselines/reference/strictNullChecksPragma6.symbols @@ -0,0 +1,344 @@ +=== tests/cases/conformance/pragma/strictNullChecks/file1.ts === +export interface A { +>A : Symbol(A, Decl(file1.ts, 0, 0)) + + member?: string; +>member : Symbol(A.member, Decl(file1.ts, 0, 20)) +} +export interface B { +>B : Symbol(B, Decl(file1.ts, 2, 1)) + + member?: string | undefined; +>member : Symbol(B.member, Decl(file1.ts, 3, 20)) +} + +let a: A = { member: undefined }; +>a : Symbol(a, Decl(file1.ts, 7, 3)) +>A : Symbol(A, Decl(file1.ts, 0, 0)) +>member : Symbol(member, Decl(file1.ts, 7, 12)) +>undefined : Symbol(undefined) + +declare var b: B; +>b : Symbol(b, Decl(file1.ts, 8, 11)) +>B : Symbol(B, Decl(file1.ts, 2, 1)) + +a = b; +>a : Symbol(a, Decl(file1.ts, 7, 3)) +>b : Symbol(b, Decl(file1.ts, 8, 11)) + +b = a; +>b : Symbol(b, Decl(file1.ts, 8, 11)) +>a : Symbol(a, Decl(file1.ts, 7, 3)) + +import {A as OtherA, B as OtherB} from "./file2"; +>A : Symbol(OtherA, Decl(file2.ts, 0, 0)) +>OtherA : Symbol(OtherA, Decl(file1.ts, 12, 8)) +>B : Symbol(OtherB, Decl(file2.ts, 3, 1)) +>OtherB : Symbol(OtherB, Decl(file1.ts, 12, 20)) + +let a2: OtherA = { member: undefined }; +>a2 : Symbol(a2, Decl(file1.ts, 14, 3)) +>OtherA : Symbol(OtherA, Decl(file1.ts, 12, 8)) +>member : Symbol(member, Decl(file1.ts, 14, 18)) +>undefined : Symbol(undefined) + +declare var b2: OtherB; +>b2 : Symbol(b2, Decl(file1.ts, 15, 11)) +>OtherB : Symbol(OtherB, Decl(file1.ts, 12, 20)) + +a2 = b2; +>a2 : Symbol(a2, Decl(file1.ts, 14, 3)) +>b2 : Symbol(b2, Decl(file1.ts, 15, 11)) + +b2 = a2; +>b2 : Symbol(b2, Decl(file1.ts, 15, 11)) +>a2 : Symbol(a2, Decl(file1.ts, 14, 3)) + +a = a2; +>a : Symbol(a, Decl(file1.ts, 7, 3)) +>a2 : Symbol(a2, Decl(file1.ts, 14, 3)) + +a2 = a; +>a2 : Symbol(a2, Decl(file1.ts, 14, 3)) +>a : Symbol(a, Decl(file1.ts, 7, 3)) + +b = b2; +>b : Symbol(b, Decl(file1.ts, 8, 11)) +>b2 : Symbol(b2, Decl(file1.ts, 15, 11)) + +b2 = b; +>b2 : Symbol(b2, Decl(file1.ts, 15, 11)) +>b : Symbol(b, Decl(file1.ts, 8, 11)) + +a = b2; +>a : Symbol(a, Decl(file1.ts, 7, 3)) +>b2 : Symbol(b2, Decl(file1.ts, 15, 11)) + +b2 = a; +>b2 : Symbol(b2, Decl(file1.ts, 15, 11)) +>a : Symbol(a, Decl(file1.ts, 7, 3)) + +b = a2; +>b : Symbol(b, Decl(file1.ts, 8, 11)) +>a2 : Symbol(a2, Decl(file1.ts, 14, 3)) + +a2 = b; +>a2 : Symbol(a2, Decl(file1.ts, 14, 3)) +>b : Symbol(b, Decl(file1.ts, 8, 11)) + +=== tests/cases/conformance/pragma/strictNullChecks/file2.ts === +// @ts-strictNullChecks false +export interface A { +>A : Symbol(A, Decl(file2.ts, 0, 0)) + + member?: string; +>member : Symbol(A.member, Decl(file2.ts, 1, 20)) +} +export interface B { +>B : Symbol(B, Decl(file2.ts, 3, 1)) + + member?: string | undefined; +>member : Symbol(B.member, Decl(file2.ts, 4, 20)) +} + +let a: A = { member: undefined }; +>a : Symbol(a, Decl(file2.ts, 8, 3)) +>A : Symbol(A, Decl(file2.ts, 0, 0)) +>member : Symbol(member, Decl(file2.ts, 8, 12)) +>undefined : Symbol(undefined) + +declare var b: B; +>b : Symbol(b, Decl(file2.ts, 9, 11)) +>B : Symbol(B, Decl(file2.ts, 3, 1)) + +a = b; +>a : Symbol(a, Decl(file2.ts, 8, 3)) +>b : Symbol(b, Decl(file2.ts, 9, 11)) + +b = a; +>b : Symbol(b, Decl(file2.ts, 9, 11)) +>a : Symbol(a, Decl(file2.ts, 8, 3)) + +import {A as OtherA, B as OtherB} from "./file1"; +>A : Symbol(OtherA, Decl(file1.ts, 0, 0)) +>OtherA : Symbol(OtherA, Decl(file2.ts, 13, 8)) +>B : Symbol(OtherB, Decl(file1.ts, 2, 1)) +>OtherB : Symbol(OtherB, Decl(file2.ts, 13, 20)) + +let a2: OtherA = { member: undefined }; +>a2 : Symbol(a2, Decl(file2.ts, 15, 3)) +>OtherA : Symbol(OtherA, Decl(file2.ts, 13, 8)) +>member : Symbol(member, Decl(file2.ts, 15, 18)) +>undefined : Symbol(undefined) + +declare var b2: OtherB; +>b2 : Symbol(b2, Decl(file2.ts, 16, 11)) +>OtherB : Symbol(OtherB, Decl(file2.ts, 13, 20)) + +a2 = b2; +>a2 : Symbol(a2, Decl(file2.ts, 15, 3)) +>b2 : Symbol(b2, Decl(file2.ts, 16, 11)) + +b2 = a2; +>b2 : Symbol(b2, Decl(file2.ts, 16, 11)) +>a2 : Symbol(a2, Decl(file2.ts, 15, 3)) + +a = a2; +>a : Symbol(a, Decl(file2.ts, 8, 3)) +>a2 : Symbol(a2, Decl(file2.ts, 15, 3)) + +a2 = a; +>a2 : Symbol(a2, Decl(file2.ts, 15, 3)) +>a : Symbol(a, Decl(file2.ts, 8, 3)) + +b = b2; +>b : Symbol(b, Decl(file2.ts, 9, 11)) +>b2 : Symbol(b2, Decl(file2.ts, 16, 11)) + +b2 = b; +>b2 : Symbol(b2, Decl(file2.ts, 16, 11)) +>b : Symbol(b, Decl(file2.ts, 9, 11)) + +a = b2; +>a : Symbol(a, Decl(file2.ts, 8, 3)) +>b2 : Symbol(b2, Decl(file2.ts, 16, 11)) + +b2 = a; +>b2 : Symbol(b2, Decl(file2.ts, 16, 11)) +>a : Symbol(a, Decl(file2.ts, 8, 3)) + +b = a2; +>b : Symbol(b, Decl(file2.ts, 9, 11)) +>a2 : Symbol(a2, Decl(file2.ts, 15, 3)) + +a2 = b; +>a2 : Symbol(a2, Decl(file2.ts, 15, 3)) +>b : Symbol(b, Decl(file2.ts, 9, 11)) + +=== tests/cases/conformance/pragma/strictNullChecks/file3.ts === +import {A, B} from "./file1"; +>A : Symbol(A, Decl(file3.ts, 0, 8)) +>B : Symbol(B, Decl(file3.ts, 0, 10)) + +import {A as A2, B as B2} from "./file2"; +>A : Symbol(A2, Decl(file2.ts, 0, 0)) +>A2 : Symbol(A2, Decl(file3.ts, 1, 8)) +>B : Symbol(B2, Decl(file2.ts, 3, 1)) +>B2 : Symbol(B2, Decl(file3.ts, 1, 16)) + +let a: A = { member: undefined }; +>a : Symbol(a, Decl(file3.ts, 3, 3)) +>A : Symbol(A, Decl(file3.ts, 0, 8)) +>member : Symbol(member, Decl(file3.ts, 3, 12)) +>undefined : Symbol(undefined) + +let b: B = { member: undefined }; +>b : Symbol(b, Decl(file3.ts, 4, 3)) +>B : Symbol(B, Decl(file3.ts, 0, 10)) +>member : Symbol(member, Decl(file3.ts, 4, 12)) +>undefined : Symbol(undefined) + +let a2: A2 = { member: undefined }; +>a2 : Symbol(a2, Decl(file3.ts, 5, 3)) +>A2 : Symbol(A2, Decl(file3.ts, 1, 8)) +>member : Symbol(member, Decl(file3.ts, 5, 14)) +>undefined : Symbol(undefined) + +let b2: B2 = { member: undefined }; +>b2 : Symbol(b2, Decl(file3.ts, 6, 3)) +>B2 : Symbol(B2, Decl(file3.ts, 1, 16)) +>member : Symbol(member, Decl(file3.ts, 6, 14)) +>undefined : Symbol(undefined) + +a = b; +>a : Symbol(a, Decl(file3.ts, 3, 3)) +>b : Symbol(b, Decl(file3.ts, 4, 3)) + +b = a; +>b : Symbol(b, Decl(file3.ts, 4, 3)) +>a : Symbol(a, Decl(file3.ts, 3, 3)) + +a2 = b2; +>a2 : Symbol(a2, Decl(file3.ts, 5, 3)) +>b2 : Symbol(b2, Decl(file3.ts, 6, 3)) + +b2 = a2; +>b2 : Symbol(b2, Decl(file3.ts, 6, 3)) +>a2 : Symbol(a2, Decl(file3.ts, 5, 3)) + +a = a2; +>a : Symbol(a, Decl(file3.ts, 3, 3)) +>a2 : Symbol(a2, Decl(file3.ts, 5, 3)) + +a2 = a; +>a2 : Symbol(a2, Decl(file3.ts, 5, 3)) +>a : Symbol(a, Decl(file3.ts, 3, 3)) + +b = b2; +>b : Symbol(b, Decl(file3.ts, 4, 3)) +>b2 : Symbol(b2, Decl(file3.ts, 6, 3)) + +b2 = b; +>b2 : Symbol(b2, Decl(file3.ts, 6, 3)) +>b : Symbol(b, Decl(file3.ts, 4, 3)) + +a = b2; +>a : Symbol(a, Decl(file3.ts, 3, 3)) +>b2 : Symbol(b2, Decl(file3.ts, 6, 3)) + +b2 = a; +>b2 : Symbol(b2, Decl(file3.ts, 6, 3)) +>a : Symbol(a, Decl(file3.ts, 3, 3)) + +b = a2; +>b : Symbol(b, Decl(file3.ts, 4, 3)) +>a2 : Symbol(a2, Decl(file3.ts, 5, 3)) + +a2 = b; +>a2 : Symbol(a2, Decl(file3.ts, 5, 3)) +>b : Symbol(b, Decl(file3.ts, 4, 3)) + +=== tests/cases/conformance/pragma/strictNullChecks/file4.ts === +// @ts-strictNullChecks false +import {A, B} from "./file1"; +>A : Symbol(A, Decl(file4.ts, 1, 8)) +>B : Symbol(B, Decl(file4.ts, 1, 10)) + +import {A as A2, B as B2} from "./file2"; +>A : Symbol(A2, Decl(file2.ts, 0, 0)) +>A2 : Symbol(A2, Decl(file4.ts, 2, 8)) +>B : Symbol(B2, Decl(file2.ts, 3, 1)) +>B2 : Symbol(B2, Decl(file4.ts, 2, 16)) + +let a: A = { member: undefined }; +>a : Symbol(a, Decl(file4.ts, 4, 3)) +>A : Symbol(A, Decl(file4.ts, 1, 8)) +>member : Symbol(member, Decl(file4.ts, 4, 12)) +>undefined : Symbol(undefined) + +let b: B = { member: undefined }; +>b : Symbol(b, Decl(file4.ts, 5, 3)) +>B : Symbol(B, Decl(file4.ts, 1, 10)) +>member : Symbol(member, Decl(file4.ts, 5, 12)) +>undefined : Symbol(undefined) + +let a2: A2 = { member: undefined }; +>a2 : Symbol(a2, Decl(file4.ts, 6, 3)) +>A2 : Symbol(A2, Decl(file4.ts, 2, 8)) +>member : Symbol(member, Decl(file4.ts, 6, 14)) +>undefined : Symbol(undefined) + +let b2: B2 = { member: undefined }; +>b2 : Symbol(b2, Decl(file4.ts, 7, 3)) +>B2 : Symbol(B2, Decl(file4.ts, 2, 16)) +>member : Symbol(member, Decl(file4.ts, 7, 14)) +>undefined : Symbol(undefined) + +a = b; +>a : Symbol(a, Decl(file4.ts, 4, 3)) +>b : Symbol(b, Decl(file4.ts, 5, 3)) + +b = a; +>b : Symbol(b, Decl(file4.ts, 5, 3)) +>a : Symbol(a, Decl(file4.ts, 4, 3)) + +a2 = b2; +>a2 : Symbol(a2, Decl(file4.ts, 6, 3)) +>b2 : Symbol(b2, Decl(file4.ts, 7, 3)) + +b2 = a2; +>b2 : Symbol(b2, Decl(file4.ts, 7, 3)) +>a2 : Symbol(a2, Decl(file4.ts, 6, 3)) + +a = a2; +>a : Symbol(a, Decl(file4.ts, 4, 3)) +>a2 : Symbol(a2, Decl(file4.ts, 6, 3)) + +a2 = a; +>a2 : Symbol(a2, Decl(file4.ts, 6, 3)) +>a : Symbol(a, Decl(file4.ts, 4, 3)) + +b = b2; +>b : Symbol(b, Decl(file4.ts, 5, 3)) +>b2 : Symbol(b2, Decl(file4.ts, 7, 3)) + +b2 = b; +>b2 : Symbol(b2, Decl(file4.ts, 7, 3)) +>b : Symbol(b, Decl(file4.ts, 5, 3)) + +a = b2; +>a : Symbol(a, Decl(file4.ts, 4, 3)) +>b2 : Symbol(b2, Decl(file4.ts, 7, 3)) + +b2 = a; +>b2 : Symbol(b2, Decl(file4.ts, 7, 3)) +>a : Symbol(a, Decl(file4.ts, 4, 3)) + +b = a2; +>b : Symbol(b, Decl(file4.ts, 5, 3)) +>a2 : Symbol(a2, Decl(file4.ts, 6, 3)) + +a2 = b; +>a2 : Symbol(a2, Decl(file4.ts, 6, 3)) +>b : Symbol(b, Decl(file4.ts, 5, 3)) + diff --git a/tests/baselines/reference/strictNullChecksPragma6.types b/tests/baselines/reference/strictNullChecksPragma6.types new file mode 100644 index 0000000000000..802d83f155afe --- /dev/null +++ b/tests/baselines/reference/strictNullChecksPragma6.types @@ -0,0 +1,380 @@ +=== tests/cases/conformance/pragma/strictNullChecks/file1.ts === +export interface A { + member?: string; +>member : string | undefined +} +export interface B { + member?: string | undefined; +>member : string | undefined +} + +let a: A = { member: undefined }; +>a : A +>{ member: undefined } : { member: undefined; } +>member : undefined +>undefined : undefined + +declare var b: B; +>b : B + +a = b; +>a = b : B +>a : A +>b : B + +b = a; +>b = a : A +>b : B +>a : A + +import {A as OtherA, B as OtherB} from "./file2"; +>A : any +>OtherA : any +>B : any +>OtherB : any + +let a2: OtherA = { member: undefined }; +>a2 : OtherA +>{ member: undefined } : { member: undefined; } +>member : undefined +>undefined : undefined + +declare var b2: OtherB; +>b2 : OtherB + +a2 = b2; +>a2 = b2 : OtherB +>a2 : OtherA +>b2 : OtherB + +b2 = a2; +>b2 = a2 : OtherA +>b2 : OtherB +>a2 : OtherA + +a = a2; +>a = a2 : OtherA +>a : A +>a2 : OtherA + +a2 = a; +>a2 = a : A +>a2 : OtherA +>a : A + +b = b2; +>b = b2 : OtherB +>b : B +>b2 : OtherB + +b2 = b; +>b2 = b : B +>b2 : OtherB +>b : B + +a = b2; +>a = b2 : OtherB +>a : A +>b2 : OtherB + +b2 = a; +>b2 = a : A +>b2 : OtherB +>a : A + +b = a2; +>b = a2 : OtherA +>b : B +>a2 : OtherA + +a2 = b; +>a2 = b : B +>a2 : OtherA +>b : B + +=== tests/cases/conformance/pragma/strictNullChecks/file2.ts === +// @ts-strictNullChecks false +export interface A { + member?: string; +>member : string +} +export interface B { + member?: string | undefined; +>member : string +} + +let a: A = { member: undefined }; +>a : A +>{ member: undefined } : { member: undefined; } +>member : undefined +>undefined : undefined + +declare var b: B; +>b : B + +a = b; +>a = b : B +>a : A +>b : B + +b = a; +>b = a : A +>b : B +>a : A + +import {A as OtherA, B as OtherB} from "./file1"; +>A : any +>OtherA : any +>B : any +>OtherB : any + +let a2: OtherA = { member: undefined }; +>a2 : OtherA +>{ member: undefined } : { member: undefined; } +>member : undefined +>undefined : undefined + +declare var b2: OtherB; +>b2 : OtherB + +a2 = b2; +>a2 = b2 : OtherB +>a2 : OtherA +>b2 : OtherB + +b2 = a2; +>b2 = a2 : OtherA +>b2 : OtherB +>a2 : OtherA + +a = a2; +>a = a2 : OtherA +>a : A +>a2 : OtherA + +a2 = a; +>a2 = a : A +>a2 : OtherA +>a : A + +b = b2; +>b = b2 : OtherB +>b : B +>b2 : OtherB + +b2 = b; +>b2 = b : B +>b2 : OtherB +>b : B + +a = b2; +>a = b2 : OtherB +>a : A +>b2 : OtherB + +b2 = a; +>b2 = a : A +>b2 : OtherB +>a : A + +b = a2; +>b = a2 : OtherA +>b : B +>a2 : OtherA + +a2 = b; +>a2 = b : B +>a2 : OtherA +>b : B + +=== tests/cases/conformance/pragma/strictNullChecks/file3.ts === +import {A, B} from "./file1"; +>A : any +>B : any + +import {A as A2, B as B2} from "./file2"; +>A : any +>A2 : any +>B : any +>B2 : any + +let a: A = { member: undefined }; +>a : A +>{ member: undefined } : { member: undefined; } +>member : undefined +>undefined : undefined + +let b: B = { member: undefined }; +>b : B +>{ member: undefined } : { member: undefined; } +>member : undefined +>undefined : undefined + +let a2: A2 = { member: undefined }; +>a2 : A2 +>{ member: undefined } : { member: undefined; } +>member : undefined +>undefined : undefined + +let b2: B2 = { member: undefined }; +>b2 : B2 +>{ member: undefined } : { member: undefined; } +>member : undefined +>undefined : undefined + +a = b; +>a = b : B +>a : A +>b : B + +b = a; +>b = a : A +>b : B +>a : A + +a2 = b2; +>a2 = b2 : B2 +>a2 : A2 +>b2 : B2 + +b2 = a2; +>b2 = a2 : A2 +>b2 : B2 +>a2 : A2 + +a = a2; +>a = a2 : A2 +>a : A +>a2 : A2 + +a2 = a; +>a2 = a : A +>a2 : A2 +>a : A + +b = b2; +>b = b2 : B2 +>b : B +>b2 : B2 + +b2 = b; +>b2 = b : B +>b2 : B2 +>b : B + +a = b2; +>a = b2 : B2 +>a : A +>b2 : B2 + +b2 = a; +>b2 = a : A +>b2 : B2 +>a : A + +b = a2; +>b = a2 : A2 +>b : B +>a2 : A2 + +a2 = b; +>a2 = b : B +>a2 : A2 +>b : B + +=== tests/cases/conformance/pragma/strictNullChecks/file4.ts === +// @ts-strictNullChecks false +import {A, B} from "./file1"; +>A : any +>B : any + +import {A as A2, B as B2} from "./file2"; +>A : any +>A2 : any +>B : any +>B2 : any + +let a: A = { member: undefined }; +>a : A +>{ member: undefined } : { member: undefined; } +>member : undefined +>undefined : undefined + +let b: B = { member: undefined }; +>b : B +>{ member: undefined } : { member: undefined; } +>member : undefined +>undefined : undefined + +let a2: A2 = { member: undefined }; +>a2 : A2 +>{ member: undefined } : { member: undefined; } +>member : undefined +>undefined : undefined + +let b2: B2 = { member: undefined }; +>b2 : B2 +>{ member: undefined } : { member: undefined; } +>member : undefined +>undefined : undefined + +a = b; +>a = b : B +>a : A +>b : B + +b = a; +>b = a : A +>b : B +>a : A + +a2 = b2; +>a2 = b2 : B2 +>a2 : A2 +>b2 : B2 + +b2 = a2; +>b2 = a2 : A2 +>b2 : B2 +>a2 : A2 + +a = a2; +>a = a2 : A2 +>a : A +>a2 : A2 + +a2 = a; +>a2 = a : A +>a2 : A2 +>a : A + +b = b2; +>b = b2 : B2 +>b : B +>b2 : B2 + +b2 = b; +>b2 = b : B +>b2 : B2 +>b : B + +a = b2; +>a = b2 : B2 +>a : A +>b2 : B2 + +b2 = a; +>b2 = a : A +>b2 : B2 +>a : A + +b = a2; +>b = a2 : A2 +>b : B +>a2 : A2 + +a2 = b; +>a2 = b : B +>a2 : A2 +>b : B + diff --git a/tests/cases/conformance/pragma/strictNullChecks/strictNullChecksPragma1.ts b/tests/cases/conformance/pragma/strictNullChecks/strictNullChecksPragma1.ts new file mode 100644 index 0000000000000..25436e9e7458c --- /dev/null +++ b/tests/cases/conformance/pragma/strictNullChecks/strictNullChecksPragma1.ts @@ -0,0 +1,122 @@ +// @strict: false +// @filename: file1.ts +// @ts-strictNullChecks +export interface A { + member: string; +} +export interface B { + member: string | undefined; +} + +let a: A = { member: undefined }; +declare var b: B; +a = b; +b = a; + +import {A as OtherA, B as OtherB} from "./file2"; + +let a2: OtherA = { member: undefined }; +declare var b2: OtherB; +a2 = b2; +b2 = a2; + +a = a2; +a2 = a; + +b = b2; +b2 = b; + +a = b2; +b2 = a; + +b = a2; +a2 = b; + +// @filename: file2.ts +// loose +export interface A { + member: string; +} +export interface B { + member: string | undefined; +} + +let a: A = { member: undefined }; +declare var b: B; +a = b; +b = a; + +import {A as OtherA, B as OtherB} from "./file1"; + +let a2: OtherA = { member: undefined }; +declare var b2: OtherB; +a2 = b2; +b2 = a2; + +a = a2; +a2 = a; + +b = b2; +b2 = b; + +a = b2; +b2 = a; + +b = a2; +a2 = b; + +// @filename: file3.ts +// @ts-strictNullChecks +import {A, B} from "./file1"; +import {A as A2, B as B2} from "./file2"; + +let a: A = { member: undefined }; +let b: B = { member: undefined }; +let a2: A2 = { member: undefined }; +let b2: B2 = { member: undefined }; + +a = b; +b = a; + +a2 = b2; +b2 = a2; + +a = a2; +a2 = a; + +b = b2; +b2 = b; + +a = b2; +b2 = a; + +b = a2; +a2 = b; + +// @filename: file4.ts +// loose +import {A, B} from "./file1"; +import {A as A2, B as B2} from "./file2"; + +let a: A = { member: undefined }; +let b: B = { member: undefined }; +let a2: A2 = { member: undefined }; +let b2: B2 = { member: undefined }; + +a = b; +b = a; + +a2 = b2; +b2 = a2; + +a = a2; +a2 = a; + +b = b2; +b2 = b; + +a = b2; +b2 = a; + +b = a2; +a2 = b; \ No newline at end of file diff --git a/tests/cases/conformance/pragma/strictNullChecks/strictNullChecksPragma2.ts b/tests/cases/conformance/pragma/strictNullChecks/strictNullChecksPragma2.ts new file mode 100644 index 0000000000000..9a9e6e0b3bfdd --- /dev/null +++ b/tests/cases/conformance/pragma/strictNullChecks/strictNullChecksPragma2.ts @@ -0,0 +1,120 @@ +// @strict: true +// @filename: file1.ts +export interface A { + member: string; +} +export interface B { + member: string | undefined; +} + +let a: A = { member: undefined }; +declare var b: B; +a = b; +b = a; + +import {A as OtherA, B as OtherB} from "./file2"; + +let a2: OtherA = { member: undefined }; +declare var b2: OtherB; +a2 = b2; +b2 = a2; + +a = a2; +a2 = a; + +b = b2; +b2 = b; + +a = b2; +b2 = a; + +b = a2; +a2 = b; + +// @filename: file2.ts +// @ts-strictNullChecks false +export interface A { + member: string; +} +export interface B { + member: string | undefined; +} + +let a: A = { member: undefined }; +declare var b: B; +a = b; +b = a; + +import {A as OtherA, B as OtherB} from "./file1"; + +let a2: OtherA = { member: undefined }; +declare var b2: OtherB; +a2 = b2; +b2 = a2; + +a = a2; +a2 = a; + +b = b2; +b2 = b; + +a = b2; +b2 = a; + +b = a2; +a2 = b; + +// @filename: file3.ts +import {A, B} from "./file1"; +import {A as A2, B as B2} from "./file2"; + +let a: A = { member: undefined }; +let b: B = { member: undefined }; +let a2: A2 = { member: undefined }; +let b2: B2 = { member: undefined }; + +a = b; +b = a; + +a2 = b2; +b2 = a2; + +a = a2; +a2 = a; + +b = b2; +b2 = b; + +a = b2; +b2 = a; + +b = a2; +a2 = b; + +// @filename: file4.ts +// @ts-strictNullChecks false +import {A, B} from "./file1"; +import {A as A2, B as B2} from "./file2"; + +let a: A = { member: undefined }; +let b: B = { member: undefined }; +let a2: A2 = { member: undefined }; +let b2: B2 = { member: undefined }; + +a = b; +b = a; + +a2 = b2; +b2 = a2; + +a = a2; +a2 = a; + +b = b2; +b2 = b; + +a = b2; +b2 = a; + +b = a2; +a2 = b; \ No newline at end of file diff --git a/tests/cases/conformance/pragma/strictNullChecks/strictNullChecksPragma3.ts b/tests/cases/conformance/pragma/strictNullChecks/strictNullChecksPragma3.ts new file mode 100644 index 0000000000000..a6507cefa2bfb --- /dev/null +++ b/tests/cases/conformance/pragma/strictNullChecks/strictNullChecksPragma3.ts @@ -0,0 +1,122 @@ +// @strict: false +// @filename: file1.ts +// @ts-strictNullChecks +export interface A { + member: number; +} +export interface B { + member: undefined; +} + +let a: A = { member: undefined }; +let b: B = { member: undefined }; +a = b; +b = a; + +import {A as OtherA, B as OtherB} from "./file2"; + +let a2: OtherA = { member: undefined }; +declare var b2: OtherB; +a2 = b2; +b2 = a2; + +a = a2; +a2 = a; + +b = b2; +b2 = b; + +a = b2; +b2 = a; + +b = a2; +a2 = b; + +// @filename: file2.ts +// loose +export interface A { + member: number; +} +export interface B { + member: undefined; +} + +let a: A = { member: undefined }; +let b: B = { member: undefined }; +a = b; +b = a; // Historic behavior is that most things aren't assignable to `undefined` when it doesn't evaporate, even outside `strict` mode - making it more like a special `never` than an `any`. + +import {A as OtherA, B as OtherB} from "./file1"; + +let a2: OtherA = { member: undefined }; +declare var b2: OtherB; +a2 = b2; +b2 = a2; + +a = a2; +a2 = a; + +b = b2; +b2 = b; + +a = b2; +b2 = a; + +b = a2; +a2 = b; + +// @filename: file3.ts +// @ts-strictNullChecks +import {A, B} from "./file1"; +import {A as A2, B as B2} from "./file2"; + +let a: A = { member: undefined }; +let b: B = { member: undefined }; +let a2: A2 = { member: undefined }; +let b2: B2 = { member: undefined }; + +a = b; +b = a; + +a2 = b2; +b2 = a2; + +a = a2; +a2 = a; + +b = b2; +b2 = b; + +a = b2; +b2 = a; + +b = a2; +a2 = b; + +// @filename: file4.ts +// loose +import {A, B} from "./file1"; +import {A as A2, B as B2} from "./file2"; + +let a: A = { member: undefined }; +let b: B = { member: undefined }; +let a2: A2 = { member: undefined }; +let b2: B2 = { member: undefined }; + +a = b; +b = a; + +a2 = b2; +b2 = a2; + +a = a2; +a2 = a; + +b = b2; +b2 = b; + +a = b2; +b2 = a; + +b = a2; +a2 = b; \ No newline at end of file diff --git a/tests/cases/conformance/pragma/strictNullChecks/strictNullChecksPragma4.ts b/tests/cases/conformance/pragma/strictNullChecks/strictNullChecksPragma4.ts new file mode 100644 index 0000000000000..16875c70c1ee1 --- /dev/null +++ b/tests/cases/conformance/pragma/strictNullChecks/strictNullChecksPragma4.ts @@ -0,0 +1,120 @@ +// @strict: true +// @filename: file1.ts +export interface A { + member: number; +} +export interface B { + member: undefined; +} + +let a: A = { member: undefined }; +let b: B = { member: undefined }; +a = b; +b = a; + +import {A as OtherA, B as OtherB} from "./file2"; + +let a2: OtherA = { member: undefined }; +declare var b2: OtherB; +a2 = b2; +b2 = a2; + +a = a2; +a2 = a; + +b = b2; +b2 = b; + +a = b2; +b2 = a; + +b = a2; +a2 = b; + +// @filename: file2.ts +// @ts-strictNullChecks false +export interface A { + member: number; +} +export interface B { + member: undefined; +} + +let a: A = { member: undefined }; +let b: B = { member: undefined }; +a = b; +b = a; // Historic behavior is that most things aren't assignable to `undefined` when it doesn't evaporate, even outside `strict` mode - making it more like a special `never` than an `any`. + +import {A as OtherA, B as OtherB} from "./file1"; + +let a2: OtherA = { member: undefined }; +declare var b2: OtherB; +a2 = b2; +b2 = a2; + +a = a2; +a2 = a; + +b = b2; +b2 = b; + +a = b2; +b2 = a; + +b = a2; +a2 = b; + +// @filename: file3.ts +import {A, B} from "./file1"; +import {A as A2, B as B2} from "./file2"; + +let a: A = { member: undefined }; +let b: B = { member: undefined }; +let a2: A2 = { member: undefined }; +let b2: B2 = { member: undefined }; + +a = b; +b = a; + +a2 = b2; +b2 = a2; + +a = a2; +a2 = a; + +b = b2; +b2 = b; + +a = b2; +b2 = a; + +b = a2; +a2 = b; + +// @filename: file4.ts +// @ts-strictNullChecks false +import {A, B} from "./file1"; +import {A as A2, B as B2} from "./file2"; + +let a: A = { member: undefined }; +let b: B = { member: undefined }; +let a2: A2 = { member: undefined }; +let b2: B2 = { member: undefined }; + +a = b; +b = a; + +a2 = b2; +b2 = a2; + +a = a2; +a2 = a; + +b = b2; +b2 = b; + +a = b2; +b2 = a; + +b = a2; +a2 = b; \ No newline at end of file diff --git a/tests/cases/conformance/pragma/strictNullChecks/strictNullChecksPragma5.ts b/tests/cases/conformance/pragma/strictNullChecks/strictNullChecksPragma5.ts new file mode 100644 index 0000000000000..141e9dc10d7ff --- /dev/null +++ b/tests/cases/conformance/pragma/strictNullChecks/strictNullChecksPragma5.ts @@ -0,0 +1,122 @@ +// @strict: false +// @filename: file1.ts +// @ts-strictNullChecks +export interface A { + member?: string; +} +export interface B { + member?: string | undefined; +} + +let a: A = { member: undefined }; +declare var b: B; +a = b; +b = a; + +import {A as OtherA, B as OtherB} from "./file2"; + +let a2: OtherA = { member: undefined }; +declare var b2: OtherB; +a2 = b2; +b2 = a2; + +a = a2; +a2 = a; + +b = b2; +b2 = b; + +a = b2; +b2 = a; + +b = a2; +a2 = b; + +// @filename: file2.ts +// loose +export interface A { + member?: string; +} +export interface B { + member?: string | undefined; +} + +let a: A = { member: undefined }; +declare var b: B; +a = b; +b = a; + +import {A as OtherA, B as OtherB} from "./file1"; + +let a2: OtherA = { member: undefined }; +declare var b2: OtherB; +a2 = b2; +b2 = a2; + +a = a2; +a2 = a; + +b = b2; +b2 = b; + +a = b2; +b2 = a; + +b = a2; +a2 = b; + +// @filename: file3.ts +// @ts-strictNullChecks +import {A, B} from "./file1"; +import {A as A2, B as B2} from "./file2"; + +let a: A = { member: undefined }; +let b: B = { member: undefined }; +let a2: A2 = { member: undefined }; +let b2: B2 = { member: undefined }; + +a = b; +b = a; + +a2 = b2; +b2 = a2; + +a = a2; +a2 = a; + +b = b2; +b2 = b; + +a = b2; +b2 = a; + +b = a2; +a2 = b; + +// @filename: file4.ts +// loose +import {A, B} from "./file1"; +import {A as A2, B as B2} from "./file2"; + +let a: A = { member: undefined }; +let b: B = { member: undefined }; +let a2: A2 = { member: undefined }; +let b2: B2 = { member: undefined }; + +a = b; +b = a; + +a2 = b2; +b2 = a2; + +a = a2; +a2 = a; + +b = b2; +b2 = b; + +a = b2; +b2 = a; + +b = a2; +a2 = b; \ No newline at end of file diff --git a/tests/cases/conformance/pragma/strictNullChecks/strictNullChecksPragma6.ts b/tests/cases/conformance/pragma/strictNullChecks/strictNullChecksPragma6.ts new file mode 100644 index 0000000000000..680bf72c1816b --- /dev/null +++ b/tests/cases/conformance/pragma/strictNullChecks/strictNullChecksPragma6.ts @@ -0,0 +1,120 @@ +// @strict: true +// @filename: file1.ts +export interface A { + member?: string; +} +export interface B { + member?: string | undefined; +} + +let a: A = { member: undefined }; +declare var b: B; +a = b; +b = a; + +import {A as OtherA, B as OtherB} from "./file2"; + +let a2: OtherA = { member: undefined }; +declare var b2: OtherB; +a2 = b2; +b2 = a2; + +a = a2; +a2 = a; + +b = b2; +b2 = b; + +a = b2; +b2 = a; + +b = a2; +a2 = b; + +// @filename: file2.ts +// @ts-strictNullChecks false +export interface A { + member?: string; +} +export interface B { + member?: string | undefined; +} + +let a: A = { member: undefined }; +declare var b: B; +a = b; +b = a; + +import {A as OtherA, B as OtherB} from "./file1"; + +let a2: OtherA = { member: undefined }; +declare var b2: OtherB; +a2 = b2; +b2 = a2; + +a = a2; +a2 = a; + +b = b2; +b2 = b; + +a = b2; +b2 = a; + +b = a2; +a2 = b; + +// @filename: file3.ts +import {A, B} from "./file1"; +import {A as A2, B as B2} from "./file2"; + +let a: A = { member: undefined }; +let b: B = { member: undefined }; +let a2: A2 = { member: undefined }; +let b2: B2 = { member: undefined }; + +a = b; +b = a; + +a2 = b2; +b2 = a2; + +a = a2; +a2 = a; + +b = b2; +b2 = b; + +a = b2; +b2 = a; + +b = a2; +a2 = b; + +// @filename: file4.ts +// @ts-strictNullChecks false +import {A, B} from "./file1"; +import {A as A2, B as B2} from "./file2"; + +let a: A = { member: undefined }; +let b: B = { member: undefined }; +let a2: A2 = { member: undefined }; +let b2: B2 = { member: undefined }; + +a = b; +b = a; + +a2 = b2; +b2 = a2; + +a = a2; +a2 = a; + +b = b2; +b2 = b; + +a = b2; +b2 = a; + +b = a2; +a2 = b; \ No newline at end of file From fe5600e0ed98803f624431d2fc1abf1bf1738e5f Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Wed, 24 Aug 2022 16:05:27 -0700 Subject: [PATCH 04/24] Tests for all new pragmas --- src/compiler/binder.ts | 2 +- src/compiler/checker.ts | 8 +- .../reference/alwaysStrictPragma1.errors.txt | 20 + .../reference/alwaysStrictPragma1.js | 28 + .../reference/alwaysStrictPragma1.symbols | 19 + .../reference/alwaysStrictPragma1.types | 23 + .../reference/alwaysStrictPragma2.errors.txt | 23 + .../reference/alwaysStrictPragma2.js | 29 + .../reference/alwaysStrictPragma2.symbols | 19 + .../reference/alwaysStrictPragma2.types | 23 + ...actOptionalPropertyTypesPragma1.errors.txt | 180 +++++++ .../exactOptionalPropertyTypesPragma1.js | 165 ++++++ .../exactOptionalPropertyTypesPragma1.symbols | 283 ++++++++++ .../exactOptionalPropertyTypesPragma1.types | 287 ++++++++++ ...actOptionalPropertyTypesPragma2.errors.txt | 192 +++++++ .../exactOptionalPropertyTypesPragma2.js | 165 ++++++ .../exactOptionalPropertyTypesPragma2.symbols | 283 ++++++++++ .../exactOptionalPropertyTypesPragma2.types | 287 ++++++++++ ...FallthroughCasesInSwitchPragma1.errors.txt | 59 ++ .../noFallthroughCasesInSwitchPragma1.js | 117 ++++ .../noFallthroughCasesInSwitchPragma1.symbols | 91 ++++ .../noFallthroughCasesInSwitchPragma1.types | 107 ++++ ...FallthroughCasesInSwitchPragma2.errors.txt | 62 +++ .../noFallthroughCasesInSwitchPragma2.js | 117 ++++ .../noFallthroughCasesInSwitchPragma2.symbols | 91 ++++ .../noFallthroughCasesInSwitchPragma2.types | 107 ++++ .../reference/noImplicitAnyPragma1.errors.txt | 275 ++++++++++ .../reference/noImplicitAnyPragma1.js | 282 ++++++++++ .../reference/noImplicitAnyPragma1.symbols | 411 ++++++++++++++ .../reference/noImplicitAnyPragma1.types | 503 ++++++++++++++++++ .../reference/noImplicitAnyPragma2.errors.txt | 304 +++++++++++ .../reference/noImplicitAnyPragma2.js | 282 ++++++++++ .../reference/noImplicitAnyPragma2.symbols | 411 ++++++++++++++ .../reference/noImplicitAnyPragma2.types | 503 ++++++++++++++++++ .../noImplicitOverridePragma1.errors.txt | 54 ++ .../reference/noImplicitOverridePragma1.js | 228 ++++++++ .../noImplicitOverridePragma1.symbols | 90 ++++ .../reference/noImplicitOverridePragma1.types | 90 ++++ .../noImplicitOverridePragma2.errors.txt | 57 ++ .../reference/noImplicitOverridePragma2.js | 228 ++++++++ .../noImplicitOverridePragma2.symbols | 90 ++++ .../reference/noImplicitOverridePragma2.types | 90 ++++ .../noImplicitReturnsPragma1.errors.txt | 38 ++ .../reference/noImplicitReturnsPragma1.js | 76 +++ .../noImplicitReturnsPragma1.symbols | 46 ++ .../reference/noImplicitReturnsPragma1.types | 58 ++ .../noImplicitReturnsPragma2.errors.txt | 41 ++ .../reference/noImplicitReturnsPragma2.js | 76 +++ .../noImplicitReturnsPragma2.symbols | 46 ++ .../reference/noImplicitReturnsPragma2.types | 58 ++ .../noImplicitThisPragma1.errors.txt | 22 + .../reference/noImplicitThisPragma1.js | 32 ++ .../reference/noImplicitThisPragma1.symbols | 31 ++ .../reference/noImplicitThisPragma1.types | 35 ++ .../noImplicitThisPragma2.errors.txt | 25 + .../reference/noImplicitThisPragma2.js | 32 ++ .../reference/noImplicitThisPragma2.symbols | 31 ++ .../reference/noImplicitThisPragma2.types | 35 ++ ...AccessFromIndexSignaturePragma1.errors.txt | 39 ++ ...PropertyAccessFromIndexSignaturePragma1.js | 54 ++ ...rtyAccessFromIndexSignaturePragma1.symbols | 63 +++ ...pertyAccessFromIndexSignaturePragma1.types | 59 ++ ...AccessFromIndexSignaturePragma2.errors.txt | 42 ++ ...PropertyAccessFromIndexSignaturePragma2.js | 54 ++ ...rtyAccessFromIndexSignaturePragma2.symbols | 63 +++ ...pertyAccessFromIndexSignaturePragma2.types | 59 ++ ...noUncheckedIndexedAccessPragma1.errors.txt | 43 ++ .../noUncheckedIndexedAccessPragma1.js | 54 ++ .../noUncheckedIndexedAccessPragma1.symbols | 63 +++ .../noUncheckedIndexedAccessPragma1.types | 59 ++ ...noUncheckedIndexedAccessPragma2.errors.txt | 48 ++ .../noUncheckedIndexedAccessPragma2.js | 54 ++ .../noUncheckedIndexedAccessPragma2.symbols | 63 +++ .../noUncheckedIndexedAccessPragma2.types | 59 ++ .../noUnusedLocalsPragma1.errors.txt | 27 + .../reference/noUnusedLocalsPragma1.js | 38 ++ .../reference/noUnusedLocalsPragma1.symbols | 23 + .../reference/noUnusedLocalsPragma1.types | 23 + .../noUnusedLocalsPragma2.errors.txt | 30 ++ .../reference/noUnusedLocalsPragma2.js | 38 ++ .../reference/noUnusedLocalsPragma2.symbols | 23 + .../reference/noUnusedLocalsPragma2.types | 23 + .../noUnusedParametersPragma1.errors.txt | 23 + .../reference/noUnusedParametersPragma1.js | 45 ++ .../noUnusedParametersPragma1.symbols | 23 + .../reference/noUnusedParametersPragma1.types | 23 + .../noUnusedParametersPragma2.errors.txt | 26 + .../reference/noUnusedParametersPragma2.js | 45 ++ .../noUnusedParametersPragma2.symbols | 23 + .../reference/noUnusedParametersPragma2.types | 23 + .../strictBindCallApplyPragma1.errors.txt | 31 ++ .../reference/strictBindCallApplyPragma1.js | 61 +++ .../strictBindCallApplyPragma1.symbols | 71 +++ .../strictBindCallApplyPragma1.types | 87 +++ .../strictBindCallApplyPragma2.errors.txt | 34 ++ .../reference/strictBindCallApplyPragma2.js | 61 +++ .../strictBindCallApplyPragma2.symbols | 71 +++ .../strictBindCallApplyPragma2.types | 87 +++ .../strictFunctionTypesPragma1.errors.txt | 47 ++ .../reference/strictFunctionTypesPragma1.js | 77 +++ .../strictFunctionTypesPragma1.symbols | 71 +++ .../strictFunctionTypesPragma1.types | 95 ++++ .../strictFunctionTypesPragma2.errors.txt | 54 ++ .../reference/strictFunctionTypesPragma2.js | 77 +++ .../strictFunctionTypesPragma2.symbols | 71 +++ .../strictFunctionTypesPragma2.types | 95 ++++ .../strictFunctionTypesPragma3.errors.txt | 57 ++ .../reference/strictFunctionTypesPragma3.js | 68 +++ .../strictFunctionTypesPragma3.symbols | 89 ++++ .../strictFunctionTypesPragma3.types | 107 ++++ .../reference/strictPragma1.errors.txt | 113 ++++ tests/baselines/reference/strictPragma1.js | 169 ++++++ .../baselines/reference/strictPragma1.symbols | 215 ++++++++ tests/baselines/reference/strictPragma1.types | 263 +++++++++ .../reference/strictPragma2.errors.txt | 129 +++++ tests/baselines/reference/strictPragma2.js | 169 ++++++ .../baselines/reference/strictPragma2.symbols | 215 ++++++++ tests/baselines/reference/strictPragma2.types | 263 +++++++++ .../reference/strictPragma3.errors.txt | 33 ++ tests/baselines/reference/strictPragma3.js | 45 ++ .../baselines/reference/strictPragma3.symbols | 55 ++ tests/baselines/reference/strictPragma3.types | 67 +++ .../reference/strictPragma4.errors.txt | 36 ++ tests/baselines/reference/strictPragma4.js | 45 ++ .../baselines/reference/strictPragma4.symbols | 55 ++ tests/baselines/reference/strictPragma4.types | 67 +++ .../reference/strictPragma5.errors.txt | 36 ++ tests/baselines/reference/strictPragma5.js | 45 ++ .../baselines/reference/strictPragma5.symbols | 55 ++ tests/baselines/reference/strictPragma5.types | 67 +++ .../reference/strictPragma6.errors.txt | 32 ++ tests/baselines/reference/strictPragma6.js | 45 ++ .../baselines/reference/strictPragma6.symbols | 55 ++ tests/baselines/reference/strictPragma6.types | 67 +++ ...ctPropertyInitializationPragma1.errors.txt | 35 ++ .../strictPropertyInitializationPragma1.js | 73 +++ ...trictPropertyInitializationPragma1.symbols | 43 ++ .../strictPropertyInitializationPragma1.types | 43 ++ ...ctPropertyInitializationPragma2.errors.txt | 38 ++ .../strictPropertyInitializationPragma2.js | 73 +++ ...trictPropertyInitializationPragma2.symbols | 43 ++ .../strictPropertyInitializationPragma2.types | 43 ++ ...eUnknownInCatchVariablesPragma1.errors.txt | 43 ++ .../useUnknownInCatchVariablesPragma1.js | 65 +++ .../useUnknownInCatchVariablesPragma1.symbols | 47 ++ .../useUnknownInCatchVariablesPragma1.types | 55 ++ ...eUnknownInCatchVariablesPragma2.errors.txt | 46 ++ .../useUnknownInCatchVariablesPragma2.js | 65 +++ .../useUnknownInCatchVariablesPragma2.symbols | 47 ++ .../useUnknownInCatchVariablesPragma2.types | 55 ++ .../alwaysStrict/alwaysStrictPragma1.ts | 11 + .../alwaysStrict/alwaysStrictPragma2.ts | 12 + .../exactOptionalPropertyTypesPragma1.ts | 109 ++++ .../exactOptionalPropertyTypesPragma2.ts | 110 ++++ .../noFallthroughCasesInSwitchPragma1.ts | 50 ++ .../noFallthroughCasesInSwitchPragma2.ts | 51 ++ .../noImplicitAny/noImplicitAnyPragma1.ts | 172 ++++++ .../noImplicitAny/noImplicitAnyPragma2.ts | 173 ++++++ .../noImplicitOverridePragma1.ts | 46 ++ .../noImplicitOverridePragma2.ts | 47 ++ .../noImplicitReturnsPragma1.ts | 30 ++ .../noImplicitReturnsPragma2.ts | 31 ++ .../noImplicitThis/noImplicitThisPragma1.ts | 14 + .../noImplicitThis/noImplicitThisPragma2.ts | 15 + ...PropertyAccessFromIndexSignaturePragma1.ts | 30 ++ ...PropertyAccessFromIndexSignaturePragma2.ts | 31 ++ .../noUncheckedIndexedAccessPragma1.ts | 31 ++ .../noUncheckedIndexedAccessPragma2.ts | 32 ++ .../noUnusedLocals/noUnusedLocalsPragma1.ts | 18 + .../noUnusedLocals/noUnusedLocalsPragma2.ts | 19 + .../noUnusedParametersPragma1.ts | 14 + .../noUnusedParametersPragma2.ts | 15 + .../pragma/strict/strictPragma1.ts | 78 +++ .../pragma/strict/strictPragma2.ts | 79 +++ .../pragma/strict/strictPragma3.ts | 20 + .../pragma/strict/strictPragma4.ts | 20 + .../pragma/strict/strictPragma5.ts | 20 + .../pragma/strict/strictPragma6.ts | 20 + .../strictBindCallApplyPragma1.ts | 22 + .../strictBindCallApplyPragma2.ts | 23 + .../strictFunctionTypesPragma1.ts | 30 ++ .../strictFunctionTypesPragma2.ts | 31 ++ .../strictFunctionTypesPragma3.ts | 33 ++ .../strictPropertyInitializationPragma1.ts | 27 + .../strictPropertyInitializationPragma2.ts | 28 + .../useUnknownInCatchVariablesPragma1.ts | 34 ++ .../useUnknownInCatchVariablesPragma2.ts | 35 ++ 187 files changed, 14821 insertions(+), 5 deletions(-) create mode 100644 tests/baselines/reference/alwaysStrictPragma1.errors.txt create mode 100644 tests/baselines/reference/alwaysStrictPragma1.js create mode 100644 tests/baselines/reference/alwaysStrictPragma1.symbols create mode 100644 tests/baselines/reference/alwaysStrictPragma1.types create mode 100644 tests/baselines/reference/alwaysStrictPragma2.errors.txt create mode 100644 tests/baselines/reference/alwaysStrictPragma2.js create mode 100644 tests/baselines/reference/alwaysStrictPragma2.symbols create mode 100644 tests/baselines/reference/alwaysStrictPragma2.types create mode 100644 tests/baselines/reference/exactOptionalPropertyTypesPragma1.errors.txt create mode 100644 tests/baselines/reference/exactOptionalPropertyTypesPragma1.js create mode 100644 tests/baselines/reference/exactOptionalPropertyTypesPragma1.symbols create mode 100644 tests/baselines/reference/exactOptionalPropertyTypesPragma1.types create mode 100644 tests/baselines/reference/exactOptionalPropertyTypesPragma2.errors.txt create mode 100644 tests/baselines/reference/exactOptionalPropertyTypesPragma2.js create mode 100644 tests/baselines/reference/exactOptionalPropertyTypesPragma2.symbols create mode 100644 tests/baselines/reference/exactOptionalPropertyTypesPragma2.types create mode 100644 tests/baselines/reference/noFallthroughCasesInSwitchPragma1.errors.txt create mode 100644 tests/baselines/reference/noFallthroughCasesInSwitchPragma1.js create mode 100644 tests/baselines/reference/noFallthroughCasesInSwitchPragma1.symbols create mode 100644 tests/baselines/reference/noFallthroughCasesInSwitchPragma1.types create mode 100644 tests/baselines/reference/noFallthroughCasesInSwitchPragma2.errors.txt create mode 100644 tests/baselines/reference/noFallthroughCasesInSwitchPragma2.js create mode 100644 tests/baselines/reference/noFallthroughCasesInSwitchPragma2.symbols create mode 100644 tests/baselines/reference/noFallthroughCasesInSwitchPragma2.types create mode 100644 tests/baselines/reference/noImplicitAnyPragma1.errors.txt create mode 100644 tests/baselines/reference/noImplicitAnyPragma1.js create mode 100644 tests/baselines/reference/noImplicitAnyPragma1.symbols create mode 100644 tests/baselines/reference/noImplicitAnyPragma1.types create mode 100644 tests/baselines/reference/noImplicitAnyPragma2.errors.txt create mode 100644 tests/baselines/reference/noImplicitAnyPragma2.js create mode 100644 tests/baselines/reference/noImplicitAnyPragma2.symbols create mode 100644 tests/baselines/reference/noImplicitAnyPragma2.types create mode 100644 tests/baselines/reference/noImplicitOverridePragma1.errors.txt create mode 100644 tests/baselines/reference/noImplicitOverridePragma1.js create mode 100644 tests/baselines/reference/noImplicitOverridePragma1.symbols create mode 100644 tests/baselines/reference/noImplicitOverridePragma1.types create mode 100644 tests/baselines/reference/noImplicitOverridePragma2.errors.txt create mode 100644 tests/baselines/reference/noImplicitOverridePragma2.js create mode 100644 tests/baselines/reference/noImplicitOverridePragma2.symbols create mode 100644 tests/baselines/reference/noImplicitOverridePragma2.types create mode 100644 tests/baselines/reference/noImplicitReturnsPragma1.errors.txt create mode 100644 tests/baselines/reference/noImplicitReturnsPragma1.js create mode 100644 tests/baselines/reference/noImplicitReturnsPragma1.symbols create mode 100644 tests/baselines/reference/noImplicitReturnsPragma1.types create mode 100644 tests/baselines/reference/noImplicitReturnsPragma2.errors.txt create mode 100644 tests/baselines/reference/noImplicitReturnsPragma2.js create mode 100644 tests/baselines/reference/noImplicitReturnsPragma2.symbols create mode 100644 tests/baselines/reference/noImplicitReturnsPragma2.types create mode 100644 tests/baselines/reference/noImplicitThisPragma1.errors.txt create mode 100644 tests/baselines/reference/noImplicitThisPragma1.js create mode 100644 tests/baselines/reference/noImplicitThisPragma1.symbols create mode 100644 tests/baselines/reference/noImplicitThisPragma1.types create mode 100644 tests/baselines/reference/noImplicitThisPragma2.errors.txt create mode 100644 tests/baselines/reference/noImplicitThisPragma2.js create mode 100644 tests/baselines/reference/noImplicitThisPragma2.symbols create mode 100644 tests/baselines/reference/noImplicitThisPragma2.types create mode 100644 tests/baselines/reference/noPropertyAccessFromIndexSignaturePragma1.errors.txt create mode 100644 tests/baselines/reference/noPropertyAccessFromIndexSignaturePragma1.js create mode 100644 tests/baselines/reference/noPropertyAccessFromIndexSignaturePragma1.symbols create mode 100644 tests/baselines/reference/noPropertyAccessFromIndexSignaturePragma1.types create mode 100644 tests/baselines/reference/noPropertyAccessFromIndexSignaturePragma2.errors.txt create mode 100644 tests/baselines/reference/noPropertyAccessFromIndexSignaturePragma2.js create mode 100644 tests/baselines/reference/noPropertyAccessFromIndexSignaturePragma2.symbols create mode 100644 tests/baselines/reference/noPropertyAccessFromIndexSignaturePragma2.types create mode 100644 tests/baselines/reference/noUncheckedIndexedAccessPragma1.errors.txt create mode 100644 tests/baselines/reference/noUncheckedIndexedAccessPragma1.js create mode 100644 tests/baselines/reference/noUncheckedIndexedAccessPragma1.symbols create mode 100644 tests/baselines/reference/noUncheckedIndexedAccessPragma1.types create mode 100644 tests/baselines/reference/noUncheckedIndexedAccessPragma2.errors.txt create mode 100644 tests/baselines/reference/noUncheckedIndexedAccessPragma2.js create mode 100644 tests/baselines/reference/noUncheckedIndexedAccessPragma2.symbols create mode 100644 tests/baselines/reference/noUncheckedIndexedAccessPragma2.types create mode 100644 tests/baselines/reference/noUnusedLocalsPragma1.errors.txt create mode 100644 tests/baselines/reference/noUnusedLocalsPragma1.js create mode 100644 tests/baselines/reference/noUnusedLocalsPragma1.symbols create mode 100644 tests/baselines/reference/noUnusedLocalsPragma1.types create mode 100644 tests/baselines/reference/noUnusedLocalsPragma2.errors.txt create mode 100644 tests/baselines/reference/noUnusedLocalsPragma2.js create mode 100644 tests/baselines/reference/noUnusedLocalsPragma2.symbols create mode 100644 tests/baselines/reference/noUnusedLocalsPragma2.types create mode 100644 tests/baselines/reference/noUnusedParametersPragma1.errors.txt create mode 100644 tests/baselines/reference/noUnusedParametersPragma1.js create mode 100644 tests/baselines/reference/noUnusedParametersPragma1.symbols create mode 100644 tests/baselines/reference/noUnusedParametersPragma1.types create mode 100644 tests/baselines/reference/noUnusedParametersPragma2.errors.txt create mode 100644 tests/baselines/reference/noUnusedParametersPragma2.js create mode 100644 tests/baselines/reference/noUnusedParametersPragma2.symbols create mode 100644 tests/baselines/reference/noUnusedParametersPragma2.types create mode 100644 tests/baselines/reference/strictBindCallApplyPragma1.errors.txt create mode 100644 tests/baselines/reference/strictBindCallApplyPragma1.js create mode 100644 tests/baselines/reference/strictBindCallApplyPragma1.symbols create mode 100644 tests/baselines/reference/strictBindCallApplyPragma1.types create mode 100644 tests/baselines/reference/strictBindCallApplyPragma2.errors.txt create mode 100644 tests/baselines/reference/strictBindCallApplyPragma2.js create mode 100644 tests/baselines/reference/strictBindCallApplyPragma2.symbols create mode 100644 tests/baselines/reference/strictBindCallApplyPragma2.types create mode 100644 tests/baselines/reference/strictFunctionTypesPragma1.errors.txt create mode 100644 tests/baselines/reference/strictFunctionTypesPragma1.js create mode 100644 tests/baselines/reference/strictFunctionTypesPragma1.symbols create mode 100644 tests/baselines/reference/strictFunctionTypesPragma1.types create mode 100644 tests/baselines/reference/strictFunctionTypesPragma2.errors.txt create mode 100644 tests/baselines/reference/strictFunctionTypesPragma2.js create mode 100644 tests/baselines/reference/strictFunctionTypesPragma2.symbols create mode 100644 tests/baselines/reference/strictFunctionTypesPragma2.types create mode 100644 tests/baselines/reference/strictFunctionTypesPragma3.errors.txt create mode 100644 tests/baselines/reference/strictFunctionTypesPragma3.js create mode 100644 tests/baselines/reference/strictFunctionTypesPragma3.symbols create mode 100644 tests/baselines/reference/strictFunctionTypesPragma3.types create mode 100644 tests/baselines/reference/strictPragma1.errors.txt create mode 100644 tests/baselines/reference/strictPragma1.js create mode 100644 tests/baselines/reference/strictPragma1.symbols create mode 100644 tests/baselines/reference/strictPragma1.types create mode 100644 tests/baselines/reference/strictPragma2.errors.txt create mode 100644 tests/baselines/reference/strictPragma2.js create mode 100644 tests/baselines/reference/strictPragma2.symbols create mode 100644 tests/baselines/reference/strictPragma2.types create mode 100644 tests/baselines/reference/strictPragma3.errors.txt create mode 100644 tests/baselines/reference/strictPragma3.js create mode 100644 tests/baselines/reference/strictPragma3.symbols create mode 100644 tests/baselines/reference/strictPragma3.types create mode 100644 tests/baselines/reference/strictPragma4.errors.txt create mode 100644 tests/baselines/reference/strictPragma4.js create mode 100644 tests/baselines/reference/strictPragma4.symbols create mode 100644 tests/baselines/reference/strictPragma4.types create mode 100644 tests/baselines/reference/strictPragma5.errors.txt create mode 100644 tests/baselines/reference/strictPragma5.js create mode 100644 tests/baselines/reference/strictPragma5.symbols create mode 100644 tests/baselines/reference/strictPragma5.types create mode 100644 tests/baselines/reference/strictPragma6.errors.txt create mode 100644 tests/baselines/reference/strictPragma6.js create mode 100644 tests/baselines/reference/strictPragma6.symbols create mode 100644 tests/baselines/reference/strictPragma6.types create mode 100644 tests/baselines/reference/strictPropertyInitializationPragma1.errors.txt create mode 100644 tests/baselines/reference/strictPropertyInitializationPragma1.js create mode 100644 tests/baselines/reference/strictPropertyInitializationPragma1.symbols create mode 100644 tests/baselines/reference/strictPropertyInitializationPragma1.types create mode 100644 tests/baselines/reference/strictPropertyInitializationPragma2.errors.txt create mode 100644 tests/baselines/reference/strictPropertyInitializationPragma2.js create mode 100644 tests/baselines/reference/strictPropertyInitializationPragma2.symbols create mode 100644 tests/baselines/reference/strictPropertyInitializationPragma2.types create mode 100644 tests/baselines/reference/useUnknownInCatchVariablesPragma1.errors.txt create mode 100644 tests/baselines/reference/useUnknownInCatchVariablesPragma1.js create mode 100644 tests/baselines/reference/useUnknownInCatchVariablesPragma1.symbols create mode 100644 tests/baselines/reference/useUnknownInCatchVariablesPragma1.types create mode 100644 tests/baselines/reference/useUnknownInCatchVariablesPragma2.errors.txt create mode 100644 tests/baselines/reference/useUnknownInCatchVariablesPragma2.js create mode 100644 tests/baselines/reference/useUnknownInCatchVariablesPragma2.symbols create mode 100644 tests/baselines/reference/useUnknownInCatchVariablesPragma2.types create mode 100644 tests/cases/conformance/pragma/alwaysStrict/alwaysStrictPragma1.ts create mode 100644 tests/cases/conformance/pragma/alwaysStrict/alwaysStrictPragma2.ts create mode 100644 tests/cases/conformance/pragma/exactOptionalPropertyTypes/exactOptionalPropertyTypesPragma1.ts create mode 100644 tests/cases/conformance/pragma/exactOptionalPropertyTypes/exactOptionalPropertyTypesPragma2.ts create mode 100644 tests/cases/conformance/pragma/noFallthroughCasesInSwitch/noFallthroughCasesInSwitchPragma1.ts create mode 100644 tests/cases/conformance/pragma/noFallthroughCasesInSwitch/noFallthroughCasesInSwitchPragma2.ts create mode 100644 tests/cases/conformance/pragma/noImplicitAny/noImplicitAnyPragma1.ts create mode 100644 tests/cases/conformance/pragma/noImplicitAny/noImplicitAnyPragma2.ts create mode 100644 tests/cases/conformance/pragma/noImplicitOverride/noImplicitOverridePragma1.ts create mode 100644 tests/cases/conformance/pragma/noImplicitOverride/noImplicitOverridePragma2.ts create mode 100644 tests/cases/conformance/pragma/noImplicitReturns/noImplicitReturnsPragma1.ts create mode 100644 tests/cases/conformance/pragma/noImplicitReturns/noImplicitReturnsPragma2.ts create mode 100644 tests/cases/conformance/pragma/noImplicitThis/noImplicitThisPragma1.ts create mode 100644 tests/cases/conformance/pragma/noImplicitThis/noImplicitThisPragma2.ts create mode 100644 tests/cases/conformance/pragma/noPropertyAccessFromIndexSignature/noPropertyAccessFromIndexSignaturePragma1.ts create mode 100644 tests/cases/conformance/pragma/noPropertyAccessFromIndexSignature/noPropertyAccessFromIndexSignaturePragma2.ts create mode 100644 tests/cases/conformance/pragma/noUncheckedIndexedAccess/noUncheckedIndexedAccessPragma1.ts create mode 100644 tests/cases/conformance/pragma/noUncheckedIndexedAccess/noUncheckedIndexedAccessPragma2.ts create mode 100644 tests/cases/conformance/pragma/noUnusedLocals/noUnusedLocalsPragma1.ts create mode 100644 tests/cases/conformance/pragma/noUnusedLocals/noUnusedLocalsPragma2.ts create mode 100644 tests/cases/conformance/pragma/noUnusedParameters/noUnusedParametersPragma1.ts create mode 100644 tests/cases/conformance/pragma/noUnusedParameters/noUnusedParametersPragma2.ts create mode 100644 tests/cases/conformance/pragma/strict/strictPragma1.ts create mode 100644 tests/cases/conformance/pragma/strict/strictPragma2.ts create mode 100644 tests/cases/conformance/pragma/strict/strictPragma3.ts create mode 100644 tests/cases/conformance/pragma/strict/strictPragma4.ts create mode 100644 tests/cases/conformance/pragma/strict/strictPragma5.ts create mode 100644 tests/cases/conformance/pragma/strict/strictPragma6.ts create mode 100644 tests/cases/conformance/pragma/strictBindCallApply/strictBindCallApplyPragma1.ts create mode 100644 tests/cases/conformance/pragma/strictBindCallApply/strictBindCallApplyPragma2.ts create mode 100644 tests/cases/conformance/pragma/strictFunctionTypes/strictFunctionTypesPragma1.ts create mode 100644 tests/cases/conformance/pragma/strictFunctionTypes/strictFunctionTypesPragma2.ts create mode 100644 tests/cases/conformance/pragma/strictFunctionTypes/strictFunctionTypesPragma3.ts create mode 100644 tests/cases/conformance/pragma/strictPropertyInitialization/strictPropertyInitializationPragma1.ts create mode 100644 tests/cases/conformance/pragma/strictPropertyInitialization/strictPropertyInitializationPragma2.ts create mode 100644 tests/cases/conformance/pragma/useUnknownInCatchVariables/useUnknownInCatchVariablesPragma1.ts create mode 100644 tests/cases/conformance/pragma/useUnknownInCatchVariables/useUnknownInCatchVariablesPragma2.ts diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index a5bb023ac0798..ae5656616e65c 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -1351,7 +1351,7 @@ namespace ts { const clause = clauses[i]; bind(clause); fallthroughFlow = currentFlow; - if (!(currentFlow.flags & FlowFlags.Unreachable) && i !== clauses.length - 1 && options.noFallthroughCasesInSwitch) { + if (!(currentFlow.flags & FlowFlags.Unreachable) && i !== clauses.length - 1 && getFileLocalCompilerOption(file, options, "noFallthroughCasesInSwitch")) { clause.fallthroughFlowNode = currentFlow; } } diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 36dfec91d839f..f622ea698df07 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -12742,7 +12742,7 @@ namespace ts { return symbol; } if (skipObjectFunctionPropertyAugment) return undefined; - const file = symbol?.valueDeclaration && getSourceFileOfNode(symbol.valueDeclaration); + const file = resolved.symbol?.declarations?.[0] && getSourceFileOfNode(resolved.symbol.declarations[0]); const functionType = resolved === anyFunctionType ? globalFunctionType : resolved.callSignatures.length ? globalCallableFunctionType(file) : resolved.constructSignatures.length ? globalNewableFunctionType(file) : @@ -19123,8 +19123,8 @@ namespace ts { } function hasExcessProperties(source: FreshObjectLiteralType, target: Type, reportErrors: boolean): boolean { - const sourceNoImplicitAny = noImplicitAny(source.symbol?.valueDeclaration); - const targetNoImplicitAny = noImplicitAny(target.symbol?.valueDeclaration); + const sourceNoImplicitAny = noImplicitAny(source.symbol?.declarations?.[0]); + const targetNoImplicitAny = noImplicitAny(target.symbol?.declarations?.[0]); if (!isExcessPropertyCheckTarget(target) || !(sourceNoImplicitAny || targetNoImplicitAny) && getObjectFlags(target) & ObjectFlags.JSLiteral) { return false; // Disable excess property checks on JS literals to simulate having an implicit "index signature" - but only outside of noImplicitAny } @@ -43113,7 +43113,7 @@ namespace ts { function getAugmentedPropertiesOfType(type: Type): Symbol[] { type = getApparentType(type); const propsByName = createSymbolTable(getPropertiesOfType(type)); - const file = type.symbol?.valueDeclaration && getSourceFileOfNode(type.symbol.valueDeclaration); + const file = type.symbol?.declarations?.[0] && getSourceFileOfNode(type.symbol.declarations[0]); const functionType = getSignaturesOfType(type, SignatureKind.Call).length ? globalCallableFunctionType(file) : getSignaturesOfType(type, SignatureKind.Construct).length ? globalNewableFunctionType(file) : undefined; diff --git a/tests/baselines/reference/alwaysStrictPragma1.errors.txt b/tests/baselines/reference/alwaysStrictPragma1.errors.txt new file mode 100644 index 0000000000000..1f6f2deabae55 --- /dev/null +++ b/tests/baselines/reference/alwaysStrictPragma1.errors.txt @@ -0,0 +1,20 @@ +tests/cases/conformance/pragma/alwaysStrict/file1.ts(2,5): error TS1212: Identifier expected. 'private' is a reserved word in strict mode. +tests/cases/conformance/pragma/alwaysStrict/file2.ts(2,5): error TS1212: Identifier expected. 'protected' is a reserved word in strict mode. + + +==== tests/cases/conformance/pragma/alwaysStrict/file1.ts (1 errors) ==== + // @ts-alwaysStrict + let private = {}; + ~~~~~~~ +!!! error TS1212: Identifier expected. 'private' is a reserved word in strict mode. +==== tests/cases/conformance/pragma/alwaysStrict/file2.ts (1 errors) ==== + // @ts-alwaysStrict true + let protected = {}; + ~~~~~~~~~ +!!! error TS1212: Identifier expected. 'protected' is a reserved word in strict mode. +==== tests/cases/conformance/pragma/alwaysStrict/file3.ts (0 errors) ==== + // @ts-alwaysStrict false + let public = {}; +==== tests/cases/conformance/pragma/alwaysStrict/file4.ts (0 errors) ==== + let static = {}; + \ No newline at end of file diff --git a/tests/baselines/reference/alwaysStrictPragma1.js b/tests/baselines/reference/alwaysStrictPragma1.js new file mode 100644 index 0000000000000..64d75d832e5ed --- /dev/null +++ b/tests/baselines/reference/alwaysStrictPragma1.js @@ -0,0 +1,28 @@ +//// [tests/cases/conformance/pragma/alwaysStrict/alwaysStrictPragma1.ts] //// + +//// [file1.ts] +// @ts-alwaysStrict +let private = {}; +//// [file2.ts] +// @ts-alwaysStrict true +let protected = {}; +//// [file3.ts] +// @ts-alwaysStrict false +let public = {}; +//// [file4.ts] +let static = {}; + + +//// [file1.js] +"use strict"; +// @ts-alwaysStrict +var private = {}; +//// [file2.js] +"use strict"; +// @ts-alwaysStrict true +var protected = {}; +//// [file3.js] +// @ts-alwaysStrict false +var public = {}; +//// [file4.js] +var static = {}; diff --git a/tests/baselines/reference/alwaysStrictPragma1.symbols b/tests/baselines/reference/alwaysStrictPragma1.symbols new file mode 100644 index 0000000000000..15b0b73796888 --- /dev/null +++ b/tests/baselines/reference/alwaysStrictPragma1.symbols @@ -0,0 +1,19 @@ +=== tests/cases/conformance/pragma/alwaysStrict/file1.ts === +// @ts-alwaysStrict +let private = {}; +>private : Symbol(private, Decl(file1.ts, 1, 3)) + +=== tests/cases/conformance/pragma/alwaysStrict/file2.ts === +// @ts-alwaysStrict true +let protected = {}; +>protected : Symbol(protected, Decl(file2.ts, 1, 3)) + +=== tests/cases/conformance/pragma/alwaysStrict/file3.ts === +// @ts-alwaysStrict false +let public = {}; +>public : Symbol(public, Decl(file3.ts, 1, 3)) + +=== tests/cases/conformance/pragma/alwaysStrict/file4.ts === +let static = {}; +>static : Symbol(static, Decl(file4.ts, 0, 3)) + diff --git a/tests/baselines/reference/alwaysStrictPragma1.types b/tests/baselines/reference/alwaysStrictPragma1.types new file mode 100644 index 0000000000000..3a29cb6586b3f --- /dev/null +++ b/tests/baselines/reference/alwaysStrictPragma1.types @@ -0,0 +1,23 @@ +=== tests/cases/conformance/pragma/alwaysStrict/file1.ts === +// @ts-alwaysStrict +let private = {}; +>private : {} +>{} : {} + +=== tests/cases/conformance/pragma/alwaysStrict/file2.ts === +// @ts-alwaysStrict true +let protected = {}; +>protected : {} +>{} : {} + +=== tests/cases/conformance/pragma/alwaysStrict/file3.ts === +// @ts-alwaysStrict false +let public = {}; +>public : {} +>{} : {} + +=== tests/cases/conformance/pragma/alwaysStrict/file4.ts === +let static = {}; +>static : {} +>{} : {} + diff --git a/tests/baselines/reference/alwaysStrictPragma2.errors.txt b/tests/baselines/reference/alwaysStrictPragma2.errors.txt new file mode 100644 index 0000000000000..98ecbc774bc5a --- /dev/null +++ b/tests/baselines/reference/alwaysStrictPragma2.errors.txt @@ -0,0 +1,23 @@ +tests/cases/conformance/pragma/alwaysStrict/file1.ts(2,5): error TS1212: Identifier expected. 'private' is a reserved word in strict mode. +tests/cases/conformance/pragma/alwaysStrict/file2.ts(2,5): error TS1212: Identifier expected. 'protected' is a reserved word in strict mode. +tests/cases/conformance/pragma/alwaysStrict/file4.ts(1,5): error TS1212: Identifier expected. 'static' is a reserved word in strict mode. + + +==== tests/cases/conformance/pragma/alwaysStrict/file1.ts (1 errors) ==== + // @ts-alwaysStrict + let private = {}; + ~~~~~~~ +!!! error TS1212: Identifier expected. 'private' is a reserved word in strict mode. +==== tests/cases/conformance/pragma/alwaysStrict/file2.ts (1 errors) ==== + // @ts-alwaysStrict true + let protected = {}; + ~~~~~~~~~ +!!! error TS1212: Identifier expected. 'protected' is a reserved word in strict mode. +==== tests/cases/conformance/pragma/alwaysStrict/file3.ts (0 errors) ==== + // @ts-alwaysStrict false + let public = {}; +==== tests/cases/conformance/pragma/alwaysStrict/file4.ts (1 errors) ==== + let static = {}; + ~~~~~~ +!!! error TS1212: Identifier expected. 'static' is a reserved word in strict mode. + \ No newline at end of file diff --git a/tests/baselines/reference/alwaysStrictPragma2.js b/tests/baselines/reference/alwaysStrictPragma2.js new file mode 100644 index 0000000000000..cda943368bd7f --- /dev/null +++ b/tests/baselines/reference/alwaysStrictPragma2.js @@ -0,0 +1,29 @@ +//// [tests/cases/conformance/pragma/alwaysStrict/alwaysStrictPragma2.ts] //// + +//// [file1.ts] +// @ts-alwaysStrict +let private = {}; +//// [file2.ts] +// @ts-alwaysStrict true +let protected = {}; +//// [file3.ts] +// @ts-alwaysStrict false +let public = {}; +//// [file4.ts] +let static = {}; + + +//// [file1.js] +"use strict"; +// @ts-alwaysStrict +var private = {}; +//// [file2.js] +"use strict"; +// @ts-alwaysStrict true +var protected = {}; +//// [file3.js] +// @ts-alwaysStrict false +var public = {}; +//// [file4.js] +"use strict"; +var static = {}; diff --git a/tests/baselines/reference/alwaysStrictPragma2.symbols b/tests/baselines/reference/alwaysStrictPragma2.symbols new file mode 100644 index 0000000000000..15b0b73796888 --- /dev/null +++ b/tests/baselines/reference/alwaysStrictPragma2.symbols @@ -0,0 +1,19 @@ +=== tests/cases/conformance/pragma/alwaysStrict/file1.ts === +// @ts-alwaysStrict +let private = {}; +>private : Symbol(private, Decl(file1.ts, 1, 3)) + +=== tests/cases/conformance/pragma/alwaysStrict/file2.ts === +// @ts-alwaysStrict true +let protected = {}; +>protected : Symbol(protected, Decl(file2.ts, 1, 3)) + +=== tests/cases/conformance/pragma/alwaysStrict/file3.ts === +// @ts-alwaysStrict false +let public = {}; +>public : Symbol(public, Decl(file3.ts, 1, 3)) + +=== tests/cases/conformance/pragma/alwaysStrict/file4.ts === +let static = {}; +>static : Symbol(static, Decl(file4.ts, 0, 3)) + diff --git a/tests/baselines/reference/alwaysStrictPragma2.types b/tests/baselines/reference/alwaysStrictPragma2.types new file mode 100644 index 0000000000000..3a29cb6586b3f --- /dev/null +++ b/tests/baselines/reference/alwaysStrictPragma2.types @@ -0,0 +1,23 @@ +=== tests/cases/conformance/pragma/alwaysStrict/file1.ts === +// @ts-alwaysStrict +let private = {}; +>private : {} +>{} : {} + +=== tests/cases/conformance/pragma/alwaysStrict/file2.ts === +// @ts-alwaysStrict true +let protected = {}; +>protected : {} +>{} : {} + +=== tests/cases/conformance/pragma/alwaysStrict/file3.ts === +// @ts-alwaysStrict false +let public = {}; +>public : {} +>{} : {} + +=== tests/cases/conformance/pragma/alwaysStrict/file4.ts === +let static = {}; +>static : {} +>{} : {} + diff --git a/tests/baselines/reference/exactOptionalPropertyTypesPragma1.errors.txt b/tests/baselines/reference/exactOptionalPropertyTypesPragma1.errors.txt new file mode 100644 index 0000000000000..51e02a85bf7a9 --- /dev/null +++ b/tests/baselines/reference/exactOptionalPropertyTypesPragma1.errors.txt @@ -0,0 +1,180 @@ +tests/cases/conformance/pragma/exactOptionalPropertyTypes/file1.ts(6,8): error TS2790: The operand of a 'delete' operator must be optional. +tests/cases/conformance/pragma/exactOptionalPropertyTypes/file1.ts(12,1): error TS2322: Type 'B' is not assignable to type 'A'. + Property 'member' is optional in type 'B' but required in type 'A'. +tests/cases/conformance/pragma/exactOptionalPropertyTypes/file1.ts(13,1): error TS2375: Type 'A' is not assignable to type 'B' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties. + Types of property 'member' are incompatible. + Type 'string | undefined' is not assignable to type 'string'. + Type 'undefined' is not assignable to type 'string'. +tests/cases/conformance/pragma/exactOptionalPropertyTypes/file2.ts(6,8): error TS2790: The operand of a 'delete' operator must be optional. +tests/cases/conformance/pragma/exactOptionalPropertyTypes/file2.ts(12,1): error TS2322: Type 'B' is not assignable to type 'A'. + Property 'member' is optional in type 'B' but required in type 'A'. +tests/cases/conformance/pragma/exactOptionalPropertyTypes/file2.ts(13,1): error TS2375: Type 'A' is not assignable to type 'B' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties. + Types of property 'member' are incompatible. + Type 'string | undefined' is not assignable to type 'string'. + Type 'undefined' is not assignable to type 'string'. +tests/cases/conformance/pragma/exactOptionalPropertyTypes/file3.ts(12,1): error TS2322: Type 'B' is not assignable to type 'A'. + Property 'member' is optional in type 'B' but required in type 'A'. +tests/cases/conformance/pragma/exactOptionalPropertyTypes/file4.ts(11,1): error TS2322: Type 'B' is not assignable to type 'A'. + Property 'member' is optional in type 'B' but required in type 'A'. +tests/cases/conformance/pragma/exactOptionalPropertyTypes/file5.ts(7,1): error TS2322: Type 'B' is not assignable to type 'A'. + Property 'member' is optional in type 'B' but required in type 'A'. +tests/cases/conformance/pragma/exactOptionalPropertyTypes/file5.ts(10,1): error TS2322: Type 'B' is not assignable to type 'A'. +tests/cases/conformance/pragma/exactOptionalPropertyTypes/file5.ts(19,1): error TS2322: Type 'B' is not assignable to type 'A'. +tests/cases/conformance/pragma/exactOptionalPropertyTypes/file5.ts(23,1): error TS2322: Type 'B' is not assignable to type 'A'. +tests/cases/conformance/pragma/exactOptionalPropertyTypes/file6.ts(7,1): error TS2322: Type 'B' is not assignable to type 'A'. +tests/cases/conformance/pragma/exactOptionalPropertyTypes/file6.ts(10,1): error TS2322: Type 'B' is not assignable to type 'A'. +tests/cases/conformance/pragma/exactOptionalPropertyTypes/file6.ts(19,1): error TS2322: Type 'B' is not assignable to type 'A'. +tests/cases/conformance/pragma/exactOptionalPropertyTypes/file6.ts(23,1): error TS2322: Type 'B' is not assignable to type 'A'. + + +==== tests/cases/conformance/pragma/exactOptionalPropertyTypes/file1.ts (3 errors) ==== + // @ts-exactOptionalPropertyTypes + export interface A { + member: string | undefined; + } + declare var a: A; + delete a.member; + ~~~~~~~~ +!!! error TS2790: The operand of a 'delete' operator must be optional. + + export interface B { + member?: string; + } + declare var b: B; + a = b; + ~ +!!! error TS2322: Type 'B' is not assignable to type 'A'. +!!! error TS2322: Property 'member' is optional in type 'B' but required in type 'A'. + b = a; + ~ +!!! error TS2375: Type 'A' is not assignable to type 'B' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties. +!!! error TS2375: Types of property 'member' are incompatible. +!!! error TS2375: Type 'string | undefined' is not assignable to type 'string'. +!!! error TS2375: Type 'undefined' is not assignable to type 'string'. + +==== tests/cases/conformance/pragma/exactOptionalPropertyTypes/file2.ts (3 errors) ==== + // @ts-exactOptionalPropertyTypes true + export interface A { + member: string | undefined; + } + declare var a: A; + delete a.member; + ~~~~~~~~ +!!! error TS2790: The operand of a 'delete' operator must be optional. + + export interface B { + member?: string; + } + declare var b: B; + a = b; + ~ +!!! error TS2322: Type 'B' is not assignable to type 'A'. +!!! error TS2322: Property 'member' is optional in type 'B' but required in type 'A'. + b = a; + ~ +!!! error TS2375: Type 'A' is not assignable to type 'B' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties. +!!! error TS2375: Types of property 'member' are incompatible. +!!! error TS2375: Type 'string | undefined' is not assignable to type 'string'. +!!! error TS2375: Type 'undefined' is not assignable to type 'string'. + +==== tests/cases/conformance/pragma/exactOptionalPropertyTypes/file3.ts (1 errors) ==== + // @ts-exactOptionalPropertyTypes false + export interface A { + member: string | undefined; + } + declare var a: A; + delete a.member; + + export interface B { + member?: string; + } + declare var b: B; + a = b; + ~ +!!! error TS2322: Type 'B' is not assignable to type 'A'. +!!! error TS2322: Property 'member' is optional in type 'B' but required in type 'A'. + b = a; + +==== tests/cases/conformance/pragma/exactOptionalPropertyTypes/file4.ts (1 errors) ==== + export interface A { + member: string | undefined; + } + declare var a: A; + delete a.member; + + export interface B { + member?: string; + } + declare var b: B; + a = b; + ~ +!!! error TS2322: Type 'B' is not assignable to type 'A'. +!!! error TS2322: Property 'member' is optional in type 'B' but required in type 'A'. + b = a; + +==== tests/cases/conformance/pragma/exactOptionalPropertyTypes/file5.ts (4 errors) ==== + // @ts-exactOptionalPropertyTypes true + import {A as A1, B as B1} from "./file2"; + import {A as A2, B as B2} from "./file3"; + + declare var a1: A1, b1: B2, a2: A2, b2: B2; + + a1 = b1; + ~~ +!!! error TS2322: Type 'B' is not assignable to type 'A'. +!!! error TS2322: Property 'member' is optional in type 'B' but required in type 'A'. + b1 = a1; + + a2 = b2; + ~~ +!!! error TS2322: Type 'B' is not assignable to type 'A'. + b2 = a2; + + a1 = a2; + a2 = a1; + + b1 = b2; + b2 = b1; + + a1 = b2; + ~~ +!!! error TS2322: Type 'B' is not assignable to type 'A'. + b2 = a1; + + b1 = a2; + a2 = b1; + ~~ +!!! error TS2322: Type 'B' is not assignable to type 'A'. + +==== tests/cases/conformance/pragma/exactOptionalPropertyTypes/file6.ts (4 errors) ==== + // @ts-exactOptionalPropertyTypes false + import {A as A1, B as B1} from "./file2"; + import {A as A2, B as B2} from "./file3"; + + declare var a1: A1, b1: B2, a2: A2, b2: B2; + + a1 = b1; + ~~ +!!! error TS2322: Type 'B' is not assignable to type 'A'. + b1 = a1; + + a2 = b2; + ~~ +!!! error TS2322: Type 'B' is not assignable to type 'A'. + b2 = a2; + + a1 = a2; + a2 = a1; + + b1 = b2; + b2 = b1; + + a1 = b2; + ~~ +!!! error TS2322: Type 'B' is not assignable to type 'A'. + b2 = a1; + + b1 = a2; + a2 = b1; + ~~ +!!! error TS2322: Type 'B' is not assignable to type 'A'. \ No newline at end of file diff --git a/tests/baselines/reference/exactOptionalPropertyTypesPragma1.js b/tests/baselines/reference/exactOptionalPropertyTypesPragma1.js new file mode 100644 index 0000000000000..57de9ee9d5543 --- /dev/null +++ b/tests/baselines/reference/exactOptionalPropertyTypesPragma1.js @@ -0,0 +1,165 @@ +//// [tests/cases/conformance/pragma/exactOptionalPropertyTypes/exactOptionalPropertyTypesPragma1.ts] //// + +//// [file1.ts] +// @ts-exactOptionalPropertyTypes +export interface A { + member: string | undefined; +} +declare var a: A; +delete a.member; + +export interface B { + member?: string; +} +declare var b: B; +a = b; +b = a; + +//// [file2.ts] +// @ts-exactOptionalPropertyTypes true +export interface A { + member: string | undefined; +} +declare var a: A; +delete a.member; + +export interface B { + member?: string; +} +declare var b: B; +a = b; +b = a; + +//// [file3.ts] +// @ts-exactOptionalPropertyTypes false +export interface A { + member: string | undefined; +} +declare var a: A; +delete a.member; + +export interface B { + member?: string; +} +declare var b: B; +a = b; +b = a; + +//// [file4.ts] +export interface A { + member: string | undefined; +} +declare var a: A; +delete a.member; + +export interface B { + member?: string; +} +declare var b: B; +a = b; +b = a; + +//// [file5.ts] +// @ts-exactOptionalPropertyTypes true +import {A as A1, B as B1} from "./file2"; +import {A as A2, B as B2} from "./file3"; + +declare var a1: A1, b1: B2, a2: A2, b2: B2; + +a1 = b1; +b1 = a1; + +a2 = b2; +b2 = a2; + +a1 = a2; +a2 = a1; + +b1 = b2; +b2 = b1; + +a1 = b2; +b2 = a1; + +b1 = a2; +a2 = b1; + +//// [file6.ts] +// @ts-exactOptionalPropertyTypes false +import {A as A1, B as B1} from "./file2"; +import {A as A2, B as B2} from "./file3"; + +declare var a1: A1, b1: B2, a2: A2, b2: B2; + +a1 = b1; +b1 = a1; + +a2 = b2; +b2 = a2; + +a1 = a2; +a2 = a1; + +b1 = b2; +b2 = b1; + +a1 = b2; +b2 = a1; + +b1 = a2; +a2 = b1; + +//// [file1.js] +"use strict"; +exports.__esModule = true; +delete a.member; +a = b; +b = a; +//// [file2.js] +"use strict"; +exports.__esModule = true; +delete a.member; +a = b; +b = a; +//// [file3.js] +"use strict"; +exports.__esModule = true; +delete a.member; +a = b; +b = a; +//// [file4.js] +"use strict"; +exports.__esModule = true; +delete a.member; +a = b; +b = a; +//// [file5.js] +"use strict"; +exports.__esModule = true; +a1 = b1; +b1 = a1; +a2 = b2; +b2 = a2; +a1 = a2; +a2 = a1; +b1 = b2; +b2 = b1; +a1 = b2; +b2 = a1; +b1 = a2; +a2 = b1; +//// [file6.js] +"use strict"; +exports.__esModule = true; +a1 = b1; +b1 = a1; +a2 = b2; +b2 = a2; +a1 = a2; +a2 = a1; +b1 = b2; +b2 = b1; +a1 = b2; +b2 = a1; +b1 = a2; +a2 = b1; diff --git a/tests/baselines/reference/exactOptionalPropertyTypesPragma1.symbols b/tests/baselines/reference/exactOptionalPropertyTypesPragma1.symbols new file mode 100644 index 0000000000000..3f39098c5ef3d --- /dev/null +++ b/tests/baselines/reference/exactOptionalPropertyTypesPragma1.symbols @@ -0,0 +1,283 @@ +=== tests/cases/conformance/pragma/exactOptionalPropertyTypes/file1.ts === +// @ts-exactOptionalPropertyTypes +export interface A { +>A : Symbol(A, Decl(file1.ts, 0, 0)) + + member: string | undefined; +>member : Symbol(A.member, Decl(file1.ts, 1, 20)) +} +declare var a: A; +>a : Symbol(a, Decl(file1.ts, 4, 11)) +>A : Symbol(A, Decl(file1.ts, 0, 0)) + +delete a.member; +>a.member : Symbol(A.member, Decl(file1.ts, 1, 20)) +>a : Symbol(a, Decl(file1.ts, 4, 11)) +>member : Symbol(A.member, Decl(file1.ts, 1, 20)) + +export interface B { +>B : Symbol(B, Decl(file1.ts, 5, 16)) + + member?: string; +>member : Symbol(B.member, Decl(file1.ts, 7, 20)) +} +declare var b: B; +>b : Symbol(b, Decl(file1.ts, 10, 11)) +>B : Symbol(B, Decl(file1.ts, 5, 16)) + +a = b; +>a : Symbol(a, Decl(file1.ts, 4, 11)) +>b : Symbol(b, Decl(file1.ts, 10, 11)) + +b = a; +>b : Symbol(b, Decl(file1.ts, 10, 11)) +>a : Symbol(a, Decl(file1.ts, 4, 11)) + +=== tests/cases/conformance/pragma/exactOptionalPropertyTypes/file2.ts === +// @ts-exactOptionalPropertyTypes true +export interface A { +>A : Symbol(A, Decl(file2.ts, 0, 0)) + + member: string | undefined; +>member : Symbol(A.member, Decl(file2.ts, 1, 20)) +} +declare var a: A; +>a : Symbol(a, Decl(file2.ts, 4, 11)) +>A : Symbol(A, Decl(file2.ts, 0, 0)) + +delete a.member; +>a.member : Symbol(A.member, Decl(file2.ts, 1, 20)) +>a : Symbol(a, Decl(file2.ts, 4, 11)) +>member : Symbol(A.member, Decl(file2.ts, 1, 20)) + +export interface B { +>B : Symbol(B, Decl(file2.ts, 5, 16)) + + member?: string; +>member : Symbol(B.member, Decl(file2.ts, 7, 20)) +} +declare var b: B; +>b : Symbol(b, Decl(file2.ts, 10, 11)) +>B : Symbol(B, Decl(file2.ts, 5, 16)) + +a = b; +>a : Symbol(a, Decl(file2.ts, 4, 11)) +>b : Symbol(b, Decl(file2.ts, 10, 11)) + +b = a; +>b : Symbol(b, Decl(file2.ts, 10, 11)) +>a : Symbol(a, Decl(file2.ts, 4, 11)) + +=== tests/cases/conformance/pragma/exactOptionalPropertyTypes/file3.ts === +// @ts-exactOptionalPropertyTypes false +export interface A { +>A : Symbol(A, Decl(file3.ts, 0, 0)) + + member: string | undefined; +>member : Symbol(A.member, Decl(file3.ts, 1, 20)) +} +declare var a: A; +>a : Symbol(a, Decl(file3.ts, 4, 11)) +>A : Symbol(A, Decl(file3.ts, 0, 0)) + +delete a.member; +>a.member : Symbol(A.member, Decl(file3.ts, 1, 20)) +>a : Symbol(a, Decl(file3.ts, 4, 11)) +>member : Symbol(A.member, Decl(file3.ts, 1, 20)) + +export interface B { +>B : Symbol(B, Decl(file3.ts, 5, 16)) + + member?: string; +>member : Symbol(B.member, Decl(file3.ts, 7, 20)) +} +declare var b: B; +>b : Symbol(b, Decl(file3.ts, 10, 11)) +>B : Symbol(B, Decl(file3.ts, 5, 16)) + +a = b; +>a : Symbol(a, Decl(file3.ts, 4, 11)) +>b : Symbol(b, Decl(file3.ts, 10, 11)) + +b = a; +>b : Symbol(b, Decl(file3.ts, 10, 11)) +>a : Symbol(a, Decl(file3.ts, 4, 11)) + +=== tests/cases/conformance/pragma/exactOptionalPropertyTypes/file4.ts === +export interface A { +>A : Symbol(A, Decl(file4.ts, 0, 0)) + + member: string | undefined; +>member : Symbol(A.member, Decl(file4.ts, 0, 20)) +} +declare var a: A; +>a : Symbol(a, Decl(file4.ts, 3, 11)) +>A : Symbol(A, Decl(file4.ts, 0, 0)) + +delete a.member; +>a.member : Symbol(A.member, Decl(file4.ts, 0, 20)) +>a : Symbol(a, Decl(file4.ts, 3, 11)) +>member : Symbol(A.member, Decl(file4.ts, 0, 20)) + +export interface B { +>B : Symbol(B, Decl(file4.ts, 4, 16)) + + member?: string; +>member : Symbol(B.member, Decl(file4.ts, 6, 20)) +} +declare var b: B; +>b : Symbol(b, Decl(file4.ts, 9, 11)) +>B : Symbol(B, Decl(file4.ts, 4, 16)) + +a = b; +>a : Symbol(a, Decl(file4.ts, 3, 11)) +>b : Symbol(b, Decl(file4.ts, 9, 11)) + +b = a; +>b : Symbol(b, Decl(file4.ts, 9, 11)) +>a : Symbol(a, Decl(file4.ts, 3, 11)) + +=== tests/cases/conformance/pragma/exactOptionalPropertyTypes/file5.ts === +// @ts-exactOptionalPropertyTypes true +import {A as A1, B as B1} from "./file2"; +>A : Symbol(A1, Decl(file2.ts, 0, 0)) +>A1 : Symbol(A1, Decl(file5.ts, 1, 8)) +>B : Symbol(B1, Decl(file2.ts, 5, 16)) +>B1 : Symbol(B1, Decl(file5.ts, 1, 16)) + +import {A as A2, B as B2} from "./file3"; +>A : Symbol(A2, Decl(file3.ts, 0, 0)) +>A2 : Symbol(A2, Decl(file5.ts, 2, 8)) +>B : Symbol(B2, Decl(file3.ts, 5, 16)) +>B2 : Symbol(B2, Decl(file5.ts, 2, 16)) + +declare var a1: A1, b1: B2, a2: A2, b2: B2; +>a1 : Symbol(a1, Decl(file5.ts, 4, 11)) +>A1 : Symbol(A1, Decl(file5.ts, 1, 8)) +>b1 : Symbol(b1, Decl(file5.ts, 4, 19)) +>B2 : Symbol(B2, Decl(file5.ts, 2, 16)) +>a2 : Symbol(a2, Decl(file5.ts, 4, 27)) +>A2 : Symbol(A2, Decl(file5.ts, 2, 8)) +>b2 : Symbol(b2, Decl(file5.ts, 4, 35)) +>B2 : Symbol(B2, Decl(file5.ts, 2, 16)) + +a1 = b1; +>a1 : Symbol(a1, Decl(file5.ts, 4, 11)) +>b1 : Symbol(b1, Decl(file5.ts, 4, 19)) + +b1 = a1; +>b1 : Symbol(b1, Decl(file5.ts, 4, 19)) +>a1 : Symbol(a1, Decl(file5.ts, 4, 11)) + +a2 = b2; +>a2 : Symbol(a2, Decl(file5.ts, 4, 27)) +>b2 : Symbol(b2, Decl(file5.ts, 4, 35)) + +b2 = a2; +>b2 : Symbol(b2, Decl(file5.ts, 4, 35)) +>a2 : Symbol(a2, Decl(file5.ts, 4, 27)) + +a1 = a2; +>a1 : Symbol(a1, Decl(file5.ts, 4, 11)) +>a2 : Symbol(a2, Decl(file5.ts, 4, 27)) + +a2 = a1; +>a2 : Symbol(a2, Decl(file5.ts, 4, 27)) +>a1 : Symbol(a1, Decl(file5.ts, 4, 11)) + +b1 = b2; +>b1 : Symbol(b1, Decl(file5.ts, 4, 19)) +>b2 : Symbol(b2, Decl(file5.ts, 4, 35)) + +b2 = b1; +>b2 : Symbol(b2, Decl(file5.ts, 4, 35)) +>b1 : Symbol(b1, Decl(file5.ts, 4, 19)) + +a1 = b2; +>a1 : Symbol(a1, Decl(file5.ts, 4, 11)) +>b2 : Symbol(b2, Decl(file5.ts, 4, 35)) + +b2 = a1; +>b2 : Symbol(b2, Decl(file5.ts, 4, 35)) +>a1 : Symbol(a1, Decl(file5.ts, 4, 11)) + +b1 = a2; +>b1 : Symbol(b1, Decl(file5.ts, 4, 19)) +>a2 : Symbol(a2, Decl(file5.ts, 4, 27)) + +a2 = b1; +>a2 : Symbol(a2, Decl(file5.ts, 4, 27)) +>b1 : Symbol(b1, Decl(file5.ts, 4, 19)) + +=== tests/cases/conformance/pragma/exactOptionalPropertyTypes/file6.ts === +// @ts-exactOptionalPropertyTypes false +import {A as A1, B as B1} from "./file2"; +>A : Symbol(A1, Decl(file2.ts, 0, 0)) +>A1 : Symbol(A1, Decl(file6.ts, 1, 8)) +>B : Symbol(B1, Decl(file2.ts, 5, 16)) +>B1 : Symbol(B1, Decl(file6.ts, 1, 16)) + +import {A as A2, B as B2} from "./file3"; +>A : Symbol(A2, Decl(file3.ts, 0, 0)) +>A2 : Symbol(A2, Decl(file6.ts, 2, 8)) +>B : Symbol(B2, Decl(file3.ts, 5, 16)) +>B2 : Symbol(B2, Decl(file6.ts, 2, 16)) + +declare var a1: A1, b1: B2, a2: A2, b2: B2; +>a1 : Symbol(a1, Decl(file6.ts, 4, 11)) +>A1 : Symbol(A1, Decl(file6.ts, 1, 8)) +>b1 : Symbol(b1, Decl(file6.ts, 4, 19)) +>B2 : Symbol(B2, Decl(file6.ts, 2, 16)) +>a2 : Symbol(a2, Decl(file6.ts, 4, 27)) +>A2 : Symbol(A2, Decl(file6.ts, 2, 8)) +>b2 : Symbol(b2, Decl(file6.ts, 4, 35)) +>B2 : Symbol(B2, Decl(file6.ts, 2, 16)) + +a1 = b1; +>a1 : Symbol(a1, Decl(file6.ts, 4, 11)) +>b1 : Symbol(b1, Decl(file6.ts, 4, 19)) + +b1 = a1; +>b1 : Symbol(b1, Decl(file6.ts, 4, 19)) +>a1 : Symbol(a1, Decl(file6.ts, 4, 11)) + +a2 = b2; +>a2 : Symbol(a2, Decl(file6.ts, 4, 27)) +>b2 : Symbol(b2, Decl(file6.ts, 4, 35)) + +b2 = a2; +>b2 : Symbol(b2, Decl(file6.ts, 4, 35)) +>a2 : Symbol(a2, Decl(file6.ts, 4, 27)) + +a1 = a2; +>a1 : Symbol(a1, Decl(file6.ts, 4, 11)) +>a2 : Symbol(a2, Decl(file6.ts, 4, 27)) + +a2 = a1; +>a2 : Symbol(a2, Decl(file6.ts, 4, 27)) +>a1 : Symbol(a1, Decl(file6.ts, 4, 11)) + +b1 = b2; +>b1 : Symbol(b1, Decl(file6.ts, 4, 19)) +>b2 : Symbol(b2, Decl(file6.ts, 4, 35)) + +b2 = b1; +>b2 : Symbol(b2, Decl(file6.ts, 4, 35)) +>b1 : Symbol(b1, Decl(file6.ts, 4, 19)) + +a1 = b2; +>a1 : Symbol(a1, Decl(file6.ts, 4, 11)) +>b2 : Symbol(b2, Decl(file6.ts, 4, 35)) + +b2 = a1; +>b2 : Symbol(b2, Decl(file6.ts, 4, 35)) +>a1 : Symbol(a1, Decl(file6.ts, 4, 11)) + +b1 = a2; +>b1 : Symbol(b1, Decl(file6.ts, 4, 19)) +>a2 : Symbol(a2, Decl(file6.ts, 4, 27)) + +a2 = b1; +>a2 : Symbol(a2, Decl(file6.ts, 4, 27)) +>b1 : Symbol(b1, Decl(file6.ts, 4, 19)) + diff --git a/tests/baselines/reference/exactOptionalPropertyTypesPragma1.types b/tests/baselines/reference/exactOptionalPropertyTypesPragma1.types new file mode 100644 index 0000000000000..d25d324df97f8 --- /dev/null +++ b/tests/baselines/reference/exactOptionalPropertyTypesPragma1.types @@ -0,0 +1,287 @@ +=== tests/cases/conformance/pragma/exactOptionalPropertyTypes/file1.ts === +// @ts-exactOptionalPropertyTypes +export interface A { + member: string | undefined; +>member : string | undefined +} +declare var a: A; +>a : A + +delete a.member; +>delete a.member : boolean +>a.member : string | undefined +>a : A +>member : string | undefined + +export interface B { + member?: string; +>member : string | undefined +} +declare var b: B; +>b : B + +a = b; +>a = b : B +>a : A +>b : B + +b = a; +>b = a : A +>b : B +>a : A + +=== tests/cases/conformance/pragma/exactOptionalPropertyTypes/file2.ts === +// @ts-exactOptionalPropertyTypes true +export interface A { + member: string | undefined; +>member : string | undefined +} +declare var a: A; +>a : A + +delete a.member; +>delete a.member : boolean +>a.member : string | undefined +>a : A +>member : string | undefined + +export interface B { + member?: string; +>member : string | undefined +} +declare var b: B; +>b : B + +a = b; +>a = b : B +>a : A +>b : B + +b = a; +>b = a : A +>b : B +>a : A + +=== tests/cases/conformance/pragma/exactOptionalPropertyTypes/file3.ts === +// @ts-exactOptionalPropertyTypes false +export interface A { + member: string | undefined; +>member : string | undefined +} +declare var a: A; +>a : A + +delete a.member; +>delete a.member : boolean +>a.member : string | undefined +>a : A +>member : string | undefined + +export interface B { + member?: string; +>member : string | undefined +} +declare var b: B; +>b : B + +a = b; +>a = b : B +>a : A +>b : B + +b = a; +>b = a : A +>b : B +>a : A + +=== tests/cases/conformance/pragma/exactOptionalPropertyTypes/file4.ts === +export interface A { + member: string | undefined; +>member : string | undefined +} +declare var a: A; +>a : A + +delete a.member; +>delete a.member : boolean +>a.member : string | undefined +>a : A +>member : string | undefined + +export interface B { + member?: string; +>member : string | undefined +} +declare var b: B; +>b : B + +a = b; +>a = b : B +>a : A +>b : B + +b = a; +>b = a : A +>b : B +>a : A + +=== tests/cases/conformance/pragma/exactOptionalPropertyTypes/file5.ts === +// @ts-exactOptionalPropertyTypes true +import {A as A1, B as B1} from "./file2"; +>A : any +>A1 : any +>B : any +>B1 : any + +import {A as A2, B as B2} from "./file3"; +>A : any +>A2 : any +>B : any +>B2 : any + +declare var a1: A1, b1: B2, a2: A2, b2: B2; +>a1 : A1 +>b1 : B2 +>a2 : A2 +>b2 : B2 + +a1 = b1; +>a1 = b1 : B2 +>a1 : A1 +>b1 : B2 + +b1 = a1; +>b1 = a1 : A1 +>b1 : B2 +>a1 : A1 + +a2 = b2; +>a2 = b2 : B2 +>a2 : A2 +>b2 : B2 + +b2 = a2; +>b2 = a2 : A2 +>b2 : B2 +>a2 : A2 + +a1 = a2; +>a1 = a2 : A2 +>a1 : A1 +>a2 : A2 + +a2 = a1; +>a2 = a1 : A1 +>a2 : A2 +>a1 : A1 + +b1 = b2; +>b1 = b2 : B2 +>b1 : B2 +>b2 : B2 + +b2 = b1; +>b2 = b1 : B2 +>b2 : B2 +>b1 : B2 + +a1 = b2; +>a1 = b2 : B2 +>a1 : A1 +>b2 : B2 + +b2 = a1; +>b2 = a1 : A1 +>b2 : B2 +>a1 : A1 + +b1 = a2; +>b1 = a2 : A2 +>b1 : B2 +>a2 : A2 + +a2 = b1; +>a2 = b1 : B2 +>a2 : A2 +>b1 : B2 + +=== tests/cases/conformance/pragma/exactOptionalPropertyTypes/file6.ts === +// @ts-exactOptionalPropertyTypes false +import {A as A1, B as B1} from "./file2"; +>A : any +>A1 : any +>B : any +>B1 : any + +import {A as A2, B as B2} from "./file3"; +>A : any +>A2 : any +>B : any +>B2 : any + +declare var a1: A1, b1: B2, a2: A2, b2: B2; +>a1 : A1 +>b1 : B2 +>a2 : A2 +>b2 : B2 + +a1 = b1; +>a1 = b1 : B2 +>a1 : A1 +>b1 : B2 + +b1 = a1; +>b1 = a1 : A1 +>b1 : B2 +>a1 : A1 + +a2 = b2; +>a2 = b2 : B2 +>a2 : A2 +>b2 : B2 + +b2 = a2; +>b2 = a2 : A2 +>b2 : B2 +>a2 : A2 + +a1 = a2; +>a1 = a2 : A2 +>a1 : A1 +>a2 : A2 + +a2 = a1; +>a2 = a1 : A1 +>a2 : A2 +>a1 : A1 + +b1 = b2; +>b1 = b2 : B2 +>b1 : B2 +>b2 : B2 + +b2 = b1; +>b2 = b1 : B2 +>b2 : B2 +>b1 : B2 + +a1 = b2; +>a1 = b2 : B2 +>a1 : A1 +>b2 : B2 + +b2 = a1; +>b2 = a1 : A1 +>b2 : B2 +>a1 : A1 + +b1 = a2; +>b1 = a2 : A2 +>b1 : B2 +>a2 : A2 + +a2 = b1; +>a2 = b1 : B2 +>a2 : A2 +>b1 : B2 + diff --git a/tests/baselines/reference/exactOptionalPropertyTypesPragma2.errors.txt b/tests/baselines/reference/exactOptionalPropertyTypesPragma2.errors.txt new file mode 100644 index 0000000000000..01b0ce3d4436d --- /dev/null +++ b/tests/baselines/reference/exactOptionalPropertyTypesPragma2.errors.txt @@ -0,0 +1,192 @@ +tests/cases/conformance/pragma/exactOptionalPropertyTypes/file1.ts(6,8): error TS2790: The operand of a 'delete' operator must be optional. +tests/cases/conformance/pragma/exactOptionalPropertyTypes/file1.ts(12,1): error TS2322: Type 'B' is not assignable to type 'A'. + Property 'member' is optional in type 'B' but required in type 'A'. +tests/cases/conformance/pragma/exactOptionalPropertyTypes/file1.ts(13,1): error TS2375: Type 'A' is not assignable to type 'B' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties. + Types of property 'member' are incompatible. + Type 'string | undefined' is not assignable to type 'string'. + Type 'undefined' is not assignable to type 'string'. +tests/cases/conformance/pragma/exactOptionalPropertyTypes/file2.ts(6,8): error TS2790: The operand of a 'delete' operator must be optional. +tests/cases/conformance/pragma/exactOptionalPropertyTypes/file2.ts(12,1): error TS2322: Type 'B' is not assignable to type 'A'. + Property 'member' is optional in type 'B' but required in type 'A'. +tests/cases/conformance/pragma/exactOptionalPropertyTypes/file2.ts(13,1): error TS2375: Type 'A' is not assignable to type 'B' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties. + Types of property 'member' are incompatible. + Type 'string | undefined' is not assignable to type 'string'. + Type 'undefined' is not assignable to type 'string'. +tests/cases/conformance/pragma/exactOptionalPropertyTypes/file3.ts(12,1): error TS2322: Type 'B' is not assignable to type 'A'. + Property 'member' is optional in type 'B' but required in type 'A'. +tests/cases/conformance/pragma/exactOptionalPropertyTypes/file4.ts(5,8): error TS2790: The operand of a 'delete' operator must be optional. +tests/cases/conformance/pragma/exactOptionalPropertyTypes/file4.ts(11,1): error TS2322: Type 'B' is not assignable to type 'A'. + Property 'member' is optional in type 'B' but required in type 'A'. +tests/cases/conformance/pragma/exactOptionalPropertyTypes/file4.ts(12,1): error TS2375: Type 'A' is not assignable to type 'B' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties. + Types of property 'member' are incompatible. + Type 'string | undefined' is not assignable to type 'string'. + Type 'undefined' is not assignable to type 'string'. +tests/cases/conformance/pragma/exactOptionalPropertyTypes/file5.ts(7,1): error TS2322: Type 'B' is not assignable to type 'A'. + Property 'member' is optional in type 'B' but required in type 'A'. +tests/cases/conformance/pragma/exactOptionalPropertyTypes/file5.ts(10,1): error TS2322: Type 'B' is not assignable to type 'A'. +tests/cases/conformance/pragma/exactOptionalPropertyTypes/file5.ts(19,1): error TS2322: Type 'B' is not assignable to type 'A'. +tests/cases/conformance/pragma/exactOptionalPropertyTypes/file5.ts(23,1): error TS2322: Type 'B' is not assignable to type 'A'. +tests/cases/conformance/pragma/exactOptionalPropertyTypes/file6.ts(7,1): error TS2322: Type 'B' is not assignable to type 'A'. +tests/cases/conformance/pragma/exactOptionalPropertyTypes/file6.ts(10,1): error TS2322: Type 'B' is not assignable to type 'A'. +tests/cases/conformance/pragma/exactOptionalPropertyTypes/file6.ts(19,1): error TS2322: Type 'B' is not assignable to type 'A'. +tests/cases/conformance/pragma/exactOptionalPropertyTypes/file6.ts(23,1): error TS2322: Type 'B' is not assignable to type 'A'. + + +==== tests/cases/conformance/pragma/exactOptionalPropertyTypes/file1.ts (3 errors) ==== + // @ts-exactOptionalPropertyTypes + export interface A { + member: string | undefined; + } + declare var a: A; + delete a.member; + ~~~~~~~~ +!!! error TS2790: The operand of a 'delete' operator must be optional. + + export interface B { + member?: string; + } + declare var b: B; + a = b; + ~ +!!! error TS2322: Type 'B' is not assignable to type 'A'. +!!! error TS2322: Property 'member' is optional in type 'B' but required in type 'A'. + b = a; + ~ +!!! error TS2375: Type 'A' is not assignable to type 'B' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties. +!!! error TS2375: Types of property 'member' are incompatible. +!!! error TS2375: Type 'string | undefined' is not assignable to type 'string'. +!!! error TS2375: Type 'undefined' is not assignable to type 'string'. + +==== tests/cases/conformance/pragma/exactOptionalPropertyTypes/file2.ts (3 errors) ==== + // @ts-exactOptionalPropertyTypes true + export interface A { + member: string | undefined; + } + declare var a: A; + delete a.member; + ~~~~~~~~ +!!! error TS2790: The operand of a 'delete' operator must be optional. + + export interface B { + member?: string; + } + declare var b: B; + a = b; + ~ +!!! error TS2322: Type 'B' is not assignable to type 'A'. +!!! error TS2322: Property 'member' is optional in type 'B' but required in type 'A'. + b = a; + ~ +!!! error TS2375: Type 'A' is not assignable to type 'B' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties. +!!! error TS2375: Types of property 'member' are incompatible. +!!! error TS2375: Type 'string | undefined' is not assignable to type 'string'. +!!! error TS2375: Type 'undefined' is not assignable to type 'string'. + +==== tests/cases/conformance/pragma/exactOptionalPropertyTypes/file3.ts (1 errors) ==== + // @ts-exactOptionalPropertyTypes false + export interface A { + member: string | undefined; + } + declare var a: A; + delete a.member; + + export interface B { + member?: string; + } + declare var b: B; + a = b; + ~ +!!! error TS2322: Type 'B' is not assignable to type 'A'. +!!! error TS2322: Property 'member' is optional in type 'B' but required in type 'A'. + b = a; + +==== tests/cases/conformance/pragma/exactOptionalPropertyTypes/file4.ts (3 errors) ==== + export interface A { + member: string | undefined; + } + declare var a: A; + delete a.member; + ~~~~~~~~ +!!! error TS2790: The operand of a 'delete' operator must be optional. + + export interface B { + member?: string; + } + declare var b: B; + a = b; + ~ +!!! error TS2322: Type 'B' is not assignable to type 'A'. +!!! error TS2322: Property 'member' is optional in type 'B' but required in type 'A'. + b = a; + ~ +!!! error TS2375: Type 'A' is not assignable to type 'B' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties. +!!! error TS2375: Types of property 'member' are incompatible. +!!! error TS2375: Type 'string | undefined' is not assignable to type 'string'. +!!! error TS2375: Type 'undefined' is not assignable to type 'string'. + +==== tests/cases/conformance/pragma/exactOptionalPropertyTypes/file5.ts (4 errors) ==== + // @ts-exactOptionalPropertyTypes true + import {A as A1, B as B1} from "./file2"; + import {A as A2, B as B2} from "./file3"; + + declare var a1: A1, b1: B2, a2: A2, b2: B2; + + a1 = b1; + ~~ +!!! error TS2322: Type 'B' is not assignable to type 'A'. +!!! error TS2322: Property 'member' is optional in type 'B' but required in type 'A'. + b1 = a1; + + a2 = b2; + ~~ +!!! error TS2322: Type 'B' is not assignable to type 'A'. + b2 = a2; + + a1 = a2; + a2 = a1; + + b1 = b2; + b2 = b1; + + a1 = b2; + ~~ +!!! error TS2322: Type 'B' is not assignable to type 'A'. + b2 = a1; + + b1 = a2; + a2 = b1; + ~~ +!!! error TS2322: Type 'B' is not assignable to type 'A'. + +==== tests/cases/conformance/pragma/exactOptionalPropertyTypes/file6.ts (4 errors) ==== + // @ts-exactOptionalPropertyTypes false + import {A as A1, B as B1} from "./file2"; + import {A as A2, B as B2} from "./file3"; + + declare var a1: A1, b1: B2, a2: A2, b2: B2; + + a1 = b1; + ~~ +!!! error TS2322: Type 'B' is not assignable to type 'A'. + b1 = a1; + + a2 = b2; + ~~ +!!! error TS2322: Type 'B' is not assignable to type 'A'. + b2 = a2; + + a1 = a2; + a2 = a1; + + b1 = b2; + b2 = b1; + + a1 = b2; + ~~ +!!! error TS2322: Type 'B' is not assignable to type 'A'. + b2 = a1; + + b1 = a2; + a2 = b1; + ~~ +!!! error TS2322: Type 'B' is not assignable to type 'A'. \ No newline at end of file diff --git a/tests/baselines/reference/exactOptionalPropertyTypesPragma2.js b/tests/baselines/reference/exactOptionalPropertyTypesPragma2.js new file mode 100644 index 0000000000000..a87f00c3211df --- /dev/null +++ b/tests/baselines/reference/exactOptionalPropertyTypesPragma2.js @@ -0,0 +1,165 @@ +//// [tests/cases/conformance/pragma/exactOptionalPropertyTypes/exactOptionalPropertyTypesPragma2.ts] //// + +//// [file1.ts] +// @ts-exactOptionalPropertyTypes +export interface A { + member: string | undefined; +} +declare var a: A; +delete a.member; + +export interface B { + member?: string; +} +declare var b: B; +a = b; +b = a; + +//// [file2.ts] +// @ts-exactOptionalPropertyTypes true +export interface A { + member: string | undefined; +} +declare var a: A; +delete a.member; + +export interface B { + member?: string; +} +declare var b: B; +a = b; +b = a; + +//// [file3.ts] +// @ts-exactOptionalPropertyTypes false +export interface A { + member: string | undefined; +} +declare var a: A; +delete a.member; + +export interface B { + member?: string; +} +declare var b: B; +a = b; +b = a; + +//// [file4.ts] +export interface A { + member: string | undefined; +} +declare var a: A; +delete a.member; + +export interface B { + member?: string; +} +declare var b: B; +a = b; +b = a; + +//// [file5.ts] +// @ts-exactOptionalPropertyTypes true +import {A as A1, B as B1} from "./file2"; +import {A as A2, B as B2} from "./file3"; + +declare var a1: A1, b1: B2, a2: A2, b2: B2; + +a1 = b1; +b1 = a1; + +a2 = b2; +b2 = a2; + +a1 = a2; +a2 = a1; + +b1 = b2; +b2 = b1; + +a1 = b2; +b2 = a1; + +b1 = a2; +a2 = b1; + +//// [file6.ts] +// @ts-exactOptionalPropertyTypes false +import {A as A1, B as B1} from "./file2"; +import {A as A2, B as B2} from "./file3"; + +declare var a1: A1, b1: B2, a2: A2, b2: B2; + +a1 = b1; +b1 = a1; + +a2 = b2; +b2 = a2; + +a1 = a2; +a2 = a1; + +b1 = b2; +b2 = b1; + +a1 = b2; +b2 = a1; + +b1 = a2; +a2 = b1; + +//// [file1.js] +"use strict"; +exports.__esModule = true; +delete a.member; +a = b; +b = a; +//// [file2.js] +"use strict"; +exports.__esModule = true; +delete a.member; +a = b; +b = a; +//// [file3.js] +"use strict"; +exports.__esModule = true; +delete a.member; +a = b; +b = a; +//// [file4.js] +"use strict"; +exports.__esModule = true; +delete a.member; +a = b; +b = a; +//// [file5.js] +"use strict"; +exports.__esModule = true; +a1 = b1; +b1 = a1; +a2 = b2; +b2 = a2; +a1 = a2; +a2 = a1; +b1 = b2; +b2 = b1; +a1 = b2; +b2 = a1; +b1 = a2; +a2 = b1; +//// [file6.js] +"use strict"; +exports.__esModule = true; +a1 = b1; +b1 = a1; +a2 = b2; +b2 = a2; +a1 = a2; +a2 = a1; +b1 = b2; +b2 = b1; +a1 = b2; +b2 = a1; +b1 = a2; +a2 = b1; diff --git a/tests/baselines/reference/exactOptionalPropertyTypesPragma2.symbols b/tests/baselines/reference/exactOptionalPropertyTypesPragma2.symbols new file mode 100644 index 0000000000000..3f39098c5ef3d --- /dev/null +++ b/tests/baselines/reference/exactOptionalPropertyTypesPragma2.symbols @@ -0,0 +1,283 @@ +=== tests/cases/conformance/pragma/exactOptionalPropertyTypes/file1.ts === +// @ts-exactOptionalPropertyTypes +export interface A { +>A : Symbol(A, Decl(file1.ts, 0, 0)) + + member: string | undefined; +>member : Symbol(A.member, Decl(file1.ts, 1, 20)) +} +declare var a: A; +>a : Symbol(a, Decl(file1.ts, 4, 11)) +>A : Symbol(A, Decl(file1.ts, 0, 0)) + +delete a.member; +>a.member : Symbol(A.member, Decl(file1.ts, 1, 20)) +>a : Symbol(a, Decl(file1.ts, 4, 11)) +>member : Symbol(A.member, Decl(file1.ts, 1, 20)) + +export interface B { +>B : Symbol(B, Decl(file1.ts, 5, 16)) + + member?: string; +>member : Symbol(B.member, Decl(file1.ts, 7, 20)) +} +declare var b: B; +>b : Symbol(b, Decl(file1.ts, 10, 11)) +>B : Symbol(B, Decl(file1.ts, 5, 16)) + +a = b; +>a : Symbol(a, Decl(file1.ts, 4, 11)) +>b : Symbol(b, Decl(file1.ts, 10, 11)) + +b = a; +>b : Symbol(b, Decl(file1.ts, 10, 11)) +>a : Symbol(a, Decl(file1.ts, 4, 11)) + +=== tests/cases/conformance/pragma/exactOptionalPropertyTypes/file2.ts === +// @ts-exactOptionalPropertyTypes true +export interface A { +>A : Symbol(A, Decl(file2.ts, 0, 0)) + + member: string | undefined; +>member : Symbol(A.member, Decl(file2.ts, 1, 20)) +} +declare var a: A; +>a : Symbol(a, Decl(file2.ts, 4, 11)) +>A : Symbol(A, Decl(file2.ts, 0, 0)) + +delete a.member; +>a.member : Symbol(A.member, Decl(file2.ts, 1, 20)) +>a : Symbol(a, Decl(file2.ts, 4, 11)) +>member : Symbol(A.member, Decl(file2.ts, 1, 20)) + +export interface B { +>B : Symbol(B, Decl(file2.ts, 5, 16)) + + member?: string; +>member : Symbol(B.member, Decl(file2.ts, 7, 20)) +} +declare var b: B; +>b : Symbol(b, Decl(file2.ts, 10, 11)) +>B : Symbol(B, Decl(file2.ts, 5, 16)) + +a = b; +>a : Symbol(a, Decl(file2.ts, 4, 11)) +>b : Symbol(b, Decl(file2.ts, 10, 11)) + +b = a; +>b : Symbol(b, Decl(file2.ts, 10, 11)) +>a : Symbol(a, Decl(file2.ts, 4, 11)) + +=== tests/cases/conformance/pragma/exactOptionalPropertyTypes/file3.ts === +// @ts-exactOptionalPropertyTypes false +export interface A { +>A : Symbol(A, Decl(file3.ts, 0, 0)) + + member: string | undefined; +>member : Symbol(A.member, Decl(file3.ts, 1, 20)) +} +declare var a: A; +>a : Symbol(a, Decl(file3.ts, 4, 11)) +>A : Symbol(A, Decl(file3.ts, 0, 0)) + +delete a.member; +>a.member : Symbol(A.member, Decl(file3.ts, 1, 20)) +>a : Symbol(a, Decl(file3.ts, 4, 11)) +>member : Symbol(A.member, Decl(file3.ts, 1, 20)) + +export interface B { +>B : Symbol(B, Decl(file3.ts, 5, 16)) + + member?: string; +>member : Symbol(B.member, Decl(file3.ts, 7, 20)) +} +declare var b: B; +>b : Symbol(b, Decl(file3.ts, 10, 11)) +>B : Symbol(B, Decl(file3.ts, 5, 16)) + +a = b; +>a : Symbol(a, Decl(file3.ts, 4, 11)) +>b : Symbol(b, Decl(file3.ts, 10, 11)) + +b = a; +>b : Symbol(b, Decl(file3.ts, 10, 11)) +>a : Symbol(a, Decl(file3.ts, 4, 11)) + +=== tests/cases/conformance/pragma/exactOptionalPropertyTypes/file4.ts === +export interface A { +>A : Symbol(A, Decl(file4.ts, 0, 0)) + + member: string | undefined; +>member : Symbol(A.member, Decl(file4.ts, 0, 20)) +} +declare var a: A; +>a : Symbol(a, Decl(file4.ts, 3, 11)) +>A : Symbol(A, Decl(file4.ts, 0, 0)) + +delete a.member; +>a.member : Symbol(A.member, Decl(file4.ts, 0, 20)) +>a : Symbol(a, Decl(file4.ts, 3, 11)) +>member : Symbol(A.member, Decl(file4.ts, 0, 20)) + +export interface B { +>B : Symbol(B, Decl(file4.ts, 4, 16)) + + member?: string; +>member : Symbol(B.member, Decl(file4.ts, 6, 20)) +} +declare var b: B; +>b : Symbol(b, Decl(file4.ts, 9, 11)) +>B : Symbol(B, Decl(file4.ts, 4, 16)) + +a = b; +>a : Symbol(a, Decl(file4.ts, 3, 11)) +>b : Symbol(b, Decl(file4.ts, 9, 11)) + +b = a; +>b : Symbol(b, Decl(file4.ts, 9, 11)) +>a : Symbol(a, Decl(file4.ts, 3, 11)) + +=== tests/cases/conformance/pragma/exactOptionalPropertyTypes/file5.ts === +// @ts-exactOptionalPropertyTypes true +import {A as A1, B as B1} from "./file2"; +>A : Symbol(A1, Decl(file2.ts, 0, 0)) +>A1 : Symbol(A1, Decl(file5.ts, 1, 8)) +>B : Symbol(B1, Decl(file2.ts, 5, 16)) +>B1 : Symbol(B1, Decl(file5.ts, 1, 16)) + +import {A as A2, B as B2} from "./file3"; +>A : Symbol(A2, Decl(file3.ts, 0, 0)) +>A2 : Symbol(A2, Decl(file5.ts, 2, 8)) +>B : Symbol(B2, Decl(file3.ts, 5, 16)) +>B2 : Symbol(B2, Decl(file5.ts, 2, 16)) + +declare var a1: A1, b1: B2, a2: A2, b2: B2; +>a1 : Symbol(a1, Decl(file5.ts, 4, 11)) +>A1 : Symbol(A1, Decl(file5.ts, 1, 8)) +>b1 : Symbol(b1, Decl(file5.ts, 4, 19)) +>B2 : Symbol(B2, Decl(file5.ts, 2, 16)) +>a2 : Symbol(a2, Decl(file5.ts, 4, 27)) +>A2 : Symbol(A2, Decl(file5.ts, 2, 8)) +>b2 : Symbol(b2, Decl(file5.ts, 4, 35)) +>B2 : Symbol(B2, Decl(file5.ts, 2, 16)) + +a1 = b1; +>a1 : Symbol(a1, Decl(file5.ts, 4, 11)) +>b1 : Symbol(b1, Decl(file5.ts, 4, 19)) + +b1 = a1; +>b1 : Symbol(b1, Decl(file5.ts, 4, 19)) +>a1 : Symbol(a1, Decl(file5.ts, 4, 11)) + +a2 = b2; +>a2 : Symbol(a2, Decl(file5.ts, 4, 27)) +>b2 : Symbol(b2, Decl(file5.ts, 4, 35)) + +b2 = a2; +>b2 : Symbol(b2, Decl(file5.ts, 4, 35)) +>a2 : Symbol(a2, Decl(file5.ts, 4, 27)) + +a1 = a2; +>a1 : Symbol(a1, Decl(file5.ts, 4, 11)) +>a2 : Symbol(a2, Decl(file5.ts, 4, 27)) + +a2 = a1; +>a2 : Symbol(a2, Decl(file5.ts, 4, 27)) +>a1 : Symbol(a1, Decl(file5.ts, 4, 11)) + +b1 = b2; +>b1 : Symbol(b1, Decl(file5.ts, 4, 19)) +>b2 : Symbol(b2, Decl(file5.ts, 4, 35)) + +b2 = b1; +>b2 : Symbol(b2, Decl(file5.ts, 4, 35)) +>b1 : Symbol(b1, Decl(file5.ts, 4, 19)) + +a1 = b2; +>a1 : Symbol(a1, Decl(file5.ts, 4, 11)) +>b2 : Symbol(b2, Decl(file5.ts, 4, 35)) + +b2 = a1; +>b2 : Symbol(b2, Decl(file5.ts, 4, 35)) +>a1 : Symbol(a1, Decl(file5.ts, 4, 11)) + +b1 = a2; +>b1 : Symbol(b1, Decl(file5.ts, 4, 19)) +>a2 : Symbol(a2, Decl(file5.ts, 4, 27)) + +a2 = b1; +>a2 : Symbol(a2, Decl(file5.ts, 4, 27)) +>b1 : Symbol(b1, Decl(file5.ts, 4, 19)) + +=== tests/cases/conformance/pragma/exactOptionalPropertyTypes/file6.ts === +// @ts-exactOptionalPropertyTypes false +import {A as A1, B as B1} from "./file2"; +>A : Symbol(A1, Decl(file2.ts, 0, 0)) +>A1 : Symbol(A1, Decl(file6.ts, 1, 8)) +>B : Symbol(B1, Decl(file2.ts, 5, 16)) +>B1 : Symbol(B1, Decl(file6.ts, 1, 16)) + +import {A as A2, B as B2} from "./file3"; +>A : Symbol(A2, Decl(file3.ts, 0, 0)) +>A2 : Symbol(A2, Decl(file6.ts, 2, 8)) +>B : Symbol(B2, Decl(file3.ts, 5, 16)) +>B2 : Symbol(B2, Decl(file6.ts, 2, 16)) + +declare var a1: A1, b1: B2, a2: A2, b2: B2; +>a1 : Symbol(a1, Decl(file6.ts, 4, 11)) +>A1 : Symbol(A1, Decl(file6.ts, 1, 8)) +>b1 : Symbol(b1, Decl(file6.ts, 4, 19)) +>B2 : Symbol(B2, Decl(file6.ts, 2, 16)) +>a2 : Symbol(a2, Decl(file6.ts, 4, 27)) +>A2 : Symbol(A2, Decl(file6.ts, 2, 8)) +>b2 : Symbol(b2, Decl(file6.ts, 4, 35)) +>B2 : Symbol(B2, Decl(file6.ts, 2, 16)) + +a1 = b1; +>a1 : Symbol(a1, Decl(file6.ts, 4, 11)) +>b1 : Symbol(b1, Decl(file6.ts, 4, 19)) + +b1 = a1; +>b1 : Symbol(b1, Decl(file6.ts, 4, 19)) +>a1 : Symbol(a1, Decl(file6.ts, 4, 11)) + +a2 = b2; +>a2 : Symbol(a2, Decl(file6.ts, 4, 27)) +>b2 : Symbol(b2, Decl(file6.ts, 4, 35)) + +b2 = a2; +>b2 : Symbol(b2, Decl(file6.ts, 4, 35)) +>a2 : Symbol(a2, Decl(file6.ts, 4, 27)) + +a1 = a2; +>a1 : Symbol(a1, Decl(file6.ts, 4, 11)) +>a2 : Symbol(a2, Decl(file6.ts, 4, 27)) + +a2 = a1; +>a2 : Symbol(a2, Decl(file6.ts, 4, 27)) +>a1 : Symbol(a1, Decl(file6.ts, 4, 11)) + +b1 = b2; +>b1 : Symbol(b1, Decl(file6.ts, 4, 19)) +>b2 : Symbol(b2, Decl(file6.ts, 4, 35)) + +b2 = b1; +>b2 : Symbol(b2, Decl(file6.ts, 4, 35)) +>b1 : Symbol(b1, Decl(file6.ts, 4, 19)) + +a1 = b2; +>a1 : Symbol(a1, Decl(file6.ts, 4, 11)) +>b2 : Symbol(b2, Decl(file6.ts, 4, 35)) + +b2 = a1; +>b2 : Symbol(b2, Decl(file6.ts, 4, 35)) +>a1 : Symbol(a1, Decl(file6.ts, 4, 11)) + +b1 = a2; +>b1 : Symbol(b1, Decl(file6.ts, 4, 19)) +>a2 : Symbol(a2, Decl(file6.ts, 4, 27)) + +a2 = b1; +>a2 : Symbol(a2, Decl(file6.ts, 4, 27)) +>b1 : Symbol(b1, Decl(file6.ts, 4, 19)) + diff --git a/tests/baselines/reference/exactOptionalPropertyTypesPragma2.types b/tests/baselines/reference/exactOptionalPropertyTypesPragma2.types new file mode 100644 index 0000000000000..d25d324df97f8 --- /dev/null +++ b/tests/baselines/reference/exactOptionalPropertyTypesPragma2.types @@ -0,0 +1,287 @@ +=== tests/cases/conformance/pragma/exactOptionalPropertyTypes/file1.ts === +// @ts-exactOptionalPropertyTypes +export interface A { + member: string | undefined; +>member : string | undefined +} +declare var a: A; +>a : A + +delete a.member; +>delete a.member : boolean +>a.member : string | undefined +>a : A +>member : string | undefined + +export interface B { + member?: string; +>member : string | undefined +} +declare var b: B; +>b : B + +a = b; +>a = b : B +>a : A +>b : B + +b = a; +>b = a : A +>b : B +>a : A + +=== tests/cases/conformance/pragma/exactOptionalPropertyTypes/file2.ts === +// @ts-exactOptionalPropertyTypes true +export interface A { + member: string | undefined; +>member : string | undefined +} +declare var a: A; +>a : A + +delete a.member; +>delete a.member : boolean +>a.member : string | undefined +>a : A +>member : string | undefined + +export interface B { + member?: string; +>member : string | undefined +} +declare var b: B; +>b : B + +a = b; +>a = b : B +>a : A +>b : B + +b = a; +>b = a : A +>b : B +>a : A + +=== tests/cases/conformance/pragma/exactOptionalPropertyTypes/file3.ts === +// @ts-exactOptionalPropertyTypes false +export interface A { + member: string | undefined; +>member : string | undefined +} +declare var a: A; +>a : A + +delete a.member; +>delete a.member : boolean +>a.member : string | undefined +>a : A +>member : string | undefined + +export interface B { + member?: string; +>member : string | undefined +} +declare var b: B; +>b : B + +a = b; +>a = b : B +>a : A +>b : B + +b = a; +>b = a : A +>b : B +>a : A + +=== tests/cases/conformance/pragma/exactOptionalPropertyTypes/file4.ts === +export interface A { + member: string | undefined; +>member : string | undefined +} +declare var a: A; +>a : A + +delete a.member; +>delete a.member : boolean +>a.member : string | undefined +>a : A +>member : string | undefined + +export interface B { + member?: string; +>member : string | undefined +} +declare var b: B; +>b : B + +a = b; +>a = b : B +>a : A +>b : B + +b = a; +>b = a : A +>b : B +>a : A + +=== tests/cases/conformance/pragma/exactOptionalPropertyTypes/file5.ts === +// @ts-exactOptionalPropertyTypes true +import {A as A1, B as B1} from "./file2"; +>A : any +>A1 : any +>B : any +>B1 : any + +import {A as A2, B as B2} from "./file3"; +>A : any +>A2 : any +>B : any +>B2 : any + +declare var a1: A1, b1: B2, a2: A2, b2: B2; +>a1 : A1 +>b1 : B2 +>a2 : A2 +>b2 : B2 + +a1 = b1; +>a1 = b1 : B2 +>a1 : A1 +>b1 : B2 + +b1 = a1; +>b1 = a1 : A1 +>b1 : B2 +>a1 : A1 + +a2 = b2; +>a2 = b2 : B2 +>a2 : A2 +>b2 : B2 + +b2 = a2; +>b2 = a2 : A2 +>b2 : B2 +>a2 : A2 + +a1 = a2; +>a1 = a2 : A2 +>a1 : A1 +>a2 : A2 + +a2 = a1; +>a2 = a1 : A1 +>a2 : A2 +>a1 : A1 + +b1 = b2; +>b1 = b2 : B2 +>b1 : B2 +>b2 : B2 + +b2 = b1; +>b2 = b1 : B2 +>b2 : B2 +>b1 : B2 + +a1 = b2; +>a1 = b2 : B2 +>a1 : A1 +>b2 : B2 + +b2 = a1; +>b2 = a1 : A1 +>b2 : B2 +>a1 : A1 + +b1 = a2; +>b1 = a2 : A2 +>b1 : B2 +>a2 : A2 + +a2 = b1; +>a2 = b1 : B2 +>a2 : A2 +>b1 : B2 + +=== tests/cases/conformance/pragma/exactOptionalPropertyTypes/file6.ts === +// @ts-exactOptionalPropertyTypes false +import {A as A1, B as B1} from "./file2"; +>A : any +>A1 : any +>B : any +>B1 : any + +import {A as A2, B as B2} from "./file3"; +>A : any +>A2 : any +>B : any +>B2 : any + +declare var a1: A1, b1: B2, a2: A2, b2: B2; +>a1 : A1 +>b1 : B2 +>a2 : A2 +>b2 : B2 + +a1 = b1; +>a1 = b1 : B2 +>a1 : A1 +>b1 : B2 + +b1 = a1; +>b1 = a1 : A1 +>b1 : B2 +>a1 : A1 + +a2 = b2; +>a2 = b2 : B2 +>a2 : A2 +>b2 : B2 + +b2 = a2; +>b2 = a2 : A2 +>b2 : B2 +>a2 : A2 + +a1 = a2; +>a1 = a2 : A2 +>a1 : A1 +>a2 : A2 + +a2 = a1; +>a2 = a1 : A1 +>a2 : A2 +>a1 : A1 + +b1 = b2; +>b1 = b2 : B2 +>b1 : B2 +>b2 : B2 + +b2 = b1; +>b2 = b1 : B2 +>b2 : B2 +>b1 : B2 + +a1 = b2; +>a1 = b2 : B2 +>a1 : A1 +>b2 : B2 + +b2 = a1; +>b2 = a1 : A1 +>b2 : B2 +>a1 : A1 + +b1 = a2; +>b1 = a2 : A2 +>b1 : B2 +>a2 : A2 + +a2 = b1; +>a2 = b1 : B2 +>a2 : A2 +>b1 : B2 + diff --git a/tests/baselines/reference/noFallthroughCasesInSwitchPragma1.errors.txt b/tests/baselines/reference/noFallthroughCasesInSwitchPragma1.errors.txt new file mode 100644 index 0000000000000..d83c11a2baff8 --- /dev/null +++ b/tests/baselines/reference/noFallthroughCasesInSwitchPragma1.errors.txt @@ -0,0 +1,59 @@ +tests/cases/conformance/pragma/noFallthroughCasesInSwitch/file1.ts(4,9): error TS7029: Fallthrough case in switch. +tests/cases/conformance/pragma/noFallthroughCasesInSwitch/file2.ts(4,9): error TS7029: Fallthrough case in switch. + + +==== tests/cases/conformance/pragma/noFallthroughCasesInSwitch/file1.ts (1 errors) ==== + // @ts-noFallthroughCasesInSwitch + export function f1(thing: "a" | "b") { + switch (thing) { + case "a": + ~~~~~~~~~ +!!! error TS7029: Fallthrough case in switch. + thing; + case "b": + thing; + break; + } + return thing; + } + +==== tests/cases/conformance/pragma/noFallthroughCasesInSwitch/file2.ts (1 errors) ==== + // @ts-noFallthroughCasesInSwitch true + export function f1(thing: "a" | "b") { + switch (thing) { + case "a": + ~~~~~~~~~ +!!! error TS7029: Fallthrough case in switch. + thing; + case "b": + thing; + break; + } + return thing; + } + +==== tests/cases/conformance/pragma/noFallthroughCasesInSwitch/file3.ts (0 errors) ==== + // @ts-noFallthroughCasesInSwitch false + export function f1(thing: "a" | "b") { + switch (thing) { + case "a": + thing; + case "b": + thing; + break; + } + return thing; + } + +==== tests/cases/conformance/pragma/noFallthroughCasesInSwitch/file4.ts (0 errors) ==== + export function f1(thing: "a" | "b") { + switch (thing) { + case "a": + thing; + case "b": + thing; + break; + } + return thing; + } + \ No newline at end of file diff --git a/tests/baselines/reference/noFallthroughCasesInSwitchPragma1.js b/tests/baselines/reference/noFallthroughCasesInSwitchPragma1.js new file mode 100644 index 0000000000000..b0a9e5033de5a --- /dev/null +++ b/tests/baselines/reference/noFallthroughCasesInSwitchPragma1.js @@ -0,0 +1,117 @@ +//// [tests/cases/conformance/pragma/noFallthroughCasesInSwitch/noFallthroughCasesInSwitchPragma1.ts] //// + +//// [file1.ts] +// @ts-noFallthroughCasesInSwitch +export function f1(thing: "a" | "b") { + switch (thing) { + case "a": + thing; + case "b": + thing; + break; + } + return thing; +} + +//// [file2.ts] +// @ts-noFallthroughCasesInSwitch true +export function f1(thing: "a" | "b") { + switch (thing) { + case "a": + thing; + case "b": + thing; + break; + } + return thing; +} + +//// [file3.ts] +// @ts-noFallthroughCasesInSwitch false +export function f1(thing: "a" | "b") { + switch (thing) { + case "a": + thing; + case "b": + thing; + break; + } + return thing; +} + +//// [file4.ts] +export function f1(thing: "a" | "b") { + switch (thing) { + case "a": + thing; + case "b": + thing; + break; + } + return thing; +} + + +//// [file1.js] +"use strict"; +exports.__esModule = true; +exports.f1 = void 0; +// @ts-noFallthroughCasesInSwitch +function f1(thing) { + switch (thing) { + case "a": + thing; + case "b": + thing; + break; + } + return thing; +} +exports.f1 = f1; +//// [file2.js] +"use strict"; +exports.__esModule = true; +exports.f1 = void 0; +// @ts-noFallthroughCasesInSwitch true +function f1(thing) { + switch (thing) { + case "a": + thing; + case "b": + thing; + break; + } + return thing; +} +exports.f1 = f1; +//// [file3.js] +"use strict"; +exports.__esModule = true; +exports.f1 = void 0; +// @ts-noFallthroughCasesInSwitch false +function f1(thing) { + switch (thing) { + case "a": + thing; + case "b": + thing; + break; + } + return thing; +} +exports.f1 = f1; +//// [file4.js] +"use strict"; +exports.__esModule = true; +exports.f1 = void 0; +function f1(thing) { + switch (thing) { + case "a": + thing; + case "b": + thing; + break; + } + return thing; +} +exports.f1 = f1; diff --git a/tests/baselines/reference/noFallthroughCasesInSwitchPragma1.symbols b/tests/baselines/reference/noFallthroughCasesInSwitchPragma1.symbols new file mode 100644 index 0000000000000..f736acefb67be --- /dev/null +++ b/tests/baselines/reference/noFallthroughCasesInSwitchPragma1.symbols @@ -0,0 +1,91 @@ +=== tests/cases/conformance/pragma/noFallthroughCasesInSwitch/file1.ts === +// @ts-noFallthroughCasesInSwitch +export function f1(thing: "a" | "b") { +>f1 : Symbol(f1, Decl(file1.ts, 0, 0)) +>thing : Symbol(thing, Decl(file1.ts, 1, 19)) + + switch (thing) { +>thing : Symbol(thing, Decl(file1.ts, 1, 19)) + + case "a": + thing; +>thing : Symbol(thing, Decl(file1.ts, 1, 19)) + + case "b": + thing; +>thing : Symbol(thing, Decl(file1.ts, 1, 19)) + + break; + } + return thing; +>thing : Symbol(thing, Decl(file1.ts, 1, 19)) +} + +=== tests/cases/conformance/pragma/noFallthroughCasesInSwitch/file2.ts === +// @ts-noFallthroughCasesInSwitch true +export function f1(thing: "a" | "b") { +>f1 : Symbol(f1, Decl(file2.ts, 0, 0)) +>thing : Symbol(thing, Decl(file2.ts, 1, 19)) + + switch (thing) { +>thing : Symbol(thing, Decl(file2.ts, 1, 19)) + + case "a": + thing; +>thing : Symbol(thing, Decl(file2.ts, 1, 19)) + + case "b": + thing; +>thing : Symbol(thing, Decl(file2.ts, 1, 19)) + + break; + } + return thing; +>thing : Symbol(thing, Decl(file2.ts, 1, 19)) +} + +=== tests/cases/conformance/pragma/noFallthroughCasesInSwitch/file3.ts === +// @ts-noFallthroughCasesInSwitch false +export function f1(thing: "a" | "b") { +>f1 : Symbol(f1, Decl(file3.ts, 0, 0)) +>thing : Symbol(thing, Decl(file3.ts, 1, 19)) + + switch (thing) { +>thing : Symbol(thing, Decl(file3.ts, 1, 19)) + + case "a": + thing; +>thing : Symbol(thing, Decl(file3.ts, 1, 19)) + + case "b": + thing; +>thing : Symbol(thing, Decl(file3.ts, 1, 19)) + + break; + } + return thing; +>thing : Symbol(thing, Decl(file3.ts, 1, 19)) +} + +=== tests/cases/conformance/pragma/noFallthroughCasesInSwitch/file4.ts === +export function f1(thing: "a" | "b") { +>f1 : Symbol(f1, Decl(file4.ts, 0, 0)) +>thing : Symbol(thing, Decl(file4.ts, 0, 19)) + + switch (thing) { +>thing : Symbol(thing, Decl(file4.ts, 0, 19)) + + case "a": + thing; +>thing : Symbol(thing, Decl(file4.ts, 0, 19)) + + case "b": + thing; +>thing : Symbol(thing, Decl(file4.ts, 0, 19)) + + break; + } + return thing; +>thing : Symbol(thing, Decl(file4.ts, 0, 19)) +} + diff --git a/tests/baselines/reference/noFallthroughCasesInSwitchPragma1.types b/tests/baselines/reference/noFallthroughCasesInSwitchPragma1.types new file mode 100644 index 0000000000000..33ca79e27989a --- /dev/null +++ b/tests/baselines/reference/noFallthroughCasesInSwitchPragma1.types @@ -0,0 +1,107 @@ +=== tests/cases/conformance/pragma/noFallthroughCasesInSwitch/file1.ts === +// @ts-noFallthroughCasesInSwitch +export function f1(thing: "a" | "b") { +>f1 : (thing: "a" | "b") => "a" | "b" +>thing : "a" | "b" + + switch (thing) { +>thing : "a" | "b" + + case "a": +>"a" : "a" + + thing; +>thing : "a" + + case "b": +>"b" : "b" + + thing; +>thing : "a" | "b" + + break; + } + return thing; +>thing : "a" | "b" +} + +=== tests/cases/conformance/pragma/noFallthroughCasesInSwitch/file2.ts === +// @ts-noFallthroughCasesInSwitch true +export function f1(thing: "a" | "b") { +>f1 : (thing: "a" | "b") => "a" | "b" +>thing : "a" | "b" + + switch (thing) { +>thing : "a" | "b" + + case "a": +>"a" : "a" + + thing; +>thing : "a" + + case "b": +>"b" : "b" + + thing; +>thing : "a" | "b" + + break; + } + return thing; +>thing : "a" | "b" +} + +=== tests/cases/conformance/pragma/noFallthroughCasesInSwitch/file3.ts === +// @ts-noFallthroughCasesInSwitch false +export function f1(thing: "a" | "b") { +>f1 : (thing: "a" | "b") => "a" | "b" +>thing : "a" | "b" + + switch (thing) { +>thing : "a" | "b" + + case "a": +>"a" : "a" + + thing; +>thing : "a" + + case "b": +>"b" : "b" + + thing; +>thing : "a" | "b" + + break; + } + return thing; +>thing : "a" | "b" +} + +=== tests/cases/conformance/pragma/noFallthroughCasesInSwitch/file4.ts === +export function f1(thing: "a" | "b") { +>f1 : (thing: "a" | "b") => "a" | "b" +>thing : "a" | "b" + + switch (thing) { +>thing : "a" | "b" + + case "a": +>"a" : "a" + + thing; +>thing : "a" + + case "b": +>"b" : "b" + + thing; +>thing : "a" | "b" + + break; + } + return thing; +>thing : "a" | "b" +} + diff --git a/tests/baselines/reference/noFallthroughCasesInSwitchPragma2.errors.txt b/tests/baselines/reference/noFallthroughCasesInSwitchPragma2.errors.txt new file mode 100644 index 0000000000000..fd90b5f75409d --- /dev/null +++ b/tests/baselines/reference/noFallthroughCasesInSwitchPragma2.errors.txt @@ -0,0 +1,62 @@ +tests/cases/conformance/pragma/noFallthroughCasesInSwitch/file1.ts(4,9): error TS7029: Fallthrough case in switch. +tests/cases/conformance/pragma/noFallthroughCasesInSwitch/file2.ts(4,9): error TS7029: Fallthrough case in switch. +tests/cases/conformance/pragma/noFallthroughCasesInSwitch/file4.ts(3,9): error TS7029: Fallthrough case in switch. + + +==== tests/cases/conformance/pragma/noFallthroughCasesInSwitch/file1.ts (1 errors) ==== + // @ts-noFallthroughCasesInSwitch + export function f1(thing: "a" | "b") { + switch (thing) { + case "a": + ~~~~~~~~~ +!!! error TS7029: Fallthrough case in switch. + thing; + case "b": + thing; + break; + } + return thing; + } + +==== tests/cases/conformance/pragma/noFallthroughCasesInSwitch/file2.ts (1 errors) ==== + // @ts-noFallthroughCasesInSwitch true + export function f1(thing: "a" | "b") { + switch (thing) { + case "a": + ~~~~~~~~~ +!!! error TS7029: Fallthrough case in switch. + thing; + case "b": + thing; + break; + } + return thing; + } + +==== tests/cases/conformance/pragma/noFallthroughCasesInSwitch/file3.ts (0 errors) ==== + // @ts-noFallthroughCasesInSwitch false + export function f1(thing: "a" | "b") { + switch (thing) { + case "a": + thing; + case "b": + thing; + break; + } + return thing; + } + +==== tests/cases/conformance/pragma/noFallthroughCasesInSwitch/file4.ts (1 errors) ==== + export function f1(thing: "a" | "b") { + switch (thing) { + case "a": + ~~~~~~~~~ +!!! error TS7029: Fallthrough case in switch. + thing; + case "b": + thing; + break; + } + return thing; + } + \ No newline at end of file diff --git a/tests/baselines/reference/noFallthroughCasesInSwitchPragma2.js b/tests/baselines/reference/noFallthroughCasesInSwitchPragma2.js new file mode 100644 index 0000000000000..d9f9e51b28e8b --- /dev/null +++ b/tests/baselines/reference/noFallthroughCasesInSwitchPragma2.js @@ -0,0 +1,117 @@ +//// [tests/cases/conformance/pragma/noFallthroughCasesInSwitch/noFallthroughCasesInSwitchPragma2.ts] //// + +//// [file1.ts] +// @ts-noFallthroughCasesInSwitch +export function f1(thing: "a" | "b") { + switch (thing) { + case "a": + thing; + case "b": + thing; + break; + } + return thing; +} + +//// [file2.ts] +// @ts-noFallthroughCasesInSwitch true +export function f1(thing: "a" | "b") { + switch (thing) { + case "a": + thing; + case "b": + thing; + break; + } + return thing; +} + +//// [file3.ts] +// @ts-noFallthroughCasesInSwitch false +export function f1(thing: "a" | "b") { + switch (thing) { + case "a": + thing; + case "b": + thing; + break; + } + return thing; +} + +//// [file4.ts] +export function f1(thing: "a" | "b") { + switch (thing) { + case "a": + thing; + case "b": + thing; + break; + } + return thing; +} + + +//// [file1.js] +"use strict"; +exports.__esModule = true; +exports.f1 = void 0; +// @ts-noFallthroughCasesInSwitch +function f1(thing) { + switch (thing) { + case "a": + thing; + case "b": + thing; + break; + } + return thing; +} +exports.f1 = f1; +//// [file2.js] +"use strict"; +exports.__esModule = true; +exports.f1 = void 0; +// @ts-noFallthroughCasesInSwitch true +function f1(thing) { + switch (thing) { + case "a": + thing; + case "b": + thing; + break; + } + return thing; +} +exports.f1 = f1; +//// [file3.js] +"use strict"; +exports.__esModule = true; +exports.f1 = void 0; +// @ts-noFallthroughCasesInSwitch false +function f1(thing) { + switch (thing) { + case "a": + thing; + case "b": + thing; + break; + } + return thing; +} +exports.f1 = f1; +//// [file4.js] +"use strict"; +exports.__esModule = true; +exports.f1 = void 0; +function f1(thing) { + switch (thing) { + case "a": + thing; + case "b": + thing; + break; + } + return thing; +} +exports.f1 = f1; diff --git a/tests/baselines/reference/noFallthroughCasesInSwitchPragma2.symbols b/tests/baselines/reference/noFallthroughCasesInSwitchPragma2.symbols new file mode 100644 index 0000000000000..f736acefb67be --- /dev/null +++ b/tests/baselines/reference/noFallthroughCasesInSwitchPragma2.symbols @@ -0,0 +1,91 @@ +=== tests/cases/conformance/pragma/noFallthroughCasesInSwitch/file1.ts === +// @ts-noFallthroughCasesInSwitch +export function f1(thing: "a" | "b") { +>f1 : Symbol(f1, Decl(file1.ts, 0, 0)) +>thing : Symbol(thing, Decl(file1.ts, 1, 19)) + + switch (thing) { +>thing : Symbol(thing, Decl(file1.ts, 1, 19)) + + case "a": + thing; +>thing : Symbol(thing, Decl(file1.ts, 1, 19)) + + case "b": + thing; +>thing : Symbol(thing, Decl(file1.ts, 1, 19)) + + break; + } + return thing; +>thing : Symbol(thing, Decl(file1.ts, 1, 19)) +} + +=== tests/cases/conformance/pragma/noFallthroughCasesInSwitch/file2.ts === +// @ts-noFallthroughCasesInSwitch true +export function f1(thing: "a" | "b") { +>f1 : Symbol(f1, Decl(file2.ts, 0, 0)) +>thing : Symbol(thing, Decl(file2.ts, 1, 19)) + + switch (thing) { +>thing : Symbol(thing, Decl(file2.ts, 1, 19)) + + case "a": + thing; +>thing : Symbol(thing, Decl(file2.ts, 1, 19)) + + case "b": + thing; +>thing : Symbol(thing, Decl(file2.ts, 1, 19)) + + break; + } + return thing; +>thing : Symbol(thing, Decl(file2.ts, 1, 19)) +} + +=== tests/cases/conformance/pragma/noFallthroughCasesInSwitch/file3.ts === +// @ts-noFallthroughCasesInSwitch false +export function f1(thing: "a" | "b") { +>f1 : Symbol(f1, Decl(file3.ts, 0, 0)) +>thing : Symbol(thing, Decl(file3.ts, 1, 19)) + + switch (thing) { +>thing : Symbol(thing, Decl(file3.ts, 1, 19)) + + case "a": + thing; +>thing : Symbol(thing, Decl(file3.ts, 1, 19)) + + case "b": + thing; +>thing : Symbol(thing, Decl(file3.ts, 1, 19)) + + break; + } + return thing; +>thing : Symbol(thing, Decl(file3.ts, 1, 19)) +} + +=== tests/cases/conformance/pragma/noFallthroughCasesInSwitch/file4.ts === +export function f1(thing: "a" | "b") { +>f1 : Symbol(f1, Decl(file4.ts, 0, 0)) +>thing : Symbol(thing, Decl(file4.ts, 0, 19)) + + switch (thing) { +>thing : Symbol(thing, Decl(file4.ts, 0, 19)) + + case "a": + thing; +>thing : Symbol(thing, Decl(file4.ts, 0, 19)) + + case "b": + thing; +>thing : Symbol(thing, Decl(file4.ts, 0, 19)) + + break; + } + return thing; +>thing : Symbol(thing, Decl(file4.ts, 0, 19)) +} + diff --git a/tests/baselines/reference/noFallthroughCasesInSwitchPragma2.types b/tests/baselines/reference/noFallthroughCasesInSwitchPragma2.types new file mode 100644 index 0000000000000..33ca79e27989a --- /dev/null +++ b/tests/baselines/reference/noFallthroughCasesInSwitchPragma2.types @@ -0,0 +1,107 @@ +=== tests/cases/conformance/pragma/noFallthroughCasesInSwitch/file1.ts === +// @ts-noFallthroughCasesInSwitch +export function f1(thing: "a" | "b") { +>f1 : (thing: "a" | "b") => "a" | "b" +>thing : "a" | "b" + + switch (thing) { +>thing : "a" | "b" + + case "a": +>"a" : "a" + + thing; +>thing : "a" + + case "b": +>"b" : "b" + + thing; +>thing : "a" | "b" + + break; + } + return thing; +>thing : "a" | "b" +} + +=== tests/cases/conformance/pragma/noFallthroughCasesInSwitch/file2.ts === +// @ts-noFallthroughCasesInSwitch true +export function f1(thing: "a" | "b") { +>f1 : (thing: "a" | "b") => "a" | "b" +>thing : "a" | "b" + + switch (thing) { +>thing : "a" | "b" + + case "a": +>"a" : "a" + + thing; +>thing : "a" + + case "b": +>"b" : "b" + + thing; +>thing : "a" | "b" + + break; + } + return thing; +>thing : "a" | "b" +} + +=== tests/cases/conformance/pragma/noFallthroughCasesInSwitch/file3.ts === +// @ts-noFallthroughCasesInSwitch false +export function f1(thing: "a" | "b") { +>f1 : (thing: "a" | "b") => "a" | "b" +>thing : "a" | "b" + + switch (thing) { +>thing : "a" | "b" + + case "a": +>"a" : "a" + + thing; +>thing : "a" + + case "b": +>"b" : "b" + + thing; +>thing : "a" | "b" + + break; + } + return thing; +>thing : "a" | "b" +} + +=== tests/cases/conformance/pragma/noFallthroughCasesInSwitch/file4.ts === +export function f1(thing: "a" | "b") { +>f1 : (thing: "a" | "b") => "a" | "b" +>thing : "a" | "b" + + switch (thing) { +>thing : "a" | "b" + + case "a": +>"a" : "a" + + thing; +>thing : "a" + + case "b": +>"b" : "b" + + thing; +>thing : "a" | "b" + + break; + } + return thing; +>thing : "a" | "b" +} + diff --git a/tests/baselines/reference/noImplicitAnyPragma1.errors.txt b/tests/baselines/reference/noImplicitAnyPragma1.errors.txt new file mode 100644 index 0000000000000..2c0746fc2d7ad --- /dev/null +++ b/tests/baselines/reference/noImplicitAnyPragma1.errors.txt @@ -0,0 +1,275 @@ +tests/cases/conformance/pragma/noImplicitAny/file1.ts(2,21): error TS2792: Cannot find module 'missing'. Did you mean to set the 'moduleResolution' option to 'node', or to add aliases to the 'paths' option? +tests/cases/conformance/pragma/noImplicitAny/file1.ts(4,11): error TS7006: Parameter 'p' implicitly has an 'any' type. +tests/cases/conformance/pragma/noImplicitAny/file1.ts(12,5): error TS7008: Member 'prop2' implicitly has an 'any' type. +tests/cases/conformance/pragma/noImplicitAny/file1.ts(14,9): error TS2322: Type 'string' is not assignable to type 'number'. +tests/cases/conformance/pragma/noImplicitAny/file1.ts(18,12): error TS7008: Member 'stat2' implicitly has an 'any' type. +tests/cases/conformance/pragma/noImplicitAny/file1.ts(20,9): error TS2322: Type 'string' is not assignable to type 'number'. +tests/cases/conformance/pragma/noImplicitAny/file1.ts(25,9): error TS7023: 'access' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions. +tests/cases/conformance/pragma/noImplicitAny/file1.ts(28,17): error TS7023: 'f1' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions. +tests/cases/conformance/pragma/noImplicitAny/file1.ts(32,13): error TS2339: Property 'none' does not exist on type '{}'. +tests/cases/conformance/pragma/noImplicitAny/file1.ts(37,11): error TS7053: Element implicitly has an 'any' type because expression of type '"none"' can't be used to index type 'B'. + Property 'none' does not exist on type 'B'. +tests/cases/conformance/pragma/noImplicitAny/file1.ts(39,26): error TS2322: Type '{ prop: string; excess: string; }' is not assignable to type 'B'. + Object literal may only specify known properties, and 'excess' does not exist in type 'B'. +tests/cases/conformance/pragma/noImplicitAny/file1.ts(42,11): error TS7009: 'new' expression, whose target lacks a construct signature, implicitly has an 'any' type. +tests/cases/conformance/pragma/noImplicitAny/file2.ts(2,21): error TS2792: Cannot find module 'missing'. Did you mean to set the 'moduleResolution' option to 'node', or to add aliases to the 'paths' option? +tests/cases/conformance/pragma/noImplicitAny/file2.ts(4,11): error TS7006: Parameter 'p' implicitly has an 'any' type. +tests/cases/conformance/pragma/noImplicitAny/file2.ts(12,5): error TS7008: Member 'prop2' implicitly has an 'any' type. +tests/cases/conformance/pragma/noImplicitAny/file2.ts(14,9): error TS2322: Type 'string' is not assignable to type 'number'. +tests/cases/conformance/pragma/noImplicitAny/file2.ts(18,12): error TS7008: Member 'stat2' implicitly has an 'any' type. +tests/cases/conformance/pragma/noImplicitAny/file2.ts(20,9): error TS2322: Type 'string' is not assignable to type 'number'. +tests/cases/conformance/pragma/noImplicitAny/file2.ts(25,9): error TS7023: 'access' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions. +tests/cases/conformance/pragma/noImplicitAny/file2.ts(28,17): error TS7023: 'f1' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions. +tests/cases/conformance/pragma/noImplicitAny/file2.ts(32,13): error TS2339: Property 'none' does not exist on type '{}'. +tests/cases/conformance/pragma/noImplicitAny/file2.ts(37,11): error TS7053: Element implicitly has an 'any' type because expression of type '"none"' can't be used to index type 'B'. + Property 'none' does not exist on type 'B'. +tests/cases/conformance/pragma/noImplicitAny/file2.ts(39,26): error TS2322: Type '{ prop: string; excess: string; }' is not assignable to type 'B'. + Object literal may only specify known properties, and 'excess' does not exist in type 'B'. +tests/cases/conformance/pragma/noImplicitAny/file2.ts(42,11): error TS7009: 'new' expression, whose target lacks a construct signature, implicitly has an 'any' type. +tests/cases/conformance/pragma/noImplicitAny/file3.ts(2,21): error TS2792: Cannot find module 'missing'. Did you mean to set the 'moduleResolution' option to 'node', or to add aliases to the 'paths' option? +tests/cases/conformance/pragma/noImplicitAny/file3.ts(39,26): error TS2322: Type '{ prop: string; excess: string; }' is not assignable to type 'B'. + Object literal may only specify known properties, and 'excess' does not exist in type 'B'. +tests/cases/conformance/pragma/noImplicitAny/file3.ts(42,11): error TS2350: Only a void function can be called with the 'new' keyword. +tests/cases/conformance/pragma/noImplicitAny/file4.ts(1,21): error TS2792: Cannot find module 'missing'. Did you mean to set the 'moduleResolution' option to 'node', or to add aliases to the 'paths' option? +tests/cases/conformance/pragma/noImplicitAny/file4.ts(38,26): error TS2322: Type '{ prop: string; excess: string; }' is not assignable to type 'B'. + Object literal may only specify known properties, and 'excess' does not exist in type 'B'. +tests/cases/conformance/pragma/noImplicitAny/file4.ts(41,11): error TS2350: Only a void function can be called with the 'new' keyword. + + +==== tests/cases/conformance/pragma/noImplicitAny/file1.ts (12 errors) ==== + // @ts-noImplicitAny + import * as ns from "missing"; + ~~~~~~~~~ +!!! error TS2792: Cannot find module 'missing'. Did you mean to set the 'moduleResolution' option to 'node', or to add aliases to the 'paths' option? + + const a = p => p + 1; + ~ +!!! error TS7006: Parameter 'p' implicitly has an 'any' type. + + let x; + x = "a"; + x = 42; + + export class A { + prop; + prop2; + ~~~~~ +!!! error TS7008: Member 'prop2' implicitly has an 'any' type. + constructor() { + this.prop = "a"; + ~~~~~~~~~ +!!! error TS2322: Type 'string' is not assignable to type 'number'. + this.prop = 42; + } + static stat; + static stat2; + ~~~~~ +!!! error TS7008: Member 'stat2' implicitly has an 'any' type. + static { + this.stat = "a"; + ~~~~~~~~~ +!!! error TS2322: Type 'string' is not assignable to type 'number'. + this.stat = 42; + } + + set access(param) {} + get access() { return this.access; } + ~~~~~~ +!!! error TS7023: 'access' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions. + } + + export function f1() { + ~~ +!!! error TS7023: 'f1' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions. + return f1(); + } + + const res = {}["none"]; + ~~~~~~~~~~ +!!! error TS2339: Property 'none' does not exist on type '{}'. + + interface B { prop: string } + declare var b: B; + + const c = b["none"]; + ~~~~~~~~~ +!!! error TS7053: Element implicitly has an 'any' type because expression of type '"none"' can't be used to index type 'B'. +!!! error TS7053: Property 'none' does not exist on type 'B'. + + const d: B = { prop: "", excess: "yes" }; + ~~~~~~~~~~~~~ +!!! error TS2322: Type '{ prop: string; excess: string; }' is not assignable to type 'B'. +!!! error TS2322: Object literal may only specify known properties, and 'excess' does not exist in type 'B'. + + function f2(): string { return ""; } + const e = new f2(); + ~~~~~~~~ +!!! error TS7009: 'new' expression, whose target lacks a construct signature, implicitly has an 'any' type. +==== tests/cases/conformance/pragma/noImplicitAny/file2.ts (12 errors) ==== + // @ts-noImplicitAny true + import * as ns from "missing"; + ~~~~~~~~~ +!!! error TS2792: Cannot find module 'missing'. Did you mean to set the 'moduleResolution' option to 'node', or to add aliases to the 'paths' option? + + const a = p => p + 1; + ~ +!!! error TS7006: Parameter 'p' implicitly has an 'any' type. + + let x; + x = "a"; + x = 42; + + export class A { + prop; + prop2; + ~~~~~ +!!! error TS7008: Member 'prop2' implicitly has an 'any' type. + constructor() { + this.prop = "a"; + ~~~~~~~~~ +!!! error TS2322: Type 'string' is not assignable to type 'number'. + this.prop = 42; + } + static stat; + static stat2; + ~~~~~ +!!! error TS7008: Member 'stat2' implicitly has an 'any' type. + static { + this.stat = "a"; + ~~~~~~~~~ +!!! error TS2322: Type 'string' is not assignable to type 'number'. + this.stat = 42; + } + + set access(param) {} + get access() { return this.access; } + ~~~~~~ +!!! error TS7023: 'access' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions. + } + + export function f1() { + ~~ +!!! error TS7023: 'f1' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions. + return f1(); + } + + const res = {}["none"]; + ~~~~~~~~~~ +!!! error TS2339: Property 'none' does not exist on type '{}'. + + interface B { prop: string } + declare var b: B; + + const c = b["none"]; + ~~~~~~~~~ +!!! error TS7053: Element implicitly has an 'any' type because expression of type '"none"' can't be used to index type 'B'. +!!! error TS7053: Property 'none' does not exist on type 'B'. + + const d: B = { prop: "", excess: "yes" }; + ~~~~~~~~~~~~~ +!!! error TS2322: Type '{ prop: string; excess: string; }' is not assignable to type 'B'. +!!! error TS2322: Object literal may only specify known properties, and 'excess' does not exist in type 'B'. + + function f2(): string { return ""; } + const e = new f2(); + ~~~~~~~~ +!!! error TS7009: 'new' expression, whose target lacks a construct signature, implicitly has an 'any' type. +==== tests/cases/conformance/pragma/noImplicitAny/file3.ts (3 errors) ==== + // @ts-noImplicitAny false + import * as ns from "missing"; + ~~~~~~~~~ +!!! error TS2792: Cannot find module 'missing'. Did you mean to set the 'moduleResolution' option to 'node', or to add aliases to the 'paths' option? + + const a = p => p + 1; + + let x; + x = "a"; + x = 42; + + export class A { + prop; + prop2; + constructor() { + this.prop = "a"; + this.prop = 42; + } + static stat; + static stat2; + static { + this.stat = "a"; + this.stat = 42; + } + + set access(param) {} + get access() { return this.access; } + } + + export function f1() { + return f1(); + } + + const res = {}["none"]; + + interface B { prop: string } + declare var b: B; + + const c = b["none"]; + + const d: B = { prop: "", excess: "yes" }; + ~~~~~~~~~~~~~ +!!! error TS2322: Type '{ prop: string; excess: string; }' is not assignable to type 'B'. +!!! error TS2322: Object literal may only specify known properties, and 'excess' does not exist in type 'B'. + + function f2(): string { return ""; } + const e = new f2(); + ~~~~~~~~ +!!! error TS2350: Only a void function can be called with the 'new' keyword. +==== tests/cases/conformance/pragma/noImplicitAny/file4.ts (3 errors) ==== + import * as ns from "missing"; + ~~~~~~~~~ +!!! error TS2792: Cannot find module 'missing'. Did you mean to set the 'moduleResolution' option to 'node', or to add aliases to the 'paths' option? + + const a = p => p + 1; + + let x; + x = "a"; + x = 42; + + export class A { + prop; + prop2; + constructor() { + this.prop = "a"; + this.prop = 42; + } + static stat; + static stat2; + static { + this.stat = "a"; + this.stat = 42; + } + + set access(param) {} + get access() { return this.access; } + } + + export function f1() { + return f1(); + } + + const res = {}["none"]; + + interface B { prop: string } + declare var b: B; + + const c = b["none"]; + + const d: B = { prop: "", excess: "yes" }; + ~~~~~~~~~~~~~ +!!! error TS2322: Type '{ prop: string; excess: string; }' is not assignable to type 'B'. +!!! error TS2322: Object literal may only specify known properties, and 'excess' does not exist in type 'B'. + + function f2(): string { return ""; } + const e = new f2(); + ~~~~~~~~ +!!! error TS2350: Only a void function can be called with the 'new' keyword. \ No newline at end of file diff --git a/tests/baselines/reference/noImplicitAnyPragma1.js b/tests/baselines/reference/noImplicitAnyPragma1.js new file mode 100644 index 0000000000000..9a89cf475570b --- /dev/null +++ b/tests/baselines/reference/noImplicitAnyPragma1.js @@ -0,0 +1,282 @@ +//// [tests/cases/conformance/pragma/noImplicitAny/noImplicitAnyPragma1.ts] //// + +//// [file1.ts] +// @ts-noImplicitAny +import * as ns from "missing"; + +const a = p => p + 1; + +let x; +x = "a"; +x = 42; + +export class A { + prop; + prop2; + constructor() { + this.prop = "a"; + this.prop = 42; + } + static stat; + static stat2; + static { + this.stat = "a"; + this.stat = 42; + } + + set access(param) {} + get access() { return this.access; } +} + +export function f1() { + return f1(); +} + +const res = {}["none"]; + +interface B { prop: string } +declare var b: B; + +const c = b["none"]; + +const d: B = { prop: "", excess: "yes" }; + +function f2(): string { return ""; } +const e = new f2(); +//// [file2.ts] +// @ts-noImplicitAny true +import * as ns from "missing"; + +const a = p => p + 1; + +let x; +x = "a"; +x = 42; + +export class A { + prop; + prop2; + constructor() { + this.prop = "a"; + this.prop = 42; + } + static stat; + static stat2; + static { + this.stat = "a"; + this.stat = 42; + } + + set access(param) {} + get access() { return this.access; } +} + +export function f1() { + return f1(); +} + +const res = {}["none"]; + +interface B { prop: string } +declare var b: B; + +const c = b["none"]; + +const d: B = { prop: "", excess: "yes" }; + +function f2(): string { return ""; } +const e = new f2(); +//// [file3.ts] +// @ts-noImplicitAny false +import * as ns from "missing"; + +const a = p => p + 1; + +let x; +x = "a"; +x = 42; + +export class A { + prop; + prop2; + constructor() { + this.prop = "a"; + this.prop = 42; + } + static stat; + static stat2; + static { + this.stat = "a"; + this.stat = 42; + } + + set access(param) {} + get access() { return this.access; } +} + +export function f1() { + return f1(); +} + +const res = {}["none"]; + +interface B { prop: string } +declare var b: B; + +const c = b["none"]; + +const d: B = { prop: "", excess: "yes" }; + +function f2(): string { return ""; } +const e = new f2(); +//// [file4.ts] +import * as ns from "missing"; + +const a = p => p + 1; + +let x; +x = "a"; +x = 42; + +export class A { + prop; + prop2; + constructor() { + this.prop = "a"; + this.prop = 42; + } + static stat; + static stat2; + static { + this.stat = "a"; + this.stat = 42; + } + + set access(param) {} + get access() { return this.access; } +} + +export function f1() { + return f1(); +} + +const res = {}["none"]; + +interface B { prop: string } +declare var b: B; + +const c = b["none"]; + +const d: B = { prop: "", excess: "yes" }; + +function f2(): string { return ""; } +const e = new f2(); + +//// [file1.js] +var _a; +const a = p => p + 1; +let x; +x = "a"; +x = 42; +export class A { + constructor() { + this.prop = "a"; + this.prop = 42; + } + set access(param) { } + get access() { return this.access; } +} +_a = A; +(() => { + _a.stat = "a"; + _a.stat = 42; +})(); +export function f1() { + return f1(); +} +const res = {}["none"]; +const c = b["none"]; +const d = { prop: "", excess: "yes" }; +function f2() { return ""; } +const e = new f2(); +//// [file2.js] +var _a; +const a = p => p + 1; +let x; +x = "a"; +x = 42; +export class A { + constructor() { + this.prop = "a"; + this.prop = 42; + } + set access(param) { } + get access() { return this.access; } +} +_a = A; +(() => { + _a.stat = "a"; + _a.stat = 42; +})(); +export function f1() { + return f1(); +} +const res = {}["none"]; +const c = b["none"]; +const d = { prop: "", excess: "yes" }; +function f2() { return ""; } +const e = new f2(); +//// [file3.js] +var _a; +const a = p => p + 1; +let x; +x = "a"; +x = 42; +export class A { + constructor() { + this.prop = "a"; + this.prop = 42; + } + set access(param) { } + get access() { return this.access; } +} +_a = A; +(() => { + _a.stat = "a"; + _a.stat = 42; +})(); +export function f1() { + return f1(); +} +const res = {}["none"]; +const c = b["none"]; +const d = { prop: "", excess: "yes" }; +function f2() { return ""; } +const e = new f2(); +//// [file4.js] +var _a; +const a = p => p + 1; +let x; +x = "a"; +x = 42; +export class A { + constructor() { + this.prop = "a"; + this.prop = 42; + } + set access(param) { } + get access() { return this.access; } +} +_a = A; +(() => { + _a.stat = "a"; + _a.stat = 42; +})(); +export function f1() { + return f1(); +} +const res = {}["none"]; +const c = b["none"]; +const d = { prop: "", excess: "yes" }; +function f2() { return ""; } +const e = new f2(); diff --git a/tests/baselines/reference/noImplicitAnyPragma1.symbols b/tests/baselines/reference/noImplicitAnyPragma1.symbols new file mode 100644 index 0000000000000..73ba0d619be12 --- /dev/null +++ b/tests/baselines/reference/noImplicitAnyPragma1.symbols @@ -0,0 +1,411 @@ +=== tests/cases/conformance/pragma/noImplicitAny/file1.ts === +// @ts-noImplicitAny +import * as ns from "missing"; +>ns : Symbol(ns, Decl(file1.ts, 1, 6)) + +const a = p => p + 1; +>a : Symbol(a, Decl(file1.ts, 3, 5)) +>p : Symbol(p, Decl(file1.ts, 3, 9)) +>p : Symbol(p, Decl(file1.ts, 3, 9)) + +let x; +>x : Symbol(x, Decl(file1.ts, 5, 3)) + +x = "a"; +>x : Symbol(x, Decl(file1.ts, 5, 3)) + +x = 42; +>x : Symbol(x, Decl(file1.ts, 5, 3)) + +export class A { +>A : Symbol(A, Decl(file1.ts, 7, 7)) + + prop; +>prop : Symbol(A.prop, Decl(file1.ts, 9, 16)) + + prop2; +>prop2 : Symbol(A.prop2, Decl(file1.ts, 10, 9)) + + constructor() { + this.prop = "a"; +>this.prop : Symbol(A.prop, Decl(file1.ts, 9, 16)) +>this : Symbol(A, Decl(file1.ts, 7, 7)) +>prop : Symbol(A.prop, Decl(file1.ts, 9, 16)) + + this.prop = 42; +>this.prop : Symbol(A.prop, Decl(file1.ts, 9, 16)) +>this : Symbol(A, Decl(file1.ts, 7, 7)) +>prop : Symbol(A.prop, Decl(file1.ts, 9, 16)) + } + static stat; +>stat : Symbol(A.stat, Decl(file1.ts, 15, 5)) + + static stat2; +>stat2 : Symbol(A.stat2, Decl(file1.ts, 16, 16)) + + static { + this.stat = "a"; +>this.stat : Symbol(A.stat, Decl(file1.ts, 15, 5)) +>this : Symbol(A, Decl(file1.ts, 7, 7)) +>stat : Symbol(A.stat, Decl(file1.ts, 15, 5)) + + this.stat = 42; +>this.stat : Symbol(A.stat, Decl(file1.ts, 15, 5)) +>this : Symbol(A, Decl(file1.ts, 7, 7)) +>stat : Symbol(A.stat, Decl(file1.ts, 15, 5)) + } + + set access(param) {} +>access : Symbol(A.access, Decl(file1.ts, 21, 5), Decl(file1.ts, 23, 24)) +>param : Symbol(param, Decl(file1.ts, 23, 15)) + + get access() { return this.access; } +>access : Symbol(A.access, Decl(file1.ts, 21, 5), Decl(file1.ts, 23, 24)) +>this.access : Symbol(A.access, Decl(file1.ts, 21, 5), Decl(file1.ts, 23, 24)) +>this : Symbol(A, Decl(file1.ts, 7, 7)) +>access : Symbol(A.access, Decl(file1.ts, 21, 5), Decl(file1.ts, 23, 24)) +} + +export function f1() { +>f1 : Symbol(f1, Decl(file1.ts, 25, 1)) + + return f1(); +>f1 : Symbol(f1, Decl(file1.ts, 25, 1)) +} + +const res = {}["none"]; +>res : Symbol(res, Decl(file1.ts, 31, 5)) + +interface B { prop: string } +>B : Symbol(B, Decl(file1.ts, 31, 23)) +>prop : Symbol(B.prop, Decl(file1.ts, 33, 13)) + +declare var b: B; +>b : Symbol(b, Decl(file1.ts, 34, 11)) +>B : Symbol(B, Decl(file1.ts, 31, 23)) + +const c = b["none"]; +>c : Symbol(c, Decl(file1.ts, 36, 5)) +>b : Symbol(b, Decl(file1.ts, 34, 11)) + +const d: B = { prop: "", excess: "yes" }; +>d : Symbol(d, Decl(file1.ts, 38, 5)) +>B : Symbol(B, Decl(file1.ts, 31, 23)) +>prop : Symbol(prop, Decl(file1.ts, 38, 14)) +>excess : Symbol(excess, Decl(file1.ts, 38, 24)) + +function f2(): string { return ""; } +>f2 : Symbol(f2, Decl(file1.ts, 38, 41)) + +const e = new f2(); +>e : Symbol(e, Decl(file1.ts, 41, 5)) +>f2 : Symbol(f2, Decl(file1.ts, 38, 41)) + +=== tests/cases/conformance/pragma/noImplicitAny/file2.ts === +// @ts-noImplicitAny true +import * as ns from "missing"; +>ns : Symbol(ns, Decl(file2.ts, 1, 6)) + +const a = p => p + 1; +>a : Symbol(a, Decl(file2.ts, 3, 5)) +>p : Symbol(p, Decl(file2.ts, 3, 9)) +>p : Symbol(p, Decl(file2.ts, 3, 9)) + +let x; +>x : Symbol(x, Decl(file2.ts, 5, 3)) + +x = "a"; +>x : Symbol(x, Decl(file2.ts, 5, 3)) + +x = 42; +>x : Symbol(x, Decl(file2.ts, 5, 3)) + +export class A { +>A : Symbol(A, Decl(file2.ts, 7, 7)) + + prop; +>prop : Symbol(A.prop, Decl(file2.ts, 9, 16)) + + prop2; +>prop2 : Symbol(A.prop2, Decl(file2.ts, 10, 9)) + + constructor() { + this.prop = "a"; +>this.prop : Symbol(A.prop, Decl(file2.ts, 9, 16)) +>this : Symbol(A, Decl(file2.ts, 7, 7)) +>prop : Symbol(A.prop, Decl(file2.ts, 9, 16)) + + this.prop = 42; +>this.prop : Symbol(A.prop, Decl(file2.ts, 9, 16)) +>this : Symbol(A, Decl(file2.ts, 7, 7)) +>prop : Symbol(A.prop, Decl(file2.ts, 9, 16)) + } + static stat; +>stat : Symbol(A.stat, Decl(file2.ts, 15, 5)) + + static stat2; +>stat2 : Symbol(A.stat2, Decl(file2.ts, 16, 16)) + + static { + this.stat = "a"; +>this.stat : Symbol(A.stat, Decl(file2.ts, 15, 5)) +>this : Symbol(A, Decl(file2.ts, 7, 7)) +>stat : Symbol(A.stat, Decl(file2.ts, 15, 5)) + + this.stat = 42; +>this.stat : Symbol(A.stat, Decl(file2.ts, 15, 5)) +>this : Symbol(A, Decl(file2.ts, 7, 7)) +>stat : Symbol(A.stat, Decl(file2.ts, 15, 5)) + } + + set access(param) {} +>access : Symbol(A.access, Decl(file2.ts, 21, 5), Decl(file2.ts, 23, 24)) +>param : Symbol(param, Decl(file2.ts, 23, 15)) + + get access() { return this.access; } +>access : Symbol(A.access, Decl(file2.ts, 21, 5), Decl(file2.ts, 23, 24)) +>this.access : Symbol(A.access, Decl(file2.ts, 21, 5), Decl(file2.ts, 23, 24)) +>this : Symbol(A, Decl(file2.ts, 7, 7)) +>access : Symbol(A.access, Decl(file2.ts, 21, 5), Decl(file2.ts, 23, 24)) +} + +export function f1() { +>f1 : Symbol(f1, Decl(file2.ts, 25, 1)) + + return f1(); +>f1 : Symbol(f1, Decl(file2.ts, 25, 1)) +} + +const res = {}["none"]; +>res : Symbol(res, Decl(file2.ts, 31, 5)) + +interface B { prop: string } +>B : Symbol(B, Decl(file2.ts, 31, 23)) +>prop : Symbol(B.prop, Decl(file2.ts, 33, 13)) + +declare var b: B; +>b : Symbol(b, Decl(file2.ts, 34, 11)) +>B : Symbol(B, Decl(file2.ts, 31, 23)) + +const c = b["none"]; +>c : Symbol(c, Decl(file2.ts, 36, 5)) +>b : Symbol(b, Decl(file2.ts, 34, 11)) + +const d: B = { prop: "", excess: "yes" }; +>d : Symbol(d, Decl(file2.ts, 38, 5)) +>B : Symbol(B, Decl(file2.ts, 31, 23)) +>prop : Symbol(prop, Decl(file2.ts, 38, 14)) +>excess : Symbol(excess, Decl(file2.ts, 38, 24)) + +function f2(): string { return ""; } +>f2 : Symbol(f2, Decl(file2.ts, 38, 41)) + +const e = new f2(); +>e : Symbol(e, Decl(file2.ts, 41, 5)) +>f2 : Symbol(f2, Decl(file2.ts, 38, 41)) + +=== tests/cases/conformance/pragma/noImplicitAny/file3.ts === +// @ts-noImplicitAny false +import * as ns from "missing"; +>ns : Symbol(ns, Decl(file3.ts, 1, 6)) + +const a = p => p + 1; +>a : Symbol(a, Decl(file3.ts, 3, 5)) +>p : Symbol(p, Decl(file3.ts, 3, 9)) +>p : Symbol(p, Decl(file3.ts, 3, 9)) + +let x; +>x : Symbol(x, Decl(file3.ts, 5, 3)) + +x = "a"; +>x : Symbol(x, Decl(file3.ts, 5, 3)) + +x = 42; +>x : Symbol(x, Decl(file3.ts, 5, 3)) + +export class A { +>A : Symbol(A, Decl(file3.ts, 7, 7)) + + prop; +>prop : Symbol(A.prop, Decl(file3.ts, 9, 16)) + + prop2; +>prop2 : Symbol(A.prop2, Decl(file3.ts, 10, 9)) + + constructor() { + this.prop = "a"; +>this.prop : Symbol(A.prop, Decl(file3.ts, 9, 16)) +>this : Symbol(A, Decl(file3.ts, 7, 7)) +>prop : Symbol(A.prop, Decl(file3.ts, 9, 16)) + + this.prop = 42; +>this.prop : Symbol(A.prop, Decl(file3.ts, 9, 16)) +>this : Symbol(A, Decl(file3.ts, 7, 7)) +>prop : Symbol(A.prop, Decl(file3.ts, 9, 16)) + } + static stat; +>stat : Symbol(A.stat, Decl(file3.ts, 15, 5)) + + static stat2; +>stat2 : Symbol(A.stat2, Decl(file3.ts, 16, 16)) + + static { + this.stat = "a"; +>this.stat : Symbol(A.stat, Decl(file3.ts, 15, 5)) +>this : Symbol(A, Decl(file3.ts, 7, 7)) +>stat : Symbol(A.stat, Decl(file3.ts, 15, 5)) + + this.stat = 42; +>this.stat : Symbol(A.stat, Decl(file3.ts, 15, 5)) +>this : Symbol(A, Decl(file3.ts, 7, 7)) +>stat : Symbol(A.stat, Decl(file3.ts, 15, 5)) + } + + set access(param) {} +>access : Symbol(A.access, Decl(file3.ts, 21, 5), Decl(file3.ts, 23, 24)) +>param : Symbol(param, Decl(file3.ts, 23, 15)) + + get access() { return this.access; } +>access : Symbol(A.access, Decl(file3.ts, 21, 5), Decl(file3.ts, 23, 24)) +>this.access : Symbol(A.access, Decl(file3.ts, 21, 5), Decl(file3.ts, 23, 24)) +>this : Symbol(A, Decl(file3.ts, 7, 7)) +>access : Symbol(A.access, Decl(file3.ts, 21, 5), Decl(file3.ts, 23, 24)) +} + +export function f1() { +>f1 : Symbol(f1, Decl(file3.ts, 25, 1)) + + return f1(); +>f1 : Symbol(f1, Decl(file3.ts, 25, 1)) +} + +const res = {}["none"]; +>res : Symbol(res, Decl(file3.ts, 31, 5)) + +interface B { prop: string } +>B : Symbol(B, Decl(file3.ts, 31, 23)) +>prop : Symbol(B.prop, Decl(file3.ts, 33, 13)) + +declare var b: B; +>b : Symbol(b, Decl(file3.ts, 34, 11)) +>B : Symbol(B, Decl(file3.ts, 31, 23)) + +const c = b["none"]; +>c : Symbol(c, Decl(file3.ts, 36, 5)) +>b : Symbol(b, Decl(file3.ts, 34, 11)) + +const d: B = { prop: "", excess: "yes" }; +>d : Symbol(d, Decl(file3.ts, 38, 5)) +>B : Symbol(B, Decl(file3.ts, 31, 23)) +>prop : Symbol(prop, Decl(file3.ts, 38, 14)) +>excess : Symbol(excess, Decl(file3.ts, 38, 24)) + +function f2(): string { return ""; } +>f2 : Symbol(f2, Decl(file3.ts, 38, 41)) + +const e = new f2(); +>e : Symbol(e, Decl(file3.ts, 41, 5)) +>f2 : Symbol(f2, Decl(file3.ts, 38, 41)) + +=== tests/cases/conformance/pragma/noImplicitAny/file4.ts === +import * as ns from "missing"; +>ns : Symbol(ns, Decl(file4.ts, 0, 6)) + +const a = p => p + 1; +>a : Symbol(a, Decl(file4.ts, 2, 5)) +>p : Symbol(p, Decl(file4.ts, 2, 9)) +>p : Symbol(p, Decl(file4.ts, 2, 9)) + +let x; +>x : Symbol(x, Decl(file4.ts, 4, 3)) + +x = "a"; +>x : Symbol(x, Decl(file4.ts, 4, 3)) + +x = 42; +>x : Symbol(x, Decl(file4.ts, 4, 3)) + +export class A { +>A : Symbol(A, Decl(file4.ts, 6, 7)) + + prop; +>prop : Symbol(A.prop, Decl(file4.ts, 8, 16)) + + prop2; +>prop2 : Symbol(A.prop2, Decl(file4.ts, 9, 9)) + + constructor() { + this.prop = "a"; +>this.prop : Symbol(A.prop, Decl(file4.ts, 8, 16)) +>this : Symbol(A, Decl(file4.ts, 6, 7)) +>prop : Symbol(A.prop, Decl(file4.ts, 8, 16)) + + this.prop = 42; +>this.prop : Symbol(A.prop, Decl(file4.ts, 8, 16)) +>this : Symbol(A, Decl(file4.ts, 6, 7)) +>prop : Symbol(A.prop, Decl(file4.ts, 8, 16)) + } + static stat; +>stat : Symbol(A.stat, Decl(file4.ts, 14, 5)) + + static stat2; +>stat2 : Symbol(A.stat2, Decl(file4.ts, 15, 16)) + + static { + this.stat = "a"; +>this.stat : Symbol(A.stat, Decl(file4.ts, 14, 5)) +>this : Symbol(A, Decl(file4.ts, 6, 7)) +>stat : Symbol(A.stat, Decl(file4.ts, 14, 5)) + + this.stat = 42; +>this.stat : Symbol(A.stat, Decl(file4.ts, 14, 5)) +>this : Symbol(A, Decl(file4.ts, 6, 7)) +>stat : Symbol(A.stat, Decl(file4.ts, 14, 5)) + } + + set access(param) {} +>access : Symbol(A.access, Decl(file4.ts, 20, 5), Decl(file4.ts, 22, 24)) +>param : Symbol(param, Decl(file4.ts, 22, 15)) + + get access() { return this.access; } +>access : Symbol(A.access, Decl(file4.ts, 20, 5), Decl(file4.ts, 22, 24)) +>this.access : Symbol(A.access, Decl(file4.ts, 20, 5), Decl(file4.ts, 22, 24)) +>this : Symbol(A, Decl(file4.ts, 6, 7)) +>access : Symbol(A.access, Decl(file4.ts, 20, 5), Decl(file4.ts, 22, 24)) +} + +export function f1() { +>f1 : Symbol(f1, Decl(file4.ts, 24, 1)) + + return f1(); +>f1 : Symbol(f1, Decl(file4.ts, 24, 1)) +} + +const res = {}["none"]; +>res : Symbol(res, Decl(file4.ts, 30, 5)) + +interface B { prop: string } +>B : Symbol(B, Decl(file4.ts, 30, 23)) +>prop : Symbol(B.prop, Decl(file4.ts, 32, 13)) + +declare var b: B; +>b : Symbol(b, Decl(file4.ts, 33, 11)) +>B : Symbol(B, Decl(file4.ts, 30, 23)) + +const c = b["none"]; +>c : Symbol(c, Decl(file4.ts, 35, 5)) +>b : Symbol(b, Decl(file4.ts, 33, 11)) + +const d: B = { prop: "", excess: "yes" }; +>d : Symbol(d, Decl(file4.ts, 37, 5)) +>B : Symbol(B, Decl(file4.ts, 30, 23)) +>prop : Symbol(prop, Decl(file4.ts, 37, 14)) +>excess : Symbol(excess, Decl(file4.ts, 37, 24)) + +function f2(): string { return ""; } +>f2 : Symbol(f2, Decl(file4.ts, 37, 41)) + +const e = new f2(); +>e : Symbol(e, Decl(file4.ts, 40, 5)) +>f2 : Symbol(f2, Decl(file4.ts, 37, 41)) + diff --git a/tests/baselines/reference/noImplicitAnyPragma1.types b/tests/baselines/reference/noImplicitAnyPragma1.types new file mode 100644 index 0000000000000..8ad58fb4e73b3 --- /dev/null +++ b/tests/baselines/reference/noImplicitAnyPragma1.types @@ -0,0 +1,503 @@ +=== tests/cases/conformance/pragma/noImplicitAny/file1.ts === +// @ts-noImplicitAny +import * as ns from "missing"; +>ns : any + +const a = p => p + 1; +>a : (p: any) => any +>p => p + 1 : (p: any) => any +>p : any +>p + 1 : any +>p : any +>1 : 1 + +let x; +>x : any + +x = "a"; +>x = "a" : "a" +>x : any +>"a" : "a" + +x = 42; +>x = 42 : 42 +>x : any +>42 : 42 + +export class A { +>A : A + + prop; +>prop : number + + prop2; +>prop2 : any + + constructor() { + this.prop = "a"; +>this.prop = "a" : "a" +>this.prop : number +>this : this +>prop : number +>"a" : "a" + + this.prop = 42; +>this.prop = 42 : 42 +>this.prop : number +>this : this +>prop : number +>42 : 42 + } + static stat; +>stat : number + + static stat2; +>stat2 : any + + static { + this.stat = "a"; +>this.stat = "a" : "a" +>this.stat : number +>this : typeof A +>stat : number +>"a" : "a" + + this.stat = 42; +>this.stat = 42 : 42 +>this.stat : number +>this : typeof A +>stat : number +>42 : 42 + } + + set access(param) {} +>access : any +>param : any + + get access() { return this.access; } +>access : any +>this.access : any +>this : this +>access : any +} + +export function f1() { +>f1 : () => any + + return f1(); +>f1() : any +>f1 : () => any +} + +const res = {}["none"]; +>res : undefined +>{}["none"] : undefined +>{} : {} +>"none" : "none" + +interface B { prop: string } +>prop : string + +declare var b: B; +>b : B + +const c = b["none"]; +>c : any +>b["none"] : any +>b : B +>"none" : "none" + +const d: B = { prop: "", excess: "yes" }; +>d : B +>{ prop: "", excess: "yes" } : { prop: string; excess: string; } +>prop : string +>"" : "" +>excess : string +>"yes" : "yes" + +function f2(): string { return ""; } +>f2 : () => string +>"" : "" + +const e = new f2(); +>e : any +>new f2() : any +>f2 : () => string + +=== tests/cases/conformance/pragma/noImplicitAny/file2.ts === +// @ts-noImplicitAny true +import * as ns from "missing"; +>ns : any + +const a = p => p + 1; +>a : (p: any) => any +>p => p + 1 : (p: any) => any +>p : any +>p + 1 : any +>p : any +>1 : 1 + +let x; +>x : any + +x = "a"; +>x = "a" : "a" +>x : any +>"a" : "a" + +x = 42; +>x = 42 : 42 +>x : any +>42 : 42 + +export class A { +>A : A + + prop; +>prop : number + + prop2; +>prop2 : any + + constructor() { + this.prop = "a"; +>this.prop = "a" : "a" +>this.prop : number +>this : this +>prop : number +>"a" : "a" + + this.prop = 42; +>this.prop = 42 : 42 +>this.prop : number +>this : this +>prop : number +>42 : 42 + } + static stat; +>stat : number + + static stat2; +>stat2 : any + + static { + this.stat = "a"; +>this.stat = "a" : "a" +>this.stat : number +>this : typeof A +>stat : number +>"a" : "a" + + this.stat = 42; +>this.stat = 42 : 42 +>this.stat : number +>this : typeof A +>stat : number +>42 : 42 + } + + set access(param) {} +>access : any +>param : any + + get access() { return this.access; } +>access : any +>this.access : any +>this : this +>access : any +} + +export function f1() { +>f1 : () => any + + return f1(); +>f1() : any +>f1 : () => any +} + +const res = {}["none"]; +>res : undefined +>{}["none"] : undefined +>{} : {} +>"none" : "none" + +interface B { prop: string } +>prop : string + +declare var b: B; +>b : B + +const c = b["none"]; +>c : any +>b["none"] : any +>b : B +>"none" : "none" + +const d: B = { prop: "", excess: "yes" }; +>d : B +>{ prop: "", excess: "yes" } : { prop: string; excess: string; } +>prop : string +>"" : "" +>excess : string +>"yes" : "yes" + +function f2(): string { return ""; } +>f2 : () => string +>"" : "" + +const e = new f2(); +>e : any +>new f2() : any +>f2 : () => string + +=== tests/cases/conformance/pragma/noImplicitAny/file3.ts === +// @ts-noImplicitAny false +import * as ns from "missing"; +>ns : any + +const a = p => p + 1; +>a : (p: any) => any +>p => p + 1 : (p: any) => any +>p : any +>p + 1 : any +>p : any +>1 : 1 + +let x; +>x : any + +x = "a"; +>x = "a" : "a" +>x : any +>"a" : "a" + +x = 42; +>x = 42 : 42 +>x : any +>42 : 42 + +export class A { +>A : A + + prop; +>prop : any + + prop2; +>prop2 : any + + constructor() { + this.prop = "a"; +>this.prop = "a" : "a" +>this.prop : any +>this : this +>prop : any +>"a" : "a" + + this.prop = 42; +>this.prop = 42 : 42 +>this.prop : any +>this : this +>prop : any +>42 : 42 + } + static stat; +>stat : any + + static stat2; +>stat2 : any + + static { + this.stat = "a"; +>this.stat = "a" : "a" +>this.stat : any +>this : typeof A +>stat : any +>"a" : "a" + + this.stat = 42; +>this.stat = 42 : 42 +>this.stat : any +>this : typeof A +>stat : any +>42 : 42 + } + + set access(param) {} +>access : any +>param : any + + get access() { return this.access; } +>access : any +>this.access : any +>this : this +>access : any +} + +export function f1() { +>f1 : () => any + + return f1(); +>f1() : any +>f1 : () => any +} + +const res = {}["none"]; +>res : any +>{}["none"] : any +>{} : {} +>"none" : "none" + +interface B { prop: string } +>prop : string + +declare var b: B; +>b : B + +const c = b["none"]; +>c : any +>b["none"] : any +>b : B +>"none" : "none" + +const d: B = { prop: "", excess: "yes" }; +>d : B +>{ prop: "", excess: "yes" } : { prop: string; excess: string; } +>prop : string +>"" : "" +>excess : string +>"yes" : "yes" + +function f2(): string { return ""; } +>f2 : () => string +>"" : "" + +const e = new f2(); +>e : any +>new f2() : any +>f2 : () => string + +=== tests/cases/conformance/pragma/noImplicitAny/file4.ts === +import * as ns from "missing"; +>ns : any + +const a = p => p + 1; +>a : (p: any) => any +>p => p + 1 : (p: any) => any +>p : any +>p + 1 : any +>p : any +>1 : 1 + +let x; +>x : any + +x = "a"; +>x = "a" : "a" +>x : any +>"a" : "a" + +x = 42; +>x = 42 : 42 +>x : any +>42 : 42 + +export class A { +>A : A + + prop; +>prop : any + + prop2; +>prop2 : any + + constructor() { + this.prop = "a"; +>this.prop = "a" : "a" +>this.prop : any +>this : this +>prop : any +>"a" : "a" + + this.prop = 42; +>this.prop = 42 : 42 +>this.prop : any +>this : this +>prop : any +>42 : 42 + } + static stat; +>stat : any + + static stat2; +>stat2 : any + + static { + this.stat = "a"; +>this.stat = "a" : "a" +>this.stat : any +>this : typeof A +>stat : any +>"a" : "a" + + this.stat = 42; +>this.stat = 42 : 42 +>this.stat : any +>this : typeof A +>stat : any +>42 : 42 + } + + set access(param) {} +>access : any +>param : any + + get access() { return this.access; } +>access : any +>this.access : any +>this : this +>access : any +} + +export function f1() { +>f1 : () => any + + return f1(); +>f1() : any +>f1 : () => any +} + +const res = {}["none"]; +>res : any +>{}["none"] : any +>{} : {} +>"none" : "none" + +interface B { prop: string } +>prop : string + +declare var b: B; +>b : B + +const c = b["none"]; +>c : any +>b["none"] : any +>b : B +>"none" : "none" + +const d: B = { prop: "", excess: "yes" }; +>d : B +>{ prop: "", excess: "yes" } : { prop: string; excess: string; } +>prop : string +>"" : "" +>excess : string +>"yes" : "yes" + +function f2(): string { return ""; } +>f2 : () => string +>"" : "" + +const e = new f2(); +>e : any +>new f2() : any +>f2 : () => string + diff --git a/tests/baselines/reference/noImplicitAnyPragma2.errors.txt b/tests/baselines/reference/noImplicitAnyPragma2.errors.txt new file mode 100644 index 0000000000000..a834b7c2ce10c --- /dev/null +++ b/tests/baselines/reference/noImplicitAnyPragma2.errors.txt @@ -0,0 +1,304 @@ +tests/cases/conformance/pragma/noImplicitAny/file1.ts(2,21): error TS2792: Cannot find module 'missing'. Did you mean to set the 'moduleResolution' option to 'node', or to add aliases to the 'paths' option? +tests/cases/conformance/pragma/noImplicitAny/file1.ts(4,11): error TS7006: Parameter 'p' implicitly has an 'any' type. +tests/cases/conformance/pragma/noImplicitAny/file1.ts(12,5): error TS7008: Member 'prop2' implicitly has an 'any' type. +tests/cases/conformance/pragma/noImplicitAny/file1.ts(14,9): error TS2322: Type 'string' is not assignable to type 'number'. +tests/cases/conformance/pragma/noImplicitAny/file1.ts(18,12): error TS7008: Member 'stat2' implicitly has an 'any' type. +tests/cases/conformance/pragma/noImplicitAny/file1.ts(20,9): error TS2322: Type 'string' is not assignable to type 'number'. +tests/cases/conformance/pragma/noImplicitAny/file1.ts(25,9): error TS7023: 'access' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions. +tests/cases/conformance/pragma/noImplicitAny/file1.ts(28,17): error TS7023: 'f1' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions. +tests/cases/conformance/pragma/noImplicitAny/file1.ts(32,13): error TS2339: Property 'none' does not exist on type '{}'. +tests/cases/conformance/pragma/noImplicitAny/file1.ts(37,11): error TS7053: Element implicitly has an 'any' type because expression of type '"none"' can't be used to index type 'B'. + Property 'none' does not exist on type 'B'. +tests/cases/conformance/pragma/noImplicitAny/file1.ts(39,26): error TS2322: Type '{ prop: string; excess: string; }' is not assignable to type 'B'. + Object literal may only specify known properties, and 'excess' does not exist in type 'B'. +tests/cases/conformance/pragma/noImplicitAny/file1.ts(42,11): error TS7009: 'new' expression, whose target lacks a construct signature, implicitly has an 'any' type. +tests/cases/conformance/pragma/noImplicitAny/file2.ts(2,21): error TS2792: Cannot find module 'missing'. Did you mean to set the 'moduleResolution' option to 'node', or to add aliases to the 'paths' option? +tests/cases/conformance/pragma/noImplicitAny/file2.ts(4,11): error TS7006: Parameter 'p' implicitly has an 'any' type. +tests/cases/conformance/pragma/noImplicitAny/file2.ts(12,5): error TS7008: Member 'prop2' implicitly has an 'any' type. +tests/cases/conformance/pragma/noImplicitAny/file2.ts(14,9): error TS2322: Type 'string' is not assignable to type 'number'. +tests/cases/conformance/pragma/noImplicitAny/file2.ts(18,12): error TS7008: Member 'stat2' implicitly has an 'any' type. +tests/cases/conformance/pragma/noImplicitAny/file2.ts(20,9): error TS2322: Type 'string' is not assignable to type 'number'. +tests/cases/conformance/pragma/noImplicitAny/file2.ts(25,9): error TS7023: 'access' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions. +tests/cases/conformance/pragma/noImplicitAny/file2.ts(28,17): error TS7023: 'f1' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions. +tests/cases/conformance/pragma/noImplicitAny/file2.ts(32,13): error TS2339: Property 'none' does not exist on type '{}'. +tests/cases/conformance/pragma/noImplicitAny/file2.ts(37,11): error TS7053: Element implicitly has an 'any' type because expression of type '"none"' can't be used to index type 'B'. + Property 'none' does not exist on type 'B'. +tests/cases/conformance/pragma/noImplicitAny/file2.ts(39,26): error TS2322: Type '{ prop: string; excess: string; }' is not assignable to type 'B'. + Object literal may only specify known properties, and 'excess' does not exist in type 'B'. +tests/cases/conformance/pragma/noImplicitAny/file2.ts(42,11): error TS7009: 'new' expression, whose target lacks a construct signature, implicitly has an 'any' type. +tests/cases/conformance/pragma/noImplicitAny/file3.ts(2,21): error TS2792: Cannot find module 'missing'. Did you mean to set the 'moduleResolution' option to 'node', or to add aliases to the 'paths' option? +tests/cases/conformance/pragma/noImplicitAny/file3.ts(39,26): error TS2322: Type '{ prop: string; excess: string; }' is not assignable to type 'B'. + Object literal may only specify known properties, and 'excess' does not exist in type 'B'. +tests/cases/conformance/pragma/noImplicitAny/file3.ts(42,11): error TS2350: Only a void function can be called with the 'new' keyword. +tests/cases/conformance/pragma/noImplicitAny/file4.ts(1,21): error TS2792: Cannot find module 'missing'. Did you mean to set the 'moduleResolution' option to 'node', or to add aliases to the 'paths' option? +tests/cases/conformance/pragma/noImplicitAny/file4.ts(3,11): error TS7006: Parameter 'p' implicitly has an 'any' type. +tests/cases/conformance/pragma/noImplicitAny/file4.ts(11,5): error TS7008: Member 'prop2' implicitly has an 'any' type. +tests/cases/conformance/pragma/noImplicitAny/file4.ts(13,9): error TS2322: Type 'string' is not assignable to type 'number'. +tests/cases/conformance/pragma/noImplicitAny/file4.ts(17,12): error TS7008: Member 'stat2' implicitly has an 'any' type. +tests/cases/conformance/pragma/noImplicitAny/file4.ts(19,9): error TS2322: Type 'string' is not assignable to type 'number'. +tests/cases/conformance/pragma/noImplicitAny/file4.ts(24,9): error TS7023: 'access' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions. +tests/cases/conformance/pragma/noImplicitAny/file4.ts(27,17): error TS7023: 'f1' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions. +tests/cases/conformance/pragma/noImplicitAny/file4.ts(31,13): error TS2339: Property 'none' does not exist on type '{}'. +tests/cases/conformance/pragma/noImplicitAny/file4.ts(36,11): error TS7053: Element implicitly has an 'any' type because expression of type '"none"' can't be used to index type 'B'. + Property 'none' does not exist on type 'B'. +tests/cases/conformance/pragma/noImplicitAny/file4.ts(38,26): error TS2322: Type '{ prop: string; excess: string; }' is not assignable to type 'B'. + Object literal may only specify known properties, and 'excess' does not exist in type 'B'. +tests/cases/conformance/pragma/noImplicitAny/file4.ts(41,11): error TS7009: 'new' expression, whose target lacks a construct signature, implicitly has an 'any' type. + + +==== tests/cases/conformance/pragma/noImplicitAny/file1.ts (12 errors) ==== + // @ts-noImplicitAny + import * as ns from "missing"; + ~~~~~~~~~ +!!! error TS2792: Cannot find module 'missing'. Did you mean to set the 'moduleResolution' option to 'node', or to add aliases to the 'paths' option? + + const a = p => p + 1; + ~ +!!! error TS7006: Parameter 'p' implicitly has an 'any' type. + + let x; + x = "a"; + x = 42; + + export class A { + prop; + prop2; + ~~~~~ +!!! error TS7008: Member 'prop2' implicitly has an 'any' type. + constructor() { + this.prop = "a"; + ~~~~~~~~~ +!!! error TS2322: Type 'string' is not assignable to type 'number'. + this.prop = 42; + } + static stat; + static stat2; + ~~~~~ +!!! error TS7008: Member 'stat2' implicitly has an 'any' type. + static { + this.stat = "a"; + ~~~~~~~~~ +!!! error TS2322: Type 'string' is not assignable to type 'number'. + this.stat = 42; + } + + set access(param) {} + get access() { return this.access; } + ~~~~~~ +!!! error TS7023: 'access' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions. + } + + export function f1() { + ~~ +!!! error TS7023: 'f1' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions. + return f1(); + } + + const res = {}["none"]; + ~~~~~~~~~~ +!!! error TS2339: Property 'none' does not exist on type '{}'. + + interface B { prop: string } + declare var b: B; + + const c = b["none"]; + ~~~~~~~~~ +!!! error TS7053: Element implicitly has an 'any' type because expression of type '"none"' can't be used to index type 'B'. +!!! error TS7053: Property 'none' does not exist on type 'B'. + + const d: B = { prop: "", excess: "yes" }; + ~~~~~~~~~~~~~ +!!! error TS2322: Type '{ prop: string; excess: string; }' is not assignable to type 'B'. +!!! error TS2322: Object literal may only specify known properties, and 'excess' does not exist in type 'B'. + + function f2(): string { return ""; } + const e = new f2(); + ~~~~~~~~ +!!! error TS7009: 'new' expression, whose target lacks a construct signature, implicitly has an 'any' type. +==== tests/cases/conformance/pragma/noImplicitAny/file2.ts (12 errors) ==== + // @ts-noImplicitAny true + import * as ns from "missing"; + ~~~~~~~~~ +!!! error TS2792: Cannot find module 'missing'. Did you mean to set the 'moduleResolution' option to 'node', or to add aliases to the 'paths' option? + + const a = p => p + 1; + ~ +!!! error TS7006: Parameter 'p' implicitly has an 'any' type. + + let x; + x = "a"; + x = 42; + + export class A { + prop; + prop2; + ~~~~~ +!!! error TS7008: Member 'prop2' implicitly has an 'any' type. + constructor() { + this.prop = "a"; + ~~~~~~~~~ +!!! error TS2322: Type 'string' is not assignable to type 'number'. + this.prop = 42; + } + static stat; + static stat2; + ~~~~~ +!!! error TS7008: Member 'stat2' implicitly has an 'any' type. + static { + this.stat = "a"; + ~~~~~~~~~ +!!! error TS2322: Type 'string' is not assignable to type 'number'. + this.stat = 42; + } + + set access(param) {} + get access() { return this.access; } + ~~~~~~ +!!! error TS7023: 'access' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions. + } + + export function f1() { + ~~ +!!! error TS7023: 'f1' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions. + return f1(); + } + + const res = {}["none"]; + ~~~~~~~~~~ +!!! error TS2339: Property 'none' does not exist on type '{}'. + + interface B { prop: string } + declare var b: B; + + const c = b["none"]; + ~~~~~~~~~ +!!! error TS7053: Element implicitly has an 'any' type because expression of type '"none"' can't be used to index type 'B'. +!!! error TS7053: Property 'none' does not exist on type 'B'. + + const d: B = { prop: "", excess: "yes" }; + ~~~~~~~~~~~~~ +!!! error TS2322: Type '{ prop: string; excess: string; }' is not assignable to type 'B'. +!!! error TS2322: Object literal may only specify known properties, and 'excess' does not exist in type 'B'. + + function f2(): string { return ""; } + const e = new f2(); + ~~~~~~~~ +!!! error TS7009: 'new' expression, whose target lacks a construct signature, implicitly has an 'any' type. +==== tests/cases/conformance/pragma/noImplicitAny/file3.ts (3 errors) ==== + // @ts-noImplicitAny false + import * as ns from "missing"; + ~~~~~~~~~ +!!! error TS2792: Cannot find module 'missing'. Did you mean to set the 'moduleResolution' option to 'node', or to add aliases to the 'paths' option? + + const a = p => p + 1; + + let x; + x = "a"; + x = 42; + + export class A { + prop; + prop2; + constructor() { + this.prop = "a"; + this.prop = 42; + } + static stat; + static stat2; + static { + this.stat = "a"; + this.stat = 42; + } + + set access(param) {} + get access() { return this.access; } + } + + export function f1() { + return f1(); + } + + const res = {}["none"]; + + interface B { prop: string } + declare var b: B; + + const c = b["none"]; + + const d: B = { prop: "", excess: "yes" }; + ~~~~~~~~~~~~~ +!!! error TS2322: Type '{ prop: string; excess: string; }' is not assignable to type 'B'. +!!! error TS2322: Object literal may only specify known properties, and 'excess' does not exist in type 'B'. + + function f2(): string { return ""; } + const e = new f2(); + ~~~~~~~~ +!!! error TS2350: Only a void function can be called with the 'new' keyword. +==== tests/cases/conformance/pragma/noImplicitAny/file4.ts (12 errors) ==== + import * as ns from "missing"; + ~~~~~~~~~ +!!! error TS2792: Cannot find module 'missing'. Did you mean to set the 'moduleResolution' option to 'node', or to add aliases to the 'paths' option? + + const a = p => p + 1; + ~ +!!! error TS7006: Parameter 'p' implicitly has an 'any' type. + + let x; + x = "a"; + x = 42; + + export class A { + prop; + prop2; + ~~~~~ +!!! error TS7008: Member 'prop2' implicitly has an 'any' type. + constructor() { + this.prop = "a"; + ~~~~~~~~~ +!!! error TS2322: Type 'string' is not assignable to type 'number'. + this.prop = 42; + } + static stat; + static stat2; + ~~~~~ +!!! error TS7008: Member 'stat2' implicitly has an 'any' type. + static { + this.stat = "a"; + ~~~~~~~~~ +!!! error TS2322: Type 'string' is not assignable to type 'number'. + this.stat = 42; + } + + set access(param) {} + get access() { return this.access; } + ~~~~~~ +!!! error TS7023: 'access' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions. + } + + export function f1() { + ~~ +!!! error TS7023: 'f1' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions. + return f1(); + } + + const res = {}["none"]; + ~~~~~~~~~~ +!!! error TS2339: Property 'none' does not exist on type '{}'. + + interface B { prop: string } + declare var b: B; + + const c = b["none"]; + ~~~~~~~~~ +!!! error TS7053: Element implicitly has an 'any' type because expression of type '"none"' can't be used to index type 'B'. +!!! error TS7053: Property 'none' does not exist on type 'B'. + + const d: B = { prop: "", excess: "yes" }; + ~~~~~~~~~~~~~ +!!! error TS2322: Type '{ prop: string; excess: string; }' is not assignable to type 'B'. +!!! error TS2322: Object literal may only specify known properties, and 'excess' does not exist in type 'B'. + + function f2(): string { return ""; } + const e = new f2(); + ~~~~~~~~ +!!! error TS7009: 'new' expression, whose target lacks a construct signature, implicitly has an 'any' type. \ No newline at end of file diff --git a/tests/baselines/reference/noImplicitAnyPragma2.js b/tests/baselines/reference/noImplicitAnyPragma2.js new file mode 100644 index 0000000000000..0a340c05675c0 --- /dev/null +++ b/tests/baselines/reference/noImplicitAnyPragma2.js @@ -0,0 +1,282 @@ +//// [tests/cases/conformance/pragma/noImplicitAny/noImplicitAnyPragma2.ts] //// + +//// [file1.ts] +// @ts-noImplicitAny +import * as ns from "missing"; + +const a = p => p + 1; + +let x; +x = "a"; +x = 42; + +export class A { + prop; + prop2; + constructor() { + this.prop = "a"; + this.prop = 42; + } + static stat; + static stat2; + static { + this.stat = "a"; + this.stat = 42; + } + + set access(param) {} + get access() { return this.access; } +} + +export function f1() { + return f1(); +} + +const res = {}["none"]; + +interface B { prop: string } +declare var b: B; + +const c = b["none"]; + +const d: B = { prop: "", excess: "yes" }; + +function f2(): string { return ""; } +const e = new f2(); +//// [file2.ts] +// @ts-noImplicitAny true +import * as ns from "missing"; + +const a = p => p + 1; + +let x; +x = "a"; +x = 42; + +export class A { + prop; + prop2; + constructor() { + this.prop = "a"; + this.prop = 42; + } + static stat; + static stat2; + static { + this.stat = "a"; + this.stat = 42; + } + + set access(param) {} + get access() { return this.access; } +} + +export function f1() { + return f1(); +} + +const res = {}["none"]; + +interface B { prop: string } +declare var b: B; + +const c = b["none"]; + +const d: B = { prop: "", excess: "yes" }; + +function f2(): string { return ""; } +const e = new f2(); +//// [file3.ts] +// @ts-noImplicitAny false +import * as ns from "missing"; + +const a = p => p + 1; + +let x; +x = "a"; +x = 42; + +export class A { + prop; + prop2; + constructor() { + this.prop = "a"; + this.prop = 42; + } + static stat; + static stat2; + static { + this.stat = "a"; + this.stat = 42; + } + + set access(param) {} + get access() { return this.access; } +} + +export function f1() { + return f1(); +} + +const res = {}["none"]; + +interface B { prop: string } +declare var b: B; + +const c = b["none"]; + +const d: B = { prop: "", excess: "yes" }; + +function f2(): string { return ""; } +const e = new f2(); +//// [file4.ts] +import * as ns from "missing"; + +const a = p => p + 1; + +let x; +x = "a"; +x = 42; + +export class A { + prop; + prop2; + constructor() { + this.prop = "a"; + this.prop = 42; + } + static stat; + static stat2; + static { + this.stat = "a"; + this.stat = 42; + } + + set access(param) {} + get access() { return this.access; } +} + +export function f1() { + return f1(); +} + +const res = {}["none"]; + +interface B { prop: string } +declare var b: B; + +const c = b["none"]; + +const d: B = { prop: "", excess: "yes" }; + +function f2(): string { return ""; } +const e = new f2(); + +//// [file1.js] +var _a; +const a = p => p + 1; +let x; +x = "a"; +x = 42; +export class A { + constructor() { + this.prop = "a"; + this.prop = 42; + } + set access(param) { } + get access() { return this.access; } +} +_a = A; +(() => { + _a.stat = "a"; + _a.stat = 42; +})(); +export function f1() { + return f1(); +} +const res = {}["none"]; +const c = b["none"]; +const d = { prop: "", excess: "yes" }; +function f2() { return ""; } +const e = new f2(); +//// [file2.js] +var _a; +const a = p => p + 1; +let x; +x = "a"; +x = 42; +export class A { + constructor() { + this.prop = "a"; + this.prop = 42; + } + set access(param) { } + get access() { return this.access; } +} +_a = A; +(() => { + _a.stat = "a"; + _a.stat = 42; +})(); +export function f1() { + return f1(); +} +const res = {}["none"]; +const c = b["none"]; +const d = { prop: "", excess: "yes" }; +function f2() { return ""; } +const e = new f2(); +//// [file3.js] +var _a; +const a = p => p + 1; +let x; +x = "a"; +x = 42; +export class A { + constructor() { + this.prop = "a"; + this.prop = 42; + } + set access(param) { } + get access() { return this.access; } +} +_a = A; +(() => { + _a.stat = "a"; + _a.stat = 42; +})(); +export function f1() { + return f1(); +} +const res = {}["none"]; +const c = b["none"]; +const d = { prop: "", excess: "yes" }; +function f2() { return ""; } +const e = new f2(); +//// [file4.js] +var _a; +const a = p => p + 1; +let x; +x = "a"; +x = 42; +export class A { + constructor() { + this.prop = "a"; + this.prop = 42; + } + set access(param) { } + get access() { return this.access; } +} +_a = A; +(() => { + _a.stat = "a"; + _a.stat = 42; +})(); +export function f1() { + return f1(); +} +const res = {}["none"]; +const c = b["none"]; +const d = { prop: "", excess: "yes" }; +function f2() { return ""; } +const e = new f2(); diff --git a/tests/baselines/reference/noImplicitAnyPragma2.symbols b/tests/baselines/reference/noImplicitAnyPragma2.symbols new file mode 100644 index 0000000000000..73ba0d619be12 --- /dev/null +++ b/tests/baselines/reference/noImplicitAnyPragma2.symbols @@ -0,0 +1,411 @@ +=== tests/cases/conformance/pragma/noImplicitAny/file1.ts === +// @ts-noImplicitAny +import * as ns from "missing"; +>ns : Symbol(ns, Decl(file1.ts, 1, 6)) + +const a = p => p + 1; +>a : Symbol(a, Decl(file1.ts, 3, 5)) +>p : Symbol(p, Decl(file1.ts, 3, 9)) +>p : Symbol(p, Decl(file1.ts, 3, 9)) + +let x; +>x : Symbol(x, Decl(file1.ts, 5, 3)) + +x = "a"; +>x : Symbol(x, Decl(file1.ts, 5, 3)) + +x = 42; +>x : Symbol(x, Decl(file1.ts, 5, 3)) + +export class A { +>A : Symbol(A, Decl(file1.ts, 7, 7)) + + prop; +>prop : Symbol(A.prop, Decl(file1.ts, 9, 16)) + + prop2; +>prop2 : Symbol(A.prop2, Decl(file1.ts, 10, 9)) + + constructor() { + this.prop = "a"; +>this.prop : Symbol(A.prop, Decl(file1.ts, 9, 16)) +>this : Symbol(A, Decl(file1.ts, 7, 7)) +>prop : Symbol(A.prop, Decl(file1.ts, 9, 16)) + + this.prop = 42; +>this.prop : Symbol(A.prop, Decl(file1.ts, 9, 16)) +>this : Symbol(A, Decl(file1.ts, 7, 7)) +>prop : Symbol(A.prop, Decl(file1.ts, 9, 16)) + } + static stat; +>stat : Symbol(A.stat, Decl(file1.ts, 15, 5)) + + static stat2; +>stat2 : Symbol(A.stat2, Decl(file1.ts, 16, 16)) + + static { + this.stat = "a"; +>this.stat : Symbol(A.stat, Decl(file1.ts, 15, 5)) +>this : Symbol(A, Decl(file1.ts, 7, 7)) +>stat : Symbol(A.stat, Decl(file1.ts, 15, 5)) + + this.stat = 42; +>this.stat : Symbol(A.stat, Decl(file1.ts, 15, 5)) +>this : Symbol(A, Decl(file1.ts, 7, 7)) +>stat : Symbol(A.stat, Decl(file1.ts, 15, 5)) + } + + set access(param) {} +>access : Symbol(A.access, Decl(file1.ts, 21, 5), Decl(file1.ts, 23, 24)) +>param : Symbol(param, Decl(file1.ts, 23, 15)) + + get access() { return this.access; } +>access : Symbol(A.access, Decl(file1.ts, 21, 5), Decl(file1.ts, 23, 24)) +>this.access : Symbol(A.access, Decl(file1.ts, 21, 5), Decl(file1.ts, 23, 24)) +>this : Symbol(A, Decl(file1.ts, 7, 7)) +>access : Symbol(A.access, Decl(file1.ts, 21, 5), Decl(file1.ts, 23, 24)) +} + +export function f1() { +>f1 : Symbol(f1, Decl(file1.ts, 25, 1)) + + return f1(); +>f1 : Symbol(f1, Decl(file1.ts, 25, 1)) +} + +const res = {}["none"]; +>res : Symbol(res, Decl(file1.ts, 31, 5)) + +interface B { prop: string } +>B : Symbol(B, Decl(file1.ts, 31, 23)) +>prop : Symbol(B.prop, Decl(file1.ts, 33, 13)) + +declare var b: B; +>b : Symbol(b, Decl(file1.ts, 34, 11)) +>B : Symbol(B, Decl(file1.ts, 31, 23)) + +const c = b["none"]; +>c : Symbol(c, Decl(file1.ts, 36, 5)) +>b : Symbol(b, Decl(file1.ts, 34, 11)) + +const d: B = { prop: "", excess: "yes" }; +>d : Symbol(d, Decl(file1.ts, 38, 5)) +>B : Symbol(B, Decl(file1.ts, 31, 23)) +>prop : Symbol(prop, Decl(file1.ts, 38, 14)) +>excess : Symbol(excess, Decl(file1.ts, 38, 24)) + +function f2(): string { return ""; } +>f2 : Symbol(f2, Decl(file1.ts, 38, 41)) + +const e = new f2(); +>e : Symbol(e, Decl(file1.ts, 41, 5)) +>f2 : Symbol(f2, Decl(file1.ts, 38, 41)) + +=== tests/cases/conformance/pragma/noImplicitAny/file2.ts === +// @ts-noImplicitAny true +import * as ns from "missing"; +>ns : Symbol(ns, Decl(file2.ts, 1, 6)) + +const a = p => p + 1; +>a : Symbol(a, Decl(file2.ts, 3, 5)) +>p : Symbol(p, Decl(file2.ts, 3, 9)) +>p : Symbol(p, Decl(file2.ts, 3, 9)) + +let x; +>x : Symbol(x, Decl(file2.ts, 5, 3)) + +x = "a"; +>x : Symbol(x, Decl(file2.ts, 5, 3)) + +x = 42; +>x : Symbol(x, Decl(file2.ts, 5, 3)) + +export class A { +>A : Symbol(A, Decl(file2.ts, 7, 7)) + + prop; +>prop : Symbol(A.prop, Decl(file2.ts, 9, 16)) + + prop2; +>prop2 : Symbol(A.prop2, Decl(file2.ts, 10, 9)) + + constructor() { + this.prop = "a"; +>this.prop : Symbol(A.prop, Decl(file2.ts, 9, 16)) +>this : Symbol(A, Decl(file2.ts, 7, 7)) +>prop : Symbol(A.prop, Decl(file2.ts, 9, 16)) + + this.prop = 42; +>this.prop : Symbol(A.prop, Decl(file2.ts, 9, 16)) +>this : Symbol(A, Decl(file2.ts, 7, 7)) +>prop : Symbol(A.prop, Decl(file2.ts, 9, 16)) + } + static stat; +>stat : Symbol(A.stat, Decl(file2.ts, 15, 5)) + + static stat2; +>stat2 : Symbol(A.stat2, Decl(file2.ts, 16, 16)) + + static { + this.stat = "a"; +>this.stat : Symbol(A.stat, Decl(file2.ts, 15, 5)) +>this : Symbol(A, Decl(file2.ts, 7, 7)) +>stat : Symbol(A.stat, Decl(file2.ts, 15, 5)) + + this.stat = 42; +>this.stat : Symbol(A.stat, Decl(file2.ts, 15, 5)) +>this : Symbol(A, Decl(file2.ts, 7, 7)) +>stat : Symbol(A.stat, Decl(file2.ts, 15, 5)) + } + + set access(param) {} +>access : Symbol(A.access, Decl(file2.ts, 21, 5), Decl(file2.ts, 23, 24)) +>param : Symbol(param, Decl(file2.ts, 23, 15)) + + get access() { return this.access; } +>access : Symbol(A.access, Decl(file2.ts, 21, 5), Decl(file2.ts, 23, 24)) +>this.access : Symbol(A.access, Decl(file2.ts, 21, 5), Decl(file2.ts, 23, 24)) +>this : Symbol(A, Decl(file2.ts, 7, 7)) +>access : Symbol(A.access, Decl(file2.ts, 21, 5), Decl(file2.ts, 23, 24)) +} + +export function f1() { +>f1 : Symbol(f1, Decl(file2.ts, 25, 1)) + + return f1(); +>f1 : Symbol(f1, Decl(file2.ts, 25, 1)) +} + +const res = {}["none"]; +>res : Symbol(res, Decl(file2.ts, 31, 5)) + +interface B { prop: string } +>B : Symbol(B, Decl(file2.ts, 31, 23)) +>prop : Symbol(B.prop, Decl(file2.ts, 33, 13)) + +declare var b: B; +>b : Symbol(b, Decl(file2.ts, 34, 11)) +>B : Symbol(B, Decl(file2.ts, 31, 23)) + +const c = b["none"]; +>c : Symbol(c, Decl(file2.ts, 36, 5)) +>b : Symbol(b, Decl(file2.ts, 34, 11)) + +const d: B = { prop: "", excess: "yes" }; +>d : Symbol(d, Decl(file2.ts, 38, 5)) +>B : Symbol(B, Decl(file2.ts, 31, 23)) +>prop : Symbol(prop, Decl(file2.ts, 38, 14)) +>excess : Symbol(excess, Decl(file2.ts, 38, 24)) + +function f2(): string { return ""; } +>f2 : Symbol(f2, Decl(file2.ts, 38, 41)) + +const e = new f2(); +>e : Symbol(e, Decl(file2.ts, 41, 5)) +>f2 : Symbol(f2, Decl(file2.ts, 38, 41)) + +=== tests/cases/conformance/pragma/noImplicitAny/file3.ts === +// @ts-noImplicitAny false +import * as ns from "missing"; +>ns : Symbol(ns, Decl(file3.ts, 1, 6)) + +const a = p => p + 1; +>a : Symbol(a, Decl(file3.ts, 3, 5)) +>p : Symbol(p, Decl(file3.ts, 3, 9)) +>p : Symbol(p, Decl(file3.ts, 3, 9)) + +let x; +>x : Symbol(x, Decl(file3.ts, 5, 3)) + +x = "a"; +>x : Symbol(x, Decl(file3.ts, 5, 3)) + +x = 42; +>x : Symbol(x, Decl(file3.ts, 5, 3)) + +export class A { +>A : Symbol(A, Decl(file3.ts, 7, 7)) + + prop; +>prop : Symbol(A.prop, Decl(file3.ts, 9, 16)) + + prop2; +>prop2 : Symbol(A.prop2, Decl(file3.ts, 10, 9)) + + constructor() { + this.prop = "a"; +>this.prop : Symbol(A.prop, Decl(file3.ts, 9, 16)) +>this : Symbol(A, Decl(file3.ts, 7, 7)) +>prop : Symbol(A.prop, Decl(file3.ts, 9, 16)) + + this.prop = 42; +>this.prop : Symbol(A.prop, Decl(file3.ts, 9, 16)) +>this : Symbol(A, Decl(file3.ts, 7, 7)) +>prop : Symbol(A.prop, Decl(file3.ts, 9, 16)) + } + static stat; +>stat : Symbol(A.stat, Decl(file3.ts, 15, 5)) + + static stat2; +>stat2 : Symbol(A.stat2, Decl(file3.ts, 16, 16)) + + static { + this.stat = "a"; +>this.stat : Symbol(A.stat, Decl(file3.ts, 15, 5)) +>this : Symbol(A, Decl(file3.ts, 7, 7)) +>stat : Symbol(A.stat, Decl(file3.ts, 15, 5)) + + this.stat = 42; +>this.stat : Symbol(A.stat, Decl(file3.ts, 15, 5)) +>this : Symbol(A, Decl(file3.ts, 7, 7)) +>stat : Symbol(A.stat, Decl(file3.ts, 15, 5)) + } + + set access(param) {} +>access : Symbol(A.access, Decl(file3.ts, 21, 5), Decl(file3.ts, 23, 24)) +>param : Symbol(param, Decl(file3.ts, 23, 15)) + + get access() { return this.access; } +>access : Symbol(A.access, Decl(file3.ts, 21, 5), Decl(file3.ts, 23, 24)) +>this.access : Symbol(A.access, Decl(file3.ts, 21, 5), Decl(file3.ts, 23, 24)) +>this : Symbol(A, Decl(file3.ts, 7, 7)) +>access : Symbol(A.access, Decl(file3.ts, 21, 5), Decl(file3.ts, 23, 24)) +} + +export function f1() { +>f1 : Symbol(f1, Decl(file3.ts, 25, 1)) + + return f1(); +>f1 : Symbol(f1, Decl(file3.ts, 25, 1)) +} + +const res = {}["none"]; +>res : Symbol(res, Decl(file3.ts, 31, 5)) + +interface B { prop: string } +>B : Symbol(B, Decl(file3.ts, 31, 23)) +>prop : Symbol(B.prop, Decl(file3.ts, 33, 13)) + +declare var b: B; +>b : Symbol(b, Decl(file3.ts, 34, 11)) +>B : Symbol(B, Decl(file3.ts, 31, 23)) + +const c = b["none"]; +>c : Symbol(c, Decl(file3.ts, 36, 5)) +>b : Symbol(b, Decl(file3.ts, 34, 11)) + +const d: B = { prop: "", excess: "yes" }; +>d : Symbol(d, Decl(file3.ts, 38, 5)) +>B : Symbol(B, Decl(file3.ts, 31, 23)) +>prop : Symbol(prop, Decl(file3.ts, 38, 14)) +>excess : Symbol(excess, Decl(file3.ts, 38, 24)) + +function f2(): string { return ""; } +>f2 : Symbol(f2, Decl(file3.ts, 38, 41)) + +const e = new f2(); +>e : Symbol(e, Decl(file3.ts, 41, 5)) +>f2 : Symbol(f2, Decl(file3.ts, 38, 41)) + +=== tests/cases/conformance/pragma/noImplicitAny/file4.ts === +import * as ns from "missing"; +>ns : Symbol(ns, Decl(file4.ts, 0, 6)) + +const a = p => p + 1; +>a : Symbol(a, Decl(file4.ts, 2, 5)) +>p : Symbol(p, Decl(file4.ts, 2, 9)) +>p : Symbol(p, Decl(file4.ts, 2, 9)) + +let x; +>x : Symbol(x, Decl(file4.ts, 4, 3)) + +x = "a"; +>x : Symbol(x, Decl(file4.ts, 4, 3)) + +x = 42; +>x : Symbol(x, Decl(file4.ts, 4, 3)) + +export class A { +>A : Symbol(A, Decl(file4.ts, 6, 7)) + + prop; +>prop : Symbol(A.prop, Decl(file4.ts, 8, 16)) + + prop2; +>prop2 : Symbol(A.prop2, Decl(file4.ts, 9, 9)) + + constructor() { + this.prop = "a"; +>this.prop : Symbol(A.prop, Decl(file4.ts, 8, 16)) +>this : Symbol(A, Decl(file4.ts, 6, 7)) +>prop : Symbol(A.prop, Decl(file4.ts, 8, 16)) + + this.prop = 42; +>this.prop : Symbol(A.prop, Decl(file4.ts, 8, 16)) +>this : Symbol(A, Decl(file4.ts, 6, 7)) +>prop : Symbol(A.prop, Decl(file4.ts, 8, 16)) + } + static stat; +>stat : Symbol(A.stat, Decl(file4.ts, 14, 5)) + + static stat2; +>stat2 : Symbol(A.stat2, Decl(file4.ts, 15, 16)) + + static { + this.stat = "a"; +>this.stat : Symbol(A.stat, Decl(file4.ts, 14, 5)) +>this : Symbol(A, Decl(file4.ts, 6, 7)) +>stat : Symbol(A.stat, Decl(file4.ts, 14, 5)) + + this.stat = 42; +>this.stat : Symbol(A.stat, Decl(file4.ts, 14, 5)) +>this : Symbol(A, Decl(file4.ts, 6, 7)) +>stat : Symbol(A.stat, Decl(file4.ts, 14, 5)) + } + + set access(param) {} +>access : Symbol(A.access, Decl(file4.ts, 20, 5), Decl(file4.ts, 22, 24)) +>param : Symbol(param, Decl(file4.ts, 22, 15)) + + get access() { return this.access; } +>access : Symbol(A.access, Decl(file4.ts, 20, 5), Decl(file4.ts, 22, 24)) +>this.access : Symbol(A.access, Decl(file4.ts, 20, 5), Decl(file4.ts, 22, 24)) +>this : Symbol(A, Decl(file4.ts, 6, 7)) +>access : Symbol(A.access, Decl(file4.ts, 20, 5), Decl(file4.ts, 22, 24)) +} + +export function f1() { +>f1 : Symbol(f1, Decl(file4.ts, 24, 1)) + + return f1(); +>f1 : Symbol(f1, Decl(file4.ts, 24, 1)) +} + +const res = {}["none"]; +>res : Symbol(res, Decl(file4.ts, 30, 5)) + +interface B { prop: string } +>B : Symbol(B, Decl(file4.ts, 30, 23)) +>prop : Symbol(B.prop, Decl(file4.ts, 32, 13)) + +declare var b: B; +>b : Symbol(b, Decl(file4.ts, 33, 11)) +>B : Symbol(B, Decl(file4.ts, 30, 23)) + +const c = b["none"]; +>c : Symbol(c, Decl(file4.ts, 35, 5)) +>b : Symbol(b, Decl(file4.ts, 33, 11)) + +const d: B = { prop: "", excess: "yes" }; +>d : Symbol(d, Decl(file4.ts, 37, 5)) +>B : Symbol(B, Decl(file4.ts, 30, 23)) +>prop : Symbol(prop, Decl(file4.ts, 37, 14)) +>excess : Symbol(excess, Decl(file4.ts, 37, 24)) + +function f2(): string { return ""; } +>f2 : Symbol(f2, Decl(file4.ts, 37, 41)) + +const e = new f2(); +>e : Symbol(e, Decl(file4.ts, 40, 5)) +>f2 : Symbol(f2, Decl(file4.ts, 37, 41)) + diff --git a/tests/baselines/reference/noImplicitAnyPragma2.types b/tests/baselines/reference/noImplicitAnyPragma2.types new file mode 100644 index 0000000000000..ed1ee947fc468 --- /dev/null +++ b/tests/baselines/reference/noImplicitAnyPragma2.types @@ -0,0 +1,503 @@ +=== tests/cases/conformance/pragma/noImplicitAny/file1.ts === +// @ts-noImplicitAny +import * as ns from "missing"; +>ns : any + +const a = p => p + 1; +>a : (p: any) => any +>p => p + 1 : (p: any) => any +>p : any +>p + 1 : any +>p : any +>1 : 1 + +let x; +>x : any + +x = "a"; +>x = "a" : "a" +>x : any +>"a" : "a" + +x = 42; +>x = 42 : 42 +>x : any +>42 : 42 + +export class A { +>A : A + + prop; +>prop : number + + prop2; +>prop2 : any + + constructor() { + this.prop = "a"; +>this.prop = "a" : "a" +>this.prop : number +>this : this +>prop : number +>"a" : "a" + + this.prop = 42; +>this.prop = 42 : 42 +>this.prop : number +>this : this +>prop : number +>42 : 42 + } + static stat; +>stat : number + + static stat2; +>stat2 : any + + static { + this.stat = "a"; +>this.stat = "a" : "a" +>this.stat : number +>this : typeof A +>stat : number +>"a" : "a" + + this.stat = 42; +>this.stat = 42 : 42 +>this.stat : number +>this : typeof A +>stat : number +>42 : 42 + } + + set access(param) {} +>access : any +>param : any + + get access() { return this.access; } +>access : any +>this.access : any +>this : this +>access : any +} + +export function f1() { +>f1 : () => any + + return f1(); +>f1() : any +>f1 : () => any +} + +const res = {}["none"]; +>res : undefined +>{}["none"] : undefined +>{} : {} +>"none" : "none" + +interface B { prop: string } +>prop : string + +declare var b: B; +>b : B + +const c = b["none"]; +>c : any +>b["none"] : any +>b : B +>"none" : "none" + +const d: B = { prop: "", excess: "yes" }; +>d : B +>{ prop: "", excess: "yes" } : { prop: string; excess: string; } +>prop : string +>"" : "" +>excess : string +>"yes" : "yes" + +function f2(): string { return ""; } +>f2 : () => string +>"" : "" + +const e = new f2(); +>e : any +>new f2() : any +>f2 : () => string + +=== tests/cases/conformance/pragma/noImplicitAny/file2.ts === +// @ts-noImplicitAny true +import * as ns from "missing"; +>ns : any + +const a = p => p + 1; +>a : (p: any) => any +>p => p + 1 : (p: any) => any +>p : any +>p + 1 : any +>p : any +>1 : 1 + +let x; +>x : any + +x = "a"; +>x = "a" : "a" +>x : any +>"a" : "a" + +x = 42; +>x = 42 : 42 +>x : any +>42 : 42 + +export class A { +>A : A + + prop; +>prop : number + + prop2; +>prop2 : any + + constructor() { + this.prop = "a"; +>this.prop = "a" : "a" +>this.prop : number +>this : this +>prop : number +>"a" : "a" + + this.prop = 42; +>this.prop = 42 : 42 +>this.prop : number +>this : this +>prop : number +>42 : 42 + } + static stat; +>stat : number + + static stat2; +>stat2 : any + + static { + this.stat = "a"; +>this.stat = "a" : "a" +>this.stat : number +>this : typeof A +>stat : number +>"a" : "a" + + this.stat = 42; +>this.stat = 42 : 42 +>this.stat : number +>this : typeof A +>stat : number +>42 : 42 + } + + set access(param) {} +>access : any +>param : any + + get access() { return this.access; } +>access : any +>this.access : any +>this : this +>access : any +} + +export function f1() { +>f1 : () => any + + return f1(); +>f1() : any +>f1 : () => any +} + +const res = {}["none"]; +>res : undefined +>{}["none"] : undefined +>{} : {} +>"none" : "none" + +interface B { prop: string } +>prop : string + +declare var b: B; +>b : B + +const c = b["none"]; +>c : any +>b["none"] : any +>b : B +>"none" : "none" + +const d: B = { prop: "", excess: "yes" }; +>d : B +>{ prop: "", excess: "yes" } : { prop: string; excess: string; } +>prop : string +>"" : "" +>excess : string +>"yes" : "yes" + +function f2(): string { return ""; } +>f2 : () => string +>"" : "" + +const e = new f2(); +>e : any +>new f2() : any +>f2 : () => string + +=== tests/cases/conformance/pragma/noImplicitAny/file3.ts === +// @ts-noImplicitAny false +import * as ns from "missing"; +>ns : any + +const a = p => p + 1; +>a : (p: any) => any +>p => p + 1 : (p: any) => any +>p : any +>p + 1 : any +>p : any +>1 : 1 + +let x; +>x : any + +x = "a"; +>x = "a" : "a" +>x : any +>"a" : "a" + +x = 42; +>x = 42 : 42 +>x : any +>42 : 42 + +export class A { +>A : A + + prop; +>prop : any + + prop2; +>prop2 : any + + constructor() { + this.prop = "a"; +>this.prop = "a" : "a" +>this.prop : any +>this : this +>prop : any +>"a" : "a" + + this.prop = 42; +>this.prop = 42 : 42 +>this.prop : any +>this : this +>prop : any +>42 : 42 + } + static stat; +>stat : any + + static stat2; +>stat2 : any + + static { + this.stat = "a"; +>this.stat = "a" : "a" +>this.stat : any +>this : typeof A +>stat : any +>"a" : "a" + + this.stat = 42; +>this.stat = 42 : 42 +>this.stat : any +>this : typeof A +>stat : any +>42 : 42 + } + + set access(param) {} +>access : any +>param : any + + get access() { return this.access; } +>access : any +>this.access : any +>this : this +>access : any +} + +export function f1() { +>f1 : () => any + + return f1(); +>f1() : any +>f1 : () => any +} + +const res = {}["none"]; +>res : any +>{}["none"] : any +>{} : {} +>"none" : "none" + +interface B { prop: string } +>prop : string + +declare var b: B; +>b : B + +const c = b["none"]; +>c : any +>b["none"] : any +>b : B +>"none" : "none" + +const d: B = { prop: "", excess: "yes" }; +>d : B +>{ prop: "", excess: "yes" } : { prop: string; excess: string; } +>prop : string +>"" : "" +>excess : string +>"yes" : "yes" + +function f2(): string { return ""; } +>f2 : () => string +>"" : "" + +const e = new f2(); +>e : any +>new f2() : any +>f2 : () => string + +=== tests/cases/conformance/pragma/noImplicitAny/file4.ts === +import * as ns from "missing"; +>ns : any + +const a = p => p + 1; +>a : (p: any) => any +>p => p + 1 : (p: any) => any +>p : any +>p + 1 : any +>p : any +>1 : 1 + +let x; +>x : any + +x = "a"; +>x = "a" : "a" +>x : any +>"a" : "a" + +x = 42; +>x = 42 : 42 +>x : any +>42 : 42 + +export class A { +>A : A + + prop; +>prop : number + + prop2; +>prop2 : any + + constructor() { + this.prop = "a"; +>this.prop = "a" : "a" +>this.prop : number +>this : this +>prop : number +>"a" : "a" + + this.prop = 42; +>this.prop = 42 : 42 +>this.prop : number +>this : this +>prop : number +>42 : 42 + } + static stat; +>stat : number + + static stat2; +>stat2 : any + + static { + this.stat = "a"; +>this.stat = "a" : "a" +>this.stat : number +>this : typeof A +>stat : number +>"a" : "a" + + this.stat = 42; +>this.stat = 42 : 42 +>this.stat : number +>this : typeof A +>stat : number +>42 : 42 + } + + set access(param) {} +>access : any +>param : any + + get access() { return this.access; } +>access : any +>this.access : any +>this : this +>access : any +} + +export function f1() { +>f1 : () => any + + return f1(); +>f1() : any +>f1 : () => any +} + +const res = {}["none"]; +>res : undefined +>{}["none"] : undefined +>{} : {} +>"none" : "none" + +interface B { prop: string } +>prop : string + +declare var b: B; +>b : B + +const c = b["none"]; +>c : any +>b["none"] : any +>b : B +>"none" : "none" + +const d: B = { prop: "", excess: "yes" }; +>d : B +>{ prop: "", excess: "yes" } : { prop: string; excess: string; } +>prop : string +>"" : "" +>excess : string +>"yes" : "yes" + +function f2(): string { return ""; } +>f2 : () => string +>"" : "" + +const e = new f2(); +>e : any +>new f2() : any +>f2 : () => string + diff --git a/tests/baselines/reference/noImplicitOverridePragma1.errors.txt b/tests/baselines/reference/noImplicitOverridePragma1.errors.txt new file mode 100644 index 0000000000000..3f3ddf6032bad --- /dev/null +++ b/tests/baselines/reference/noImplicitOverridePragma1.errors.txt @@ -0,0 +1,54 @@ +tests/cases/conformance/pragma/noImplicitOverride/file1.ts(6,5): error TS4114: This member must have an 'override' modifier because it overrides a member in the base class 'A'. +tests/cases/conformance/pragma/noImplicitOverride/file2.ts(6,5): error TS4114: This member must have an 'override' modifier because it overrides a member in the base class 'A'. + + +==== tests/cases/conformance/pragma/noImplicitOverride/file1.ts (1 errors) ==== + // @ts-noImplicitOverride + export class A { + method() {} + } + export class B extends A { + method() {} + ~~~~~~ +!!! error TS4114: This member must have an 'override' modifier because it overrides a member in the base class 'A'. + } + export class C extends A { + override method() {} + } + +==== tests/cases/conformance/pragma/noImplicitOverride/file2.ts (1 errors) ==== + // @ts-noImplicitOverride true + export class A { + method() {} + } + export class B extends A { + method() {} + ~~~~~~ +!!! error TS4114: This member must have an 'override' modifier because it overrides a member in the base class 'A'. + } + export class C extends A { + override method() {} + } + +==== tests/cases/conformance/pragma/noImplicitOverride/file3.ts (0 errors) ==== + // @ts-noImplicitOverride false + export class A { + method() {} + } + export class B extends A { + method() {} + } + export class C extends A { + override method() {} + } + +==== tests/cases/conformance/pragma/noImplicitOverride/file4.ts (0 errors) ==== + export class A { + method() {} + } + export class B extends A { + method() {} + } + export class C extends A { + override method() {} + } \ No newline at end of file diff --git a/tests/baselines/reference/noImplicitOverridePragma1.js b/tests/baselines/reference/noImplicitOverridePragma1.js new file mode 100644 index 0000000000000..6b93121d3d667 --- /dev/null +++ b/tests/baselines/reference/noImplicitOverridePragma1.js @@ -0,0 +1,228 @@ +//// [tests/cases/conformance/pragma/noImplicitOverride/noImplicitOverridePragma1.ts] //// + +//// [file1.ts] +// @ts-noImplicitOverride +export class A { + method() {} +} +export class B extends A { + method() {} +} +export class C extends A { + override method() {} +} + +//// [file2.ts] +// @ts-noImplicitOverride true +export class A { + method() {} +} +export class B extends A { + method() {} +} +export class C extends A { + override method() {} +} + +//// [file3.ts] +// @ts-noImplicitOverride false +export class A { + method() {} +} +export class B extends A { + method() {} +} +export class C extends A { + override method() {} +} + +//// [file4.ts] +export class A { + method() {} +} +export class B extends A { + method() {} +} +export class C extends A { + override method() {} +} + +//// [file1.js] +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + if (typeof b !== "function" && b !== null) + throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +exports.__esModule = true; +exports.C = exports.B = exports.A = void 0; +// @ts-noImplicitOverride +var A = /** @class */ (function () { + function A() { + } + A.prototype.method = function () { }; + return A; +}()); +exports.A = A; +var B = /** @class */ (function (_super) { + __extends(B, _super); + function B() { + return _super !== null && _super.apply(this, arguments) || this; + } + B.prototype.method = function () { }; + return B; +}(A)); +exports.B = B; +var C = /** @class */ (function (_super) { + __extends(C, _super); + function C() { + return _super !== null && _super.apply(this, arguments) || this; + } + C.prototype.method = function () { }; + return C; +}(A)); +exports.C = C; +//// [file2.js] +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + if (typeof b !== "function" && b !== null) + throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +exports.__esModule = true; +exports.C = exports.B = exports.A = void 0; +// @ts-noImplicitOverride true +var A = /** @class */ (function () { + function A() { + } + A.prototype.method = function () { }; + return A; +}()); +exports.A = A; +var B = /** @class */ (function (_super) { + __extends(B, _super); + function B() { + return _super !== null && _super.apply(this, arguments) || this; + } + B.prototype.method = function () { }; + return B; +}(A)); +exports.B = B; +var C = /** @class */ (function (_super) { + __extends(C, _super); + function C() { + return _super !== null && _super.apply(this, arguments) || this; + } + C.prototype.method = function () { }; + return C; +}(A)); +exports.C = C; +//// [file3.js] +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + if (typeof b !== "function" && b !== null) + throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +exports.__esModule = true; +exports.C = exports.B = exports.A = void 0; +// @ts-noImplicitOverride false +var A = /** @class */ (function () { + function A() { + } + A.prototype.method = function () { }; + return A; +}()); +exports.A = A; +var B = /** @class */ (function (_super) { + __extends(B, _super); + function B() { + return _super !== null && _super.apply(this, arguments) || this; + } + B.prototype.method = function () { }; + return B; +}(A)); +exports.B = B; +var C = /** @class */ (function (_super) { + __extends(C, _super); + function C() { + return _super !== null && _super.apply(this, arguments) || this; + } + C.prototype.method = function () { }; + return C; +}(A)); +exports.C = C; +//// [file4.js] +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + if (typeof b !== "function" && b !== null) + throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +exports.__esModule = true; +exports.C = exports.B = exports.A = void 0; +var A = /** @class */ (function () { + function A() { + } + A.prototype.method = function () { }; + return A; +}()); +exports.A = A; +var B = /** @class */ (function (_super) { + __extends(B, _super); + function B() { + return _super !== null && _super.apply(this, arguments) || this; + } + B.prototype.method = function () { }; + return B; +}(A)); +exports.B = B; +var C = /** @class */ (function (_super) { + __extends(C, _super); + function C() { + return _super !== null && _super.apply(this, arguments) || this; + } + C.prototype.method = function () { }; + return C; +}(A)); +exports.C = C; diff --git a/tests/baselines/reference/noImplicitOverridePragma1.symbols b/tests/baselines/reference/noImplicitOverridePragma1.symbols new file mode 100644 index 0000000000000..521dd870819fe --- /dev/null +++ b/tests/baselines/reference/noImplicitOverridePragma1.symbols @@ -0,0 +1,90 @@ +=== tests/cases/conformance/pragma/noImplicitOverride/file1.ts === +// @ts-noImplicitOverride +export class A { +>A : Symbol(A, Decl(file1.ts, 0, 0)) + + method() {} +>method : Symbol(A.method, Decl(file1.ts, 1, 16)) +} +export class B extends A { +>B : Symbol(B, Decl(file1.ts, 3, 1)) +>A : Symbol(A, Decl(file1.ts, 0, 0)) + + method() {} +>method : Symbol(B.method, Decl(file1.ts, 4, 26)) +} +export class C extends A { +>C : Symbol(C, Decl(file1.ts, 6, 1)) +>A : Symbol(A, Decl(file1.ts, 0, 0)) + + override method() {} +>method : Symbol(C.method, Decl(file1.ts, 7, 26)) +} + +=== tests/cases/conformance/pragma/noImplicitOverride/file2.ts === +// @ts-noImplicitOverride true +export class A { +>A : Symbol(A, Decl(file2.ts, 0, 0)) + + method() {} +>method : Symbol(A.method, Decl(file2.ts, 1, 16)) +} +export class B extends A { +>B : Symbol(B, Decl(file2.ts, 3, 1)) +>A : Symbol(A, Decl(file2.ts, 0, 0)) + + method() {} +>method : Symbol(B.method, Decl(file2.ts, 4, 26)) +} +export class C extends A { +>C : Symbol(C, Decl(file2.ts, 6, 1)) +>A : Symbol(A, Decl(file2.ts, 0, 0)) + + override method() {} +>method : Symbol(C.method, Decl(file2.ts, 7, 26)) +} + +=== tests/cases/conformance/pragma/noImplicitOverride/file3.ts === +// @ts-noImplicitOverride false +export class A { +>A : Symbol(A, Decl(file3.ts, 0, 0)) + + method() {} +>method : Symbol(A.method, Decl(file3.ts, 1, 16)) +} +export class B extends A { +>B : Symbol(B, Decl(file3.ts, 3, 1)) +>A : Symbol(A, Decl(file3.ts, 0, 0)) + + method() {} +>method : Symbol(B.method, Decl(file3.ts, 4, 26)) +} +export class C extends A { +>C : Symbol(C, Decl(file3.ts, 6, 1)) +>A : Symbol(A, Decl(file3.ts, 0, 0)) + + override method() {} +>method : Symbol(C.method, Decl(file3.ts, 7, 26)) +} + +=== tests/cases/conformance/pragma/noImplicitOverride/file4.ts === +export class A { +>A : Symbol(A, Decl(file4.ts, 0, 0)) + + method() {} +>method : Symbol(A.method, Decl(file4.ts, 0, 16)) +} +export class B extends A { +>B : Symbol(B, Decl(file4.ts, 2, 1)) +>A : Symbol(A, Decl(file4.ts, 0, 0)) + + method() {} +>method : Symbol(B.method, Decl(file4.ts, 3, 26)) +} +export class C extends A { +>C : Symbol(C, Decl(file4.ts, 5, 1)) +>A : Symbol(A, Decl(file4.ts, 0, 0)) + + override method() {} +>method : Symbol(C.method, Decl(file4.ts, 6, 26)) +} diff --git a/tests/baselines/reference/noImplicitOverridePragma1.types b/tests/baselines/reference/noImplicitOverridePragma1.types new file mode 100644 index 0000000000000..2cfd099e90f77 --- /dev/null +++ b/tests/baselines/reference/noImplicitOverridePragma1.types @@ -0,0 +1,90 @@ +=== tests/cases/conformance/pragma/noImplicitOverride/file1.ts === +// @ts-noImplicitOverride +export class A { +>A : A + + method() {} +>method : () => void +} +export class B extends A { +>B : B +>A : A + + method() {} +>method : () => void +} +export class C extends A { +>C : C +>A : A + + override method() {} +>method : () => void +} + +=== tests/cases/conformance/pragma/noImplicitOverride/file2.ts === +// @ts-noImplicitOverride true +export class A { +>A : A + + method() {} +>method : () => void +} +export class B extends A { +>B : B +>A : A + + method() {} +>method : () => void +} +export class C extends A { +>C : C +>A : A + + override method() {} +>method : () => void +} + +=== tests/cases/conformance/pragma/noImplicitOverride/file3.ts === +// @ts-noImplicitOverride false +export class A { +>A : A + + method() {} +>method : () => void +} +export class B extends A { +>B : B +>A : A + + method() {} +>method : () => void +} +export class C extends A { +>C : C +>A : A + + override method() {} +>method : () => void +} + +=== tests/cases/conformance/pragma/noImplicitOverride/file4.ts === +export class A { +>A : A + + method() {} +>method : () => void +} +export class B extends A { +>B : B +>A : A + + method() {} +>method : () => void +} +export class C extends A { +>C : C +>A : A + + override method() {} +>method : () => void +} diff --git a/tests/baselines/reference/noImplicitOverridePragma2.errors.txt b/tests/baselines/reference/noImplicitOverridePragma2.errors.txt new file mode 100644 index 0000000000000..4195a94d8ca8f --- /dev/null +++ b/tests/baselines/reference/noImplicitOverridePragma2.errors.txt @@ -0,0 +1,57 @@ +tests/cases/conformance/pragma/noImplicitOverride/file1.ts(6,5): error TS4114: This member must have an 'override' modifier because it overrides a member in the base class 'A'. +tests/cases/conformance/pragma/noImplicitOverride/file2.ts(6,5): error TS4114: This member must have an 'override' modifier because it overrides a member in the base class 'A'. +tests/cases/conformance/pragma/noImplicitOverride/file4.ts(5,5): error TS4114: This member must have an 'override' modifier because it overrides a member in the base class 'A'. + + +==== tests/cases/conformance/pragma/noImplicitOverride/file1.ts (1 errors) ==== + // @ts-noImplicitOverride + export class A { + method() {} + } + export class B extends A { + method() {} + ~~~~~~ +!!! error TS4114: This member must have an 'override' modifier because it overrides a member in the base class 'A'. + } + export class C extends A { + override method() {} + } + +==== tests/cases/conformance/pragma/noImplicitOverride/file2.ts (1 errors) ==== + // @ts-noImplicitOverride true + export class A { + method() {} + } + export class B extends A { + method() {} + ~~~~~~ +!!! error TS4114: This member must have an 'override' modifier because it overrides a member in the base class 'A'. + } + export class C extends A { + override method() {} + } + +==== tests/cases/conformance/pragma/noImplicitOverride/file3.ts (0 errors) ==== + // @ts-noImplicitOverride false + export class A { + method() {} + } + export class B extends A { + method() {} + } + export class C extends A { + override method() {} + } + +==== tests/cases/conformance/pragma/noImplicitOverride/file4.ts (1 errors) ==== + export class A { + method() {} + } + export class B extends A { + method() {} + ~~~~~~ +!!! error TS4114: This member must have an 'override' modifier because it overrides a member in the base class 'A'. + } + export class C extends A { + override method() {} + } \ No newline at end of file diff --git a/tests/baselines/reference/noImplicitOverridePragma2.js b/tests/baselines/reference/noImplicitOverridePragma2.js new file mode 100644 index 0000000000000..f39696335a337 --- /dev/null +++ b/tests/baselines/reference/noImplicitOverridePragma2.js @@ -0,0 +1,228 @@ +//// [tests/cases/conformance/pragma/noImplicitOverride/noImplicitOverridePragma2.ts] //// + +//// [file1.ts] +// @ts-noImplicitOverride +export class A { + method() {} +} +export class B extends A { + method() {} +} +export class C extends A { + override method() {} +} + +//// [file2.ts] +// @ts-noImplicitOverride true +export class A { + method() {} +} +export class B extends A { + method() {} +} +export class C extends A { + override method() {} +} + +//// [file3.ts] +// @ts-noImplicitOverride false +export class A { + method() {} +} +export class B extends A { + method() {} +} +export class C extends A { + override method() {} +} + +//// [file4.ts] +export class A { + method() {} +} +export class B extends A { + method() {} +} +export class C extends A { + override method() {} +} + +//// [file1.js] +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + if (typeof b !== "function" && b !== null) + throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +exports.__esModule = true; +exports.C = exports.B = exports.A = void 0; +// @ts-noImplicitOverride +var A = /** @class */ (function () { + function A() { + } + A.prototype.method = function () { }; + return A; +}()); +exports.A = A; +var B = /** @class */ (function (_super) { + __extends(B, _super); + function B() { + return _super !== null && _super.apply(this, arguments) || this; + } + B.prototype.method = function () { }; + return B; +}(A)); +exports.B = B; +var C = /** @class */ (function (_super) { + __extends(C, _super); + function C() { + return _super !== null && _super.apply(this, arguments) || this; + } + C.prototype.method = function () { }; + return C; +}(A)); +exports.C = C; +//// [file2.js] +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + if (typeof b !== "function" && b !== null) + throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +exports.__esModule = true; +exports.C = exports.B = exports.A = void 0; +// @ts-noImplicitOverride true +var A = /** @class */ (function () { + function A() { + } + A.prototype.method = function () { }; + return A; +}()); +exports.A = A; +var B = /** @class */ (function (_super) { + __extends(B, _super); + function B() { + return _super !== null && _super.apply(this, arguments) || this; + } + B.prototype.method = function () { }; + return B; +}(A)); +exports.B = B; +var C = /** @class */ (function (_super) { + __extends(C, _super); + function C() { + return _super !== null && _super.apply(this, arguments) || this; + } + C.prototype.method = function () { }; + return C; +}(A)); +exports.C = C; +//// [file3.js] +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + if (typeof b !== "function" && b !== null) + throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +exports.__esModule = true; +exports.C = exports.B = exports.A = void 0; +// @ts-noImplicitOverride false +var A = /** @class */ (function () { + function A() { + } + A.prototype.method = function () { }; + return A; +}()); +exports.A = A; +var B = /** @class */ (function (_super) { + __extends(B, _super); + function B() { + return _super !== null && _super.apply(this, arguments) || this; + } + B.prototype.method = function () { }; + return B; +}(A)); +exports.B = B; +var C = /** @class */ (function (_super) { + __extends(C, _super); + function C() { + return _super !== null && _super.apply(this, arguments) || this; + } + C.prototype.method = function () { }; + return C; +}(A)); +exports.C = C; +//// [file4.js] +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + if (typeof b !== "function" && b !== null) + throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +exports.__esModule = true; +exports.C = exports.B = exports.A = void 0; +var A = /** @class */ (function () { + function A() { + } + A.prototype.method = function () { }; + return A; +}()); +exports.A = A; +var B = /** @class */ (function (_super) { + __extends(B, _super); + function B() { + return _super !== null && _super.apply(this, arguments) || this; + } + B.prototype.method = function () { }; + return B; +}(A)); +exports.B = B; +var C = /** @class */ (function (_super) { + __extends(C, _super); + function C() { + return _super !== null && _super.apply(this, arguments) || this; + } + C.prototype.method = function () { }; + return C; +}(A)); +exports.C = C; diff --git a/tests/baselines/reference/noImplicitOverridePragma2.symbols b/tests/baselines/reference/noImplicitOverridePragma2.symbols new file mode 100644 index 0000000000000..521dd870819fe --- /dev/null +++ b/tests/baselines/reference/noImplicitOverridePragma2.symbols @@ -0,0 +1,90 @@ +=== tests/cases/conformance/pragma/noImplicitOverride/file1.ts === +// @ts-noImplicitOverride +export class A { +>A : Symbol(A, Decl(file1.ts, 0, 0)) + + method() {} +>method : Symbol(A.method, Decl(file1.ts, 1, 16)) +} +export class B extends A { +>B : Symbol(B, Decl(file1.ts, 3, 1)) +>A : Symbol(A, Decl(file1.ts, 0, 0)) + + method() {} +>method : Symbol(B.method, Decl(file1.ts, 4, 26)) +} +export class C extends A { +>C : Symbol(C, Decl(file1.ts, 6, 1)) +>A : Symbol(A, Decl(file1.ts, 0, 0)) + + override method() {} +>method : Symbol(C.method, Decl(file1.ts, 7, 26)) +} + +=== tests/cases/conformance/pragma/noImplicitOverride/file2.ts === +// @ts-noImplicitOverride true +export class A { +>A : Symbol(A, Decl(file2.ts, 0, 0)) + + method() {} +>method : Symbol(A.method, Decl(file2.ts, 1, 16)) +} +export class B extends A { +>B : Symbol(B, Decl(file2.ts, 3, 1)) +>A : Symbol(A, Decl(file2.ts, 0, 0)) + + method() {} +>method : Symbol(B.method, Decl(file2.ts, 4, 26)) +} +export class C extends A { +>C : Symbol(C, Decl(file2.ts, 6, 1)) +>A : Symbol(A, Decl(file2.ts, 0, 0)) + + override method() {} +>method : Symbol(C.method, Decl(file2.ts, 7, 26)) +} + +=== tests/cases/conformance/pragma/noImplicitOverride/file3.ts === +// @ts-noImplicitOverride false +export class A { +>A : Symbol(A, Decl(file3.ts, 0, 0)) + + method() {} +>method : Symbol(A.method, Decl(file3.ts, 1, 16)) +} +export class B extends A { +>B : Symbol(B, Decl(file3.ts, 3, 1)) +>A : Symbol(A, Decl(file3.ts, 0, 0)) + + method() {} +>method : Symbol(B.method, Decl(file3.ts, 4, 26)) +} +export class C extends A { +>C : Symbol(C, Decl(file3.ts, 6, 1)) +>A : Symbol(A, Decl(file3.ts, 0, 0)) + + override method() {} +>method : Symbol(C.method, Decl(file3.ts, 7, 26)) +} + +=== tests/cases/conformance/pragma/noImplicitOverride/file4.ts === +export class A { +>A : Symbol(A, Decl(file4.ts, 0, 0)) + + method() {} +>method : Symbol(A.method, Decl(file4.ts, 0, 16)) +} +export class B extends A { +>B : Symbol(B, Decl(file4.ts, 2, 1)) +>A : Symbol(A, Decl(file4.ts, 0, 0)) + + method() {} +>method : Symbol(B.method, Decl(file4.ts, 3, 26)) +} +export class C extends A { +>C : Symbol(C, Decl(file4.ts, 5, 1)) +>A : Symbol(A, Decl(file4.ts, 0, 0)) + + override method() {} +>method : Symbol(C.method, Decl(file4.ts, 6, 26)) +} diff --git a/tests/baselines/reference/noImplicitOverridePragma2.types b/tests/baselines/reference/noImplicitOverridePragma2.types new file mode 100644 index 0000000000000..2cfd099e90f77 --- /dev/null +++ b/tests/baselines/reference/noImplicitOverridePragma2.types @@ -0,0 +1,90 @@ +=== tests/cases/conformance/pragma/noImplicitOverride/file1.ts === +// @ts-noImplicitOverride +export class A { +>A : A + + method() {} +>method : () => void +} +export class B extends A { +>B : B +>A : A + + method() {} +>method : () => void +} +export class C extends A { +>C : C +>A : A + + override method() {} +>method : () => void +} + +=== tests/cases/conformance/pragma/noImplicitOverride/file2.ts === +// @ts-noImplicitOverride true +export class A { +>A : A + + method() {} +>method : () => void +} +export class B extends A { +>B : B +>A : A + + method() {} +>method : () => void +} +export class C extends A { +>C : C +>A : A + + override method() {} +>method : () => void +} + +=== tests/cases/conformance/pragma/noImplicitOverride/file3.ts === +// @ts-noImplicitOverride false +export class A { +>A : A + + method() {} +>method : () => void +} +export class B extends A { +>B : B +>A : A + + method() {} +>method : () => void +} +export class C extends A { +>C : C +>A : A + + override method() {} +>method : () => void +} + +=== tests/cases/conformance/pragma/noImplicitOverride/file4.ts === +export class A { +>A : A + + method() {} +>method : () => void +} +export class B extends A { +>B : B +>A : A + + method() {} +>method : () => void +} +export class C extends A { +>C : C +>A : A + + override method() {} +>method : () => void +} diff --git a/tests/baselines/reference/noImplicitReturnsPragma1.errors.txt b/tests/baselines/reference/noImplicitReturnsPragma1.errors.txt new file mode 100644 index 0000000000000..e335557804163 --- /dev/null +++ b/tests/baselines/reference/noImplicitReturnsPragma1.errors.txt @@ -0,0 +1,38 @@ +tests/cases/conformance/pragma/noImplicitReturns/file1.ts(2,23): error TS7030: Not all code paths return a value. +tests/cases/conformance/pragma/noImplicitReturns/file2.ts(2,23): error TS7030: Not all code paths return a value. + + +==== tests/cases/conformance/pragma/noImplicitReturns/file1.ts (1 errors) ==== + // @ts-noImplicitReturns + export function f1(): string | undefined { + ~~~~~~~~~~~~~~~~~~ +!!! error TS7030: Not all code paths return a value. + if (!!f1) { + return ""; + } + } + +==== tests/cases/conformance/pragma/noImplicitReturns/file2.ts (1 errors) ==== + // @ts-noImplicitReturns true + export function f1(): string | undefined { + ~~~~~~~~~~~~~~~~~~ +!!! error TS7030: Not all code paths return a value. + if (!!f1) { + return ""; + } + } + +==== tests/cases/conformance/pragma/noImplicitReturns/file3.ts (0 errors) ==== + // @ts-noImplicitReturns false + export function f1(): string | undefined { + if (!!f1) { + return ""; + } + } + +==== tests/cases/conformance/pragma/noImplicitReturns/file4.ts (0 errors) ==== + export function f1(): string | undefined { + if (!!f1) { + return ""; + } + } \ No newline at end of file diff --git a/tests/baselines/reference/noImplicitReturnsPragma1.js b/tests/baselines/reference/noImplicitReturnsPragma1.js new file mode 100644 index 0000000000000..0dd6f51c04e8f --- /dev/null +++ b/tests/baselines/reference/noImplicitReturnsPragma1.js @@ -0,0 +1,76 @@ +//// [tests/cases/conformance/pragma/noImplicitReturns/noImplicitReturnsPragma1.ts] //// + +//// [file1.ts] +// @ts-noImplicitReturns +export function f1(): string | undefined { + if (!!f1) { + return ""; + } +} + +//// [file2.ts] +// @ts-noImplicitReturns true +export function f1(): string | undefined { + if (!!f1) { + return ""; + } +} + +//// [file3.ts] +// @ts-noImplicitReturns false +export function f1(): string | undefined { + if (!!f1) { + return ""; + } +} + +//// [file4.ts] +export function f1(): string | undefined { + if (!!f1) { + return ""; + } +} + +//// [file1.js] +"use strict"; +exports.__esModule = true; +exports.f1 = void 0; +// @ts-noImplicitReturns +function f1() { + if (!!f1) { + return ""; + } +} +exports.f1 = f1; +//// [file2.js] +"use strict"; +exports.__esModule = true; +exports.f1 = void 0; +// @ts-noImplicitReturns true +function f1() { + if (!!f1) { + return ""; + } +} +exports.f1 = f1; +//// [file3.js] +"use strict"; +exports.__esModule = true; +exports.f1 = void 0; +// @ts-noImplicitReturns false +function f1() { + if (!!f1) { + return ""; + } +} +exports.f1 = f1; +//// [file4.js] +"use strict"; +exports.__esModule = true; +exports.f1 = void 0; +function f1() { + if (!!f1) { + return ""; + } +} +exports.f1 = f1; diff --git a/tests/baselines/reference/noImplicitReturnsPragma1.symbols b/tests/baselines/reference/noImplicitReturnsPragma1.symbols new file mode 100644 index 0000000000000..bd49a7cbac9cf --- /dev/null +++ b/tests/baselines/reference/noImplicitReturnsPragma1.symbols @@ -0,0 +1,46 @@ +=== tests/cases/conformance/pragma/noImplicitReturns/file1.ts === +// @ts-noImplicitReturns +export function f1(): string | undefined { +>f1 : Symbol(f1, Decl(file1.ts, 0, 0)) + + if (!!f1) { +>f1 : Symbol(f1, Decl(file1.ts, 0, 0)) + + return ""; + } +} + +=== tests/cases/conformance/pragma/noImplicitReturns/file2.ts === +// @ts-noImplicitReturns true +export function f1(): string | undefined { +>f1 : Symbol(f1, Decl(file2.ts, 0, 0)) + + if (!!f1) { +>f1 : Symbol(f1, Decl(file2.ts, 0, 0)) + + return ""; + } +} + +=== tests/cases/conformance/pragma/noImplicitReturns/file3.ts === +// @ts-noImplicitReturns false +export function f1(): string | undefined { +>f1 : Symbol(f1, Decl(file3.ts, 0, 0)) + + if (!!f1) { +>f1 : Symbol(f1, Decl(file3.ts, 0, 0)) + + return ""; + } +} + +=== tests/cases/conformance/pragma/noImplicitReturns/file4.ts === +export function f1(): string | undefined { +>f1 : Symbol(f1, Decl(file4.ts, 0, 0)) + + if (!!f1) { +>f1 : Symbol(f1, Decl(file4.ts, 0, 0)) + + return ""; + } +} diff --git a/tests/baselines/reference/noImplicitReturnsPragma1.types b/tests/baselines/reference/noImplicitReturnsPragma1.types new file mode 100644 index 0000000000000..f259a25929e38 --- /dev/null +++ b/tests/baselines/reference/noImplicitReturnsPragma1.types @@ -0,0 +1,58 @@ +=== tests/cases/conformance/pragma/noImplicitReturns/file1.ts === +// @ts-noImplicitReturns +export function f1(): string | undefined { +>f1 : () => string | undefined + + if (!!f1) { +>!!f1 : boolean +>!f1 : boolean +>f1 : () => string + + return ""; +>"" : "" + } +} + +=== tests/cases/conformance/pragma/noImplicitReturns/file2.ts === +// @ts-noImplicitReturns true +export function f1(): string | undefined { +>f1 : () => string | undefined + + if (!!f1) { +>!!f1 : boolean +>!f1 : boolean +>f1 : () => string + + return ""; +>"" : "" + } +} + +=== tests/cases/conformance/pragma/noImplicitReturns/file3.ts === +// @ts-noImplicitReturns false +export function f1(): string | undefined { +>f1 : () => string | undefined + + if (!!f1) { +>!!f1 : boolean +>!f1 : boolean +>f1 : () => string + + return ""; +>"" : "" + } +} + +=== tests/cases/conformance/pragma/noImplicitReturns/file4.ts === +export function f1(): string | undefined { +>f1 : () => string | undefined + + if (!!f1) { +>!!f1 : boolean +>!f1 : boolean +>f1 : () => string + + return ""; +>"" : "" + } +} diff --git a/tests/baselines/reference/noImplicitReturnsPragma2.errors.txt b/tests/baselines/reference/noImplicitReturnsPragma2.errors.txt new file mode 100644 index 0000000000000..8e193b9b724f6 --- /dev/null +++ b/tests/baselines/reference/noImplicitReturnsPragma2.errors.txt @@ -0,0 +1,41 @@ +tests/cases/conformance/pragma/noImplicitReturns/file1.ts(2,23): error TS7030: Not all code paths return a value. +tests/cases/conformance/pragma/noImplicitReturns/file2.ts(2,23): error TS7030: Not all code paths return a value. +tests/cases/conformance/pragma/noImplicitReturns/file4.ts(1,23): error TS7030: Not all code paths return a value. + + +==== tests/cases/conformance/pragma/noImplicitReturns/file1.ts (1 errors) ==== + // @ts-noImplicitReturns + export function f1(): string | undefined { + ~~~~~~~~~~~~~~~~~~ +!!! error TS7030: Not all code paths return a value. + if (!!f1) { + return ""; + } + } + +==== tests/cases/conformance/pragma/noImplicitReturns/file2.ts (1 errors) ==== + // @ts-noImplicitReturns true + export function f1(): string | undefined { + ~~~~~~~~~~~~~~~~~~ +!!! error TS7030: Not all code paths return a value. + if (!!f1) { + return ""; + } + } + +==== tests/cases/conformance/pragma/noImplicitReturns/file3.ts (0 errors) ==== + // @ts-noImplicitReturns false + export function f1(): string | undefined { + if (!!f1) { + return ""; + } + } + +==== tests/cases/conformance/pragma/noImplicitReturns/file4.ts (1 errors) ==== + export function f1(): string | undefined { + ~~~~~~~~~~~~~~~~~~ +!!! error TS7030: Not all code paths return a value. + if (!!f1) { + return ""; + } + } \ No newline at end of file diff --git a/tests/baselines/reference/noImplicitReturnsPragma2.js b/tests/baselines/reference/noImplicitReturnsPragma2.js new file mode 100644 index 0000000000000..ab2a480694155 --- /dev/null +++ b/tests/baselines/reference/noImplicitReturnsPragma2.js @@ -0,0 +1,76 @@ +//// [tests/cases/conformance/pragma/noImplicitReturns/noImplicitReturnsPragma2.ts] //// + +//// [file1.ts] +// @ts-noImplicitReturns +export function f1(): string | undefined { + if (!!f1) { + return ""; + } +} + +//// [file2.ts] +// @ts-noImplicitReturns true +export function f1(): string | undefined { + if (!!f1) { + return ""; + } +} + +//// [file3.ts] +// @ts-noImplicitReturns false +export function f1(): string | undefined { + if (!!f1) { + return ""; + } +} + +//// [file4.ts] +export function f1(): string | undefined { + if (!!f1) { + return ""; + } +} + +//// [file1.js] +"use strict"; +exports.__esModule = true; +exports.f1 = void 0; +// @ts-noImplicitReturns +function f1() { + if (!!f1) { + return ""; + } +} +exports.f1 = f1; +//// [file2.js] +"use strict"; +exports.__esModule = true; +exports.f1 = void 0; +// @ts-noImplicitReturns true +function f1() { + if (!!f1) { + return ""; + } +} +exports.f1 = f1; +//// [file3.js] +"use strict"; +exports.__esModule = true; +exports.f1 = void 0; +// @ts-noImplicitReturns false +function f1() { + if (!!f1) { + return ""; + } +} +exports.f1 = f1; +//// [file4.js] +"use strict"; +exports.__esModule = true; +exports.f1 = void 0; +function f1() { + if (!!f1) { + return ""; + } +} +exports.f1 = f1; diff --git a/tests/baselines/reference/noImplicitReturnsPragma2.symbols b/tests/baselines/reference/noImplicitReturnsPragma2.symbols new file mode 100644 index 0000000000000..bd49a7cbac9cf --- /dev/null +++ b/tests/baselines/reference/noImplicitReturnsPragma2.symbols @@ -0,0 +1,46 @@ +=== tests/cases/conformance/pragma/noImplicitReturns/file1.ts === +// @ts-noImplicitReturns +export function f1(): string | undefined { +>f1 : Symbol(f1, Decl(file1.ts, 0, 0)) + + if (!!f1) { +>f1 : Symbol(f1, Decl(file1.ts, 0, 0)) + + return ""; + } +} + +=== tests/cases/conformance/pragma/noImplicitReturns/file2.ts === +// @ts-noImplicitReturns true +export function f1(): string | undefined { +>f1 : Symbol(f1, Decl(file2.ts, 0, 0)) + + if (!!f1) { +>f1 : Symbol(f1, Decl(file2.ts, 0, 0)) + + return ""; + } +} + +=== tests/cases/conformance/pragma/noImplicitReturns/file3.ts === +// @ts-noImplicitReturns false +export function f1(): string | undefined { +>f1 : Symbol(f1, Decl(file3.ts, 0, 0)) + + if (!!f1) { +>f1 : Symbol(f1, Decl(file3.ts, 0, 0)) + + return ""; + } +} + +=== tests/cases/conformance/pragma/noImplicitReturns/file4.ts === +export function f1(): string | undefined { +>f1 : Symbol(f1, Decl(file4.ts, 0, 0)) + + if (!!f1) { +>f1 : Symbol(f1, Decl(file4.ts, 0, 0)) + + return ""; + } +} diff --git a/tests/baselines/reference/noImplicitReturnsPragma2.types b/tests/baselines/reference/noImplicitReturnsPragma2.types new file mode 100644 index 0000000000000..f259a25929e38 --- /dev/null +++ b/tests/baselines/reference/noImplicitReturnsPragma2.types @@ -0,0 +1,58 @@ +=== tests/cases/conformance/pragma/noImplicitReturns/file1.ts === +// @ts-noImplicitReturns +export function f1(): string | undefined { +>f1 : () => string | undefined + + if (!!f1) { +>!!f1 : boolean +>!f1 : boolean +>f1 : () => string + + return ""; +>"" : "" + } +} + +=== tests/cases/conformance/pragma/noImplicitReturns/file2.ts === +// @ts-noImplicitReturns true +export function f1(): string | undefined { +>f1 : () => string | undefined + + if (!!f1) { +>!!f1 : boolean +>!f1 : boolean +>f1 : () => string + + return ""; +>"" : "" + } +} + +=== tests/cases/conformance/pragma/noImplicitReturns/file3.ts === +// @ts-noImplicitReturns false +export function f1(): string | undefined { +>f1 : () => string | undefined + + if (!!f1) { +>!!f1 : boolean +>!f1 : boolean +>f1 : () => string + + return ""; +>"" : "" + } +} + +=== tests/cases/conformance/pragma/noImplicitReturns/file4.ts === +export function f1(): string | undefined { +>f1 : () => string | undefined + + if (!!f1) { +>!!f1 : boolean +>!f1 : boolean +>f1 : () => string + + return ""; +>"" : "" + } +} diff --git a/tests/baselines/reference/noImplicitThisPragma1.errors.txt b/tests/baselines/reference/noImplicitThisPragma1.errors.txt new file mode 100644 index 0000000000000..7c29cdf370e8e --- /dev/null +++ b/tests/baselines/reference/noImplicitThisPragma1.errors.txt @@ -0,0 +1,22 @@ +tests/cases/conformance/pragma/noImplicitThis/file1.ts(2,17): error TS7041: The containing arrow function captures the global value of 'this'. +tests/cases/conformance/pragma/noImplicitThis/file2.ts(2,17): error TS7041: The containing arrow function captures the global value of 'this'. + + +==== tests/cases/conformance/pragma/noImplicitThis/file1.ts (1 errors) ==== + // @ts-noImplicitThis + const a = () => this.Math; + ~~~~ +!!! error TS7041: The containing arrow function captures the global value of 'this'. + +==== tests/cases/conformance/pragma/noImplicitThis/file2.ts (1 errors) ==== + // @ts-noImplicitThis true + const b = () => this.Math; + ~~~~ +!!! error TS7041: The containing arrow function captures the global value of 'this'. + +==== tests/cases/conformance/pragma/noImplicitThis/file3.ts (0 errors) ==== + // @ts-noImplicitThis false + const c = () => this.Math; + +==== tests/cases/conformance/pragma/noImplicitThis/file4.ts (0 errors) ==== + const d = () => this.Math; \ No newline at end of file diff --git a/tests/baselines/reference/noImplicitThisPragma1.js b/tests/baselines/reference/noImplicitThisPragma1.js new file mode 100644 index 0000000000000..54fbf0b03032f --- /dev/null +++ b/tests/baselines/reference/noImplicitThisPragma1.js @@ -0,0 +1,32 @@ +//// [tests/cases/conformance/pragma/noImplicitThis/noImplicitThisPragma1.ts] //// + +//// [file1.ts] +// @ts-noImplicitThis +const a = () => this.Math; + +//// [file2.ts] +// @ts-noImplicitThis true +const b = () => this.Math; + +//// [file3.ts] +// @ts-noImplicitThis false +const c = () => this.Math; + +//// [file4.ts] +const d = () => this.Math; + +//// [file1.js] +var _this = this; +// @ts-noImplicitThis +var a = function () { return _this.Math; }; +//// [file2.js] +var _this = this; +// @ts-noImplicitThis true +var b = function () { return _this.Math; }; +//// [file3.js] +var _this = this; +// @ts-noImplicitThis false +var c = function () { return _this.Math; }; +//// [file4.js] +var _this = this; +var d = function () { return _this.Math; }; diff --git a/tests/baselines/reference/noImplicitThisPragma1.symbols b/tests/baselines/reference/noImplicitThisPragma1.symbols new file mode 100644 index 0000000000000..d4aced80ee4a6 --- /dev/null +++ b/tests/baselines/reference/noImplicitThisPragma1.symbols @@ -0,0 +1,31 @@ +=== tests/cases/conformance/pragma/noImplicitThis/file1.ts === +// @ts-noImplicitThis +const a = () => this.Math; +>a : Symbol(a, Decl(file1.ts, 1, 5)) +>this.Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>this : Symbol(globalThis) +>Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) + +=== tests/cases/conformance/pragma/noImplicitThis/file2.ts === +// @ts-noImplicitThis true +const b = () => this.Math; +>b : Symbol(b, Decl(file2.ts, 1, 5)) +>this.Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>this : Symbol(globalThis) +>Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) + +=== tests/cases/conformance/pragma/noImplicitThis/file3.ts === +// @ts-noImplicitThis false +const c = () => this.Math; +>c : Symbol(c, Decl(file3.ts, 1, 5)) +>this.Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>this : Symbol(globalThis) +>Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) + +=== tests/cases/conformance/pragma/noImplicitThis/file4.ts === +const d = () => this.Math; +>d : Symbol(d, Decl(file4.ts, 0, 5)) +>this.Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>this : Symbol(globalThis) +>Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) + diff --git a/tests/baselines/reference/noImplicitThisPragma1.types b/tests/baselines/reference/noImplicitThisPragma1.types new file mode 100644 index 0000000000000..7f64b65c96c72 --- /dev/null +++ b/tests/baselines/reference/noImplicitThisPragma1.types @@ -0,0 +1,35 @@ +=== tests/cases/conformance/pragma/noImplicitThis/file1.ts === +// @ts-noImplicitThis +const a = () => this.Math; +>a : () => Math +>() => this.Math : () => Math +>this.Math : Math +>this : typeof globalThis +>Math : Math + +=== tests/cases/conformance/pragma/noImplicitThis/file2.ts === +// @ts-noImplicitThis true +const b = () => this.Math; +>b : () => Math +>() => this.Math : () => Math +>this.Math : Math +>this : typeof globalThis +>Math : Math + +=== tests/cases/conformance/pragma/noImplicitThis/file3.ts === +// @ts-noImplicitThis false +const c = () => this.Math; +>c : () => Math +>() => this.Math : () => Math +>this.Math : Math +>this : typeof globalThis +>Math : Math + +=== tests/cases/conformance/pragma/noImplicitThis/file4.ts === +const d = () => this.Math; +>d : () => Math +>() => this.Math : () => Math +>this.Math : Math +>this : typeof globalThis +>Math : Math + diff --git a/tests/baselines/reference/noImplicitThisPragma2.errors.txt b/tests/baselines/reference/noImplicitThisPragma2.errors.txt new file mode 100644 index 0000000000000..1e9dccfa26a80 --- /dev/null +++ b/tests/baselines/reference/noImplicitThisPragma2.errors.txt @@ -0,0 +1,25 @@ +tests/cases/conformance/pragma/noImplicitThis/file1.ts(2,17): error TS7041: The containing arrow function captures the global value of 'this'. +tests/cases/conformance/pragma/noImplicitThis/file2.ts(2,17): error TS7041: The containing arrow function captures the global value of 'this'. +tests/cases/conformance/pragma/noImplicitThis/file4.ts(1,17): error TS7041: The containing arrow function captures the global value of 'this'. + + +==== tests/cases/conformance/pragma/noImplicitThis/file1.ts (1 errors) ==== + // @ts-noImplicitThis + const a = () => this.Math; + ~~~~ +!!! error TS7041: The containing arrow function captures the global value of 'this'. + +==== tests/cases/conformance/pragma/noImplicitThis/file2.ts (1 errors) ==== + // @ts-noImplicitThis true + const b = () => this.Math; + ~~~~ +!!! error TS7041: The containing arrow function captures the global value of 'this'. + +==== tests/cases/conformance/pragma/noImplicitThis/file3.ts (0 errors) ==== + // @ts-noImplicitThis false + const c = () => this.Math; + +==== tests/cases/conformance/pragma/noImplicitThis/file4.ts (1 errors) ==== + const d = () => this.Math; + ~~~~ +!!! error TS7041: The containing arrow function captures the global value of 'this'. \ No newline at end of file diff --git a/tests/baselines/reference/noImplicitThisPragma2.js b/tests/baselines/reference/noImplicitThisPragma2.js new file mode 100644 index 0000000000000..4687cad493ea0 --- /dev/null +++ b/tests/baselines/reference/noImplicitThisPragma2.js @@ -0,0 +1,32 @@ +//// [tests/cases/conformance/pragma/noImplicitThis/noImplicitThisPragma2.ts] //// + +//// [file1.ts] +// @ts-noImplicitThis +const a = () => this.Math; + +//// [file2.ts] +// @ts-noImplicitThis true +const b = () => this.Math; + +//// [file3.ts] +// @ts-noImplicitThis false +const c = () => this.Math; + +//// [file4.ts] +const d = () => this.Math; + +//// [file1.js] +var _this = this; +// @ts-noImplicitThis +var a = function () { return _this.Math; }; +//// [file2.js] +var _this = this; +// @ts-noImplicitThis true +var b = function () { return _this.Math; }; +//// [file3.js] +var _this = this; +// @ts-noImplicitThis false +var c = function () { return _this.Math; }; +//// [file4.js] +var _this = this; +var d = function () { return _this.Math; }; diff --git a/tests/baselines/reference/noImplicitThisPragma2.symbols b/tests/baselines/reference/noImplicitThisPragma2.symbols new file mode 100644 index 0000000000000..d4aced80ee4a6 --- /dev/null +++ b/tests/baselines/reference/noImplicitThisPragma2.symbols @@ -0,0 +1,31 @@ +=== tests/cases/conformance/pragma/noImplicitThis/file1.ts === +// @ts-noImplicitThis +const a = () => this.Math; +>a : Symbol(a, Decl(file1.ts, 1, 5)) +>this.Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>this : Symbol(globalThis) +>Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) + +=== tests/cases/conformance/pragma/noImplicitThis/file2.ts === +// @ts-noImplicitThis true +const b = () => this.Math; +>b : Symbol(b, Decl(file2.ts, 1, 5)) +>this.Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>this : Symbol(globalThis) +>Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) + +=== tests/cases/conformance/pragma/noImplicitThis/file3.ts === +// @ts-noImplicitThis false +const c = () => this.Math; +>c : Symbol(c, Decl(file3.ts, 1, 5)) +>this.Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>this : Symbol(globalThis) +>Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) + +=== tests/cases/conformance/pragma/noImplicitThis/file4.ts === +const d = () => this.Math; +>d : Symbol(d, Decl(file4.ts, 0, 5)) +>this.Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>this : Symbol(globalThis) +>Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) + diff --git a/tests/baselines/reference/noImplicitThisPragma2.types b/tests/baselines/reference/noImplicitThisPragma2.types new file mode 100644 index 0000000000000..7f64b65c96c72 --- /dev/null +++ b/tests/baselines/reference/noImplicitThisPragma2.types @@ -0,0 +1,35 @@ +=== tests/cases/conformance/pragma/noImplicitThis/file1.ts === +// @ts-noImplicitThis +const a = () => this.Math; +>a : () => Math +>() => this.Math : () => Math +>this.Math : Math +>this : typeof globalThis +>Math : Math + +=== tests/cases/conformance/pragma/noImplicitThis/file2.ts === +// @ts-noImplicitThis true +const b = () => this.Math; +>b : () => Math +>() => this.Math : () => Math +>this.Math : Math +>this : typeof globalThis +>Math : Math + +=== tests/cases/conformance/pragma/noImplicitThis/file3.ts === +// @ts-noImplicitThis false +const c = () => this.Math; +>c : () => Math +>() => this.Math : () => Math +>this.Math : Math +>this : typeof globalThis +>Math : Math + +=== tests/cases/conformance/pragma/noImplicitThis/file4.ts === +const d = () => this.Math; +>d : () => Math +>() => this.Math : () => Math +>this.Math : Math +>this : typeof globalThis +>Math : Math + diff --git a/tests/baselines/reference/noPropertyAccessFromIndexSignaturePragma1.errors.txt b/tests/baselines/reference/noPropertyAccessFromIndexSignaturePragma1.errors.txt new file mode 100644 index 0000000000000..2fbee89256c00 --- /dev/null +++ b/tests/baselines/reference/noPropertyAccessFromIndexSignaturePragma1.errors.txt @@ -0,0 +1,39 @@ +tests/cases/conformance/pragma/noPropertyAccessFromIndexSignature/file1.ts(6,20): error TS4111: Property 'something' comes from an index signature, so it must be accessed with ['something']. +tests/cases/conformance/pragma/noPropertyAccessFromIndexSignature/file2.ts(6,20): error TS4111: Property 'something' comes from an index signature, so it must be accessed with ['something']. + + +==== tests/cases/conformance/pragma/noPropertyAccessFromIndexSignature/file1.ts (1 errors) ==== + // @ts-noPropertyAccessFromIndexSignature + interface A { + [idx: string]: string; + } + declare var a: A; + export const b = a.something; + ~~~~~~~~~ +!!! error TS4111: Property 'something' comes from an index signature, so it must be accessed with ['something']. + +==== tests/cases/conformance/pragma/noPropertyAccessFromIndexSignature/file2.ts (1 errors) ==== + // @ts-noPropertyAccessFromIndexSignature true + interface A { + [idx: string]: string; + } + declare var a: A; + export const b = a.something; + ~~~~~~~~~ +!!! error TS4111: Property 'something' comes from an index signature, so it must be accessed with ['something']. + +==== tests/cases/conformance/pragma/noPropertyAccessFromIndexSignature/file3.ts (0 errors) ==== + // @ts-noPropertyAccessFromIndexSignature false + interface A { + [idx: string]: string; + } + declare var a: A; + export const b = a.something; + +==== tests/cases/conformance/pragma/noPropertyAccessFromIndexSignature/file4.ts (0 errors) ==== + interface A { + [idx: string]: string; + } + declare var a: A; + export const b = a.something; + \ No newline at end of file diff --git a/tests/baselines/reference/noPropertyAccessFromIndexSignaturePragma1.js b/tests/baselines/reference/noPropertyAccessFromIndexSignaturePragma1.js new file mode 100644 index 0000000000000..8dd5620e13a9d --- /dev/null +++ b/tests/baselines/reference/noPropertyAccessFromIndexSignaturePragma1.js @@ -0,0 +1,54 @@ +//// [tests/cases/conformance/pragma/noPropertyAccessFromIndexSignature/noPropertyAccessFromIndexSignaturePragma1.ts] //// + +//// [file1.ts] +// @ts-noPropertyAccessFromIndexSignature +interface A { + [idx: string]: string; +} +declare var a: A; +export const b = a.something; + +//// [file2.ts] +// @ts-noPropertyAccessFromIndexSignature true +interface A { + [idx: string]: string; +} +declare var a: A; +export const b = a.something; + +//// [file3.ts] +// @ts-noPropertyAccessFromIndexSignature false +interface A { + [idx: string]: string; +} +declare var a: A; +export const b = a.something; + +//// [file4.ts] +interface A { + [idx: string]: string; +} +declare var a: A; +export const b = a.something; + + +//// [file1.js] +"use strict"; +exports.__esModule = true; +exports.b = void 0; +exports.b = a.something; +//// [file2.js] +"use strict"; +exports.__esModule = true; +exports.b = void 0; +exports.b = a.something; +//// [file3.js] +"use strict"; +exports.__esModule = true; +exports.b = void 0; +exports.b = a.something; +//// [file4.js] +"use strict"; +exports.__esModule = true; +exports.b = void 0; +exports.b = a.something; diff --git a/tests/baselines/reference/noPropertyAccessFromIndexSignaturePragma1.symbols b/tests/baselines/reference/noPropertyAccessFromIndexSignaturePragma1.symbols new file mode 100644 index 0000000000000..e49c188c613c9 --- /dev/null +++ b/tests/baselines/reference/noPropertyAccessFromIndexSignaturePragma1.symbols @@ -0,0 +1,63 @@ +=== tests/cases/conformance/pragma/noPropertyAccessFromIndexSignature/file1.ts === +// @ts-noPropertyAccessFromIndexSignature +interface A { +>A : Symbol(A, Decl(file1.ts, 0, 0)) + + [idx: string]: string; +>idx : Symbol(idx, Decl(file1.ts, 2, 5)) +} +declare var a: A; +>a : Symbol(a, Decl(file1.ts, 4, 11)) +>A : Symbol(A, Decl(file1.ts, 0, 0)) + +export const b = a.something; +>b : Symbol(b, Decl(file1.ts, 5, 12)) +>a : Symbol(a, Decl(file1.ts, 4, 11)) + +=== tests/cases/conformance/pragma/noPropertyAccessFromIndexSignature/file2.ts === +// @ts-noPropertyAccessFromIndexSignature true +interface A { +>A : Symbol(A, Decl(file2.ts, 0, 0)) + + [idx: string]: string; +>idx : Symbol(idx, Decl(file2.ts, 2, 5)) +} +declare var a: A; +>a : Symbol(a, Decl(file2.ts, 4, 11)) +>A : Symbol(A, Decl(file2.ts, 0, 0)) + +export const b = a.something; +>b : Symbol(b, Decl(file2.ts, 5, 12)) +>a : Symbol(a, Decl(file2.ts, 4, 11)) + +=== tests/cases/conformance/pragma/noPropertyAccessFromIndexSignature/file3.ts === +// @ts-noPropertyAccessFromIndexSignature false +interface A { +>A : Symbol(A, Decl(file3.ts, 0, 0)) + + [idx: string]: string; +>idx : Symbol(idx, Decl(file3.ts, 2, 5)) +} +declare var a: A; +>a : Symbol(a, Decl(file3.ts, 4, 11)) +>A : Symbol(A, Decl(file3.ts, 0, 0)) + +export const b = a.something; +>b : Symbol(b, Decl(file3.ts, 5, 12)) +>a : Symbol(a, Decl(file3.ts, 4, 11)) + +=== tests/cases/conformance/pragma/noPropertyAccessFromIndexSignature/file4.ts === +interface A { +>A : Symbol(A, Decl(file4.ts, 0, 0)) + + [idx: string]: string; +>idx : Symbol(idx, Decl(file4.ts, 1, 5)) +} +declare var a: A; +>a : Symbol(a, Decl(file4.ts, 3, 11)) +>A : Symbol(A, Decl(file4.ts, 0, 0)) + +export const b = a.something; +>b : Symbol(b, Decl(file4.ts, 4, 12)) +>a : Symbol(a, Decl(file4.ts, 3, 11)) + diff --git a/tests/baselines/reference/noPropertyAccessFromIndexSignaturePragma1.types b/tests/baselines/reference/noPropertyAccessFromIndexSignaturePragma1.types new file mode 100644 index 0000000000000..6478c8bf9dcbc --- /dev/null +++ b/tests/baselines/reference/noPropertyAccessFromIndexSignaturePragma1.types @@ -0,0 +1,59 @@ +=== tests/cases/conformance/pragma/noPropertyAccessFromIndexSignature/file1.ts === +// @ts-noPropertyAccessFromIndexSignature +interface A { + [idx: string]: string; +>idx : string +} +declare var a: A; +>a : A + +export const b = a.something; +>b : string +>a.something : string +>a : A +>something : string + +=== tests/cases/conformance/pragma/noPropertyAccessFromIndexSignature/file2.ts === +// @ts-noPropertyAccessFromIndexSignature true +interface A { + [idx: string]: string; +>idx : string +} +declare var a: A; +>a : A + +export const b = a.something; +>b : string +>a.something : string +>a : A +>something : string + +=== tests/cases/conformance/pragma/noPropertyAccessFromIndexSignature/file3.ts === +// @ts-noPropertyAccessFromIndexSignature false +interface A { + [idx: string]: string; +>idx : string +} +declare var a: A; +>a : A + +export const b = a.something; +>b : string +>a.something : string +>a : A +>something : string + +=== tests/cases/conformance/pragma/noPropertyAccessFromIndexSignature/file4.ts === +interface A { + [idx: string]: string; +>idx : string +} +declare var a: A; +>a : A + +export const b = a.something; +>b : string +>a.something : string +>a : A +>something : string + diff --git a/tests/baselines/reference/noPropertyAccessFromIndexSignaturePragma2.errors.txt b/tests/baselines/reference/noPropertyAccessFromIndexSignaturePragma2.errors.txt new file mode 100644 index 0000000000000..58577983c0ed7 --- /dev/null +++ b/tests/baselines/reference/noPropertyAccessFromIndexSignaturePragma2.errors.txt @@ -0,0 +1,42 @@ +tests/cases/conformance/pragma/noPropertyAccessFromIndexSignature/file1.ts(6,20): error TS4111: Property 'something' comes from an index signature, so it must be accessed with ['something']. +tests/cases/conformance/pragma/noPropertyAccessFromIndexSignature/file2.ts(6,20): error TS4111: Property 'something' comes from an index signature, so it must be accessed with ['something']. +tests/cases/conformance/pragma/noPropertyAccessFromIndexSignature/file4.ts(5,20): error TS4111: Property 'something' comes from an index signature, so it must be accessed with ['something']. + + +==== tests/cases/conformance/pragma/noPropertyAccessFromIndexSignature/file1.ts (1 errors) ==== + // @ts-noPropertyAccessFromIndexSignature + interface A { + [idx: string]: string; + } + declare var a: A; + export const b = a.something; + ~~~~~~~~~ +!!! error TS4111: Property 'something' comes from an index signature, so it must be accessed with ['something']. + +==== tests/cases/conformance/pragma/noPropertyAccessFromIndexSignature/file2.ts (1 errors) ==== + // @ts-noPropertyAccessFromIndexSignature true + interface A { + [idx: string]: string; + } + declare var a: A; + export const b = a.something; + ~~~~~~~~~ +!!! error TS4111: Property 'something' comes from an index signature, so it must be accessed with ['something']. + +==== tests/cases/conformance/pragma/noPropertyAccessFromIndexSignature/file3.ts (0 errors) ==== + // @ts-noPropertyAccessFromIndexSignature false + interface A { + [idx: string]: string; + } + declare var a: A; + export const b = a.something; + +==== tests/cases/conformance/pragma/noPropertyAccessFromIndexSignature/file4.ts (1 errors) ==== + interface A { + [idx: string]: string; + } + declare var a: A; + export const b = a.something; + ~~~~~~~~~ +!!! error TS4111: Property 'something' comes from an index signature, so it must be accessed with ['something']. + \ No newline at end of file diff --git a/tests/baselines/reference/noPropertyAccessFromIndexSignaturePragma2.js b/tests/baselines/reference/noPropertyAccessFromIndexSignaturePragma2.js new file mode 100644 index 0000000000000..563378b2406dd --- /dev/null +++ b/tests/baselines/reference/noPropertyAccessFromIndexSignaturePragma2.js @@ -0,0 +1,54 @@ +//// [tests/cases/conformance/pragma/noPropertyAccessFromIndexSignature/noPropertyAccessFromIndexSignaturePragma2.ts] //// + +//// [file1.ts] +// @ts-noPropertyAccessFromIndexSignature +interface A { + [idx: string]: string; +} +declare var a: A; +export const b = a.something; + +//// [file2.ts] +// @ts-noPropertyAccessFromIndexSignature true +interface A { + [idx: string]: string; +} +declare var a: A; +export const b = a.something; + +//// [file3.ts] +// @ts-noPropertyAccessFromIndexSignature false +interface A { + [idx: string]: string; +} +declare var a: A; +export const b = a.something; + +//// [file4.ts] +interface A { + [idx: string]: string; +} +declare var a: A; +export const b = a.something; + + +//// [file1.js] +"use strict"; +exports.__esModule = true; +exports.b = void 0; +exports.b = a.something; +//// [file2.js] +"use strict"; +exports.__esModule = true; +exports.b = void 0; +exports.b = a.something; +//// [file3.js] +"use strict"; +exports.__esModule = true; +exports.b = void 0; +exports.b = a.something; +//// [file4.js] +"use strict"; +exports.__esModule = true; +exports.b = void 0; +exports.b = a.something; diff --git a/tests/baselines/reference/noPropertyAccessFromIndexSignaturePragma2.symbols b/tests/baselines/reference/noPropertyAccessFromIndexSignaturePragma2.symbols new file mode 100644 index 0000000000000..e49c188c613c9 --- /dev/null +++ b/tests/baselines/reference/noPropertyAccessFromIndexSignaturePragma2.symbols @@ -0,0 +1,63 @@ +=== tests/cases/conformance/pragma/noPropertyAccessFromIndexSignature/file1.ts === +// @ts-noPropertyAccessFromIndexSignature +interface A { +>A : Symbol(A, Decl(file1.ts, 0, 0)) + + [idx: string]: string; +>idx : Symbol(idx, Decl(file1.ts, 2, 5)) +} +declare var a: A; +>a : Symbol(a, Decl(file1.ts, 4, 11)) +>A : Symbol(A, Decl(file1.ts, 0, 0)) + +export const b = a.something; +>b : Symbol(b, Decl(file1.ts, 5, 12)) +>a : Symbol(a, Decl(file1.ts, 4, 11)) + +=== tests/cases/conformance/pragma/noPropertyAccessFromIndexSignature/file2.ts === +// @ts-noPropertyAccessFromIndexSignature true +interface A { +>A : Symbol(A, Decl(file2.ts, 0, 0)) + + [idx: string]: string; +>idx : Symbol(idx, Decl(file2.ts, 2, 5)) +} +declare var a: A; +>a : Symbol(a, Decl(file2.ts, 4, 11)) +>A : Symbol(A, Decl(file2.ts, 0, 0)) + +export const b = a.something; +>b : Symbol(b, Decl(file2.ts, 5, 12)) +>a : Symbol(a, Decl(file2.ts, 4, 11)) + +=== tests/cases/conformance/pragma/noPropertyAccessFromIndexSignature/file3.ts === +// @ts-noPropertyAccessFromIndexSignature false +interface A { +>A : Symbol(A, Decl(file3.ts, 0, 0)) + + [idx: string]: string; +>idx : Symbol(idx, Decl(file3.ts, 2, 5)) +} +declare var a: A; +>a : Symbol(a, Decl(file3.ts, 4, 11)) +>A : Symbol(A, Decl(file3.ts, 0, 0)) + +export const b = a.something; +>b : Symbol(b, Decl(file3.ts, 5, 12)) +>a : Symbol(a, Decl(file3.ts, 4, 11)) + +=== tests/cases/conformance/pragma/noPropertyAccessFromIndexSignature/file4.ts === +interface A { +>A : Symbol(A, Decl(file4.ts, 0, 0)) + + [idx: string]: string; +>idx : Symbol(idx, Decl(file4.ts, 1, 5)) +} +declare var a: A; +>a : Symbol(a, Decl(file4.ts, 3, 11)) +>A : Symbol(A, Decl(file4.ts, 0, 0)) + +export const b = a.something; +>b : Symbol(b, Decl(file4.ts, 4, 12)) +>a : Symbol(a, Decl(file4.ts, 3, 11)) + diff --git a/tests/baselines/reference/noPropertyAccessFromIndexSignaturePragma2.types b/tests/baselines/reference/noPropertyAccessFromIndexSignaturePragma2.types new file mode 100644 index 0000000000000..6478c8bf9dcbc --- /dev/null +++ b/tests/baselines/reference/noPropertyAccessFromIndexSignaturePragma2.types @@ -0,0 +1,59 @@ +=== tests/cases/conformance/pragma/noPropertyAccessFromIndexSignature/file1.ts === +// @ts-noPropertyAccessFromIndexSignature +interface A { + [idx: string]: string; +>idx : string +} +declare var a: A; +>a : A + +export const b = a.something; +>b : string +>a.something : string +>a : A +>something : string + +=== tests/cases/conformance/pragma/noPropertyAccessFromIndexSignature/file2.ts === +// @ts-noPropertyAccessFromIndexSignature true +interface A { + [idx: string]: string; +>idx : string +} +declare var a: A; +>a : A + +export const b = a.something; +>b : string +>a.something : string +>a : A +>something : string + +=== tests/cases/conformance/pragma/noPropertyAccessFromIndexSignature/file3.ts === +// @ts-noPropertyAccessFromIndexSignature false +interface A { + [idx: string]: string; +>idx : string +} +declare var a: A; +>a : A + +export const b = a.something; +>b : string +>a.something : string +>a : A +>something : string + +=== tests/cases/conformance/pragma/noPropertyAccessFromIndexSignature/file4.ts === +interface A { + [idx: string]: string; +>idx : string +} +declare var a: A; +>a : A + +export const b = a.something; +>b : string +>a.something : string +>a : A +>something : string + diff --git a/tests/baselines/reference/noUncheckedIndexedAccessPragma1.errors.txt b/tests/baselines/reference/noUncheckedIndexedAccessPragma1.errors.txt new file mode 100644 index 0000000000000..602f74c0e60ec --- /dev/null +++ b/tests/baselines/reference/noUncheckedIndexedAccessPragma1.errors.txt @@ -0,0 +1,43 @@ +tests/cases/conformance/pragma/noUncheckedIndexedAccess/file1.ts(6,14): error TS2322: Type 'string | undefined' is not assignable to type 'string'. + Type 'undefined' is not assignable to type 'string'. +tests/cases/conformance/pragma/noUncheckedIndexedAccess/file2.ts(6,14): error TS2322: Type 'string | undefined' is not assignable to type 'string'. + Type 'undefined' is not assignable to type 'string'. + + +==== tests/cases/conformance/pragma/noUncheckedIndexedAccess/file1.ts (1 errors) ==== + // @ts-noUncheckedIndexedAccess + interface A { + [index: string]: string; + } + declare var a: A; + export const x: string = a.something; + ~ +!!! error TS2322: Type 'string | undefined' is not assignable to type 'string'. +!!! error TS2322: Type 'undefined' is not assignable to type 'string'. + +==== tests/cases/conformance/pragma/noUncheckedIndexedAccess/file2.ts (1 errors) ==== + // @ts-noUncheckedIndexedAccess true + interface A { + [index: string]: string; + } + declare var a: A; + export const x: string = a.something; + ~ +!!! error TS2322: Type 'string | undefined' is not assignable to type 'string'. +!!! error TS2322: Type 'undefined' is not assignable to type 'string'. + +==== tests/cases/conformance/pragma/noUncheckedIndexedAccess/file3.ts (0 errors) ==== + // @ts-noUncheckedIndexedAccess false + interface A { + [index: string]: string; + } + declare var a: A; + export const x: string = a.something; + +==== tests/cases/conformance/pragma/noUncheckedIndexedAccess/file4.ts (0 errors) ==== + interface A { + [index: string]: string; + } + declare var a: A; + export const x: string = a.something; + \ No newline at end of file diff --git a/tests/baselines/reference/noUncheckedIndexedAccessPragma1.js b/tests/baselines/reference/noUncheckedIndexedAccessPragma1.js new file mode 100644 index 0000000000000..632ad5f1b5db2 --- /dev/null +++ b/tests/baselines/reference/noUncheckedIndexedAccessPragma1.js @@ -0,0 +1,54 @@ +//// [tests/cases/conformance/pragma/noUncheckedIndexedAccess/noUncheckedIndexedAccessPragma1.ts] //// + +//// [file1.ts] +// @ts-noUncheckedIndexedAccess +interface A { + [index: string]: string; +} +declare var a: A; +export const x: string = a.something; + +//// [file2.ts] +// @ts-noUncheckedIndexedAccess true +interface A { + [index: string]: string; +} +declare var a: A; +export const x: string = a.something; + +//// [file3.ts] +// @ts-noUncheckedIndexedAccess false +interface A { + [index: string]: string; +} +declare var a: A; +export const x: string = a.something; + +//// [file4.ts] +interface A { + [index: string]: string; +} +declare var a: A; +export const x: string = a.something; + + +//// [file1.js] +"use strict"; +exports.__esModule = true; +exports.x = void 0; +exports.x = a.something; +//// [file2.js] +"use strict"; +exports.__esModule = true; +exports.x = void 0; +exports.x = a.something; +//// [file3.js] +"use strict"; +exports.__esModule = true; +exports.x = void 0; +exports.x = a.something; +//// [file4.js] +"use strict"; +exports.__esModule = true; +exports.x = void 0; +exports.x = a.something; diff --git a/tests/baselines/reference/noUncheckedIndexedAccessPragma1.symbols b/tests/baselines/reference/noUncheckedIndexedAccessPragma1.symbols new file mode 100644 index 0000000000000..7ea29dd1baa90 --- /dev/null +++ b/tests/baselines/reference/noUncheckedIndexedAccessPragma1.symbols @@ -0,0 +1,63 @@ +=== tests/cases/conformance/pragma/noUncheckedIndexedAccess/file1.ts === +// @ts-noUncheckedIndexedAccess +interface A { +>A : Symbol(A, Decl(file1.ts, 0, 0)) + + [index: string]: string; +>index : Symbol(index, Decl(file1.ts, 2, 5)) +} +declare var a: A; +>a : Symbol(a, Decl(file1.ts, 4, 11)) +>A : Symbol(A, Decl(file1.ts, 0, 0)) + +export const x: string = a.something; +>x : Symbol(x, Decl(file1.ts, 5, 12)) +>a : Symbol(a, Decl(file1.ts, 4, 11)) + +=== tests/cases/conformance/pragma/noUncheckedIndexedAccess/file2.ts === +// @ts-noUncheckedIndexedAccess true +interface A { +>A : Symbol(A, Decl(file2.ts, 0, 0)) + + [index: string]: string; +>index : Symbol(index, Decl(file2.ts, 2, 5)) +} +declare var a: A; +>a : Symbol(a, Decl(file2.ts, 4, 11)) +>A : Symbol(A, Decl(file2.ts, 0, 0)) + +export const x: string = a.something; +>x : Symbol(x, Decl(file2.ts, 5, 12)) +>a : Symbol(a, Decl(file2.ts, 4, 11)) + +=== tests/cases/conformance/pragma/noUncheckedIndexedAccess/file3.ts === +// @ts-noUncheckedIndexedAccess false +interface A { +>A : Symbol(A, Decl(file3.ts, 0, 0)) + + [index: string]: string; +>index : Symbol(index, Decl(file3.ts, 2, 5)) +} +declare var a: A; +>a : Symbol(a, Decl(file3.ts, 4, 11)) +>A : Symbol(A, Decl(file3.ts, 0, 0)) + +export const x: string = a.something; +>x : Symbol(x, Decl(file3.ts, 5, 12)) +>a : Symbol(a, Decl(file3.ts, 4, 11)) + +=== tests/cases/conformance/pragma/noUncheckedIndexedAccess/file4.ts === +interface A { +>A : Symbol(A, Decl(file4.ts, 0, 0)) + + [index: string]: string; +>index : Symbol(index, Decl(file4.ts, 1, 5)) +} +declare var a: A; +>a : Symbol(a, Decl(file4.ts, 3, 11)) +>A : Symbol(A, Decl(file4.ts, 0, 0)) + +export const x: string = a.something; +>x : Symbol(x, Decl(file4.ts, 4, 12)) +>a : Symbol(a, Decl(file4.ts, 3, 11)) + diff --git a/tests/baselines/reference/noUncheckedIndexedAccessPragma1.types b/tests/baselines/reference/noUncheckedIndexedAccessPragma1.types new file mode 100644 index 0000000000000..87aa046584e10 --- /dev/null +++ b/tests/baselines/reference/noUncheckedIndexedAccessPragma1.types @@ -0,0 +1,59 @@ +=== tests/cases/conformance/pragma/noUncheckedIndexedAccess/file1.ts === +// @ts-noUncheckedIndexedAccess +interface A { + [index: string]: string; +>index : string +} +declare var a: A; +>a : A + +export const x: string = a.something; +>x : string +>a.something : string | undefined +>a : A +>something : string | undefined + +=== tests/cases/conformance/pragma/noUncheckedIndexedAccess/file2.ts === +// @ts-noUncheckedIndexedAccess true +interface A { + [index: string]: string; +>index : string +} +declare var a: A; +>a : A + +export const x: string = a.something; +>x : string +>a.something : string | undefined +>a : A +>something : string | undefined + +=== tests/cases/conformance/pragma/noUncheckedIndexedAccess/file3.ts === +// @ts-noUncheckedIndexedAccess false +interface A { + [index: string]: string; +>index : string +} +declare var a: A; +>a : A + +export const x: string = a.something; +>x : string +>a.something : string +>a : A +>something : string + +=== tests/cases/conformance/pragma/noUncheckedIndexedAccess/file4.ts === +interface A { + [index: string]: string; +>index : string +} +declare var a: A; +>a : A + +export const x: string = a.something; +>x : string +>a.something : string +>a : A +>something : string + diff --git a/tests/baselines/reference/noUncheckedIndexedAccessPragma2.errors.txt b/tests/baselines/reference/noUncheckedIndexedAccessPragma2.errors.txt new file mode 100644 index 0000000000000..350297731e2e0 --- /dev/null +++ b/tests/baselines/reference/noUncheckedIndexedAccessPragma2.errors.txt @@ -0,0 +1,48 @@ +tests/cases/conformance/pragma/noUncheckedIndexedAccess/file1.ts(6,14): error TS2322: Type 'string | undefined' is not assignable to type 'string'. + Type 'undefined' is not assignable to type 'string'. +tests/cases/conformance/pragma/noUncheckedIndexedAccess/file2.ts(6,14): error TS2322: Type 'string | undefined' is not assignable to type 'string'. + Type 'undefined' is not assignable to type 'string'. +tests/cases/conformance/pragma/noUncheckedIndexedAccess/file4.ts(5,14): error TS2322: Type 'string | undefined' is not assignable to type 'string'. + Type 'undefined' is not assignable to type 'string'. + + +==== tests/cases/conformance/pragma/noUncheckedIndexedAccess/file1.ts (1 errors) ==== + // @ts-noUncheckedIndexedAccess + interface A { + [index: string]: string; + } + declare var a: A; + export const x: string = a.something; + ~ +!!! error TS2322: Type 'string | undefined' is not assignable to type 'string'. +!!! error TS2322: Type 'undefined' is not assignable to type 'string'. + +==== tests/cases/conformance/pragma/noUncheckedIndexedAccess/file2.ts (1 errors) ==== + // @ts-noUncheckedIndexedAccess true + interface A { + [index: string]: string; + } + declare var a: A; + export const x: string = a.something; + ~ +!!! error TS2322: Type 'string | undefined' is not assignable to type 'string'. +!!! error TS2322: Type 'undefined' is not assignable to type 'string'. + +==== tests/cases/conformance/pragma/noUncheckedIndexedAccess/file3.ts (0 errors) ==== + // @ts-noUncheckedIndexedAccess false + interface A { + [index: string]: string; + } + declare var a: A; + export const x: string = a.something; + +==== tests/cases/conformance/pragma/noUncheckedIndexedAccess/file4.ts (1 errors) ==== + interface A { + [index: string]: string; + } + declare var a: A; + export const x: string = a.something; + ~ +!!! error TS2322: Type 'string | undefined' is not assignable to type 'string'. +!!! error TS2322: Type 'undefined' is not assignable to type 'string'. + \ No newline at end of file diff --git a/tests/baselines/reference/noUncheckedIndexedAccessPragma2.js b/tests/baselines/reference/noUncheckedIndexedAccessPragma2.js new file mode 100644 index 0000000000000..221a00418faee --- /dev/null +++ b/tests/baselines/reference/noUncheckedIndexedAccessPragma2.js @@ -0,0 +1,54 @@ +//// [tests/cases/conformance/pragma/noUncheckedIndexedAccess/noUncheckedIndexedAccessPragma2.ts] //// + +//// [file1.ts] +// @ts-noUncheckedIndexedAccess +interface A { + [index: string]: string; +} +declare var a: A; +export const x: string = a.something; + +//// [file2.ts] +// @ts-noUncheckedIndexedAccess true +interface A { + [index: string]: string; +} +declare var a: A; +export const x: string = a.something; + +//// [file3.ts] +// @ts-noUncheckedIndexedAccess false +interface A { + [index: string]: string; +} +declare var a: A; +export const x: string = a.something; + +//// [file4.ts] +interface A { + [index: string]: string; +} +declare var a: A; +export const x: string = a.something; + + +//// [file1.js] +"use strict"; +exports.__esModule = true; +exports.x = void 0; +exports.x = a.something; +//// [file2.js] +"use strict"; +exports.__esModule = true; +exports.x = void 0; +exports.x = a.something; +//// [file3.js] +"use strict"; +exports.__esModule = true; +exports.x = void 0; +exports.x = a.something; +//// [file4.js] +"use strict"; +exports.__esModule = true; +exports.x = void 0; +exports.x = a.something; diff --git a/tests/baselines/reference/noUncheckedIndexedAccessPragma2.symbols b/tests/baselines/reference/noUncheckedIndexedAccessPragma2.symbols new file mode 100644 index 0000000000000..7ea29dd1baa90 --- /dev/null +++ b/tests/baselines/reference/noUncheckedIndexedAccessPragma2.symbols @@ -0,0 +1,63 @@ +=== tests/cases/conformance/pragma/noUncheckedIndexedAccess/file1.ts === +// @ts-noUncheckedIndexedAccess +interface A { +>A : Symbol(A, Decl(file1.ts, 0, 0)) + + [index: string]: string; +>index : Symbol(index, Decl(file1.ts, 2, 5)) +} +declare var a: A; +>a : Symbol(a, Decl(file1.ts, 4, 11)) +>A : Symbol(A, Decl(file1.ts, 0, 0)) + +export const x: string = a.something; +>x : Symbol(x, Decl(file1.ts, 5, 12)) +>a : Symbol(a, Decl(file1.ts, 4, 11)) + +=== tests/cases/conformance/pragma/noUncheckedIndexedAccess/file2.ts === +// @ts-noUncheckedIndexedAccess true +interface A { +>A : Symbol(A, Decl(file2.ts, 0, 0)) + + [index: string]: string; +>index : Symbol(index, Decl(file2.ts, 2, 5)) +} +declare var a: A; +>a : Symbol(a, Decl(file2.ts, 4, 11)) +>A : Symbol(A, Decl(file2.ts, 0, 0)) + +export const x: string = a.something; +>x : Symbol(x, Decl(file2.ts, 5, 12)) +>a : Symbol(a, Decl(file2.ts, 4, 11)) + +=== tests/cases/conformance/pragma/noUncheckedIndexedAccess/file3.ts === +// @ts-noUncheckedIndexedAccess false +interface A { +>A : Symbol(A, Decl(file3.ts, 0, 0)) + + [index: string]: string; +>index : Symbol(index, Decl(file3.ts, 2, 5)) +} +declare var a: A; +>a : Symbol(a, Decl(file3.ts, 4, 11)) +>A : Symbol(A, Decl(file3.ts, 0, 0)) + +export const x: string = a.something; +>x : Symbol(x, Decl(file3.ts, 5, 12)) +>a : Symbol(a, Decl(file3.ts, 4, 11)) + +=== tests/cases/conformance/pragma/noUncheckedIndexedAccess/file4.ts === +interface A { +>A : Symbol(A, Decl(file4.ts, 0, 0)) + + [index: string]: string; +>index : Symbol(index, Decl(file4.ts, 1, 5)) +} +declare var a: A; +>a : Symbol(a, Decl(file4.ts, 3, 11)) +>A : Symbol(A, Decl(file4.ts, 0, 0)) + +export const x: string = a.something; +>x : Symbol(x, Decl(file4.ts, 4, 12)) +>a : Symbol(a, Decl(file4.ts, 3, 11)) + diff --git a/tests/baselines/reference/noUncheckedIndexedAccessPragma2.types b/tests/baselines/reference/noUncheckedIndexedAccessPragma2.types new file mode 100644 index 0000000000000..8d173d748ba19 --- /dev/null +++ b/tests/baselines/reference/noUncheckedIndexedAccessPragma2.types @@ -0,0 +1,59 @@ +=== tests/cases/conformance/pragma/noUncheckedIndexedAccess/file1.ts === +// @ts-noUncheckedIndexedAccess +interface A { + [index: string]: string; +>index : string +} +declare var a: A; +>a : A + +export const x: string = a.something; +>x : string +>a.something : string | undefined +>a : A +>something : string | undefined + +=== tests/cases/conformance/pragma/noUncheckedIndexedAccess/file2.ts === +// @ts-noUncheckedIndexedAccess true +interface A { + [index: string]: string; +>index : string +} +declare var a: A; +>a : A + +export const x: string = a.something; +>x : string +>a.something : string | undefined +>a : A +>something : string | undefined + +=== tests/cases/conformance/pragma/noUncheckedIndexedAccess/file3.ts === +// @ts-noUncheckedIndexedAccess false +interface A { + [index: string]: string; +>index : string +} +declare var a: A; +>a : A + +export const x: string = a.something; +>x : string +>a.something : string +>a : A +>something : string + +=== tests/cases/conformance/pragma/noUncheckedIndexedAccess/file4.ts === +interface A { + [index: string]: string; +>index : string +} +declare var a: A; +>a : A + +export const x: string = a.something; +>x : string +>a.something : string | undefined +>a : A +>something : string | undefined + diff --git a/tests/baselines/reference/noUnusedLocalsPragma1.errors.txt b/tests/baselines/reference/noUnusedLocalsPragma1.errors.txt new file mode 100644 index 0000000000000..b289564b9d1c4 --- /dev/null +++ b/tests/baselines/reference/noUnusedLocalsPragma1.errors.txt @@ -0,0 +1,27 @@ +tests/cases/conformance/pragma/noUnusedLocals/file1.ts(3,5): error TS6133: 'x' is declared but its value is never read. +tests/cases/conformance/pragma/noUnusedLocals/file2.ts(3,5): error TS6133: 'x' is declared but its value is never read. + + +==== tests/cases/conformance/pragma/noUnusedLocals/file1.ts (1 errors) ==== + // @ts-noUnusedLocals + export {}; + let x; + ~ +!!! error TS6133: 'x' is declared but its value is never read. + +==== tests/cases/conformance/pragma/noUnusedLocals/file2.ts (1 errors) ==== + // @ts-noUnusedLocals true + export {}; + let x; + ~ +!!! error TS6133: 'x' is declared but its value is never read. + +==== tests/cases/conformance/pragma/noUnusedLocals/file3.ts (0 errors) ==== + // @ts-noUnusedLocals false + export {}; + let x; + +==== tests/cases/conformance/pragma/noUnusedLocals/file4.ts (0 errors) ==== + export {}; + let x; + \ No newline at end of file diff --git a/tests/baselines/reference/noUnusedLocalsPragma1.js b/tests/baselines/reference/noUnusedLocalsPragma1.js new file mode 100644 index 0000000000000..57fce7105b797 --- /dev/null +++ b/tests/baselines/reference/noUnusedLocalsPragma1.js @@ -0,0 +1,38 @@ +//// [tests/cases/conformance/pragma/noUnusedLocals/noUnusedLocalsPragma1.ts] //// + +//// [file1.ts] +// @ts-noUnusedLocals +export {}; +let x; + +//// [file2.ts] +// @ts-noUnusedLocals true +export {}; +let x; + +//// [file3.ts] +// @ts-noUnusedLocals false +export {}; +let x; + +//// [file4.ts] +export {}; +let x; + + +//// [file1.js] +"use strict"; +exports.__esModule = true; +var x; +//// [file2.js] +"use strict"; +exports.__esModule = true; +var x; +//// [file3.js] +"use strict"; +exports.__esModule = true; +var x; +//// [file4.js] +"use strict"; +exports.__esModule = true; +var x; diff --git a/tests/baselines/reference/noUnusedLocalsPragma1.symbols b/tests/baselines/reference/noUnusedLocalsPragma1.symbols new file mode 100644 index 0000000000000..ad0097db2e32e --- /dev/null +++ b/tests/baselines/reference/noUnusedLocalsPragma1.symbols @@ -0,0 +1,23 @@ +=== tests/cases/conformance/pragma/noUnusedLocals/file1.ts === +// @ts-noUnusedLocals +export {}; +let x; +>x : Symbol(x, Decl(file1.ts, 2, 3)) + +=== tests/cases/conformance/pragma/noUnusedLocals/file2.ts === +// @ts-noUnusedLocals true +export {}; +let x; +>x : Symbol(x, Decl(file2.ts, 2, 3)) + +=== tests/cases/conformance/pragma/noUnusedLocals/file3.ts === +// @ts-noUnusedLocals false +export {}; +let x; +>x : Symbol(x, Decl(file3.ts, 2, 3)) + +=== tests/cases/conformance/pragma/noUnusedLocals/file4.ts === +export {}; +let x; +>x : Symbol(x, Decl(file4.ts, 1, 3)) + diff --git a/tests/baselines/reference/noUnusedLocalsPragma1.types b/tests/baselines/reference/noUnusedLocalsPragma1.types new file mode 100644 index 0000000000000..9936de1f6c8d7 --- /dev/null +++ b/tests/baselines/reference/noUnusedLocalsPragma1.types @@ -0,0 +1,23 @@ +=== tests/cases/conformance/pragma/noUnusedLocals/file1.ts === +// @ts-noUnusedLocals +export {}; +let x; +>x : any + +=== tests/cases/conformance/pragma/noUnusedLocals/file2.ts === +// @ts-noUnusedLocals true +export {}; +let x; +>x : any + +=== tests/cases/conformance/pragma/noUnusedLocals/file3.ts === +// @ts-noUnusedLocals false +export {}; +let x; +>x : any + +=== tests/cases/conformance/pragma/noUnusedLocals/file4.ts === +export {}; +let x; +>x : any + diff --git a/tests/baselines/reference/noUnusedLocalsPragma2.errors.txt b/tests/baselines/reference/noUnusedLocalsPragma2.errors.txt new file mode 100644 index 0000000000000..3ae804241115d --- /dev/null +++ b/tests/baselines/reference/noUnusedLocalsPragma2.errors.txt @@ -0,0 +1,30 @@ +tests/cases/conformance/pragma/noUnusedLocals/file1.ts(3,5): error TS6133: 'x' is declared but its value is never read. +tests/cases/conformance/pragma/noUnusedLocals/file2.ts(3,5): error TS6133: 'x' is declared but its value is never read. +tests/cases/conformance/pragma/noUnusedLocals/file4.ts(2,5): error TS6133: 'x' is declared but its value is never read. + + +==== tests/cases/conformance/pragma/noUnusedLocals/file1.ts (1 errors) ==== + // @ts-noUnusedLocals + export {}; + let x; + ~ +!!! error TS6133: 'x' is declared but its value is never read. + +==== tests/cases/conformance/pragma/noUnusedLocals/file2.ts (1 errors) ==== + // @ts-noUnusedLocals true + export {}; + let x; + ~ +!!! error TS6133: 'x' is declared but its value is never read. + +==== tests/cases/conformance/pragma/noUnusedLocals/file3.ts (0 errors) ==== + // @ts-noUnusedLocals false + export {}; + let x; + +==== tests/cases/conformance/pragma/noUnusedLocals/file4.ts (1 errors) ==== + export {}; + let x; + ~ +!!! error TS6133: 'x' is declared but its value is never read. + \ No newline at end of file diff --git a/tests/baselines/reference/noUnusedLocalsPragma2.js b/tests/baselines/reference/noUnusedLocalsPragma2.js new file mode 100644 index 0000000000000..f49c06932dfe5 --- /dev/null +++ b/tests/baselines/reference/noUnusedLocalsPragma2.js @@ -0,0 +1,38 @@ +//// [tests/cases/conformance/pragma/noUnusedLocals/noUnusedLocalsPragma2.ts] //// + +//// [file1.ts] +// @ts-noUnusedLocals +export {}; +let x; + +//// [file2.ts] +// @ts-noUnusedLocals true +export {}; +let x; + +//// [file3.ts] +// @ts-noUnusedLocals false +export {}; +let x; + +//// [file4.ts] +export {}; +let x; + + +//// [file1.js] +"use strict"; +exports.__esModule = true; +var x; +//// [file2.js] +"use strict"; +exports.__esModule = true; +var x; +//// [file3.js] +"use strict"; +exports.__esModule = true; +var x; +//// [file4.js] +"use strict"; +exports.__esModule = true; +var x; diff --git a/tests/baselines/reference/noUnusedLocalsPragma2.symbols b/tests/baselines/reference/noUnusedLocalsPragma2.symbols new file mode 100644 index 0000000000000..ad0097db2e32e --- /dev/null +++ b/tests/baselines/reference/noUnusedLocalsPragma2.symbols @@ -0,0 +1,23 @@ +=== tests/cases/conformance/pragma/noUnusedLocals/file1.ts === +// @ts-noUnusedLocals +export {}; +let x; +>x : Symbol(x, Decl(file1.ts, 2, 3)) + +=== tests/cases/conformance/pragma/noUnusedLocals/file2.ts === +// @ts-noUnusedLocals true +export {}; +let x; +>x : Symbol(x, Decl(file2.ts, 2, 3)) + +=== tests/cases/conformance/pragma/noUnusedLocals/file3.ts === +// @ts-noUnusedLocals false +export {}; +let x; +>x : Symbol(x, Decl(file3.ts, 2, 3)) + +=== tests/cases/conformance/pragma/noUnusedLocals/file4.ts === +export {}; +let x; +>x : Symbol(x, Decl(file4.ts, 1, 3)) + diff --git a/tests/baselines/reference/noUnusedLocalsPragma2.types b/tests/baselines/reference/noUnusedLocalsPragma2.types new file mode 100644 index 0000000000000..9936de1f6c8d7 --- /dev/null +++ b/tests/baselines/reference/noUnusedLocalsPragma2.types @@ -0,0 +1,23 @@ +=== tests/cases/conformance/pragma/noUnusedLocals/file1.ts === +// @ts-noUnusedLocals +export {}; +let x; +>x : any + +=== tests/cases/conformance/pragma/noUnusedLocals/file2.ts === +// @ts-noUnusedLocals true +export {}; +let x; +>x : any + +=== tests/cases/conformance/pragma/noUnusedLocals/file3.ts === +// @ts-noUnusedLocals false +export {}; +let x; +>x : any + +=== tests/cases/conformance/pragma/noUnusedLocals/file4.ts === +export {}; +let x; +>x : any + diff --git a/tests/baselines/reference/noUnusedParametersPragma1.errors.txt b/tests/baselines/reference/noUnusedParametersPragma1.errors.txt new file mode 100644 index 0000000000000..5adafe16390f2 --- /dev/null +++ b/tests/baselines/reference/noUnusedParametersPragma1.errors.txt @@ -0,0 +1,23 @@ +tests/cases/conformance/pragma/noUnusedParameters/file1.ts(2,20): error TS6133: 'x' is declared but its value is never read. +tests/cases/conformance/pragma/noUnusedParameters/file2.ts(2,20): error TS6133: 'x' is declared but its value is never read. + + +==== tests/cases/conformance/pragma/noUnusedParameters/file1.ts (1 errors) ==== + // @ts-noUnusedParameters + export function f1(x: number) {} + ~ +!!! error TS6133: 'x' is declared but its value is never read. + +==== tests/cases/conformance/pragma/noUnusedParameters/file2.ts (1 errors) ==== + // @ts-noUnusedParameters true + export function f1(x: number) {} + ~ +!!! error TS6133: 'x' is declared but its value is never read. + +==== tests/cases/conformance/pragma/noUnusedParameters/file3.ts (0 errors) ==== + // @ts-noUnusedParameters false + export function f1(x: number) {} + +==== tests/cases/conformance/pragma/noUnusedParameters/file4.ts (0 errors) ==== + export function f1(x: number) {} + \ No newline at end of file diff --git a/tests/baselines/reference/noUnusedParametersPragma1.js b/tests/baselines/reference/noUnusedParametersPragma1.js new file mode 100644 index 0000000000000..cfb799daa443f --- /dev/null +++ b/tests/baselines/reference/noUnusedParametersPragma1.js @@ -0,0 +1,45 @@ +//// [tests/cases/conformance/pragma/noUnusedParameters/noUnusedParametersPragma1.ts] //// + +//// [file1.ts] +// @ts-noUnusedParameters +export function f1(x: number) {} + +//// [file2.ts] +// @ts-noUnusedParameters true +export function f1(x: number) {} + +//// [file3.ts] +// @ts-noUnusedParameters false +export function f1(x: number) {} + +//// [file4.ts] +export function f1(x: number) {} + + +//// [file1.js] +"use strict"; +exports.__esModule = true; +exports.f1 = void 0; +// @ts-noUnusedParameters +function f1(x) { } +exports.f1 = f1; +//// [file2.js] +"use strict"; +exports.__esModule = true; +exports.f1 = void 0; +// @ts-noUnusedParameters true +function f1(x) { } +exports.f1 = f1; +//// [file3.js] +"use strict"; +exports.__esModule = true; +exports.f1 = void 0; +// @ts-noUnusedParameters false +function f1(x) { } +exports.f1 = f1; +//// [file4.js] +"use strict"; +exports.__esModule = true; +exports.f1 = void 0; +function f1(x) { } +exports.f1 = f1; diff --git a/tests/baselines/reference/noUnusedParametersPragma1.symbols b/tests/baselines/reference/noUnusedParametersPragma1.symbols new file mode 100644 index 0000000000000..fba031181be0d --- /dev/null +++ b/tests/baselines/reference/noUnusedParametersPragma1.symbols @@ -0,0 +1,23 @@ +=== tests/cases/conformance/pragma/noUnusedParameters/file1.ts === +// @ts-noUnusedParameters +export function f1(x: number) {} +>f1 : Symbol(f1, Decl(file1.ts, 0, 0)) +>x : Symbol(x, Decl(file1.ts, 1, 19)) + +=== tests/cases/conformance/pragma/noUnusedParameters/file2.ts === +// @ts-noUnusedParameters true +export function f1(x: number) {} +>f1 : Symbol(f1, Decl(file2.ts, 0, 0)) +>x : Symbol(x, Decl(file2.ts, 1, 19)) + +=== tests/cases/conformance/pragma/noUnusedParameters/file3.ts === +// @ts-noUnusedParameters false +export function f1(x: number) {} +>f1 : Symbol(f1, Decl(file3.ts, 0, 0)) +>x : Symbol(x, Decl(file3.ts, 1, 19)) + +=== tests/cases/conformance/pragma/noUnusedParameters/file4.ts === +export function f1(x: number) {} +>f1 : Symbol(f1, Decl(file4.ts, 0, 0)) +>x : Symbol(x, Decl(file4.ts, 0, 19)) + diff --git a/tests/baselines/reference/noUnusedParametersPragma1.types b/tests/baselines/reference/noUnusedParametersPragma1.types new file mode 100644 index 0000000000000..252b000f50f43 --- /dev/null +++ b/tests/baselines/reference/noUnusedParametersPragma1.types @@ -0,0 +1,23 @@ +=== tests/cases/conformance/pragma/noUnusedParameters/file1.ts === +// @ts-noUnusedParameters +export function f1(x: number) {} +>f1 : (x: number) => void +>x : number + +=== tests/cases/conformance/pragma/noUnusedParameters/file2.ts === +// @ts-noUnusedParameters true +export function f1(x: number) {} +>f1 : (x: number) => void +>x : number + +=== tests/cases/conformance/pragma/noUnusedParameters/file3.ts === +// @ts-noUnusedParameters false +export function f1(x: number) {} +>f1 : (x: number) => void +>x : number + +=== tests/cases/conformance/pragma/noUnusedParameters/file4.ts === +export function f1(x: number) {} +>f1 : (x: number) => void +>x : number + diff --git a/tests/baselines/reference/noUnusedParametersPragma2.errors.txt b/tests/baselines/reference/noUnusedParametersPragma2.errors.txt new file mode 100644 index 0000000000000..588d8a7baeaec --- /dev/null +++ b/tests/baselines/reference/noUnusedParametersPragma2.errors.txt @@ -0,0 +1,26 @@ +tests/cases/conformance/pragma/noUnusedParameters/file1.ts(2,20): error TS6133: 'x' is declared but its value is never read. +tests/cases/conformance/pragma/noUnusedParameters/file2.ts(2,20): error TS6133: 'x' is declared but its value is never read. +tests/cases/conformance/pragma/noUnusedParameters/file4.ts(1,20): error TS6133: 'x' is declared but its value is never read. + + +==== tests/cases/conformance/pragma/noUnusedParameters/file1.ts (1 errors) ==== + // @ts-noUnusedParameters + export function f1(x: number) {} + ~ +!!! error TS6133: 'x' is declared but its value is never read. + +==== tests/cases/conformance/pragma/noUnusedParameters/file2.ts (1 errors) ==== + // @ts-noUnusedParameters true + export function f1(x: number) {} + ~ +!!! error TS6133: 'x' is declared but its value is never read. + +==== tests/cases/conformance/pragma/noUnusedParameters/file3.ts (0 errors) ==== + // @ts-noUnusedParameters false + export function f1(x: number) {} + +==== tests/cases/conformance/pragma/noUnusedParameters/file4.ts (1 errors) ==== + export function f1(x: number) {} + ~ +!!! error TS6133: 'x' is declared but its value is never read. + \ No newline at end of file diff --git a/tests/baselines/reference/noUnusedParametersPragma2.js b/tests/baselines/reference/noUnusedParametersPragma2.js new file mode 100644 index 0000000000000..35b712c7b43d2 --- /dev/null +++ b/tests/baselines/reference/noUnusedParametersPragma2.js @@ -0,0 +1,45 @@ +//// [tests/cases/conformance/pragma/noUnusedParameters/noUnusedParametersPragma2.ts] //// + +//// [file1.ts] +// @ts-noUnusedParameters +export function f1(x: number) {} + +//// [file2.ts] +// @ts-noUnusedParameters true +export function f1(x: number) {} + +//// [file3.ts] +// @ts-noUnusedParameters false +export function f1(x: number) {} + +//// [file4.ts] +export function f1(x: number) {} + + +//// [file1.js] +"use strict"; +exports.__esModule = true; +exports.f1 = void 0; +// @ts-noUnusedParameters +function f1(x) { } +exports.f1 = f1; +//// [file2.js] +"use strict"; +exports.__esModule = true; +exports.f1 = void 0; +// @ts-noUnusedParameters true +function f1(x) { } +exports.f1 = f1; +//// [file3.js] +"use strict"; +exports.__esModule = true; +exports.f1 = void 0; +// @ts-noUnusedParameters false +function f1(x) { } +exports.f1 = f1; +//// [file4.js] +"use strict"; +exports.__esModule = true; +exports.f1 = void 0; +function f1(x) { } +exports.f1 = f1; diff --git a/tests/baselines/reference/noUnusedParametersPragma2.symbols b/tests/baselines/reference/noUnusedParametersPragma2.symbols new file mode 100644 index 0000000000000..fba031181be0d --- /dev/null +++ b/tests/baselines/reference/noUnusedParametersPragma2.symbols @@ -0,0 +1,23 @@ +=== tests/cases/conformance/pragma/noUnusedParameters/file1.ts === +// @ts-noUnusedParameters +export function f1(x: number) {} +>f1 : Symbol(f1, Decl(file1.ts, 0, 0)) +>x : Symbol(x, Decl(file1.ts, 1, 19)) + +=== tests/cases/conformance/pragma/noUnusedParameters/file2.ts === +// @ts-noUnusedParameters true +export function f1(x: number) {} +>f1 : Symbol(f1, Decl(file2.ts, 0, 0)) +>x : Symbol(x, Decl(file2.ts, 1, 19)) + +=== tests/cases/conformance/pragma/noUnusedParameters/file3.ts === +// @ts-noUnusedParameters false +export function f1(x: number) {} +>f1 : Symbol(f1, Decl(file3.ts, 0, 0)) +>x : Symbol(x, Decl(file3.ts, 1, 19)) + +=== tests/cases/conformance/pragma/noUnusedParameters/file4.ts === +export function f1(x: number) {} +>f1 : Symbol(f1, Decl(file4.ts, 0, 0)) +>x : Symbol(x, Decl(file4.ts, 0, 19)) + diff --git a/tests/baselines/reference/noUnusedParametersPragma2.types b/tests/baselines/reference/noUnusedParametersPragma2.types new file mode 100644 index 0000000000000..252b000f50f43 --- /dev/null +++ b/tests/baselines/reference/noUnusedParametersPragma2.types @@ -0,0 +1,23 @@ +=== tests/cases/conformance/pragma/noUnusedParameters/file1.ts === +// @ts-noUnusedParameters +export function f1(x: number) {} +>f1 : (x: number) => void +>x : number + +=== tests/cases/conformance/pragma/noUnusedParameters/file2.ts === +// @ts-noUnusedParameters true +export function f1(x: number) {} +>f1 : (x: number) => void +>x : number + +=== tests/cases/conformance/pragma/noUnusedParameters/file3.ts === +// @ts-noUnusedParameters false +export function f1(x: number) {} +>f1 : (x: number) => void +>x : number + +=== tests/cases/conformance/pragma/noUnusedParameters/file4.ts === +export function f1(x: number) {} +>f1 : (x: number) => void +>x : number + diff --git a/tests/baselines/reference/strictBindCallApplyPragma1.errors.txt b/tests/baselines/reference/strictBindCallApplyPragma1.errors.txt new file mode 100644 index 0000000000000..4374ba13e6ad4 --- /dev/null +++ b/tests/baselines/reference/strictBindCallApplyPragma1.errors.txt @@ -0,0 +1,31 @@ +tests/cases/conformance/pragma/strictBindCallApply/file1.ts(3,20): error TS2345: Argument of type 'number' is not assignable to parameter of type 'string'. +tests/cases/conformance/pragma/strictBindCallApply/file2.ts(3,20): error TS2345: Argument of type 'number' is not assignable to parameter of type 'string'. + + +==== tests/cases/conformance/pragma/strictBindCallApply/file1.ts (1 errors) ==== + // @ts-strictBindCallApply + export function f1(x: string) {} + f1.call(undefined, 42); // wrong + ~~ +!!! error TS2345: Argument of type 'number' is not assignable to parameter of type 'string'. + f1.call(undefined, "ok"); // right + +==== tests/cases/conformance/pragma/strictBindCallApply/file2.ts (1 errors) ==== + // @ts-strictBindCallApply true + export function f1(x: string) {} + f1.call(undefined, 42); // wrong + ~~ +!!! error TS2345: Argument of type 'number' is not assignable to parameter of type 'string'. + f1.call(undefined, "ok"); // right + +==== tests/cases/conformance/pragma/strictBindCallApply/file3.ts (0 errors) ==== + // @ts-strictBindCallApply false + export function f1(x: string) {} + f1.call(undefined, 42); // wrong + f1.call(undefined, "ok"); // right + +==== tests/cases/conformance/pragma/strictBindCallApply/file4.ts (0 errors) ==== + export function f1(x: string) {} + f1.call(undefined, 42); // wrong + f1.call(undefined, "ok"); // right + \ No newline at end of file diff --git a/tests/baselines/reference/strictBindCallApplyPragma1.js b/tests/baselines/reference/strictBindCallApplyPragma1.js new file mode 100644 index 0000000000000..6c61d44f862aa --- /dev/null +++ b/tests/baselines/reference/strictBindCallApplyPragma1.js @@ -0,0 +1,61 @@ +//// [tests/cases/conformance/pragma/strictBindCallApply/strictBindCallApplyPragma1.ts] //// + +//// [file1.ts] +// @ts-strictBindCallApply +export function f1(x: string) {} +f1.call(undefined, 42); // wrong +f1.call(undefined, "ok"); // right + +//// [file2.ts] +// @ts-strictBindCallApply true +export function f1(x: string) {} +f1.call(undefined, 42); // wrong +f1.call(undefined, "ok"); // right + +//// [file3.ts] +// @ts-strictBindCallApply false +export function f1(x: string) {} +f1.call(undefined, 42); // wrong +f1.call(undefined, "ok"); // right + +//// [file4.ts] +export function f1(x: string) {} +f1.call(undefined, 42); // wrong +f1.call(undefined, "ok"); // right + + +//// [file1.js] +"use strict"; +exports.__esModule = true; +exports.f1 = void 0; +// @ts-strictBindCallApply +function f1(x) { } +exports.f1 = f1; +f1.call(undefined, 42); // wrong +f1.call(undefined, "ok"); // right +//// [file2.js] +"use strict"; +exports.__esModule = true; +exports.f1 = void 0; +// @ts-strictBindCallApply true +function f1(x) { } +exports.f1 = f1; +f1.call(undefined, 42); // wrong +f1.call(undefined, "ok"); // right +//// [file3.js] +"use strict"; +exports.__esModule = true; +exports.f1 = void 0; +// @ts-strictBindCallApply false +function f1(x) { } +exports.f1 = f1; +f1.call(undefined, 42); // wrong +f1.call(undefined, "ok"); // right +//// [file4.js] +"use strict"; +exports.__esModule = true; +exports.f1 = void 0; +function f1(x) { } +exports.f1 = f1; +f1.call(undefined, 42); // wrong +f1.call(undefined, "ok"); // right diff --git a/tests/baselines/reference/strictBindCallApplyPragma1.symbols b/tests/baselines/reference/strictBindCallApplyPragma1.symbols new file mode 100644 index 0000000000000..5819783a626bc --- /dev/null +++ b/tests/baselines/reference/strictBindCallApplyPragma1.symbols @@ -0,0 +1,71 @@ +=== tests/cases/conformance/pragma/strictBindCallApply/file1.ts === +// @ts-strictBindCallApply +export function f1(x: string) {} +>f1 : Symbol(f1, Decl(file1.ts, 0, 0)) +>x : Symbol(x, Decl(file1.ts, 1, 19)) + +f1.call(undefined, 42); // wrong +>f1.call : Symbol(CallableFunction.call, Decl(lib.es5.d.ts, --, --)) +>f1 : Symbol(f1, Decl(file1.ts, 0, 0)) +>call : Symbol(CallableFunction.call, Decl(lib.es5.d.ts, --, --)) +>undefined : Symbol(undefined) + +f1.call(undefined, "ok"); // right +>f1.call : Symbol(CallableFunction.call, Decl(lib.es5.d.ts, --, --)) +>f1 : Symbol(f1, Decl(file1.ts, 0, 0)) +>call : Symbol(CallableFunction.call, Decl(lib.es5.d.ts, --, --)) +>undefined : Symbol(undefined) + +=== tests/cases/conformance/pragma/strictBindCallApply/file2.ts === +// @ts-strictBindCallApply true +export function f1(x: string) {} +>f1 : Symbol(f1, Decl(file2.ts, 0, 0)) +>x : Symbol(x, Decl(file2.ts, 1, 19)) + +f1.call(undefined, 42); // wrong +>f1.call : Symbol(CallableFunction.call, Decl(lib.es5.d.ts, --, --)) +>f1 : Symbol(f1, Decl(file2.ts, 0, 0)) +>call : Symbol(CallableFunction.call, Decl(lib.es5.d.ts, --, --)) +>undefined : Symbol(undefined) + +f1.call(undefined, "ok"); // right +>f1.call : Symbol(CallableFunction.call, Decl(lib.es5.d.ts, --, --)) +>f1 : Symbol(f1, Decl(file2.ts, 0, 0)) +>call : Symbol(CallableFunction.call, Decl(lib.es5.d.ts, --, --)) +>undefined : Symbol(undefined) + +=== tests/cases/conformance/pragma/strictBindCallApply/file3.ts === +// @ts-strictBindCallApply false +export function f1(x: string) {} +>f1 : Symbol(f1, Decl(file3.ts, 0, 0)) +>x : Symbol(x, Decl(file3.ts, 1, 19)) + +f1.call(undefined, 42); // wrong +>f1.call : Symbol(Function.call, Decl(lib.es5.d.ts, --, --)) +>f1 : Symbol(f1, Decl(file3.ts, 0, 0)) +>call : Symbol(Function.call, Decl(lib.es5.d.ts, --, --)) +>undefined : Symbol(undefined) + +f1.call(undefined, "ok"); // right +>f1.call : Symbol(Function.call, Decl(lib.es5.d.ts, --, --)) +>f1 : Symbol(f1, Decl(file3.ts, 0, 0)) +>call : Symbol(Function.call, Decl(lib.es5.d.ts, --, --)) +>undefined : Symbol(undefined) + +=== tests/cases/conformance/pragma/strictBindCallApply/file4.ts === +export function f1(x: string) {} +>f1 : Symbol(f1, Decl(file4.ts, 0, 0)) +>x : Symbol(x, Decl(file4.ts, 0, 19)) + +f1.call(undefined, 42); // wrong +>f1.call : Symbol(Function.call, Decl(lib.es5.d.ts, --, --)) +>f1 : Symbol(f1, Decl(file4.ts, 0, 0)) +>call : Symbol(Function.call, Decl(lib.es5.d.ts, --, --)) +>undefined : Symbol(undefined) + +f1.call(undefined, "ok"); // right +>f1.call : Symbol(Function.call, Decl(lib.es5.d.ts, --, --)) +>f1 : Symbol(f1, Decl(file4.ts, 0, 0)) +>call : Symbol(Function.call, Decl(lib.es5.d.ts, --, --)) +>undefined : Symbol(undefined) + diff --git a/tests/baselines/reference/strictBindCallApplyPragma1.types b/tests/baselines/reference/strictBindCallApplyPragma1.types new file mode 100644 index 0000000000000..97ffc120ff123 --- /dev/null +++ b/tests/baselines/reference/strictBindCallApplyPragma1.types @@ -0,0 +1,87 @@ +=== tests/cases/conformance/pragma/strictBindCallApply/file1.ts === +// @ts-strictBindCallApply +export function f1(x: string) {} +>f1 : (x: string) => void +>x : string + +f1.call(undefined, 42); // wrong +>f1.call(undefined, 42) : void +>f1.call : (this: (this: T, ...args: A) => R, thisArg: T, ...args: A) => R +>f1 : (x: string) => void +>call : (this: (this: T, ...args: A) => R, thisArg: T, ...args: A) => R +>undefined : undefined +>42 : 42 + +f1.call(undefined, "ok"); // right +>f1.call(undefined, "ok") : void +>f1.call : (this: (this: T, ...args: A) => R, thisArg: T, ...args: A) => R +>f1 : (x: string) => void +>call : (this: (this: T, ...args: A) => R, thisArg: T, ...args: A) => R +>undefined : undefined +>"ok" : "ok" + +=== tests/cases/conformance/pragma/strictBindCallApply/file2.ts === +// @ts-strictBindCallApply true +export function f1(x: string) {} +>f1 : (x: string) => void +>x : string + +f1.call(undefined, 42); // wrong +>f1.call(undefined, 42) : void +>f1.call : (this: (this: T, ...args: A) => R, thisArg: T, ...args: A) => R +>f1 : (x: string) => void +>call : (this: (this: T, ...args: A) => R, thisArg: T, ...args: A) => R +>undefined : undefined +>42 : 42 + +f1.call(undefined, "ok"); // right +>f1.call(undefined, "ok") : void +>f1.call : (this: (this: T, ...args: A) => R, thisArg: T, ...args: A) => R +>f1 : (x: string) => void +>call : (this: (this: T, ...args: A) => R, thisArg: T, ...args: A) => R +>undefined : undefined +>"ok" : "ok" + +=== tests/cases/conformance/pragma/strictBindCallApply/file3.ts === +// @ts-strictBindCallApply false +export function f1(x: string) {} +>f1 : (x: string) => void +>x : string + +f1.call(undefined, 42); // wrong +>f1.call(undefined, 42) : any +>f1.call : (this: Function, thisArg: any, ...argArray: any[]) => any +>f1 : (x: string) => void +>call : (this: Function, thisArg: any, ...argArray: any[]) => any +>undefined : undefined +>42 : 42 + +f1.call(undefined, "ok"); // right +>f1.call(undefined, "ok") : any +>f1.call : (this: Function, thisArg: any, ...argArray: any[]) => any +>f1 : (x: string) => void +>call : (this: Function, thisArg: any, ...argArray: any[]) => any +>undefined : undefined +>"ok" : "ok" + +=== tests/cases/conformance/pragma/strictBindCallApply/file4.ts === +export function f1(x: string) {} +>f1 : (x: string) => void +>x : string + +f1.call(undefined, 42); // wrong +>f1.call(undefined, 42) : any +>f1.call : (this: Function, thisArg: any, ...argArray: any[]) => any +>f1 : (x: string) => void +>call : (this: Function, thisArg: any, ...argArray: any[]) => any +>undefined : undefined +>42 : 42 + +f1.call(undefined, "ok"); // right +>f1.call(undefined, "ok") : any +>f1.call : (this: Function, thisArg: any, ...argArray: any[]) => any +>f1 : (x: string) => void +>call : (this: Function, thisArg: any, ...argArray: any[]) => any +>undefined : undefined +>"ok" : "ok" + diff --git a/tests/baselines/reference/strictBindCallApplyPragma2.errors.txt b/tests/baselines/reference/strictBindCallApplyPragma2.errors.txt new file mode 100644 index 0000000000000..6ca7c6412d974 --- /dev/null +++ b/tests/baselines/reference/strictBindCallApplyPragma2.errors.txt @@ -0,0 +1,34 @@ +tests/cases/conformance/pragma/strictBindCallApply/file1.ts(3,20): error TS2345: Argument of type 'number' is not assignable to parameter of type 'string'. +tests/cases/conformance/pragma/strictBindCallApply/file2.ts(3,20): error TS2345: Argument of type 'number' is not assignable to parameter of type 'string'. +tests/cases/conformance/pragma/strictBindCallApply/file4.ts(2,20): error TS2345: Argument of type 'number' is not assignable to parameter of type 'string'. + + +==== tests/cases/conformance/pragma/strictBindCallApply/file1.ts (1 errors) ==== + // @ts-strictBindCallApply + export function f1(x: string) {} + f1.call(undefined, 42); // wrong + ~~ +!!! error TS2345: Argument of type 'number' is not assignable to parameter of type 'string'. + f1.call(undefined, "ok"); // right + +==== tests/cases/conformance/pragma/strictBindCallApply/file2.ts (1 errors) ==== + // @ts-strictBindCallApply true + export function f1(x: string) {} + f1.call(undefined, 42); // wrong + ~~ +!!! error TS2345: Argument of type 'number' is not assignable to parameter of type 'string'. + f1.call(undefined, "ok"); // right + +==== tests/cases/conformance/pragma/strictBindCallApply/file3.ts (0 errors) ==== + // @ts-strictBindCallApply false + export function f1(x: string) {} + f1.call(undefined, 42); // wrong + f1.call(undefined, "ok"); // right + +==== tests/cases/conformance/pragma/strictBindCallApply/file4.ts (1 errors) ==== + export function f1(x: string) {} + f1.call(undefined, 42); // wrong + ~~ +!!! error TS2345: Argument of type 'number' is not assignable to parameter of type 'string'. + f1.call(undefined, "ok"); // right + \ No newline at end of file diff --git a/tests/baselines/reference/strictBindCallApplyPragma2.js b/tests/baselines/reference/strictBindCallApplyPragma2.js new file mode 100644 index 0000000000000..bec17ddca8034 --- /dev/null +++ b/tests/baselines/reference/strictBindCallApplyPragma2.js @@ -0,0 +1,61 @@ +//// [tests/cases/conformance/pragma/strictBindCallApply/strictBindCallApplyPragma2.ts] //// + +//// [file1.ts] +// @ts-strictBindCallApply +export function f1(x: string) {} +f1.call(undefined, 42); // wrong +f1.call(undefined, "ok"); // right + +//// [file2.ts] +// @ts-strictBindCallApply true +export function f1(x: string) {} +f1.call(undefined, 42); // wrong +f1.call(undefined, "ok"); // right + +//// [file3.ts] +// @ts-strictBindCallApply false +export function f1(x: string) {} +f1.call(undefined, 42); // wrong +f1.call(undefined, "ok"); // right + +//// [file4.ts] +export function f1(x: string) {} +f1.call(undefined, 42); // wrong +f1.call(undefined, "ok"); // right + + +//// [file1.js] +"use strict"; +exports.__esModule = true; +exports.f1 = void 0; +// @ts-strictBindCallApply +function f1(x) { } +exports.f1 = f1; +f1.call(undefined, 42); // wrong +f1.call(undefined, "ok"); // right +//// [file2.js] +"use strict"; +exports.__esModule = true; +exports.f1 = void 0; +// @ts-strictBindCallApply true +function f1(x) { } +exports.f1 = f1; +f1.call(undefined, 42); // wrong +f1.call(undefined, "ok"); // right +//// [file3.js] +"use strict"; +exports.__esModule = true; +exports.f1 = void 0; +// @ts-strictBindCallApply false +function f1(x) { } +exports.f1 = f1; +f1.call(undefined, 42); // wrong +f1.call(undefined, "ok"); // right +//// [file4.js] +"use strict"; +exports.__esModule = true; +exports.f1 = void 0; +function f1(x) { } +exports.f1 = f1; +f1.call(undefined, 42); // wrong +f1.call(undefined, "ok"); // right diff --git a/tests/baselines/reference/strictBindCallApplyPragma2.symbols b/tests/baselines/reference/strictBindCallApplyPragma2.symbols new file mode 100644 index 0000000000000..beabe97d7c812 --- /dev/null +++ b/tests/baselines/reference/strictBindCallApplyPragma2.symbols @@ -0,0 +1,71 @@ +=== tests/cases/conformance/pragma/strictBindCallApply/file1.ts === +// @ts-strictBindCallApply +export function f1(x: string) {} +>f1 : Symbol(f1, Decl(file1.ts, 0, 0)) +>x : Symbol(x, Decl(file1.ts, 1, 19)) + +f1.call(undefined, 42); // wrong +>f1.call : Symbol(CallableFunction.call, Decl(lib.es5.d.ts, --, --)) +>f1 : Symbol(f1, Decl(file1.ts, 0, 0)) +>call : Symbol(CallableFunction.call, Decl(lib.es5.d.ts, --, --)) +>undefined : Symbol(undefined) + +f1.call(undefined, "ok"); // right +>f1.call : Symbol(CallableFunction.call, Decl(lib.es5.d.ts, --, --)) +>f1 : Symbol(f1, Decl(file1.ts, 0, 0)) +>call : Symbol(CallableFunction.call, Decl(lib.es5.d.ts, --, --)) +>undefined : Symbol(undefined) + +=== tests/cases/conformance/pragma/strictBindCallApply/file2.ts === +// @ts-strictBindCallApply true +export function f1(x: string) {} +>f1 : Symbol(f1, Decl(file2.ts, 0, 0)) +>x : Symbol(x, Decl(file2.ts, 1, 19)) + +f1.call(undefined, 42); // wrong +>f1.call : Symbol(CallableFunction.call, Decl(lib.es5.d.ts, --, --)) +>f1 : Symbol(f1, Decl(file2.ts, 0, 0)) +>call : Symbol(CallableFunction.call, Decl(lib.es5.d.ts, --, --)) +>undefined : Symbol(undefined) + +f1.call(undefined, "ok"); // right +>f1.call : Symbol(CallableFunction.call, Decl(lib.es5.d.ts, --, --)) +>f1 : Symbol(f1, Decl(file2.ts, 0, 0)) +>call : Symbol(CallableFunction.call, Decl(lib.es5.d.ts, --, --)) +>undefined : Symbol(undefined) + +=== tests/cases/conformance/pragma/strictBindCallApply/file3.ts === +// @ts-strictBindCallApply false +export function f1(x: string) {} +>f1 : Symbol(f1, Decl(file3.ts, 0, 0)) +>x : Symbol(x, Decl(file3.ts, 1, 19)) + +f1.call(undefined, 42); // wrong +>f1.call : Symbol(Function.call, Decl(lib.es5.d.ts, --, --)) +>f1 : Symbol(f1, Decl(file3.ts, 0, 0)) +>call : Symbol(Function.call, Decl(lib.es5.d.ts, --, --)) +>undefined : Symbol(undefined) + +f1.call(undefined, "ok"); // right +>f1.call : Symbol(Function.call, Decl(lib.es5.d.ts, --, --)) +>f1 : Symbol(f1, Decl(file3.ts, 0, 0)) +>call : Symbol(Function.call, Decl(lib.es5.d.ts, --, --)) +>undefined : Symbol(undefined) + +=== tests/cases/conformance/pragma/strictBindCallApply/file4.ts === +export function f1(x: string) {} +>f1 : Symbol(f1, Decl(file4.ts, 0, 0)) +>x : Symbol(x, Decl(file4.ts, 0, 19)) + +f1.call(undefined, 42); // wrong +>f1.call : Symbol(CallableFunction.call, Decl(lib.es5.d.ts, --, --)) +>f1 : Symbol(f1, Decl(file4.ts, 0, 0)) +>call : Symbol(CallableFunction.call, Decl(lib.es5.d.ts, --, --)) +>undefined : Symbol(undefined) + +f1.call(undefined, "ok"); // right +>f1.call : Symbol(CallableFunction.call, Decl(lib.es5.d.ts, --, --)) +>f1 : Symbol(f1, Decl(file4.ts, 0, 0)) +>call : Symbol(CallableFunction.call, Decl(lib.es5.d.ts, --, --)) +>undefined : Symbol(undefined) + diff --git a/tests/baselines/reference/strictBindCallApplyPragma2.types b/tests/baselines/reference/strictBindCallApplyPragma2.types new file mode 100644 index 0000000000000..73e0cb4a5b029 --- /dev/null +++ b/tests/baselines/reference/strictBindCallApplyPragma2.types @@ -0,0 +1,87 @@ +=== tests/cases/conformance/pragma/strictBindCallApply/file1.ts === +// @ts-strictBindCallApply +export function f1(x: string) {} +>f1 : (x: string) => void +>x : string + +f1.call(undefined, 42); // wrong +>f1.call(undefined, 42) : void +>f1.call : (this: (this: T, ...args: A) => R, thisArg: T, ...args: A) => R +>f1 : (x: string) => void +>call : (this: (this: T, ...args: A) => R, thisArg: T, ...args: A) => R +>undefined : undefined +>42 : 42 + +f1.call(undefined, "ok"); // right +>f1.call(undefined, "ok") : void +>f1.call : (this: (this: T, ...args: A) => R, thisArg: T, ...args: A) => R +>f1 : (x: string) => void +>call : (this: (this: T, ...args: A) => R, thisArg: T, ...args: A) => R +>undefined : undefined +>"ok" : "ok" + +=== tests/cases/conformance/pragma/strictBindCallApply/file2.ts === +// @ts-strictBindCallApply true +export function f1(x: string) {} +>f1 : (x: string) => void +>x : string + +f1.call(undefined, 42); // wrong +>f1.call(undefined, 42) : void +>f1.call : (this: (this: T, ...args: A) => R, thisArg: T, ...args: A) => R +>f1 : (x: string) => void +>call : (this: (this: T, ...args: A) => R, thisArg: T, ...args: A) => R +>undefined : undefined +>42 : 42 + +f1.call(undefined, "ok"); // right +>f1.call(undefined, "ok") : void +>f1.call : (this: (this: T, ...args: A) => R, thisArg: T, ...args: A) => R +>f1 : (x: string) => void +>call : (this: (this: T, ...args: A) => R, thisArg: T, ...args: A) => R +>undefined : undefined +>"ok" : "ok" + +=== tests/cases/conformance/pragma/strictBindCallApply/file3.ts === +// @ts-strictBindCallApply false +export function f1(x: string) {} +>f1 : (x: string) => void +>x : string + +f1.call(undefined, 42); // wrong +>f1.call(undefined, 42) : any +>f1.call : (this: Function, thisArg: any, ...argArray: any[]) => any +>f1 : (x: string) => void +>call : (this: Function, thisArg: any, ...argArray: any[]) => any +>undefined : undefined +>42 : 42 + +f1.call(undefined, "ok"); // right +>f1.call(undefined, "ok") : any +>f1.call : (this: Function, thisArg: any, ...argArray: any[]) => any +>f1 : (x: string) => void +>call : (this: Function, thisArg: any, ...argArray: any[]) => any +>undefined : undefined +>"ok" : "ok" + +=== tests/cases/conformance/pragma/strictBindCallApply/file4.ts === +export function f1(x: string) {} +>f1 : (x: string) => void +>x : string + +f1.call(undefined, 42); // wrong +>f1.call(undefined, 42) : void +>f1.call : (this: (this: T, ...args: A) => R, thisArg: T, ...args: A) => R +>f1 : (x: string) => void +>call : (this: (this: T, ...args: A) => R, thisArg: T, ...args: A) => R +>undefined : undefined +>42 : 42 + +f1.call(undefined, "ok"); // right +>f1.call(undefined, "ok") : void +>f1.call : (this: (this: T, ...args: A) => R, thisArg: T, ...args: A) => R +>f1 : (x: string) => void +>call : (this: (this: T, ...args: A) => R, thisArg: T, ...args: A) => R +>undefined : undefined +>"ok" : "ok" + diff --git a/tests/baselines/reference/strictFunctionTypesPragma1.errors.txt b/tests/baselines/reference/strictFunctionTypesPragma1.errors.txt new file mode 100644 index 0000000000000..4504a13808bc4 --- /dev/null +++ b/tests/baselines/reference/strictFunctionTypesPragma1.errors.txt @@ -0,0 +1,47 @@ +tests/cases/conformance/pragma/strictFunctionTypes/file1.ts(6,1): error TS2322: Type '(arg: string) => number' is not assignable to type '(arg: unknown) => number'. + Types of parameters 'arg' and 'arg' are incompatible. + Type 'unknown' is not assignable to type 'string'. +tests/cases/conformance/pragma/strictFunctionTypes/file2.ts(6,1): error TS2322: Type '(arg: string) => number' is not assignable to type '(arg: unknown) => number'. + Types of parameters 'arg' and 'arg' are incompatible. + Type 'unknown' is not assignable to type 'string'. + + +==== tests/cases/conformance/pragma/strictFunctionTypes/file1.ts (1 errors) ==== + // @ts-strictFunctionTypes + export let a = (arg: string) => 0; + export let b = (arg: unknown) => 0; + + a = b; + b = a; + ~ +!!! error TS2322: Type '(arg: string) => number' is not assignable to type '(arg: unknown) => number'. +!!! error TS2322: Types of parameters 'arg' and 'arg' are incompatible. +!!! error TS2322: Type 'unknown' is not assignable to type 'string'. + +==== tests/cases/conformance/pragma/strictFunctionTypes/file2.ts (1 errors) ==== + // @ts-strictFunctionTypes true + export let a = (arg: string) => 0; + export let b = (arg: unknown) => 0; + + a = b; + b = a; + ~ +!!! error TS2322: Type '(arg: string) => number' is not assignable to type '(arg: unknown) => number'. +!!! error TS2322: Types of parameters 'arg' and 'arg' are incompatible. +!!! error TS2322: Type 'unknown' is not assignable to type 'string'. + +==== tests/cases/conformance/pragma/strictFunctionTypes/file3.ts (0 errors) ==== + // @ts-strictFunctionTypes false + export let a = (arg: string) => 0; + export let b = (arg: unknown) => 0; + + a = b; + b = a; + +==== tests/cases/conformance/pragma/strictFunctionTypes/file4.ts (0 errors) ==== + export let a = (arg: string) => 0; + export let b = (arg: unknown) => 0; + + a = b; + b = a; + \ No newline at end of file diff --git a/tests/baselines/reference/strictFunctionTypesPragma1.js b/tests/baselines/reference/strictFunctionTypesPragma1.js new file mode 100644 index 0000000000000..4353d2bddc35b --- /dev/null +++ b/tests/baselines/reference/strictFunctionTypesPragma1.js @@ -0,0 +1,77 @@ +//// [tests/cases/conformance/pragma/strictFunctionTypes/strictFunctionTypesPragma1.ts] //// + +//// [file1.ts] +// @ts-strictFunctionTypes +export let a = (arg: string) => 0; +export let b = (arg: unknown) => 0; + +a = b; +b = a; + +//// [file2.ts] +// @ts-strictFunctionTypes true +export let a = (arg: string) => 0; +export let b = (arg: unknown) => 0; + +a = b; +b = a; + +//// [file3.ts] +// @ts-strictFunctionTypes false +export let a = (arg: string) => 0; +export let b = (arg: unknown) => 0; + +a = b; +b = a; + +//// [file4.ts] +export let a = (arg: string) => 0; +export let b = (arg: unknown) => 0; + +a = b; +b = a; + + +//// [file1.js] +"use strict"; +exports.__esModule = true; +exports.b = exports.a = void 0; +// @ts-strictFunctionTypes +var a = function (arg) { return 0; }; +exports.a = a; +var b = function (arg) { return 0; }; +exports.b = b; +exports.a = exports.b; +exports.b = exports.a; +//// [file2.js] +"use strict"; +exports.__esModule = true; +exports.b = exports.a = void 0; +// @ts-strictFunctionTypes true +var a = function (arg) { return 0; }; +exports.a = a; +var b = function (arg) { return 0; }; +exports.b = b; +exports.a = exports.b; +exports.b = exports.a; +//// [file3.js] +"use strict"; +exports.__esModule = true; +exports.b = exports.a = void 0; +// @ts-strictFunctionTypes false +var a = function (arg) { return 0; }; +exports.a = a; +var b = function (arg) { return 0; }; +exports.b = b; +exports.a = exports.b; +exports.b = exports.a; +//// [file4.js] +"use strict"; +exports.__esModule = true; +exports.b = exports.a = void 0; +var a = function (arg) { return 0; }; +exports.a = a; +var b = function (arg) { return 0; }; +exports.b = b; +exports.a = exports.b; +exports.b = exports.a; diff --git a/tests/baselines/reference/strictFunctionTypesPragma1.symbols b/tests/baselines/reference/strictFunctionTypesPragma1.symbols new file mode 100644 index 0000000000000..e0f6c41249d3b --- /dev/null +++ b/tests/baselines/reference/strictFunctionTypesPragma1.symbols @@ -0,0 +1,71 @@ +=== tests/cases/conformance/pragma/strictFunctionTypes/file1.ts === +// @ts-strictFunctionTypes +export let a = (arg: string) => 0; +>a : Symbol(a, Decl(file1.ts, 1, 10)) +>arg : Symbol(arg, Decl(file1.ts, 1, 16)) + +export let b = (arg: unknown) => 0; +>b : Symbol(b, Decl(file1.ts, 2, 10)) +>arg : Symbol(arg, Decl(file1.ts, 2, 16)) + +a = b; +>a : Symbol(a, Decl(file1.ts, 1, 10)) +>b : Symbol(b, Decl(file1.ts, 2, 10)) + +b = a; +>b : Symbol(b, Decl(file1.ts, 2, 10)) +>a : Symbol(a, Decl(file1.ts, 1, 10)) + +=== tests/cases/conformance/pragma/strictFunctionTypes/file2.ts === +// @ts-strictFunctionTypes true +export let a = (arg: string) => 0; +>a : Symbol(a, Decl(file2.ts, 1, 10)) +>arg : Symbol(arg, Decl(file2.ts, 1, 16)) + +export let b = (arg: unknown) => 0; +>b : Symbol(b, Decl(file2.ts, 2, 10)) +>arg : Symbol(arg, Decl(file2.ts, 2, 16)) + +a = b; +>a : Symbol(a, Decl(file2.ts, 1, 10)) +>b : Symbol(b, Decl(file2.ts, 2, 10)) + +b = a; +>b : Symbol(b, Decl(file2.ts, 2, 10)) +>a : Symbol(a, Decl(file2.ts, 1, 10)) + +=== tests/cases/conformance/pragma/strictFunctionTypes/file3.ts === +// @ts-strictFunctionTypes false +export let a = (arg: string) => 0; +>a : Symbol(a, Decl(file3.ts, 1, 10)) +>arg : Symbol(arg, Decl(file3.ts, 1, 16)) + +export let b = (arg: unknown) => 0; +>b : Symbol(b, Decl(file3.ts, 2, 10)) +>arg : Symbol(arg, Decl(file3.ts, 2, 16)) + +a = b; +>a : Symbol(a, Decl(file3.ts, 1, 10)) +>b : Symbol(b, Decl(file3.ts, 2, 10)) + +b = a; +>b : Symbol(b, Decl(file3.ts, 2, 10)) +>a : Symbol(a, Decl(file3.ts, 1, 10)) + +=== tests/cases/conformance/pragma/strictFunctionTypes/file4.ts === +export let a = (arg: string) => 0; +>a : Symbol(a, Decl(file4.ts, 0, 10)) +>arg : Symbol(arg, Decl(file4.ts, 0, 16)) + +export let b = (arg: unknown) => 0; +>b : Symbol(b, Decl(file4.ts, 1, 10)) +>arg : Symbol(arg, Decl(file4.ts, 1, 16)) + +a = b; +>a : Symbol(a, Decl(file4.ts, 0, 10)) +>b : Symbol(b, Decl(file4.ts, 1, 10)) + +b = a; +>b : Symbol(b, Decl(file4.ts, 1, 10)) +>a : Symbol(a, Decl(file4.ts, 0, 10)) + diff --git a/tests/baselines/reference/strictFunctionTypesPragma1.types b/tests/baselines/reference/strictFunctionTypesPragma1.types new file mode 100644 index 0000000000000..5fc9051b34f0a --- /dev/null +++ b/tests/baselines/reference/strictFunctionTypesPragma1.types @@ -0,0 +1,95 @@ +=== tests/cases/conformance/pragma/strictFunctionTypes/file1.ts === +// @ts-strictFunctionTypes +export let a = (arg: string) => 0; +>a : (arg: string) => number +>(arg: string) => 0 : (arg: string) => number +>arg : string +>0 : 0 + +export let b = (arg: unknown) => 0; +>b : (arg: unknown) => number +>(arg: unknown) => 0 : (arg: unknown) => number +>arg : unknown +>0 : 0 + +a = b; +>a = b : (arg: unknown) => number +>a : (arg: string) => number +>b : (arg: unknown) => number + +b = a; +>b = a : (arg: string) => number +>b : (arg: unknown) => number +>a : (arg: string) => number + +=== tests/cases/conformance/pragma/strictFunctionTypes/file2.ts === +// @ts-strictFunctionTypes true +export let a = (arg: string) => 0; +>a : (arg: string) => number +>(arg: string) => 0 : (arg: string) => number +>arg : string +>0 : 0 + +export let b = (arg: unknown) => 0; +>b : (arg: unknown) => number +>(arg: unknown) => 0 : (arg: unknown) => number +>arg : unknown +>0 : 0 + +a = b; +>a = b : (arg: unknown) => number +>a : (arg: string) => number +>b : (arg: unknown) => number + +b = a; +>b = a : (arg: string) => number +>b : (arg: unknown) => number +>a : (arg: string) => number + +=== tests/cases/conformance/pragma/strictFunctionTypes/file3.ts === +// @ts-strictFunctionTypes false +export let a = (arg: string) => 0; +>a : (arg: string) => number +>(arg: string) => 0 : (arg: string) => number +>arg : string +>0 : 0 + +export let b = (arg: unknown) => 0; +>b : (arg: unknown) => number +>(arg: unknown) => 0 : (arg: unknown) => number +>arg : unknown +>0 : 0 + +a = b; +>a = b : (arg: unknown) => number +>a : (arg: string) => number +>b : (arg: unknown) => number + +b = a; +>b = a : (arg: string) => number +>b : (arg: unknown) => number +>a : (arg: string) => number + +=== tests/cases/conformance/pragma/strictFunctionTypes/file4.ts === +export let a = (arg: string) => 0; +>a : (arg: string) => number +>(arg: string) => 0 : (arg: string) => number +>arg : string +>0 : 0 + +export let b = (arg: unknown) => 0; +>b : (arg: unknown) => number +>(arg: unknown) => 0 : (arg: unknown) => number +>arg : unknown +>0 : 0 + +a = b; +>a = b : (arg: unknown) => number +>a : (arg: string) => number +>b : (arg: unknown) => number + +b = a; +>b = a : (arg: string) => number +>b : (arg: unknown) => number +>a : (arg: string) => number + diff --git a/tests/baselines/reference/strictFunctionTypesPragma2.errors.txt b/tests/baselines/reference/strictFunctionTypesPragma2.errors.txt new file mode 100644 index 0000000000000..d9cb0eafad180 --- /dev/null +++ b/tests/baselines/reference/strictFunctionTypesPragma2.errors.txt @@ -0,0 +1,54 @@ +tests/cases/conformance/pragma/strictFunctionTypes/file1.ts(6,1): error TS2322: Type '(arg: string) => number' is not assignable to type '(arg: unknown) => number'. + Types of parameters 'arg' and 'arg' are incompatible. + Type 'unknown' is not assignable to type 'string'. +tests/cases/conformance/pragma/strictFunctionTypes/file2.ts(6,1): error TS2322: Type '(arg: string) => number' is not assignable to type '(arg: unknown) => number'. + Types of parameters 'arg' and 'arg' are incompatible. + Type 'unknown' is not assignable to type 'string'. +tests/cases/conformance/pragma/strictFunctionTypes/file4.ts(5,1): error TS2322: Type '(arg: string) => number' is not assignable to type '(arg: unknown) => number'. + Types of parameters 'arg' and 'arg' are incompatible. + Type 'unknown' is not assignable to type 'string'. + + +==== tests/cases/conformance/pragma/strictFunctionTypes/file1.ts (1 errors) ==== + // @ts-strictFunctionTypes + export let a = (arg: string) => 0; + export let b = (arg: unknown) => 0; + + a = b; + b = a; + ~ +!!! error TS2322: Type '(arg: string) => number' is not assignable to type '(arg: unknown) => number'. +!!! error TS2322: Types of parameters 'arg' and 'arg' are incompatible. +!!! error TS2322: Type 'unknown' is not assignable to type 'string'. + +==== tests/cases/conformance/pragma/strictFunctionTypes/file2.ts (1 errors) ==== + // @ts-strictFunctionTypes true + export let a = (arg: string) => 0; + export let b = (arg: unknown) => 0; + + a = b; + b = a; + ~ +!!! error TS2322: Type '(arg: string) => number' is not assignable to type '(arg: unknown) => number'. +!!! error TS2322: Types of parameters 'arg' and 'arg' are incompatible. +!!! error TS2322: Type 'unknown' is not assignable to type 'string'. + +==== tests/cases/conformance/pragma/strictFunctionTypes/file3.ts (0 errors) ==== + // @ts-strictFunctionTypes false + export let a = (arg: string) => 0; + export let b = (arg: unknown) => 0; + + a = b; + b = a; + +==== tests/cases/conformance/pragma/strictFunctionTypes/file4.ts (1 errors) ==== + export let a = (arg: string) => 0; + export let b = (arg: unknown) => 0; + + a = b; + b = a; + ~ +!!! error TS2322: Type '(arg: string) => number' is not assignable to type '(arg: unknown) => number'. +!!! error TS2322: Types of parameters 'arg' and 'arg' are incompatible. +!!! error TS2322: Type 'unknown' is not assignable to type 'string'. + \ No newline at end of file diff --git a/tests/baselines/reference/strictFunctionTypesPragma2.js b/tests/baselines/reference/strictFunctionTypesPragma2.js new file mode 100644 index 0000000000000..758a3f57f8553 --- /dev/null +++ b/tests/baselines/reference/strictFunctionTypesPragma2.js @@ -0,0 +1,77 @@ +//// [tests/cases/conformance/pragma/strictFunctionTypes/strictFunctionTypesPragma2.ts] //// + +//// [file1.ts] +// @ts-strictFunctionTypes +export let a = (arg: string) => 0; +export let b = (arg: unknown) => 0; + +a = b; +b = a; + +//// [file2.ts] +// @ts-strictFunctionTypes true +export let a = (arg: string) => 0; +export let b = (arg: unknown) => 0; + +a = b; +b = a; + +//// [file3.ts] +// @ts-strictFunctionTypes false +export let a = (arg: string) => 0; +export let b = (arg: unknown) => 0; + +a = b; +b = a; + +//// [file4.ts] +export let a = (arg: string) => 0; +export let b = (arg: unknown) => 0; + +a = b; +b = a; + + +//// [file1.js] +"use strict"; +exports.__esModule = true; +exports.b = exports.a = void 0; +// @ts-strictFunctionTypes +var a = function (arg) { return 0; }; +exports.a = a; +var b = function (arg) { return 0; }; +exports.b = b; +exports.a = exports.b; +exports.b = exports.a; +//// [file2.js] +"use strict"; +exports.__esModule = true; +exports.b = exports.a = void 0; +// @ts-strictFunctionTypes true +var a = function (arg) { return 0; }; +exports.a = a; +var b = function (arg) { return 0; }; +exports.b = b; +exports.a = exports.b; +exports.b = exports.a; +//// [file3.js] +"use strict"; +exports.__esModule = true; +exports.b = exports.a = void 0; +// @ts-strictFunctionTypes false +var a = function (arg) { return 0; }; +exports.a = a; +var b = function (arg) { return 0; }; +exports.b = b; +exports.a = exports.b; +exports.b = exports.a; +//// [file4.js] +"use strict"; +exports.__esModule = true; +exports.b = exports.a = void 0; +var a = function (arg) { return 0; }; +exports.a = a; +var b = function (arg) { return 0; }; +exports.b = b; +exports.a = exports.b; +exports.b = exports.a; diff --git a/tests/baselines/reference/strictFunctionTypesPragma2.symbols b/tests/baselines/reference/strictFunctionTypesPragma2.symbols new file mode 100644 index 0000000000000..e0f6c41249d3b --- /dev/null +++ b/tests/baselines/reference/strictFunctionTypesPragma2.symbols @@ -0,0 +1,71 @@ +=== tests/cases/conformance/pragma/strictFunctionTypes/file1.ts === +// @ts-strictFunctionTypes +export let a = (arg: string) => 0; +>a : Symbol(a, Decl(file1.ts, 1, 10)) +>arg : Symbol(arg, Decl(file1.ts, 1, 16)) + +export let b = (arg: unknown) => 0; +>b : Symbol(b, Decl(file1.ts, 2, 10)) +>arg : Symbol(arg, Decl(file1.ts, 2, 16)) + +a = b; +>a : Symbol(a, Decl(file1.ts, 1, 10)) +>b : Symbol(b, Decl(file1.ts, 2, 10)) + +b = a; +>b : Symbol(b, Decl(file1.ts, 2, 10)) +>a : Symbol(a, Decl(file1.ts, 1, 10)) + +=== tests/cases/conformance/pragma/strictFunctionTypes/file2.ts === +// @ts-strictFunctionTypes true +export let a = (arg: string) => 0; +>a : Symbol(a, Decl(file2.ts, 1, 10)) +>arg : Symbol(arg, Decl(file2.ts, 1, 16)) + +export let b = (arg: unknown) => 0; +>b : Symbol(b, Decl(file2.ts, 2, 10)) +>arg : Symbol(arg, Decl(file2.ts, 2, 16)) + +a = b; +>a : Symbol(a, Decl(file2.ts, 1, 10)) +>b : Symbol(b, Decl(file2.ts, 2, 10)) + +b = a; +>b : Symbol(b, Decl(file2.ts, 2, 10)) +>a : Symbol(a, Decl(file2.ts, 1, 10)) + +=== tests/cases/conformance/pragma/strictFunctionTypes/file3.ts === +// @ts-strictFunctionTypes false +export let a = (arg: string) => 0; +>a : Symbol(a, Decl(file3.ts, 1, 10)) +>arg : Symbol(arg, Decl(file3.ts, 1, 16)) + +export let b = (arg: unknown) => 0; +>b : Symbol(b, Decl(file3.ts, 2, 10)) +>arg : Symbol(arg, Decl(file3.ts, 2, 16)) + +a = b; +>a : Symbol(a, Decl(file3.ts, 1, 10)) +>b : Symbol(b, Decl(file3.ts, 2, 10)) + +b = a; +>b : Symbol(b, Decl(file3.ts, 2, 10)) +>a : Symbol(a, Decl(file3.ts, 1, 10)) + +=== tests/cases/conformance/pragma/strictFunctionTypes/file4.ts === +export let a = (arg: string) => 0; +>a : Symbol(a, Decl(file4.ts, 0, 10)) +>arg : Symbol(arg, Decl(file4.ts, 0, 16)) + +export let b = (arg: unknown) => 0; +>b : Symbol(b, Decl(file4.ts, 1, 10)) +>arg : Symbol(arg, Decl(file4.ts, 1, 16)) + +a = b; +>a : Symbol(a, Decl(file4.ts, 0, 10)) +>b : Symbol(b, Decl(file4.ts, 1, 10)) + +b = a; +>b : Symbol(b, Decl(file4.ts, 1, 10)) +>a : Symbol(a, Decl(file4.ts, 0, 10)) + diff --git a/tests/baselines/reference/strictFunctionTypesPragma2.types b/tests/baselines/reference/strictFunctionTypesPragma2.types new file mode 100644 index 0000000000000..5fc9051b34f0a --- /dev/null +++ b/tests/baselines/reference/strictFunctionTypesPragma2.types @@ -0,0 +1,95 @@ +=== tests/cases/conformance/pragma/strictFunctionTypes/file1.ts === +// @ts-strictFunctionTypes +export let a = (arg: string) => 0; +>a : (arg: string) => number +>(arg: string) => 0 : (arg: string) => number +>arg : string +>0 : 0 + +export let b = (arg: unknown) => 0; +>b : (arg: unknown) => number +>(arg: unknown) => 0 : (arg: unknown) => number +>arg : unknown +>0 : 0 + +a = b; +>a = b : (arg: unknown) => number +>a : (arg: string) => number +>b : (arg: unknown) => number + +b = a; +>b = a : (arg: string) => number +>b : (arg: unknown) => number +>a : (arg: string) => number + +=== tests/cases/conformance/pragma/strictFunctionTypes/file2.ts === +// @ts-strictFunctionTypes true +export let a = (arg: string) => 0; +>a : (arg: string) => number +>(arg: string) => 0 : (arg: string) => number +>arg : string +>0 : 0 + +export let b = (arg: unknown) => 0; +>b : (arg: unknown) => number +>(arg: unknown) => 0 : (arg: unknown) => number +>arg : unknown +>0 : 0 + +a = b; +>a = b : (arg: unknown) => number +>a : (arg: string) => number +>b : (arg: unknown) => number + +b = a; +>b = a : (arg: string) => number +>b : (arg: unknown) => number +>a : (arg: string) => number + +=== tests/cases/conformance/pragma/strictFunctionTypes/file3.ts === +// @ts-strictFunctionTypes false +export let a = (arg: string) => 0; +>a : (arg: string) => number +>(arg: string) => 0 : (arg: string) => number +>arg : string +>0 : 0 + +export let b = (arg: unknown) => 0; +>b : (arg: unknown) => number +>(arg: unknown) => 0 : (arg: unknown) => number +>arg : unknown +>0 : 0 + +a = b; +>a = b : (arg: unknown) => number +>a : (arg: string) => number +>b : (arg: unknown) => number + +b = a; +>b = a : (arg: string) => number +>b : (arg: unknown) => number +>a : (arg: string) => number + +=== tests/cases/conformance/pragma/strictFunctionTypes/file4.ts === +export let a = (arg: string) => 0; +>a : (arg: string) => number +>(arg: string) => 0 : (arg: string) => number +>arg : string +>0 : 0 + +export let b = (arg: unknown) => 0; +>b : (arg: unknown) => number +>(arg: unknown) => 0 : (arg: unknown) => number +>arg : unknown +>0 : 0 + +a = b; +>a = b : (arg: unknown) => number +>a : (arg: string) => number +>b : (arg: unknown) => number + +b = a; +>b = a : (arg: string) => number +>b : (arg: unknown) => number +>a : (arg: string) => number + diff --git a/tests/baselines/reference/strictFunctionTypesPragma3.errors.txt b/tests/baselines/reference/strictFunctionTypesPragma3.errors.txt new file mode 100644 index 0000000000000..838f01eecac6f --- /dev/null +++ b/tests/baselines/reference/strictFunctionTypesPragma3.errors.txt @@ -0,0 +1,57 @@ +tests/cases/conformance/pragma/strictFunctionTypes/file3.ts(10,1): error TS2322: Type '(a: number) => number' is not assignable to type '(a: unknown) => number'. + Types of parameters 'a' and 'a' are incompatible. + Type 'unknown' is not assignable to type 'number'. +tests/cases/conformance/pragma/strictFunctionTypes/file3.ts(16,1): error TS2322: Type '(a: number) => number' is not assignable to type '(a: unknown) => number'. + Types of parameters 'a' and 'a' are incompatible. + Type 'unknown' is not assignable to type 'number'. +tests/cases/conformance/pragma/strictFunctionTypes/file3.ts(22,1): error TS2322: Type '(a: number) => number' is not assignable to type '(a: unknown) => number'. + Types of parameters 'a' and 'a' are incompatible. + Type 'unknown' is not assignable to type 'number'. + + +==== tests/cases/conformance/pragma/strictFunctionTypes/file1.ts (0 errors) ==== + // @ts-strictFunctionTypes + export const a = (a: number) => 0; + export const b = (a: unknown) => 0; + +==== tests/cases/conformance/pragma/strictFunctionTypes/file2.ts (0 errors) ==== + // @ts-strictFunctionTypes false + export const a = (a: number) => 0; + export const b = (a: unknown) => 0; + +==== tests/cases/conformance/pragma/strictFunctionTypes/file3.ts (3 errors) ==== + import {a as a1, b as b1} from "./file1"; + import {a as a2, b as b2} from "./file2"; + + declare var numberArgStrict: typeof a1; + declare var numberArgLoose: typeof a2; + declare var unknownArgStrict: typeof b1; + declare var unknownArgLoose: typeof b2; + + numberArgStrict = unknownArgStrict; + unknownArgStrict = numberArgStrict; + ~~~~~~~~~~~~~~~~ +!!! error TS2322: Type '(a: number) => number' is not assignable to type '(a: unknown) => number'. +!!! error TS2322: Types of parameters 'a' and 'a' are incompatible. +!!! error TS2322: Type 'unknown' is not assignable to type 'number'. + + numberArgStrict = numberArgLoose; + numberArgLoose = numberArgStrict; + + numberArgStrict = unknownArgLoose; + unknownArgLoose = numberArgStrict; + ~~~~~~~~~~~~~~~ +!!! error TS2322: Type '(a: number) => number' is not assignable to type '(a: unknown) => number'. +!!! error TS2322: Types of parameters 'a' and 'a' are incompatible. +!!! error TS2322: Type 'unknown' is not assignable to type 'number'. + + numberArgLoose = unknownArgLoose; + unknownArgLoose = numberArgLoose; + + numberArgLoose = unknownArgStrict; + unknownArgStrict = numberArgLoose; + ~~~~~~~~~~~~~~~~ +!!! error TS2322: Type '(a: number) => number' is not assignable to type '(a: unknown) => number'. +!!! error TS2322: Types of parameters 'a' and 'a' are incompatible. +!!! error TS2322: Type 'unknown' is not assignable to type 'number'. + \ No newline at end of file diff --git a/tests/baselines/reference/strictFunctionTypesPragma3.js b/tests/baselines/reference/strictFunctionTypesPragma3.js new file mode 100644 index 0000000000000..c6a91ec5d82cd --- /dev/null +++ b/tests/baselines/reference/strictFunctionTypesPragma3.js @@ -0,0 +1,68 @@ +//// [tests/cases/conformance/pragma/strictFunctionTypes/strictFunctionTypesPragma3.ts] //// + +//// [file1.ts] +// @ts-strictFunctionTypes +export const a = (a: number) => 0; +export const b = (a: unknown) => 0; + +//// [file2.ts] +// @ts-strictFunctionTypes false +export const a = (a: number) => 0; +export const b = (a: unknown) => 0; + +//// [file3.ts] +import {a as a1, b as b1} from "./file1"; +import {a as a2, b as b2} from "./file2"; + +declare var numberArgStrict: typeof a1; +declare var numberArgLoose: typeof a2; +declare var unknownArgStrict: typeof b1; +declare var unknownArgLoose: typeof b2; + +numberArgStrict = unknownArgStrict; +unknownArgStrict = numberArgStrict; + +numberArgStrict = numberArgLoose; +numberArgLoose = numberArgStrict; + +numberArgStrict = unknownArgLoose; +unknownArgLoose = numberArgStrict; + +numberArgLoose = unknownArgLoose; +unknownArgLoose = numberArgLoose; + +numberArgLoose = unknownArgStrict; +unknownArgStrict = numberArgLoose; + + +//// [file1.js] +"use strict"; +exports.__esModule = true; +exports.b = exports.a = void 0; +// @ts-strictFunctionTypes +var a = function (a) { return 0; }; +exports.a = a; +var b = function (a) { return 0; }; +exports.b = b; +//// [file2.js] +"use strict"; +exports.__esModule = true; +exports.b = exports.a = void 0; +// @ts-strictFunctionTypes false +var a = function (a) { return 0; }; +exports.a = a; +var b = function (a) { return 0; }; +exports.b = b; +//// [file3.js] +"use strict"; +exports.__esModule = true; +numberArgStrict = unknownArgStrict; +unknownArgStrict = numberArgStrict; +numberArgStrict = numberArgLoose; +numberArgLoose = numberArgStrict; +numberArgStrict = unknownArgLoose; +unknownArgLoose = numberArgStrict; +numberArgLoose = unknownArgLoose; +unknownArgLoose = numberArgLoose; +numberArgLoose = unknownArgStrict; +unknownArgStrict = numberArgLoose; diff --git a/tests/baselines/reference/strictFunctionTypesPragma3.symbols b/tests/baselines/reference/strictFunctionTypesPragma3.symbols new file mode 100644 index 0000000000000..4a2e187c85ec2 --- /dev/null +++ b/tests/baselines/reference/strictFunctionTypesPragma3.symbols @@ -0,0 +1,89 @@ +=== tests/cases/conformance/pragma/strictFunctionTypes/file1.ts === +// @ts-strictFunctionTypes +export const a = (a: number) => 0; +>a : Symbol(a, Decl(file1.ts, 1, 12)) +>a : Symbol(a, Decl(file1.ts, 1, 18)) + +export const b = (a: unknown) => 0; +>b : Symbol(b, Decl(file1.ts, 2, 12)) +>a : Symbol(a, Decl(file1.ts, 2, 18)) + +=== tests/cases/conformance/pragma/strictFunctionTypes/file2.ts === +// @ts-strictFunctionTypes false +export const a = (a: number) => 0; +>a : Symbol(a, Decl(file2.ts, 1, 12)) +>a : Symbol(a, Decl(file2.ts, 1, 18)) + +export const b = (a: unknown) => 0; +>b : Symbol(b, Decl(file2.ts, 2, 12)) +>a : Symbol(a, Decl(file2.ts, 2, 18)) + +=== tests/cases/conformance/pragma/strictFunctionTypes/file3.ts === +import {a as a1, b as b1} from "./file1"; +>a : Symbol(a1, Decl(file1.ts, 1, 12)) +>a1 : Symbol(a1, Decl(file3.ts, 0, 8)) +>b : Symbol(b1, Decl(file1.ts, 2, 12)) +>b1 : Symbol(b1, Decl(file3.ts, 0, 16)) + +import {a as a2, b as b2} from "./file2"; +>a : Symbol(a2, Decl(file2.ts, 1, 12)) +>a2 : Symbol(a2, Decl(file3.ts, 1, 8)) +>b : Symbol(b2, Decl(file2.ts, 2, 12)) +>b2 : Symbol(b2, Decl(file3.ts, 1, 16)) + +declare var numberArgStrict: typeof a1; +>numberArgStrict : Symbol(numberArgStrict, Decl(file3.ts, 3, 11)) +>a1 : Symbol(a1, Decl(file3.ts, 0, 8)) + +declare var numberArgLoose: typeof a2; +>numberArgLoose : Symbol(numberArgLoose, Decl(file3.ts, 4, 11)) +>a2 : Symbol(a2, Decl(file3.ts, 1, 8)) + +declare var unknownArgStrict: typeof b1; +>unknownArgStrict : Symbol(unknownArgStrict, Decl(file3.ts, 5, 11)) +>b1 : Symbol(b1, Decl(file3.ts, 0, 16)) + +declare var unknownArgLoose: typeof b2; +>unknownArgLoose : Symbol(unknownArgLoose, Decl(file3.ts, 6, 11)) +>b2 : Symbol(b2, Decl(file3.ts, 1, 16)) + +numberArgStrict = unknownArgStrict; +>numberArgStrict : Symbol(numberArgStrict, Decl(file3.ts, 3, 11)) +>unknownArgStrict : Symbol(unknownArgStrict, Decl(file3.ts, 5, 11)) + +unknownArgStrict = numberArgStrict; +>unknownArgStrict : Symbol(unknownArgStrict, Decl(file3.ts, 5, 11)) +>numberArgStrict : Symbol(numberArgStrict, Decl(file3.ts, 3, 11)) + +numberArgStrict = numberArgLoose; +>numberArgStrict : Symbol(numberArgStrict, Decl(file3.ts, 3, 11)) +>numberArgLoose : Symbol(numberArgLoose, Decl(file3.ts, 4, 11)) + +numberArgLoose = numberArgStrict; +>numberArgLoose : Symbol(numberArgLoose, Decl(file3.ts, 4, 11)) +>numberArgStrict : Symbol(numberArgStrict, Decl(file3.ts, 3, 11)) + +numberArgStrict = unknownArgLoose; +>numberArgStrict : Symbol(numberArgStrict, Decl(file3.ts, 3, 11)) +>unknownArgLoose : Symbol(unknownArgLoose, Decl(file3.ts, 6, 11)) + +unknownArgLoose = numberArgStrict; +>unknownArgLoose : Symbol(unknownArgLoose, Decl(file3.ts, 6, 11)) +>numberArgStrict : Symbol(numberArgStrict, Decl(file3.ts, 3, 11)) + +numberArgLoose = unknownArgLoose; +>numberArgLoose : Symbol(numberArgLoose, Decl(file3.ts, 4, 11)) +>unknownArgLoose : Symbol(unknownArgLoose, Decl(file3.ts, 6, 11)) + +unknownArgLoose = numberArgLoose; +>unknownArgLoose : Symbol(unknownArgLoose, Decl(file3.ts, 6, 11)) +>numberArgLoose : Symbol(numberArgLoose, Decl(file3.ts, 4, 11)) + +numberArgLoose = unknownArgStrict; +>numberArgLoose : Symbol(numberArgLoose, Decl(file3.ts, 4, 11)) +>unknownArgStrict : Symbol(unknownArgStrict, Decl(file3.ts, 5, 11)) + +unknownArgStrict = numberArgLoose; +>unknownArgStrict : Symbol(unknownArgStrict, Decl(file3.ts, 5, 11)) +>numberArgLoose : Symbol(numberArgLoose, Decl(file3.ts, 4, 11)) + diff --git a/tests/baselines/reference/strictFunctionTypesPragma3.types b/tests/baselines/reference/strictFunctionTypesPragma3.types new file mode 100644 index 0000000000000..3bdcba7390a3c --- /dev/null +++ b/tests/baselines/reference/strictFunctionTypesPragma3.types @@ -0,0 +1,107 @@ +=== tests/cases/conformance/pragma/strictFunctionTypes/file1.ts === +// @ts-strictFunctionTypes +export const a = (a: number) => 0; +>a : (a: number) => number +>(a: number) => 0 : (a: number) => number +>a : number +>0 : 0 + +export const b = (a: unknown) => 0; +>b : (a: unknown) => number +>(a: unknown) => 0 : (a: unknown) => number +>a : unknown +>0 : 0 + +=== tests/cases/conformance/pragma/strictFunctionTypes/file2.ts === +// @ts-strictFunctionTypes false +export const a = (a: number) => 0; +>a : (a: number) => number +>(a: number) => 0 : (a: number) => number +>a : number +>0 : 0 + +export const b = (a: unknown) => 0; +>b : (a: unknown) => number +>(a: unknown) => 0 : (a: unknown) => number +>a : unknown +>0 : 0 + +=== tests/cases/conformance/pragma/strictFunctionTypes/file3.ts === +import {a as a1, b as b1} from "./file1"; +>a : (a: number) => number +>a1 : (a: number) => number +>b : (a: unknown) => number +>b1 : (a: unknown) => number + +import {a as a2, b as b2} from "./file2"; +>a : (a: number) => number +>a2 : (a: number) => number +>b : (a: unknown) => number +>b2 : (a: unknown) => number + +declare var numberArgStrict: typeof a1; +>numberArgStrict : (a: number) => number +>a1 : (a: number) => number + +declare var numberArgLoose: typeof a2; +>numberArgLoose : (a: number) => number +>a2 : (a: number) => number + +declare var unknownArgStrict: typeof b1; +>unknownArgStrict : (a: unknown) => number +>b1 : (a: unknown) => number + +declare var unknownArgLoose: typeof b2; +>unknownArgLoose : (a: unknown) => number +>b2 : (a: unknown) => number + +numberArgStrict = unknownArgStrict; +>numberArgStrict = unknownArgStrict : (a: unknown) => number +>numberArgStrict : (a: number) => number +>unknownArgStrict : (a: unknown) => number + +unknownArgStrict = numberArgStrict; +>unknownArgStrict = numberArgStrict : (a: number) => number +>unknownArgStrict : (a: unknown) => number +>numberArgStrict : (a: number) => number + +numberArgStrict = numberArgLoose; +>numberArgStrict = numberArgLoose : (a: number) => number +>numberArgStrict : (a: number) => number +>numberArgLoose : (a: number) => number + +numberArgLoose = numberArgStrict; +>numberArgLoose = numberArgStrict : (a: number) => number +>numberArgLoose : (a: number) => number +>numberArgStrict : (a: number) => number + +numberArgStrict = unknownArgLoose; +>numberArgStrict = unknownArgLoose : (a: unknown) => number +>numberArgStrict : (a: number) => number +>unknownArgLoose : (a: unknown) => number + +unknownArgLoose = numberArgStrict; +>unknownArgLoose = numberArgStrict : (a: number) => number +>unknownArgLoose : (a: unknown) => number +>numberArgStrict : (a: number) => number + +numberArgLoose = unknownArgLoose; +>numberArgLoose = unknownArgLoose : (a: unknown) => number +>numberArgLoose : (a: number) => number +>unknownArgLoose : (a: unknown) => number + +unknownArgLoose = numberArgLoose; +>unknownArgLoose = numberArgLoose : (a: number) => number +>unknownArgLoose : (a: unknown) => number +>numberArgLoose : (a: number) => number + +numberArgLoose = unknownArgStrict; +>numberArgLoose = unknownArgStrict : (a: unknown) => number +>numberArgLoose : (a: number) => number +>unknownArgStrict : (a: unknown) => number + +unknownArgStrict = numberArgLoose; +>unknownArgStrict = numberArgLoose : (a: number) => number +>unknownArgStrict : (a: unknown) => number +>numberArgLoose : (a: number) => number + diff --git a/tests/baselines/reference/strictPragma1.errors.txt b/tests/baselines/reference/strictPragma1.errors.txt new file mode 100644 index 0000000000000..e8bb40341baca --- /dev/null +++ b/tests/baselines/reference/strictPragma1.errors.txt @@ -0,0 +1,113 @@ +tests/cases/conformance/pragma/strict/file1.ts(3,20): error TS2345: Argument of type 'number' is not assignable to parameter of type 'string'. +tests/cases/conformance/pragma/strict/file1.ts(10,1): error TS2322: Type '(arg: string) => number' is not assignable to type '(arg: unknown) => number'. + Types of parameters 'arg' and 'arg' are incompatible. + Type 'unknown' is not assignable to type 'string'. +tests/cases/conformance/pragma/strict/file1.ts(13,5): error TS2564: Property 'prop' has no initializer and is not definitely assigned in the constructor. +tests/cases/conformance/pragma/strict/file1.ts(18,1): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/pragma/strict/file2.ts(3,20): error TS2345: Argument of type 'number' is not assignable to parameter of type 'string'. +tests/cases/conformance/pragma/strict/file2.ts(10,1): error TS2322: Type '(arg: string) => number' is not assignable to type '(arg: unknown) => number'. + Types of parameters 'arg' and 'arg' are incompatible. + Type 'unknown' is not assignable to type 'string'. +tests/cases/conformance/pragma/strict/file2.ts(13,5): error TS2564: Property 'prop' has no initializer and is not definitely assigned in the constructor. +tests/cases/conformance/pragma/strict/file2.ts(18,1): error TS2532: Object is possibly 'undefined'. + + +==== tests/cases/conformance/pragma/strict/file1.ts (4 errors) ==== + // @ts-strict + export function f1(x: string) {} + f1.call(undefined, 42); // wrong + ~~ +!!! error TS2345: Argument of type 'number' is not assignable to parameter of type 'string'. + f1.call(undefined, "ok"); // right + + export let a = (arg: string) => 0; + export let b = (arg: unknown) => 0; + + a = b; + b = a; + ~ +!!! error TS2322: Type '(arg: string) => number' is not assignable to type '(arg: unknown) => number'. +!!! error TS2322: Types of parameters 'arg' and 'arg' are incompatible. +!!! error TS2322: Type 'unknown' is not assignable to type 'string'. + + export class A { + prop: string; + ~~~~ +!!! error TS2564: Property 'prop' has no initializer and is not definitely assigned in the constructor. + constructor() {} + } + + declare var c: { member?: string }; + c.member.charAt(0); + ~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + +==== tests/cases/conformance/pragma/strict/file2.ts (4 errors) ==== + // @ts-strict true + export function f1(x: string) {} + f1.call(undefined, 42); // wrong + ~~ +!!! error TS2345: Argument of type 'number' is not assignable to parameter of type 'string'. + f1.call(undefined, "ok"); // right + + export let a = (arg: string) => 0; + export let b = (arg: unknown) => 0; + + a = b; + b = a; + ~ +!!! error TS2322: Type '(arg: string) => number' is not assignable to type '(arg: unknown) => number'. +!!! error TS2322: Types of parameters 'arg' and 'arg' are incompatible. +!!! error TS2322: Type 'unknown' is not assignable to type 'string'. + + export class A { + prop: string; + ~~~~ +!!! error TS2564: Property 'prop' has no initializer and is not definitely assigned in the constructor. + constructor() {} + } + + declare var c: { member?: string }; + c.member.charAt(0); + ~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + +==== tests/cases/conformance/pragma/strict/file3.ts (0 errors) ==== + // @ts-strict false + export function f1(x: string) {} + f1.call(undefined, 42); // wrong + f1.call(undefined, "ok"); // right + + export let a = (arg: string) => 0; + export let b = (arg: unknown) => 0; + + a = b; + b = a; + + export class A { + prop: string; + constructor() {} + } + + declare var c: { member?: string }; + c.member.charAt(0); + +==== tests/cases/conformance/pragma/strict/file4.ts (0 errors) ==== + export function f1(x: string) {} + f1.call(undefined, 42); // wrong + f1.call(undefined, "ok"); // right + + export let a = (arg: string) => 0; + export let b = (arg: unknown) => 0; + + a = b; + b = a; + + export class A { + prop: string; + constructor() {} + } + + declare var c: { member?: string }; + c.member.charAt(0); + \ No newline at end of file diff --git a/tests/baselines/reference/strictPragma1.js b/tests/baselines/reference/strictPragma1.js new file mode 100644 index 0000000000000..9e3689a566e2d --- /dev/null +++ b/tests/baselines/reference/strictPragma1.js @@ -0,0 +1,169 @@ +//// [tests/cases/conformance/pragma/strict/strictPragma1.ts] //// + +//// [file1.ts] +// @ts-strict +export function f1(x: string) {} +f1.call(undefined, 42); // wrong +f1.call(undefined, "ok"); // right + +export let a = (arg: string) => 0; +export let b = (arg: unknown) => 0; + +a = b; +b = a; + +export class A { + prop: string; + constructor() {} +} + +declare var c: { member?: string }; +c.member.charAt(0); + +//// [file2.ts] +// @ts-strict true +export function f1(x: string) {} +f1.call(undefined, 42); // wrong +f1.call(undefined, "ok"); // right + +export let a = (arg: string) => 0; +export let b = (arg: unknown) => 0; + +a = b; +b = a; + +export class A { + prop: string; + constructor() {} +} + +declare var c: { member?: string }; +c.member.charAt(0); + +//// [file3.ts] +// @ts-strict false +export function f1(x: string) {} +f1.call(undefined, 42); // wrong +f1.call(undefined, "ok"); // right + +export let a = (arg: string) => 0; +export let b = (arg: unknown) => 0; + +a = b; +b = a; + +export class A { + prop: string; + constructor() {} +} + +declare var c: { member?: string }; +c.member.charAt(0); + +//// [file4.ts] +export function f1(x: string) {} +f1.call(undefined, 42); // wrong +f1.call(undefined, "ok"); // right + +export let a = (arg: string) => 0; +export let b = (arg: unknown) => 0; + +a = b; +b = a; + +export class A { + prop: string; + constructor() {} +} + +declare var c: { member?: string }; +c.member.charAt(0); + + +//// [file1.js] +"use strict"; +exports.__esModule = true; +exports.A = exports.b = exports.a = exports.f1 = void 0; +// @ts-strict +function f1(x) { } +exports.f1 = f1; +f1.call(undefined, 42); // wrong +f1.call(undefined, "ok"); // right +var a = function (arg) { return 0; }; +exports.a = a; +var b = function (arg) { return 0; }; +exports.b = b; +exports.a = exports.b; +exports.b = exports.a; +var A = /** @class */ (function () { + function A() { + } + return A; +}()); +exports.A = A; +c.member.charAt(0); +//// [file2.js] +"use strict"; +exports.__esModule = true; +exports.A = exports.b = exports.a = exports.f1 = void 0; +// @ts-strict true +function f1(x) { } +exports.f1 = f1; +f1.call(undefined, 42); // wrong +f1.call(undefined, "ok"); // right +var a = function (arg) { return 0; }; +exports.a = a; +var b = function (arg) { return 0; }; +exports.b = b; +exports.a = exports.b; +exports.b = exports.a; +var A = /** @class */ (function () { + function A() { + } + return A; +}()); +exports.A = A; +c.member.charAt(0); +//// [file3.js] +"use strict"; +exports.__esModule = true; +exports.A = exports.b = exports.a = exports.f1 = void 0; +// @ts-strict false +function f1(x) { } +exports.f1 = f1; +f1.call(undefined, 42); // wrong +f1.call(undefined, "ok"); // right +var a = function (arg) { return 0; }; +exports.a = a; +var b = function (arg) { return 0; }; +exports.b = b; +exports.a = exports.b; +exports.b = exports.a; +var A = /** @class */ (function () { + function A() { + } + return A; +}()); +exports.A = A; +c.member.charAt(0); +//// [file4.js] +"use strict"; +exports.__esModule = true; +exports.A = exports.b = exports.a = exports.f1 = void 0; +function f1(x) { } +exports.f1 = f1; +f1.call(undefined, 42); // wrong +f1.call(undefined, "ok"); // right +var a = function (arg) { return 0; }; +exports.a = a; +var b = function (arg) { return 0; }; +exports.b = b; +exports.a = exports.b; +exports.b = exports.a; +var A = /** @class */ (function () { + function A() { + } + return A; +}()); +exports.A = A; +c.member.charAt(0); diff --git a/tests/baselines/reference/strictPragma1.symbols b/tests/baselines/reference/strictPragma1.symbols new file mode 100644 index 0000000000000..5861056e2289a --- /dev/null +++ b/tests/baselines/reference/strictPragma1.symbols @@ -0,0 +1,215 @@ +=== tests/cases/conformance/pragma/strict/file1.ts === +// @ts-strict +export function f1(x: string) {} +>f1 : Symbol(f1, Decl(file1.ts, 0, 0)) +>x : Symbol(x, Decl(file1.ts, 1, 19)) + +f1.call(undefined, 42); // wrong +>f1.call : Symbol(CallableFunction.call, Decl(lib.es5.d.ts, --, --)) +>f1 : Symbol(f1, Decl(file1.ts, 0, 0)) +>call : Symbol(CallableFunction.call, Decl(lib.es5.d.ts, --, --)) +>undefined : Symbol(undefined) + +f1.call(undefined, "ok"); // right +>f1.call : Symbol(CallableFunction.call, Decl(lib.es5.d.ts, --, --)) +>f1 : Symbol(f1, Decl(file1.ts, 0, 0)) +>call : Symbol(CallableFunction.call, Decl(lib.es5.d.ts, --, --)) +>undefined : Symbol(undefined) + +export let a = (arg: string) => 0; +>a : Symbol(a, Decl(file1.ts, 5, 10)) +>arg : Symbol(arg, Decl(file1.ts, 5, 16)) + +export let b = (arg: unknown) => 0; +>b : Symbol(b, Decl(file1.ts, 6, 10)) +>arg : Symbol(arg, Decl(file1.ts, 6, 16)) + +a = b; +>a : Symbol(a, Decl(file1.ts, 5, 10)) +>b : Symbol(b, Decl(file1.ts, 6, 10)) + +b = a; +>b : Symbol(b, Decl(file1.ts, 6, 10)) +>a : Symbol(a, Decl(file1.ts, 5, 10)) + +export class A { +>A : Symbol(A, Decl(file1.ts, 9, 6)) + + prop: string; +>prop : Symbol(A.prop, Decl(file1.ts, 11, 16)) + + constructor() {} +} + +declare var c: { member?: string }; +>c : Symbol(c, Decl(file1.ts, 16, 11)) +>member : Symbol(member, Decl(file1.ts, 16, 16)) + +c.member.charAt(0); +>c.member.charAt : Symbol(String.charAt, Decl(lib.es5.d.ts, --, --)) +>c.member : Symbol(member, Decl(file1.ts, 16, 16)) +>c : Symbol(c, Decl(file1.ts, 16, 11)) +>member : Symbol(member, Decl(file1.ts, 16, 16)) +>charAt : Symbol(String.charAt, Decl(lib.es5.d.ts, --, --)) + +=== tests/cases/conformance/pragma/strict/file2.ts === +// @ts-strict true +export function f1(x: string) {} +>f1 : Symbol(f1, Decl(file2.ts, 0, 0)) +>x : Symbol(x, Decl(file2.ts, 1, 19)) + +f1.call(undefined, 42); // wrong +>f1.call : Symbol(CallableFunction.call, Decl(lib.es5.d.ts, --, --)) +>f1 : Symbol(f1, Decl(file2.ts, 0, 0)) +>call : Symbol(CallableFunction.call, Decl(lib.es5.d.ts, --, --)) +>undefined : Symbol(undefined) + +f1.call(undefined, "ok"); // right +>f1.call : Symbol(CallableFunction.call, Decl(lib.es5.d.ts, --, --)) +>f1 : Symbol(f1, Decl(file2.ts, 0, 0)) +>call : Symbol(CallableFunction.call, Decl(lib.es5.d.ts, --, --)) +>undefined : Symbol(undefined) + +export let a = (arg: string) => 0; +>a : Symbol(a, Decl(file2.ts, 5, 10)) +>arg : Symbol(arg, Decl(file2.ts, 5, 16)) + +export let b = (arg: unknown) => 0; +>b : Symbol(b, Decl(file2.ts, 6, 10)) +>arg : Symbol(arg, Decl(file2.ts, 6, 16)) + +a = b; +>a : Symbol(a, Decl(file2.ts, 5, 10)) +>b : Symbol(b, Decl(file2.ts, 6, 10)) + +b = a; +>b : Symbol(b, Decl(file2.ts, 6, 10)) +>a : Symbol(a, Decl(file2.ts, 5, 10)) + +export class A { +>A : Symbol(A, Decl(file2.ts, 9, 6)) + + prop: string; +>prop : Symbol(A.prop, Decl(file2.ts, 11, 16)) + + constructor() {} +} + +declare var c: { member?: string }; +>c : Symbol(c, Decl(file2.ts, 16, 11)) +>member : Symbol(member, Decl(file2.ts, 16, 16)) + +c.member.charAt(0); +>c.member.charAt : Symbol(String.charAt, Decl(lib.es5.d.ts, --, --)) +>c.member : Symbol(member, Decl(file2.ts, 16, 16)) +>c : Symbol(c, Decl(file2.ts, 16, 11)) +>member : Symbol(member, Decl(file2.ts, 16, 16)) +>charAt : Symbol(String.charAt, Decl(lib.es5.d.ts, --, --)) + +=== tests/cases/conformance/pragma/strict/file3.ts === +// @ts-strict false +export function f1(x: string) {} +>f1 : Symbol(f1, Decl(file3.ts, 0, 0)) +>x : Symbol(x, Decl(file3.ts, 1, 19)) + +f1.call(undefined, 42); // wrong +>f1.call : Symbol(Function.call, Decl(lib.es5.d.ts, --, --)) +>f1 : Symbol(f1, Decl(file3.ts, 0, 0)) +>call : Symbol(Function.call, Decl(lib.es5.d.ts, --, --)) +>undefined : Symbol(undefined) + +f1.call(undefined, "ok"); // right +>f1.call : Symbol(Function.call, Decl(lib.es5.d.ts, --, --)) +>f1 : Symbol(f1, Decl(file3.ts, 0, 0)) +>call : Symbol(Function.call, Decl(lib.es5.d.ts, --, --)) +>undefined : Symbol(undefined) + +export let a = (arg: string) => 0; +>a : Symbol(a, Decl(file3.ts, 5, 10)) +>arg : Symbol(arg, Decl(file3.ts, 5, 16)) + +export let b = (arg: unknown) => 0; +>b : Symbol(b, Decl(file3.ts, 6, 10)) +>arg : Symbol(arg, Decl(file3.ts, 6, 16)) + +a = b; +>a : Symbol(a, Decl(file3.ts, 5, 10)) +>b : Symbol(b, Decl(file3.ts, 6, 10)) + +b = a; +>b : Symbol(b, Decl(file3.ts, 6, 10)) +>a : Symbol(a, Decl(file3.ts, 5, 10)) + +export class A { +>A : Symbol(A, Decl(file3.ts, 9, 6)) + + prop: string; +>prop : Symbol(A.prop, Decl(file3.ts, 11, 16)) + + constructor() {} +} + +declare var c: { member?: string }; +>c : Symbol(c, Decl(file3.ts, 16, 11)) +>member : Symbol(member, Decl(file3.ts, 16, 16)) + +c.member.charAt(0); +>c.member.charAt : Symbol(String.charAt, Decl(lib.es5.d.ts, --, --)) +>c.member : Symbol(member, Decl(file3.ts, 16, 16)) +>c : Symbol(c, Decl(file3.ts, 16, 11)) +>member : Symbol(member, Decl(file3.ts, 16, 16)) +>charAt : Symbol(String.charAt, Decl(lib.es5.d.ts, --, --)) + +=== tests/cases/conformance/pragma/strict/file4.ts === +export function f1(x: string) {} +>f1 : Symbol(f1, Decl(file4.ts, 0, 0)) +>x : Symbol(x, Decl(file4.ts, 0, 19)) + +f1.call(undefined, 42); // wrong +>f1.call : Symbol(Function.call, Decl(lib.es5.d.ts, --, --)) +>f1 : Symbol(f1, Decl(file4.ts, 0, 0)) +>call : Symbol(Function.call, Decl(lib.es5.d.ts, --, --)) +>undefined : Symbol(undefined) + +f1.call(undefined, "ok"); // right +>f1.call : Symbol(Function.call, Decl(lib.es5.d.ts, --, --)) +>f1 : Symbol(f1, Decl(file4.ts, 0, 0)) +>call : Symbol(Function.call, Decl(lib.es5.d.ts, --, --)) +>undefined : Symbol(undefined) + +export let a = (arg: string) => 0; +>a : Symbol(a, Decl(file4.ts, 4, 10)) +>arg : Symbol(arg, Decl(file4.ts, 4, 16)) + +export let b = (arg: unknown) => 0; +>b : Symbol(b, Decl(file4.ts, 5, 10)) +>arg : Symbol(arg, Decl(file4.ts, 5, 16)) + +a = b; +>a : Symbol(a, Decl(file4.ts, 4, 10)) +>b : Symbol(b, Decl(file4.ts, 5, 10)) + +b = a; +>b : Symbol(b, Decl(file4.ts, 5, 10)) +>a : Symbol(a, Decl(file4.ts, 4, 10)) + +export class A { +>A : Symbol(A, Decl(file4.ts, 8, 6)) + + prop: string; +>prop : Symbol(A.prop, Decl(file4.ts, 10, 16)) + + constructor() {} +} + +declare var c: { member?: string }; +>c : Symbol(c, Decl(file4.ts, 15, 11)) +>member : Symbol(member, Decl(file4.ts, 15, 16)) + +c.member.charAt(0); +>c.member.charAt : Symbol(String.charAt, Decl(lib.es5.d.ts, --, --)) +>c.member : Symbol(member, Decl(file4.ts, 15, 16)) +>c : Symbol(c, Decl(file4.ts, 15, 11)) +>member : Symbol(member, Decl(file4.ts, 15, 16)) +>charAt : Symbol(String.charAt, Decl(lib.es5.d.ts, --, --)) + diff --git a/tests/baselines/reference/strictPragma1.types b/tests/baselines/reference/strictPragma1.types new file mode 100644 index 0000000000000..b43e0af05f7a2 --- /dev/null +++ b/tests/baselines/reference/strictPragma1.types @@ -0,0 +1,263 @@ +=== tests/cases/conformance/pragma/strict/file1.ts === +// @ts-strict +export function f1(x: string) {} +>f1 : (x: string) => void +>x : string + +f1.call(undefined, 42); // wrong +>f1.call(undefined, 42) : void +>f1.call : (this: (this: T, ...args: A) => R, thisArg: T, ...args: A) => R +>f1 : (x: string) => void +>call : (this: (this: T, ...args: A) => R, thisArg: T, ...args: A) => R +>undefined : undefined +>42 : 42 + +f1.call(undefined, "ok"); // right +>f1.call(undefined, "ok") : void +>f1.call : (this: (this: T, ...args: A) => R, thisArg: T, ...args: A) => R +>f1 : (x: string) => void +>call : (this: (this: T, ...args: A) => R, thisArg: T, ...args: A) => R +>undefined : undefined +>"ok" : "ok" + +export let a = (arg: string) => 0; +>a : (arg: string) => number +>(arg: string) => 0 : (arg: string) => number +>arg : string +>0 : 0 + +export let b = (arg: unknown) => 0; +>b : (arg: unknown) => number +>(arg: unknown) => 0 : (arg: unknown) => number +>arg : unknown +>0 : 0 + +a = b; +>a = b : (arg: unknown) => number +>a : (arg: string) => number +>b : (arg: unknown) => number + +b = a; +>b = a : (arg: string) => number +>b : (arg: unknown) => number +>a : (arg: string) => number + +export class A { +>A : A + + prop: string; +>prop : string + + constructor() {} +} + +declare var c: { member?: string }; +>c : { member?: string | undefined; } +>member : string | undefined + +c.member.charAt(0); +>c.member.charAt(0) : string +>c.member.charAt : (pos: number) => string +>c.member : string | undefined +>c : { member?: string | undefined; } +>member : string | undefined +>charAt : (pos: number) => string +>0 : 0 + +=== tests/cases/conformance/pragma/strict/file2.ts === +// @ts-strict true +export function f1(x: string) {} +>f1 : (x: string) => void +>x : string + +f1.call(undefined, 42); // wrong +>f1.call(undefined, 42) : void +>f1.call : (this: (this: T, ...args: A) => R, thisArg: T, ...args: A) => R +>f1 : (x: string) => void +>call : (this: (this: T, ...args: A) => R, thisArg: T, ...args: A) => R +>undefined : undefined +>42 : 42 + +f1.call(undefined, "ok"); // right +>f1.call(undefined, "ok") : void +>f1.call : (this: (this: T, ...args: A) => R, thisArg: T, ...args: A) => R +>f1 : (x: string) => void +>call : (this: (this: T, ...args: A) => R, thisArg: T, ...args: A) => R +>undefined : undefined +>"ok" : "ok" + +export let a = (arg: string) => 0; +>a : (arg: string) => number +>(arg: string) => 0 : (arg: string) => number +>arg : string +>0 : 0 + +export let b = (arg: unknown) => 0; +>b : (arg: unknown) => number +>(arg: unknown) => 0 : (arg: unknown) => number +>arg : unknown +>0 : 0 + +a = b; +>a = b : (arg: unknown) => number +>a : (arg: string) => number +>b : (arg: unknown) => number + +b = a; +>b = a : (arg: string) => number +>b : (arg: unknown) => number +>a : (arg: string) => number + +export class A { +>A : A + + prop: string; +>prop : string + + constructor() {} +} + +declare var c: { member?: string }; +>c : { member?: string | undefined; } +>member : string | undefined + +c.member.charAt(0); +>c.member.charAt(0) : string +>c.member.charAt : (pos: number) => string +>c.member : string | undefined +>c : { member?: string | undefined; } +>member : string | undefined +>charAt : (pos: number) => string +>0 : 0 + +=== tests/cases/conformance/pragma/strict/file3.ts === +// @ts-strict false +export function f1(x: string) {} +>f1 : (x: string) => void +>x : string + +f1.call(undefined, 42); // wrong +>f1.call(undefined, 42) : any +>f1.call : (this: Function, thisArg: any, ...argArray: any[]) => any +>f1 : (x: string) => void +>call : (this: Function, thisArg: any, ...argArray: any[]) => any +>undefined : undefined +>42 : 42 + +f1.call(undefined, "ok"); // right +>f1.call(undefined, "ok") : any +>f1.call : (this: Function, thisArg: any, ...argArray: any[]) => any +>f1 : (x: string) => void +>call : (this: Function, thisArg: any, ...argArray: any[]) => any +>undefined : undefined +>"ok" : "ok" + +export let a = (arg: string) => 0; +>a : (arg: string) => number +>(arg: string) => 0 : (arg: string) => number +>arg : string +>0 : 0 + +export let b = (arg: unknown) => 0; +>b : (arg: unknown) => number +>(arg: unknown) => 0 : (arg: unknown) => number +>arg : unknown +>0 : 0 + +a = b; +>a = b : (arg: unknown) => number +>a : (arg: string) => number +>b : (arg: unknown) => number + +b = a; +>b = a : (arg: string) => number +>b : (arg: unknown) => number +>a : (arg: string) => number + +export class A { +>A : A + + prop: string; +>prop : string + + constructor() {} +} + +declare var c: { member?: string }; +>c : { member?: string; } +>member : string + +c.member.charAt(0); +>c.member.charAt(0) : string +>c.member.charAt : (pos: number) => string +>c.member : string +>c : { member?: string; } +>member : string +>charAt : (pos: number) => string +>0 : 0 + +=== tests/cases/conformance/pragma/strict/file4.ts === +export function f1(x: string) {} +>f1 : (x: string) => void +>x : string + +f1.call(undefined, 42); // wrong +>f1.call(undefined, 42) : any +>f1.call : (this: Function, thisArg: any, ...argArray: any[]) => any +>f1 : (x: string) => void +>call : (this: Function, thisArg: any, ...argArray: any[]) => any +>undefined : undefined +>42 : 42 + +f1.call(undefined, "ok"); // right +>f1.call(undefined, "ok") : any +>f1.call : (this: Function, thisArg: any, ...argArray: any[]) => any +>f1 : (x: string) => void +>call : (this: Function, thisArg: any, ...argArray: any[]) => any +>undefined : undefined +>"ok" : "ok" + +export let a = (arg: string) => 0; +>a : (arg: string) => number +>(arg: string) => 0 : (arg: string) => number +>arg : string +>0 : 0 + +export let b = (arg: unknown) => 0; +>b : (arg: unknown) => number +>(arg: unknown) => 0 : (arg: unknown) => number +>arg : unknown +>0 : 0 + +a = b; +>a = b : (arg: unknown) => number +>a : (arg: string) => number +>b : (arg: unknown) => number + +b = a; +>b = a : (arg: string) => number +>b : (arg: unknown) => number +>a : (arg: string) => number + +export class A { +>A : A + + prop: string; +>prop : string + + constructor() {} +} + +declare var c: { member?: string }; +>c : { member?: string; } +>member : string + +c.member.charAt(0); +>c.member.charAt(0) : string +>c.member.charAt : (pos: number) => string +>c.member : string +>c : { member?: string; } +>member : string +>charAt : (pos: number) => string +>0 : 0 + diff --git a/tests/baselines/reference/strictPragma2.errors.txt b/tests/baselines/reference/strictPragma2.errors.txt new file mode 100644 index 0000000000000..6cd5311ab60bd --- /dev/null +++ b/tests/baselines/reference/strictPragma2.errors.txt @@ -0,0 +1,129 @@ +tests/cases/conformance/pragma/strict/file1.ts(3,20): error TS2345: Argument of type 'number' is not assignable to parameter of type 'string'. +tests/cases/conformance/pragma/strict/file1.ts(10,1): error TS2322: Type '(arg: string) => number' is not assignable to type '(arg: unknown) => number'. + Types of parameters 'arg' and 'arg' are incompatible. + Type 'unknown' is not assignable to type 'string'. +tests/cases/conformance/pragma/strict/file1.ts(13,5): error TS2564: Property 'prop' has no initializer and is not definitely assigned in the constructor. +tests/cases/conformance/pragma/strict/file1.ts(18,1): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/pragma/strict/file2.ts(3,20): error TS2345: Argument of type 'number' is not assignable to parameter of type 'string'. +tests/cases/conformance/pragma/strict/file2.ts(10,1): error TS2322: Type '(arg: string) => number' is not assignable to type '(arg: unknown) => number'. + Types of parameters 'arg' and 'arg' are incompatible. + Type 'unknown' is not assignable to type 'string'. +tests/cases/conformance/pragma/strict/file2.ts(13,5): error TS2564: Property 'prop' has no initializer and is not definitely assigned in the constructor. +tests/cases/conformance/pragma/strict/file2.ts(18,1): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/pragma/strict/file4.ts(2,20): error TS2345: Argument of type 'number' is not assignable to parameter of type 'string'. +tests/cases/conformance/pragma/strict/file4.ts(9,1): error TS2322: Type '(arg: string) => number' is not assignable to type '(arg: unknown) => number'. + Types of parameters 'arg' and 'arg' are incompatible. + Type 'unknown' is not assignable to type 'string'. +tests/cases/conformance/pragma/strict/file4.ts(12,5): error TS2564: Property 'prop' has no initializer and is not definitely assigned in the constructor. +tests/cases/conformance/pragma/strict/file4.ts(17,1): error TS2532: Object is possibly 'undefined'. + + +==== tests/cases/conformance/pragma/strict/file1.ts (4 errors) ==== + // @ts-strict + export function f1(x: string) {} + f1.call(undefined, 42); // wrong + ~~ +!!! error TS2345: Argument of type 'number' is not assignable to parameter of type 'string'. + f1.call(undefined, "ok"); // right + + export let a = (arg: string) => 0; + export let b = (arg: unknown) => 0; + + a = b; + b = a; + ~ +!!! error TS2322: Type '(arg: string) => number' is not assignable to type '(arg: unknown) => number'. +!!! error TS2322: Types of parameters 'arg' and 'arg' are incompatible. +!!! error TS2322: Type 'unknown' is not assignable to type 'string'. + + export class A { + prop: string; + ~~~~ +!!! error TS2564: Property 'prop' has no initializer and is not definitely assigned in the constructor. + constructor() {} + } + + declare var c: { member?: string }; + c.member.charAt(0); + ~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + +==== tests/cases/conformance/pragma/strict/file2.ts (4 errors) ==== + // @ts-strict true + export function f1(x: string) {} + f1.call(undefined, 42); // wrong + ~~ +!!! error TS2345: Argument of type 'number' is not assignable to parameter of type 'string'. + f1.call(undefined, "ok"); // right + + export let a = (arg: string) => 0; + export let b = (arg: unknown) => 0; + + a = b; + b = a; + ~ +!!! error TS2322: Type '(arg: string) => number' is not assignable to type '(arg: unknown) => number'. +!!! error TS2322: Types of parameters 'arg' and 'arg' are incompatible. +!!! error TS2322: Type 'unknown' is not assignable to type 'string'. + + export class A { + prop: string; + ~~~~ +!!! error TS2564: Property 'prop' has no initializer and is not definitely assigned in the constructor. + constructor() {} + } + + declare var c: { member?: string }; + c.member.charAt(0); + ~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + +==== tests/cases/conformance/pragma/strict/file3.ts (0 errors) ==== + // @ts-strict false + export function f1(x: string) {} + f1.call(undefined, 42); // wrong + f1.call(undefined, "ok"); // right + + export let a = (arg: string) => 0; + export let b = (arg: unknown) => 0; + + a = b; + b = a; + + export class A { + prop: string; + constructor() {} + } + + declare var c: { member?: string }; + c.member.charAt(0); + +==== tests/cases/conformance/pragma/strict/file4.ts (4 errors) ==== + export function f1(x: string) {} + f1.call(undefined, 42); // wrong + ~~ +!!! error TS2345: Argument of type 'number' is not assignable to parameter of type 'string'. + f1.call(undefined, "ok"); // right + + export let a = (arg: string) => 0; + export let b = (arg: unknown) => 0; + + a = b; + b = a; + ~ +!!! error TS2322: Type '(arg: string) => number' is not assignable to type '(arg: unknown) => number'. +!!! error TS2322: Types of parameters 'arg' and 'arg' are incompatible. +!!! error TS2322: Type 'unknown' is not assignable to type 'string'. + + export class A { + prop: string; + ~~~~ +!!! error TS2564: Property 'prop' has no initializer and is not definitely assigned in the constructor. + constructor() {} + } + + declare var c: { member?: string }; + c.member.charAt(0); + ~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + \ No newline at end of file diff --git a/tests/baselines/reference/strictPragma2.js b/tests/baselines/reference/strictPragma2.js new file mode 100644 index 0000000000000..76308089b5147 --- /dev/null +++ b/tests/baselines/reference/strictPragma2.js @@ -0,0 +1,169 @@ +//// [tests/cases/conformance/pragma/strict/strictPragma2.ts] //// + +//// [file1.ts] +// @ts-strict +export function f1(x: string) {} +f1.call(undefined, 42); // wrong +f1.call(undefined, "ok"); // right + +export let a = (arg: string) => 0; +export let b = (arg: unknown) => 0; + +a = b; +b = a; + +export class A { + prop: string; + constructor() {} +} + +declare var c: { member?: string }; +c.member.charAt(0); + +//// [file2.ts] +// @ts-strict true +export function f1(x: string) {} +f1.call(undefined, 42); // wrong +f1.call(undefined, "ok"); // right + +export let a = (arg: string) => 0; +export let b = (arg: unknown) => 0; + +a = b; +b = a; + +export class A { + prop: string; + constructor() {} +} + +declare var c: { member?: string }; +c.member.charAt(0); + +//// [file3.ts] +// @ts-strict false +export function f1(x: string) {} +f1.call(undefined, 42); // wrong +f1.call(undefined, "ok"); // right + +export let a = (arg: string) => 0; +export let b = (arg: unknown) => 0; + +a = b; +b = a; + +export class A { + prop: string; + constructor() {} +} + +declare var c: { member?: string }; +c.member.charAt(0); + +//// [file4.ts] +export function f1(x: string) {} +f1.call(undefined, 42); // wrong +f1.call(undefined, "ok"); // right + +export let a = (arg: string) => 0; +export let b = (arg: unknown) => 0; + +a = b; +b = a; + +export class A { + prop: string; + constructor() {} +} + +declare var c: { member?: string }; +c.member.charAt(0); + + +//// [file1.js] +"use strict"; +exports.__esModule = true; +exports.A = exports.b = exports.a = exports.f1 = void 0; +// @ts-strict +function f1(x) { } +exports.f1 = f1; +f1.call(undefined, 42); // wrong +f1.call(undefined, "ok"); // right +var a = function (arg) { return 0; }; +exports.a = a; +var b = function (arg) { return 0; }; +exports.b = b; +exports.a = exports.b; +exports.b = exports.a; +var A = /** @class */ (function () { + function A() { + } + return A; +}()); +exports.A = A; +c.member.charAt(0); +//// [file2.js] +"use strict"; +exports.__esModule = true; +exports.A = exports.b = exports.a = exports.f1 = void 0; +// @ts-strict true +function f1(x) { } +exports.f1 = f1; +f1.call(undefined, 42); // wrong +f1.call(undefined, "ok"); // right +var a = function (arg) { return 0; }; +exports.a = a; +var b = function (arg) { return 0; }; +exports.b = b; +exports.a = exports.b; +exports.b = exports.a; +var A = /** @class */ (function () { + function A() { + } + return A; +}()); +exports.A = A; +c.member.charAt(0); +//// [file3.js] +"use strict"; +exports.__esModule = true; +exports.A = exports.b = exports.a = exports.f1 = void 0; +// @ts-strict false +function f1(x) { } +exports.f1 = f1; +f1.call(undefined, 42); // wrong +f1.call(undefined, "ok"); // right +var a = function (arg) { return 0; }; +exports.a = a; +var b = function (arg) { return 0; }; +exports.b = b; +exports.a = exports.b; +exports.b = exports.a; +var A = /** @class */ (function () { + function A() { + } + return A; +}()); +exports.A = A; +c.member.charAt(0); +//// [file4.js] +"use strict"; +exports.__esModule = true; +exports.A = exports.b = exports.a = exports.f1 = void 0; +function f1(x) { } +exports.f1 = f1; +f1.call(undefined, 42); // wrong +f1.call(undefined, "ok"); // right +var a = function (arg) { return 0; }; +exports.a = a; +var b = function (arg) { return 0; }; +exports.b = b; +exports.a = exports.b; +exports.b = exports.a; +var A = /** @class */ (function () { + function A() { + } + return A; +}()); +exports.A = A; +c.member.charAt(0); diff --git a/tests/baselines/reference/strictPragma2.symbols b/tests/baselines/reference/strictPragma2.symbols new file mode 100644 index 0000000000000..620fab4d23e31 --- /dev/null +++ b/tests/baselines/reference/strictPragma2.symbols @@ -0,0 +1,215 @@ +=== tests/cases/conformance/pragma/strict/file1.ts === +// @ts-strict +export function f1(x: string) {} +>f1 : Symbol(f1, Decl(file1.ts, 0, 0)) +>x : Symbol(x, Decl(file1.ts, 1, 19)) + +f1.call(undefined, 42); // wrong +>f1.call : Symbol(CallableFunction.call, Decl(lib.es5.d.ts, --, --)) +>f1 : Symbol(f1, Decl(file1.ts, 0, 0)) +>call : Symbol(CallableFunction.call, Decl(lib.es5.d.ts, --, --)) +>undefined : Symbol(undefined) + +f1.call(undefined, "ok"); // right +>f1.call : Symbol(CallableFunction.call, Decl(lib.es5.d.ts, --, --)) +>f1 : Symbol(f1, Decl(file1.ts, 0, 0)) +>call : Symbol(CallableFunction.call, Decl(lib.es5.d.ts, --, --)) +>undefined : Symbol(undefined) + +export let a = (arg: string) => 0; +>a : Symbol(a, Decl(file1.ts, 5, 10)) +>arg : Symbol(arg, Decl(file1.ts, 5, 16)) + +export let b = (arg: unknown) => 0; +>b : Symbol(b, Decl(file1.ts, 6, 10)) +>arg : Symbol(arg, Decl(file1.ts, 6, 16)) + +a = b; +>a : Symbol(a, Decl(file1.ts, 5, 10)) +>b : Symbol(b, Decl(file1.ts, 6, 10)) + +b = a; +>b : Symbol(b, Decl(file1.ts, 6, 10)) +>a : Symbol(a, Decl(file1.ts, 5, 10)) + +export class A { +>A : Symbol(A, Decl(file1.ts, 9, 6)) + + prop: string; +>prop : Symbol(A.prop, Decl(file1.ts, 11, 16)) + + constructor() {} +} + +declare var c: { member?: string }; +>c : Symbol(c, Decl(file1.ts, 16, 11)) +>member : Symbol(member, Decl(file1.ts, 16, 16)) + +c.member.charAt(0); +>c.member.charAt : Symbol(String.charAt, Decl(lib.es5.d.ts, --, --)) +>c.member : Symbol(member, Decl(file1.ts, 16, 16)) +>c : Symbol(c, Decl(file1.ts, 16, 11)) +>member : Symbol(member, Decl(file1.ts, 16, 16)) +>charAt : Symbol(String.charAt, Decl(lib.es5.d.ts, --, --)) + +=== tests/cases/conformance/pragma/strict/file2.ts === +// @ts-strict true +export function f1(x: string) {} +>f1 : Symbol(f1, Decl(file2.ts, 0, 0)) +>x : Symbol(x, Decl(file2.ts, 1, 19)) + +f1.call(undefined, 42); // wrong +>f1.call : Symbol(CallableFunction.call, Decl(lib.es5.d.ts, --, --)) +>f1 : Symbol(f1, Decl(file2.ts, 0, 0)) +>call : Symbol(CallableFunction.call, Decl(lib.es5.d.ts, --, --)) +>undefined : Symbol(undefined) + +f1.call(undefined, "ok"); // right +>f1.call : Symbol(CallableFunction.call, Decl(lib.es5.d.ts, --, --)) +>f1 : Symbol(f1, Decl(file2.ts, 0, 0)) +>call : Symbol(CallableFunction.call, Decl(lib.es5.d.ts, --, --)) +>undefined : Symbol(undefined) + +export let a = (arg: string) => 0; +>a : Symbol(a, Decl(file2.ts, 5, 10)) +>arg : Symbol(arg, Decl(file2.ts, 5, 16)) + +export let b = (arg: unknown) => 0; +>b : Symbol(b, Decl(file2.ts, 6, 10)) +>arg : Symbol(arg, Decl(file2.ts, 6, 16)) + +a = b; +>a : Symbol(a, Decl(file2.ts, 5, 10)) +>b : Symbol(b, Decl(file2.ts, 6, 10)) + +b = a; +>b : Symbol(b, Decl(file2.ts, 6, 10)) +>a : Symbol(a, Decl(file2.ts, 5, 10)) + +export class A { +>A : Symbol(A, Decl(file2.ts, 9, 6)) + + prop: string; +>prop : Symbol(A.prop, Decl(file2.ts, 11, 16)) + + constructor() {} +} + +declare var c: { member?: string }; +>c : Symbol(c, Decl(file2.ts, 16, 11)) +>member : Symbol(member, Decl(file2.ts, 16, 16)) + +c.member.charAt(0); +>c.member.charAt : Symbol(String.charAt, Decl(lib.es5.d.ts, --, --)) +>c.member : Symbol(member, Decl(file2.ts, 16, 16)) +>c : Symbol(c, Decl(file2.ts, 16, 11)) +>member : Symbol(member, Decl(file2.ts, 16, 16)) +>charAt : Symbol(String.charAt, Decl(lib.es5.d.ts, --, --)) + +=== tests/cases/conformance/pragma/strict/file3.ts === +// @ts-strict false +export function f1(x: string) {} +>f1 : Symbol(f1, Decl(file3.ts, 0, 0)) +>x : Symbol(x, Decl(file3.ts, 1, 19)) + +f1.call(undefined, 42); // wrong +>f1.call : Symbol(Function.call, Decl(lib.es5.d.ts, --, --)) +>f1 : Symbol(f1, Decl(file3.ts, 0, 0)) +>call : Symbol(Function.call, Decl(lib.es5.d.ts, --, --)) +>undefined : Symbol(undefined) + +f1.call(undefined, "ok"); // right +>f1.call : Symbol(Function.call, Decl(lib.es5.d.ts, --, --)) +>f1 : Symbol(f1, Decl(file3.ts, 0, 0)) +>call : Symbol(Function.call, Decl(lib.es5.d.ts, --, --)) +>undefined : Symbol(undefined) + +export let a = (arg: string) => 0; +>a : Symbol(a, Decl(file3.ts, 5, 10)) +>arg : Symbol(arg, Decl(file3.ts, 5, 16)) + +export let b = (arg: unknown) => 0; +>b : Symbol(b, Decl(file3.ts, 6, 10)) +>arg : Symbol(arg, Decl(file3.ts, 6, 16)) + +a = b; +>a : Symbol(a, Decl(file3.ts, 5, 10)) +>b : Symbol(b, Decl(file3.ts, 6, 10)) + +b = a; +>b : Symbol(b, Decl(file3.ts, 6, 10)) +>a : Symbol(a, Decl(file3.ts, 5, 10)) + +export class A { +>A : Symbol(A, Decl(file3.ts, 9, 6)) + + prop: string; +>prop : Symbol(A.prop, Decl(file3.ts, 11, 16)) + + constructor() {} +} + +declare var c: { member?: string }; +>c : Symbol(c, Decl(file3.ts, 16, 11)) +>member : Symbol(member, Decl(file3.ts, 16, 16)) + +c.member.charAt(0); +>c.member.charAt : Symbol(String.charAt, Decl(lib.es5.d.ts, --, --)) +>c.member : Symbol(member, Decl(file3.ts, 16, 16)) +>c : Symbol(c, Decl(file3.ts, 16, 11)) +>member : Symbol(member, Decl(file3.ts, 16, 16)) +>charAt : Symbol(String.charAt, Decl(lib.es5.d.ts, --, --)) + +=== tests/cases/conformance/pragma/strict/file4.ts === +export function f1(x: string) {} +>f1 : Symbol(f1, Decl(file4.ts, 0, 0)) +>x : Symbol(x, Decl(file4.ts, 0, 19)) + +f1.call(undefined, 42); // wrong +>f1.call : Symbol(CallableFunction.call, Decl(lib.es5.d.ts, --, --)) +>f1 : Symbol(f1, Decl(file4.ts, 0, 0)) +>call : Symbol(CallableFunction.call, Decl(lib.es5.d.ts, --, --)) +>undefined : Symbol(undefined) + +f1.call(undefined, "ok"); // right +>f1.call : Symbol(CallableFunction.call, Decl(lib.es5.d.ts, --, --)) +>f1 : Symbol(f1, Decl(file4.ts, 0, 0)) +>call : Symbol(CallableFunction.call, Decl(lib.es5.d.ts, --, --)) +>undefined : Symbol(undefined) + +export let a = (arg: string) => 0; +>a : Symbol(a, Decl(file4.ts, 4, 10)) +>arg : Symbol(arg, Decl(file4.ts, 4, 16)) + +export let b = (arg: unknown) => 0; +>b : Symbol(b, Decl(file4.ts, 5, 10)) +>arg : Symbol(arg, Decl(file4.ts, 5, 16)) + +a = b; +>a : Symbol(a, Decl(file4.ts, 4, 10)) +>b : Symbol(b, Decl(file4.ts, 5, 10)) + +b = a; +>b : Symbol(b, Decl(file4.ts, 5, 10)) +>a : Symbol(a, Decl(file4.ts, 4, 10)) + +export class A { +>A : Symbol(A, Decl(file4.ts, 8, 6)) + + prop: string; +>prop : Symbol(A.prop, Decl(file4.ts, 10, 16)) + + constructor() {} +} + +declare var c: { member?: string }; +>c : Symbol(c, Decl(file4.ts, 15, 11)) +>member : Symbol(member, Decl(file4.ts, 15, 16)) + +c.member.charAt(0); +>c.member.charAt : Symbol(String.charAt, Decl(lib.es5.d.ts, --, --)) +>c.member : Symbol(member, Decl(file4.ts, 15, 16)) +>c : Symbol(c, Decl(file4.ts, 15, 11)) +>member : Symbol(member, Decl(file4.ts, 15, 16)) +>charAt : Symbol(String.charAt, Decl(lib.es5.d.ts, --, --)) + diff --git a/tests/baselines/reference/strictPragma2.types b/tests/baselines/reference/strictPragma2.types new file mode 100644 index 0000000000000..ac8c00b2396e0 --- /dev/null +++ b/tests/baselines/reference/strictPragma2.types @@ -0,0 +1,263 @@ +=== tests/cases/conformance/pragma/strict/file1.ts === +// @ts-strict +export function f1(x: string) {} +>f1 : (x: string) => void +>x : string + +f1.call(undefined, 42); // wrong +>f1.call(undefined, 42) : void +>f1.call : (this: (this: T, ...args: A) => R, thisArg: T, ...args: A) => R +>f1 : (x: string) => void +>call : (this: (this: T, ...args: A) => R, thisArg: T, ...args: A) => R +>undefined : undefined +>42 : 42 + +f1.call(undefined, "ok"); // right +>f1.call(undefined, "ok") : void +>f1.call : (this: (this: T, ...args: A) => R, thisArg: T, ...args: A) => R +>f1 : (x: string) => void +>call : (this: (this: T, ...args: A) => R, thisArg: T, ...args: A) => R +>undefined : undefined +>"ok" : "ok" + +export let a = (arg: string) => 0; +>a : (arg: string) => number +>(arg: string) => 0 : (arg: string) => number +>arg : string +>0 : 0 + +export let b = (arg: unknown) => 0; +>b : (arg: unknown) => number +>(arg: unknown) => 0 : (arg: unknown) => number +>arg : unknown +>0 : 0 + +a = b; +>a = b : (arg: unknown) => number +>a : (arg: string) => number +>b : (arg: unknown) => number + +b = a; +>b = a : (arg: string) => number +>b : (arg: unknown) => number +>a : (arg: string) => number + +export class A { +>A : A + + prop: string; +>prop : string + + constructor() {} +} + +declare var c: { member?: string }; +>c : { member?: string | undefined; } +>member : string | undefined + +c.member.charAt(0); +>c.member.charAt(0) : string +>c.member.charAt : (pos: number) => string +>c.member : string | undefined +>c : { member?: string | undefined; } +>member : string | undefined +>charAt : (pos: number) => string +>0 : 0 + +=== tests/cases/conformance/pragma/strict/file2.ts === +// @ts-strict true +export function f1(x: string) {} +>f1 : (x: string) => void +>x : string + +f1.call(undefined, 42); // wrong +>f1.call(undefined, 42) : void +>f1.call : (this: (this: T, ...args: A) => R, thisArg: T, ...args: A) => R +>f1 : (x: string) => void +>call : (this: (this: T, ...args: A) => R, thisArg: T, ...args: A) => R +>undefined : undefined +>42 : 42 + +f1.call(undefined, "ok"); // right +>f1.call(undefined, "ok") : void +>f1.call : (this: (this: T, ...args: A) => R, thisArg: T, ...args: A) => R +>f1 : (x: string) => void +>call : (this: (this: T, ...args: A) => R, thisArg: T, ...args: A) => R +>undefined : undefined +>"ok" : "ok" + +export let a = (arg: string) => 0; +>a : (arg: string) => number +>(arg: string) => 0 : (arg: string) => number +>arg : string +>0 : 0 + +export let b = (arg: unknown) => 0; +>b : (arg: unknown) => number +>(arg: unknown) => 0 : (arg: unknown) => number +>arg : unknown +>0 : 0 + +a = b; +>a = b : (arg: unknown) => number +>a : (arg: string) => number +>b : (arg: unknown) => number + +b = a; +>b = a : (arg: string) => number +>b : (arg: unknown) => number +>a : (arg: string) => number + +export class A { +>A : A + + prop: string; +>prop : string + + constructor() {} +} + +declare var c: { member?: string }; +>c : { member?: string | undefined; } +>member : string | undefined + +c.member.charAt(0); +>c.member.charAt(0) : string +>c.member.charAt : (pos: number) => string +>c.member : string | undefined +>c : { member?: string | undefined; } +>member : string | undefined +>charAt : (pos: number) => string +>0 : 0 + +=== tests/cases/conformance/pragma/strict/file3.ts === +// @ts-strict false +export function f1(x: string) {} +>f1 : (x: string) => void +>x : string + +f1.call(undefined, 42); // wrong +>f1.call(undefined, 42) : any +>f1.call : (this: Function, thisArg: any, ...argArray: any[]) => any +>f1 : (x: string) => void +>call : (this: Function, thisArg: any, ...argArray: any[]) => any +>undefined : undefined +>42 : 42 + +f1.call(undefined, "ok"); // right +>f1.call(undefined, "ok") : any +>f1.call : (this: Function, thisArg: any, ...argArray: any[]) => any +>f1 : (x: string) => void +>call : (this: Function, thisArg: any, ...argArray: any[]) => any +>undefined : undefined +>"ok" : "ok" + +export let a = (arg: string) => 0; +>a : (arg: string) => number +>(arg: string) => 0 : (arg: string) => number +>arg : string +>0 : 0 + +export let b = (arg: unknown) => 0; +>b : (arg: unknown) => number +>(arg: unknown) => 0 : (arg: unknown) => number +>arg : unknown +>0 : 0 + +a = b; +>a = b : (arg: unknown) => number +>a : (arg: string) => number +>b : (arg: unknown) => number + +b = a; +>b = a : (arg: string) => number +>b : (arg: unknown) => number +>a : (arg: string) => number + +export class A { +>A : A + + prop: string; +>prop : string + + constructor() {} +} + +declare var c: { member?: string }; +>c : { member?: string; } +>member : string + +c.member.charAt(0); +>c.member.charAt(0) : string +>c.member.charAt : (pos: number) => string +>c.member : string +>c : { member?: string; } +>member : string +>charAt : (pos: number) => string +>0 : 0 + +=== tests/cases/conformance/pragma/strict/file4.ts === +export function f1(x: string) {} +>f1 : (x: string) => void +>x : string + +f1.call(undefined, 42); // wrong +>f1.call(undefined, 42) : void +>f1.call : (this: (this: T, ...args: A) => R, thisArg: T, ...args: A) => R +>f1 : (x: string) => void +>call : (this: (this: T, ...args: A) => R, thisArg: T, ...args: A) => R +>undefined : undefined +>42 : 42 + +f1.call(undefined, "ok"); // right +>f1.call(undefined, "ok") : void +>f1.call : (this: (this: T, ...args: A) => R, thisArg: T, ...args: A) => R +>f1 : (x: string) => void +>call : (this: (this: T, ...args: A) => R, thisArg: T, ...args: A) => R +>undefined : undefined +>"ok" : "ok" + +export let a = (arg: string) => 0; +>a : (arg: string) => number +>(arg: string) => 0 : (arg: string) => number +>arg : string +>0 : 0 + +export let b = (arg: unknown) => 0; +>b : (arg: unknown) => number +>(arg: unknown) => 0 : (arg: unknown) => number +>arg : unknown +>0 : 0 + +a = b; +>a = b : (arg: unknown) => number +>a : (arg: string) => number +>b : (arg: unknown) => number + +b = a; +>b = a : (arg: string) => number +>b : (arg: unknown) => number +>a : (arg: string) => number + +export class A { +>A : A + + prop: string; +>prop : string + + constructor() {} +} + +declare var c: { member?: string }; +>c : { member?: string | undefined; } +>member : string | undefined + +c.member.charAt(0); +>c.member.charAt(0) : string +>c.member.charAt : (pos: number) => string +>c.member : string | undefined +>c : { member?: string | undefined; } +>member : string | undefined +>charAt : (pos: number) => string +>0 : 0 + diff --git a/tests/baselines/reference/strictPragma3.errors.txt b/tests/baselines/reference/strictPragma3.errors.txt new file mode 100644 index 0000000000000..5e3671148b99c --- /dev/null +++ b/tests/baselines/reference/strictPragma3.errors.txt @@ -0,0 +1,33 @@ +tests/cases/conformance/pragma/strict/file1.ts(4,20): error TS2345: Argument of type 'number' is not assignable to parameter of type 'string'. +tests/cases/conformance/pragma/strict/file1.ts(11,1): error TS2322: Type '(arg: string) => number' is not assignable to type '(arg: unknown) => number'. + Types of parameters 'arg' and 'arg' are incompatible. + Type 'unknown' is not assignable to type 'string'. + + +==== tests/cases/conformance/pragma/strict/file1.ts (2 errors) ==== + // @ts-strict + // @ts-strictNullChecks false + export function f1(x: string) {} + f1.call(undefined, 42); // wrong + ~~ +!!! error TS2345: Argument of type 'number' is not assignable to parameter of type 'string'. + f1.call(undefined, "ok"); // right + + export let a = (arg: string) => 0; + export let b = (arg: unknown) => 0; + + a = b; + b = a; + ~ +!!! error TS2322: Type '(arg: string) => number' is not assignable to type '(arg: unknown) => number'. +!!! error TS2322: Types of parameters 'arg' and 'arg' are incompatible. +!!! error TS2322: Type 'unknown' is not assignable to type 'string'. + + export class A { + prop: string; + constructor() {} + } + + declare var c: { member?: string }; + c.member.charAt(0); + \ No newline at end of file diff --git a/tests/baselines/reference/strictPragma3.js b/tests/baselines/reference/strictPragma3.js new file mode 100644 index 0000000000000..7a8c2aa095d0f --- /dev/null +++ b/tests/baselines/reference/strictPragma3.js @@ -0,0 +1,45 @@ +//// [file1.ts] +// @ts-strict +// @ts-strictNullChecks false +export function f1(x: string) {} +f1.call(undefined, 42); // wrong +f1.call(undefined, "ok"); // right + +export let a = (arg: string) => 0; +export let b = (arg: unknown) => 0; + +a = b; +b = a; + +export class A { + prop: string; + constructor() {} +} + +declare var c: { member?: string }; +c.member.charAt(0); + + +//// [file1.js] +"use strict"; +exports.__esModule = true; +exports.A = exports.b = exports.a = exports.f1 = void 0; +// @ts-strict +// @ts-strictNullChecks false +function f1(x) { } +exports.f1 = f1; +f1.call(undefined, 42); // wrong +f1.call(undefined, "ok"); // right +var a = function (arg) { return 0; }; +exports.a = a; +var b = function (arg) { return 0; }; +exports.b = b; +exports.a = exports.b; +exports.b = exports.a; +var A = /** @class */ (function () { + function A() { + } + return A; +}()); +exports.A = A; +c.member.charAt(0); diff --git a/tests/baselines/reference/strictPragma3.symbols b/tests/baselines/reference/strictPragma3.symbols new file mode 100644 index 0000000000000..75b8eb18c8eeb --- /dev/null +++ b/tests/baselines/reference/strictPragma3.symbols @@ -0,0 +1,55 @@ +=== tests/cases/conformance/pragma/strict/file1.ts === +// @ts-strict +// @ts-strictNullChecks false +export function f1(x: string) {} +>f1 : Symbol(f1, Decl(file1.ts, 0, 0)) +>x : Symbol(x, Decl(file1.ts, 2, 19)) + +f1.call(undefined, 42); // wrong +>f1.call : Symbol(CallableFunction.call, Decl(lib.es5.d.ts, --, --)) +>f1 : Symbol(f1, Decl(file1.ts, 0, 0)) +>call : Symbol(CallableFunction.call, Decl(lib.es5.d.ts, --, --)) +>undefined : Symbol(undefined) + +f1.call(undefined, "ok"); // right +>f1.call : Symbol(CallableFunction.call, Decl(lib.es5.d.ts, --, --)) +>f1 : Symbol(f1, Decl(file1.ts, 0, 0)) +>call : Symbol(CallableFunction.call, Decl(lib.es5.d.ts, --, --)) +>undefined : Symbol(undefined) + +export let a = (arg: string) => 0; +>a : Symbol(a, Decl(file1.ts, 6, 10)) +>arg : Symbol(arg, Decl(file1.ts, 6, 16)) + +export let b = (arg: unknown) => 0; +>b : Symbol(b, Decl(file1.ts, 7, 10)) +>arg : Symbol(arg, Decl(file1.ts, 7, 16)) + +a = b; +>a : Symbol(a, Decl(file1.ts, 6, 10)) +>b : Symbol(b, Decl(file1.ts, 7, 10)) + +b = a; +>b : Symbol(b, Decl(file1.ts, 7, 10)) +>a : Symbol(a, Decl(file1.ts, 6, 10)) + +export class A { +>A : Symbol(A, Decl(file1.ts, 10, 6)) + + prop: string; +>prop : Symbol(A.prop, Decl(file1.ts, 12, 16)) + + constructor() {} +} + +declare var c: { member?: string }; +>c : Symbol(c, Decl(file1.ts, 17, 11)) +>member : Symbol(member, Decl(file1.ts, 17, 16)) + +c.member.charAt(0); +>c.member.charAt : Symbol(String.charAt, Decl(lib.es5.d.ts, --, --)) +>c.member : Symbol(member, Decl(file1.ts, 17, 16)) +>c : Symbol(c, Decl(file1.ts, 17, 11)) +>member : Symbol(member, Decl(file1.ts, 17, 16)) +>charAt : Symbol(String.charAt, Decl(lib.es5.d.ts, --, --)) + diff --git a/tests/baselines/reference/strictPragma3.types b/tests/baselines/reference/strictPragma3.types new file mode 100644 index 0000000000000..27e0a7cb546be --- /dev/null +++ b/tests/baselines/reference/strictPragma3.types @@ -0,0 +1,67 @@ +=== tests/cases/conformance/pragma/strict/file1.ts === +// @ts-strict +// @ts-strictNullChecks false +export function f1(x: string) {} +>f1 : (x: string) => void +>x : string + +f1.call(undefined, 42); // wrong +>f1.call(undefined, 42) : void +>f1.call : (this: (this: T, ...args: A) => R, thisArg: T, ...args: A) => R +>f1 : (x: string) => void +>call : (this: (this: T, ...args: A) => R, thisArg: T, ...args: A) => R +>undefined : undefined +>42 : 42 + +f1.call(undefined, "ok"); // right +>f1.call(undefined, "ok") : void +>f1.call : (this: (this: T, ...args: A) => R, thisArg: T, ...args: A) => R +>f1 : (x: string) => void +>call : (this: (this: T, ...args: A) => R, thisArg: T, ...args: A) => R +>undefined : undefined +>"ok" : "ok" + +export let a = (arg: string) => 0; +>a : (arg: string) => number +>(arg: string) => 0 : (arg: string) => number +>arg : string +>0 : 0 + +export let b = (arg: unknown) => 0; +>b : (arg: unknown) => number +>(arg: unknown) => 0 : (arg: unknown) => number +>arg : unknown +>0 : 0 + +a = b; +>a = b : (arg: unknown) => number +>a : (arg: string) => number +>b : (arg: unknown) => number + +b = a; +>b = a : (arg: string) => number +>b : (arg: unknown) => number +>a : (arg: string) => number + +export class A { +>A : A + + prop: string; +>prop : string + + constructor() {} +} + +declare var c: { member?: string }; +>c : { member?: string; } +>member : string + +c.member.charAt(0); +>c.member.charAt(0) : string +>c.member.charAt : (pos: number) => string +>c.member : string +>c : { member?: string; } +>member : string +>charAt : (pos: number) => string +>0 : 0 + diff --git a/tests/baselines/reference/strictPragma4.errors.txt b/tests/baselines/reference/strictPragma4.errors.txt new file mode 100644 index 0000000000000..1f4d0a490097e --- /dev/null +++ b/tests/baselines/reference/strictPragma4.errors.txt @@ -0,0 +1,36 @@ +tests/cases/conformance/pragma/strict/file2.ts(11,1): error TS2322: Type '(arg: string) => number' is not assignable to type '(arg: unknown) => number'. + Types of parameters 'arg' and 'arg' are incompatible. + Type 'unknown' is not assignable to type 'string'. +tests/cases/conformance/pragma/strict/file2.ts(14,5): error TS2564: Property 'prop' has no initializer and is not definitely assigned in the constructor. +tests/cases/conformance/pragma/strict/file2.ts(19,1): error TS2532: Object is possibly 'undefined'. + + +==== tests/cases/conformance/pragma/strict/file2.ts (3 errors) ==== + // @ts-strict + // @ts-strictBindCallApply false + export function f1(x: string) {} + f1.call(undefined, 42); // wrong + f1.call(undefined, "ok"); // right + + export let a = (arg: string) => 0; + export let b = (arg: unknown) => 0; + + a = b; + b = a; + ~ +!!! error TS2322: Type '(arg: string) => number' is not assignable to type '(arg: unknown) => number'. +!!! error TS2322: Types of parameters 'arg' and 'arg' are incompatible. +!!! error TS2322: Type 'unknown' is not assignable to type 'string'. + + export class A { + prop: string; + ~~~~ +!!! error TS2564: Property 'prop' has no initializer and is not definitely assigned in the constructor. + constructor() {} + } + + declare var c: { member?: string }; + c.member.charAt(0); + ~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + \ No newline at end of file diff --git a/tests/baselines/reference/strictPragma4.js b/tests/baselines/reference/strictPragma4.js new file mode 100644 index 0000000000000..3de937a10554b --- /dev/null +++ b/tests/baselines/reference/strictPragma4.js @@ -0,0 +1,45 @@ +//// [file2.ts] +// @ts-strict +// @ts-strictBindCallApply false +export function f1(x: string) {} +f1.call(undefined, 42); // wrong +f1.call(undefined, "ok"); // right + +export let a = (arg: string) => 0; +export let b = (arg: unknown) => 0; + +a = b; +b = a; + +export class A { + prop: string; + constructor() {} +} + +declare var c: { member?: string }; +c.member.charAt(0); + + +//// [file2.js] +"use strict"; +exports.__esModule = true; +exports.A = exports.b = exports.a = exports.f1 = void 0; +// @ts-strict +// @ts-strictBindCallApply false +function f1(x) { } +exports.f1 = f1; +f1.call(undefined, 42); // wrong +f1.call(undefined, "ok"); // right +var a = function (arg) { return 0; }; +exports.a = a; +var b = function (arg) { return 0; }; +exports.b = b; +exports.a = exports.b; +exports.b = exports.a; +var A = /** @class */ (function () { + function A() { + } + return A; +}()); +exports.A = A; +c.member.charAt(0); diff --git a/tests/baselines/reference/strictPragma4.symbols b/tests/baselines/reference/strictPragma4.symbols new file mode 100644 index 0000000000000..8b9104030a4a3 --- /dev/null +++ b/tests/baselines/reference/strictPragma4.symbols @@ -0,0 +1,55 @@ +=== tests/cases/conformance/pragma/strict/file2.ts === +// @ts-strict +// @ts-strictBindCallApply false +export function f1(x: string) {} +>f1 : Symbol(f1, Decl(file2.ts, 0, 0)) +>x : Symbol(x, Decl(file2.ts, 2, 19)) + +f1.call(undefined, 42); // wrong +>f1.call : Symbol(Function.call, Decl(lib.es5.d.ts, --, --)) +>f1 : Symbol(f1, Decl(file2.ts, 0, 0)) +>call : Symbol(Function.call, Decl(lib.es5.d.ts, --, --)) +>undefined : Symbol(undefined) + +f1.call(undefined, "ok"); // right +>f1.call : Symbol(Function.call, Decl(lib.es5.d.ts, --, --)) +>f1 : Symbol(f1, Decl(file2.ts, 0, 0)) +>call : Symbol(Function.call, Decl(lib.es5.d.ts, --, --)) +>undefined : Symbol(undefined) + +export let a = (arg: string) => 0; +>a : Symbol(a, Decl(file2.ts, 6, 10)) +>arg : Symbol(arg, Decl(file2.ts, 6, 16)) + +export let b = (arg: unknown) => 0; +>b : Symbol(b, Decl(file2.ts, 7, 10)) +>arg : Symbol(arg, Decl(file2.ts, 7, 16)) + +a = b; +>a : Symbol(a, Decl(file2.ts, 6, 10)) +>b : Symbol(b, Decl(file2.ts, 7, 10)) + +b = a; +>b : Symbol(b, Decl(file2.ts, 7, 10)) +>a : Symbol(a, Decl(file2.ts, 6, 10)) + +export class A { +>A : Symbol(A, Decl(file2.ts, 10, 6)) + + prop: string; +>prop : Symbol(A.prop, Decl(file2.ts, 12, 16)) + + constructor() {} +} + +declare var c: { member?: string }; +>c : Symbol(c, Decl(file2.ts, 17, 11)) +>member : Symbol(member, Decl(file2.ts, 17, 16)) + +c.member.charAt(0); +>c.member.charAt : Symbol(String.charAt, Decl(lib.es5.d.ts, --, --)) +>c.member : Symbol(member, Decl(file2.ts, 17, 16)) +>c : Symbol(c, Decl(file2.ts, 17, 11)) +>member : Symbol(member, Decl(file2.ts, 17, 16)) +>charAt : Symbol(String.charAt, Decl(lib.es5.d.ts, --, --)) + diff --git a/tests/baselines/reference/strictPragma4.types b/tests/baselines/reference/strictPragma4.types new file mode 100644 index 0000000000000..0c30849b5f80b --- /dev/null +++ b/tests/baselines/reference/strictPragma4.types @@ -0,0 +1,67 @@ +=== tests/cases/conformance/pragma/strict/file2.ts === +// @ts-strict +// @ts-strictBindCallApply false +export function f1(x: string) {} +>f1 : (x: string) => void +>x : string + +f1.call(undefined, 42); // wrong +>f1.call(undefined, 42) : any +>f1.call : (this: Function, thisArg: any, ...argArray: any[]) => any +>f1 : (x: string) => void +>call : (this: Function, thisArg: any, ...argArray: any[]) => any +>undefined : undefined +>42 : 42 + +f1.call(undefined, "ok"); // right +>f1.call(undefined, "ok") : any +>f1.call : (this: Function, thisArg: any, ...argArray: any[]) => any +>f1 : (x: string) => void +>call : (this: Function, thisArg: any, ...argArray: any[]) => any +>undefined : undefined +>"ok" : "ok" + +export let a = (arg: string) => 0; +>a : (arg: string) => number +>(arg: string) => 0 : (arg: string) => number +>arg : string +>0 : 0 + +export let b = (arg: unknown) => 0; +>b : (arg: unknown) => number +>(arg: unknown) => 0 : (arg: unknown) => number +>arg : unknown +>0 : 0 + +a = b; +>a = b : (arg: unknown) => number +>a : (arg: string) => number +>b : (arg: unknown) => number + +b = a; +>b = a : (arg: string) => number +>b : (arg: unknown) => number +>a : (arg: string) => number + +export class A { +>A : A + + prop: string; +>prop : string + + constructor() {} +} + +declare var c: { member?: string }; +>c : { member?: string | undefined; } +>member : string | undefined + +c.member.charAt(0); +>c.member.charAt(0) : string +>c.member.charAt : (pos: number) => string +>c.member : string | undefined +>c : { member?: string | undefined; } +>member : string | undefined +>charAt : (pos: number) => string +>0 : 0 + diff --git a/tests/baselines/reference/strictPragma5.errors.txt b/tests/baselines/reference/strictPragma5.errors.txt new file mode 100644 index 0000000000000..3fe951cb7210a --- /dev/null +++ b/tests/baselines/reference/strictPragma5.errors.txt @@ -0,0 +1,36 @@ +tests/cases/conformance/pragma/strict/file3.ts(4,20): error TS2345: Argument of type 'number' is not assignable to parameter of type 'string'. +tests/cases/conformance/pragma/strict/file3.ts(11,1): error TS2322: Type '(arg: string) => number' is not assignable to type '(arg: unknown) => number'. + Types of parameters 'arg' and 'arg' are incompatible. + Type 'unknown' is not assignable to type 'string'. +tests/cases/conformance/pragma/strict/file3.ts(19,1): error TS2532: Object is possibly 'undefined'. + + +==== tests/cases/conformance/pragma/strict/file3.ts (3 errors) ==== + // @ts-strict + // @ts-strictPropertyInitialization false + export function f1(x: string) {} + f1.call(undefined, 42); // wrong + ~~ +!!! error TS2345: Argument of type 'number' is not assignable to parameter of type 'string'. + f1.call(undefined, "ok"); // right + + export let a = (arg: string) => 0; + export let b = (arg: unknown) => 0; + + a = b; + b = a; + ~ +!!! error TS2322: Type '(arg: string) => number' is not assignable to type '(arg: unknown) => number'. +!!! error TS2322: Types of parameters 'arg' and 'arg' are incompatible. +!!! error TS2322: Type 'unknown' is not assignable to type 'string'. + + export class A { + prop: string; + constructor() {} + } + + declare var c: { member?: string }; + c.member.charAt(0); + ~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + \ No newline at end of file diff --git a/tests/baselines/reference/strictPragma5.js b/tests/baselines/reference/strictPragma5.js new file mode 100644 index 0000000000000..ce1007cfd26f0 --- /dev/null +++ b/tests/baselines/reference/strictPragma5.js @@ -0,0 +1,45 @@ +//// [file3.ts] +// @ts-strict +// @ts-strictPropertyInitialization false +export function f1(x: string) {} +f1.call(undefined, 42); // wrong +f1.call(undefined, "ok"); // right + +export let a = (arg: string) => 0; +export let b = (arg: unknown) => 0; + +a = b; +b = a; + +export class A { + prop: string; + constructor() {} +} + +declare var c: { member?: string }; +c.member.charAt(0); + + +//// [file3.js] +"use strict"; +exports.__esModule = true; +exports.A = exports.b = exports.a = exports.f1 = void 0; +// @ts-strict +// @ts-strictPropertyInitialization false +function f1(x) { } +exports.f1 = f1; +f1.call(undefined, 42); // wrong +f1.call(undefined, "ok"); // right +var a = function (arg) { return 0; }; +exports.a = a; +var b = function (arg) { return 0; }; +exports.b = b; +exports.a = exports.b; +exports.b = exports.a; +var A = /** @class */ (function () { + function A() { + } + return A; +}()); +exports.A = A; +c.member.charAt(0); diff --git a/tests/baselines/reference/strictPragma5.symbols b/tests/baselines/reference/strictPragma5.symbols new file mode 100644 index 0000000000000..d3f39c79fe588 --- /dev/null +++ b/tests/baselines/reference/strictPragma5.symbols @@ -0,0 +1,55 @@ +=== tests/cases/conformance/pragma/strict/file3.ts === +// @ts-strict +// @ts-strictPropertyInitialization false +export function f1(x: string) {} +>f1 : Symbol(f1, Decl(file3.ts, 0, 0)) +>x : Symbol(x, Decl(file3.ts, 2, 19)) + +f1.call(undefined, 42); // wrong +>f1.call : Symbol(CallableFunction.call, Decl(lib.es5.d.ts, --, --)) +>f1 : Symbol(f1, Decl(file3.ts, 0, 0)) +>call : Symbol(CallableFunction.call, Decl(lib.es5.d.ts, --, --)) +>undefined : Symbol(undefined) + +f1.call(undefined, "ok"); // right +>f1.call : Symbol(CallableFunction.call, Decl(lib.es5.d.ts, --, --)) +>f1 : Symbol(f1, Decl(file3.ts, 0, 0)) +>call : Symbol(CallableFunction.call, Decl(lib.es5.d.ts, --, --)) +>undefined : Symbol(undefined) + +export let a = (arg: string) => 0; +>a : Symbol(a, Decl(file3.ts, 6, 10)) +>arg : Symbol(arg, Decl(file3.ts, 6, 16)) + +export let b = (arg: unknown) => 0; +>b : Symbol(b, Decl(file3.ts, 7, 10)) +>arg : Symbol(arg, Decl(file3.ts, 7, 16)) + +a = b; +>a : Symbol(a, Decl(file3.ts, 6, 10)) +>b : Symbol(b, Decl(file3.ts, 7, 10)) + +b = a; +>b : Symbol(b, Decl(file3.ts, 7, 10)) +>a : Symbol(a, Decl(file3.ts, 6, 10)) + +export class A { +>A : Symbol(A, Decl(file3.ts, 10, 6)) + + prop: string; +>prop : Symbol(A.prop, Decl(file3.ts, 12, 16)) + + constructor() {} +} + +declare var c: { member?: string }; +>c : Symbol(c, Decl(file3.ts, 17, 11)) +>member : Symbol(member, Decl(file3.ts, 17, 16)) + +c.member.charAt(0); +>c.member.charAt : Symbol(String.charAt, Decl(lib.es5.d.ts, --, --)) +>c.member : Symbol(member, Decl(file3.ts, 17, 16)) +>c : Symbol(c, Decl(file3.ts, 17, 11)) +>member : Symbol(member, Decl(file3.ts, 17, 16)) +>charAt : Symbol(String.charAt, Decl(lib.es5.d.ts, --, --)) + diff --git a/tests/baselines/reference/strictPragma5.types b/tests/baselines/reference/strictPragma5.types new file mode 100644 index 0000000000000..394c39caab1c6 --- /dev/null +++ b/tests/baselines/reference/strictPragma5.types @@ -0,0 +1,67 @@ +=== tests/cases/conformance/pragma/strict/file3.ts === +// @ts-strict +// @ts-strictPropertyInitialization false +export function f1(x: string) {} +>f1 : (x: string) => void +>x : string + +f1.call(undefined, 42); // wrong +>f1.call(undefined, 42) : void +>f1.call : (this: (this: T, ...args: A) => R, thisArg: T, ...args: A) => R +>f1 : (x: string) => void +>call : (this: (this: T, ...args: A) => R, thisArg: T, ...args: A) => R +>undefined : undefined +>42 : 42 + +f1.call(undefined, "ok"); // right +>f1.call(undefined, "ok") : void +>f1.call : (this: (this: T, ...args: A) => R, thisArg: T, ...args: A) => R +>f1 : (x: string) => void +>call : (this: (this: T, ...args: A) => R, thisArg: T, ...args: A) => R +>undefined : undefined +>"ok" : "ok" + +export let a = (arg: string) => 0; +>a : (arg: string) => number +>(arg: string) => 0 : (arg: string) => number +>arg : string +>0 : 0 + +export let b = (arg: unknown) => 0; +>b : (arg: unknown) => number +>(arg: unknown) => 0 : (arg: unknown) => number +>arg : unknown +>0 : 0 + +a = b; +>a = b : (arg: unknown) => number +>a : (arg: string) => number +>b : (arg: unknown) => number + +b = a; +>b = a : (arg: string) => number +>b : (arg: unknown) => number +>a : (arg: string) => number + +export class A { +>A : A + + prop: string; +>prop : string + + constructor() {} +} + +declare var c: { member?: string }; +>c : { member?: string | undefined; } +>member : string | undefined + +c.member.charAt(0); +>c.member.charAt(0) : string +>c.member.charAt : (pos: number) => string +>c.member : string | undefined +>c : { member?: string | undefined; } +>member : string | undefined +>charAt : (pos: number) => string +>0 : 0 + diff --git a/tests/baselines/reference/strictPragma6.errors.txt b/tests/baselines/reference/strictPragma6.errors.txt new file mode 100644 index 0000000000000..26a1750237478 --- /dev/null +++ b/tests/baselines/reference/strictPragma6.errors.txt @@ -0,0 +1,32 @@ +tests/cases/conformance/pragma/strict/file1.ts(4,20): error TS2345: Argument of type 'number' is not assignable to parameter of type 'string'. +tests/cases/conformance/pragma/strict/file1.ts(14,5): error TS2564: Property 'prop' has no initializer and is not definitely assigned in the constructor. +tests/cases/conformance/pragma/strict/file1.ts(19,1): error TS2532: Object is possibly 'undefined'. + + +==== tests/cases/conformance/pragma/strict/file1.ts (3 errors) ==== + // @ts-strict + // @ts-strictFunctionTypes false + export function f1(x: string) {} + f1.call(undefined, 42); // wrong + ~~ +!!! error TS2345: Argument of type 'number' is not assignable to parameter of type 'string'. + f1.call(undefined, "ok"); // right + + export let a = (arg: string) => 0; + export let b = (arg: unknown) => 0; + + a = b; + b = a; + + export class A { + prop: string; + ~~~~ +!!! error TS2564: Property 'prop' has no initializer and is not definitely assigned in the constructor. + constructor() {} + } + + declare var c: { member?: string }; + c.member.charAt(0); + ~~~~~~~~ +!!! error TS2532: Object is possibly 'undefined'. + \ No newline at end of file diff --git a/tests/baselines/reference/strictPragma6.js b/tests/baselines/reference/strictPragma6.js new file mode 100644 index 0000000000000..6bf9d803aaa27 --- /dev/null +++ b/tests/baselines/reference/strictPragma6.js @@ -0,0 +1,45 @@ +//// [file1.ts] +// @ts-strict +// @ts-strictFunctionTypes false +export function f1(x: string) {} +f1.call(undefined, 42); // wrong +f1.call(undefined, "ok"); // right + +export let a = (arg: string) => 0; +export let b = (arg: unknown) => 0; + +a = b; +b = a; + +export class A { + prop: string; + constructor() {} +} + +declare var c: { member?: string }; +c.member.charAt(0); + + +//// [file1.js] +"use strict"; +exports.__esModule = true; +exports.A = exports.b = exports.a = exports.f1 = void 0; +// @ts-strict +// @ts-strictFunctionTypes false +function f1(x) { } +exports.f1 = f1; +f1.call(undefined, 42); // wrong +f1.call(undefined, "ok"); // right +var a = function (arg) { return 0; }; +exports.a = a; +var b = function (arg) { return 0; }; +exports.b = b; +exports.a = exports.b; +exports.b = exports.a; +var A = /** @class */ (function () { + function A() { + } + return A; +}()); +exports.A = A; +c.member.charAt(0); diff --git a/tests/baselines/reference/strictPragma6.symbols b/tests/baselines/reference/strictPragma6.symbols new file mode 100644 index 0000000000000..f5268e0c26728 --- /dev/null +++ b/tests/baselines/reference/strictPragma6.symbols @@ -0,0 +1,55 @@ +=== tests/cases/conformance/pragma/strict/file1.ts === +// @ts-strict +// @ts-strictFunctionTypes false +export function f1(x: string) {} +>f1 : Symbol(f1, Decl(file1.ts, 0, 0)) +>x : Symbol(x, Decl(file1.ts, 2, 19)) + +f1.call(undefined, 42); // wrong +>f1.call : Symbol(CallableFunction.call, Decl(lib.es5.d.ts, --, --)) +>f1 : Symbol(f1, Decl(file1.ts, 0, 0)) +>call : Symbol(CallableFunction.call, Decl(lib.es5.d.ts, --, --)) +>undefined : Symbol(undefined) + +f1.call(undefined, "ok"); // right +>f1.call : Symbol(CallableFunction.call, Decl(lib.es5.d.ts, --, --)) +>f1 : Symbol(f1, Decl(file1.ts, 0, 0)) +>call : Symbol(CallableFunction.call, Decl(lib.es5.d.ts, --, --)) +>undefined : Symbol(undefined) + +export let a = (arg: string) => 0; +>a : Symbol(a, Decl(file1.ts, 6, 10)) +>arg : Symbol(arg, Decl(file1.ts, 6, 16)) + +export let b = (arg: unknown) => 0; +>b : Symbol(b, Decl(file1.ts, 7, 10)) +>arg : Symbol(arg, Decl(file1.ts, 7, 16)) + +a = b; +>a : Symbol(a, Decl(file1.ts, 6, 10)) +>b : Symbol(b, Decl(file1.ts, 7, 10)) + +b = a; +>b : Symbol(b, Decl(file1.ts, 7, 10)) +>a : Symbol(a, Decl(file1.ts, 6, 10)) + +export class A { +>A : Symbol(A, Decl(file1.ts, 10, 6)) + + prop: string; +>prop : Symbol(A.prop, Decl(file1.ts, 12, 16)) + + constructor() {} +} + +declare var c: { member?: string }; +>c : Symbol(c, Decl(file1.ts, 17, 11)) +>member : Symbol(member, Decl(file1.ts, 17, 16)) + +c.member.charAt(0); +>c.member.charAt : Symbol(String.charAt, Decl(lib.es5.d.ts, --, --)) +>c.member : Symbol(member, Decl(file1.ts, 17, 16)) +>c : Symbol(c, Decl(file1.ts, 17, 11)) +>member : Symbol(member, Decl(file1.ts, 17, 16)) +>charAt : Symbol(String.charAt, Decl(lib.es5.d.ts, --, --)) + diff --git a/tests/baselines/reference/strictPragma6.types b/tests/baselines/reference/strictPragma6.types new file mode 100644 index 0000000000000..f57ac0ff23714 --- /dev/null +++ b/tests/baselines/reference/strictPragma6.types @@ -0,0 +1,67 @@ +=== tests/cases/conformance/pragma/strict/file1.ts === +// @ts-strict +// @ts-strictFunctionTypes false +export function f1(x: string) {} +>f1 : (x: string) => void +>x : string + +f1.call(undefined, 42); // wrong +>f1.call(undefined, 42) : void +>f1.call : (this: (this: T, ...args: A) => R, thisArg: T, ...args: A) => R +>f1 : (x: string) => void +>call : (this: (this: T, ...args: A) => R, thisArg: T, ...args: A) => R +>undefined : undefined +>42 : 42 + +f1.call(undefined, "ok"); // right +>f1.call(undefined, "ok") : void +>f1.call : (this: (this: T, ...args: A) => R, thisArg: T, ...args: A) => R +>f1 : (x: string) => void +>call : (this: (this: T, ...args: A) => R, thisArg: T, ...args: A) => R +>undefined : undefined +>"ok" : "ok" + +export let a = (arg: string) => 0; +>a : (arg: string) => number +>(arg: string) => 0 : (arg: string) => number +>arg : string +>0 : 0 + +export let b = (arg: unknown) => 0; +>b : (arg: unknown) => number +>(arg: unknown) => 0 : (arg: unknown) => number +>arg : unknown +>0 : 0 + +a = b; +>a = b : (arg: unknown) => number +>a : (arg: string) => number +>b : (arg: unknown) => number + +b = a; +>b = a : (arg: string) => number +>b : (arg: unknown) => number +>a : (arg: string) => number + +export class A { +>A : A + + prop: string; +>prop : string + + constructor() {} +} + +declare var c: { member?: string }; +>c : { member?: string | undefined; } +>member : string | undefined + +c.member.charAt(0); +>c.member.charAt(0) : string +>c.member.charAt : (pos: number) => string +>c.member : string | undefined +>c : { member?: string | undefined; } +>member : string | undefined +>charAt : (pos: number) => string +>0 : 0 + diff --git a/tests/baselines/reference/strictPropertyInitializationPragma1.errors.txt b/tests/baselines/reference/strictPropertyInitializationPragma1.errors.txt new file mode 100644 index 0000000000000..020d2c53d9344 --- /dev/null +++ b/tests/baselines/reference/strictPropertyInitializationPragma1.errors.txt @@ -0,0 +1,35 @@ +tests/cases/conformance/pragma/strictPropertyInitialization/file1.ts(3,5): error TS2564: Property 'prop' has no initializer and is not definitely assigned in the constructor. +tests/cases/conformance/pragma/strictPropertyInitialization/file2.ts(3,5): error TS2564: Property 'prop' has no initializer and is not definitely assigned in the constructor. + + +==== tests/cases/conformance/pragma/strictPropertyInitialization/file1.ts (1 errors) ==== + // @ts-strictPropertyInitialization + export class A { + prop: string; + ~~~~ +!!! error TS2564: Property 'prop' has no initializer and is not definitely assigned in the constructor. + constructor() {} + } + +==== tests/cases/conformance/pragma/strictPropertyInitialization/file2.ts (1 errors) ==== + // @ts-strictPropertyInitialization true + export class A { + prop: string; + ~~~~ +!!! error TS2564: Property 'prop' has no initializer and is not definitely assigned in the constructor. + constructor() {} + } + +==== tests/cases/conformance/pragma/strictPropertyInitialization/file3.ts (0 errors) ==== + // @ts-strictPropertyInitialization false + export class A { + prop: string; + constructor() {} + } + +==== tests/cases/conformance/pragma/strictPropertyInitialization/file4.ts (0 errors) ==== + export class A { + prop: string; + constructor() {} + } + \ No newline at end of file diff --git a/tests/baselines/reference/strictPropertyInitializationPragma1.js b/tests/baselines/reference/strictPropertyInitializationPragma1.js new file mode 100644 index 0000000000000..180d1a5bec2f9 --- /dev/null +++ b/tests/baselines/reference/strictPropertyInitializationPragma1.js @@ -0,0 +1,73 @@ +//// [tests/cases/conformance/pragma/strictPropertyInitialization/strictPropertyInitializationPragma1.ts] //// + +//// [file1.ts] +// @ts-strictPropertyInitialization +export class A { + prop: string; + constructor() {} +} + +//// [file2.ts] +// @ts-strictPropertyInitialization true +export class A { + prop: string; + constructor() {} +} + +//// [file3.ts] +// @ts-strictPropertyInitialization false +export class A { + prop: string; + constructor() {} +} + +//// [file4.ts] +export class A { + prop: string; + constructor() {} +} + + +//// [file1.js] +"use strict"; +exports.__esModule = true; +exports.A = void 0; +// @ts-strictPropertyInitialization +var A = /** @class */ (function () { + function A() { + } + return A; +}()); +exports.A = A; +//// [file2.js] +"use strict"; +exports.__esModule = true; +exports.A = void 0; +// @ts-strictPropertyInitialization true +var A = /** @class */ (function () { + function A() { + } + return A; +}()); +exports.A = A; +//// [file3.js] +"use strict"; +exports.__esModule = true; +exports.A = void 0; +// @ts-strictPropertyInitialization false +var A = /** @class */ (function () { + function A() { + } + return A; +}()); +exports.A = A; +//// [file4.js] +"use strict"; +exports.__esModule = true; +exports.A = void 0; +var A = /** @class */ (function () { + function A() { + } + return A; +}()); +exports.A = A; diff --git a/tests/baselines/reference/strictPropertyInitializationPragma1.symbols b/tests/baselines/reference/strictPropertyInitializationPragma1.symbols new file mode 100644 index 0000000000000..eb73cf2b987ef --- /dev/null +++ b/tests/baselines/reference/strictPropertyInitializationPragma1.symbols @@ -0,0 +1,43 @@ +=== tests/cases/conformance/pragma/strictPropertyInitialization/file1.ts === +// @ts-strictPropertyInitialization +export class A { +>A : Symbol(A, Decl(file1.ts, 0, 0)) + + prop: string; +>prop : Symbol(A.prop, Decl(file1.ts, 1, 16)) + + constructor() {} +} + +=== tests/cases/conformance/pragma/strictPropertyInitialization/file2.ts === +// @ts-strictPropertyInitialization true +export class A { +>A : Symbol(A, Decl(file2.ts, 0, 0)) + + prop: string; +>prop : Symbol(A.prop, Decl(file2.ts, 1, 16)) + + constructor() {} +} + +=== tests/cases/conformance/pragma/strictPropertyInitialization/file3.ts === +// @ts-strictPropertyInitialization false +export class A { +>A : Symbol(A, Decl(file3.ts, 0, 0)) + + prop: string; +>prop : Symbol(A.prop, Decl(file3.ts, 1, 16)) + + constructor() {} +} + +=== tests/cases/conformance/pragma/strictPropertyInitialization/file4.ts === +export class A { +>A : Symbol(A, Decl(file4.ts, 0, 0)) + + prop: string; +>prop : Symbol(A.prop, Decl(file4.ts, 0, 16)) + + constructor() {} +} + diff --git a/tests/baselines/reference/strictPropertyInitializationPragma1.types b/tests/baselines/reference/strictPropertyInitializationPragma1.types new file mode 100644 index 0000000000000..917fb6a3da664 --- /dev/null +++ b/tests/baselines/reference/strictPropertyInitializationPragma1.types @@ -0,0 +1,43 @@ +=== tests/cases/conformance/pragma/strictPropertyInitialization/file1.ts === +// @ts-strictPropertyInitialization +export class A { +>A : A + + prop: string; +>prop : string + + constructor() {} +} + +=== tests/cases/conformance/pragma/strictPropertyInitialization/file2.ts === +// @ts-strictPropertyInitialization true +export class A { +>A : A + + prop: string; +>prop : string + + constructor() {} +} + +=== tests/cases/conformance/pragma/strictPropertyInitialization/file3.ts === +// @ts-strictPropertyInitialization false +export class A { +>A : A + + prop: string; +>prop : string + + constructor() {} +} + +=== tests/cases/conformance/pragma/strictPropertyInitialization/file4.ts === +export class A { +>A : A + + prop: string; +>prop : string + + constructor() {} +} + diff --git a/tests/baselines/reference/strictPropertyInitializationPragma2.errors.txt b/tests/baselines/reference/strictPropertyInitializationPragma2.errors.txt new file mode 100644 index 0000000000000..e24eba66dbe89 --- /dev/null +++ b/tests/baselines/reference/strictPropertyInitializationPragma2.errors.txt @@ -0,0 +1,38 @@ +tests/cases/conformance/pragma/strictPropertyInitialization/file1.ts(3,5): error TS2564: Property 'prop' has no initializer and is not definitely assigned in the constructor. +tests/cases/conformance/pragma/strictPropertyInitialization/file2.ts(3,5): error TS2564: Property 'prop' has no initializer and is not definitely assigned in the constructor. +tests/cases/conformance/pragma/strictPropertyInitialization/file4.ts(2,5): error TS2564: Property 'prop' has no initializer and is not definitely assigned in the constructor. + + +==== tests/cases/conformance/pragma/strictPropertyInitialization/file1.ts (1 errors) ==== + // @ts-strictPropertyInitialization + export class A { + prop: string; + ~~~~ +!!! error TS2564: Property 'prop' has no initializer and is not definitely assigned in the constructor. + constructor() {} + } + +==== tests/cases/conformance/pragma/strictPropertyInitialization/file2.ts (1 errors) ==== + // @ts-strictPropertyInitialization true + export class A { + prop: string; + ~~~~ +!!! error TS2564: Property 'prop' has no initializer and is not definitely assigned in the constructor. + constructor() {} + } + +==== tests/cases/conformance/pragma/strictPropertyInitialization/file3.ts (0 errors) ==== + // @ts-strictPropertyInitialization false + export class A { + prop: string; + constructor() {} + } + +==== tests/cases/conformance/pragma/strictPropertyInitialization/file4.ts (1 errors) ==== + export class A { + prop: string; + ~~~~ +!!! error TS2564: Property 'prop' has no initializer and is not definitely assigned in the constructor. + constructor() {} + } + \ No newline at end of file diff --git a/tests/baselines/reference/strictPropertyInitializationPragma2.js b/tests/baselines/reference/strictPropertyInitializationPragma2.js new file mode 100644 index 0000000000000..8afcbd0079543 --- /dev/null +++ b/tests/baselines/reference/strictPropertyInitializationPragma2.js @@ -0,0 +1,73 @@ +//// [tests/cases/conformance/pragma/strictPropertyInitialization/strictPropertyInitializationPragma2.ts] //// + +//// [file1.ts] +// @ts-strictPropertyInitialization +export class A { + prop: string; + constructor() {} +} + +//// [file2.ts] +// @ts-strictPropertyInitialization true +export class A { + prop: string; + constructor() {} +} + +//// [file3.ts] +// @ts-strictPropertyInitialization false +export class A { + prop: string; + constructor() {} +} + +//// [file4.ts] +export class A { + prop: string; + constructor() {} +} + + +//// [file1.js] +"use strict"; +exports.__esModule = true; +exports.A = void 0; +// @ts-strictPropertyInitialization +var A = /** @class */ (function () { + function A() { + } + return A; +}()); +exports.A = A; +//// [file2.js] +"use strict"; +exports.__esModule = true; +exports.A = void 0; +// @ts-strictPropertyInitialization true +var A = /** @class */ (function () { + function A() { + } + return A; +}()); +exports.A = A; +//// [file3.js] +"use strict"; +exports.__esModule = true; +exports.A = void 0; +// @ts-strictPropertyInitialization false +var A = /** @class */ (function () { + function A() { + } + return A; +}()); +exports.A = A; +//// [file4.js] +"use strict"; +exports.__esModule = true; +exports.A = void 0; +var A = /** @class */ (function () { + function A() { + } + return A; +}()); +exports.A = A; diff --git a/tests/baselines/reference/strictPropertyInitializationPragma2.symbols b/tests/baselines/reference/strictPropertyInitializationPragma2.symbols new file mode 100644 index 0000000000000..eb73cf2b987ef --- /dev/null +++ b/tests/baselines/reference/strictPropertyInitializationPragma2.symbols @@ -0,0 +1,43 @@ +=== tests/cases/conformance/pragma/strictPropertyInitialization/file1.ts === +// @ts-strictPropertyInitialization +export class A { +>A : Symbol(A, Decl(file1.ts, 0, 0)) + + prop: string; +>prop : Symbol(A.prop, Decl(file1.ts, 1, 16)) + + constructor() {} +} + +=== tests/cases/conformance/pragma/strictPropertyInitialization/file2.ts === +// @ts-strictPropertyInitialization true +export class A { +>A : Symbol(A, Decl(file2.ts, 0, 0)) + + prop: string; +>prop : Symbol(A.prop, Decl(file2.ts, 1, 16)) + + constructor() {} +} + +=== tests/cases/conformance/pragma/strictPropertyInitialization/file3.ts === +// @ts-strictPropertyInitialization false +export class A { +>A : Symbol(A, Decl(file3.ts, 0, 0)) + + prop: string; +>prop : Symbol(A.prop, Decl(file3.ts, 1, 16)) + + constructor() {} +} + +=== tests/cases/conformance/pragma/strictPropertyInitialization/file4.ts === +export class A { +>A : Symbol(A, Decl(file4.ts, 0, 0)) + + prop: string; +>prop : Symbol(A.prop, Decl(file4.ts, 0, 16)) + + constructor() {} +} + diff --git a/tests/baselines/reference/strictPropertyInitializationPragma2.types b/tests/baselines/reference/strictPropertyInitializationPragma2.types new file mode 100644 index 0000000000000..917fb6a3da664 --- /dev/null +++ b/tests/baselines/reference/strictPropertyInitializationPragma2.types @@ -0,0 +1,43 @@ +=== tests/cases/conformance/pragma/strictPropertyInitialization/file1.ts === +// @ts-strictPropertyInitialization +export class A { +>A : A + + prop: string; +>prop : string + + constructor() {} +} + +=== tests/cases/conformance/pragma/strictPropertyInitialization/file2.ts === +// @ts-strictPropertyInitialization true +export class A { +>A : A + + prop: string; +>prop : string + + constructor() {} +} + +=== tests/cases/conformance/pragma/strictPropertyInitialization/file3.ts === +// @ts-strictPropertyInitialization false +export class A { +>A : A + + prop: string; +>prop : string + + constructor() {} +} + +=== tests/cases/conformance/pragma/strictPropertyInitialization/file4.ts === +export class A { +>A : A + + prop: string; +>prop : string + + constructor() {} +} + diff --git a/tests/baselines/reference/useUnknownInCatchVariablesPragma1.errors.txt b/tests/baselines/reference/useUnknownInCatchVariablesPragma1.errors.txt new file mode 100644 index 0000000000000..1976bc46d63cb --- /dev/null +++ b/tests/baselines/reference/useUnknownInCatchVariablesPragma1.errors.txt @@ -0,0 +1,43 @@ +tests/cases/conformance/pragma/useUnknownInCatchVariables/file1.ts(6,11): error TS2339: Property 'a' does not exist on type 'unknown'. +tests/cases/conformance/pragma/useUnknownInCatchVariables/file2.ts(6,11): error TS2339: Property 'a' does not exist on type 'unknown'. + + +==== tests/cases/conformance/pragma/useUnknownInCatchVariables/file1.ts (1 errors) ==== + // @ts-useUnknownInCatchVariables + try { + + } + catch (thing) { + thing.a; + ~ +!!! error TS2339: Property 'a' does not exist on type 'unknown'. + } + +==== tests/cases/conformance/pragma/useUnknownInCatchVariables/file2.ts (1 errors) ==== + // @ts-useUnknownInCatchVariables true + try { + + } + catch (thing) { + thing.a; + ~ +!!! error TS2339: Property 'a' does not exist on type 'unknown'. + } + +==== tests/cases/conformance/pragma/useUnknownInCatchVariables/file3.ts (0 errors) ==== + // @ts-useUnknownInCatchVariables false + try { + + } + catch (thing) { + thing.a; + } + +==== tests/cases/conformance/pragma/useUnknownInCatchVariables/file4.ts (0 errors) ==== + try { + + } + catch (thing) { + thing.a; + } + \ No newline at end of file diff --git a/tests/baselines/reference/useUnknownInCatchVariablesPragma1.js b/tests/baselines/reference/useUnknownInCatchVariablesPragma1.js new file mode 100644 index 0000000000000..d6245be1ebb05 --- /dev/null +++ b/tests/baselines/reference/useUnknownInCatchVariablesPragma1.js @@ -0,0 +1,65 @@ +//// [tests/cases/conformance/pragma/useUnknownInCatchVariables/useUnknownInCatchVariablesPragma1.ts] //// + +//// [file1.ts] +// @ts-useUnknownInCatchVariables +try { + +} +catch (thing) { + thing.a; +} + +//// [file2.ts] +// @ts-useUnknownInCatchVariables true +try { + +} +catch (thing) { + thing.a; +} + +//// [file3.ts] +// @ts-useUnknownInCatchVariables false +try { + +} +catch (thing) { + thing.a; +} + +//// [file4.ts] +try { + +} +catch (thing) { + thing.a; +} + + +//// [file1.js] +// @ts-useUnknownInCatchVariables +try { +} +catch (thing) { + thing.a; +} +//// [file2.js] +// @ts-useUnknownInCatchVariables true +try { +} +catch (thing) { + thing.a; +} +//// [file3.js] +// @ts-useUnknownInCatchVariables false +try { +} +catch (thing) { + thing.a; +} +//// [file4.js] +try { +} +catch (thing) { + thing.a; +} diff --git a/tests/baselines/reference/useUnknownInCatchVariablesPragma1.symbols b/tests/baselines/reference/useUnknownInCatchVariablesPragma1.symbols new file mode 100644 index 0000000000000..d3a22b69bbaf8 --- /dev/null +++ b/tests/baselines/reference/useUnknownInCatchVariablesPragma1.symbols @@ -0,0 +1,47 @@ +=== tests/cases/conformance/pragma/useUnknownInCatchVariables/file1.ts === +// @ts-useUnknownInCatchVariables +try { + +} +catch (thing) { +>thing : Symbol(thing, Decl(file1.ts, 4, 7)) + + thing.a; +>thing : Symbol(thing, Decl(file1.ts, 4, 7)) +} + +=== tests/cases/conformance/pragma/useUnknownInCatchVariables/file2.ts === +// @ts-useUnknownInCatchVariables true +try { + +} +catch (thing) { +>thing : Symbol(thing, Decl(file2.ts, 4, 7)) + + thing.a; +>thing : Symbol(thing, Decl(file2.ts, 4, 7)) +} + +=== tests/cases/conformance/pragma/useUnknownInCatchVariables/file3.ts === +// @ts-useUnknownInCatchVariables false +try { + +} +catch (thing) { +>thing : Symbol(thing, Decl(file3.ts, 4, 7)) + + thing.a; +>thing : Symbol(thing, Decl(file3.ts, 4, 7)) +} + +=== tests/cases/conformance/pragma/useUnknownInCatchVariables/file4.ts === +try { + +} +catch (thing) { +>thing : Symbol(thing, Decl(file4.ts, 3, 7)) + + thing.a; +>thing : Symbol(thing, Decl(file4.ts, 3, 7)) +} + diff --git a/tests/baselines/reference/useUnknownInCatchVariablesPragma1.types b/tests/baselines/reference/useUnknownInCatchVariablesPragma1.types new file mode 100644 index 0000000000000..c3a4ebc89608e --- /dev/null +++ b/tests/baselines/reference/useUnknownInCatchVariablesPragma1.types @@ -0,0 +1,55 @@ +=== tests/cases/conformance/pragma/useUnknownInCatchVariables/file1.ts === +// @ts-useUnknownInCatchVariables +try { + +} +catch (thing) { +>thing : unknown + + thing.a; +>thing.a : any +>thing : unknown +>a : any +} + +=== tests/cases/conformance/pragma/useUnknownInCatchVariables/file2.ts === +// @ts-useUnknownInCatchVariables true +try { + +} +catch (thing) { +>thing : unknown + + thing.a; +>thing.a : any +>thing : unknown +>a : any +} + +=== tests/cases/conformance/pragma/useUnknownInCatchVariables/file3.ts === +// @ts-useUnknownInCatchVariables false +try { + +} +catch (thing) { +>thing : any + + thing.a; +>thing.a : any +>thing : any +>a : any +} + +=== tests/cases/conformance/pragma/useUnknownInCatchVariables/file4.ts === +try { + +} +catch (thing) { +>thing : any + + thing.a; +>thing.a : any +>thing : any +>a : any +} + diff --git a/tests/baselines/reference/useUnknownInCatchVariablesPragma2.errors.txt b/tests/baselines/reference/useUnknownInCatchVariablesPragma2.errors.txt new file mode 100644 index 0000000000000..1aa05a9108bf4 --- /dev/null +++ b/tests/baselines/reference/useUnknownInCatchVariablesPragma2.errors.txt @@ -0,0 +1,46 @@ +tests/cases/conformance/pragma/useUnknownInCatchVariables/file1.ts(6,11): error TS2339: Property 'a' does not exist on type 'unknown'. +tests/cases/conformance/pragma/useUnknownInCatchVariables/file2.ts(6,11): error TS2339: Property 'a' does not exist on type 'unknown'. +tests/cases/conformance/pragma/useUnknownInCatchVariables/file4.ts(5,11): error TS2339: Property 'a' does not exist on type 'unknown'. + + +==== tests/cases/conformance/pragma/useUnknownInCatchVariables/file1.ts (1 errors) ==== + // @ts-useUnknownInCatchVariables + try { + + } + catch (thing) { + thing.a; + ~ +!!! error TS2339: Property 'a' does not exist on type 'unknown'. + } + +==== tests/cases/conformance/pragma/useUnknownInCatchVariables/file2.ts (1 errors) ==== + // @ts-useUnknownInCatchVariables true + try { + + } + catch (thing) { + thing.a; + ~ +!!! error TS2339: Property 'a' does not exist on type 'unknown'. + } + +==== tests/cases/conformance/pragma/useUnknownInCatchVariables/file3.ts (0 errors) ==== + // @ts-useUnknownInCatchVariables false + try { + + } + catch (thing) { + thing.a; + } + +==== tests/cases/conformance/pragma/useUnknownInCatchVariables/file4.ts (1 errors) ==== + try { + + } + catch (thing) { + thing.a; + ~ +!!! error TS2339: Property 'a' does not exist on type 'unknown'. + } + \ No newline at end of file diff --git a/tests/baselines/reference/useUnknownInCatchVariablesPragma2.js b/tests/baselines/reference/useUnknownInCatchVariablesPragma2.js new file mode 100644 index 0000000000000..b0a81910751a0 --- /dev/null +++ b/tests/baselines/reference/useUnknownInCatchVariablesPragma2.js @@ -0,0 +1,65 @@ +//// [tests/cases/conformance/pragma/useUnknownInCatchVariables/useUnknownInCatchVariablesPragma2.ts] //// + +//// [file1.ts] +// @ts-useUnknownInCatchVariables +try { + +} +catch (thing) { + thing.a; +} + +//// [file2.ts] +// @ts-useUnknownInCatchVariables true +try { + +} +catch (thing) { + thing.a; +} + +//// [file3.ts] +// @ts-useUnknownInCatchVariables false +try { + +} +catch (thing) { + thing.a; +} + +//// [file4.ts] +try { + +} +catch (thing) { + thing.a; +} + + +//// [file1.js] +// @ts-useUnknownInCatchVariables +try { +} +catch (thing) { + thing.a; +} +//// [file2.js] +// @ts-useUnknownInCatchVariables true +try { +} +catch (thing) { + thing.a; +} +//// [file3.js] +// @ts-useUnknownInCatchVariables false +try { +} +catch (thing) { + thing.a; +} +//// [file4.js] +try { +} +catch (thing) { + thing.a; +} diff --git a/tests/baselines/reference/useUnknownInCatchVariablesPragma2.symbols b/tests/baselines/reference/useUnknownInCatchVariablesPragma2.symbols new file mode 100644 index 0000000000000..d3a22b69bbaf8 --- /dev/null +++ b/tests/baselines/reference/useUnknownInCatchVariablesPragma2.symbols @@ -0,0 +1,47 @@ +=== tests/cases/conformance/pragma/useUnknownInCatchVariables/file1.ts === +// @ts-useUnknownInCatchVariables +try { + +} +catch (thing) { +>thing : Symbol(thing, Decl(file1.ts, 4, 7)) + + thing.a; +>thing : Symbol(thing, Decl(file1.ts, 4, 7)) +} + +=== tests/cases/conformance/pragma/useUnknownInCatchVariables/file2.ts === +// @ts-useUnknownInCatchVariables true +try { + +} +catch (thing) { +>thing : Symbol(thing, Decl(file2.ts, 4, 7)) + + thing.a; +>thing : Symbol(thing, Decl(file2.ts, 4, 7)) +} + +=== tests/cases/conformance/pragma/useUnknownInCatchVariables/file3.ts === +// @ts-useUnknownInCatchVariables false +try { + +} +catch (thing) { +>thing : Symbol(thing, Decl(file3.ts, 4, 7)) + + thing.a; +>thing : Symbol(thing, Decl(file3.ts, 4, 7)) +} + +=== tests/cases/conformance/pragma/useUnknownInCatchVariables/file4.ts === +try { + +} +catch (thing) { +>thing : Symbol(thing, Decl(file4.ts, 3, 7)) + + thing.a; +>thing : Symbol(thing, Decl(file4.ts, 3, 7)) +} + diff --git a/tests/baselines/reference/useUnknownInCatchVariablesPragma2.types b/tests/baselines/reference/useUnknownInCatchVariablesPragma2.types new file mode 100644 index 0000000000000..cd9cef849dcfc --- /dev/null +++ b/tests/baselines/reference/useUnknownInCatchVariablesPragma2.types @@ -0,0 +1,55 @@ +=== tests/cases/conformance/pragma/useUnknownInCatchVariables/file1.ts === +// @ts-useUnknownInCatchVariables +try { + +} +catch (thing) { +>thing : unknown + + thing.a; +>thing.a : any +>thing : unknown +>a : any +} + +=== tests/cases/conformance/pragma/useUnknownInCatchVariables/file2.ts === +// @ts-useUnknownInCatchVariables true +try { + +} +catch (thing) { +>thing : unknown + + thing.a; +>thing.a : any +>thing : unknown +>a : any +} + +=== tests/cases/conformance/pragma/useUnknownInCatchVariables/file3.ts === +// @ts-useUnknownInCatchVariables false +try { + +} +catch (thing) { +>thing : any + + thing.a; +>thing.a : any +>thing : any +>a : any +} + +=== tests/cases/conformance/pragma/useUnknownInCatchVariables/file4.ts === +try { + +} +catch (thing) { +>thing : unknown + + thing.a; +>thing.a : any +>thing : unknown +>a : any +} + diff --git a/tests/cases/conformance/pragma/alwaysStrict/alwaysStrictPragma1.ts b/tests/cases/conformance/pragma/alwaysStrict/alwaysStrictPragma1.ts new file mode 100644 index 0000000000000..69fc6f564ab13 --- /dev/null +++ b/tests/cases/conformance/pragma/alwaysStrict/alwaysStrictPragma1.ts @@ -0,0 +1,11 @@ +// @filename: file1.ts +// @ts-alwaysStrict +let private = {}; +// @filename: file2.ts +// @ts-alwaysStrict true +let protected = {}; +// @filename: file3.ts +// @ts-alwaysStrict false +let public = {}; +// @filename: file4.ts +let static = {}; diff --git a/tests/cases/conformance/pragma/alwaysStrict/alwaysStrictPragma2.ts b/tests/cases/conformance/pragma/alwaysStrict/alwaysStrictPragma2.ts new file mode 100644 index 0000000000000..d4d123911245e --- /dev/null +++ b/tests/cases/conformance/pragma/alwaysStrict/alwaysStrictPragma2.ts @@ -0,0 +1,12 @@ +// @alwaysStrict: true +// @filename: file1.ts +// @ts-alwaysStrict +let private = {}; +// @filename: file2.ts +// @ts-alwaysStrict true +let protected = {}; +// @filename: file3.ts +// @ts-alwaysStrict false +let public = {}; +// @filename: file4.ts +let static = {}; diff --git a/tests/cases/conformance/pragma/exactOptionalPropertyTypes/exactOptionalPropertyTypesPragma1.ts b/tests/cases/conformance/pragma/exactOptionalPropertyTypes/exactOptionalPropertyTypesPragma1.ts new file mode 100644 index 0000000000000..29eb1ffc5772d --- /dev/null +++ b/tests/cases/conformance/pragma/exactOptionalPropertyTypes/exactOptionalPropertyTypesPragma1.ts @@ -0,0 +1,109 @@ +// @strictNullChecks: true +// @filename: file1.ts +// @ts-exactOptionalPropertyTypes +export interface A { + member: string | undefined; +} +declare var a: A; +delete a.member; + +export interface B { + member?: string; +} +declare var b: B; +a = b; +b = a; + +// @filename: file2.ts +// @ts-exactOptionalPropertyTypes true +export interface A { + member: string | undefined; +} +declare var a: A; +delete a.member; + +export interface B { + member?: string; +} +declare var b: B; +a = b; +b = a; + +// @filename: file3.ts +// @ts-exactOptionalPropertyTypes false +export interface A { + member: string | undefined; +} +declare var a: A; +delete a.member; + +export interface B { + member?: string; +} +declare var b: B; +a = b; +b = a; + +// @filename: file4.ts +export interface A { + member: string | undefined; +} +declare var a: A; +delete a.member; + +export interface B { + member?: string; +} +declare var b: B; +a = b; +b = a; + +// @filename: file5.ts +// @ts-exactOptionalPropertyTypes true +import {A as A1, B as B1} from "./file2"; +import {A as A2, B as B2} from "./file3"; + +declare var a1: A1, b1: B2, a2: A2, b2: B2; + +a1 = b1; +b1 = a1; + +a2 = b2; +b2 = a2; + +a1 = a2; +a2 = a1; + +b1 = b2; +b2 = b1; + +a1 = b2; +b2 = a1; + +b1 = a2; +a2 = b1; + +// @filename: file6.ts +// @ts-exactOptionalPropertyTypes false +import {A as A1, B as B1} from "./file2"; +import {A as A2, B as B2} from "./file3"; + +declare var a1: A1, b1: B2, a2: A2, b2: B2; + +a1 = b1; +b1 = a1; + +a2 = b2; +b2 = a2; + +a1 = a2; +a2 = a1; + +b1 = b2; +b2 = b1; + +a1 = b2; +b2 = a1; + +b1 = a2; +a2 = b1; \ No newline at end of file diff --git a/tests/cases/conformance/pragma/exactOptionalPropertyTypes/exactOptionalPropertyTypesPragma2.ts b/tests/cases/conformance/pragma/exactOptionalPropertyTypes/exactOptionalPropertyTypesPragma2.ts new file mode 100644 index 0000000000000..542fd6d4d5527 --- /dev/null +++ b/tests/cases/conformance/pragma/exactOptionalPropertyTypes/exactOptionalPropertyTypesPragma2.ts @@ -0,0 +1,110 @@ +// @strictNullChecks: true +// @exactOptionalPropertyTypes: true +// @filename: file1.ts +// @ts-exactOptionalPropertyTypes +export interface A { + member: string | undefined; +} +declare var a: A; +delete a.member; + +export interface B { + member?: string; +} +declare var b: B; +a = b; +b = a; + +// @filename: file2.ts +// @ts-exactOptionalPropertyTypes true +export interface A { + member: string | undefined; +} +declare var a: A; +delete a.member; + +export interface B { + member?: string; +} +declare var b: B; +a = b; +b = a; + +// @filename: file3.ts +// @ts-exactOptionalPropertyTypes false +export interface A { + member: string | undefined; +} +declare var a: A; +delete a.member; + +export interface B { + member?: string; +} +declare var b: B; +a = b; +b = a; + +// @filename: file4.ts +export interface A { + member: string | undefined; +} +declare var a: A; +delete a.member; + +export interface B { + member?: string; +} +declare var b: B; +a = b; +b = a; + +// @filename: file5.ts +// @ts-exactOptionalPropertyTypes true +import {A as A1, B as B1} from "./file2"; +import {A as A2, B as B2} from "./file3"; + +declare var a1: A1, b1: B2, a2: A2, b2: B2; + +a1 = b1; +b1 = a1; + +a2 = b2; +b2 = a2; + +a1 = a2; +a2 = a1; + +b1 = b2; +b2 = b1; + +a1 = b2; +b2 = a1; + +b1 = a2; +a2 = b1; + +// @filename: file6.ts +// @ts-exactOptionalPropertyTypes false +import {A as A1, B as B1} from "./file2"; +import {A as A2, B as B2} from "./file3"; + +declare var a1: A1, b1: B2, a2: A2, b2: B2; + +a1 = b1; +b1 = a1; + +a2 = b2; +b2 = a2; + +a1 = a2; +a2 = a1; + +b1 = b2; +b2 = b1; + +a1 = b2; +b2 = a1; + +b1 = a2; +a2 = b1; \ No newline at end of file diff --git a/tests/cases/conformance/pragma/noFallthroughCasesInSwitch/noFallthroughCasesInSwitchPragma1.ts b/tests/cases/conformance/pragma/noFallthroughCasesInSwitch/noFallthroughCasesInSwitchPragma1.ts new file mode 100644 index 0000000000000..2f6c0246270ea --- /dev/null +++ b/tests/cases/conformance/pragma/noFallthroughCasesInSwitch/noFallthroughCasesInSwitchPragma1.ts @@ -0,0 +1,50 @@ +// @filename: file1.ts +// @ts-noFallthroughCasesInSwitch +export function f1(thing: "a" | "b") { + switch (thing) { + case "a": + thing; + case "b": + thing; + break; + } + return thing; +} + +// @filename: file2.ts +// @ts-noFallthroughCasesInSwitch true +export function f1(thing: "a" | "b") { + switch (thing) { + case "a": + thing; + case "b": + thing; + break; + } + return thing; +} + +// @filename: file3.ts +// @ts-noFallthroughCasesInSwitch false +export function f1(thing: "a" | "b") { + switch (thing) { + case "a": + thing; + case "b": + thing; + break; + } + return thing; +} + +// @filename: file4.ts +export function f1(thing: "a" | "b") { + switch (thing) { + case "a": + thing; + case "b": + thing; + break; + } + return thing; +} diff --git a/tests/cases/conformance/pragma/noFallthroughCasesInSwitch/noFallthroughCasesInSwitchPragma2.ts b/tests/cases/conformance/pragma/noFallthroughCasesInSwitch/noFallthroughCasesInSwitchPragma2.ts new file mode 100644 index 0000000000000..375d1bff001d8 --- /dev/null +++ b/tests/cases/conformance/pragma/noFallthroughCasesInSwitch/noFallthroughCasesInSwitchPragma2.ts @@ -0,0 +1,51 @@ +// @noFallthroughCasesInSwitch: true +// @filename: file1.ts +// @ts-noFallthroughCasesInSwitch +export function f1(thing: "a" | "b") { + switch (thing) { + case "a": + thing; + case "b": + thing; + break; + } + return thing; +} + +// @filename: file2.ts +// @ts-noFallthroughCasesInSwitch true +export function f1(thing: "a" | "b") { + switch (thing) { + case "a": + thing; + case "b": + thing; + break; + } + return thing; +} + +// @filename: file3.ts +// @ts-noFallthroughCasesInSwitch false +export function f1(thing: "a" | "b") { + switch (thing) { + case "a": + thing; + case "b": + thing; + break; + } + return thing; +} + +// @filename: file4.ts +export function f1(thing: "a" | "b") { + switch (thing) { + case "a": + thing; + case "b": + thing; + break; + } + return thing; +} diff --git a/tests/cases/conformance/pragma/noImplicitAny/noImplicitAnyPragma1.ts b/tests/cases/conformance/pragma/noImplicitAny/noImplicitAnyPragma1.ts new file mode 100644 index 0000000000000..ec85464720440 --- /dev/null +++ b/tests/cases/conformance/pragma/noImplicitAny/noImplicitAnyPragma1.ts @@ -0,0 +1,172 @@ +// @target: es2015 +// @filename: file1.ts +// @ts-noImplicitAny +import * as ns from "missing"; + +const a = p => p + 1; + +let x; +x = "a"; +x = 42; + +export class A { + prop; + prop2; + constructor() { + this.prop = "a"; + this.prop = 42; + } + static stat; + static stat2; + static { + this.stat = "a"; + this.stat = 42; + } + + set access(param) {} + get access() { return this.access; } +} + +export function f1() { + return f1(); +} + +const res = {}["none"]; + +interface B { prop: string } +declare var b: B; + +const c = b["none"]; + +const d: B = { prop: "", excess: "yes" }; + +function f2(): string { return ""; } +const e = new f2(); +// @filename: file2.ts +// @ts-noImplicitAny true +import * as ns from "missing"; + +const a = p => p + 1; + +let x; +x = "a"; +x = 42; + +export class A { + prop; + prop2; + constructor() { + this.prop = "a"; + this.prop = 42; + } + static stat; + static stat2; + static { + this.stat = "a"; + this.stat = 42; + } + + set access(param) {} + get access() { return this.access; } +} + +export function f1() { + return f1(); +} + +const res = {}["none"]; + +interface B { prop: string } +declare var b: B; + +const c = b["none"]; + +const d: B = { prop: "", excess: "yes" }; + +function f2(): string { return ""; } +const e = new f2(); +// @filename: file3.ts +// @ts-noImplicitAny false +import * as ns from "missing"; + +const a = p => p + 1; + +let x; +x = "a"; +x = 42; + +export class A { + prop; + prop2; + constructor() { + this.prop = "a"; + this.prop = 42; + } + static stat; + static stat2; + static { + this.stat = "a"; + this.stat = 42; + } + + set access(param) {} + get access() { return this.access; } +} + +export function f1() { + return f1(); +} + +const res = {}["none"]; + +interface B { prop: string } +declare var b: B; + +const c = b["none"]; + +const d: B = { prop: "", excess: "yes" }; + +function f2(): string { return ""; } +const e = new f2(); +// @filename: file4.ts +import * as ns from "missing"; + +const a = p => p + 1; + +let x; +x = "a"; +x = 42; + +export class A { + prop; + prop2; + constructor() { + this.prop = "a"; + this.prop = 42; + } + static stat; + static stat2; + static { + this.stat = "a"; + this.stat = 42; + } + + set access(param) {} + get access() { return this.access; } +} + +export function f1() { + return f1(); +} + +const res = {}["none"]; + +interface B { prop: string } +declare var b: B; + +const c = b["none"]; + +const d: B = { prop: "", excess: "yes" }; + +function f2(): string { return ""; } +const e = new f2(); \ No newline at end of file diff --git a/tests/cases/conformance/pragma/noImplicitAny/noImplicitAnyPragma2.ts b/tests/cases/conformance/pragma/noImplicitAny/noImplicitAnyPragma2.ts new file mode 100644 index 0000000000000..8c4e99c6543ba --- /dev/null +++ b/tests/cases/conformance/pragma/noImplicitAny/noImplicitAnyPragma2.ts @@ -0,0 +1,173 @@ +// @noImplicitAny: true +// @target: es2015 +// @filename: file1.ts +// @ts-noImplicitAny +import * as ns from "missing"; + +const a = p => p + 1; + +let x; +x = "a"; +x = 42; + +export class A { + prop; + prop2; + constructor() { + this.prop = "a"; + this.prop = 42; + } + static stat; + static stat2; + static { + this.stat = "a"; + this.stat = 42; + } + + set access(param) {} + get access() { return this.access; } +} + +export function f1() { + return f1(); +} + +const res = {}["none"]; + +interface B { prop: string } +declare var b: B; + +const c = b["none"]; + +const d: B = { prop: "", excess: "yes" }; + +function f2(): string { return ""; } +const e = new f2(); +// @filename: file2.ts +// @ts-noImplicitAny true +import * as ns from "missing"; + +const a = p => p + 1; + +let x; +x = "a"; +x = 42; + +export class A { + prop; + prop2; + constructor() { + this.prop = "a"; + this.prop = 42; + } + static stat; + static stat2; + static { + this.stat = "a"; + this.stat = 42; + } + + set access(param) {} + get access() { return this.access; } +} + +export function f1() { + return f1(); +} + +const res = {}["none"]; + +interface B { prop: string } +declare var b: B; + +const c = b["none"]; + +const d: B = { prop: "", excess: "yes" }; + +function f2(): string { return ""; } +const e = new f2(); +// @filename: file3.ts +// @ts-noImplicitAny false +import * as ns from "missing"; + +const a = p => p + 1; + +let x; +x = "a"; +x = 42; + +export class A { + prop; + prop2; + constructor() { + this.prop = "a"; + this.prop = 42; + } + static stat; + static stat2; + static { + this.stat = "a"; + this.stat = 42; + } + + set access(param) {} + get access() { return this.access; } +} + +export function f1() { + return f1(); +} + +const res = {}["none"]; + +interface B { prop: string } +declare var b: B; + +const c = b["none"]; + +const d: B = { prop: "", excess: "yes" }; + +function f2(): string { return ""; } +const e = new f2(); +// @filename: file4.ts +import * as ns from "missing"; + +const a = p => p + 1; + +let x; +x = "a"; +x = 42; + +export class A { + prop; + prop2; + constructor() { + this.prop = "a"; + this.prop = 42; + } + static stat; + static stat2; + static { + this.stat = "a"; + this.stat = 42; + } + + set access(param) {} + get access() { return this.access; } +} + +export function f1() { + return f1(); +} + +const res = {}["none"]; + +interface B { prop: string } +declare var b: B; + +const c = b["none"]; + +const d: B = { prop: "", excess: "yes" }; + +function f2(): string { return ""; } +const e = new f2(); \ No newline at end of file diff --git a/tests/cases/conformance/pragma/noImplicitOverride/noImplicitOverridePragma1.ts b/tests/cases/conformance/pragma/noImplicitOverride/noImplicitOverridePragma1.ts new file mode 100644 index 0000000000000..0c24887c4456b --- /dev/null +++ b/tests/cases/conformance/pragma/noImplicitOverride/noImplicitOverridePragma1.ts @@ -0,0 +1,46 @@ +// @filename: file1.ts +// @ts-noImplicitOverride +export class A { + method() {} +} +export class B extends A { + method() {} +} +export class C extends A { + override method() {} +} + +// @filename: file2.ts +// @ts-noImplicitOverride true +export class A { + method() {} +} +export class B extends A { + method() {} +} +export class C extends A { + override method() {} +} + +// @filename: file3.ts +// @ts-noImplicitOverride false +export class A { + method() {} +} +export class B extends A { + method() {} +} +export class C extends A { + override method() {} +} + +// @filename: file4.ts +export class A { + method() {} +} +export class B extends A { + method() {} +} +export class C extends A { + override method() {} +} \ No newline at end of file diff --git a/tests/cases/conformance/pragma/noImplicitOverride/noImplicitOverridePragma2.ts b/tests/cases/conformance/pragma/noImplicitOverride/noImplicitOverridePragma2.ts new file mode 100644 index 0000000000000..9170fe92d6841 --- /dev/null +++ b/tests/cases/conformance/pragma/noImplicitOverride/noImplicitOverridePragma2.ts @@ -0,0 +1,47 @@ +// @noImplicitOverride: true +// @filename: file1.ts +// @ts-noImplicitOverride +export class A { + method() {} +} +export class B extends A { + method() {} +} +export class C extends A { + override method() {} +} + +// @filename: file2.ts +// @ts-noImplicitOverride true +export class A { + method() {} +} +export class B extends A { + method() {} +} +export class C extends A { + override method() {} +} + +// @filename: file3.ts +// @ts-noImplicitOverride false +export class A { + method() {} +} +export class B extends A { + method() {} +} +export class C extends A { + override method() {} +} + +// @filename: file4.ts +export class A { + method() {} +} +export class B extends A { + method() {} +} +export class C extends A { + override method() {} +} \ No newline at end of file diff --git a/tests/cases/conformance/pragma/noImplicitReturns/noImplicitReturnsPragma1.ts b/tests/cases/conformance/pragma/noImplicitReturns/noImplicitReturnsPragma1.ts new file mode 100644 index 0000000000000..e0aee75f2a4bf --- /dev/null +++ b/tests/cases/conformance/pragma/noImplicitReturns/noImplicitReturnsPragma1.ts @@ -0,0 +1,30 @@ +// @filename: file1.ts +// @ts-noImplicitReturns +export function f1(): string | undefined { + if (!!f1) { + return ""; + } +} + +// @filename: file2.ts +// @ts-noImplicitReturns true +export function f1(): string | undefined { + if (!!f1) { + return ""; + } +} + +// @filename: file3.ts +// @ts-noImplicitReturns false +export function f1(): string | undefined { + if (!!f1) { + return ""; + } +} + +// @filename: file4.ts +export function f1(): string | undefined { + if (!!f1) { + return ""; + } +} \ No newline at end of file diff --git a/tests/cases/conformance/pragma/noImplicitReturns/noImplicitReturnsPragma2.ts b/tests/cases/conformance/pragma/noImplicitReturns/noImplicitReturnsPragma2.ts new file mode 100644 index 0000000000000..acb0dcb6a471c --- /dev/null +++ b/tests/cases/conformance/pragma/noImplicitReturns/noImplicitReturnsPragma2.ts @@ -0,0 +1,31 @@ +// @noImplicitReturns: true +// @filename: file1.ts +// @ts-noImplicitReturns +export function f1(): string | undefined { + if (!!f1) { + return ""; + } +} + +// @filename: file2.ts +// @ts-noImplicitReturns true +export function f1(): string | undefined { + if (!!f1) { + return ""; + } +} + +// @filename: file3.ts +// @ts-noImplicitReturns false +export function f1(): string | undefined { + if (!!f1) { + return ""; + } +} + +// @filename: file4.ts +export function f1(): string | undefined { + if (!!f1) { + return ""; + } +} \ No newline at end of file diff --git a/tests/cases/conformance/pragma/noImplicitThis/noImplicitThisPragma1.ts b/tests/cases/conformance/pragma/noImplicitThis/noImplicitThisPragma1.ts new file mode 100644 index 0000000000000..e0ccaa7330e4e --- /dev/null +++ b/tests/cases/conformance/pragma/noImplicitThis/noImplicitThisPragma1.ts @@ -0,0 +1,14 @@ +// @filename: file1.ts +// @ts-noImplicitThis +const a = () => this.Math; + +// @filename: file2.ts +// @ts-noImplicitThis true +const b = () => this.Math; + +// @filename: file3.ts +// @ts-noImplicitThis false +const c = () => this.Math; + +// @filename: file4.ts +const d = () => this.Math; \ No newline at end of file diff --git a/tests/cases/conformance/pragma/noImplicitThis/noImplicitThisPragma2.ts b/tests/cases/conformance/pragma/noImplicitThis/noImplicitThisPragma2.ts new file mode 100644 index 0000000000000..f7842bcbcd3bc --- /dev/null +++ b/tests/cases/conformance/pragma/noImplicitThis/noImplicitThisPragma2.ts @@ -0,0 +1,15 @@ +// @noImplicitThis: true +// @filename: file1.ts +// @ts-noImplicitThis +const a = () => this.Math; + +// @filename: file2.ts +// @ts-noImplicitThis true +const b = () => this.Math; + +// @filename: file3.ts +// @ts-noImplicitThis false +const c = () => this.Math; + +// @filename: file4.ts +const d = () => this.Math; \ No newline at end of file diff --git a/tests/cases/conformance/pragma/noPropertyAccessFromIndexSignature/noPropertyAccessFromIndexSignaturePragma1.ts b/tests/cases/conformance/pragma/noPropertyAccessFromIndexSignature/noPropertyAccessFromIndexSignaturePragma1.ts new file mode 100644 index 0000000000000..fad80ae56fbfa --- /dev/null +++ b/tests/cases/conformance/pragma/noPropertyAccessFromIndexSignature/noPropertyAccessFromIndexSignaturePragma1.ts @@ -0,0 +1,30 @@ +// @filename: file1.ts +// @ts-noPropertyAccessFromIndexSignature +interface A { + [idx: string]: string; +} +declare var a: A; +export const b = a.something; + +// @filename: file2.ts +// @ts-noPropertyAccessFromIndexSignature true +interface A { + [idx: string]: string; +} +declare var a: A; +export const b = a.something; + +// @filename: file3.ts +// @ts-noPropertyAccessFromIndexSignature false +interface A { + [idx: string]: string; +} +declare var a: A; +export const b = a.something; + +// @filename: file4.ts +interface A { + [idx: string]: string; +} +declare var a: A; +export const b = a.something; diff --git a/tests/cases/conformance/pragma/noPropertyAccessFromIndexSignature/noPropertyAccessFromIndexSignaturePragma2.ts b/tests/cases/conformance/pragma/noPropertyAccessFromIndexSignature/noPropertyAccessFromIndexSignaturePragma2.ts new file mode 100644 index 0000000000000..b41778496336e --- /dev/null +++ b/tests/cases/conformance/pragma/noPropertyAccessFromIndexSignature/noPropertyAccessFromIndexSignaturePragma2.ts @@ -0,0 +1,31 @@ +// @noPropertyAccessFromIndexSignature: true +// @filename: file1.ts +// @ts-noPropertyAccessFromIndexSignature +interface A { + [idx: string]: string; +} +declare var a: A; +export const b = a.something; + +// @filename: file2.ts +// @ts-noPropertyAccessFromIndexSignature true +interface A { + [idx: string]: string; +} +declare var a: A; +export const b = a.something; + +// @filename: file3.ts +// @ts-noPropertyAccessFromIndexSignature false +interface A { + [idx: string]: string; +} +declare var a: A; +export const b = a.something; + +// @filename: file4.ts +interface A { + [idx: string]: string; +} +declare var a: A; +export const b = a.something; diff --git a/tests/cases/conformance/pragma/noUncheckedIndexedAccess/noUncheckedIndexedAccessPragma1.ts b/tests/cases/conformance/pragma/noUncheckedIndexedAccess/noUncheckedIndexedAccessPragma1.ts new file mode 100644 index 0000000000000..29149e0db0bbd --- /dev/null +++ b/tests/cases/conformance/pragma/noUncheckedIndexedAccess/noUncheckedIndexedAccessPragma1.ts @@ -0,0 +1,31 @@ +// @strict: true +// @filename: file1.ts +// @ts-noUncheckedIndexedAccess +interface A { + [index: string]: string; +} +declare var a: A; +export const x: string = a.something; + +// @filename: file2.ts +// @ts-noUncheckedIndexedAccess true +interface A { + [index: string]: string; +} +declare var a: A; +export const x: string = a.something; + +// @filename: file3.ts +// @ts-noUncheckedIndexedAccess false +interface A { + [index: string]: string; +} +declare var a: A; +export const x: string = a.something; + +// @filename: file4.ts +interface A { + [index: string]: string; +} +declare var a: A; +export const x: string = a.something; diff --git a/tests/cases/conformance/pragma/noUncheckedIndexedAccess/noUncheckedIndexedAccessPragma2.ts b/tests/cases/conformance/pragma/noUncheckedIndexedAccess/noUncheckedIndexedAccessPragma2.ts new file mode 100644 index 0000000000000..1ba8be4bb17af --- /dev/null +++ b/tests/cases/conformance/pragma/noUncheckedIndexedAccess/noUncheckedIndexedAccessPragma2.ts @@ -0,0 +1,32 @@ +// @strict: true +// @noUncheckedIndexedAccess: true +// @filename: file1.ts +// @ts-noUncheckedIndexedAccess +interface A { + [index: string]: string; +} +declare var a: A; +export const x: string = a.something; + +// @filename: file2.ts +// @ts-noUncheckedIndexedAccess true +interface A { + [index: string]: string; +} +declare var a: A; +export const x: string = a.something; + +// @filename: file3.ts +// @ts-noUncheckedIndexedAccess false +interface A { + [index: string]: string; +} +declare var a: A; +export const x: string = a.something; + +// @filename: file4.ts +interface A { + [index: string]: string; +} +declare var a: A; +export const x: string = a.something; diff --git a/tests/cases/conformance/pragma/noUnusedLocals/noUnusedLocalsPragma1.ts b/tests/cases/conformance/pragma/noUnusedLocals/noUnusedLocalsPragma1.ts new file mode 100644 index 0000000000000..15db6b9cb8ab4 --- /dev/null +++ b/tests/cases/conformance/pragma/noUnusedLocals/noUnusedLocalsPragma1.ts @@ -0,0 +1,18 @@ +// @filename: file1.ts +// @ts-noUnusedLocals +export {}; +let x; + +// @filename: file2.ts +// @ts-noUnusedLocals true +export {}; +let x; + +// @filename: file3.ts +// @ts-noUnusedLocals false +export {}; +let x; + +// @filename: file4.ts +export {}; +let x; diff --git a/tests/cases/conformance/pragma/noUnusedLocals/noUnusedLocalsPragma2.ts b/tests/cases/conformance/pragma/noUnusedLocals/noUnusedLocalsPragma2.ts new file mode 100644 index 0000000000000..7c232586a87a6 --- /dev/null +++ b/tests/cases/conformance/pragma/noUnusedLocals/noUnusedLocalsPragma2.ts @@ -0,0 +1,19 @@ +// @noUnusedLocals: true +// @filename: file1.ts +// @ts-noUnusedLocals +export {}; +let x; + +// @filename: file2.ts +// @ts-noUnusedLocals true +export {}; +let x; + +// @filename: file3.ts +// @ts-noUnusedLocals false +export {}; +let x; + +// @filename: file4.ts +export {}; +let x; diff --git a/tests/cases/conformance/pragma/noUnusedParameters/noUnusedParametersPragma1.ts b/tests/cases/conformance/pragma/noUnusedParameters/noUnusedParametersPragma1.ts new file mode 100644 index 0000000000000..3ec199dc428d6 --- /dev/null +++ b/tests/cases/conformance/pragma/noUnusedParameters/noUnusedParametersPragma1.ts @@ -0,0 +1,14 @@ +// @filename: file1.ts +// @ts-noUnusedParameters +export function f1(x: number) {} + +// @filename: file2.ts +// @ts-noUnusedParameters true +export function f1(x: number) {} + +// @filename: file3.ts +// @ts-noUnusedParameters false +export function f1(x: number) {} + +// @filename: file4.ts +export function f1(x: number) {} diff --git a/tests/cases/conformance/pragma/noUnusedParameters/noUnusedParametersPragma2.ts b/tests/cases/conformance/pragma/noUnusedParameters/noUnusedParametersPragma2.ts new file mode 100644 index 0000000000000..807ad1855c83c --- /dev/null +++ b/tests/cases/conformance/pragma/noUnusedParameters/noUnusedParametersPragma2.ts @@ -0,0 +1,15 @@ +// @noUnusedParameters: true +// @filename: file1.ts +// @ts-noUnusedParameters +export function f1(x: number) {} + +// @filename: file2.ts +// @ts-noUnusedParameters true +export function f1(x: number) {} + +// @filename: file3.ts +// @ts-noUnusedParameters false +export function f1(x: number) {} + +// @filename: file4.ts +export function f1(x: number) {} diff --git a/tests/cases/conformance/pragma/strict/strictPragma1.ts b/tests/cases/conformance/pragma/strict/strictPragma1.ts new file mode 100644 index 0000000000000..498dee996821a --- /dev/null +++ b/tests/cases/conformance/pragma/strict/strictPragma1.ts @@ -0,0 +1,78 @@ +// @filename: file1.ts +// @ts-strict +export function f1(x: string) {} +f1.call(undefined, 42); // wrong +f1.call(undefined, "ok"); // right + +export let a = (arg: string) => 0; +export let b = (arg: unknown) => 0; + +a = b; +b = a; + +export class A { + prop: string; + constructor() {} +} + +declare var c: { member?: string }; +c.member.charAt(0); + +// @filename: file2.ts +// @ts-strict true +export function f1(x: string) {} +f1.call(undefined, 42); // wrong +f1.call(undefined, "ok"); // right + +export let a = (arg: string) => 0; +export let b = (arg: unknown) => 0; + +a = b; +b = a; + +export class A { + prop: string; + constructor() {} +} + +declare var c: { member?: string }; +c.member.charAt(0); + +// @filename: file3.ts +// @ts-strict false +export function f1(x: string) {} +f1.call(undefined, 42); // wrong +f1.call(undefined, "ok"); // right + +export let a = (arg: string) => 0; +export let b = (arg: unknown) => 0; + +a = b; +b = a; + +export class A { + prop: string; + constructor() {} +} + +declare var c: { member?: string }; +c.member.charAt(0); + +// @filename: file4.ts +export function f1(x: string) {} +f1.call(undefined, 42); // wrong +f1.call(undefined, "ok"); // right + +export let a = (arg: string) => 0; +export let b = (arg: unknown) => 0; + +a = b; +b = a; + +export class A { + prop: string; + constructor() {} +} + +declare var c: { member?: string }; +c.member.charAt(0); diff --git a/tests/cases/conformance/pragma/strict/strictPragma2.ts b/tests/cases/conformance/pragma/strict/strictPragma2.ts new file mode 100644 index 0000000000000..23345ab665382 --- /dev/null +++ b/tests/cases/conformance/pragma/strict/strictPragma2.ts @@ -0,0 +1,79 @@ +// @strict: true +// @filename: file1.ts +// @ts-strict +export function f1(x: string) {} +f1.call(undefined, 42); // wrong +f1.call(undefined, "ok"); // right + +export let a = (arg: string) => 0; +export let b = (arg: unknown) => 0; + +a = b; +b = a; + +export class A { + prop: string; + constructor() {} +} + +declare var c: { member?: string }; +c.member.charAt(0); + +// @filename: file2.ts +// @ts-strict true +export function f1(x: string) {} +f1.call(undefined, 42); // wrong +f1.call(undefined, "ok"); // right + +export let a = (arg: string) => 0; +export let b = (arg: unknown) => 0; + +a = b; +b = a; + +export class A { + prop: string; + constructor() {} +} + +declare var c: { member?: string }; +c.member.charAt(0); + +// @filename: file3.ts +// @ts-strict false +export function f1(x: string) {} +f1.call(undefined, 42); // wrong +f1.call(undefined, "ok"); // right + +export let a = (arg: string) => 0; +export let b = (arg: unknown) => 0; + +a = b; +b = a; + +export class A { + prop: string; + constructor() {} +} + +declare var c: { member?: string }; +c.member.charAt(0); + +// @filename: file4.ts +export function f1(x: string) {} +f1.call(undefined, 42); // wrong +f1.call(undefined, "ok"); // right + +export let a = (arg: string) => 0; +export let b = (arg: unknown) => 0; + +a = b; +b = a; + +export class A { + prop: string; + constructor() {} +} + +declare var c: { member?: string }; +c.member.charAt(0); diff --git a/tests/cases/conformance/pragma/strict/strictPragma3.ts b/tests/cases/conformance/pragma/strict/strictPragma3.ts new file mode 100644 index 0000000000000..ffb6a97c3bec5 --- /dev/null +++ b/tests/cases/conformance/pragma/strict/strictPragma3.ts @@ -0,0 +1,20 @@ +// @filename: file1.ts +// @ts-strict +// @ts-strictNullChecks false +export function f1(x: string) {} +f1.call(undefined, 42); // wrong +f1.call(undefined, "ok"); // right + +export let a = (arg: string) => 0; +export let b = (arg: unknown) => 0; + +a = b; +b = a; + +export class A { + prop: string; + constructor() {} +} + +declare var c: { member?: string }; +c.member.charAt(0); diff --git a/tests/cases/conformance/pragma/strict/strictPragma4.ts b/tests/cases/conformance/pragma/strict/strictPragma4.ts new file mode 100644 index 0000000000000..3de84e5aa61bb --- /dev/null +++ b/tests/cases/conformance/pragma/strict/strictPragma4.ts @@ -0,0 +1,20 @@ +// @filename: file2.ts +// @ts-strict +// @ts-strictBindCallApply false +export function f1(x: string) {} +f1.call(undefined, 42); // wrong +f1.call(undefined, "ok"); // right + +export let a = (arg: string) => 0; +export let b = (arg: unknown) => 0; + +a = b; +b = a; + +export class A { + prop: string; + constructor() {} +} + +declare var c: { member?: string }; +c.member.charAt(0); diff --git a/tests/cases/conformance/pragma/strict/strictPragma5.ts b/tests/cases/conformance/pragma/strict/strictPragma5.ts new file mode 100644 index 0000000000000..00d0764adcdb0 --- /dev/null +++ b/tests/cases/conformance/pragma/strict/strictPragma5.ts @@ -0,0 +1,20 @@ +// @filename: file3.ts +// @ts-strict +// @ts-strictPropertyInitialization false +export function f1(x: string) {} +f1.call(undefined, 42); // wrong +f1.call(undefined, "ok"); // right + +export let a = (arg: string) => 0; +export let b = (arg: unknown) => 0; + +a = b; +b = a; + +export class A { + prop: string; + constructor() {} +} + +declare var c: { member?: string }; +c.member.charAt(0); diff --git a/tests/cases/conformance/pragma/strict/strictPragma6.ts b/tests/cases/conformance/pragma/strict/strictPragma6.ts new file mode 100644 index 0000000000000..6fa5d709524f5 --- /dev/null +++ b/tests/cases/conformance/pragma/strict/strictPragma6.ts @@ -0,0 +1,20 @@ +// @filename: file1.ts +// @ts-strict +// @ts-strictFunctionTypes false +export function f1(x: string) {} +f1.call(undefined, 42); // wrong +f1.call(undefined, "ok"); // right + +export let a = (arg: string) => 0; +export let b = (arg: unknown) => 0; + +a = b; +b = a; + +export class A { + prop: string; + constructor() {} +} + +declare var c: { member?: string }; +c.member.charAt(0); diff --git a/tests/cases/conformance/pragma/strictBindCallApply/strictBindCallApplyPragma1.ts b/tests/cases/conformance/pragma/strictBindCallApply/strictBindCallApplyPragma1.ts new file mode 100644 index 0000000000000..d050c47565462 --- /dev/null +++ b/tests/cases/conformance/pragma/strictBindCallApply/strictBindCallApplyPragma1.ts @@ -0,0 +1,22 @@ +// @filename: file1.ts +// @ts-strictBindCallApply +export function f1(x: string) {} +f1.call(undefined, 42); // wrong +f1.call(undefined, "ok"); // right + +// @filename: file2.ts +// @ts-strictBindCallApply true +export function f1(x: string) {} +f1.call(undefined, 42); // wrong +f1.call(undefined, "ok"); // right + +// @filename: file3.ts +// @ts-strictBindCallApply false +export function f1(x: string) {} +f1.call(undefined, 42); // wrong +f1.call(undefined, "ok"); // right + +// @filename: file4.ts +export function f1(x: string) {} +f1.call(undefined, 42); // wrong +f1.call(undefined, "ok"); // right diff --git a/tests/cases/conformance/pragma/strictBindCallApply/strictBindCallApplyPragma2.ts b/tests/cases/conformance/pragma/strictBindCallApply/strictBindCallApplyPragma2.ts new file mode 100644 index 0000000000000..bddc6b2619865 --- /dev/null +++ b/tests/cases/conformance/pragma/strictBindCallApply/strictBindCallApplyPragma2.ts @@ -0,0 +1,23 @@ +// @strictBindCallApply: true +// @filename: file1.ts +// @ts-strictBindCallApply +export function f1(x: string) {} +f1.call(undefined, 42); // wrong +f1.call(undefined, "ok"); // right + +// @filename: file2.ts +// @ts-strictBindCallApply true +export function f1(x: string) {} +f1.call(undefined, 42); // wrong +f1.call(undefined, "ok"); // right + +// @filename: file3.ts +// @ts-strictBindCallApply false +export function f1(x: string) {} +f1.call(undefined, 42); // wrong +f1.call(undefined, "ok"); // right + +// @filename: file4.ts +export function f1(x: string) {} +f1.call(undefined, 42); // wrong +f1.call(undefined, "ok"); // right diff --git a/tests/cases/conformance/pragma/strictFunctionTypes/strictFunctionTypesPragma1.ts b/tests/cases/conformance/pragma/strictFunctionTypes/strictFunctionTypesPragma1.ts new file mode 100644 index 0000000000000..9fe8104de56ef --- /dev/null +++ b/tests/cases/conformance/pragma/strictFunctionTypes/strictFunctionTypesPragma1.ts @@ -0,0 +1,30 @@ +// @filename: file1.ts +// @ts-strictFunctionTypes +export let a = (arg: string) => 0; +export let b = (arg: unknown) => 0; + +a = b; +b = a; + +// @filename: file2.ts +// @ts-strictFunctionTypes true +export let a = (arg: string) => 0; +export let b = (arg: unknown) => 0; + +a = b; +b = a; + +// @filename: file3.ts +// @ts-strictFunctionTypes false +export let a = (arg: string) => 0; +export let b = (arg: unknown) => 0; + +a = b; +b = a; + +// @filename: file4.ts +export let a = (arg: string) => 0; +export let b = (arg: unknown) => 0; + +a = b; +b = a; diff --git a/tests/cases/conformance/pragma/strictFunctionTypes/strictFunctionTypesPragma2.ts b/tests/cases/conformance/pragma/strictFunctionTypes/strictFunctionTypesPragma2.ts new file mode 100644 index 0000000000000..65da20e602df8 --- /dev/null +++ b/tests/cases/conformance/pragma/strictFunctionTypes/strictFunctionTypesPragma2.ts @@ -0,0 +1,31 @@ +// @strictFunctionTypes: true +// @filename: file1.ts +// @ts-strictFunctionTypes +export let a = (arg: string) => 0; +export let b = (arg: unknown) => 0; + +a = b; +b = a; + +// @filename: file2.ts +// @ts-strictFunctionTypes true +export let a = (arg: string) => 0; +export let b = (arg: unknown) => 0; + +a = b; +b = a; + +// @filename: file3.ts +// @ts-strictFunctionTypes false +export let a = (arg: string) => 0; +export let b = (arg: unknown) => 0; + +a = b; +b = a; + +// @filename: file4.ts +export let a = (arg: string) => 0; +export let b = (arg: unknown) => 0; + +a = b; +b = a; diff --git a/tests/cases/conformance/pragma/strictFunctionTypes/strictFunctionTypesPragma3.ts b/tests/cases/conformance/pragma/strictFunctionTypes/strictFunctionTypesPragma3.ts new file mode 100644 index 0000000000000..d668484f5a2e7 --- /dev/null +++ b/tests/cases/conformance/pragma/strictFunctionTypes/strictFunctionTypesPragma3.ts @@ -0,0 +1,33 @@ +// @filename: file1.ts +// @ts-strictFunctionTypes +export const a = (a: number) => 0; +export const b = (a: unknown) => 0; + +// @filename: file2.ts +// @ts-strictFunctionTypes false +export const a = (a: number) => 0; +export const b = (a: unknown) => 0; + +// @filename: file3.ts +import {a as a1, b as b1} from "./file1"; +import {a as a2, b as b2} from "./file2"; + +declare var numberArgStrict: typeof a1; +declare var numberArgLoose: typeof a2; +declare var unknownArgStrict: typeof b1; +declare var unknownArgLoose: typeof b2; + +numberArgStrict = unknownArgStrict; +unknownArgStrict = numberArgStrict; + +numberArgStrict = numberArgLoose; +numberArgLoose = numberArgStrict; + +numberArgStrict = unknownArgLoose; +unknownArgLoose = numberArgStrict; + +numberArgLoose = unknownArgLoose; +unknownArgLoose = numberArgLoose; + +numberArgLoose = unknownArgStrict; +unknownArgStrict = numberArgLoose; diff --git a/tests/cases/conformance/pragma/strictPropertyInitialization/strictPropertyInitializationPragma1.ts b/tests/cases/conformance/pragma/strictPropertyInitialization/strictPropertyInitializationPragma1.ts new file mode 100644 index 0000000000000..220968bbb277f --- /dev/null +++ b/tests/cases/conformance/pragma/strictPropertyInitialization/strictPropertyInitializationPragma1.ts @@ -0,0 +1,27 @@ +// @strictNullChecks: true +// @filename: file1.ts +// @ts-strictPropertyInitialization +export class A { + prop: string; + constructor() {} +} + +// @filename: file2.ts +// @ts-strictPropertyInitialization true +export class A { + prop: string; + constructor() {} +} + +// @filename: file3.ts +// @ts-strictPropertyInitialization false +export class A { + prop: string; + constructor() {} +} + +// @filename: file4.ts +export class A { + prop: string; + constructor() {} +} diff --git a/tests/cases/conformance/pragma/strictPropertyInitialization/strictPropertyInitializationPragma2.ts b/tests/cases/conformance/pragma/strictPropertyInitialization/strictPropertyInitializationPragma2.ts new file mode 100644 index 0000000000000..b193cb7e5994c --- /dev/null +++ b/tests/cases/conformance/pragma/strictPropertyInitialization/strictPropertyInitializationPragma2.ts @@ -0,0 +1,28 @@ +// @strictNullChecks: true +// @strictPropertyInitialization: true +// @filename: file1.ts +// @ts-strictPropertyInitialization +export class A { + prop: string; + constructor() {} +} + +// @filename: file2.ts +// @ts-strictPropertyInitialization true +export class A { + prop: string; + constructor() {} +} + +// @filename: file3.ts +// @ts-strictPropertyInitialization false +export class A { + prop: string; + constructor() {} +} + +// @filename: file4.ts +export class A { + prop: string; + constructor() {} +} diff --git a/tests/cases/conformance/pragma/useUnknownInCatchVariables/useUnknownInCatchVariablesPragma1.ts b/tests/cases/conformance/pragma/useUnknownInCatchVariables/useUnknownInCatchVariablesPragma1.ts new file mode 100644 index 0000000000000..066cf7b7c4885 --- /dev/null +++ b/tests/cases/conformance/pragma/useUnknownInCatchVariables/useUnknownInCatchVariablesPragma1.ts @@ -0,0 +1,34 @@ +// @filename: file1.ts +// @ts-useUnknownInCatchVariables +try { + +} +catch (thing) { + thing.a; +} + +// @filename: file2.ts +// @ts-useUnknownInCatchVariables true +try { + +} +catch (thing) { + thing.a; +} + +// @filename: file3.ts +// @ts-useUnknownInCatchVariables false +try { + +} +catch (thing) { + thing.a; +} + +// @filename: file4.ts +try { + +} +catch (thing) { + thing.a; +} diff --git a/tests/cases/conformance/pragma/useUnknownInCatchVariables/useUnknownInCatchVariablesPragma2.ts b/tests/cases/conformance/pragma/useUnknownInCatchVariables/useUnknownInCatchVariablesPragma2.ts new file mode 100644 index 0000000000000..cc5a00daabd82 --- /dev/null +++ b/tests/cases/conformance/pragma/useUnknownInCatchVariables/useUnknownInCatchVariablesPragma2.ts @@ -0,0 +1,35 @@ +// @useUnknownInCatchVariables: true +// @filename: file1.ts +// @ts-useUnknownInCatchVariables +try { + +} +catch (thing) { + thing.a; +} + +// @filename: file2.ts +// @ts-useUnknownInCatchVariables true +try { + +} +catch (thing) { + thing.a; +} + +// @filename: file3.ts +// @ts-useUnknownInCatchVariables false +try { + +} +catch (thing) { + thing.a; +} + +// @filename: file4.ts +try { + +} +catch (thing) { + thing.a; +} From e25d5a8ca5a47c12c2ab25f38e0ac2e8d8726b16 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Wed, 31 Aug 2022 11:00:30 -0700 Subject: [PATCH 05/24] Error on duplicate local compiler options --- src/compiler/diagnosticMessages.json | 5 +++++ src/compiler/program.ts | 12 ++++++++++++ src/compiler/utilities.ts | 10 +++++++++- .../duplicateLocalPragmas1.errors.txt | 13 +++++++++++++ .../reference/duplicateLocalPragmas1.js | 18 ++++++++++++++++++ .../reference/duplicateLocalPragmas1.symbols | 6 ++++++ .../reference/duplicateLocalPragmas1.types | 6 ++++++ .../pragma/duplicateLocalPragmas1.ts | 3 +++ 8 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/duplicateLocalPragmas1.errors.txt create mode 100644 tests/baselines/reference/duplicateLocalPragmas1.js create mode 100644 tests/baselines/reference/duplicateLocalPragmas1.symbols create mode 100644 tests/baselines/reference/duplicateLocalPragmas1.types create mode 100644 tests/cases/conformance/pragma/duplicateLocalPragmas1.ts diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 54b131fa32ae6..2bb82233a0a73 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -900,6 +900,11 @@ "code": 1274 }, + "Duplicate local compiler option '{0}'.": { + "category": "Error", + "code": 1280 + }, + "'with' statements are not allowed in an async function block.": { "category": "Error", "code": 1300 diff --git a/src/compiler/program.ts b/src/compiler/program.ts index d7afe81bdaf4e..c95d0ccca7bdf 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -3662,6 +3662,18 @@ namespace ts { }); } + for (const file of files) { + const entries = file.pragmas.entries(); + for (let result = entries.next(); !result.done; result = entries.next()) { + const [key, value] = result.value; + if (startsWith(key, "ts-") && key !== "ts-check" && key !== "ts-nocheck" && isArray(value)) { + for (const elem of value) { + programDiagnostics.add(createDiagnosticForRange(file, elem.range, Diagnostics.Duplicate_local_compiler_option_0, key.slice(3))); + } + } + } + } + // Verify that all the emit files are unique and don't overwrite input files function verifyEmitFilePath(emitFileName: string | undefined, emitFilesSeen: Set) { if (emitFileName) { diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index c3ed467d5ea76..62aad514b6132 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -1101,14 +1101,22 @@ namespace ts { } : diagnostic.messageText; } + + export function createDiagnosticForRange(sourceFile: SourceFile, range: TextRange, message: DiagnosticMessage, ...args: (string | number | undefined)[]): DiagnosticWithLocation; export function createDiagnosticForRange(sourceFile: SourceFile, range: TextRange, message: DiagnosticMessage): DiagnosticWithLocation { + let text = getLocaleSpecificMessage(message); + + if (arguments.length > 3) { + text = formatStringFromArgs(text, arguments, 3); + } + return { file: sourceFile, start: range.pos, length: range.end - range.pos, code: message.code, category: message.category, - messageText: message.message, + messageText: text, }; } diff --git a/tests/baselines/reference/duplicateLocalPragmas1.errors.txt b/tests/baselines/reference/duplicateLocalPragmas1.errors.txt new file mode 100644 index 0000000000000..f1ce32ebea627 --- /dev/null +++ b/tests/baselines/reference/duplicateLocalPragmas1.errors.txt @@ -0,0 +1,13 @@ +tests/cases/conformance/pragma/duplicateLocalPragmas1.ts(1,1): error TS1280: Duplicate local compiler option 'strict'. +tests/cases/conformance/pragma/duplicateLocalPragmas1.ts(2,1): error TS1280: Duplicate local compiler option 'strict'. + + +==== tests/cases/conformance/pragma/duplicateLocalPragmas1.ts (2 errors) ==== + // @ts-strict + ~~~~~~~~~~~~~ +!!! error TS1280: Duplicate local compiler option 'strict'. + // @ts-strict + ~~~~~~~~~~~~~ +!!! error TS1280: Duplicate local compiler option 'strict'. + export class A {} + \ No newline at end of file diff --git a/tests/baselines/reference/duplicateLocalPragmas1.js b/tests/baselines/reference/duplicateLocalPragmas1.js new file mode 100644 index 0000000000000..4f76cdcefe21b --- /dev/null +++ b/tests/baselines/reference/duplicateLocalPragmas1.js @@ -0,0 +1,18 @@ +//// [duplicateLocalPragmas1.ts] +// @ts-strict +// @ts-strict +export class A {} + + +//// [duplicateLocalPragmas1.js] +"use strict"; +exports.__esModule = true; +exports.A = void 0; +// @ts-strict +// @ts-strict +var A = /** @class */ (function () { + function A() { + } + return A; +}()); +exports.A = A; diff --git a/tests/baselines/reference/duplicateLocalPragmas1.symbols b/tests/baselines/reference/duplicateLocalPragmas1.symbols new file mode 100644 index 0000000000000..e76253c5bd3ab --- /dev/null +++ b/tests/baselines/reference/duplicateLocalPragmas1.symbols @@ -0,0 +1,6 @@ +=== tests/cases/conformance/pragma/duplicateLocalPragmas1.ts === +// @ts-strict +// @ts-strict +export class A {} +>A : Symbol(A, Decl(duplicateLocalPragmas1.ts, 0, 0)) + diff --git a/tests/baselines/reference/duplicateLocalPragmas1.types b/tests/baselines/reference/duplicateLocalPragmas1.types new file mode 100644 index 0000000000000..ed1716d3e11af --- /dev/null +++ b/tests/baselines/reference/duplicateLocalPragmas1.types @@ -0,0 +1,6 @@ +=== tests/cases/conformance/pragma/duplicateLocalPragmas1.ts === +// @ts-strict +// @ts-strict +export class A {} +>A : A + diff --git a/tests/cases/conformance/pragma/duplicateLocalPragmas1.ts b/tests/cases/conformance/pragma/duplicateLocalPragmas1.ts new file mode 100644 index 0000000000000..c8bc9cc2a6723 --- /dev/null +++ b/tests/cases/conformance/pragma/duplicateLocalPragmas1.ts @@ -0,0 +1,3 @@ +// @ts-strict +// @ts-strict +export class A {} From 5b336c6262cceaa07afd05067c61928e55e7435b Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Wed, 31 Aug 2022 11:09:40 -0700 Subject: [PATCH 06/24] Fix lint --- src/compiler/utilities.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 62aad514b6132..34280d676a44d 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -1101,7 +1101,6 @@ namespace ts { } : diagnostic.messageText; } - export function createDiagnosticForRange(sourceFile: SourceFile, range: TextRange, message: DiagnosticMessage, ...args: (string | number | undefined)[]): DiagnosticWithLocation; export function createDiagnosticForRange(sourceFile: SourceFile, range: TextRange, message: DiagnosticMessage): DiagnosticWithLocation { let text = getLocaleSpecificMessage(message); From 562f5ea4772a667a4eafaaaa5877ab7692676310 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Wed, 31 Aug 2022 11:36:46 -0700 Subject: [PATCH 07/24] Remove non-ignored old script again --- scripts/authors.js | 163 --------------------------------------------- 1 file changed, 163 deletions(-) delete mode 100644 scripts/authors.js diff --git a/scripts/authors.js b/scripts/authors.js deleted file mode 100644 index 79f98634df4ad..0000000000000 --- a/scripts/authors.js +++ /dev/null @@ -1,163 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -const fs = require("fs"); -const path = require("path"); -const childProcess = require("child_process"); -const mailMapPath = path.resolve(__dirname, "../.mailmap"); -const authorsPath = path.resolve(__dirname, "../AUTHORS.md"); -function getKnownAuthors() { - const segmentRegExp = /\s?([^<]+)\s+<([^>]+)>/g; - const preferredNameRegeExp = /\s?#\s?([^#]+)$/; - const knownAuthors = []; - if (!fs.existsSync(mailMapPath)) { - throw new Error(`Could not load known users form .mailmap file at: ${mailMapPath}`); - } - const mailMap = fs.readFileSync(mailMapPath).toString(); - for (const line of mailMap.split("\r\n")) { - const author = { displayNames: [], emails: [] }; - let match; - while (match = segmentRegExp.exec(line)) { - author.displayNames.push(match[1]); - author.emails.push(match[2]); - } - if (match = preferredNameRegeExp.exec(line)) { - author.preferredName = match[1]; - } - if (!author.emails) - continue; - knownAuthors.push(author); - if (line.indexOf("#") > 0 && !author.preferredName) { - throw new Error("Could not match preferred name for: " + line); - } - // console.log("===> line: " + line); - // console.log(JSON.stringify(author, undefined, 2)); - } - return knownAuthors; -} -function getAuthorName(author) { - return author.preferredName || author.displayNames[0]; -} -function getKnownAuthorMaps() { - const knownAuthors = getKnownAuthors(); - const authorsByName = {}; - const authorsByEmail = {}; - knownAuthors.forEach(author => { - author.displayNames.forEach(n => authorsByName[n] = author); - author.emails.forEach(e => authorsByEmail[e.toLocaleLowerCase()] = author); - }); - return { - knownAuthors, - authorsByName, - authorsByEmail - }; -} -function deduplicate(array) { - const result = []; - if (array) { - for (const item of array) { - if (result.indexOf(item) < 0) { - result.push(item); - } - } - } - return result; -} -function log(s) { - console.log(` ${s}`); -} -function sortAuthors(a, b) { - if (a.charAt(0) === "@") - a = a.substr(1); - if (b.charAt(0) === "@") - b = b.substr(1); - if (a.toLocaleLowerCase() < b.toLocaleLowerCase()) { - return -1; - } - else { - return 1; - } -} -var Commands; -(function (Commands) { - Commands.writeAuthors = () => { - const output = deduplicate(getKnownAuthors().map(getAuthorName).filter(a => !!a)).sort(sortAuthors).join("\r\n* "); - fs.writeFileSync(authorsPath, "TypeScript is authored by:\r\n* " + output); - }; - Commands.writeAuthors.description = "Write known authors to AUTHORS.md file."; - Commands.listKnownAuthors = () => { - deduplicate(getKnownAuthors().map(getAuthorName)).filter(a => !!a).sort(sortAuthors).forEach(log); - }; - Commands.listKnownAuthors.description = "List known authors as listed in .mailmap file."; - Commands.listAuthors = (...specs) => { - const cmd = "git shortlog -se " + specs.join(" "); - console.log(cmd); - const outputRegExp = /\d+\s+([^<]+)<([^>]+)>/; - const authors = []; - const { output: [error, stdout, stderr] } = childProcess.spawnSync(`git`, ["shortlog", "-se", ...specs], { cwd: path.resolve(__dirname, "../") }); - if (error) { - console.log(stderr.toString()); - } - else { - const output = stdout.toString(); - const lines = output.split("\n"); - lines.forEach(line => { - if (line) { - let match; - if (match = outputRegExp.exec(line)) { - authors.push({ name: match[1], email: match[2] }); - } - else { - throw new Error("Could not parse output: " + line); - } - } - }); - const maps = getKnownAuthorMaps(); - const lookupAuthor = ({ name, email }) => { - return maps.authorsByEmail[email.toLocaleLowerCase()] || maps.authorsByName[name]; - }; - const knownAuthors = authors - .map(lookupAuthor) - .filter(a => !!a) - .map(getAuthorName); - const unknownAuthors = authors - .filter(a => !lookupAuthor(a)) - .map(a => `${a.name} <${a.email}>`); - if (knownAuthors.length) { - console.log("\r\n"); - console.log("Found known authors: "); - console.log("====================="); - deduplicate(knownAuthors).sort(sortAuthors).forEach(log); - } - if (unknownAuthors.length) { - console.log("\r\n"); - console.log("Found unknown authors: "); - console.log("====================="); - deduplicate(unknownAuthors).sort(sortAuthors).forEach(log); - } - const allAuthors = deduplicate([...knownAuthors, ...unknownAuthors].map(a => a.split("<")[0].trim())).sort(sortAuthors); - if (allAuthors.length) { - console.log("\r\n"); - console.log("Revised Authors.md: "); - console.log("====================="); - allAuthors.forEach(name => console.log(" - " + name)); - } - } - }; - Commands.listAuthors.description = "List known and unknown authors for a given spec, e.g. 'node authors.js listAuthors origin/release-2.6..origin/release-2.7'"; -})(Commands || (Commands = {})); -const args = process.argv.slice(2); -if (args.length < 1) { - console.log("Usage: node authors.js [command]"); - console.log("List of commands: "); - Object.keys(Commands).forEach(k => console.log(` ${k}: ${Commands[k].description}`)); -} -else { - const cmd = Commands[args[0]]; - if (cmd === undefined) { - console.log("Unknown command " + args[1]); - } - else { - cmd.apply(undefined, args.slice(1)); - } -} -//# sourceMappingURL=authors.js.map \ No newline at end of file From 84b15d9d63634e6e79517e8c1c1fbe0cb3147568 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Wed, 31 Aug 2022 11:56:48 -0700 Subject: [PATCH 08/24] Test & for for local boolean option with invalid argument type --- src/compiler/parser.ts | 15 +++++++++++++-- .../incorrectPragmaOptionType1.errors.txt | 9 +++++++++ .../reference/incorrectPragmaOptionType1.js | 16 ++++++++++++++++ .../reference/incorrectPragmaOptionType1.symbols | 5 +++++ .../reference/incorrectPragmaOptionType1.types | 5 +++++ .../pragma/incorrectPragmaOptionType1.ts | 2 ++ 6 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 tests/baselines/reference/incorrectPragmaOptionType1.errors.txt create mode 100644 tests/baselines/reference/incorrectPragmaOptionType1.js create mode 100644 tests/baselines/reference/incorrectPragmaOptionType1.symbols create mode 100644 tests/baselines/reference/incorrectPragmaOptionType1.types create mode 100644 tests/cases/conformance/pragma/incorrectPragmaOptionType1.ts diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 1cbcbd73a453d..9ed6bb84f1f86 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -9854,9 +9854,20 @@ namespace ts { const opt = find(optionsAllowedAsPragmaOption, o => o.name.toLowerCase() === optName)!; const entry = (isArray(entryOrList) ? last(entryOrList) : entryOrList); const unparsedValue = (entry.arguments as PragmaArgumentType<`ts-${Lowercase}`>).value; - const optContainer: OptionsBase = {}; + let parsedValue: OptionsBase[string]; const errors: Diagnostic[] = []; - const parsedValue = unparsedValue === undefined ? true : (parseOptionValue([unparsedValue], 0, /*diagnostics*/ undefined, opt, optContainer, errors), optContainer[opt.name]); + if (!unparsedValue || !trimString(unparsedValue)) { + parsedValue = true; + } + else { + const optContainer: OptionsBase = {}; + const newIdx = parseOptionValue([unparsedValue], 0, /*diagnostics*/ undefined, opt, optContainer, errors); + parsedValue = optContainer[opt.name]; + if (newIdx === 0) { + // argument was not consumed, issue an error + errors.push(createCompilerDiagnostic(Diagnostics.Compiler_option_0_requires_a_value_of_type_1, optName, opt.type)); + } + } if (unparsedValue === undefined && opt.type !== "boolean") { errors.push(createCompilerDiagnostic(Diagnostics.Compiler_option_0_expects_an_argument, optName)); } diff --git a/tests/baselines/reference/incorrectPragmaOptionType1.errors.txt b/tests/baselines/reference/incorrectPragmaOptionType1.errors.txt new file mode 100644 index 0000000000000..46a63b659037d --- /dev/null +++ b/tests/baselines/reference/incorrectPragmaOptionType1.errors.txt @@ -0,0 +1,9 @@ +tests/cases/conformance/pragma/incorrectPragmaOptionType1.ts(1,1): error TS5024: Compiler option 'strict' requires a value of type boolean. + + +==== tests/cases/conformance/pragma/incorrectPragmaOptionType1.ts (1 errors) ==== + // @ts-strict 42 + ~~~~~~~~~~~~~~~~ +!!! error TS5024: Compiler option 'strict' requires a value of type boolean. + export class A {} + \ No newline at end of file diff --git a/tests/baselines/reference/incorrectPragmaOptionType1.js b/tests/baselines/reference/incorrectPragmaOptionType1.js new file mode 100644 index 0000000000000..0efc04729d237 --- /dev/null +++ b/tests/baselines/reference/incorrectPragmaOptionType1.js @@ -0,0 +1,16 @@ +//// [incorrectPragmaOptionType1.ts] +// @ts-strict 42 +export class A {} + + +//// [incorrectPragmaOptionType1.js] +"use strict"; +exports.__esModule = true; +exports.A = void 0; +// @ts-strict 42 +var A = /** @class */ (function () { + function A() { + } + return A; +}()); +exports.A = A; diff --git a/tests/baselines/reference/incorrectPragmaOptionType1.symbols b/tests/baselines/reference/incorrectPragmaOptionType1.symbols new file mode 100644 index 0000000000000..6e3299596c5d2 --- /dev/null +++ b/tests/baselines/reference/incorrectPragmaOptionType1.symbols @@ -0,0 +1,5 @@ +=== tests/cases/conformance/pragma/incorrectPragmaOptionType1.ts === +// @ts-strict 42 +export class A {} +>A : Symbol(A, Decl(incorrectPragmaOptionType1.ts, 0, 0)) + diff --git a/tests/baselines/reference/incorrectPragmaOptionType1.types b/tests/baselines/reference/incorrectPragmaOptionType1.types new file mode 100644 index 0000000000000..26b42eac5089a --- /dev/null +++ b/tests/baselines/reference/incorrectPragmaOptionType1.types @@ -0,0 +1,5 @@ +=== tests/cases/conformance/pragma/incorrectPragmaOptionType1.ts === +// @ts-strict 42 +export class A {} +>A : A + diff --git a/tests/cases/conformance/pragma/incorrectPragmaOptionType1.ts b/tests/cases/conformance/pragma/incorrectPragmaOptionType1.ts new file mode 100644 index 0000000000000..abd7bd3656970 --- /dev/null +++ b/tests/cases/conformance/pragma/incorrectPragmaOptionType1.ts @@ -0,0 +1,2 @@ +// @ts-strict 42 +export class A {} From 1050e184b8b759dd17d1363c4f0b6262a4aa616e Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Wed, 31 Aug 2022 11:59:46 -0700 Subject: [PATCH 09/24] Test showing unknown pragma behavior --- .../baselines/reference/nonExistantPragma1.js | 18 ++++++++++++++++++ .../reference/nonExistantPragma1.symbols | 6 ++++++ .../reference/nonExistantPragma1.types | 6 ++++++ .../conformance/pragma/nonExistantPragma1.ts | 3 +++ 4 files changed, 33 insertions(+) create mode 100644 tests/baselines/reference/nonExistantPragma1.js create mode 100644 tests/baselines/reference/nonExistantPragma1.symbols create mode 100644 tests/baselines/reference/nonExistantPragma1.types create mode 100644 tests/cases/conformance/pragma/nonExistantPragma1.ts diff --git a/tests/baselines/reference/nonExistantPragma1.js b/tests/baselines/reference/nonExistantPragma1.js new file mode 100644 index 0000000000000..9b1f5c8f168d4 --- /dev/null +++ b/tests/baselines/reference/nonExistantPragma1.js @@ -0,0 +1,18 @@ +//// [nonExistantPragma1.ts] +// @ts-thisOptionDoesNotExist +// unknown option is ignored +export class A {} + + +//// [nonExistantPragma1.js] +"use strict"; +exports.__esModule = true; +exports.A = void 0; +// @ts-thisOptionDoesNotExist +// unknown option is ignored +var A = /** @class */ (function () { + function A() { + } + return A; +}()); +exports.A = A; diff --git a/tests/baselines/reference/nonExistantPragma1.symbols b/tests/baselines/reference/nonExistantPragma1.symbols new file mode 100644 index 0000000000000..e0a754623c3c4 --- /dev/null +++ b/tests/baselines/reference/nonExistantPragma1.symbols @@ -0,0 +1,6 @@ +=== tests/cases/conformance/pragma/nonExistantPragma1.ts === +// @ts-thisOptionDoesNotExist +// unknown option is ignored +export class A {} +>A : Symbol(A, Decl(nonExistantPragma1.ts, 0, 0)) + diff --git a/tests/baselines/reference/nonExistantPragma1.types b/tests/baselines/reference/nonExistantPragma1.types new file mode 100644 index 0000000000000..3a5f7c72cf3e7 --- /dev/null +++ b/tests/baselines/reference/nonExistantPragma1.types @@ -0,0 +1,6 @@ +=== tests/cases/conformance/pragma/nonExistantPragma1.ts === +// @ts-thisOptionDoesNotExist +// unknown option is ignored +export class A {} +>A : A + diff --git a/tests/cases/conformance/pragma/nonExistantPragma1.ts b/tests/cases/conformance/pragma/nonExistantPragma1.ts new file mode 100644 index 0000000000000..8527b5de1f0a7 --- /dev/null +++ b/tests/cases/conformance/pragma/nonExistantPragma1.ts @@ -0,0 +1,3 @@ +// @ts-thisOptionDoesNotExist +// unknown option is ignored +export class A {} From 6492a764fbbb8431a021f4d24aae60dd8d1a2aeb Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Wed, 31 Aug 2022 13:12:36 -0700 Subject: [PATCH 10/24] Use permissive undefined in loose mode control flow --- src/compiler/checker.ts | 2 +- ...cksUndefinedNarrowingAssignableToNumber.js | 30 +++++++++++++ ...definedNarrowingAssignableToNumber.symbols | 32 ++++++++++++++ ...UndefinedNarrowingAssignableToNumber.types | 43 +++++++++++++++++++ .../reference/typeGuardTypeOfUndefined.types | 6 +-- ...cksUndefinedNarrowingAssignableToNumber.ts | 12 ++++++ 6 files changed, 121 insertions(+), 4 deletions(-) create mode 100644 tests/baselines/reference/nonStrictNullChecksUndefinedNarrowingAssignableToNumber.js create mode 100644 tests/baselines/reference/nonStrictNullChecksUndefinedNarrowingAssignableToNumber.symbols create mode 100644 tests/baselines/reference/nonStrictNullChecksUndefinedNarrowingAssignableToNumber.types create mode 100644 tests/cases/compiler/nonStrictNullChecksUndefinedNarrowingAssignableToNumber.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index d636e167d1455..ea67a7f0ee3e2 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -25500,7 +25500,7 @@ namespace ts { case "symbol": return narrowTypeByTypeFacts(type, esSymbolType, TypeFacts.TypeofEQSymbol); case "object": return type.flags & TypeFlags.Any ? type : getUnionType([narrowTypeByTypeFacts(type, nonPrimitiveType, TypeFacts.TypeofEQObject), narrowTypeByTypeFacts(type, nullType, TypeFacts.EQNull)]); case "function": return type.flags & TypeFlags.Any ? type : narrowTypeByTypeFacts(type, globalFunctionType, TypeFacts.TypeofEQFunction); - case "undefined": return narrowTypeByTypeFacts(type, undefinedType, TypeFacts.EQUndefined); + case "undefined": return narrowTypeByTypeFacts(type, strictNullChecks(reference) ? undefinedType : undefinedPermissiveType, TypeFacts.EQUndefined); } return narrowTypeByTypeFacts(type, nonPrimitiveType, TypeFacts.TypeofEQHostObject); } diff --git a/tests/baselines/reference/nonStrictNullChecksUndefinedNarrowingAssignableToNumber.js b/tests/baselines/reference/nonStrictNullChecksUndefinedNarrowingAssignableToNumber.js new file mode 100644 index 0000000000000..1604f7858dd39 --- /dev/null +++ b/tests/baselines/reference/nonStrictNullChecksUndefinedNarrowingAssignableToNumber.js @@ -0,0 +1,30 @@ +//// [nonStrictNullChecksUndefinedNarrowingAssignableToNumber.ts] +export function hash(obj: any, hashVal = 0): number { + switch (typeof obj) { + case 'number': + return numberHash(obj, hashVal); + case 'undefined': + return numberHash(obj, 937); + default: + return numberHash(obj, 617); + } +} + +declare function numberHash(val: number, initialHashVal: number): number; + +//// [nonStrictNullChecksUndefinedNarrowingAssignableToNumber.js] +"use strict"; +exports.__esModule = true; +exports.hash = void 0; +function hash(obj, hashVal) { + if (hashVal === void 0) { hashVal = 0; } + switch (typeof obj) { + case 'number': + return numberHash(obj, hashVal); + case 'undefined': + return numberHash(obj, 937); + default: + return numberHash(obj, 617); + } +} +exports.hash = hash; diff --git a/tests/baselines/reference/nonStrictNullChecksUndefinedNarrowingAssignableToNumber.symbols b/tests/baselines/reference/nonStrictNullChecksUndefinedNarrowingAssignableToNumber.symbols new file mode 100644 index 0000000000000..5a94040e24f40 --- /dev/null +++ b/tests/baselines/reference/nonStrictNullChecksUndefinedNarrowingAssignableToNumber.symbols @@ -0,0 +1,32 @@ +=== tests/cases/compiler/nonStrictNullChecksUndefinedNarrowingAssignableToNumber.ts === +export function hash(obj: any, hashVal = 0): number { +>hash : Symbol(hash, Decl(nonStrictNullChecksUndefinedNarrowingAssignableToNumber.ts, 0, 0)) +>obj : Symbol(obj, Decl(nonStrictNullChecksUndefinedNarrowingAssignableToNumber.ts, 0, 21)) +>hashVal : Symbol(hashVal, Decl(nonStrictNullChecksUndefinedNarrowingAssignableToNumber.ts, 0, 30)) + + switch (typeof obj) { +>obj : Symbol(obj, Decl(nonStrictNullChecksUndefinedNarrowingAssignableToNumber.ts, 0, 21)) + + case 'number': + return numberHash(obj, hashVal); +>numberHash : Symbol(numberHash, Decl(nonStrictNullChecksUndefinedNarrowingAssignableToNumber.ts, 9, 1)) +>obj : Symbol(obj, Decl(nonStrictNullChecksUndefinedNarrowingAssignableToNumber.ts, 0, 21)) +>hashVal : Symbol(hashVal, Decl(nonStrictNullChecksUndefinedNarrowingAssignableToNumber.ts, 0, 30)) + + case 'undefined': + return numberHash(obj, 937); +>numberHash : Symbol(numberHash, Decl(nonStrictNullChecksUndefinedNarrowingAssignableToNumber.ts, 9, 1)) +>obj : Symbol(obj, Decl(nonStrictNullChecksUndefinedNarrowingAssignableToNumber.ts, 0, 21)) + + default: + return numberHash(obj, 617); +>numberHash : Symbol(numberHash, Decl(nonStrictNullChecksUndefinedNarrowingAssignableToNumber.ts, 9, 1)) +>obj : Symbol(obj, Decl(nonStrictNullChecksUndefinedNarrowingAssignableToNumber.ts, 0, 21)) + } +} + +declare function numberHash(val: number, initialHashVal: number): number; +>numberHash : Symbol(numberHash, Decl(nonStrictNullChecksUndefinedNarrowingAssignableToNumber.ts, 9, 1)) +>val : Symbol(val, Decl(nonStrictNullChecksUndefinedNarrowingAssignableToNumber.ts, 11, 28)) +>initialHashVal : Symbol(initialHashVal, Decl(nonStrictNullChecksUndefinedNarrowingAssignableToNumber.ts, 11, 40)) + diff --git a/tests/baselines/reference/nonStrictNullChecksUndefinedNarrowingAssignableToNumber.types b/tests/baselines/reference/nonStrictNullChecksUndefinedNarrowingAssignableToNumber.types new file mode 100644 index 0000000000000..21a646ce942f9 --- /dev/null +++ b/tests/baselines/reference/nonStrictNullChecksUndefinedNarrowingAssignableToNumber.types @@ -0,0 +1,43 @@ +=== tests/cases/compiler/nonStrictNullChecksUndefinedNarrowingAssignableToNumber.ts === +export function hash(obj: any, hashVal = 0): number { +>hash : (obj: any, hashVal?: number) => number +>obj : any +>hashVal : number +>0 : 0 + + switch (typeof obj) { +>typeof obj : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function" +>obj : any + + case 'number': +>'number' : "number" + + return numberHash(obj, hashVal); +>numberHash(obj, hashVal) : number +>numberHash : (val: number, initialHashVal: number) => number +>obj : number +>hashVal : number + + case 'undefined': +>'undefined' : "undefined" + + return numberHash(obj, 937); +>numberHash(obj, 937) : number +>numberHash : (val: number, initialHashVal: number) => number +>obj : undefined +>937 : 937 + + default: + return numberHash(obj, 617); +>numberHash(obj, 617) : number +>numberHash : (val: number, initialHashVal: number) => number +>obj : any +>617 : 617 + } +} + +declare function numberHash(val: number, initialHashVal: number): number; +>numberHash : (val: number, initialHashVal: number) => number +>val : number +>initialHashVal : number + diff --git a/tests/baselines/reference/typeGuardTypeOfUndefined.types b/tests/baselines/reference/typeGuardTypeOfUndefined.types index ffc82e57e6693..79f87e101caa8 100644 --- a/tests/baselines/reference/typeGuardTypeOfUndefined.types +++ b/tests/baselines/reference/typeGuardTypeOfUndefined.types @@ -242,7 +242,7 @@ function test9(a: boolean | number) { } else { a; ->a : never +>a : undefined } } @@ -259,7 +259,7 @@ function test10(a: boolean | number) { if (typeof a === "boolean") { >typeof a === "boolean" : boolean >typeof a : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function" ->a : never +>a : undefined >"boolean" : "boolean" a; @@ -267,7 +267,7 @@ function test10(a: boolean | number) { } else { a; ->a : never +>a : undefined } } else { diff --git a/tests/cases/compiler/nonStrictNullChecksUndefinedNarrowingAssignableToNumber.ts b/tests/cases/compiler/nonStrictNullChecksUndefinedNarrowingAssignableToNumber.ts new file mode 100644 index 0000000000000..386f639108024 --- /dev/null +++ b/tests/cases/compiler/nonStrictNullChecksUndefinedNarrowingAssignableToNumber.ts @@ -0,0 +1,12 @@ +export function hash(obj: any, hashVal = 0): number { + switch (typeof obj) { + case 'number': + return numberHash(obj, hashVal); + case 'undefined': + return numberHash(obj, 937); + default: + return numberHash(obj, 617); + } +} + +declare function numberHash(val: number, initialHashVal: number): number; \ No newline at end of file From c8695977b98d9f88a0c73e880d135d530e716954 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Wed, 31 Aug 2022 13:23:59 -0700 Subject: [PATCH 11/24] Avoid introducing null in control flow in non-strict checking modes --- src/compiler/checker.ts | 2 +- .../inDoesNotOperateOnPrimitiveTypes.types | 4 +- ...NullChecksNoNullIntroducedByControlFlow.js | 36 +++++++++ ...hecksNoNullIntroducedByControlFlow.symbols | 55 +++++++++++++ ...lChecksNoNullIntroducedByControlFlow.types | 80 +++++++++++++++++++ ...NullChecksNoNullIntroducedByControlFlow.ts | 14 ++++ 6 files changed, 188 insertions(+), 3 deletions(-) create mode 100644 tests/baselines/reference/nonStrictNullChecksNoNullIntroducedByControlFlow.js create mode 100644 tests/baselines/reference/nonStrictNullChecksNoNullIntroducedByControlFlow.symbols create mode 100644 tests/baselines/reference/nonStrictNullChecksNoNullIntroducedByControlFlow.types create mode 100644 tests/cases/compiler/nonStrictNullChecksNoNullIntroducedByControlFlow.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ea67a7f0ee3e2..3869c9949425e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -25498,7 +25498,7 @@ namespace ts { case "bigint": return narrowTypeByTypeFacts(type, bigintType, TypeFacts.TypeofEQBigInt); case "boolean": return narrowTypeByTypeFacts(type, booleanType, TypeFacts.TypeofEQBoolean); case "symbol": return narrowTypeByTypeFacts(type, esSymbolType, TypeFacts.TypeofEQSymbol); - case "object": return type.flags & TypeFlags.Any ? type : getUnionType([narrowTypeByTypeFacts(type, nonPrimitiveType, TypeFacts.TypeofEQObject), narrowTypeByTypeFacts(type, nullType, TypeFacts.EQNull)]); + case "object": return type.flags & TypeFlags.Any ? type : getUnionType([narrowTypeByTypeFacts(type, nonPrimitiveType, TypeFacts.TypeofEQObject), strictNullChecks(reference) ? narrowTypeByTypeFacts(type, nullType, TypeFacts.EQNull) : neverType]); case "function": return type.flags & TypeFlags.Any ? type : narrowTypeByTypeFacts(type, globalFunctionType, TypeFacts.TypeofEQFunction); case "undefined": return narrowTypeByTypeFacts(type, strictNullChecks(reference) ? undefinedType : undefinedPermissiveType, TypeFacts.EQUndefined); } diff --git a/tests/baselines/reference/inDoesNotOperateOnPrimitiveTypes.types b/tests/baselines/reference/inDoesNotOperateOnPrimitiveTypes.types index 047e1168a3479..f56bbf9395d40 100644 --- a/tests/baselines/reference/inDoesNotOperateOnPrimitiveTypes.types +++ b/tests/baselines/reference/inDoesNotOperateOnPrimitiveTypes.types @@ -79,7 +79,7 @@ function union2(thing: T | U) { "key" in thing; // Ok >"key" in thing : boolean >"key" : "key" ->thing : T | (T & null) | (U & null) +>thing : T } } @@ -146,7 +146,7 @@ function union5(p: T | U) "key" in p; >"key" in p : boolean >"key" : "key" ->p : (T & object) | (U & object) | (T & null) | (U & null) +>p : (T & object) | (U & object) } } diff --git a/tests/baselines/reference/nonStrictNullChecksNoNullIntroducedByControlFlow.js b/tests/baselines/reference/nonStrictNullChecksNoNullIntroducedByControlFlow.js new file mode 100644 index 0000000000000..08205c5f92558 --- /dev/null +++ b/tests/baselines/reference/nonStrictNullChecksNoNullIntroducedByControlFlow.js @@ -0,0 +1,36 @@ +//// [nonStrictNullChecksNoNullIntroducedByControlFlow.ts] +export function clone(obj: T): T { + if (!obj || typeof obj !== 'object') { + return obj; + } + var result = (Array.isArray(obj)) ? [] : {}; + Object.keys(obj).forEach((key) => { + if (obj[key] && typeof obj[key] === 'object') { + result[key] = clone(obj[key]); + } else { + result[key] = obj[key]; + } + }); + return result; +} + +//// [nonStrictNullChecksNoNullIntroducedByControlFlow.js] +"use strict"; +exports.__esModule = true; +exports.clone = void 0; +function clone(obj) { + if (!obj || typeof obj !== 'object') { + return obj; + } + var result = (Array.isArray(obj)) ? [] : {}; + Object.keys(obj).forEach(function (key) { + if (obj[key] && typeof obj[key] === 'object') { + result[key] = clone(obj[key]); + } + else { + result[key] = obj[key]; + } + }); + return result; +} +exports.clone = clone; diff --git a/tests/baselines/reference/nonStrictNullChecksNoNullIntroducedByControlFlow.symbols b/tests/baselines/reference/nonStrictNullChecksNoNullIntroducedByControlFlow.symbols new file mode 100644 index 0000000000000..6b4168bc658b4 --- /dev/null +++ b/tests/baselines/reference/nonStrictNullChecksNoNullIntroducedByControlFlow.symbols @@ -0,0 +1,55 @@ +=== tests/cases/compiler/nonStrictNullChecksNoNullIntroducedByControlFlow.ts === +export function clone(obj: T): T { +>clone : Symbol(clone, Decl(nonStrictNullChecksNoNullIntroducedByControlFlow.ts, 0, 0)) +>T : Symbol(T, Decl(nonStrictNullChecksNoNullIntroducedByControlFlow.ts, 0, 22)) +>obj : Symbol(obj, Decl(nonStrictNullChecksNoNullIntroducedByControlFlow.ts, 0, 25)) +>T : Symbol(T, Decl(nonStrictNullChecksNoNullIntroducedByControlFlow.ts, 0, 22)) +>T : Symbol(T, Decl(nonStrictNullChecksNoNullIntroducedByControlFlow.ts, 0, 22)) + + if (!obj || typeof obj !== 'object') { +>obj : Symbol(obj, Decl(nonStrictNullChecksNoNullIntroducedByControlFlow.ts, 0, 25)) +>obj : Symbol(obj, Decl(nonStrictNullChecksNoNullIntroducedByControlFlow.ts, 0, 25)) + + return obj; +>obj : Symbol(obj, Decl(nonStrictNullChecksNoNullIntroducedByControlFlow.ts, 0, 25)) + } + var result = (Array.isArray(obj)) ? [] : {}; +>result : Symbol(result, Decl(nonStrictNullChecksNoNullIntroducedByControlFlow.ts, 4, 4)) +>Array.isArray : Symbol(ArrayConstructor.isArray, Decl(lib.es5.d.ts, --, --)) +>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>isArray : Symbol(ArrayConstructor.isArray, Decl(lib.es5.d.ts, --, --)) +>obj : Symbol(obj, Decl(nonStrictNullChecksNoNullIntroducedByControlFlow.ts, 0, 25)) + + Object.keys(obj).forEach((key) => { +>Object.keys(obj).forEach : Symbol(Array.forEach, Decl(lib.es5.d.ts, --, --)) +>Object.keys : Symbol(ObjectConstructor.keys, Decl(lib.es5.d.ts, --, --)) +>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>keys : Symbol(ObjectConstructor.keys, Decl(lib.es5.d.ts, --, --)) +>obj : Symbol(obj, Decl(nonStrictNullChecksNoNullIntroducedByControlFlow.ts, 0, 25)) +>forEach : Symbol(Array.forEach, Decl(lib.es5.d.ts, --, --)) +>key : Symbol(key, Decl(nonStrictNullChecksNoNullIntroducedByControlFlow.ts, 5, 27)) + + if (obj[key] && typeof obj[key] === 'object') { +>obj : Symbol(obj, Decl(nonStrictNullChecksNoNullIntroducedByControlFlow.ts, 0, 25)) +>key : Symbol(key, Decl(nonStrictNullChecksNoNullIntroducedByControlFlow.ts, 5, 27)) +>obj : Symbol(obj, Decl(nonStrictNullChecksNoNullIntroducedByControlFlow.ts, 0, 25)) +>key : Symbol(key, Decl(nonStrictNullChecksNoNullIntroducedByControlFlow.ts, 5, 27)) + + result[key] = clone(obj[key]); +>result : Symbol(result, Decl(nonStrictNullChecksNoNullIntroducedByControlFlow.ts, 4, 4)) +>key : Symbol(key, Decl(nonStrictNullChecksNoNullIntroducedByControlFlow.ts, 5, 27)) +>clone : Symbol(clone, Decl(nonStrictNullChecksNoNullIntroducedByControlFlow.ts, 0, 0)) +>obj : Symbol(obj, Decl(nonStrictNullChecksNoNullIntroducedByControlFlow.ts, 0, 25)) +>key : Symbol(key, Decl(nonStrictNullChecksNoNullIntroducedByControlFlow.ts, 5, 27)) + + } else { + result[key] = obj[key]; +>result : Symbol(result, Decl(nonStrictNullChecksNoNullIntroducedByControlFlow.ts, 4, 4)) +>key : Symbol(key, Decl(nonStrictNullChecksNoNullIntroducedByControlFlow.ts, 5, 27)) +>obj : Symbol(obj, Decl(nonStrictNullChecksNoNullIntroducedByControlFlow.ts, 0, 25)) +>key : Symbol(key, Decl(nonStrictNullChecksNoNullIntroducedByControlFlow.ts, 5, 27)) + } + }); + return result; +>result : Symbol(result, Decl(nonStrictNullChecksNoNullIntroducedByControlFlow.ts, 4, 4)) +} diff --git a/tests/baselines/reference/nonStrictNullChecksNoNullIntroducedByControlFlow.types b/tests/baselines/reference/nonStrictNullChecksNoNullIntroducedByControlFlow.types new file mode 100644 index 0000000000000..649167fddc188 --- /dev/null +++ b/tests/baselines/reference/nonStrictNullChecksNoNullIntroducedByControlFlow.types @@ -0,0 +1,80 @@ +=== tests/cases/compiler/nonStrictNullChecksNoNullIntroducedByControlFlow.ts === +export function clone(obj: T): T { +>clone : (obj: T) => T +>obj : T + + if (!obj || typeof obj !== 'object') { +>!obj || typeof obj !== 'object' : boolean +>!obj : boolean +>obj : T +>typeof obj !== 'object' : boolean +>typeof obj : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function" +>obj : T +>'object' : "object" + + return obj; +>obj : T + } + var result = (Array.isArray(obj)) ? [] : {}; +>result : any +>(Array.isArray(obj)) ? [] : {} : any +>(Array.isArray(obj)) : boolean +>Array.isArray(obj) : boolean +>Array.isArray : (arg: any) => arg is any[] +>Array : ArrayConstructor +>isArray : (arg: any) => arg is any[] +>obj : T & object +>[] : any +>[] : undefined[] +>{} : any +>{} : {} + + Object.keys(obj).forEach((key) => { +>Object.keys(obj).forEach((key) => { if (obj[key] && typeof obj[key] === 'object') { result[key] = clone(obj[key]); } else { result[key] = obj[key]; } }) : void +>Object.keys(obj).forEach : (callbackfn: (value: string, index: number, array: string[]) => void, thisArg?: any) => void +>Object.keys(obj) : string[] +>Object.keys : (o: object) => string[] +>Object : ObjectConstructor +>keys : (o: object) => string[] +>obj : T & object +>forEach : (callbackfn: (value: string, index: number, array: string[]) => void, thisArg?: any) => void +>(key) => { if (obj[key] && typeof obj[key] === 'object') { result[key] = clone(obj[key]); } else { result[key] = obj[key]; } } : (key: string) => void +>key : string + + if (obj[key] && typeof obj[key] === 'object') { +>obj[key] && typeof obj[key] === 'object' : boolean +>obj[key] : error +>obj : T & object +>key : string +>typeof obj[key] === 'object' : boolean +>typeof obj[key] : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function" +>obj[key] : error +>obj : T & object +>key : string +>'object' : "object" + + result[key] = clone(obj[key]); +>result[key] = clone(obj[key]) : error +>result[key] : any +>result : any +>key : string +>clone(obj[key]) : error +>clone : (obj: T) => T +>obj[key] : error +>obj : T & object +>key : string + + } else { + result[key] = obj[key]; +>result[key] = obj[key] : error +>result[key] : any +>result : any +>key : string +>obj[key] : error +>obj : T & object +>key : string + } + }); + return result; +>result : any +} diff --git a/tests/cases/compiler/nonStrictNullChecksNoNullIntroducedByControlFlow.ts b/tests/cases/compiler/nonStrictNullChecksNoNullIntroducedByControlFlow.ts new file mode 100644 index 0000000000000..ffd036b2a856d --- /dev/null +++ b/tests/cases/compiler/nonStrictNullChecksNoNullIntroducedByControlFlow.ts @@ -0,0 +1,14 @@ +export function clone(obj: T): T { + if (!obj || typeof obj !== 'object') { + return obj; + } + var result = (Array.isArray(obj)) ? [] : {}; + Object.keys(obj).forEach((key) => { + if (obj[key] && typeof obj[key] === 'object') { + result[key] = clone(obj[key]); + } else { + result[key] = obj[key]; + } + }); + return result; +} \ No newline at end of file From 82a7b3caf695382231a99269632f51c253ba0d18 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Wed, 31 Aug 2022 14:02:05 -0700 Subject: [PATCH 12/24] undefined properties from widening should use an appropriately permissive undefined in loose mode --- src/compiler/checker.ts | 13 +- ...ecksMissingPropertyAssignableToAnything.js | 104 +++++++++++++ ...issingPropertyAssignableToAnything.symbols | 120 +++++++++++++++ ...sMissingPropertyAssignableToAnything.types | 144 ++++++++++++++++++ ...ecksMissingPropertyAssignableToAnything.ts | 56 +++++++ 5 files changed, 433 insertions(+), 4 deletions(-) create mode 100644 tests/baselines/reference/nonStrictNullChecksMissingPropertyAssignableToAnything.js create mode 100644 tests/baselines/reference/nonStrictNullChecksMissingPropertyAssignableToAnything.symbols create mode 100644 tests/baselines/reference/nonStrictNullChecksMissingPropertyAssignableToAnything.types create mode 100644 tests/cases/compiler/nonStrictNullChecksMissingPropertyAssignableToAnything.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 3869c9949425e..76ce3891e6699 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -778,7 +778,7 @@ namespace ts { const subtypeReductionCache = new Map(); const cachedTypes = new Map(); const evolvingArrayTypes: EvolvingArrayType[] = []; - const undefinedProperties: SymbolTable = new Map(); + const undefinedProperties = new Map(); const markerTypes = new Set(); const unknownSymbol = createSymbol(SymbolFlags.Property, "unknown" as __String); @@ -21875,14 +21875,19 @@ namespace ts { return widened === original ? prop : createSymbolWithType(prop, widened); } + function getUndefinedPropertyNameHash(prop: Symbol): string { + return `${prop.escapedName}|${strictNullChecks(prop.valueDeclaration)}|${!!exactOptionalPropertyTypes(prop.valueDeclaration)}`; + } + function getUndefinedProperty(prop: Symbol) { - const cached = undefinedProperties.get(prop.escapedName); + const id = getUndefinedPropertyNameHash(prop); + const cached = undefinedProperties.get(id); if (cached) { return cached; } - const result = createSymbolWithType(prop, getMissingOrUndefinedType(prop.valueDeclaration)); + const result = createSymbolWithType(prop, !strictNullChecks(prop.valueDeclaration) ? undefinedWideningType : getMissingOrUndefinedType(prop.valueDeclaration)); result.flags |= SymbolFlags.Optional; - undefinedProperties.set(prop.escapedName, result); + undefinedProperties.set(id, result); return result; } diff --git a/tests/baselines/reference/nonStrictNullChecksMissingPropertyAssignableToAnything.js b/tests/baselines/reference/nonStrictNullChecksMissingPropertyAssignableToAnything.js new file mode 100644 index 0000000000000..ee6dc9f812d1e --- /dev/null +++ b/tests/baselines/reference/nonStrictNullChecksMissingPropertyAssignableToAnything.js @@ -0,0 +1,104 @@ +//// [nonStrictNullChecksMissingPropertyAssignableToAnything.ts] +export interface IJSONSchema { + id?: string; + type?: string | string[]; + anyOf?: IJSONSchema[]; + enum?: any[]; + items?: IJSONSchema | IJSONSchema[]; + properties?: IJSONSchemaMap; +} + +export interface IJSONSchemaMap { + [name: string]: IJSONSchema; +} + +export const tokenColorsSchema = { + type: 'array', + items: { + type: 'object', + properties: { + scope: { + anyOf: [ + { + enum: ["a", "b"] + }, + { + type: 'string' + }, + { + type: 'array', + items: { + enum: ["a", "b"] + } + }, + { + type: 'array', + items: { + type: 'string' + } + } + ] + }, + } + } +}; + +const schema: IJSONSchema = { + type: 'object', + properties: { + tokenColors: { + anyOf: [{ + type: 'string' + }, + tokenColorsSchema + ] + } + } +}; + +//// [nonStrictNullChecksMissingPropertyAssignableToAnything.js] +"use strict"; +exports.__esModule = true; +exports.tokenColorsSchema = void 0; +exports.tokenColorsSchema = { + type: 'array', + items: { + type: 'object', + properties: { + scope: { + anyOf: [ + { + "enum": ["a", "b"] + }, + { + type: 'string' + }, + { + type: 'array', + items: { + "enum": ["a", "b"] + } + }, + { + type: 'array', + items: { + type: 'string' + } + } + ] + } + } + } +}; +var schema = { + type: 'object', + properties: { + tokenColors: { + anyOf: [{ + type: 'string' + }, + exports.tokenColorsSchema + ] + } + } +}; diff --git a/tests/baselines/reference/nonStrictNullChecksMissingPropertyAssignableToAnything.symbols b/tests/baselines/reference/nonStrictNullChecksMissingPropertyAssignableToAnything.symbols new file mode 100644 index 0000000000000..6f4cb27aad229 --- /dev/null +++ b/tests/baselines/reference/nonStrictNullChecksMissingPropertyAssignableToAnything.symbols @@ -0,0 +1,120 @@ +=== tests/cases/compiler/nonStrictNullChecksMissingPropertyAssignableToAnything.ts === +export interface IJSONSchema { +>IJSONSchema : Symbol(IJSONSchema, Decl(nonStrictNullChecksMissingPropertyAssignableToAnything.ts, 0, 0)) + + id?: string; +>id : Symbol(IJSONSchema.id, Decl(nonStrictNullChecksMissingPropertyAssignableToAnything.ts, 0, 30)) + + type?: string | string[]; +>type : Symbol(IJSONSchema.type, Decl(nonStrictNullChecksMissingPropertyAssignableToAnything.ts, 1, 16)) + + anyOf?: IJSONSchema[]; +>anyOf : Symbol(IJSONSchema.anyOf, Decl(nonStrictNullChecksMissingPropertyAssignableToAnything.ts, 2, 29)) +>IJSONSchema : Symbol(IJSONSchema, Decl(nonStrictNullChecksMissingPropertyAssignableToAnything.ts, 0, 0)) + + enum?: any[]; +>enum : Symbol(IJSONSchema.enum, Decl(nonStrictNullChecksMissingPropertyAssignableToAnything.ts, 3, 26)) + + items?: IJSONSchema | IJSONSchema[]; +>items : Symbol(IJSONSchema.items, Decl(nonStrictNullChecksMissingPropertyAssignableToAnything.ts, 4, 14)) +>IJSONSchema : Symbol(IJSONSchema, Decl(nonStrictNullChecksMissingPropertyAssignableToAnything.ts, 0, 0)) +>IJSONSchema : Symbol(IJSONSchema, Decl(nonStrictNullChecksMissingPropertyAssignableToAnything.ts, 0, 0)) + + properties?: IJSONSchemaMap; +>properties : Symbol(IJSONSchema.properties, Decl(nonStrictNullChecksMissingPropertyAssignableToAnything.ts, 5, 37)) +>IJSONSchemaMap : Symbol(IJSONSchemaMap, Decl(nonStrictNullChecksMissingPropertyAssignableToAnything.ts, 7, 1)) +} + +export interface IJSONSchemaMap { +>IJSONSchemaMap : Symbol(IJSONSchemaMap, Decl(nonStrictNullChecksMissingPropertyAssignableToAnything.ts, 7, 1)) + + [name: string]: IJSONSchema; +>name : Symbol(name, Decl(nonStrictNullChecksMissingPropertyAssignableToAnything.ts, 10, 5)) +>IJSONSchema : Symbol(IJSONSchema, Decl(nonStrictNullChecksMissingPropertyAssignableToAnything.ts, 0, 0)) +} + +export const tokenColorsSchema = { +>tokenColorsSchema : Symbol(tokenColorsSchema, Decl(nonStrictNullChecksMissingPropertyAssignableToAnything.ts, 13, 12)) + + type: 'array', +>type : Symbol(type, Decl(nonStrictNullChecksMissingPropertyAssignableToAnything.ts, 13, 34)) + + items: { +>items : Symbol(items, Decl(nonStrictNullChecksMissingPropertyAssignableToAnything.ts, 14, 18)) + + type: 'object', +>type : Symbol(type, Decl(nonStrictNullChecksMissingPropertyAssignableToAnything.ts, 15, 12)) + + properties: { +>properties : Symbol(properties, Decl(nonStrictNullChecksMissingPropertyAssignableToAnything.ts, 16, 23)) + + scope: { +>scope : Symbol(scope, Decl(nonStrictNullChecksMissingPropertyAssignableToAnything.ts, 17, 21)) + + anyOf: [ +>anyOf : Symbol(anyOf, Decl(nonStrictNullChecksMissingPropertyAssignableToAnything.ts, 18, 20)) + { + enum: ["a", "b"] +>enum : Symbol(enum, Decl(nonStrictNullChecksMissingPropertyAssignableToAnything.ts, 20, 21)) + + }, + { + type: 'string' +>type : Symbol(type, Decl(nonStrictNullChecksMissingPropertyAssignableToAnything.ts, 23, 21)) + + }, + { + type: 'array', +>type : Symbol(type, Decl(nonStrictNullChecksMissingPropertyAssignableToAnything.ts, 26, 21)) + + items: { +>items : Symbol(items, Decl(nonStrictNullChecksMissingPropertyAssignableToAnything.ts, 27, 38)) + + enum: ["a", "b"] +>enum : Symbol(enum, Decl(nonStrictNullChecksMissingPropertyAssignableToAnything.ts, 28, 32)) + } + }, + { + type: 'array', +>type : Symbol(type, Decl(nonStrictNullChecksMissingPropertyAssignableToAnything.ts, 32, 21)) + + items: { +>items : Symbol(items, Decl(nonStrictNullChecksMissingPropertyAssignableToAnything.ts, 33, 38)) + + type: 'string' +>type : Symbol(type, Decl(nonStrictNullChecksMissingPropertyAssignableToAnything.ts, 34, 32)) + } + } + ] + }, + } + } +}; + +const schema: IJSONSchema = { +>schema : Symbol(schema, Decl(nonStrictNullChecksMissingPropertyAssignableToAnything.ts, 44, 5)) +>IJSONSchema : Symbol(IJSONSchema, Decl(nonStrictNullChecksMissingPropertyAssignableToAnything.ts, 0, 0)) + + type: 'object', +>type : Symbol(type, Decl(nonStrictNullChecksMissingPropertyAssignableToAnything.ts, 44, 29)) + + properties: { +>properties : Symbol(properties, Decl(nonStrictNullChecksMissingPropertyAssignableToAnything.ts, 45, 19)) + + tokenColors: { +>tokenColors : Symbol(tokenColors, Decl(nonStrictNullChecksMissingPropertyAssignableToAnything.ts, 46, 17)) + + anyOf: [{ +>anyOf : Symbol(anyOf, Decl(nonStrictNullChecksMissingPropertyAssignableToAnything.ts, 47, 22)) + + type: 'string' +>type : Symbol(type, Decl(nonStrictNullChecksMissingPropertyAssignableToAnything.ts, 48, 21)) + + }, + tokenColorsSchema +>tokenColorsSchema : Symbol(tokenColorsSchema, Decl(nonStrictNullChecksMissingPropertyAssignableToAnything.ts, 13, 12)) + + ] + } + } +}; diff --git a/tests/baselines/reference/nonStrictNullChecksMissingPropertyAssignableToAnything.types b/tests/baselines/reference/nonStrictNullChecksMissingPropertyAssignableToAnything.types new file mode 100644 index 0000000000000..fc3f6020a6b95 --- /dev/null +++ b/tests/baselines/reference/nonStrictNullChecksMissingPropertyAssignableToAnything.types @@ -0,0 +1,144 @@ +=== tests/cases/compiler/nonStrictNullChecksMissingPropertyAssignableToAnything.ts === +export interface IJSONSchema { + id?: string; +>id : string + + type?: string | string[]; +>type : string | string[] + + anyOf?: IJSONSchema[]; +>anyOf : IJSONSchema[] + + enum?: any[]; +>enum : any[] + + items?: IJSONSchema | IJSONSchema[]; +>items : IJSONSchema | IJSONSchema[] + + properties?: IJSONSchemaMap; +>properties : IJSONSchemaMap +} + +export interface IJSONSchemaMap { + [name: string]: IJSONSchema; +>name : string +} + +export const tokenColorsSchema = { +>tokenColorsSchema : { type: string; items: { type: string; properties: { scope: { anyOf: ({ enum: string[]; type?: undefined; items?: undefined; } | { type: string; enum?: undefined; items?: undefined; } | { type: string; items: { enum: string[]; type?: undefined; }; enum?: undefined; } | { type: string; items: { type: string; enum?: undefined; }; enum?: undefined; })[]; }; }; }; } +>{ type: 'array', items: { type: 'object', properties: { scope: { anyOf: [ { enum: ["a", "b"] }, { type: 'string' }, { type: 'array', items: { enum: ["a", "b"] } }, { type: 'array', items: { type: 'string' } } ] }, } }} : { type: string; items: { type: string; properties: { scope: { anyOf: ({ enum: string[]; } | { type: string; } | { type: string; items: { enum: string[]; }; } | { type: string; items: { type: string; }; })[]; }; }; }; } + + type: 'array', +>type : string +>'array' : "array" + + items: { +>items : { type: string; properties: { scope: { anyOf: ({ enum: string[]; } | { type: string; } | { type: string; items: { enum: string[]; }; } | { type: string; items: { type: string; }; })[]; }; }; } +>{ type: 'object', properties: { scope: { anyOf: [ { enum: ["a", "b"] }, { type: 'string' }, { type: 'array', items: { enum: ["a", "b"] } }, { type: 'array', items: { type: 'string' } } ] }, } } : { type: string; properties: { scope: { anyOf: ({ enum: string[]; } | { type: string; } | { type: string; items: { enum: string[]; }; } | { type: string; items: { type: string; }; })[]; }; }; } + + type: 'object', +>type : string +>'object' : "object" + + properties: { +>properties : { scope: { anyOf: ({ enum: string[]; } | { type: string; } | { type: string; items: { enum: string[]; }; } | { type: string; items: { type: string; }; })[]; }; } +>{ scope: { anyOf: [ { enum: ["a", "b"] }, { type: 'string' }, { type: 'array', items: { enum: ["a", "b"] } }, { type: 'array', items: { type: 'string' } } ] }, } : { scope: { anyOf: ({ enum: string[]; } | { type: string; } | { type: string; items: { enum: string[]; }; } | { type: string; items: { type: string; }; })[]; }; } + + scope: { +>scope : { anyOf: ({ enum: string[]; } | { type: string; } | { type: string; items: { enum: string[]; }; } | { type: string; items: { type: string; }; })[]; } +>{ anyOf: [ { enum: ["a", "b"] }, { type: 'string' }, { type: 'array', items: { enum: ["a", "b"] } }, { type: 'array', items: { type: 'string' } } ] } : { anyOf: ({ enum: string[]; } | { type: string; } | { type: string; items: { enum: string[]; }; } | { type: string; items: { type: string; }; })[]; } + + anyOf: [ +>anyOf : ({ enum: string[]; } | { type: string; } | { type: string; items: { enum: string[]; }; } | { type: string; items: { type: string; }; })[] +>[ { enum: ["a", "b"] }, { type: 'string' }, { type: 'array', items: { enum: ["a", "b"] } }, { type: 'array', items: { type: 'string' } } ] : ({ enum: string[]; } | { type: string; } | { type: string; items: { enum: string[]; }; } | { type: string; items: { type: string; }; })[] + { +>{ enum: ["a", "b"] } : { enum: string[]; } + + enum: ["a", "b"] +>enum : string[] +>["a", "b"] : string[] +>"a" : "a" +>"b" : "b" + + }, + { +>{ type: 'string' } : { type: string; } + + type: 'string' +>type : string +>'string' : "string" + + }, + { +>{ type: 'array', items: { enum: ["a", "b"] } } : { type: string; items: { enum: string[]; }; } + + type: 'array', +>type : string +>'array' : "array" + + items: { +>items : { enum: string[]; } +>{ enum: ["a", "b"] } : { enum: string[]; } + + enum: ["a", "b"] +>enum : string[] +>["a", "b"] : string[] +>"a" : "a" +>"b" : "b" + } + }, + { +>{ type: 'array', items: { type: 'string' } } : { type: string; items: { type: string; }; } + + type: 'array', +>type : string +>'array' : "array" + + items: { +>items : { type: string; } +>{ type: 'string' } : { type: string; } + + type: 'string' +>type : string +>'string' : "string" + } + } + ] + }, + } + } +}; + +const schema: IJSONSchema = { +>schema : IJSONSchema +>{ type: 'object', properties: { tokenColors: { anyOf: [{ type: 'string' }, tokenColorsSchema ] } }} : { type: string; properties: { tokenColors: { anyOf: ({ type: string; items: { type: string; properties: { scope: { anyOf: ({ enum: string[]; type?: undefined; items?: undefined; } | { type: string; enum?: undefined; items?: undefined; } | { type: string; items: { enum: string[]; type?: undefined; }; enum?: undefined; } | { type: string; items: { type: string; enum?: undefined; }; enum?: undefined; })[]; }; }; }; } | { type: string; })[]; }; }; } + + type: 'object', +>type : string +>'object' : "object" + + properties: { +>properties : { tokenColors: { anyOf: ({ type: string; items: { type: string; properties: { scope: { anyOf: ({ enum: string[]; type?: undefined; items?: undefined; } | { type: string; enum?: undefined; items?: undefined; } | { type: string; items: { enum: string[]; type?: undefined; }; enum?: undefined; } | { type: string; items: { type: string; enum?: undefined; }; enum?: undefined; })[]; }; }; }; } | { type: string; })[]; }; } +>{ tokenColors: { anyOf: [{ type: 'string' }, tokenColorsSchema ] } } : { tokenColors: { anyOf: ({ type: string; items: { type: string; properties: { scope: { anyOf: ({ enum: string[]; type?: undefined; items?: undefined; } | { type: string; enum?: undefined; items?: undefined; } | { type: string; items: { enum: string[]; type?: undefined; }; enum?: undefined; } | { type: string; items: { type: string; enum?: undefined; }; enum?: undefined; })[]; }; }; }; } | { type: string; })[]; }; } + + tokenColors: { +>tokenColors : { anyOf: ({ type: string; items: { type: string; properties: { scope: { anyOf: ({ enum: string[]; type?: undefined; items?: undefined; } | { type: string; enum?: undefined; items?: undefined; } | { type: string; items: { enum: string[]; type?: undefined; }; enum?: undefined; } | { type: string; items: { type: string; enum?: undefined; }; enum?: undefined; })[]; }; }; }; } | { type: string; })[]; } +>{ anyOf: [{ type: 'string' }, tokenColorsSchema ] } : { anyOf: ({ type: string; items: { type: string; properties: { scope: { anyOf: ({ enum: string[]; type?: undefined; items?: undefined; } | { type: string; enum?: undefined; items?: undefined; } | { type: string; items: { enum: string[]; type?: undefined; }; enum?: undefined; } | { type: string; items: { type: string; enum?: undefined; }; enum?: undefined; })[]; }; }; }; } | { type: string; })[]; } + + anyOf: [{ +>anyOf : ({ type: string; items: { type: string; properties: { scope: { anyOf: ({ enum: string[]; type?: undefined; items?: undefined; } | { type: string; enum?: undefined; items?: undefined; } | { type: string; items: { enum: string[]; type?: undefined; }; enum?: undefined; } | { type: string; items: { type: string; enum?: undefined; }; enum?: undefined; })[]; }; }; }; } | { type: string; })[] +>[{ type: 'string' }, tokenColorsSchema ] : ({ type: string; items: { type: string; properties: { scope: { anyOf: ({ enum: string[]; type?: undefined; items?: undefined; } | { type: string; enum?: undefined; items?: undefined; } | { type: string; items: { enum: string[]; type?: undefined; }; enum?: undefined; } | { type: string; items: { type: string; enum?: undefined; }; enum?: undefined; })[]; }; }; }; } | { type: string; })[] +>{ type: 'string' } : { type: string; } + + type: 'string' +>type : string +>'string' : "string" + + }, + tokenColorsSchema +>tokenColorsSchema : { type: string; items: { type: string; properties: { scope: { anyOf: ({ enum: string[]; type?: undefined; items?: undefined; } | { type: string; enum?: undefined; items?: undefined; } | { type: string; items: { enum: string[]; type?: undefined; }; enum?: undefined; } | { type: string; items: { type: string; enum?: undefined; }; enum?: undefined; })[]; }; }; }; } + + ] + } + } +}; diff --git a/tests/cases/compiler/nonStrictNullChecksMissingPropertyAssignableToAnything.ts b/tests/cases/compiler/nonStrictNullChecksMissingPropertyAssignableToAnything.ts new file mode 100644 index 0000000000000..9e195a62bc884 --- /dev/null +++ b/tests/cases/compiler/nonStrictNullChecksMissingPropertyAssignableToAnything.ts @@ -0,0 +1,56 @@ +export interface IJSONSchema { + id?: string; + type?: string | string[]; + anyOf?: IJSONSchema[]; + enum?: any[]; + items?: IJSONSchema | IJSONSchema[]; + properties?: IJSONSchemaMap; +} + +export interface IJSONSchemaMap { + [name: string]: IJSONSchema; +} + +export const tokenColorsSchema = { + type: 'array', + items: { + type: 'object', + properties: { + scope: { + anyOf: [ + { + enum: ["a", "b"] + }, + { + type: 'string' + }, + { + type: 'array', + items: { + enum: ["a", "b"] + } + }, + { + type: 'array', + items: { + type: 'string' + } + } + ] + }, + } + } +}; + +const schema: IJSONSchema = { + type: 'object', + properties: { + tokenColors: { + anyOf: [{ + type: 'string' + }, + tokenColorsSchema + ] + } + } +}; \ No newline at end of file From b18eca0f207d65f60338e403170e1cdfd5453633 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Wed, 31 Aug 2022 16:45:24 -0700 Subject: [PATCH 13/24] Use unknown with object apparent type in more places in loose mode --- src/compiler/checker.ts | 21 +++++++------- ...wnNotAssignableToConcreteObject.errors.txt | 5 ++-- .../nonStrictUnknownLooksLikeEmptyObject.js | 16 ++++++++++ ...nStrictUnknownLooksLikeEmptyObject.symbols | 29 +++++++++++++++++++ ...nonStrictUnknownLooksLikeEmptyObject.types | 29 +++++++++++++++++++ ...teFieldAssignabilityFromUnknown.errors.txt | 5 ++-- ...sOnTypeParameterWithoutConstraints.symbols | 1 + .../nonStrictUnknownLooksLikeEmptyObject.ts | 9 ++++++ 8 files changed, 100 insertions(+), 15 deletions(-) create mode 100644 tests/baselines/reference/nonStrictUnknownLooksLikeEmptyObject.js create mode 100644 tests/baselines/reference/nonStrictUnknownLooksLikeEmptyObject.symbols create mode 100644 tests/baselines/reference/nonStrictUnknownLooksLikeEmptyObject.types create mode 100644 tests/cases/compiler/nonStrictUnknownLooksLikeEmptyObject.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 76ce3891e6699..8dcac1e2c417c 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -9754,7 +9754,7 @@ namespace ts { } const type = getTypeOfNode(typeNode); // an errorType will make `checkTryStatement` issue an error - return isTypeAny(type) || type === unknownType ? type : errorType; + return isTypeAny(type) || !!(type.flags & TypeFlags.Unknown) ? type : errorType; } // Handle export default expressions if (isSourceFile(declaration) && isJsonSourceFile(declaration)) { @@ -12992,8 +12992,8 @@ namespace ts { for (let i = numTypeArguments; i < numTypeParameters; i++) { result[i] = errorType; } - const baseDefaultType = getDefaultTypeArgumentType(isJavaScriptImplicitAny); for (let i = numTypeArguments; i < numTypeParameters; i++) { + const baseDefaultType = getDefaultTypeArgumentType(isJavaScriptImplicitAny, typeParameters![i]); let defaultType = getDefaultFromTypeParameter(typeParameters![i]); if (isJavaScriptImplicitAny && defaultType && (isTypeIdenticalTo(defaultType, unknownType) || isTypeIdenticalTo(defaultType, emptyObjectType))) { defaultType = anyType; @@ -16888,7 +16888,7 @@ namespace ts { case SyntaxKind.JSDocUnknownType: return anyType; case SyntaxKind.UnknownKeyword: - return unknownType; + return strictNullChecks(node) ? unknownType : nonNullUnknownType; case SyntaxKind.StringKeyword: return stringType; case SyntaxKind.NumberKeyword: @@ -23418,7 +23418,7 @@ namespace ts { inferredType = getTypeFromInference(inference); } - inference.inferredType = inferredType || getDefaultTypeArgumentType(!!(context.flags & InferenceFlags.AnyDefault)); + inference.inferredType = inferredType || getDefaultTypeArgumentType(!!(context.flags & InferenceFlags.AnyDefault), inference.typeParameter); const constraint = getConstraintOfTypeParameter(inference.typeParameter); if (constraint) { @@ -23432,8 +23432,8 @@ namespace ts { return inference.inferredType; } - function getDefaultTypeArgumentType(isInJavaScriptFile: boolean): Type { - return isInJavaScriptFile ? anyType : unknownType; + function getDefaultTypeArgumentType(isInJavaScriptFile: boolean, param: TypeParameter): Type { + return isInJavaScriptFile ? anyType : strictNullChecks(param.symbol?.declarations?.[0]) ? unknownType : nonNullUnknownType; } function getInferredTypes(context: InferenceContext): Type[] { @@ -24677,8 +24677,7 @@ namespace ts { if (resultType === unreachableNeverType || reference.parent && reference.parent.kind === SyntaxKind.NonNullExpression && !(resultType.flags & TypeFlags.Never) && getTypeWithFacts(resultType, TypeFacts.NEUndefinedOrNull, reference).flags & TypeFlags.Never) { return declaredType; } - // The non-null unknown type should never escape control flow analysis. - return resultType === nonNullUnknownType ? unknownType : resultType; + return resultType; function getOrSetCacheKey() { if (isKeySet) { @@ -31437,7 +31436,7 @@ namespace ts { typeArguments.pop(); } while (typeArguments.length < typeParameters.length) { - typeArguments.push(getDefaultFromTypeParameter(typeParameters[typeArguments.length]) || getConstraintOfTypeParameter(typeParameters[typeArguments.length]) || getDefaultTypeArgumentType(isJs)); + typeArguments.push(getDefaultFromTypeParameter(typeParameters[typeArguments.length]) || getConstraintOfTypeParameter(typeParameters[typeArguments.length]) || getDefaultTypeArgumentType(isJs, typeParameters[typeArguments.length])); } return typeArguments; } @@ -32945,7 +32944,7 @@ namespace ts { links.type = type || (declaration ? getWidenedTypeForVariableLikeDeclaration(declaration, /*reportErrors*/ true) : getTypeOfSymbol(parameter)); if (declaration && declaration.name.kind !== SyntaxKind.Identifier) { // if inference didn't come up with anything but unknown, fall back to the binding pattern if present. - if (links.type === unknownType) { + if (!!(links.type?.flags & TypeFlags.Unknown)) { links.type = getTypeFromBindingPattern(declaration.name); } assignBindingElementTypes(declaration.name, links.type); @@ -33000,7 +32999,7 @@ namespace ts { function createPromiseReturnType(func: FunctionLikeDeclaration | ImportCall, promisedType: Type) { const promiseType = createPromiseType(promisedType); - if (promiseType === unknownType) { + if (!!(promiseType.flags & TypeFlags.Unknown)) { 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); diff --git a/tests/baselines/reference/genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.errors.txt b/tests/baselines/reference/genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.errors.txt index f14f6292a27b4..2063b58b4e3dc 100644 --- a/tests/baselines/reference/genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.errors.txt +++ b/tests/baselines/reference/genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.errors.txt @@ -9,7 +9,7 @@ tests/cases/compiler/genericConditionalConstrainedToUnknownNotAssignableToConcre Type 'unknown' is not assignable to type 'A'. Type 'ReturnType[string]>' is not assignable to type 'A'. Type 'unknown' is not assignable to type 'A'. - Type 'unknown' is not assignable to type 'A'. + Property 'x' is missing in type '{}' but required in type 'A'. ==== tests/cases/compiler/genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.ts (1 errors) ==== @@ -38,7 +38,8 @@ tests/cases/compiler/genericConditionalConstrainedToUnknownNotAssignableToConcre !!! error TS2322: Type 'unknown' is not assignable to type 'A'. !!! error TS2322: Type 'ReturnType[string]>' is not assignable to type 'A'. !!! error TS2322: Type 'unknown' is not assignable to type 'A'. -!!! error TS2322: Type 'unknown' is not assignable to type 'A'. +!!! error TS2322: Property 'x' is missing in type '{}' but required in type 'A'. +!!! related TS2728 tests/cases/compiler/genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.ts:1:15: 'x' is declared here. } // Original CFA report of the above issue diff --git a/tests/baselines/reference/nonStrictUnknownLooksLikeEmptyObject.js b/tests/baselines/reference/nonStrictUnknownLooksLikeEmptyObject.js new file mode 100644 index 0000000000000..78207150b2d49 --- /dev/null +++ b/tests/baselines/reference/nonStrictUnknownLooksLikeEmptyObject.js @@ -0,0 +1,16 @@ +//// [nonStrictUnknownLooksLikeEmptyObject.ts] +declare var a: { x?: number, y?: number }; +declare var b: unknown; // direct unknown + +a = b; + +// unknown via failed inference +declare function f1(x?: T): T; +const res = f1(); +a = res; + + +//// [nonStrictUnknownLooksLikeEmptyObject.js] +a = b; +var res = f1(); +a = res; diff --git a/tests/baselines/reference/nonStrictUnknownLooksLikeEmptyObject.symbols b/tests/baselines/reference/nonStrictUnknownLooksLikeEmptyObject.symbols new file mode 100644 index 0000000000000..604eefb0b4b2e --- /dev/null +++ b/tests/baselines/reference/nonStrictUnknownLooksLikeEmptyObject.symbols @@ -0,0 +1,29 @@ +=== tests/cases/compiler/nonStrictUnknownLooksLikeEmptyObject.ts === +declare var a: { x?: number, y?: number }; +>a : Symbol(a, Decl(nonStrictUnknownLooksLikeEmptyObject.ts, 0, 11)) +>x : Symbol(x, Decl(nonStrictUnknownLooksLikeEmptyObject.ts, 0, 16)) +>y : Symbol(y, Decl(nonStrictUnknownLooksLikeEmptyObject.ts, 0, 28)) + +declare var b: unknown; // direct unknown +>b : Symbol(b, Decl(nonStrictUnknownLooksLikeEmptyObject.ts, 1, 11)) + +a = b; +>a : Symbol(a, Decl(nonStrictUnknownLooksLikeEmptyObject.ts, 0, 11)) +>b : Symbol(b, Decl(nonStrictUnknownLooksLikeEmptyObject.ts, 1, 11)) + +// unknown via failed inference +declare function f1(x?: T): T; +>f1 : Symbol(f1, Decl(nonStrictUnknownLooksLikeEmptyObject.ts, 3, 6)) +>T : Symbol(T, Decl(nonStrictUnknownLooksLikeEmptyObject.ts, 6, 20)) +>x : Symbol(x, Decl(nonStrictUnknownLooksLikeEmptyObject.ts, 6, 23)) +>T : Symbol(T, Decl(nonStrictUnknownLooksLikeEmptyObject.ts, 6, 20)) +>T : Symbol(T, Decl(nonStrictUnknownLooksLikeEmptyObject.ts, 6, 20)) + +const res = f1(); +>res : Symbol(res, Decl(nonStrictUnknownLooksLikeEmptyObject.ts, 7, 5)) +>f1 : Symbol(f1, Decl(nonStrictUnknownLooksLikeEmptyObject.ts, 3, 6)) + +a = res; +>a : Symbol(a, Decl(nonStrictUnknownLooksLikeEmptyObject.ts, 0, 11)) +>res : Symbol(res, Decl(nonStrictUnknownLooksLikeEmptyObject.ts, 7, 5)) + diff --git a/tests/baselines/reference/nonStrictUnknownLooksLikeEmptyObject.types b/tests/baselines/reference/nonStrictUnknownLooksLikeEmptyObject.types new file mode 100644 index 0000000000000..c895377213646 --- /dev/null +++ b/tests/baselines/reference/nonStrictUnknownLooksLikeEmptyObject.types @@ -0,0 +1,29 @@ +=== tests/cases/compiler/nonStrictUnknownLooksLikeEmptyObject.ts === +declare var a: { x?: number, y?: number }; +>a : { x?: number; y?: number; } +>x : number +>y : number + +declare var b: unknown; // direct unknown +>b : unknown + +a = b; +>a = b : unknown +>a : { x?: number; y?: number; } +>b : unknown + +// unknown via failed inference +declare function f1(x?: T): T; +>f1 : (x?: T) => T +>x : T + +const res = f1(); +>res : unknown +>f1() : unknown +>f1 : (x?: T) => T + +a = res; +>a = res : unknown +>a : { x?: number; y?: number; } +>res : unknown + diff --git a/tests/baselines/reference/privateFieldAssignabilityFromUnknown.errors.txt b/tests/baselines/reference/privateFieldAssignabilityFromUnknown.errors.txt index bdf2d4116dbee..22f50eec6ff01 100644 --- a/tests/baselines/reference/privateFieldAssignabilityFromUnknown.errors.txt +++ b/tests/baselines/reference/privateFieldAssignabilityFromUnknown.errors.txt @@ -1,5 +1,5 @@ tests/cases/compiler/privateFieldAssignabilityFromUnknown.ts(2,3): error TS18028: Private identifiers are only available when targeting ECMAScript 2015 and higher. -tests/cases/compiler/privateFieldAssignabilityFromUnknown.ts(5,7): error TS2322: Type 'unknown' is not assignable to type 'Class'. +tests/cases/compiler/privateFieldAssignabilityFromUnknown.ts(5,7): error TS2741: Property '#field' is missing in type '{}' but required in type 'Class'. ==== tests/cases/compiler/privateFieldAssignabilityFromUnknown.ts (2 errors) ==== @@ -11,5 +11,6 @@ tests/cases/compiler/privateFieldAssignabilityFromUnknown.ts(5,7): error TS2322: const task: Class = {} as unknown; ~~~~ -!!! error TS2322: Type 'unknown' is not assignable to type 'Class'. +!!! error TS2741: Property '#field' is missing in type '{}' but required in type 'Class'. +!!! related TS2728 tests/cases/compiler/privateFieldAssignabilityFromUnknown.ts:2:3: '#field' is declared here. \ No newline at end of file diff --git a/tests/baselines/reference/propertyAccessOnTypeParameterWithoutConstraints.symbols b/tests/baselines/reference/propertyAccessOnTypeParameterWithoutConstraints.symbols index b0531585c744a..fbbfb557ef6f1 100644 --- a/tests/baselines/reference/propertyAccessOnTypeParameterWithoutConstraints.symbols +++ b/tests/baselines/reference/propertyAccessOnTypeParameterWithoutConstraints.symbols @@ -72,6 +72,7 @@ var r3: string = a().toString(); var r3b: string = a()['toString'](); >r3b : Symbol(r3b, Decl(propertyAccessOnTypeParameterWithoutConstraints.ts, 21, 3)) >a : Symbol(a, Decl(propertyAccessOnTypeParameterWithoutConstraints.ts, 17, 3)) +>'toString' : Symbol(Object.toString, Decl(lib.es5.d.ts, --, --)) var b = { >b : Symbol(b, Decl(propertyAccessOnTypeParameterWithoutConstraints.ts, 23, 3)) diff --git a/tests/cases/compiler/nonStrictUnknownLooksLikeEmptyObject.ts b/tests/cases/compiler/nonStrictUnknownLooksLikeEmptyObject.ts new file mode 100644 index 0000000000000..31dcb48ad2f6b --- /dev/null +++ b/tests/cases/compiler/nonStrictUnknownLooksLikeEmptyObject.ts @@ -0,0 +1,9 @@ +declare var a: { x?: number, y?: number }; +declare var b: unknown; // direct unknown + +a = b; + +// unknown via failed inference +declare function f1(x?: T): T; +const res = f1(); +a = res; From 8f14a2c41558863c4998f74b220ca23ec66d32ed Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Wed, 14 Sep 2022 15:01:26 -0700 Subject: [PATCH 14/24] Fix break in RWC --- src/compiler/checker.ts | 15 ++++++------- ...ctIndexedAccessOnObjectInReturnPosition.js | 17 +++++++++++++++ ...exedAccessOnObjectInReturnPosition.symbols | 16 ++++++++++++++ ...ndexedAccessOnObjectInReturnPosition.types | 21 +++++++++++++++++++ ...ctIndexedAccessOnObjectInReturnPosition.ts | 5 +++++ 5 files changed, 67 insertions(+), 7 deletions(-) create mode 100644 tests/baselines/reference/nonStrictIndexedAccessOnObjectInReturnPosition.js create mode 100644 tests/baselines/reference/nonStrictIndexedAccessOnObjectInReturnPosition.symbols create mode 100644 tests/baselines/reference/nonStrictIndexedAccessOnObjectInReturnPosition.types create mode 100644 tests/cases/compiler/nonStrictIndexedAccessOnObjectInReturnPosition.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 38ad9c7d27177..5992824265385 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -15761,6 +15761,7 @@ namespace ts { function getPropertyTypeForIndexType(originalObjectType: Type, objectType: Type, indexType: Type, fullIndexType: Type, accessNode: ElementAccessExpression | IndexedAccessTypeNode | PropertyName | BindingName | SyntheticExpression | undefined, accessFlags: AccessFlags) { const accessExpression = accessNode && accessNode.kind === SyntaxKind.ElementAccessExpression ? accessNode : undefined; const propName = accessNode && isPrivateIdentifier(accessNode) ? undefined : getPropertyNameFromIndex(indexType, accessNode); + const undefinedForAccess = strictNullChecks(accessNode) ? undefinedType : undefinedPermissiveType; if (propName !== undefined) { if (accessFlags & AccessFlags.Contextual) { @@ -15797,7 +15798,7 @@ namespace ts { if (isTupleType(objectType)) { if (index < 0) { error(indexNode, Diagnostics.A_tuple_type_cannot_be_indexed_with_a_negative_value); - return undefinedType; + return undefinedForAccess; } error(indexNode, Diagnostics.Tuple_type_0_of_length_1_has_no_element_at_index_2, typeToString(objectType), getTypeReferenceArity(objectType), unescapeLeadingUnderscores(propName)); @@ -15809,8 +15810,8 @@ namespace ts { if (index >= 0) { errorIfWritingToReadonlyIndex(getIndexInfoOfType(objectType, numberType)); return mapType(objectType, t => { - const restType = getRestTypeOfTupleType(t as TupleTypeReference) || undefinedType; - return accessFlags & AccessFlags.IncludeUndefined ? getUnionType([restType, undefinedType]) : restType; + const restType = getRestTypeOfTupleType(t as TupleTypeReference) || undefinedForAccess; + return accessFlags & AccessFlags.IncludeUndefined ? getUnionType([restType, undefinedForAccess]) : restType; }); } } @@ -15832,10 +15833,10 @@ namespace ts { if (accessNode && indexInfo.keyType === stringType && !isTypeAssignableToKind(indexType, TypeFlags.String | TypeFlags.Number)) { const indexNode = getIndexNodeForAccessExpression(accessNode); error(indexNode, Diagnostics.Type_0_cannot_be_used_as_an_index_type, typeToString(indexType)); - return accessFlags & AccessFlags.IncludeUndefined ? getUnionType([indexInfo.type, undefinedType]) : indexInfo.type; + return accessFlags & AccessFlags.IncludeUndefined ? getUnionType([indexInfo.type, undefinedForAccess]) : indexInfo.type; } errorIfWritingToReadonlyIndex(indexInfo); - return accessFlags & AccessFlags.IncludeUndefined ? getUnionType([indexInfo.type, undefinedType]) : indexInfo.type; + return accessFlags & AccessFlags.IncludeUndefined ? getUnionType([indexInfo.type, undefinedForAccess]) : indexInfo.type; } if (indexType.flags & TypeFlags.Never) { return neverType; @@ -15847,13 +15848,13 @@ namespace ts { if (isObjectLiteralType(objectType)) { if (noImplicitAny(accessNode) && indexType.flags & (TypeFlags.StringLiteral | TypeFlags.NumberLiteral)) { diagnostics.add(createDiagnosticForNode(accessExpression, Diagnostics.Property_0_does_not_exist_on_type_1, (indexType as StringLiteralType).value, typeToString(objectType))); - return undefinedType; + return undefinedForAccess; } else if (indexType.flags & (TypeFlags.Number | TypeFlags.String)) { const types = map((objectType as ResolvedType).properties, property => { return getTypeOfSymbol(property); }); - return getUnionType(append(types, undefinedType)); + return getUnionType(append(types, undefinedForAccess)); } } diff --git a/tests/baselines/reference/nonStrictIndexedAccessOnObjectInReturnPosition.js b/tests/baselines/reference/nonStrictIndexedAccessOnObjectInReturnPosition.js new file mode 100644 index 0000000000000..ac8e77b1e652f --- /dev/null +++ b/tests/baselines/reference/nonStrictIndexedAccessOnObjectInReturnPosition.js @@ -0,0 +1,17 @@ +//// [nonStrictIndexedAccessOnObjectInReturnPosition.ts] +export function func(id: string): string[] { + var a1 = []; + var a2 = ["elem"]; + return { a1, a2 }[id]; +} + +//// [nonStrictIndexedAccessOnObjectInReturnPosition.js] +"use strict"; +exports.__esModule = true; +exports.func = void 0; +function func(id) { + var a1 = []; + var a2 = ["elem"]; + return { a1: a1, a2: a2 }[id]; +} +exports.func = func; diff --git a/tests/baselines/reference/nonStrictIndexedAccessOnObjectInReturnPosition.symbols b/tests/baselines/reference/nonStrictIndexedAccessOnObjectInReturnPosition.symbols new file mode 100644 index 0000000000000..d09ddbb3c4e82 --- /dev/null +++ b/tests/baselines/reference/nonStrictIndexedAccessOnObjectInReturnPosition.symbols @@ -0,0 +1,16 @@ +=== tests/cases/compiler/nonStrictIndexedAccessOnObjectInReturnPosition.ts === +export function func(id: string): string[] { +>func : Symbol(func, Decl(nonStrictIndexedAccessOnObjectInReturnPosition.ts, 0, 0)) +>id : Symbol(id, Decl(nonStrictIndexedAccessOnObjectInReturnPosition.ts, 0, 21)) + + var a1 = []; +>a1 : Symbol(a1, Decl(nonStrictIndexedAccessOnObjectInReturnPosition.ts, 1, 7)) + + var a2 = ["elem"]; +>a2 : Symbol(a2, Decl(nonStrictIndexedAccessOnObjectInReturnPosition.ts, 2, 7)) + + return { a1, a2 }[id]; +>a1 : Symbol(a1, Decl(nonStrictIndexedAccessOnObjectInReturnPosition.ts, 3, 12)) +>a2 : Symbol(a2, Decl(nonStrictIndexedAccessOnObjectInReturnPosition.ts, 3, 16)) +>id : Symbol(id, Decl(nonStrictIndexedAccessOnObjectInReturnPosition.ts, 0, 21)) +} diff --git a/tests/baselines/reference/nonStrictIndexedAccessOnObjectInReturnPosition.types b/tests/baselines/reference/nonStrictIndexedAccessOnObjectInReturnPosition.types new file mode 100644 index 0000000000000..4a272d0e882ce --- /dev/null +++ b/tests/baselines/reference/nonStrictIndexedAccessOnObjectInReturnPosition.types @@ -0,0 +1,21 @@ +=== tests/cases/compiler/nonStrictIndexedAccessOnObjectInReturnPosition.ts === +export function func(id: string): string[] { +>func : (id: string) => string[] +>id : string + + var a1 = []; +>a1 : any[] +>[] : undefined[] + + var a2 = ["elem"]; +>a2 : string[] +>["elem"] : string[] +>"elem" : "elem" + + return { a1, a2 }[id]; +>{ a1, a2 }[id] : any[] | string[] +>{ a1, a2 } : { a1: any[]; a2: string[]; } +>a1 : any[] +>a2 : string[] +>id : string +} diff --git a/tests/cases/compiler/nonStrictIndexedAccessOnObjectInReturnPosition.ts b/tests/cases/compiler/nonStrictIndexedAccessOnObjectInReturnPosition.ts new file mode 100644 index 0000000000000..e84254bd078e3 --- /dev/null +++ b/tests/cases/compiler/nonStrictIndexedAccessOnObjectInReturnPosition.ts @@ -0,0 +1,5 @@ +export function func(id: string): string[] { + var a1 = []; + var a2 = ["elem"]; + return { a1, a2 }[id]; +} \ No newline at end of file From 3410b4e9189d515b97e79b0763de0c102c7aa64b Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Mon, 19 Sep 2022 12:18:05 -0700 Subject: [PATCH 15/24] Accept updated baselines --- tests/baselines/reference/strictPragma1.errors.txt | 8 ++++---- tests/baselines/reference/strictPragma2.errors.txt | 12 ++++++------ tests/baselines/reference/strictPragma4.errors.txt | 4 ++-- tests/baselines/reference/strictPragma5.errors.txt | 4 ++-- tests/baselines/reference/strictPragma6.errors.txt | 4 ++-- 5 files changed, 16 insertions(+), 16 deletions(-) diff --git a/tests/baselines/reference/strictPragma1.errors.txt b/tests/baselines/reference/strictPragma1.errors.txt index e8bb40341baca..ab70991887ddd 100644 --- a/tests/baselines/reference/strictPragma1.errors.txt +++ b/tests/baselines/reference/strictPragma1.errors.txt @@ -3,13 +3,13 @@ tests/cases/conformance/pragma/strict/file1.ts(10,1): error TS2322: Type '(arg: Types of parameters 'arg' and 'arg' are incompatible. Type 'unknown' is not assignable to type 'string'. tests/cases/conformance/pragma/strict/file1.ts(13,5): error TS2564: Property 'prop' has no initializer and is not definitely assigned in the constructor. -tests/cases/conformance/pragma/strict/file1.ts(18,1): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/pragma/strict/file1.ts(18,1): error TS18048: 'c.member' is possibly 'undefined'. tests/cases/conformance/pragma/strict/file2.ts(3,20): error TS2345: Argument of type 'number' is not assignable to parameter of type 'string'. tests/cases/conformance/pragma/strict/file2.ts(10,1): error TS2322: Type '(arg: string) => number' is not assignable to type '(arg: unknown) => number'. Types of parameters 'arg' and 'arg' are incompatible. Type 'unknown' is not assignable to type 'string'. tests/cases/conformance/pragma/strict/file2.ts(13,5): error TS2564: Property 'prop' has no initializer and is not definitely assigned in the constructor. -tests/cases/conformance/pragma/strict/file2.ts(18,1): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/pragma/strict/file2.ts(18,1): error TS18048: 'c.member' is possibly 'undefined'. ==== tests/cases/conformance/pragma/strict/file1.ts (4 errors) ==== @@ -40,7 +40,7 @@ tests/cases/conformance/pragma/strict/file2.ts(18,1): error TS2532: Object is po declare var c: { member?: string }; c.member.charAt(0); ~~~~~~~~ -!!! error TS2532: Object is possibly 'undefined'. +!!! error TS18048: 'c.member' is possibly 'undefined'. ==== tests/cases/conformance/pragma/strict/file2.ts (4 errors) ==== // @ts-strict true @@ -70,7 +70,7 @@ tests/cases/conformance/pragma/strict/file2.ts(18,1): error TS2532: Object is po declare var c: { member?: string }; c.member.charAt(0); ~~~~~~~~ -!!! error TS2532: Object is possibly 'undefined'. +!!! error TS18048: 'c.member' is possibly 'undefined'. ==== tests/cases/conformance/pragma/strict/file3.ts (0 errors) ==== // @ts-strict false diff --git a/tests/baselines/reference/strictPragma2.errors.txt b/tests/baselines/reference/strictPragma2.errors.txt index 6cd5311ab60bd..4579b0bd221b8 100644 --- a/tests/baselines/reference/strictPragma2.errors.txt +++ b/tests/baselines/reference/strictPragma2.errors.txt @@ -3,19 +3,19 @@ tests/cases/conformance/pragma/strict/file1.ts(10,1): error TS2322: Type '(arg: Types of parameters 'arg' and 'arg' are incompatible. Type 'unknown' is not assignable to type 'string'. tests/cases/conformance/pragma/strict/file1.ts(13,5): error TS2564: Property 'prop' has no initializer and is not definitely assigned in the constructor. -tests/cases/conformance/pragma/strict/file1.ts(18,1): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/pragma/strict/file1.ts(18,1): error TS18048: 'c.member' is possibly 'undefined'. tests/cases/conformance/pragma/strict/file2.ts(3,20): error TS2345: Argument of type 'number' is not assignable to parameter of type 'string'. tests/cases/conformance/pragma/strict/file2.ts(10,1): error TS2322: Type '(arg: string) => number' is not assignable to type '(arg: unknown) => number'. Types of parameters 'arg' and 'arg' are incompatible. Type 'unknown' is not assignable to type 'string'. tests/cases/conformance/pragma/strict/file2.ts(13,5): error TS2564: Property 'prop' has no initializer and is not definitely assigned in the constructor. -tests/cases/conformance/pragma/strict/file2.ts(18,1): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/pragma/strict/file2.ts(18,1): error TS18048: 'c.member' is possibly 'undefined'. tests/cases/conformance/pragma/strict/file4.ts(2,20): error TS2345: Argument of type 'number' is not assignable to parameter of type 'string'. tests/cases/conformance/pragma/strict/file4.ts(9,1): error TS2322: Type '(arg: string) => number' is not assignable to type '(arg: unknown) => number'. Types of parameters 'arg' and 'arg' are incompatible. Type 'unknown' is not assignable to type 'string'. tests/cases/conformance/pragma/strict/file4.ts(12,5): error TS2564: Property 'prop' has no initializer and is not definitely assigned in the constructor. -tests/cases/conformance/pragma/strict/file4.ts(17,1): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/pragma/strict/file4.ts(17,1): error TS18048: 'c.member' is possibly 'undefined'. ==== tests/cases/conformance/pragma/strict/file1.ts (4 errors) ==== @@ -46,7 +46,7 @@ tests/cases/conformance/pragma/strict/file4.ts(17,1): error TS2532: Object is po declare var c: { member?: string }; c.member.charAt(0); ~~~~~~~~ -!!! error TS2532: Object is possibly 'undefined'. +!!! error TS18048: 'c.member' is possibly 'undefined'. ==== tests/cases/conformance/pragma/strict/file2.ts (4 errors) ==== // @ts-strict true @@ -76,7 +76,7 @@ tests/cases/conformance/pragma/strict/file4.ts(17,1): error TS2532: Object is po declare var c: { member?: string }; c.member.charAt(0); ~~~~~~~~ -!!! error TS2532: Object is possibly 'undefined'. +!!! error TS18048: 'c.member' is possibly 'undefined'. ==== tests/cases/conformance/pragma/strict/file3.ts (0 errors) ==== // @ts-strict false @@ -125,5 +125,5 @@ tests/cases/conformance/pragma/strict/file4.ts(17,1): error TS2532: Object is po declare var c: { member?: string }; c.member.charAt(0); ~~~~~~~~ -!!! error TS2532: Object is possibly 'undefined'. +!!! error TS18048: 'c.member' is possibly 'undefined'. \ No newline at end of file diff --git a/tests/baselines/reference/strictPragma4.errors.txt b/tests/baselines/reference/strictPragma4.errors.txt index 1f4d0a490097e..ab5242ed8a143 100644 --- a/tests/baselines/reference/strictPragma4.errors.txt +++ b/tests/baselines/reference/strictPragma4.errors.txt @@ -2,7 +2,7 @@ tests/cases/conformance/pragma/strict/file2.ts(11,1): error TS2322: Type '(arg: Types of parameters 'arg' and 'arg' are incompatible. Type 'unknown' is not assignable to type 'string'. tests/cases/conformance/pragma/strict/file2.ts(14,5): error TS2564: Property 'prop' has no initializer and is not definitely assigned in the constructor. -tests/cases/conformance/pragma/strict/file2.ts(19,1): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/pragma/strict/file2.ts(19,1): error TS18048: 'c.member' is possibly 'undefined'. ==== tests/cases/conformance/pragma/strict/file2.ts (3 errors) ==== @@ -32,5 +32,5 @@ tests/cases/conformance/pragma/strict/file2.ts(19,1): error TS2532: Object is po declare var c: { member?: string }; c.member.charAt(0); ~~~~~~~~ -!!! error TS2532: Object is possibly 'undefined'. +!!! error TS18048: 'c.member' is possibly 'undefined'. \ No newline at end of file diff --git a/tests/baselines/reference/strictPragma5.errors.txt b/tests/baselines/reference/strictPragma5.errors.txt index 3fe951cb7210a..59fcb5cf8f680 100644 --- a/tests/baselines/reference/strictPragma5.errors.txt +++ b/tests/baselines/reference/strictPragma5.errors.txt @@ -2,7 +2,7 @@ tests/cases/conformance/pragma/strict/file3.ts(4,20): error TS2345: Argument of tests/cases/conformance/pragma/strict/file3.ts(11,1): error TS2322: Type '(arg: string) => number' is not assignable to type '(arg: unknown) => number'. Types of parameters 'arg' and 'arg' are incompatible. Type 'unknown' is not assignable to type 'string'. -tests/cases/conformance/pragma/strict/file3.ts(19,1): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/pragma/strict/file3.ts(19,1): error TS18048: 'c.member' is possibly 'undefined'. ==== tests/cases/conformance/pragma/strict/file3.ts (3 errors) ==== @@ -32,5 +32,5 @@ tests/cases/conformance/pragma/strict/file3.ts(19,1): error TS2532: Object is po declare var c: { member?: string }; c.member.charAt(0); ~~~~~~~~ -!!! error TS2532: Object is possibly 'undefined'. +!!! error TS18048: 'c.member' is possibly 'undefined'. \ No newline at end of file diff --git a/tests/baselines/reference/strictPragma6.errors.txt b/tests/baselines/reference/strictPragma6.errors.txt index 26a1750237478..fd44cdd6714c4 100644 --- a/tests/baselines/reference/strictPragma6.errors.txt +++ b/tests/baselines/reference/strictPragma6.errors.txt @@ -1,6 +1,6 @@ tests/cases/conformance/pragma/strict/file1.ts(4,20): error TS2345: Argument of type 'number' is not assignable to parameter of type 'string'. tests/cases/conformance/pragma/strict/file1.ts(14,5): error TS2564: Property 'prop' has no initializer and is not definitely assigned in the constructor. -tests/cases/conformance/pragma/strict/file1.ts(19,1): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/pragma/strict/file1.ts(19,1): error TS18048: 'c.member' is possibly 'undefined'. ==== tests/cases/conformance/pragma/strict/file1.ts (3 errors) ==== @@ -28,5 +28,5 @@ tests/cases/conformance/pragma/strict/file1.ts(19,1): error TS2532: Object is po declare var c: { member?: string }; c.member.charAt(0); ~~~~~~~~ -!!! error TS2532: Object is possibly 'undefined'. +!!! error TS18048: 'c.member' is possibly 'undefined'. \ No newline at end of file From 83ec34f593a7f8195031b6cc840477a804a793a3 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Mon, 19 Sep 2022 12:36:49 -0700 Subject: [PATCH 16/24] Use permissive undefined type for auto type initial types in loose mode --- src/compiler/checker.ts | 6 +- .../reference/noImplicitAnyForIn.types | 4 +- ...nStrictMapConstructorCompatability.symbols | 80 ++++++++++++++++ ...nonStrictMapConstructorCompatability.types | 94 +++++++++++++++++++ .../nonStrictMapConstructorCompatability.ts | 43 +++++++++ 5 files changed, 222 insertions(+), 5 deletions(-) create mode 100644 tests/baselines/reference/nonStrictMapConstructorCompatability.symbols create mode 100644 tests/baselines/reference/nonStrictMapConstructorCompatability.types create mode 100644 tests/cases/compiler/nonStrictMapConstructorCompatability.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index bedb168da4b8d..838b0dc1f8368 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -9250,7 +9250,7 @@ namespace ts { setParent(reference.expression, reference); setParent(reference, file); reference.flowNode = file.endFlowNode; - return getFlowTypeOfReference(reference, autoType, undefinedType); + return getFlowTypeOfReference(reference, autoType, strictNullChecks(file) ? undefinedType : undefinedPermissiveType); } function getFlowTypeInStaticBlocks(symbol: Symbol, staticBlocks: readonly ClassStaticBlockDeclaration[]) { @@ -9294,7 +9294,7 @@ namespace ts { const initialType = prop?.valueDeclaration && (!isAutoTypedProperty(prop) || getEffectiveModifierFlags(prop.valueDeclaration) & ModifierFlags.Ambient) && getTypeOfPropertyInBaseClass(prop) - || undefinedType; + || (strictNullChecks(reference) ? undefinedType : undefinedPermissiveType); return getFlowTypeOfReference(reference, autoType, initialType); } @@ -26285,7 +26285,7 @@ namespace ts { declaration.kind === SyntaxKind.VariableDeclaration && (declaration as VariableDeclaration).exclamationToken || declaration.flags & NodeFlags.Ambient; const initialType = assumeInitialized ? (isParameter ? removeOptionalityFromDeclaredType(type, declaration as VariableLikeDeclaration) : type) : - type === autoType || type === autoArrayType ? undefinedType : + type === autoType || type === autoArrayType ? (strictNullChecks(node) ? undefinedType : undefinedPermissiveType) : getOptionalType(type, node); const flowType = getFlowTypeOfReference(node, type, initialType, flowContainer); // A variable is considered uninitialized when it is possible to analyze the entire control flow graph diff --git a/tests/baselines/reference/noImplicitAnyForIn.types b/tests/baselines/reference/noImplicitAnyForIn.types index 6fcd13004a276..bd8cb1c8c200c 100644 --- a/tests/baselines/reference/noImplicitAnyForIn.types +++ b/tests/baselines/reference/noImplicitAnyForIn.types @@ -59,8 +59,8 @@ for (var a in x) { >b : any var c = a || b; ->c : string | undefined ->a || b : string | undefined +>c : string +>a || b : string >a : string >b : undefined } diff --git a/tests/baselines/reference/nonStrictMapConstructorCompatability.symbols b/tests/baselines/reference/nonStrictMapConstructorCompatability.symbols new file mode 100644 index 0000000000000..012fe86b84530 --- /dev/null +++ b/tests/baselines/reference/nonStrictMapConstructorCompatability.symbols @@ -0,0 +1,80 @@ +=== tests/cases/compiler/file.js === +// reduced a bit from Webpack + +const EMPTY_MAP = new Map(); +>EMPTY_MAP : Symbol(EMPTY_MAP, Decl(file.js, 2, 5)) +>Map : Symbol(Map, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + +class HarmonyExportInitFragment { +>HarmonyExportInitFragment : Symbol(HarmonyExportInitFragment, Decl(file.js, 2, 28)) + + /** + * @param {Map} exportMap mapping from used name to exposed variable name + */ + constructor( + exportMap = EMPTY_MAP, +>exportMap : Symbol(exportMap, Decl(file.js, 8, 16)) +>EMPTY_MAP : Symbol(EMPTY_MAP, Decl(file.js, 2, 5)) + + ) { + this.exportMap = exportMap; +>this.exportMap : Symbol(HarmonyExportInitFragment.exportMap, Decl(file.js, 10, 7)) +>this : Symbol(HarmonyExportInitFragment, Decl(file.js, 2, 28)) +>exportMap : Symbol(HarmonyExportInitFragment.exportMap, Decl(file.js, 10, 7)) +>exportMap : Symbol(exportMap, Decl(file.js, 8, 16)) + } + + /** + * @param {HarmonyExportInitFragment[]} fragments all fragments to merge + */ + mergeAll(fragments) { +>mergeAll : Symbol(HarmonyExportInitFragment.mergeAll, Decl(file.js, 12, 5)) +>fragments : Symbol(fragments, Decl(file.js, 17, 13)) + + let exportMap; +>exportMap : Symbol(exportMap, Decl(file.js, 18, 11)) + + let exportMapOwned = false; +>exportMapOwned : Symbol(exportMapOwned, Decl(file.js, 19, 11)) + + for (const fragment of fragments) { +>fragment : Symbol(fragment, Decl(file.js, 21, 18)) +>fragments : Symbol(fragments, Decl(file.js, 17, 13)) + + if (fragment.exportMap.size !== 0) { +>fragment.exportMap.size : Symbol(Map.size, Decl(lib.es2015.collection.d.ts, --, --)) +>fragment.exportMap : Symbol(HarmonyExportInitFragment.exportMap, Decl(file.js, 10, 7)) +>fragment : Symbol(fragment, Decl(file.js, 21, 18)) +>exportMap : Symbol(HarmonyExportInitFragment.exportMap, Decl(file.js, 10, 7)) +>size : Symbol(Map.size, Decl(lib.es2015.collection.d.ts, --, --)) + + if (exportMap === undefined) { +>exportMap : Symbol(exportMap, Decl(file.js, 18, 11)) +>undefined : Symbol(undefined) + + exportMap = fragment.exportMap; +>exportMap : Symbol(exportMap, Decl(file.js, 18, 11)) +>fragment.exportMap : Symbol(HarmonyExportInitFragment.exportMap, Decl(file.js, 10, 7)) +>fragment : Symbol(fragment, Decl(file.js, 21, 18)) +>exportMap : Symbol(HarmonyExportInitFragment.exportMap, Decl(file.js, 10, 7)) + + exportMapOwned = false; +>exportMapOwned : Symbol(exportMapOwned, Decl(file.js, 19, 11)) + + } else { + if (!exportMapOwned) { +>exportMapOwned : Symbol(exportMapOwned, Decl(file.js, 19, 11)) + + exportMap = new Map(exportMap); +>exportMap : Symbol(exportMap, Decl(file.js, 18, 11)) +>Map : Symbol(Map, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>exportMap : Symbol(exportMap, Decl(file.js, 18, 11)) + + exportMapOwned = true; +>exportMapOwned : Symbol(exportMapOwned, Decl(file.js, 19, 11)) + } + } + } + } + } +} diff --git a/tests/baselines/reference/nonStrictMapConstructorCompatability.types b/tests/baselines/reference/nonStrictMapConstructorCompatability.types new file mode 100644 index 0000000000000..39583f82dfeec --- /dev/null +++ b/tests/baselines/reference/nonStrictMapConstructorCompatability.types @@ -0,0 +1,94 @@ +=== tests/cases/compiler/file.js === +// reduced a bit from Webpack + +const EMPTY_MAP = new Map(); +>EMPTY_MAP : Map +>new Map() : Map +>Map : MapConstructor + +class HarmonyExportInitFragment { +>HarmonyExportInitFragment : HarmonyExportInitFragment + + /** + * @param {Map} exportMap mapping from used name to exposed variable name + */ + constructor( + exportMap = EMPTY_MAP, +>exportMap : Map +>EMPTY_MAP : Map + + ) { + this.exportMap = exportMap; +>this.exportMap = exportMap : Map +>this.exportMap : any +>this : this +>exportMap : any +>exportMap : Map + } + + /** + * @param {HarmonyExportInitFragment[]} fragments all fragments to merge + */ + mergeAll(fragments) { +>mergeAll : (fragments: HarmonyExportInitFragment[]) => void +>fragments : HarmonyExportInitFragment[] + + let exportMap; +>exportMap : any + + let exportMapOwned = false; +>exportMapOwned : boolean +>false : false + + for (const fragment of fragments) { +>fragment : HarmonyExportInitFragment +>fragments : HarmonyExportInitFragment[] + + if (fragment.exportMap.size !== 0) { +>fragment.exportMap.size !== 0 : boolean +>fragment.exportMap.size : number +>fragment.exportMap : Map +>fragment : HarmonyExportInitFragment +>exportMap : Map +>size : number +>0 : 0 + + if (exportMap === undefined) { +>exportMap === undefined : boolean +>exportMap : Map +>undefined : undefined + + exportMap = fragment.exportMap; +>exportMap = fragment.exportMap : Map +>exportMap : any +>fragment.exportMap : Map +>fragment : HarmonyExportInitFragment +>exportMap : Map + + exportMapOwned = false; +>exportMapOwned = false : false +>exportMapOwned : boolean +>false : false + + } else { + if (!exportMapOwned) { +>!exportMapOwned : boolean +>exportMapOwned : boolean + + exportMap = new Map(exportMap); +>exportMap = new Map(exportMap) : Map +>exportMap : any +>new Map(exportMap) : Map +>Map : MapConstructor +>exportMap : Map + + exportMapOwned = true; +>exportMapOwned = true : true +>exportMapOwned : boolean +>true : true + } + } + } + } + } +} diff --git a/tests/cases/compiler/nonStrictMapConstructorCompatability.ts b/tests/cases/compiler/nonStrictMapConstructorCompatability.ts new file mode 100644 index 0000000000000..7c8cfaa388cf9 --- /dev/null +++ b/tests/cases/compiler/nonStrictMapConstructorCompatability.ts @@ -0,0 +1,43 @@ +// @target: es6 +// @checkJs: true +// @allowJs: true +// @noEmit: true +// @strict: false +// @filename: file.js + +// reduced a bit from Webpack + +const EMPTY_MAP = new Map(); + +class HarmonyExportInitFragment { + /** + * @param {Map} exportMap mapping from used name to exposed variable name + */ + constructor( + exportMap = EMPTY_MAP, + ) { + this.exportMap = exportMap; + } + + /** + * @param {HarmonyExportInitFragment[]} fragments all fragments to merge + */ + mergeAll(fragments) { + let exportMap; + let exportMapOwned = false; + + for (const fragment of fragments) { + if (fragment.exportMap.size !== 0) { + if (exportMap === undefined) { + exportMap = fragment.exportMap; + exportMapOwned = false; + } else { + if (!exportMapOwned) { + exportMap = new Map(exportMap); + exportMapOwned = true; + } + } + } + } + } +} \ No newline at end of file From 7a9751ec70927310e35e9b4b31583f4d1e052926 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Mon, 19 Sep 2022 14:10:51 -0700 Subject: [PATCH 17/24] Remove sourcefile lookup to see perf impact --- src/compiler/checker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 838b0dc1f8368..6e081e343105b 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -359,7 +359,7 @@ namespace ts { const moduleKind = getEmitModuleKind(compilerOptions); const useDefineForClassFields = getUseDefineForClassFields(compilerOptions); const allowSyntheticDefaultImports = getAllowSyntheticDefaultImports(compilerOptions); - const strictNullChecks = (context: Node | undefined) => getStrictOptionValue(context && getSourceFileOfNode(context), compilerOptions, "strictNullChecks"); + const strictNullChecks = (_context: Node | undefined) => getStrictOptionValue(/*context && getSourceFileOfNode(context)*/ undefined, compilerOptions, "strictNullChecks"); const strictFunctionTypes = (file: SourceFile | undefined) => getStrictOptionValue(file, compilerOptions, "strictFunctionTypes"); const strictBindCallApply = (file: SourceFile | undefined) => getStrictOptionValue(file, compilerOptions, "strictBindCallApply"); const strictPropertyInitialization = (file: SourceFile) => getStrictOptionValue(file, compilerOptions, "strictPropertyInitialization"); From de8bdbe1806f2302f2c3be347d784d30a2e4c351 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Wed, 21 Sep 2022 09:01:41 -0700 Subject: [PATCH 18/24] Revert "Remove sourcefile lookup to see perf impact" This reverts commit 7a9751ec70927310e35e9b4b31583f4d1e052926. --- src/compiler/checker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 6e081e343105b..838b0dc1f8368 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -359,7 +359,7 @@ namespace ts { const moduleKind = getEmitModuleKind(compilerOptions); const useDefineForClassFields = getUseDefineForClassFields(compilerOptions); const allowSyntheticDefaultImports = getAllowSyntheticDefaultImports(compilerOptions); - const strictNullChecks = (_context: Node | undefined) => getStrictOptionValue(/*context && getSourceFileOfNode(context)*/ undefined, compilerOptions, "strictNullChecks"); + const strictNullChecks = (context: Node | undefined) => getStrictOptionValue(context && getSourceFileOfNode(context), compilerOptions, "strictNullChecks"); const strictFunctionTypes = (file: SourceFile | undefined) => getStrictOptionValue(file, compilerOptions, "strictFunctionTypes"); const strictBindCallApply = (file: SourceFile | undefined) => getStrictOptionValue(file, compilerOptions, "strictBindCallApply"); const strictPropertyInitialization = (file: SourceFile) => getStrictOptionValue(file, compilerOptions, "strictPropertyInitialization"); From fcee526c471b18d09b110e5c5e775f2366257d91 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Wed, 21 Sep 2022 09:03:47 -0700 Subject: [PATCH 19/24] Use fixed value for SNC to see perf floor of optimizing the function --- src/compiler/checker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 838b0dc1f8368..5596140246655 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -359,7 +359,7 @@ namespace ts { const moduleKind = getEmitModuleKind(compilerOptions); const useDefineForClassFields = getUseDefineForClassFields(compilerOptions); const allowSyntheticDefaultImports = getAllowSyntheticDefaultImports(compilerOptions); - const strictNullChecks = (context: Node | undefined) => getStrictOptionValue(context && getSourceFileOfNode(context), compilerOptions, "strictNullChecks"); + const strictNullChecks = (_context: Node | undefined) => true; //getStrictOptionValue(context && getSourceFileOfNode(context), compilerOptions, "strictNullChecks"); const strictFunctionTypes = (file: SourceFile | undefined) => getStrictOptionValue(file, compilerOptions, "strictFunctionTypes"); const strictBindCallApply = (file: SourceFile | undefined) => getStrictOptionValue(file, compilerOptions, "strictBindCallApply"); const strictPropertyInitialization = (file: SourceFile) => getStrictOptionValue(file, compilerOptions, "strictPropertyInitialization"); From 454e854f1251b263b60fa0a47650e6717aa8915b Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Wed, 21 Sep 2022 09:05:45 -0700 Subject: [PATCH 20/24] Revert "Use fixed value for SNC to see perf floor of optimizing the function" This reverts commit fcee526c471b18d09b110e5c5e775f2366257d91. --- src/compiler/checker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 5596140246655..838b0dc1f8368 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -359,7 +359,7 @@ namespace ts { const moduleKind = getEmitModuleKind(compilerOptions); const useDefineForClassFields = getUseDefineForClassFields(compilerOptions); const allowSyntheticDefaultImports = getAllowSyntheticDefaultImports(compilerOptions); - const strictNullChecks = (_context: Node | undefined) => true; //getStrictOptionValue(context && getSourceFileOfNode(context), compilerOptions, "strictNullChecks"); + const strictNullChecks = (context: Node | undefined) => getStrictOptionValue(context && getSourceFileOfNode(context), compilerOptions, "strictNullChecks"); const strictFunctionTypes = (file: SourceFile | undefined) => getStrictOptionValue(file, compilerOptions, "strictFunctionTypes"); const strictBindCallApply = (file: SourceFile | undefined) => getStrictOptionValue(file, compilerOptions, "strictBindCallApply"); const strictPropertyInitialization = (file: SourceFile) => getStrictOptionValue(file, compilerOptions, "strictPropertyInitialization"); From b632e6a8a1b325fa56c157600eb048e6b682536f Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Wed, 21 Sep 2022 09:16:29 -0700 Subject: [PATCH 21/24] Once again, set snc to fixed value to see perf floor of function --- src/compiler/checker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 3efcc8d526f27..4550565cef432 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -359,7 +359,7 @@ namespace ts { const moduleKind = getEmitModuleKind(compilerOptions); const useDefineForClassFields = getUseDefineForClassFields(compilerOptions); const allowSyntheticDefaultImports = getAllowSyntheticDefaultImports(compilerOptions); - const strictNullChecks = (context: Node | undefined) => getStrictOptionValue(context && getSourceFileOfNode(context), compilerOptions, "strictNullChecks"); + const strictNullChecks = (_context: Node | undefined) => true; //getStrictOptionValue(context && getSourceFileOfNode(context), compilerOptions, "strictNullChecks"); const strictFunctionTypes = (file: SourceFile | undefined) => getStrictOptionValue(file, compilerOptions, "strictFunctionTypes"); const strictBindCallApply = (file: SourceFile | undefined) => getStrictOptionValue(file, compilerOptions, "strictBindCallApply"); const strictPropertyInitialization = (file: SourceFile) => getStrictOptionValue(file, compilerOptions, "strictPropertyInitialization"); From 08dfb4c50c1a3d3e6b54d0717d200e752c6691e0 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Wed, 21 Sep 2022 12:24:55 -0700 Subject: [PATCH 22/24] Revert "Once again, set snc to fixed value to see perf floor of function" This reverts commit b632e6a8a1b325fa56c157600eb048e6b682536f. --- src/compiler/checker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 4550565cef432..3efcc8d526f27 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -359,7 +359,7 @@ namespace ts { const moduleKind = getEmitModuleKind(compilerOptions); const useDefineForClassFields = getUseDefineForClassFields(compilerOptions); const allowSyntheticDefaultImports = getAllowSyntheticDefaultImports(compilerOptions); - const strictNullChecks = (_context: Node | undefined) => true; //getStrictOptionValue(context && getSourceFileOfNode(context), compilerOptions, "strictNullChecks"); + const strictNullChecks = (context: Node | undefined) => getStrictOptionValue(context && getSourceFileOfNode(context), compilerOptions, "strictNullChecks"); const strictFunctionTypes = (file: SourceFile | undefined) => getStrictOptionValue(file, compilerOptions, "strictFunctionTypes"); const strictBindCallApply = (file: SourceFile | undefined) => getStrictOptionValue(file, compilerOptions, "strictBindCallApply"); const strictPropertyInitialization = (file: SourceFile) => getStrictOptionValue(file, compilerOptions, "strictPropertyInitialization"); From 638a3bfb1ed715b18e647c28e00b95821a714c00 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Wed, 21 Sep 2022 12:42:58 -0700 Subject: [PATCH 23/24] Remove now duplicated handling of `missingType` --- src/compiler/checker.ts | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 3efcc8d526f27..04c55f550f0a5 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -14952,12 +14952,6 @@ namespace ts { includes & TypeFlags.IncludesWildcard ? wildcardType : anyType : includes & TypeFlags.Null || containsType(typeSet, unknownType) ? unknownType : nonNullUnknownType; } - if (includes & TypeFlags.Undefined) { - const missingIndex = binarySearch(typeSet, missingType, getTypeId, compareValues); - if (missingIndex >= 0 && containsType(typeSet, undefinedType)) { - orderedRemoveItemAt(typeSet, missingIndex); - } - } if (includes & (TypeFlags.Literal | TypeFlags.UniqueESSymbol | TypeFlags.TemplateLiteral | TypeFlags.StringMapping) || includes & TypeFlags.Void && includes & TypeFlags.Undefined) { removeRedundantLiteralTypes(typeSet, includes, !!(unionReduction & UnionReduction.Subtype)); } From 5b7732853c4968e93a6e26861ec049ee115a59d2 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Wed, 21 Sep 2022 13:56:05 -0700 Subject: [PATCH 24/24] Remove now-redundant control flow filtering logic --- src/compiler/checker.ts | 32 +++----------------------------- 1 file changed, 3 insertions(+), 29 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 04c55f550f0a5..f307191fa24bd 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -14784,11 +14784,11 @@ namespace ts { includes |= TypeFlags.IncludesNonWideningType; if (flags & TypeFlags.Undefined) { if (!undefinedVariant) undefinedVariant = type; - else undefinedVariant = undefinedType; // multiple of the missing, optional, or base undefined types combine to just normal undefined + else if (undefinedVariant !== type) undefinedVariant = undefinedType; // multiple of the missing, optional, or base undefined types combine to just normal undefined } else if (flags & TypeFlags.Null) { if (!nullVariant) nullVariant = type; - else nullVariant = nullType; + else if (nullVariant !== type) nullVariant = nullType; } } } @@ -25185,32 +25185,6 @@ namespace ts { return result; } - /** - * This function preserves the non-strict mode behavior of `undefined` and `null` evaporating on contact with a union - * It uses `filterType` rather than `getTypeWithFacts` because `getTypeWithFacts` would consider generic constraints, which - * the old non-strict union-creation behavior never did. - */ - function filterNullAndUndefinedFromUnionIfNotStrict(type: Type) { - if (strictNullChecks(reference)) { - return type; - } - if (!(type.flags & TypeFlags.Union)) { - return type; - } - let containedNull: Type | undefined; - const filtered = filterType(type, t => { - if (t.flags & TypeFlags.Null) { - containedNull = t; - } - return !(t.flags & TypeFlags.Nullable); - }); - if (!(filtered.flags & TypeFlags.Never)) { - return filtered; - } - // only null/undefined union members - if both are present, historically, this makes the union evaluate to `null` - return containedNull || type; - } - // At flow control branch or loop junctions, if the type along every antecedent code path // is an evolving array type, we construct a combined evolving array type. Otherwise we // finalize all evolving array types. @@ -25218,7 +25192,7 @@ namespace ts { if (isEvolvingArrayTypeList(types)) { return getEvolvingArrayType(getUnionType(map(types, getElementTypeOfEvolvingArrayType))); } - const result = filterNullAndUndefinedFromUnionIfNotStrict(recombineUnknownType(getUnionType(sameMap(types, finalizeEvolvingArrayType), subtypeReduction))); + const result = recombineUnknownType(getUnionType(sameMap(types, finalizeEvolvingArrayType), subtypeReduction)); if (result !== declaredType && result.flags & declaredType.flags & TypeFlags.Union && arraysEqual((result as UnionType).types, (declaredType as UnionType).types)) { return declaredType; }