diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts
index 4c3eac092b45a..6c6e1f0e41238 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;
             }
@@ -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 cfdc767d9cf40..f307191fa24bd 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 = (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");
+        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();
@@ -635,8 +635,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,
@@ -701,7 +701,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 });
                         }
                     });
@@ -779,7 +779,7 @@ namespace ts {
         const subtypeReductionCache = new Map<string, Type[]>();
         const cachedTypes = new Map<string, Type>();
         const evolvingArrayTypes: EvolvingArrayType[] = [];
-        const undefinedProperties: SymbolTable = new Map();
+        const undefinedProperties = new Map<string, Symbol>();
         const markerTypes = new Set<number>();
 
         const unknownSymbol = createSymbol(SymbolFlags.Property, "unknown" as __String);
@@ -797,11 +797,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 = 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 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");
@@ -859,7 +864,7 @@ namespace ts {
         const emptyTypeLiteralType = createAnonymousType(emptyTypeLiteralSymbol, emptySymbols, emptyArray, emptyArray, emptyArray);
 
         const unknownEmptyObjectType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, emptyArray);
-        const unknownUnionType = strictNullChecks ? getUnionType([undefinedType, nullType, unknownEmptyObjectType]) : unknownType;
+        const unknownUnionType = getUnionType([undefinedType, nullType, unknownEmptyObjectType]);
 
         const emptyGenericType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, emptyArray) as ObjectType as GenericType;
         emptyGenericType.instantiations = new Map<string, TypeReference>();
@@ -956,8 +961,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;
@@ -1079,6 +1084,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;
         }
@@ -3608,7 +3624,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);
@@ -3707,7 +3723,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;
@@ -6099,7 +6115,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);
 
@@ -6752,7 +6768,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;
             }
@@ -8885,9 +8901,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
@@ -8968,19 +8984,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;
                     }
@@ -9030,9 +9046,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) {
@@ -9053,8 +9069,8 @@ namespace ts {
             return expr.kind === SyntaxKind.ArrayLiteralExpression && (expr as ArrayLiteralExpression).elements.length === 0;
         }
 
-        function addOptionality(type: Type, isProperty = false, 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
@@ -9066,7 +9082,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;
             }
 
@@ -9092,10 +9108,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, declaration, isProperty, 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,
@@ -9132,7 +9148,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, declaration, /*isProperty*/ undefined, isOptional);
                 }
             }
 
@@ -9146,10 +9162,10 @@ namespace ts {
                     }
                 }
                 const type = widenTypeInferredFromInitializer(declaration, checkDeclarationInitializer(declaration, checkMode));
-                return addOptionality(type, isProperty, isOptional);
+                return addOptionality(type, declaration, isProperty, 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)) {
@@ -9157,14 +9173,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, /*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, /*isProperty*/ true, isOptional);
+                    return type && addOptionality(type, declaration, /*isProperty*/ true, isOptional);
                 }
             }
 
@@ -9208,7 +9224,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) {
@@ -9237,7 +9253,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[]) {
@@ -9250,11 +9266,11 @@ 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.
-                if (everyType(flowType, isNullableType)) {
+                if (everyType(flowType, t => isNullableType(t, reference))) {
                     continue;
                 }
                 return convertAutoToAny(flowType);
@@ -9270,18 +9286,18 @@ 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.
-            return everyType(flowType, isNullableType) ? undefined : convertAutoToAny(flowType);
+            return everyType(flowType, t => isNullableType(t, reference)) ? undefined : convertAutoToAny(flowType);
         }
 
         function getFlowTypeOfProperty(reference: Node, prop: Symbol | undefined) {
             const initialType = prop?.valueDeclaration
                 && (!isAutoTypedProperty(prop) || getEffectiveModifierFlags(prop.valueDeclaration) & ModifierFlags.Ambient)
                 && getTypeOfPropertyInBaseClass(prop)
-                || undefinedType;
+                || (strictNullChecks(reference) ? undefinedType : undefinedPermissiveType);
             return getFlowTypeOfReference(reference, autoType, initialType);
         }
 
@@ -9353,7 +9369,7 @@ namespace ts {
                     type = getUnionType(sourceTypes!);
                 }
             }
-            const widened = getWidenedType(addOptionality(type, /*isProperty*/ false, 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;
@@ -9552,7 +9568,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);
@@ -9738,11 +9754,11 @@ 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
-                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)) {
@@ -9887,13 +9903,13 @@ namespace ts {
                     accessor && accessor.initializer && getWidenedTypeForVariableLikeDeclaration(accessor, /*includeOptionality*/ true);
                 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));
                     }
                     else if (accessor && !isPrivateWithinAmbient(accessor)) {
-                        errorOrSuggestion(noImplicitAny, accessor, Diagnostics.Member_0_implicitly_has_an_1_type, symbolToString(symbol), "any");
+                        errorOrSuggestion(noImplicitAny(accessor), accessor, Diagnostics.Member_0_implicitly_has_an_1_type, symbolToString(symbol), "any");
                     }
                     type = anyType;
                 }
@@ -9907,7 +9923,7 @@ namespace ts {
                     else if (getAnnotatedAccessorTypeNode(accessor)) {
                         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;
@@ -9993,7 +10009,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;
             }
         }
 
@@ -10041,7 +10057,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));
             }
@@ -11883,7 +11899,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;
@@ -11923,8 +11939,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(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()) {
                     error(currentNode, Diagnostics.Type_of_property_0_circularly_references_itself_in_mapped_type_1, symbolToString(symbol), typeToString(mappedType));
@@ -11954,7 +11970,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, /*isProperty*/ true, !!(getMappedTypeModifiers(type) & MappedTypeModifiers.IncludeOptional)), type.mapper) :
                     errorType);
         }
 
@@ -12147,6 +12163,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;
         }
@@ -12481,7 +12501,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 :
@@ -12491,7 +12511,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;
         }
 
@@ -12568,11 +12588,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;
@@ -12801,9 +12821,10 @@ namespace ts {
                     return symbol;
                 }
                 if (skipObjectFunctionPropertyAugment) return undefined;
+                const file = resolved.symbol?.declarations?.[0] && getSourceFileOfNode(resolved.symbol.declarations[0]);
                 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);
@@ -13028,8 +13049,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;
@@ -13314,10 +13335,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) {
@@ -13325,7 +13346,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) {
@@ -13761,7 +13782,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 ?
@@ -14067,9 +14088,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)) {
@@ -14081,14 +14102,14 @@ namespace ts {
                             return anyType;
                         }
                         checkNoTypeArguments(node);
-                        return !noImplicitAny ? anyType : undefined;
+                        return !noImplicitAny(node) ? anyType : undefined;
                 }
             }
         }
 
         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 {
@@ -14660,7 +14681,7 @@ namespace ts {
                 if (flags & (ElementFlags.Optional | ElementFlags.Rest)) {
                     lastOptionalOrRestIndex = expandedFlags.length;
                 }
-                expandedTypes.push(flags & ElementFlags.Optional ? addOptionality(type, /*isProperty*/ true) : type);
+                expandedTypes.push(flags & ElementFlags.Optional ? addOptionality(type, currentNode, /*isProperty*/ true) : type);
                 expandedFlags.push(flags);
                 if (expandedDeclarations && declaration) {
                     expandedDeclarations.push(declaration);
@@ -14696,7 +14717,7 @@ namespace ts {
         }
 
         function getTypeFromOptionalTypeNode(node: OptionalTypeNode): Type {
-            return addOptionality(getTypeFromTypeNode(node.type), /*isProperty*/ true);
+            return addOptionality(getTypeFromTypeNode(node.type), node, /*isProperty*/ true);
         }
 
         function getTypeId(type: Type): TypeId {
@@ -14716,37 +14737,74 @@ 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;
+            let nullVariant: Type | undefined;
+            includes = addTypesToUnionWorker(typeSet, includes, types);
+            if (includes & TypeFlags.Null) {
+                if (includes & TypeFlags.IncludesNonWideningType && nullVariant !== nullPermissiveType) {
+                    addTypeToListSorted(typeSet, includes & TypeFlags.IncludesNonWideningType ? nullVariant || nullType : nullWideningType);
+                }
+            }
+            if (includes & TypeFlags.Undefined) {
+                if (includes & TypeFlags.IncludesNonWideningType && undefinedVariant !== undefinedPermissiveType) {
+                    addTypeToListSorted(typeSet, includes & TypeFlags.IncludesNonWideningType ? undefinedVariant || undefinedType : undefinedWideningType);
+                }
+            }
+            if (!length(typeSet) && includes & TypeFlags.Nullable && includes & TypeFlags.IncludesNonWideningType) {
+                // One or more of the nullPermissiveType and undefinedPermissiveType, which _usually_ evaporate on contact with a union, _except_ when they're the only items.
+                // In such cases, they are preserved. If both are present, only the `null` survives.
+                addTypeToListSorted(typeSet, includes & TypeFlags.Null ? nullPermissiveType : undefinedPermissiveType);
             }
             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 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 if (nullVariant !== type) nullVariant = nullType;
+                            }
+                        }
+                    }
+                    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 {
@@ -14894,12 +14952,6 @@ namespace ts {
                         includes & TypeFlags.IncludesWildcard ? wildcardType : anyType :
                         includes & TypeFlags.Null || containsType(typeSet, unknownType) ? unknownType : nonNullUnknownType;
                 }
-                if (exactOptionalPropertyTypes && 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));
                 }
@@ -15037,8 +15089,8 @@ namespace ts {
                 if (flags & TypeFlags.AnyOrUnknown) {
                     if (type === wildcardType) includes |= TypeFlags.IncludesWildcard;
                 }
-                else if (strictNullChecks || !(flags & TypeFlags.Nullable)) {
-                    if (exactOptionalPropertyTypes && type === missingType) {
+                else {
+                    if (type === missingType) {
                         includes |= TypeFlags.IncludesMissingType;
                         type = undefinedType;
                     }
@@ -15212,17 +15264,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)) {
@@ -15231,9 +15285,6 @@ namespace ts {
             if (includes & TypeFlags.Any) {
                 return includes & TypeFlags.IncludesWildcard ? wildcardType : anyType;
             }
-            if (!strictNullChecks && includes & TypeFlags.Nullable) {
-                return includes & TypeFlags.IncludesEmptyObject ? neverType : 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 ||
@@ -15262,7 +15313,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);
                     }
@@ -15696,15 +15747,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);
@@ -15739,6 +15790,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) {
@@ -15775,7 +15827,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));
@@ -15787,8 +15839,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;
                         });
                     }
                 }
@@ -15810,35 +15862,35 @@ 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;
                 }
-                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;
+                            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));
                         }
                     }
 
                     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) + "]");
@@ -15889,7 +15941,7 @@ namespace ts {
                     return undefined;
                 }
             }
-            if (isJSLiteralType(objectType)) {
+            if (isJSLiteralType(objectType, accessNode)) {
                 return anyType;
             }
             if (accessNode) {
@@ -16106,7 +16158,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
@@ -16132,7 +16184,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;
@@ -16597,7 +16652,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.declarations?.[0], /*isProperty*/ true);
                         result.declarations = prop.declarations;
                         result.nameType = getSymbolLinks(prop).nameType;
                         result.syntheticOrigin = prop;
@@ -16685,7 +16740,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 +16843,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) {
@@ -16877,7 +16932,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, /*isProperty*/ true, !!node.questionToken));
         }
 
         function getTypeFromTypeNode(node: TypeNode): Type {
@@ -16891,7 +16946,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:
@@ -16905,14 +16960,14 @@ 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:
-                    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:
@@ -16941,7 +16996,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:
@@ -17389,8 +17444,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, /*isProperty*/ true) :
-                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;
         }
 
@@ -17932,7 +17987,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];
@@ -18257,7 +18312,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;
 
@@ -18293,10 +18351,10 @@ namespace ts {
                     // similar to return values, callback parameters are output positions. This means that a Promise<T>,
                     // 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);
@@ -18432,7 +18490,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 &&
@@ -18512,8 +18570,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;
@@ -18825,7 +18884,9 @@ namespace ts {
                     relatedInfo = [info];
                 }
                 else {
-                    relatedInfo.push(info);
+                    if (!some(relatedInfo, i => compareDiagnostics(i, info) === Comparison.EqualTo)) {
+                        relatedInfo.push(info);
+                    }
                 }
             }
 
