diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 7e8a99343bd1e..ef00a3aecde3c 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -182,7 +182,7 @@ namespace ts { return bindSourceFile; function bindInStrictMode(file: SourceFile, opts: CompilerOptions): boolean { - if (opts.alwaysStrict && !isDeclarationFile(file)) { + if ((opts.alwaysStrict === undefined ? opts.strict : opts.alwaysStrict) && !isDeclarationFile(file)) { // bind in strict mode source files with alwaysStrict option return true; } diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index a4c0acc405d5e..1af021e152ac5 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -56,7 +56,9 @@ namespace ts { const modulekind = getEmitModuleKind(compilerOptions); const noUnusedIdentifiers = !!compilerOptions.noUnusedLocals || !!compilerOptions.noUnusedParameters; const allowSyntheticDefaultImports = typeof compilerOptions.allowSyntheticDefaultImports !== "undefined" ? compilerOptions.allowSyntheticDefaultImports : modulekind === ModuleKind.System; - const strictNullChecks = compilerOptions.strictNullChecks; + const strictNullChecks = compilerOptions.strictNullChecks === undefined ? compilerOptions.strict : compilerOptions.strictNullChecks; + const noImplicitAny = compilerOptions.noImplicitAny === undefined ? compilerOptions.strict : compilerOptions.noImplicitAny; + const noImplicitThis = compilerOptions.noImplicitThis === undefined ? compilerOptions.strict : compilerOptions.noImplicitThis; const emitResolver = createResolver(); @@ -1564,7 +1566,7 @@ namespace ts { error(errorNode, diag, moduleReference, resolvedModule.resolvedFileName); return undefined; } - else if (compilerOptions.noImplicitAny && moduleNotFoundError) { + else if (noImplicitAny && moduleNotFoundError) { error(errorNode, Diagnostics.Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type, moduleReference, @@ -3407,7 +3409,7 @@ namespace ts { return addOptionality(declaredType, /*optional*/ declaration.questionToken && includeOptionality); } - if ((compilerOptions.noImplicitAny || declaration.flags & NodeFlags.JavaScriptFile) && + if ((noImplicitAny || declaration.flags & NodeFlags.JavaScriptFile) && declaration.kind === SyntaxKind.VariableDeclaration && !isBindingPattern(declaration.name) && !(getCombinedModifierFlags(declaration) & ModifierFlags.Export) && !isInAmbientContext(declaration)) { // If --noImplicitAny is on or the declaration is in a Javascript file, @@ -3509,7 +3511,7 @@ namespace ts { if (isBindingPattern(element.name)) { return getTypeFromBindingPattern(element.name, includePatternInType, reportErrors); } - if (reportErrors && compilerOptions.noImplicitAny && !declarationBelongsToPrivateAmbientMember(element)) { + if (reportErrors && noImplicitAny && !declarationBelongsToPrivateAmbientMember(element)) { reportImplicitAnyError(element, anyType); } return anyType; @@ -3607,7 +3609,7 @@ namespace ts { type = declaration.dotDotDotToken ? anyArrayType : anyType; // Report implicit any errors unless this is a private property within an ambient declaration - if (reportErrors && compilerOptions.noImplicitAny) { + if (reportErrors && noImplicitAny) { if (!declarationBelongsToPrivateAmbientMember(declaration)) { reportImplicitAnyError(declaration, type); } @@ -3726,7 +3728,7 @@ namespace ts { } // Otherwise, fall back to 'any'. else { - if (compilerOptions.noImplicitAny) { + if (noImplicitAny) { if (setter) { error(setter, Diagnostics.Property_0_implicitly_has_type_any_because_its_set_accessor_lacks_a_parameter_type_annotation, symbolToString(symbol)); } @@ -3741,7 +3743,7 @@ namespace ts { } if (!popTypeResolution()) { type = anyType; - if (compilerOptions.noImplicitAny) { + if (noImplicitAny) { const getter = getDeclarationOfKind(symbol, SyntaxKind.GetAccessor); 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)); } @@ -3824,7 +3826,7 @@ namespace ts { return unknownType; } // Otherwise variable has initializer that circularly references the variable itself - if (compilerOptions.noImplicitAny) { + if (noImplicitAny) { 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)); } @@ -5585,7 +5587,7 @@ namespace ts { } if (!popTypeResolution()) { type = anyType; - if (compilerOptions.noImplicitAny) { + if (noImplicitAny) { const declaration = signature.declaration; if (declaration.name) { error(declaration.name, 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, declarationNameToString(declaration.name)); @@ -6540,7 +6542,7 @@ namespace ts { return indexInfo.type; } if (accessExpression && !isConstEnumObjectType(objectType)) { - if (compilerOptions.noImplicitAny && !compilerOptions.suppressImplicitAnyIndexErrors) { + if (noImplicitAny && !compilerOptions.suppressImplicitAnyIndexErrors) { if (getIndexTypeOfType(objectType, IndexKind.Number)) { error(accessExpression.argumentExpression, Diagnostics.Element_implicitly_has_an_any_type_because_index_expression_is_not_of_type_number); } @@ -9126,7 +9128,7 @@ namespace ts { } function reportErrorsFromWidening(declaration: Declaration, type: Type) { - if (produceDiagnostics && compilerOptions.noImplicitAny && type.flags & TypeFlags.ContainsWideningType) { + if (produceDiagnostics && noImplicitAny && type.flags & TypeFlags.ContainsWideningType) { // Report implicit any error within type if possible, otherwise report error on declaration if (!reportWideningErrorsInType(type)) { reportImplicitAnyError(declaration, type); @@ -11007,7 +11009,7 @@ namespace ts { // control flow based type does include undefined. if (type === autoType || type === autoArrayType) { if (flowType === autoType || flowType === autoArrayType) { - if (compilerOptions.noImplicitAny) { + if (noImplicitAny) { error(declaration.name, 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)); } @@ -11277,7 +11279,7 @@ namespace ts { } } - if (compilerOptions.noImplicitThis) { + if (noImplicitThis) { // With noImplicitThis, functions may not reference 'this' if it has type 'any' error(node, Diagnostics.this_implicitly_has_type_any_because_it_does_not_have_a_type_annotation); } @@ -12531,7 +12533,7 @@ namespace ts { return links.resolvedSymbol = unknownSymbol; } else { - if (compilerOptions.noImplicitAny) { + if (noImplicitAny) { error(node, Diagnostics.JSX_element_implicitly_has_type_any_because_no_interface_JSX_0_exists, JsxNames.IntrinsicElements); } return links.resolvedSymbol = unknownSymbol; @@ -12919,7 +12921,7 @@ namespace ts { } if (jsxElementType === undefined) { - if (compilerOptions.noImplicitAny) { + if (noImplicitAny) { error(errorNode, Diagnostics.JSX_element_implicitly_has_type_any_because_the_global_type_JSX_Element_does_not_exist); } } @@ -14742,7 +14744,7 @@ namespace ts { if (funcSymbol && funcSymbol.members && funcSymbol.flags & SymbolFlags.Function) { return getInferredClassType(funcSymbol); } - else if (compilerOptions.noImplicitAny) { + else if (noImplicitAny) { error(node, Diagnostics.new_expression_whose_target_lacks_a_construct_signature_implicitly_has_an_any_type); } return anyType; @@ -15002,7 +15004,7 @@ namespace ts { const iterableIteratorAny = functionFlags & FunctionFlags.Async ? createAsyncIterableIteratorType(anyType) // AsyncGenerator function : createIterableIteratorType(anyType); // Generator function - if (compilerOptions.noImplicitAny) { + if (noImplicitAny) { error(func.asteriskToken, Diagnostics.Generator_implicitly_has_type_0_because_it_does_not_yield_any_values_Consider_supplying_a_return_type, typeToString(iterableIteratorAny)); } @@ -16546,7 +16548,7 @@ namespace ts { if (produceDiagnostics) { checkCollisionWithArgumentsInGeneratedCode(node); - if (compilerOptions.noImplicitAny && !node.type) { + if (noImplicitAny && !node.type) { switch (node.kind) { case SyntaxKind.ConstructSignature: error(node, Diagnostics.Construct_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type); @@ -17858,7 +17860,7 @@ namespace ts { if (produceDiagnostics && !node.type) { // Report an implicit any error if there is no body, no explicit return type, and node is not a private method // in an ambient context - if (compilerOptions.noImplicitAny && nodeIsMissing(node.body) && !isPrivateWithinAmbient(node)) { + if (noImplicitAny && nodeIsMissing(node.body) && !isPrivateWithinAmbient(node)) { reportImplicitAnyError(node, anyType); } diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 6b4e9ff590efc..dc69297289116 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -467,6 +467,11 @@ namespace ts { type: "boolean", description: Diagnostics.Parse_in_strict_mode_and_emit_use_strict_for_each_source_file }, + { + name: "strict", + type: "boolean", + description: Diagnostics.Enable_all_strict_type_checks + }, { // A list of plugins to load in the language service name: "plugins", @@ -520,7 +525,7 @@ namespace ts { export const defaultInitCompilerOptions: CompilerOptions = { module: ModuleKind.CommonJS, target: ScriptTarget.ES5, - noImplicitAny: false, + strict: true, sourceMap: false, }; diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 75aa5d25f7236..318f06ceeaa3f 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -3045,6 +3045,10 @@ "category": "Message", "code": 6149 }, + "Enable all strict type checks.": { + "category": "Message", + "code": 6150 + }, "Variable '{0}' implicitly has an '{1}' type.": { "category": "Error", "code": 7005 diff --git a/src/compiler/program.ts b/src/compiler/program.ts index eb9f0f0e0a1a2..d9ddf486e0d1d 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -1630,7 +1630,7 @@ namespace ts { programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_with_option_1, "lib", "noLib")); } - if (options.noImplicitUseStrict && options.alwaysStrict) { + if (options.noImplicitUseStrict && (options.alwaysStrict === undefined ? options.strict : options.alwaysStrict)) { programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_with_option_1, "noImplicitUseStrict", "alwaysStrict")); } diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index e712393b2f0cf..b3696c31153c0 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -472,7 +472,8 @@ namespace ts { } function visitSourceFile(node: SourceFile) { - const alwaysStrict = compilerOptions.alwaysStrict && !(isExternalModule(node) && moduleKind === ModuleKind.ES2015); + const alwaysStrict = (compilerOptions.alwaysStrict === undefined ? compilerOptions.strict : compilerOptions.alwaysStrict) && + !(isExternalModule(node) && moduleKind === ModuleKind.ES2015); return updateSourceFileNode( node, visitLexicalEnvironment(node.statements, sourceElementVisitor, context, /*start*/ 0, alwaysStrict)); diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 53d8411860968..e50e7e9e1d0c4 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3308,7 +3308,7 @@ allowSyntheticDefaultImports?: boolean; allowUnreachableCode?: boolean; allowUnusedLabels?: boolean; - alwaysStrict?: boolean; + alwaysStrict?: boolean; // Always combine with strict property baseUrl?: string; charset?: string; /* @internal */ configFilePath?: string; @@ -3344,9 +3344,9 @@ noEmitOnError?: boolean; noErrorTruncation?: boolean; noFallthroughCasesInSwitch?: boolean; - noImplicitAny?: boolean; + noImplicitAny?: boolean; // Always combine with strict property noImplicitReturns?: boolean; - noImplicitThis?: boolean; + noImplicitThis?: boolean; // Always combine with strict property noUnusedLocals?: boolean; noUnusedParameters?: boolean; noImplicitUseStrict?: boolean; @@ -3369,7 +3369,8 @@ skipDefaultLibCheck?: boolean; sourceMap?: boolean; sourceRoot?: string; - strictNullChecks?: boolean; + strict?: boolean; + strictNullChecks?: boolean; // Always combine with strict property /* @internal */ stripInternal?: boolean; suppressExcessPropertyErrors?: boolean; suppressImplicitAnyIndexErrors?: boolean; diff --git a/tests/baselines/reference/tsConfig/Default initialized TSConfig/tsconfig.json b/tests/baselines/reference/tsConfig/Default initialized TSConfig/tsconfig.json index ea891967cb510..a4c1c4490956f 100644 --- a/tests/baselines/reference/tsConfig/Default initialized TSConfig/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Default initialized TSConfig/tsconfig.json @@ -2,7 +2,7 @@ "compilerOptions": { "module": "commonjs", "target": "es5", - "noImplicitAny": false, + "strict": true, "sourceMap": false } } \ No newline at end of file diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with boolean value compiler options/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with boolean value compiler options/tsconfig.json index abe135b4f1687..23061360bc2c4 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with boolean value compiler options/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with boolean value compiler options/tsconfig.json @@ -2,7 +2,7 @@ "compilerOptions": { "module": "commonjs", "target": "es5", - "noImplicitAny": false, + "strict": true, "sourceMap": false, "noUnusedLocals": true } diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with enum value compiler options/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with enum value compiler options/tsconfig.json index e28b66c8c2bf9..16535c7960a36 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with enum value compiler options/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with enum value compiler options/tsconfig.json @@ -2,7 +2,7 @@ "compilerOptions": { "module": "commonjs", "target": "es5", - "noImplicitAny": false, + "strict": true, "sourceMap": false, "jsx": "react" } diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with files options/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with files options/tsconfig.json index 5273b3cb7c8ed..133de87dc1d30 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with files options/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with files options/tsconfig.json @@ -2,7 +2,7 @@ "compilerOptions": { "module": "commonjs", "target": "es5", - "noImplicitAny": false, + "strict": true, "sourceMap": false }, "files": [ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option value/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option value/tsconfig.json index fa9cb6cad8411..2ab8d9412ea11 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option value/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option value/tsconfig.json @@ -2,7 +2,7 @@ "compilerOptions": { "module": "commonjs", "target": "es5", - "noImplicitAny": false, + "strict": true, "sourceMap": false, "lib": [ "es5", diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option/tsconfig.json index ea891967cb510..a4c1c4490956f 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option/tsconfig.json @@ -2,7 +2,7 @@ "compilerOptions": { "module": "commonjs", "target": "es5", - "noImplicitAny": false, + "strict": true, "sourceMap": false } } \ No newline at end of file diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options with enum value/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options with enum value/tsconfig.json index 3ff8208d9d64c..5716902e02ce9 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options with enum value/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options with enum value/tsconfig.json @@ -2,7 +2,7 @@ "compilerOptions": { "module": "commonjs", "target": "es5", - "noImplicitAny": false, + "strict": true, "sourceMap": false, "lib": [ "es5", diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options/tsconfig.json index b1740ac4c12c3..4fc209f9b9ca9 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options/tsconfig.json @@ -2,7 +2,7 @@ "compilerOptions": { "module": "commonjs", "target": "es5", - "noImplicitAny": false, + "strict": true, "sourceMap": false, "types": [ "jquery",