Add --strictAny mode where 'any' is assignable only to 'any' and '{}'

This commit is contained in:
Anders Hejlsberg
2018-05-22 09:14:19 -07:00
parent f52c4af448
commit a4c16168c8
5 changed files with 19 additions and 5 deletions
+6 -4
View File
@@ -65,6 +65,7 @@ namespace ts {
const strictNullChecks = getStrictOptionValue(compilerOptions, "strictNullChecks");
const strictFunctionTypes = getStrictOptionValue(compilerOptions, "strictFunctionTypes");
const strictPropertyInitialization = getStrictOptionValue(compilerOptions, "strictPropertyInitialization");
const strictAny = getStrictOptionValue(compilerOptions, "strictAny");
const noImplicitAny = getStrictOptionValue(compilerOptions, "noImplicitAny");
const noImplicitThis = getStrictOptionValue(compilerOptions, "noImplicitThis");
const keyofStringsOnly = !!compilerOptions.keyofStringsOnly;
@@ -7464,7 +7465,8 @@ namespace ts {
if (signature.hasRestParameter) {
const type = getTypeOfSymbol(lastOrUndefined(signature.parameters));
if (getObjectFlags(type) & ObjectFlags.Reference && (<TypeReference>type).target === globalArrayType) {
return (<TypeReference>type).typeArguments[0];
const t = (<TypeReference>type).typeArguments[0];
return strictAny && t.flags & TypeFlags.Any ? unknownType : t;
}
}
return anyType;
@@ -10248,7 +10250,7 @@ namespace ts {
if (s & TypeFlags.Object && t & TypeFlags.NonPrimitive) return true;
if (s & TypeFlags.UniqueESSymbol || t & TypeFlags.UniqueESSymbol) return false;
if (relation === assignableRelation || relation === definitelyAssignableRelation || relation === comparableRelation) {
if (s & TypeFlags.Any) return true;
if (s & TypeFlags.Any && (!strictAny || source === unknownType || t & TypeFlags.Object && isEmptyObjectType(target))) return true;
// Type number or any numeric literal type is assignable to any numeric enum type or any
// numeric enum literal type. This rule exists for backwards compatibility reasons because
// bit-flag enum types sometimes look like literal enum types with numeric literal values.
@@ -19935,7 +19937,7 @@ namespace ts {
if (!(isTypeComparableTo(leftType, stringType) || isTypeAssignableToKind(leftType, TypeFlags.NumberLike | TypeFlags.ESSymbolLike))) {
error(left, Diagnostics.The_left_hand_side_of_an_in_expression_must_be_of_type_any_string_number_or_symbol);
}
if (!isTypeAssignableToKind(rightType, TypeFlags.NonPrimitive | TypeFlags.InstantiableNonPrimitive)) {
if (!(rightType.flags & TypeFlags.Any || isTypeAssignableToKind(rightType, TypeFlags.NonPrimitive | TypeFlags.InstantiableNonPrimitive))) {
error(right, Diagnostics.The_right_hand_side_of_an_in_expression_must_be_of_type_any_an_object_type_or_a_type_parameter);
}
return booleanType;
@@ -23410,7 +23412,7 @@ namespace ts {
// unknownType is returned i.e. if node.expression is identifier whose name cannot be resolved
// in this case error about missing name is already reported - do not report extra one
if (rightType === neverType || !isTypeAssignableToKind(rightType, TypeFlags.NonPrimitive | TypeFlags.InstantiableNonPrimitive)) {
if (rightType === neverType || !(rightType.flags & TypeFlags.Any || isTypeAssignableToKind(rightType, TypeFlags.NonPrimitive | TypeFlags.InstantiableNonPrimitive))) {
error(node.expression, Diagnostics.The_right_hand_side_of_a_for_in_statement_must_be_of_type_any_an_object_type_or_a_type_parameter_but_here_has_type_0, typeToString(rightType));
}
+7
View File
@@ -290,6 +290,13 @@ namespace ts {
category: Diagnostics.Strict_Type_Checking_Options,
description: Diagnostics.Raise_error_on_expressions_and_declarations_with_an_implied_any_type,
},
{
name: "strictAny",
type: "boolean",
showInSimplifiedHelpView: true,
category: Diagnostics.Strict_Type_Checking_Options,
description: Diagnostics.Enable_strict_checking_of_any_type
},
{
name: "strictNullChecks",
type: "boolean",
+1 -1
View File
@@ -2008,7 +2008,7 @@ namespace ts {
return !!(compilerOptions.declaration || compilerOptions.composite);
}
export type StrictOptionName = "noImplicitAny" | "noImplicitThis" | "strictNullChecks" | "strictFunctionTypes" | "strictPropertyInitialization" | "alwaysStrict";
export type StrictOptionName = "noImplicitAny" | "noImplicitThis" | "strictNullChecks" | "strictFunctionTypes" | "strictPropertyInitialization" | "alwaysStrict" | "strictAny";
export function getStrictOptionValue(compilerOptions: CompilerOptions, flag: StrictOptionName): boolean {
return compilerOptions[flag] === undefined ? compilerOptions.strict : compilerOptions[flag];
+4
View File
@@ -3561,6 +3561,10 @@
"code": 6199,
"reportsUnnecessary": true
},
"Enable strict checking of 'any' type.": {
"category": "Message",
"code": 6200
},
"Projects to reference": {
"category": "Message",
+1
View File
@@ -4341,6 +4341,7 @@ namespace ts {
sourceMap?: boolean;
sourceRoot?: string;
strict?: boolean;
strictAny?: boolean; // Always combine with strict property
strictFunctionTypes?: boolean; // Always combine with strict property
strictNullChecks?: boolean; // Always combine with strict property
strictPropertyInitialization?: boolean; // Always combine with strict property