@@ -18869,7 +18930,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 {
@@ -18884,7 +18945,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;
                 }
@@ -19168,7 +19228,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?.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
                 }
                 const isComparingJsxAttributes = !!(getObjectFlags(source) & ObjectFlags.JsxAttributes);
@@ -19946,13 +20008,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)) {
@@ -20268,7 +20330,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) {
@@ -20325,8 +20387,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*/ false, 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);
             }
@@ -20780,9 +20842,9 @@ 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);
+                            : getTypeWithFacts(propType, TypeFacts.NEUndefined, prop.valueDeclaration);
                         const related = isRelatedTo(type, targetInfo.type, RecursionFlags.Both, reportErrors);
                         if (!related) {
                             if (reportErrors) {
@@ -20939,7 +21001,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;
@@ -21434,12 +21497,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.
@@ -21514,7 +21577,7 @@ namespace ts {
         }
 
         function isEmptyLiteralType(type: Type): boolean {
-            return strictNullChecks ? type === implicitNeverType : type === undefinedWideningType;
+            return type === implicitNeverType || type === undefinedWideningType;
         }
 
         function isEmptyArrayLiteralType(type: Type): boolean {
@@ -21669,8 +21732,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 {
@@ -21703,10 +21766,15 @@ namespace ts {
                 getUnionType([type, undefinedType, nullType]);
         }
 
-        function getOptionalType(type: Type, isProperty = false): Type {
-            Debug.assert(strictNullChecks);
+        /**
+         * *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 {
             const missingOrUndefined = isProperty ? missingType : undefinedType;
-            return type.flags & TypeFlags.Undefined || type.flags & TypeFlags.Union && (type as UnionType).types[0] === missingOrUndefined ? type : getUnionType([type, missingOrUndefined]);
+            return type.flags & TypeFlags.Undefined || type.flags & TypeFlags.Union && (type as UnionType).types[0] === missingOrUndefined ? type : getUnionType([type, isProperty ? getMissingOrUndefinedType(context) : undefinedType]);
         }
 
         function getGlobalNonNullableTypeInstantiation(type: Type) {
@@ -21718,38 +21786,38 @@ 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;
         }
 
         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, context);
         }
 
         /**
@@ -21893,14 +21961,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, missingType);
+            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;
         }
 
@@ -22019,7 +22092,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;
@@ -22030,16 +22103,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;
                     }
@@ -22054,7 +22127,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);
                         }
@@ -22063,24 +22136,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);
@@ -22936,7 +23009,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 {
@@ -23311,7 +23387,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)) {
@@ -23334,7 +23410,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));
         }
 
@@ -23388,7 +23464,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);
         }
 
@@ -23431,7 +23507,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) {
@@ -23445,8 +23521,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[] {
@@ -23872,52 +23948,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;
@@ -23929,24 +24005,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);
@@ -23956,7 +24032,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;
                 }
@@ -23964,24 +24040,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;
@@ -23993,7 +24069,7 @@ namespace ts {
 
         function getTypeWithDefault(type: Type, defaultExpression: Expression) {
             return defaultExpression ?
-                getUnionType([getNonUndefinedType(type), getTypeOfExpression(defaultExpression)]) :
+                getUnionType([getNonUndefinedType(type, defaultExpression), getTypeOfExpression(defaultExpression)]) :
                 type;
         }
 
@@ -24001,18 +24077,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;
         }
@@ -24687,11 +24763,10 @@ 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.
-            return resultType === nonNullUnknownType ? unknownType : resultType;
+            return resultType;
 
             function getOrSetCacheKey() {
                 if (isKeySet) {
@@ -24850,7 +24925,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;
@@ -24955,7 +25030,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)));
@@ -25184,12 +25259,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);
@@ -25225,14 +25300,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;
             }
@@ -25289,7 +25364,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);
                             }
@@ -25323,7 +25398,7 @@ namespace ts {
                         if (leftType.flags & TypeFlags.StringOrNumberLiteralOrUnique) {
                             if (containsMissingType(type) && isAccessExpression(reference) && isMatchingReference(reference.expression, target) &&
                                 getAccessedPropertyName(reference) === getPropertyNameFromType(leftType as StringLiteralType | NumberLiteralType | UniqueESSymbolType)) {
-                                return getTypeWithFacts(type, assumeTrue ? TypeFacts.NEUndefined : TypeFacts.EQUndefined);
+                                return getTypeWithFacts(type, assumeTrue ? TypeFacts.NEUndefined : TypeFacts.EQUndefined, expr);
                             }
                             if (isMatchingReference(reference, target)) {
                                 return narrowByInKeyword(type, leftType as StringLiteralType | NumberLiteralType | UniqueESSymbolType, assumeTrue);
@@ -25381,7 +25456,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 {
@@ -25394,7 +25469,7 @@ namespace ts {
                 const valueType = getTypeOfExpression(value);
                 const doubleEquals = operator === SyntaxKind.EqualsEqualsToken || operator === SyntaxKind.ExclamationEqualsToken;
                 if (valueType.flags & TypeFlags.Nullable) {
-                    if (!strictNullChecks) {
+                    if (!strictNullChecks(value)) {
                         return type;
                     }
                     const facts = doubleEquals ?
@@ -25402,7 +25477,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) {
                     if (!doubleEquals && (type.flags & TypeFlags.Unknown || someType(type, isEmptyAnonymousObjectType))) {
@@ -25433,8 +25508,8 @@ namespace ts {
                     if (propertyAccess) {
                         return narrowTypeByDiscriminant(type, propertyAccess, t => narrowTypeByLiteralExpression(t, literal, assumeTrue));
                     }
-                    if (strictNullChecks && optionalChainContainsReference(target, reference) && assumeTrue === (literal.text !== "undefined")) {
-                        return getAdjustedTypeWithFacts(type, TypeFacts.NEUndefinedOrNull);
+                    if (strictNullChecks(reference) && optionalChainContainsReference(target, reference) && assumeTrue === (literal.text !== "undefined")) {
+                        return getAdjustedTypeWithFacts(type, TypeFacts.NEUndefinedOrNull, reference);
                     }
                     return type;
                 }
@@ -25444,12 +25519,12 @@ namespace ts {
             function narrowTypeByLiteralExpression(type: Type, literal: LiteralExpression, assumeTrue: boolean) {
                 return assumeTrue ?
                     narrowTypeByTypeName(type, literal.text) :
-                    getTypeWithFacts(type, typeofNEFacts.get(literal.text) || TypeFacts.TypeofNEHostObject);
+                    getTypeWithFacts(type, typeofNEFacts.get(literal.text) || TypeFacts.TypeofNEHostObject, reference);
             }
 
             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) {
@@ -25502,9 +25577,9 @@ 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, undefinedType, TypeFacts.EQUndefined);
+                    case "undefined": return narrowTypeByTypeFacts(type, strictNullChecks(reference) ? undefinedType : undefinedPermissiveType, TypeFacts.EQUndefined);
                 }
                 return narrowTypeByTypeFacts(type, nonPrimitiveType, TypeFacts.TypeofEQHostObject);
             }
@@ -25515,14 +25590,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);
             }
 
@@ -25537,7 +25612,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);
@@ -25601,8 +25676,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;
                 }
@@ -25700,7 +25775,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);
                         }
                     }
                 }
@@ -25715,9 +25790,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) {
@@ -25776,11 +25851,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;
             }
@@ -25865,14 +25940,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);
@@ -26061,6 +26136,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
@@ -26206,21 +26294,21 @@ 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);
+                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
             // from declaration to use, and when the variable's declared type doesn't include undefined but the
             // 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));
                     }
@@ -26455,7 +26543,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);
@@ -26857,7 +26945,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
@@ -26880,7 +26968,7 @@ namespace ts {
                     // There was no contextual ThisType<T> 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'.
@@ -26922,7 +27010,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;
             }
@@ -27792,7 +27880,7 @@ namespace ts {
         }
 
         function getIntersectedSignatures(signatures: readonly Signature[]) {
-            return getStrictOptionValue(compilerOptions, "noImplicitAny")
+            return some(signatures, s => noImplicitAny(s.declaration))
                 ? reduceLeft(
                     signatures,
                     (left, right) =>
@@ -28023,7 +28111,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);
@@ -28031,7 +28119,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, /*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);
@@ -28048,7 +28136,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) {
@@ -28160,7 +28248,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;
@@ -28277,7 +28365,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);
@@ -28396,10 +28484,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) {
@@ -28478,7 +28566,7 @@ namespace ts {
         function createJsxAttributesTypeFromAttributesProperty(openingLikeElement: JsxOpeningLikeElement, checkMode: CheckMode | undefined) {
             const attributes = openingLikeElement.attributes;
             const attributesType = getContextualType(attributes, ContextFlags.None);
-            const allAttributesTable = strictNullChecks ? createSymbolTable() : undefined;
+            const allAttributesTable = strictNullChecks(openingLikeElement) ? createSymbolTable() : undefined;
             let attributesTable = createSymbolTable();
             let spread: Type = emptyJsxObjectType;
             let hasSpreadAnyType = false;
@@ -28523,7 +28611,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);
@@ -28675,7 +28763,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;
@@ -28930,7 +29018,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);
                 }
             }
@@ -29240,12 +29328,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) {
@@ -29288,7 +29376,7 @@ namespace ts {
             node: Node,
             reportError: (node: Node, facts: TypeFacts) => void
         ): Type {
-            if (strictNullChecks && type.flags & TypeFlags.Unknown) {
+            if (strictNullChecks(node) && type.flags & TypeFlags.Unknown) {
                 if (isEntityNameExpression(node)) {
                     const nodeText = entityNameToString(node);
                     if (nodeText.length < 100) {
@@ -29299,10 +29387,15 @@ namespace ts {
                 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;
@@ -29479,7 +29572,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)) {
@@ -29548,14 +29644,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;
@@ -29569,8 +29665,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) {
@@ -29640,7 +29736,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(node) && strictPropertyInitialization(file) && isAccessExpression(node) && node.expression.kind === SyntaxKind.ThisKeyword) {
                 const declaration = prop && prop.valueDeclaration;
                 if (declaration && isPropertyWithoutInitializer(declaration)) {
                     if (!isStatic(declaration)) {
@@ -29651,13 +29748,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
@@ -30341,7 +30438,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;
                 }
             }
@@ -30415,7 +30512,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;
         }
@@ -31459,7 +31556,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;
         }
@@ -31683,7 +31780,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);
                     }
@@ -32245,7 +32342,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;
@@ -32411,7 +32508,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;
@@ -32528,12 +32625,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) {
@@ -32678,10 +32775,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;
@@ -32967,7 +33064,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);
@@ -33022,7 +33119,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);
@@ -33135,7 +33232,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
@@ -33147,7 +33245,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;
@@ -33160,7 +33258,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) {
@@ -33185,7 +33283,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) {
@@ -33241,7 +33339,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)) {
@@ -33287,7 +33385,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);
@@ -33345,10 +33443,10 @@ 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 (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.
@@ -33634,9 +33732,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 ? 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);
             }
         }
@@ -33648,7 +33746,7 @@ namespace ts {
 
         function checkVoidExpression(node: VoidExpression): Type {
             checkExpression(node.expression);
-            return undefinedWideningType;
+            return getUndefinedWideningType(node);
         }
 
         function checkAwaitExpressionGrammar(node: AwaitExpression): void {
@@ -33767,7 +33865,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;
@@ -33934,7 +34032,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++) {
@@ -33997,7 +34095,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) {
@@ -34020,7 +34118,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);
                     }
@@ -34053,9 +34151,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);
                 }
@@ -34069,8 +34167,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) {
@@ -34511,8 +34609,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);
@@ -34521,8 +34619,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);
@@ -34531,8 +34629,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);
@@ -34649,7 +34747,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;
@@ -34805,7 +34903,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);
@@ -34824,7 +34922,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);
@@ -35065,7 +35163,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);
@@ -35355,7 +35453,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));
@@ -35432,7 +35530,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:
@@ -35685,7 +35783,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);
@@ -35713,7 +35811,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);
                         }
                     }
@@ -36322,7 +36420,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;
             }
@@ -36925,7 +37026,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;
             }
@@ -36959,14 +37060,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 {
@@ -36992,7 +37093,7 @@ namespace ts {
                 type;
         }
 
-        function isAwaitedTypeNeeded(type: Type) {
+        function isAwaitedTypeNeeded(type: Type, context: Node | undefined) {
             // If this is already an `Awaited<T>`, we shouldn't wrap it. This helps to avoid `Awaited<Awaited<T>>` in higher-order.
             if (isTypeAny(type) || isAwaitedTypeInstantiation(type)) {
                 return false;
@@ -37004,7 +37105,7 @@ namespace ts {
                 // We only need `Awaited<T>` 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;
                 }
@@ -37025,7 +37126,7 @@ namespace ts {
             return undefined;
         }
 
-        function createAwaitedTypeIfNeeded(type: Type): Type {
+        function createAwaitedTypeIfNeeded(type: Type, context: Node | undefined): Type {
             // We wrap type `T` in `Awaited<T>` based on the following conditions:
             // - `T` is not already an `Awaited<U>`, and
             // - `T` is generic, and
@@ -37034,7 +37135,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;
@@ -37057,7 +37158,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);
         }
 
         /**
@@ -37100,7 +37201,7 @@ namespace ts {
             }
 
             // If `type` is generic and should be wrapped in `Awaited<T>`, return it.
-            if (isAwaitedTypeNeeded(type)) {
+            if (isAwaitedTypeNeeded(type, errorNode)) {
                 return typeAsAwaitable.awaitedTypeOfType = type;
             }
 
@@ -37175,7 +37276,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 <any>.
-            if (isThenableType(type)) {
+            if (isThenableType(type, errorNode)) {
                 if (errorNode) {
                     Debug.assertIsDefined(diagnosticMessage);
                     let chain: DiagnosticMessageChain | undefined;
@@ -37416,7 +37517,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);
@@ -38410,7 +38511,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 {
@@ -38422,7 +38523,7 @@ namespace ts {
                         if (isArrayBindingPattern(node.name)) {
                             checkIteratedTypeOrElementType(IterationUse.Destructuring, widenedType, undefinedType, node);
                         }
-                        else if (strictNullChecks) {
+                        else if (strictNullChecks(node)) {
                             checkNonNullNonVoidType(widenedType, node);
                         }
                     }
@@ -38564,7 +38665,7 @@ namespace ts {
         }
 
         function checkTestingKnownTruthyCallableOrAwaitableType(condExpr: Expression, condType: Type, body?: Statement | Expression) {
-            if (!strictNullChecks) return;
+            if (!strictNullChecks(condExpr)) return;
 
             helper(condExpr, body);
             while (isBinaryExpression(condExpr) && condExpr.operatorToken.kind === SyntaxKind.BarBarToken) {
@@ -38580,7 +38681,7 @@ namespace ts {
                 if (isModuleExportsAccessExpression(location)) return;
                 const type = location === condExpr ? condType : 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
@@ -38795,7 +38896,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
@@ -38877,7 +38983,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<T>` or `IterableIterator<T>` only in ES2015
             // or higher, when inside of an async generator or for-await-if, or when
@@ -38899,7 +39005,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);
                 }
             }
 
@@ -38936,7 +39042,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;
                     }
                 }
             }
@@ -38956,20 +39062,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) {
@@ -39520,7 +39626,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)) {
@@ -39710,7 +39816,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) {
@@ -39735,7 +39841,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);
             }
@@ -39784,7 +39890,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);
                 }
 
@@ -40402,7 +40508,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;
@@ -40430,7 +40536,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;
@@ -40679,7 +40785,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));
@@ -40779,7 +40885,7 @@ namespace ts {
         }
 
         function checkPropertyInitialization(node: ClassLikeDeclaration) {
-            if (!strictNullChecks || !strictPropertyInitialization || node.flags & NodeFlags.Ambient) {
+            if (!strictNullChecks(node) || !strictPropertyInitialization(getSourceFileOfNode(node)) || node.flags & NodeFlags.Ambient) {
                 return;
             }
             const constructor = findConstructorDeclaration(node);
@@ -40816,7 +40922,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;
                     }
@@ -40832,7 +40938,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);
         }
 
@@ -42205,7 +42311,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
@@ -42285,15 +42391,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);
             }
@@ -42331,9 +42437,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);
                             }
                         });
@@ -43206,8 +43312,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?.declarations?.[0] && getSourceFileOfNode(type.symbol.declarations[0]);
+            const functionType = getSignaturesOfType(type, SignatureKind.Call).length ? globalCallableFunctionType(file) :
+                getSignaturesOfType(type, SignatureKind.Construct).length ? globalNewableFunctionType(file) :
                 undefined;
             if (functionType) {
                 forEach(getPropertiesOfType(functionType), p => {
@@ -43530,7 +43637,7 @@ namespace ts {
         }
 
         function isRequiredInitializedParameter(parameter: ParameterDeclaration | JSDocParameterTag): boolean {
-            return !!strictNullChecks &&
+            return !!strictNullChecks(parameter) &&
                 !isOptionalParameter(parameter) &&
                 !isJSDocParameterTag(parameter) &&
                 !!parameter.initializer &&
@@ -43538,7 +43645,7 @@ namespace ts {
         }
 
         function isOptionalUninitializedParameterProperty(parameter: ParameterDeclaration) {
-            return strictNullChecks &&
+            return strictNullChecks(parameter) &&
                 isOptionalParameter(parameter) &&
                 !parameter.initializer &&
                 hasSyntacticModifier(parameter, ModifierFlags.ParameterPropertyModifier);
@@ -43699,7 +43806,7 @@ namespace ts {
                 flags |= NodeBuilderFlags.AllowUniqueESSymbolType;
             }
             if (addUndefined) {
-                type = getOptionalType(type);
+                type = getOptionalType(type, declarationIn);
             }
             return nodeBuilder.typeToTypeNode(type, enclosingDeclaration, flags | NodeBuilderFlags.MultilineObjectLiterals, tracker);
         }
@@ -44138,7 +44245,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);
@@ -44147,8 +44254,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 b3dcb04c777d9..2f567f89d23fd 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({
@@ -164,6 +165,7 @@ namespace ts {
             type: "list",
             element: {
                 name: "excludeDirectory",
+                category: Diagnostics.Watch_and_Build_Modes,
                 type: "string",
                 isFilePath: true,
                 extraValidation: specToDiagnostic
@@ -176,6 +178,7 @@ namespace ts {
             type: "list",
             element: {
                 name: "excludeFile",
+                category: Diagnostics.Watch_and_Build_Modes,
                 type: "string",
                 isFilePath: true,
                 extraValidation: specToDiagnostic
@@ -186,7 +189,7 @@ namespace ts {
     ];
 
     /* @internal */
-    export const commonOptionsWithBuild: CommandLineOption[] = [
+    export const commonOptionsWithBuild = is<readonly CommandLineOption[]>()([
         {
             name: "help",
             shortName: "h",
@@ -318,10 +321,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<CommandLineOptionOfCustomType>()({
         name: "target",
         shortName: "t",
         type: new Map(getEntries({
@@ -347,10 +350,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<CommandLineOptionOfCustomType>()({
         name: "module",
         shortName: "m",
         type: new Map(getEntries({
@@ -375,9 +378,9 @@ namespace ts {
         category: Diagnostics.Modules,
         description: Diagnostics.Specify_what_module_code_is_generated,
         defaultValueDescription: undefined,
-    };
+    });
 
-    const commandOptionsWithoutBuild: CommandLineOption[] = [
+    const commandOptionsWithoutBuild = is<readonly CommandLineOption[]>()([
         // CommandLine only options
         {
             name: "all",
@@ -453,6 +456,7 @@ namespace ts {
             element: {
                 name: "lib",
                 type: libMap,
+                category: Diagnostics.Language_and_Environment,
                 defaultValueDescription: undefined,
             },
             affectsProgramStructure: true,
@@ -672,6 +676,7 @@ namespace ts {
             category: Diagnostics.Type_Checking,
             description: Diagnostics.Enable_all_strict_type_checking_options,
             defaultValueDescription: false,
+            allowedAsPragma: true,
         },
         {
             name: "noImplicitAny",
@@ -681,7 +686,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",
@@ -691,7 +697,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",
@@ -701,7 +708,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",
@@ -711,7 +719,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",
@@ -721,7 +730,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",
@@ -731,7 +741,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",
@@ -742,6 +753,7 @@ namespace ts {
             category: Diagnostics.Type_Checking,
             description: Diagnostics.Default_catch_clause_variables_as_unknown_instead_of_any,
             defaultValueDescription: false,
+            allowedAsPragma: true,
         },
         {
             name: "alwaysStrict",
@@ -752,7 +764,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
@@ -764,6 +777,7 @@ namespace ts {
             category: Diagnostics.Type_Checking,
             description: Diagnostics.Enable_error_reporting_when_local_variables_aren_t_read,
             defaultValueDescription: false,
+            allowedAsPragma: true,
         },
         {
             name: "noUnusedParameters",
@@ -773,6 +787,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",
@@ -782,6 +797,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",
@@ -791,6 +807,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",
@@ -801,6 +818,7 @@ namespace ts {
             category: Diagnostics.Type_Checking,
             description: Diagnostics.Enable_error_reporting_for_fallthrough_cases_in_switch_statements,
             defaultValueDescription: false,
+            allowedAsPragma: true,
         },
         {
             name: "noUncheckedIndexedAccess",
@@ -810,6 +828,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",
@@ -819,6 +838,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",
@@ -829,6 +849,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
@@ -874,6 +895,7 @@ namespace ts {
             element: {
                 name: "rootDirs",
                 type: "string",
+                category: Diagnostics.Modules,
                 isFilePath: true
             },
             affectsModuleResolution: true,
@@ -888,6 +910,7 @@ namespace ts {
             element: {
                 name: "typeRoots",
                 type: "string",
+                category: Diagnostics.Modules,
                 isFilePath: true
             },
             affectsModuleResolution: true,
@@ -899,6 +922,7 @@ namespace ts {
             type: "list",
             element: {
                 name: "types",
+                category: Diagnostics.Modules,
                 type: "string"
             },
             affectsProgramStructure: true,
@@ -948,6 +972,7 @@ namespace ts {
             type: "list",
             element: {
                 name: "suffix",
+                category: Diagnostics.Modules,
                 type: "string",
             },
             listPreserveFalsyValues: true,
@@ -1338,6 +1363,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,
@@ -1356,37 +1382,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<readonly CommandLineOption[]>()([
         ...commonOptionsWithBuild,
         ...commandOptionsWithoutBuild,
-    ];
+    ] as const);
 
     /* @internal */
-    export const semanticDiagnosticsOptionDeclarations: readonly CommandLineOption[] =
-        optionDeclarations.filter(option => !!option.affectsSemanticDiagnostics);
+    type WithTrue<T, K extends keyof T> = T extends unknown ? K extends unknown ? T[K] extends true ? T : never : never : never;
+
+    function isAffectsSemanticDiagnosticsOption<T extends CommandLineOption>(option: T): option is WithTrue<T, "affectsSemanticDiagnostics"> {
+        return !!option.affectsSemanticDiagnostics;
+    }
 
     /* @internal */
-    export const affectsEmitOptionDeclarations: readonly CommandLineOption[] =
-        optionDeclarations.filter(option => !!option.affectsEmit);
+    export const semanticDiagnosticsOptionDeclarations = optionDeclarations.filter(isAffectsSemanticDiagnosticsOption);
+
+    function isAffectsEmitOption<T extends CommandLineOption>(option: T): option is WithTrue<T, "affectsEmit"> {
+        return !!option.affectsEmit;
+    }
 
     /* @internal */
-    export const affectsDeclarationPathOptionDeclarations: readonly CommandLineOption[] =
-        optionDeclarations.filter(option => !!option.affectsDeclarationPath);
+    export const affectsEmitOptionDeclarations = optionDeclarations.filter(isAffectsEmitOption);
+
+    function isAffectsDeclarationPathOption<T extends CommandLineOption>(option: T): option is WithTrue<T, "affectsDeclarationPath"> {
+        return !!option.affectsDeclarationPath;
+    }
 
     /* @internal */
-    export const moduleResolutionOptionDeclarations: readonly CommandLineOption[] =
-        optionDeclarations.filter(option => !!option.affectsModuleResolution);
+    export const affectsDeclarationPathOptionDeclarations = optionDeclarations.filter(isAffectsDeclarationPathOption);
+
+    function isAffectsModuleResolutionOption<T extends CommandLineOption>(option: T): option is WithTrue<T, "affectsModuleResolution"> {
+        return !!option.affectsModuleResolution;
+    }
+
+    /* @internal */
+    export const moduleResolutionOptionDeclarations = optionDeclarations.filter(isAffectsModuleResolutionOption);
+
+    function isSourceFileAffectingOptions<T extends CommandLineOption>(option: T): option is WithTrue<T, "affectsSourceFile" | "affectsModuleResolution" | "affectsBindDiagnostics"> {
+        return !!option.affectsSourceFile || !!option.affectsModuleResolution || !!option.affectsBindDiagnostics;
+    }
 
     /* @internal */
-    export const sourceFileAffectingCompilerOptions: readonly CommandLineOption[] = optionDeclarations.filter(option =>
-        !!option.affectsSourceFile || !!option.affectsModuleResolution || !!option.affectsBindDiagnostics);
+    export const sourceFileAffectingCompilerOptions = optionDeclarations.filter(isSourceFileAffectingOptions);
+
+    function isAffectsProgramStructureOption<T extends CommandLineOption>(option: T): option is WithTrue<T, "affectsProgramStructure"> {
+        return !!option.affectsProgramStructure;
+    }
 
     /* @internal */
-    export const optionsAffectingProgramStructure: readonly CommandLineOption[] =
-        optionDeclarations.filter(option => !!option.affectsProgramStructure);
+    export const optionsAffectingProgramStructure = optionDeclarations.filter(isAffectsProgramStructureOption);
+
+    /* @internal */
+    export function isStrictOption<T extends CommandLineOption>(option: T): option is WithTrue<T, "strictFlag"> {
+        return !!option.strictFlag === true;
+    }
+
+    function isAllowedAsPragmaOption<T extends CommandLineOption>(option: T): option is WithTrue<T, "allowedAsPragma"> {
+        return !!option.allowedAsPragma;
+    }
+
+    /* @internal */
+    export const optionsAllowedAsPragmaOption = optionDeclarations.filter(isAllowedAsPragmaOption);
+
+    /* @internal */
+    type CompilerOptionsIntoPragmaDefinitions<T extends CommandLineOption> = UnionToIntersection<T extends unknown ? {[K in T["name"] & string as `ts-${Lowercase<K>}`]: { readonly kind: PragmaKindFlags, readonly args: readonly [{ readonly name: "value", readonly optional: true }] }} : never>;
+
+    function convertCompilerOptionsIntoPragmasSpecs<T extends readonly CommandLineOption[]>(options: T): CompilerOptionsIntoPragmaDefinitions<T[number]> {
+        const result = {} as CompilerOptionsIntoPragmaDefinitions<T[number]>;
+        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 =>
@@ -1442,11 +1560,13 @@ namespace ts {
              */
             name: "enableAutoDiscovery",
             type: "boolean",
+            category: Diagnostics.File_Management,
             defaultValueDescription: false,
         },
         {
             name: "enable",
             type: "boolean",
+            category: Diagnostics.File_Management,
             defaultValueDescription: false,
         },
         {
@@ -1454,20 +1574,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,
         },
     ];
@@ -1674,10 +1799,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[]
@@ -1705,7 +1831,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)));
             }
 
@@ -1981,30 +2107,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",
@@ -2016,6 +2147,7 @@ namespace ts {
                         type: "list",
                         element: {
                             name: "references",
+                            category: Diagnostics.Projects,
                             type: "object"
                         },
                         category: Diagnostics.Projects,
@@ -2025,6 +2157,7 @@ namespace ts {
                         type: "list",
                         element: {
                             name: "files",
+                            category: Diagnostics.File_Management,
                             type: "string"
                         },
                         category: Diagnostics.File_Management,
@@ -2034,6 +2167,7 @@ namespace ts {
                         type: "list",
                         element: {
                             name: "include",
+                            category: Diagnostics.File_Management,
                             type: "string"
                         },
                         category: Diagnostics.File_Management,
@@ -2044,6 +2178,7 @@ namespace ts {
                         type: "list",
                         element: {
                             name: "exclude",
+                            category: Diagnostics.File_Management,
                             type: "string"
                         },
                         category: Diagnostics.File_Management,
@@ -2587,7 +2722,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 698f7bb2fb705..814be7c072b49 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<T>(name: string, candidates: T[], getName: (candidate: T) => string | undefined): T | undefined {
+    export function getSpellingSuggestion<T>(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;
@@ -2530,4 +2530,8 @@ namespace ts {
         }
         return s.slice(0, end + 1);
     }
+
+    export function is<T>(): <U extends T>(arg: U) => U {
+        return identity;
+    }
 }
diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json
index 7a8f3192d917c..3d5502025ee05 100644
--- a/src/compiler/diagnosticMessages.json
+++ b/src/compiler/diagnosticMessages.json
@@ -908,6 +908,11 @@
         "code": 1276
     },
 
+    "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/parser.ts b/src/compiler/parser.ts
index bd85362d90409..25233abe71a79 100644
--- a/src/compiler/parser.ts
+++ b/src/compiler/parser.ts
@@ -9713,6 +9713,7 @@ namespace ts {
     export interface PragmaContext {
         languageVersion: ScriptTarget;
         pragmas?: PragmaMap;
+        localOptions?: CompilerOptions;
         checkJsDirective?: CheckJsDirective;
         referencedFiles: FileReference[];
         typeReferenceDirectives: FileReference[];
@@ -9720,6 +9721,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 {
@@ -9836,12 +9838,65 @@ 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<FileLocalOptionName>}`>).value;
+                    let parsedValue: OptionsBase[string];
+                    const errors: Diagnostic[] = [];
+                    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));
+                    }
+                    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 5b48d317db7df..b76eba7b4d5ff 100644
--- a/src/compiler/program.ts
+++ b/src/compiler/program.ts
@@ -3288,7 +3288,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
@@ -3390,10 +3390,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");
             }
 
@@ -3522,7 +3522,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");
             }
 
@@ -3669,6 +3669,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<string>) {
                 if (emitFileName) {
@@ -4323,7 +4335,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:
@@ -4343,7 +4355,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 c495d51a2bb30..e96f35603ef2a 100644
--- a/src/compiler/transformers/ts.ts
+++ b/src/compiler/transformers/ts.ts
@@ -577,7 +577,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 7c773f5bdc3c5..ddc6ab09052b1 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 1753770f44ce4..73b66e2acd2e9 100644
--- a/src/compiler/types.ts
+++ b/src/compiler/types.ts
@@ -4084,6 +4084,7 @@ namespace ts {
         /* @internal */ checkJsDirective?: CheckJsDirective;
         /* @internal */ version: string;
         /* @internal */ pragmas: ReadonlyPragmaMap;
+        /* @internal */ localOptions?: CompilerOptions;
         /* @internal */ localJsxNamespace?: __String;
         /* @internal */ localJsxFragmentNamespace?: __String;
         /* @internal */ localJsxFactory?: EntityName;
@@ -4613,9 +4614,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.
@@ -4749,8 +4750,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;
@@ -5573,6 +5574,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<string, TypeNode & {truncating?: boolean, addedLength: number}>; // Collection of types serialized at this location
+        sourceFile?: SourceFile | undefined; // Cached lookup result of `getSourceFileOfNode`
     }
 
     export const enum TypeFlags {
@@ -5651,12 +5653,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 */
@@ -6842,7 +6844,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`
@@ -6855,6 +6857,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 */
@@ -6890,7 +6893,7 @@ namespace ts {
     /* @internal */
     export interface DidYouMeanOptionsDiagnostics {
         alternateMode?: AlternateModeDiagnostics;
-        optionDeclarations: CommandLineOption[];
+        optionDeclarations: readonly CommandLineOption[];
         unknownOptionDiagnostic: DiagnosticMessage,
         unknownDidYouMeanDiagnostic: DiagnosticMessage,
     }
@@ -9119,52 +9122,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> = TDesc extends {captureSpan: true} ? {value: string, pos: number, end: number} : string;
 
@@ -9175,7 +9132,7 @@ namespace ts {
             : {[K in TName]: PragmaArgTypeMaybeCapture<TDesc>};
 
     /* @internal */
-    type UnionToIntersection<U> =
+    export type UnionToIntersection<U> =
             (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never;
 
     /* @internal */
@@ -9187,7 +9144,7 @@ namespace ts {
      * Maps a pragma definition into the desired shape for its arguments object
      */
     /* @internal */
-    type PragmaArgumentType<KPrag extends keyof ConcretePragmaSpecs> =
+    export type PragmaArgumentType<KPrag extends keyof ConcretePragmaSpecs> =
         ConcretePragmaSpecs[KPrag] extends { args: readonly PragmaArgumentSpecification<any>[] }
             ? UnionToIntersection<ArgumentDefinitionToFieldUnion<ConcretePragmaSpecs[KPrag]["args"]>>
             : never;
diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts
index cdc0db9407b34..1d675f59c7123 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.
@@ -1105,14 +1105,21 @@ 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,
         };
     }
 
@@ -6457,6 +6464,17 @@ namespace ts {
         return !!(options.incremental || options.composite);
     }
 
+    export type FileLocalOptionName = (typeof optionsAllowedAsPragmaOption)[number]["name"];
+
+    export function getFileLocalCompilerOption<T extends FileLocalOptionName>(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"
@@ -6468,8 +6486,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 {
@@ -6493,7 +6511,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 5a891ad05c580..7a077b4c684cd 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 87148c13492a7..c2c799b55ff66 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<string, ts.CommandLineOption>;
diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts
index 7b8e091a96205..c2ba991990d89 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<string, ESMap<string, number>> {
+    function prepareConvertersForEnumLikeCompilerOptions(commandLineOptions: readonly CommandLineOption[]): ESMap<string, ESMap<string, number>> {
         const map = new Map<string, ESMap<string, number>>();
         for (const option of commandLineOptions) {
             if (typeof option.type === "object") {
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<ParameterInference>(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/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/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/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts
index 50fbd1d4dea72..decb5f48226e7 100644
--- a/tests/baselines/reference/api/tsserverlibrary.d.ts
+++ b/tests/baselines/reference/api/tsserverlibrary.d.ts
@@ -2337,7 +2337,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 d323d77c229dd..046fe99e1d442 100644
--- a/tests/baselines/reference/api/typescript.d.ts
+++ b/tests/baselines/reference/api/typescript.d.ts
@@ -2337,7 +2337,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/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) => <div>Hello</div>;
-    
-    let Fail1 = () => <Funk mandatoryFn={() => { }} optionalBool={true} />
-    let Fail2 = () => <Funk mandatoryFn={() => { }} optionalBool={true as true} />
-    let True = true as true;
-    let Fail3 = () => <Funk mandatoryFn={() => { }} optionalBool={True} />
-    let attrs2 = { optionalBool: true as true, mandatoryFn: () => { } }
-    let Success = () => <Funk {...attrs2} />
\ No newline at end of file
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<C>[P] | (TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : TInjectedProps[P])' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
           Type 'GetProps<C>[P]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
             Type 'GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-              Type 'Extract<keyof TInjectedProps, keyof GetProps<C>> extends keyof TInjectedProps ? TInjectedProps[Extract<keyof TInjectedProps, keyof GetProps<C>>] extends GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>] ? GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>] : TInjectedProps[Extract<keyof TInjectedProps, keyof GetProps<C>>] : GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-                Type 'GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>] | (TInjectedProps[Extract<keyof TInjectedProps, keyof GetProps<C>>] extends GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>] ? GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>] : TInjectedProps[Extract<keyof TInjectedProps, keyof GetProps<C>>])' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-                  Type 'GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-                    Type 'GetProps<C>[Extract<string, keyof GetProps<C>>] | GetProps<C>[Extract<number, keyof GetProps<C>>] | GetProps<C>[Extract<symbol, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-                      Type 'GetProps<C>[Extract<string, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-                        Type 'GetProps<C>[keyof GetProps<C> & string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-                          Type 'GetProps<C>[string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-                            Type '(Extract<string, keyof GetProps<C>> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : GetProps<C>[Extract<string, keyof GetProps<C>>]) | (Extract<number, keyof GetProps<C>> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract<number, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<number, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<number, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<number, keyof GetProps<C>>] : GetProps<C>[Extract<number, keyof GetProps<C>>]) | (Extract<symbol, keyof GetProps<C>> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract<symbol, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<symbol, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<symbol, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<symbol, keyof GetProps<C>>] : GetProps<C>[Extract<symbol, keyof GetProps<C>>])' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-                              Type 'Extract<string, keyof GetProps<C>> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : GetProps<C>[Extract<string, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-                                Type '(TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>]) | GetProps<C>[Extract<string, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-                                  Type 'TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-                                    Type 'GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] | TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-                                      Type 'GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-                                        Type 'GetProps<C>[string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-                                          Type 'keyof GetProps<C> & string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string] extends GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] ? GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string] : GetProps<C>[keyof GetProps<C> & string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-                                            Type '(TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string] extends GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] ? GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string]) | GetProps<C>[keyof GetProps<C> & string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-                                              Type 'TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string] extends GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] ? GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-                                                Type 'GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] | TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-                                                  Type 'GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-                                                    Type 'GetProps<C>[string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-                                                      Type 'string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & string] extends GetProps<C>[keyof TInjectedProps & string] ? GetProps<C>[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string] : GetProps<C>[string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+              Type 'GetProps<C>[P]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+                Type 'Extract<keyof TInjectedProps, keyof GetProps<C>> extends keyof TInjectedProps ? TInjectedProps[Extract<keyof TInjectedProps, keyof GetProps<C>>] extends GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>] ? GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>] : TInjectedProps[Extract<keyof TInjectedProps, keyof GetProps<C>>] : GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+                  Type 'GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>] | (TInjectedProps[Extract<keyof TInjectedProps, keyof GetProps<C>>] extends GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>] ? GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>] : TInjectedProps[Extract<keyof TInjectedProps, keyof GetProps<C>>])' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+                    Type 'GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+                      Type 'GetProps<C>[Extract<string, keyof GetProps<C>>] | GetProps<C>[Extract<number, keyof GetProps<C>>] | GetProps<C>[Extract<symbol, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+                        Type 'GetProps<C>[Extract<string, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+                          Type 'GetProps<C>[keyof GetProps<C> & string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+                            Type 'GetProps<C>[string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+                              Type 'GetProps<C>[keyof GetProps<C> & string]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+                                Type 'GetProps<C>[Extract<string, keyof GetProps<C>>]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+                                  Type 'GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+                                    Type '(Extract<string, keyof GetProps<C>> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : GetProps<C>[Extract<string, keyof GetProps<C>>]) | (Extract<number, keyof GetProps<C>> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract<number, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<number, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<number, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<number, keyof GetProps<C>>] : GetProps<C>[Extract<number, keyof GetProps<C>>]) | (Extract<symbol, keyof GetProps<C>> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract<symbol, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<symbol, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<symbol, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<symbol, keyof GetProps<C>>] : GetProps<C>[Extract<symbol, keyof GetProps<C>>])' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+                                      Type 'Extract<string, keyof GetProps<C>> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : GetProps<C>[Extract<string, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+                                        Type '(TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>]) | GetProps<C>[Extract<string, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+                                          Type 'TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+                                            Type 'GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] | TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+                                              Type 'GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+                                                Type 'GetProps<C>[string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+                                                  Type 'GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+                                                    Type 'TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+                                                      Type 'keyof GetProps<C> & string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string] extends GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] ? GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string] : GetProps<C>[keyof GetProps<C> & string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+                                                        Type '(TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string] extends GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] ? GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string]) | GetProps<C>[keyof GetProps<C> & string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+                                                          Type 'TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string] extends GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] ? GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+                                                            Type 'GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] | TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+                                                              Type 'GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+                                                                Type 'GetProps<C>[string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+                                                                  Type 'GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+                                                                    Type 'TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string] extends GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] ? GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+                                                                      Type 'string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & string] extends GetProps<C>[keyof TInjectedProps & string] ? GetProps<C>[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string] : GetProps<C>[string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+                                                                        Type 'keyof GetProps<C> & string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string] extends GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] ? GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string] : GetProps<C>[keyof GetProps<C> & string]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+                                                                          Type '(TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string] extends GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] ? GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string]) | GetProps<C>[keyof GetProps<C> & string]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+                                                                            Type 'TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string] extends GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] ? GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+                                                                              Type 'GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] | TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+                                                                                Type 'GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+                                                                                  Type 'GetProps<C>[string]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+                                                                                    Type 'Extract<string, keyof GetProps<C>> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : GetProps<C>[Extract<string, keyof GetProps<C>>]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+                                                                                      Type '(TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>]) | GetProps<C>[Extract<string, keyof GetProps<C>>]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+                                                                                        Type 'TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+                                                                                          Type 'GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] | TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+                                                                                            Type 'GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+                                                                                              Type 'GetProps<C>[string]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+                                                                                                Type 'Extract<keyof TInjectedProps, keyof GetProps<C>> extends keyof TInjectedProps ? TInjectedProps[Extract<keyof TInjectedProps, keyof GetProps<C>>] extends GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>] ? GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>] : TInjectedProps[Extract<keyof TInjectedProps, keyof GetProps<C>>] : GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+                                                                                                  Type 'GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>] | (TInjectedProps[Extract<keyof TInjectedProps, keyof GetProps<C>>] extends GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>] ? GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>] : TInjectedProps[Extract<keyof TInjectedProps, keyof GetProps<C>>])' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+                                                                                                    Type 'GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+                                                                                                      Type 'P extends keyof TInjectedProps ? TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : TInjectedProps[P] : GetProps<C>[P]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+                                                                                                        Type 'GetProps<C>[P] | (TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : TInjectedProps[P])' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+                                                                                                          Type 'GetProps<C>[P]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+                                                                                                            Type 'GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+                                                                                                              Type 'GetProps<C>[Extract<string, keyof GetProps<C>>] | GetProps<C>[Extract<number, keyof GetProps<C>>] | GetProps<C>[Extract<symbol, keyof GetProps<C>>]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+                                                                                                                Type 'GetProps<C>[Extract<string, keyof GetProps<C>>]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+                                                                                                                  Type 'GetProps<C>[keyof GetProps<C> & string]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+                                                                                                                    Type 'GetProps<C>[string]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
 
 
 ==== tests/cases/compiler/circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts (1 errors) ====
@@ -100,25 +131,56 @@ tests/cases/compiler/circularlyConstrainedMappedTypeContainingConditionalNoInfin
 !!! error TS2344:         Type 'GetProps<C>[P] | (TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : TInjectedProps[P])' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
 !!! error TS2344:           Type 'GetProps<C>[P]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
 !!! error TS2344:             Type 'GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-!!! error TS2344:               Type 'Extract<keyof TInjectedProps, keyof GetProps<C>> extends keyof TInjectedProps ? TInjectedProps[Extract<keyof TInjectedProps, keyof GetProps<C>>] extends GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>] ? GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>] : TInjectedProps[Extract<keyof TInjectedProps, keyof GetProps<C>>] : GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-!!! error TS2344:                 Type 'GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>] | (TInjectedProps[Extract<keyof TInjectedProps, keyof GetProps<C>>] extends GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>] ? GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>] : TInjectedProps[Extract<keyof TInjectedProps, keyof GetProps<C>>])' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-!!! error TS2344:                   Type 'GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-!!! error TS2344:                     Type 'GetProps<C>[Extract<string, keyof GetProps<C>>] | GetProps<C>[Extract<number, keyof GetProps<C>>] | GetProps<C>[Extract<symbol, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-!!! error TS2344:                       Type 'GetProps<C>[Extract<string, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-!!! error TS2344:                         Type 'GetProps<C>[keyof GetProps<C> & string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-!!! error TS2344:                           Type 'GetProps<C>[string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-!!! error TS2344:                             Type '(Extract<string, keyof GetProps<C>> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : GetProps<C>[Extract<string, keyof GetProps<C>>]) | (Extract<number, keyof GetProps<C>> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract<number, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<number, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<number, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<number, keyof GetProps<C>>] : GetProps<C>[Extract<number, keyof GetProps<C>>]) | (Extract<symbol, keyof GetProps<C>> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract<symbol, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<symbol, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<symbol, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<symbol, keyof GetProps<C>>] : GetProps<C>[Extract<symbol, keyof GetProps<C>>])' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-!!! error TS2344:                               Type 'Extract<string, keyof GetProps<C>> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : GetProps<C>[Extract<string, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-!!! error TS2344:                                 Type '(TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>]) | GetProps<C>[Extract<string, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-!!! error TS2344:                                   Type 'TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-!!! error TS2344:                                     Type 'GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] | TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-!!! error TS2344:                                       Type 'GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-!!! error TS2344:                                         Type 'GetProps<C>[string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-!!! error TS2344:                                           Type 'keyof GetProps<C> & string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string] extends GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] ? GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string] : GetProps<C>[keyof GetProps<C> & string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-!!! error TS2344:                                             Type '(TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string] extends GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] ? GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string]) | GetProps<C>[keyof GetProps<C> & string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-!!! error TS2344:                                               Type 'TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string] extends GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] ? GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-!!! error TS2344:                                                 Type 'GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] | TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-!!! error TS2344:                                                   Type 'GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-!!! error TS2344:                                                     Type 'GetProps<C>[string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-!!! error TS2344:                                                       Type 'string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & string] extends GetProps<C>[keyof TInjectedProps & string] ? GetProps<C>[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string] : GetProps<C>[string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+!!! error TS2344:               Type 'GetProps<C>[P]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+!!! error TS2344:                 Type 'Extract<keyof TInjectedProps, keyof GetProps<C>> extends keyof TInjectedProps ? TInjectedProps[Extract<keyof TInjectedProps, keyof GetProps<C>>] extends GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>] ? GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>] : TInjectedProps[Extract<keyof TInjectedProps, keyof GetProps<C>>] : GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+!!! error TS2344:                   Type 'GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>] | (TInjectedProps[Extract<keyof TInjectedProps, keyof GetProps<C>>] extends GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>] ? GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>] : TInjectedProps[Extract<keyof TInjectedProps, keyof GetProps<C>>])' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+!!! error TS2344:                     Type 'GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+!!! error TS2344:                       Type 'GetProps<C>[Extract<string, keyof GetProps<C>>] | GetProps<C>[Extract<number, keyof GetProps<C>>] | GetProps<C>[Extract<symbol, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+!!! error TS2344:                         Type 'GetProps<C>[Extract<string, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+!!! error TS2344:                           Type 'GetProps<C>[keyof GetProps<C> & string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+!!! error TS2344:                             Type 'GetProps<C>[string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+!!! error TS2344:                               Type 'GetProps<C>[keyof GetProps<C> & string]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+!!! error TS2344:                                 Type 'GetProps<C>[Extract<string, keyof GetProps<C>>]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+!!! error TS2344:                                   Type 'GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+!!! error TS2344:                                     Type '(Extract<string, keyof GetProps<C>> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : GetProps<C>[Extract<string, keyof GetProps<C>>]) | (Extract<number, keyof GetProps<C>> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract<number, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<number, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<number, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<number, keyof GetProps<C>>] : GetProps<C>[Extract<number, keyof GetProps<C>>]) | (Extract<symbol, keyof GetProps<C>> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract<symbol, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<symbol, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<symbol, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<symbol, keyof GetProps<C>>] : GetProps<C>[Extract<symbol, keyof GetProps<C>>])' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+!!! error TS2344:                                       Type 'Extract<string, keyof GetProps<C>> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : GetProps<C>[Extract<string, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+!!! error TS2344:                                         Type '(TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>]) | GetProps<C>[Extract<string, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+!!! error TS2344:                                           Type 'TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+!!! error TS2344:                                             Type 'GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] | TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+!!! error TS2344:                                               Type 'GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+!!! error TS2344:                                                 Type 'GetProps<C>[string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+!!! error TS2344:                                                   Type 'GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+!!! error TS2344:                                                     Type 'TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+!!! error TS2344:                                                       Type 'keyof GetProps<C> & string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string] extends GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] ? GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string] : GetProps<C>[keyof GetProps<C> & string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+!!! error TS2344:                                                         Type '(TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string] extends GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] ? GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string]) | GetProps<C>[keyof GetProps<C> & string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+!!! error TS2344:                                                           Type 'TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string] extends GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] ? GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+!!! error TS2344:                                                             Type 'GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] | TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+!!! error TS2344:                                                               Type 'GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+!!! error TS2344:                                                                 Type 'GetProps<C>[string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+!!! error TS2344:                                                                   Type 'GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+!!! error TS2344:                                                                     Type 'TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string] extends GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] ? GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+!!! error TS2344:                                                                       Type 'string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & string] extends GetProps<C>[keyof TInjectedProps & string] ? GetProps<C>[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string] : GetProps<C>[string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+!!! error TS2344:                                                                         Type 'keyof GetProps<C> & string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string] extends GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] ? GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string] : GetProps<C>[keyof GetProps<C> & string]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+!!! error TS2344:                                                                           Type '(TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string] extends GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] ? GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string]) | GetProps<C>[keyof GetProps<C> & string]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+!!! error TS2344:                                                                             Type 'TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string] extends GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] ? GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+!!! error TS2344:                                                                               Type 'GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] | TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+!!! error TS2344:                                                                                 Type 'GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+!!! error TS2344:                                                                                   Type 'GetProps<C>[string]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+!!! error TS2344:                                                                                     Type 'Extract<string, keyof GetProps<C>> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : GetProps<C>[Extract<string, keyof GetProps<C>>]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+!!! error TS2344:                                                                                       Type '(TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>]) | GetProps<C>[Extract<string, keyof GetProps<C>>]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+!!! error TS2344:                                                                                         Type 'TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+!!! error TS2344:                                                                                           Type 'GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] | TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+!!! error TS2344:                                                                                             Type 'GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+!!! error TS2344:                                                                                               Type 'GetProps<C>[string]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+!!! error TS2344:                                                                                                 Type 'Extract<keyof TInjectedProps, keyof GetProps<C>> extends keyof TInjectedProps ? TInjectedProps[Extract<keyof TInjectedProps, keyof GetProps<C>>] extends GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>] ? GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>] : TInjectedProps[Extract<keyof TInjectedProps, keyof GetProps<C>>] : GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+!!! error TS2344:                                                                                                   Type 'GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>] | (TInjectedProps[Extract<keyof TInjectedProps, keyof GetProps<C>>] extends GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>] ? GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>] : TInjectedProps[Extract<keyof TInjectedProps, keyof GetProps<C>>])' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+!!! error TS2344:                                                                                                     Type 'GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+!!! error TS2344:                                                                                                       Type 'P extends keyof TInjectedProps ? TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : TInjectedProps[P] : GetProps<C>[P]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+!!! error TS2344:                                                                                                         Type 'GetProps<C>[P] | (TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : TInjectedProps[P])' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+!!! error TS2344:                                                                                                           Type 'GetProps<C>[P]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+!!! error TS2344:                                                                                                             Type 'GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+!!! error TS2344:                                                                                                               Type 'GetProps<C>[Extract<string, keyof GetProps<C>>] | GetProps<C>[Extract<number, keyof GetProps<C>>] | GetProps<C>[Extract<symbol, keyof GetProps<C>>]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+!!! error TS2344:                                                                                                                 Type 'GetProps<C>[Extract<string, keyof GetProps<C>>]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+!!! error TS2344:                                                                                                                   Type 'GetProps<C>[keyof GetProps<C> & string]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+!!! error TS2344:                                                                                                                     Type 'GetProps<C>[string]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[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<V extends Message>(protoCtor: MsgConstructor<V>): V {
 >protoCtor : MsgConstructor<V>
 
   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 a96e6b907f749..3af55ab1c8277 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<T, Bar>' 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<T extends { x: Map<T['x']> }>(sliceIndex: T): AllArg<T['x']> {
 >sliceIndex : T
 
     return null!;
->null! : null
+>null! : never
 >null : null
 }
 
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/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/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) ====
     /// <reference path="/.lib/react16.d.ts" />
     
     class I<T1 extends keyof JSX.IntrinsicElements, T2 extends keyof JSX.IntrinsicElements> {
@@ -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/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/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/baselines/reference/intersectionReduction.types b/tests/baselines/reference/intersectionReduction.types
index fc04d01441c43..d7b27bb530ac6 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;
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/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<S extends Schema>  {
 >getRows : <C extends keyof S>() => Array<UnrollOnHover<Pick<S, C>>>
 
         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<T>' only permits reading.
 tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(56,5): error TS2542: Index signature in type 'Readonly<T>' 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<T, U extends T, K extends keyof T>(x: T, y: Partial<U>, 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<T>(x: T, y: Readonly<T>, k: keyof T) {
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..5a6c61af365f3
--- /dev/null
+++ b/tests/baselines/reference/noPropertyAccessFromIndexSignaturePragma1.symbols
@@ -0,0 +1,71 @@
+=== 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.something : Symbol(A.__index, Decl(file1.ts, 1, 13))
+>a : Symbol(a, Decl(file1.ts, 4, 11))
+>something : Symbol(A.__index, Decl(file1.ts, 1, 13))
+
+=== 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.something : Symbol(A.__index, Decl(file2.ts, 1, 13))
+>a : Symbol(a, Decl(file2.ts, 4, 11))
+>something : Symbol(A.__index, Decl(file2.ts, 1, 13))
+
+=== 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.something : Symbol(A.__index, Decl(file3.ts, 1, 13))
+>a : Symbol(a, Decl(file3.ts, 4, 11))
+>something : Symbol(A.__index, Decl(file3.ts, 1, 13))
+
+=== 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.something : Symbol(A.__index, Decl(file4.ts, 0, 13))
+>a : Symbol(a, Decl(file4.ts, 3, 11))
+>something : Symbol(A.__index, Decl(file4.ts, 0, 13))
+
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..5a6c61af365f3
--- /dev/null
+++ b/tests/baselines/reference/noPropertyAccessFromIndexSignaturePragma2.symbols
@@ -0,0 +1,71 @@
+=== 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.something : Symbol(A.__index, Decl(file1.ts, 1, 13))
+>a : Symbol(a, Decl(file1.ts, 4, 11))
+>something : Symbol(A.__index, Decl(file1.ts, 1, 13))
+
+=== 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.something : Symbol(A.__index, Decl(file2.ts, 1, 13))
+>a : Symbol(a, Decl(file2.ts, 4, 11))
+>something : Symbol(A.__index, Decl(file2.ts, 1, 13))
+
+=== 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.something : Symbol(A.__index, Decl(file3.ts, 1, 13))
+>a : Symbol(a, Decl(file3.ts, 4, 11))
+>something : Symbol(A.__index, Decl(file3.ts, 1, 13))
+
+=== 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.something : Symbol(A.__index, Decl(file4.ts, 0, 13))
+>a : Symbol(a, Decl(file4.ts, 3, 11))
+>something : Symbol(A.__index, Decl(file4.ts, 0, 13))
+
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..a82e202c645cd
--- /dev/null
+++ b/tests/baselines/reference/noUncheckedIndexedAccessPragma1.symbols
@@ -0,0 +1,71 @@
+=== 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.something : Symbol(A.__index, Decl(file1.ts, 1, 13))
+>a : Symbol(a, Decl(file1.ts, 4, 11))
+>something : Symbol(A.__index, Decl(file1.ts, 1, 13))
+
+=== 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.something : Symbol(A.__index, Decl(file2.ts, 1, 13))
+>a : Symbol(a, Decl(file2.ts, 4, 11))
+>something : Symbol(A.__index, Decl(file2.ts, 1, 13))
+
+=== 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.something : Symbol(A.__index, Decl(file3.ts, 1, 13))
+>a : Symbol(a, Decl(file3.ts, 4, 11))
+>something : Symbol(A.__index, Decl(file3.ts, 1, 13))
+
+=== 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.something : Symbol(A.__index, Decl(file4.ts, 0, 13))
+>a : Symbol(a, Decl(file4.ts, 3, 11))
+>something : Symbol(A.__index, Decl(file4.ts, 0, 13))
+
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..a82e202c645cd
--- /dev/null
+++ b/tests/baselines/reference/noUncheckedIndexedAccessPragma2.symbols
@@ -0,0 +1,71 @@
+=== 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.something : Symbol(A.__index, Decl(file1.ts, 1, 13))
+>a : Symbol(a, Decl(file1.ts, 4, 11))
+>something : Symbol(A.__index, Decl(file1.ts, 1, 13))
+
+=== 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.something : Symbol(A.__index, Decl(file2.ts, 1, 13))
+>a : Symbol(a, Decl(file2.ts, 4, 11))
+>something : Symbol(A.__index, Decl(file2.ts, 1, 13))
+
+=== 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.something : Symbol(A.__index, Decl(file3.ts, 1, 13))
+>a : Symbol(a, Decl(file3.ts, 4, 11))
+>something : Symbol(A.__index, Decl(file3.ts, 1, 13))
+
+=== 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.something : Symbol(A.__index, Decl(file4.ts, 0, 13))
+>a : Symbol(a, Decl(file4.ts, 3, 11))
+>something : Symbol(A.__index, Decl(file4.ts, 0, 13))
+
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/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/baselines/reference/nonNullableReductionNonStrict.types b/tests/baselines/reference/nonNullableReductionNonStrict.types
index 075ee5a41fd1b..3aac0950df4a0 100644
--- a/tests/baselines/reference/nonNullableReductionNonStrict.types
+++ b/tests/baselines/reference/nonNullableReductionNonStrict.types
@@ -32,8 +32,8 @@ function f1<T>(x: T | (string extends T ? null | undefined : never)) {
 >null : null
 
     let z = x!;  // NonNullable<T>
->z : T | (string extends T ? null : never)
->x! : T | (string extends T ? null : never)
+>z : T
+>x! : T
 >x : T | (string extends T ? null : never)
 }
 
@@ -43,8 +43,8 @@ function f2<T, U extends null | undefined>(x: T | U) {
 >x : T | U
 
     let z = x!;  // NonNullable<T>
->z : T | U
->x! : T | U
+>z : T
+>x! : T
 >x : T | U
 }
 
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/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<string, string>} 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<any, any>
+>new Map() : Map<any, any>
+>Map : MapConstructor
+
+class HarmonyExportInitFragment {
+>HarmonyExportInitFragment : HarmonyExportInitFragment
+
+    /**
+     * @param {Map<string, string>} exportMap mapping from used name to exposed variable name
+     */
+    constructor(
+        exportMap = EMPTY_MAP,
+>exportMap : Map<string, string>
+>EMPTY_MAP : Map<any, any>
+
+    ) {
+        this.exportMap = exportMap;
+>this.exportMap = exportMap : Map<string, string>
+>this.exportMap : any
+>this : this
+>exportMap : any
+>exportMap : Map<string, string>
+    }
+
+    /**
+     * @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<string, string>
+>fragment : HarmonyExportInitFragment
+>exportMap : Map<string, string>
+>size : number
+>0 : 0
+
+                if (exportMap === undefined) {
+>exportMap === undefined : boolean
+>exportMap : Map<any, any>
+>undefined : undefined
+
+                    exportMap = fragment.exportMap;
+>exportMap = fragment.exportMap : Map<string, string>
+>exportMap : any
+>fragment.exportMap : Map<string, string>
+>fragment : HarmonyExportInitFragment
+>exportMap : Map<string, string>
+
+                    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<any, any>
+>exportMap : any
+>new Map(exportMap) : Map<any, any>
+>Map : MapConstructor
+>exportMap : Map<any, any>
+
+                        exportMapOwned = true;
+>exportMapOwned = true : true
+>exportMapOwned : boolean
+>true : true
+                    }
+                }
+            }
+        }
+    }
+}
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/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<T>(obj: T): T {
+	if (!obj || typeof obj !== 'object') {
+		return obj;
+	}
+	var result = (Array.isArray(obj)) ? <any>[] : <any>{};
+	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<T>(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)) ? <any>[] : <any>{};
+>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<T>(obj: T): T {
+>clone : <T>(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)) ? <any>[] : <any>{};
+>result : any
+>(Array.isArray(obj)) ? <any>[] : <any>{} : 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>[] : any
+>[] : undefined[]
+><any>{} : 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 : <T>(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/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/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<T>(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<T>(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<T>(x?: T): T;
+>f1 : <T>(x?: T) => T
+>x : T
+
+const res = f1();
+>res : unknown
+>f1() : unknown
+>f1 : <T>(x?: T) => T
+
+a = res;
+>a = res : unknown
+>a : { x?: number; y?: number; }
+>res : unknown
+
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<C>[P] | (TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : TInjectedProps[P])' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
           Type 'GetProps<C>[P]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
             Type 'GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-              Type 'Extract<keyof TInjectedProps, keyof GetProps<C>> extends keyof TInjectedProps ? TInjectedProps[Extract<keyof TInjectedProps, keyof GetProps<C>>] extends GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>] ? GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>] : TInjectedProps[Extract<keyof TInjectedProps, keyof GetProps<C>>] : GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-                Type 'GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>] | (TInjectedProps[Extract<keyof TInjectedProps, keyof GetProps<C>>] extends GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>] ? GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>] : TInjectedProps[Extract<keyof TInjectedProps, keyof GetProps<C>>])' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-                  Type 'GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-                    Type 'GetProps<C>[Extract<string, keyof GetProps<C>>] | GetProps<C>[Extract<number, keyof GetProps<C>>] | GetProps<C>[Extract<symbol, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-                      Type 'GetProps<C>[Extract<string, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-                        Type 'GetProps<C>[keyof GetProps<C> & string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-                          Type 'GetProps<C>[string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-                            Type '(Extract<string, keyof GetProps<C>> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : GetProps<C>[Extract<string, keyof GetProps<C>>]) | (Extract<number, keyof GetProps<C>> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract<number, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<number, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<number, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<number, keyof GetProps<C>>] : GetProps<C>[Extract<number, keyof GetProps<C>>]) | (Extract<symbol, keyof GetProps<C>> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract<symbol, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<symbol, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<symbol, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<symbol, keyof GetProps<C>>] : GetProps<C>[Extract<symbol, keyof GetProps<C>>])' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-                              Type 'Extract<string, keyof GetProps<C>> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : GetProps<C>[Extract<string, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-                                Type '(TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>]) | GetProps<C>[Extract<string, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-                                  Type 'TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-                                    Type 'GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] | TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-                                      Type 'GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-                                        Type 'GetProps<C>[string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-                                          Type 'keyof GetProps<C> & string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string] extends GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] ? GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string] : GetProps<C>[keyof GetProps<C> & string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-                                            Type '(TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string] extends GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] ? GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string]) | GetProps<C>[keyof GetProps<C> & string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-                                              Type 'TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string] extends GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] ? GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-                                                Type 'GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] | TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-                                                  Type 'GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-                                                    Type 'GetProps<C>[string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-                                                      Type 'string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & string] extends GetProps<C>[keyof TInjectedProps & string] ? GetProps<C>[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string] : GetProps<C>[string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+              Type 'GetProps<C>[P]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+                Type 'Extract<keyof TInjectedProps, keyof GetProps<C>> extends keyof TInjectedProps ? TInjectedProps[Extract<keyof TInjectedProps, keyof GetProps<C>>] extends GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>] ? GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>] : TInjectedProps[Extract<keyof TInjectedProps, keyof GetProps<C>>] : GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+                  Type 'GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>] | (TInjectedProps[Extract<keyof TInjectedProps, keyof GetProps<C>>] extends GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>] ? GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>] : TInjectedProps[Extract<keyof TInjectedProps, keyof GetProps<C>>])' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+                    Type 'GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+                      Type 'GetProps<C>[Extract<string, keyof GetProps<C>>] | GetProps<C>[Extract<number, keyof GetProps<C>>] | GetProps<C>[Extract<symbol, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+                        Type 'GetProps<C>[Extract<string, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+                          Type 'GetProps<C>[keyof GetProps<C> & string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+                            Type 'GetProps<C>[string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+                              Type 'GetProps<C>[keyof GetProps<C> & string]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+                                Type 'GetProps<C>[Extract<string, keyof GetProps<C>>]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+                                  Type 'GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+                                    Type '(Extract<string, keyof GetProps<C>> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : GetProps<C>[Extract<string, keyof GetProps<C>>]) | (Extract<number, keyof GetProps<C>> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract<number, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<number, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<number, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<number, keyof GetProps<C>>] : GetProps<C>[Extract<number, keyof GetProps<C>>]) | (Extract<symbol, keyof GetProps<C>> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract<symbol, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<symbol, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<symbol, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<symbol, keyof GetProps<C>>] : GetProps<C>[Extract<symbol, keyof GetProps<C>>])' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+                                      Type 'Extract<string, keyof GetProps<C>> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : GetProps<C>[Extract<string, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+                                        Type '(TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>]) | GetProps<C>[Extract<string, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+                                          Type 'TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+                                            Type 'GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] | TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+                                              Type 'GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+                                                Type 'GetProps<C>[string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+                                                  Type 'GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+                                                    Type 'TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+                                                      Type 'keyof GetProps<C> & string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string] extends GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] ? GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string] : GetProps<C>[keyof GetProps<C> & string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+                                                        Type '(TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string] extends GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] ? GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string]) | GetProps<C>[keyof GetProps<C> & string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+                                                          Type 'TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string] extends GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] ? GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+                                                            Type 'GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] | TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+                                                              Type 'GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+                                                                Type 'GetProps<C>[string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+                                                                  Type 'GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+                                                                    Type 'TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string] extends GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] ? GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+                                                                      Type 'string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & string] extends GetProps<C>[keyof TInjectedProps & string] ? GetProps<C>[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string] : GetProps<C>[string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+                                                                        Type 'keyof GetProps<C> & string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string] extends GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] ? GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string] : GetProps<C>[keyof GetProps<C> & string]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+                                                                          Type '(TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string] extends GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] ? GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string]) | GetProps<C>[keyof GetProps<C> & string]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+                                                                            Type 'TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string] extends GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] ? GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+                                                                              Type 'GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] | TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+                                                                                Type 'GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+                                                                                  Type 'GetProps<C>[string]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+                                                                                    Type 'Extract<string, keyof GetProps<C>> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : GetProps<C>[Extract<string, keyof GetProps<C>>]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+                                                                                      Type '(TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>]) | GetProps<C>[Extract<string, keyof GetProps<C>>]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+                                                                                        Type 'TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+                                                                                          Type 'GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] | TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+                                                                                            Type 'GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+                                                                                              Type 'GetProps<C>[string]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+                                                                                                Type 'Extract<keyof TInjectedProps, keyof GetProps<C>> extends keyof TInjectedProps ? TInjectedProps[Extract<keyof TInjectedProps, keyof GetProps<C>>] extends GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>] ? GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>] : TInjectedProps[Extract<keyof TInjectedProps, keyof GetProps<C>>] : GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+                                                                                                  Type 'GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>] | (TInjectedProps[Extract<keyof TInjectedProps, keyof GetProps<C>>] extends GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>] ? GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>] : TInjectedProps[Extract<keyof TInjectedProps, keyof GetProps<C>>])' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+                                                                                                    Type 'GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+                                                                                                      Type 'P extends keyof TInjectedProps ? TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : TInjectedProps[P] : GetProps<C>[P]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+                                                                                                        Type 'GetProps<C>[P] | (TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : TInjectedProps[P])' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+                                                                                                          Type 'GetProps<C>[P]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+                                                                                                            Type 'GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+                                                                                                              Type 'GetProps<C>[Extract<string, keyof GetProps<C>>] | GetProps<C>[Extract<number, keyof GetProps<C>>] | GetProps<C>[Extract<symbol, keyof GetProps<C>>]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+                                                                                                                Type 'GetProps<C>[Extract<string, keyof GetProps<C>>]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+                                                                                                                  Type 'GetProps<C>[keyof GetProps<C> & string]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+                                                                                                                    Type 'GetProps<C>[string]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
 
 
 ==== tests/cases/compiler/reactReduxLikeDeferredInferenceAllowsAssignment.ts (1 errors) ====
@@ -113,27 +144,58 @@ tests/cases/compiler/reactReduxLikeDeferredInferenceAllowsAssignment.ts(76,50):
 !!! error TS2344:         Type 'GetProps<C>[P] | (TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : TInjectedProps[P])' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
 !!! error TS2344:           Type 'GetProps<C>[P]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
 !!! error TS2344:             Type 'GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-!!! error TS2344:               Type 'Extract<keyof TInjectedProps, keyof GetProps<C>> extends keyof TInjectedProps ? TInjectedProps[Extract<keyof TInjectedProps, keyof GetProps<C>>] extends GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>] ? GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>] : TInjectedProps[Extract<keyof TInjectedProps, keyof GetProps<C>>] : GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-!!! error TS2344:                 Type 'GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>] | (TInjectedProps[Extract<keyof TInjectedProps, keyof GetProps<C>>] extends GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>] ? GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>] : TInjectedProps[Extract<keyof TInjectedProps, keyof GetProps<C>>])' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-!!! error TS2344:                   Type 'GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-!!! error TS2344:                     Type 'GetProps<C>[Extract<string, keyof GetProps<C>>] | GetProps<C>[Extract<number, keyof GetProps<C>>] | GetProps<C>[Extract<symbol, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-!!! error TS2344:                       Type 'GetProps<C>[Extract<string, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-!!! error TS2344:                         Type 'GetProps<C>[keyof GetProps<C> & string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-!!! error TS2344:                           Type 'GetProps<C>[string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-!!! error TS2344:                             Type '(Extract<string, keyof GetProps<C>> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : GetProps<C>[Extract<string, keyof GetProps<C>>]) | (Extract<number, keyof GetProps<C>> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract<number, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<number, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<number, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<number, keyof GetProps<C>>] : GetProps<C>[Extract<number, keyof GetProps<C>>]) | (Extract<symbol, keyof GetProps<C>> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract<symbol, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<symbol, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<symbol, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<symbol, keyof GetProps<C>>] : GetProps<C>[Extract<symbol, keyof GetProps<C>>])' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-!!! error TS2344:                               Type 'Extract<string, keyof GetProps<C>> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : GetProps<C>[Extract<string, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-!!! error TS2344:                                 Type '(TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>]) | GetProps<C>[Extract<string, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-!!! error TS2344:                                   Type 'TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-!!! error TS2344:                                     Type 'GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] | TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-!!! error TS2344:                                       Type 'GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-!!! error TS2344:                                         Type 'GetProps<C>[string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-!!! error TS2344:                                           Type 'keyof GetProps<C> & string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string] extends GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] ? GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string] : GetProps<C>[keyof GetProps<C> & string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-!!! error TS2344:                                             Type '(TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string] extends GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] ? GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string]) | GetProps<C>[keyof GetProps<C> & string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-!!! error TS2344:                                               Type 'TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string] extends GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] ? GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-!!! error TS2344:                                                 Type 'GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] | TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-!!! error TS2344:                                                   Type 'GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-!!! error TS2344:                                                     Type 'GetProps<C>[string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
-!!! error TS2344:                                                       Type 'string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & string] extends GetProps<C>[keyof TInjectedProps & string] ? GetProps<C>[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string] : GetProps<C>[string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+!!! error TS2344:               Type 'GetProps<C>[P]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+!!! error TS2344:                 Type 'Extract<keyof TInjectedProps, keyof GetProps<C>> extends keyof TInjectedProps ? TInjectedProps[Extract<keyof TInjectedProps, keyof GetProps<C>>] extends GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>] ? GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>] : TInjectedProps[Extract<keyof TInjectedProps, keyof GetProps<C>>] : GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+!!! error TS2344:                   Type 'GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>] | (TInjectedProps[Extract<keyof TInjectedProps, keyof GetProps<C>>] extends GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>] ? GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>] : TInjectedProps[Extract<keyof TInjectedProps, keyof GetProps<C>>])' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+!!! error TS2344:                     Type 'GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+!!! error TS2344:                       Type 'GetProps<C>[Extract<string, keyof GetProps<C>>] | GetProps<C>[Extract<number, keyof GetProps<C>>] | GetProps<C>[Extract<symbol, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+!!! error TS2344:                         Type 'GetProps<C>[Extract<string, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+!!! error TS2344:                           Type 'GetProps<C>[keyof GetProps<C> & string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+!!! error TS2344:                             Type 'GetProps<C>[string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+!!! error TS2344:                               Type 'GetProps<C>[keyof GetProps<C> & string]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+!!! error TS2344:                                 Type 'GetProps<C>[Extract<string, keyof GetProps<C>>]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+!!! error TS2344:                                   Type 'GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+!!! error TS2344:                                     Type '(Extract<string, keyof GetProps<C>> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : GetProps<C>[Extract<string, keyof GetProps<C>>]) | (Extract<number, keyof GetProps<C>> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract<number, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<number, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<number, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<number, keyof GetProps<C>>] : GetProps<C>[Extract<number, keyof GetProps<C>>]) | (Extract<symbol, keyof GetProps<C>> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract<symbol, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<symbol, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<symbol, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<symbol, keyof GetProps<C>>] : GetProps<C>[Extract<symbol, keyof GetProps<C>>])' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+!!! error TS2344:                                       Type 'Extract<string, keyof GetProps<C>> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : GetProps<C>[Extract<string, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+!!! error TS2344:                                         Type '(TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>]) | GetProps<C>[Extract<string, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+!!! error TS2344:                                           Type 'TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+!!! error TS2344:                                             Type 'GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] | TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+!!! error TS2344:                                               Type 'GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+!!! error TS2344:                                                 Type 'GetProps<C>[string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+!!! error TS2344:                                                   Type 'GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+!!! error TS2344:                                                     Type 'TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+!!! error TS2344:                                                       Type 'keyof GetProps<C> & string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string] extends GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] ? GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string] : GetProps<C>[keyof GetProps<C> & string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+!!! error TS2344:                                                         Type '(TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string] extends GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] ? GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string]) | GetProps<C>[keyof GetProps<C> & string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+!!! error TS2344:                                                           Type 'TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string] extends GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] ? GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+!!! error TS2344:                                                             Type 'GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] | TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+!!! error TS2344:                                                               Type 'GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+!!! error TS2344:                                                                 Type 'GetProps<C>[string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+!!! error TS2344:                                                                   Type 'GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+!!! error TS2344:                                                                     Type 'TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string] extends GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] ? GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+!!! error TS2344:                                                                       Type 'string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & string] extends GetProps<C>[keyof TInjectedProps & string] ? GetProps<C>[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string] : GetProps<C>[string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
+!!! error TS2344:                                                                         Type 'keyof GetProps<C> & string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string] extends GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] ? GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string] : GetProps<C>[keyof GetProps<C> & string]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+!!! error TS2344:                                                                           Type '(TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string] extends GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] ? GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string]) | GetProps<C>[keyof GetProps<C> & string]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+!!! error TS2344:                                                                             Type 'TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string] extends GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] ? GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+!!! error TS2344:                                                                               Type 'GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] | TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+!!! error TS2344:                                                                                 Type 'GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+!!! error TS2344:                                                                                   Type 'GetProps<C>[string]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+!!! error TS2344:                                                                                     Type 'Extract<string, keyof GetProps<C>> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : GetProps<C>[Extract<string, keyof GetProps<C>>]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+!!! error TS2344:                                                                                       Type '(TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>]) | GetProps<C>[Extract<string, keyof GetProps<C>>]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+!!! error TS2344:                                                                                         Type 'TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+!!! error TS2344:                                                                                           Type 'GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] | TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+!!! error TS2344:                                                                                             Type 'GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+!!! error TS2344:                                                                                               Type 'GetProps<C>[string]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+!!! error TS2344:                                                                                                 Type 'Extract<keyof TInjectedProps, keyof GetProps<C>> extends keyof TInjectedProps ? TInjectedProps[Extract<keyof TInjectedProps, keyof GetProps<C>>] extends GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>] ? GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>] : TInjectedProps[Extract<keyof TInjectedProps, keyof GetProps<C>>] : GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+!!! error TS2344:                                                                                                   Type 'GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>] | (TInjectedProps[Extract<keyof TInjectedProps, keyof GetProps<C>>] extends GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>] ? GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>] : TInjectedProps[Extract<keyof TInjectedProps, keyof GetProps<C>>])' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+!!! error TS2344:                                                                                                     Type 'GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+!!! error TS2344:                                                                                                       Type 'P extends keyof TInjectedProps ? TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : TInjectedProps[P] : GetProps<C>[P]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+!!! error TS2344:                                                                                                         Type 'GetProps<C>[P] | (TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : TInjectedProps[P])' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+!!! error TS2344:                                                                                                           Type 'GetProps<C>[P]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+!!! error TS2344:                                                                                                             Type 'GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+!!! error TS2344:                                                                                                               Type 'GetProps<C>[Extract<string, keyof GetProps<C>>] | GetProps<C>[Extract<number, keyof GetProps<C>>] | GetProps<C>[Extract<symbol, keyof GetProps<C>>]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+!!! error TS2344:                                                                                                                 Type 'GetProps<C>[Extract<string, keyof GetProps<C>>]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+!!! error TS2344:                                                                                                                   Type 'GetProps<C>[keyof GetProps<C> & string]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
+!!! error TS2344:                                                                                                                     Type 'GetProps<C>[string]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[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 }> {
 
 <MyComp2 class="" />;
 ><MyComp2 class="" /> : JSX.Element
->MyComp2 : (props: { className?: string; htmlFor?: string; }) => any
+>MyComp2 : (props: { className?: string; htmlFor?: string; }) => never
 >class : string
 
 <MyComp for="" />;
@@ -59,6 +59,6 @@ class MyComp extends React.Component<{ className?: string, htmlFor?: string }> {
 
 <MyComp2 for="" />;
 ><MyComp2 for="" /> : JSX.Element
->MyComp2 : (props: { className?: string; htmlFor?: string; }) => any
+>MyComp2 : (props: { className?: string; htmlFor?: string; }) => never
 >for : string
 
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 : <T, A extends any[], R>(this: (this: T, ...args: A) => R, thisArg: T, ...args: A) => R
+>f1 : (x: string) => void
+>call : <T, A extends any[], R>(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 : <T, A extends any[], R>(this: (this: T, ...args: A) => R, thisArg: T, ...args: A) => R
+>f1 : (x: string) => void
+>call : <T, A extends any[], R>(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 : <T, A extends any[], R>(this: (this: T, ...args: A) => R, thisArg: T, ...args: A) => R
+>f1 : (x: string) => void
+>call : <T, A extends any[], R>(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 : <T, A extends any[], R>(this: (this: T, ...args: A) => R, thisArg: T, ...args: A) => R
+>f1 : (x: string) => void
+>call : <T, A extends any[], R>(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 : <T, A extends any[], R>(this: (this: T, ...args: A) => R, thisArg: T, ...args: A) => R
+>f1 : (x: string) => void
+>call : <T, A extends any[], R>(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 : <T, A extends any[], R>(this: (this: T, ...args: A) => R, thisArg: T, ...args: A) => R
+>f1 : (x: string) => void
+>call : <T, A extends any[], R>(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 : <T, A extends any[], R>(this: (this: T, ...args: A) => R, thisArg: T, ...args: A) => R
+>f1 : (x: string) => void
+>call : <T, A extends any[], R>(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 : <T, A extends any[], R>(this: (this: T, ...args: A) => R, thisArg: T, ...args: A) => R
+>f1 : (x: string) => void
+>call : <T, A extends any[], R>(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 : <T, A extends any[], R>(this: (this: T, ...args: A) => R, thisArg: T, ...args: A) => R
+>f1 : (x: string) => void
+>call : <T, A extends any[], R>(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 : <T, A extends any[], R>(this: (this: T, ...args: A) => R, thisArg: T, ...args: A) => R
+>f1 : (x: string) => void
+>call : <T, A extends any[], R>(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/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/baselines/reference/strictPragma1.errors.txt b/tests/baselines/reference/strictPragma1.errors.txt
new file mode 100644
index 0000000000000..ab70991887ddd
--- /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 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 TS18048: 'c.member' 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 TS18048: 'c.member' 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 TS18048: 'c.member' 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 : <T, A extends any[], R>(this: (this: T, ...args: A) => R, thisArg: T, ...args: A) => R
+>f1 : (x: string) => void
+>call : <T, A extends any[], R>(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 : <T, A extends any[], R>(this: (this: T, ...args: A) => R, thisArg: T, ...args: A) => R
+>f1 : (x: string) => void
+>call : <T, A extends any[], R>(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 : <T, A extends any[], R>(this: (this: T, ...args: A) => R, thisArg: T, ...args: A) => R
+>f1 : (x: string) => void
+>call : <T, A extends any[], R>(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 : <T, A extends any[], R>(this: (this: T, ...args: A) => R, thisArg: T, ...args: A) => R
+>f1 : (x: string) => void
+>call : <T, A extends any[], R>(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..4579b0bd221b8
--- /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 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 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 TS18048: 'c.member' 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 TS18048: 'c.member' 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 TS18048: 'c.member' 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 TS18048: 'c.member' 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 : <T, A extends any[], R>(this: (this: T, ...args: A) => R, thisArg: T, ...args: A) => R
+>f1 : (x: string) => void
+>call : <T, A extends any[], R>(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 : <T, A extends any[], R>(this: (this: T, ...args: A) => R, thisArg: T, ...args: A) => R
+>f1 : (x: string) => void
+>call : <T, A extends any[], R>(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 : <T, A extends any[], R>(this: (this: T, ...args: A) => R, thisArg: T, ...args: A) => R
+>f1 : (x: string) => void
+>call : <T, A extends any[], R>(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 : <T, A extends any[], R>(this: (this: T, ...args: A) => R, thisArg: T, ...args: A) => R
+>f1 : (x: string) => void
+>call : <T, A extends any[], R>(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 : <T, A extends any[], R>(this: (this: T, ...args: A) => R, thisArg: T, ...args: A) => R
+>f1 : (x: string) => void
+>call : <T, A extends any[], R>(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 : <T, A extends any[], R>(this: (this: T, ...args: A) => R, thisArg: T, ...args: A) => R
+>f1 : (x: string) => void
+>call : <T, A extends any[], R>(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 : <T, A extends any[], R>(this: (this: T, ...args: A) => R, thisArg: T, ...args: A) => R
+>f1 : (x: string) => void
+>call : <T, A extends any[], R>(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 : <T, A extends any[], R>(this: (this: T, ...args: A) => R, thisArg: T, ...args: A) => R
+>f1 : (x: string) => void
+>call : <T, A extends any[], R>(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..ab5242ed8a143
--- /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 TS18048: 'c.member' 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 TS18048: 'c.member' 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..59fcb5cf8f680
--- /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 TS18048: 'c.member' 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 TS18048: 'c.member' 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 : <T, A extends any[], R>(this: (this: T, ...args: A) => R, thisArg: T, ...args: A) => R
+>f1 : (x: string) => void
+>call : <T, A extends any[], R>(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 : <T, A extends any[], R>(this: (this: T, ...args: A) => R, thisArg: T, ...args: A) => R
+>f1 : (x: string) => void
+>call : <T, A extends any[], R>(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..fd44cdd6714c4
--- /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 TS18048: 'c.member' 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 TS18048: 'c.member' 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 : <T, A extends any[], R>(this: (this: T, ...args: A) => R, thisArg: T, ...args: A) => R
+>f1 : (x: string) => void
+>call : <T, A extends any[], R>(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 : <T, A extends any[], R>(this: (this: T, ...args: A) => R, thisArg: T, ...args: A) => R
+>f1 : (x: string) => void
+>call : <T, A extends any[], R>(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/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 2cf43a8189e28..2ffa63839d952 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 0bdc2d356c5e3..008d5cb14ac3b 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 673a8e6669886..1e9a97ea4dad2 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 83e6548b002fb..db486e1b0a1bd 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 c87baf238012c..f96f4e1999b0c 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 82310b617cd3d..771059e06039e 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.
 
 
 
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/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/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
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<string, string>} 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
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
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<T>(obj: T): T {
+	if (!obj || typeof obj !== 'object') {
+		return obj;
+	}
+	var result = (Array.isArray(obj)) ? <any>[] : <any>{};
+	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
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
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<T>(x?: T): T;
+const res = f1();
+a = res;
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/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 {}
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/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 {}
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/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 {}
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/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
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;
+}
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;
     }
 }`,