Add non-widening forms of null and undefined
This commit is contained in:
parent
166f399d17
commit
2517238269
2 changed files with 23 additions and 20 deletions
|
@ -110,16 +110,17 @@ namespace ts {
|
||||||
const unknownSymbol = createSymbol(SymbolFlags.Property | SymbolFlags.Transient, "unknown");
|
const unknownSymbol = createSymbol(SymbolFlags.Property | SymbolFlags.Transient, "unknown");
|
||||||
const resolvingSymbol = createSymbol(SymbolFlags.Transient, "__resolving__");
|
const resolvingSymbol = createSymbol(SymbolFlags.Transient, "__resolving__");
|
||||||
|
|
||||||
const nullableWideningFlags = strictNullChecks ? 0 : TypeFlags.ContainsUndefinedOrNull;
|
|
||||||
const anyType = createIntrinsicType(TypeFlags.Any, "any");
|
const anyType = createIntrinsicType(TypeFlags.Any, "any");
|
||||||
const stringType = createIntrinsicType(TypeFlags.String, "string");
|
const stringType = createIntrinsicType(TypeFlags.String, "string");
|
||||||
const numberType = createIntrinsicType(TypeFlags.Number, "number");
|
const numberType = createIntrinsicType(TypeFlags.Number, "number");
|
||||||
const booleanType = createIntrinsicType(TypeFlags.Boolean, "boolean");
|
const booleanType = createIntrinsicType(TypeFlags.Boolean, "boolean");
|
||||||
const esSymbolType = createIntrinsicType(TypeFlags.ESSymbol, "symbol");
|
const esSymbolType = createIntrinsicType(TypeFlags.ESSymbol, "symbol");
|
||||||
const voidType = createIntrinsicType(TypeFlags.Void, "void");
|
const voidType = createIntrinsicType(TypeFlags.Void, "void");
|
||||||
const undefinedType = createIntrinsicType(TypeFlags.Undefined | nullableWideningFlags, "undefined");
|
const undefinedType = createIntrinsicType(TypeFlags.Undefined, "undefined");
|
||||||
const nullType = createIntrinsicType(TypeFlags.Null | nullableWideningFlags, "null");
|
const undefinedWideningType = strictNullChecks ? undefinedType : createIntrinsicType(TypeFlags.Undefined | TypeFlags.ContainsWideningType, "undefined");
|
||||||
const emptyArrayElementType = createIntrinsicType(TypeFlags.Undefined | TypeFlags.ContainsUndefinedOrNull, "undefined");
|
const nullType = createIntrinsicType(TypeFlags.Null, "null");
|
||||||
|
const nullWideningType = strictNullChecks ? nullType : createIntrinsicType(TypeFlags.Null | TypeFlags.ContainsWideningType, "null");
|
||||||
|
const emptyArrayElementType = createIntrinsicType(TypeFlags.Undefined | TypeFlags.ContainsWideningType, "undefined");
|
||||||
const unknownType = createIntrinsicType(TypeFlags.Any, "unknown");
|
const unknownType = createIntrinsicType(TypeFlags.Any, "unknown");
|
||||||
const neverType = createIntrinsicType(TypeFlags.Never, "never");
|
const neverType = createIntrinsicType(TypeFlags.Never, "never");
|
||||||
|
|
||||||
|
@ -3405,7 +3406,7 @@ namespace ts {
|
||||||
error(type.symbol.valueDeclaration, Diagnostics._0_is_referenced_directly_or_indirectly_in_its_own_base_expression, symbolToString(type.symbol));
|
error(type.symbol.valueDeclaration, Diagnostics._0_is_referenced_directly_or_indirectly_in_its_own_base_expression, symbolToString(type.symbol));
|
||||||
return type.resolvedBaseConstructorType = unknownType;
|
return type.resolvedBaseConstructorType = unknownType;
|
||||||
}
|
}
|
||||||
if (baseConstructorType !== unknownType && baseConstructorType !== nullType && !isConstructorType(baseConstructorType)) {
|
if (baseConstructorType !== unknownType && baseConstructorType !== nullWideningType && !isConstructorType(baseConstructorType)) {
|
||||||
error(baseTypeNode.expression, Diagnostics.Type_0_is_not_a_constructor_function_type, typeToString(baseConstructorType));
|
error(baseTypeNode.expression, Diagnostics.Type_0_is_not_a_constructor_function_type, typeToString(baseConstructorType));
|
||||||
return type.resolvedBaseConstructorType = unknownType;
|
return type.resolvedBaseConstructorType = unknownType;
|
||||||
}
|
}
|
||||||
|
@ -5011,6 +5012,7 @@ namespace ts {
|
||||||
containsAny?: boolean;
|
containsAny?: boolean;
|
||||||
containsUndefined?: boolean;
|
containsUndefined?: boolean;
|
||||||
containsNull?: boolean;
|
containsNull?: boolean;
|
||||||
|
containsNonWideningType?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
function addTypeToSet(typeSet: TypeSet, type: Type, typeSetKind: TypeFlags) {
|
function addTypeToSet(typeSet: TypeSet, type: Type, typeSetKind: TypeFlags) {
|
||||||
|
@ -5021,6 +5023,7 @@ namespace ts {
|
||||||
if (type.flags & TypeFlags.Any) typeSet.containsAny = true;
|
if (type.flags & TypeFlags.Any) typeSet.containsAny = true;
|
||||||
if (type.flags & TypeFlags.Undefined) typeSet.containsUndefined = true;
|
if (type.flags & TypeFlags.Undefined) typeSet.containsUndefined = true;
|
||||||
if (type.flags & TypeFlags.Null) typeSet.containsNull = true;
|
if (type.flags & TypeFlags.Null) typeSet.containsNull = true;
|
||||||
|
if (!(type.flags & TypeFlags.ContainsWideningType)) typeSet.containsNonWideningType = true;
|
||||||
}
|
}
|
||||||
else if (type !== neverType && !contains(typeSet, type)) {
|
else if (type !== neverType && !contains(typeSet, type)) {
|
||||||
typeSet.push(type);
|
typeSet.push(type);
|
||||||
|
@ -5081,8 +5084,8 @@ namespace ts {
|
||||||
removeSubtypes(typeSet);
|
removeSubtypes(typeSet);
|
||||||
}
|
}
|
||||||
if (typeSet.length === 0) {
|
if (typeSet.length === 0) {
|
||||||
return typeSet.containsNull ? nullType :
|
return typeSet.containsNull ? typeSet.containsNonWideningType ? nullType : nullWideningType :
|
||||||
typeSet.containsUndefined ? undefinedType :
|
typeSet.containsUndefined ? typeSet.containsNonWideningType ? undefinedType : undefinedWideningType :
|
||||||
neverType;
|
neverType;
|
||||||
}
|
}
|
||||||
else if (typeSet.length === 1) {
|
else if (typeSet.length === 1) {
|
||||||
|
@ -5882,7 +5885,7 @@ namespace ts {
|
||||||
if (!(target.flags & TypeFlags.Never)) {
|
if (!(target.flags & TypeFlags.Never)) {
|
||||||
if (target.flags & TypeFlags.Any || source.flags & TypeFlags.Never) return Ternary.True;
|
if (target.flags & TypeFlags.Any || source.flags & TypeFlags.Never) return Ternary.True;
|
||||||
if (source.flags & TypeFlags.Undefined) {
|
if (source.flags & TypeFlags.Undefined) {
|
||||||
if (!strictNullChecks || target.flags & (TypeFlags.Undefined | TypeFlags.Void) || source === emptyArrayElementType) return Ternary.True;
|
if (!strictNullChecks || target.flags & (TypeFlags.Undefined | TypeFlags.Void)) return Ternary.True;
|
||||||
}
|
}
|
||||||
if (source.flags & TypeFlags.Null) {
|
if (source.flags & TypeFlags.Null) {
|
||||||
if (!strictNullChecks || target.flags & TypeFlags.Null) return Ternary.True;
|
if (!strictNullChecks || target.flags & TypeFlags.Null) return Ternary.True;
|
||||||
|
@ -6972,7 +6975,7 @@ namespace ts {
|
||||||
if (type.flags & TypeFlags.ObjectLiteral) {
|
if (type.flags & TypeFlags.ObjectLiteral) {
|
||||||
for (const p of getPropertiesOfObjectType(type)) {
|
for (const p of getPropertiesOfObjectType(type)) {
|
||||||
const t = getTypeOfSymbol(p);
|
const t = getTypeOfSymbol(p);
|
||||||
if (t.flags & TypeFlags.ContainsUndefinedOrNull) {
|
if (t.flags & TypeFlags.ContainsWideningType) {
|
||||||
if (!reportWideningErrorsInType(t)) {
|
if (!reportWideningErrorsInType(t)) {
|
||||||
error(p.valueDeclaration, Diagnostics.Object_literal_s_property_0_implicitly_has_an_1_type, p.name, typeToString(getWidenedType(t)));
|
error(p.valueDeclaration, Diagnostics.Object_literal_s_property_0_implicitly_has_an_1_type, p.name, typeToString(getWidenedType(t)));
|
||||||
}
|
}
|
||||||
|
@ -7019,7 +7022,7 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
function reportErrorsFromWidening(declaration: Declaration, type: Type) {
|
function reportErrorsFromWidening(declaration: Declaration, type: Type) {
|
||||||
if (produceDiagnostics && compilerOptions.noImplicitAny && type.flags & TypeFlags.ContainsUndefinedOrNull) {
|
if (produceDiagnostics && compilerOptions.noImplicitAny && type.flags & TypeFlags.ContainsWideningType) {
|
||||||
// Report implicit any error within type if possible, otherwise report error on declaration
|
// Report implicit any error within type if possible, otherwise report error on declaration
|
||||||
if (!reportWideningErrorsInType(type)) {
|
if (!reportWideningErrorsInType(type)) {
|
||||||
reportImplicitAnyError(declaration, type);
|
reportImplicitAnyError(declaration, type);
|
||||||
|
@ -8311,7 +8314,7 @@ namespace ts {
|
||||||
const classInstanceType = <InterfaceType>getDeclaredTypeOfSymbol(classSymbol);
|
const classInstanceType = <InterfaceType>getDeclaredTypeOfSymbol(classSymbol);
|
||||||
const baseConstructorType = getBaseConstructorTypeOfClass(classInstanceType);
|
const baseConstructorType = getBaseConstructorTypeOfClass(classInstanceType);
|
||||||
|
|
||||||
return baseConstructorType === nullType;
|
return baseConstructorType === nullWideningType;
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkThisExpression(node: Node): Type {
|
function checkThisExpression(node: Node): Type {
|
||||||
|
@ -9202,7 +9205,7 @@ namespace ts {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return createArrayType(elementTypes.length ? getUnionType(elementTypes) : emptyArrayElementType);
|
return createArrayType(elementTypes.length ? getUnionType(elementTypes) : strictNullChecks ? neverType : undefinedWideningType);
|
||||||
}
|
}
|
||||||
|
|
||||||
function isNumericName(name: DeclarationName): boolean {
|
function isNumericName(name: DeclarationName): boolean {
|
||||||
|
@ -12002,7 +12005,7 @@ namespace ts {
|
||||||
|
|
||||||
function checkVoidExpression(node: VoidExpression): Type {
|
function checkVoidExpression(node: VoidExpression): Type {
|
||||||
checkExpression(node.expression);
|
checkExpression(node.expression);
|
||||||
return undefinedType;
|
return undefinedWideningType;
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkAwaitExpression(node: AwaitExpression): Type {
|
function checkAwaitExpression(node: AwaitExpression): Type {
|
||||||
|
@ -12409,7 +12412,7 @@ namespace ts {
|
||||||
case SyntaxKind.InKeyword:
|
case SyntaxKind.InKeyword:
|
||||||
return checkInExpression(left, right, leftType, rightType);
|
return checkInExpression(left, right, leftType, rightType);
|
||||||
case SyntaxKind.AmpersandAmpersandToken:
|
case SyntaxKind.AmpersandAmpersandToken:
|
||||||
return addNullableKind(rightType, getNullableKind(leftType));
|
return strictNullChecks ? addNullableKind(rightType, getNullableKind(leftType)) : rightType;
|
||||||
case SyntaxKind.BarBarToken:
|
case SyntaxKind.BarBarToken:
|
||||||
return getUnionType([getNonNullableType(leftType), rightType]);
|
return getUnionType([getNonNullableType(leftType), rightType]);
|
||||||
case SyntaxKind.EqualsToken:
|
case SyntaxKind.EqualsToken:
|
||||||
|
@ -12676,7 +12679,7 @@ namespace ts {
|
||||||
case SyntaxKind.SuperKeyword:
|
case SyntaxKind.SuperKeyword:
|
||||||
return checkSuperExpression(node);
|
return checkSuperExpression(node);
|
||||||
case SyntaxKind.NullKeyword:
|
case SyntaxKind.NullKeyword:
|
||||||
return nullType;
|
return nullWideningType;
|
||||||
case SyntaxKind.TrueKeyword:
|
case SyntaxKind.TrueKeyword:
|
||||||
case SyntaxKind.FalseKeyword:
|
case SyntaxKind.FalseKeyword:
|
||||||
return booleanType;
|
return booleanType;
|
||||||
|
@ -12734,7 +12737,7 @@ namespace ts {
|
||||||
case SyntaxKind.SpreadElementExpression:
|
case SyntaxKind.SpreadElementExpression:
|
||||||
return checkSpreadElementExpression(<SpreadElementExpression>node, contextualMapper);
|
return checkSpreadElementExpression(<SpreadElementExpression>node, contextualMapper);
|
||||||
case SyntaxKind.OmittedExpression:
|
case SyntaxKind.OmittedExpression:
|
||||||
return undefinedType;
|
return undefinedWideningType;
|
||||||
case SyntaxKind.YieldExpression:
|
case SyntaxKind.YieldExpression:
|
||||||
return checkYieldExpression(<YieldExpression>node);
|
return checkYieldExpression(<YieldExpression>node);
|
||||||
case SyntaxKind.JsxExpression:
|
case SyntaxKind.JsxExpression:
|
||||||
|
@ -17648,7 +17651,7 @@ namespace ts {
|
||||||
// Setup global builtins
|
// Setup global builtins
|
||||||
addToSymbolTable(globals, builtinGlobals, Diagnostics.Declaration_name_conflicts_with_built_in_global_identifier_0);
|
addToSymbolTable(globals, builtinGlobals, Diagnostics.Declaration_name_conflicts_with_built_in_global_identifier_0);
|
||||||
|
|
||||||
getSymbolLinks(undefinedSymbol).type = undefinedType;
|
getSymbolLinks(undefinedSymbol).type = undefinedWideningType;
|
||||||
getSymbolLinks(argumentsSymbol).type = getGlobalType("IArguments");
|
getSymbolLinks(argumentsSymbol).type = getGlobalType("IArguments");
|
||||||
getSymbolLinks(unknownSymbol).type = unknownType;
|
getSymbolLinks(unknownSymbol).type = unknownType;
|
||||||
|
|
||||||
|
|
|
@ -2197,7 +2197,7 @@ namespace ts {
|
||||||
/* @internal */
|
/* @internal */
|
||||||
FreshObjectLiteral = 0x00100000, // Fresh object literal type
|
FreshObjectLiteral = 0x00100000, // Fresh object literal type
|
||||||
/* @internal */
|
/* @internal */
|
||||||
ContainsUndefinedOrNull = 0x00200000, // Type is or contains undefined or null type
|
ContainsWideningType = 0x00200000, // Type is or contains undefined or null widening type
|
||||||
/* @internal */
|
/* @internal */
|
||||||
ContainsObjectLiteral = 0x00400000, // Type is or contains object literal type
|
ContainsObjectLiteral = 0x00400000, // Type is or contains object literal type
|
||||||
/* @internal */
|
/* @internal */
|
||||||
|
@ -2220,9 +2220,9 @@ namespace ts {
|
||||||
StructuredType = ObjectType | Union | Intersection,
|
StructuredType = ObjectType | Union | Intersection,
|
||||||
Narrowable = Any | ObjectType | Union | TypeParameter,
|
Narrowable = Any | ObjectType | Union | TypeParameter,
|
||||||
/* @internal */
|
/* @internal */
|
||||||
RequiresWidening = ContainsUndefinedOrNull | ContainsObjectLiteral,
|
RequiresWidening = ContainsWideningType | ContainsObjectLiteral,
|
||||||
/* @internal */
|
/* @internal */
|
||||||
PropagatingFlags = ContainsUndefinedOrNull | ContainsObjectLiteral | ContainsAnyFunctionType
|
PropagatingFlags = ContainsWideningType | ContainsObjectLiteral | ContainsAnyFunctionType
|
||||||
}
|
}
|
||||||
|
|
||||||
export type DestructuringPattern = BindingPattern | ObjectLiteralExpression | ArrayLiteralExpression;
|
export type DestructuringPattern = BindingPattern | ObjectLiteralExpression | ArrayLiteralExpression;
|
||||||
|
|
Loading…
Reference in a new issue