From 411e7144a9d1ea35bbb4ac2632c37b711de1ecc1 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 10 Apr 2019 16:53:38 -1000 Subject: [PATCH] Add new nonInferrableType with ObjectFlags.NonInferrableType --- src/compiler/checker.ts | 32 ++++++++++++++------------------ src/compiler/types.ts | 6 +++--- 2 files changed, 17 insertions(+), 21 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 79480be336d..a1e21e010fb 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -404,10 +404,10 @@ namespace ts { const wildcardType = createIntrinsicType(TypeFlags.Any, "any"); const errorType = createIntrinsicType(TypeFlags.Any, "error"); const unknownType = createIntrinsicType(TypeFlags.Unknown, "unknown"); - const undefinedType = createNullableType(TypeFlags.Undefined, "undefined", 0); - const undefinedWideningType = strictNullChecks ? undefinedType : createNullableType(TypeFlags.Undefined, "undefined", ObjectFlags.ContainsWideningType); - const nullType = createNullableType(TypeFlags.Null, "null", 0); - const nullWideningType = strictNullChecks ? nullType : createNullableType(TypeFlags.Null, "null", ObjectFlags.ContainsWideningType); + const undefinedType = createIntrinsicType(TypeFlags.Undefined, "undefined"); + const undefinedWideningType = strictNullChecks ? undefinedType : createIntrinsicType(TypeFlags.Undefined, "undefined", ObjectFlags.ContainsWideningType); + const nullType = createIntrinsicType(TypeFlags.Null, "null"); + const nullWideningType = strictNullChecks ? nullType : createIntrinsicType(TypeFlags.Null, "null", ObjectFlags.ContainsWideningType); const stringType = createIntrinsicType(TypeFlags.String, "string"); const numberType = createIntrinsicType(TypeFlags.Number, "number"); const bigintType = createIntrinsicType(TypeFlags.BigInt, "bigint"); @@ -433,6 +433,7 @@ namespace ts { const voidType = createIntrinsicType(TypeFlags.Void, "void"); const neverType = createIntrinsicType(TypeFlags.Never, "never"); const silentNeverType = createIntrinsicType(TypeFlags.Never, "never"); + const nonInferrableType = createIntrinsicType(TypeFlags.Never, "never", ObjectFlags.NonInferrableType); const implicitNeverType = createIntrinsicType(TypeFlags.Never, "never"); const nonPrimitiveType = createIntrinsicType(TypeFlags.NonPrimitive, "object"); const stringNumberSymbolType = getUnionType([stringType, numberType, esSymbolType]); @@ -453,7 +454,7 @@ namespace ts { const anyFunctionType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined); // The anyFunctionType contains the anyFunctionType by definition. The flag is further propagated // in getPropagatingFlagsOfTypes, and it is checked in inferFromTypes. - anyFunctionType.objectFlags |= ObjectFlags.ContainsAnyFunctionType; + anyFunctionType.objectFlags |= ObjectFlags.NonInferrableType; const noConstraintType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined); const circularConstraintType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined); @@ -2797,14 +2798,9 @@ namespace ts { return result; } - function createIntrinsicType(kind: TypeFlags, intrinsicName: string): IntrinsicType { + function createIntrinsicType(kind: TypeFlags, intrinsicName: string, objectFlags: ObjectFlags = 0): IntrinsicType { const type = createType(kind); type.intrinsicName = intrinsicName; - return type; - } - - function createNullableType(kind: TypeFlags, intrinsicName: string, objectFlags: ObjectFlags): NullableType { - const type = createIntrinsicType(kind, intrinsicName); type.objectFlags = objectFlags; return type; } @@ -14513,7 +14509,7 @@ namespace ts { // If any property contains context sensitive functions that have been skipped, the source type // is incomplete and we can't infer a meaningful input type. for (const prop of properties) { - if (getObjectFlags(getTypeOfSymbol(prop)) & ObjectFlags.ContainsAnyFunctionType) { + if (getObjectFlags(getTypeOfSymbol(prop)) & ObjectFlags.NonInferrableType) { return undefined; } } @@ -14670,7 +14666,7 @@ namespace ts { // not contain anyFunctionType when we come back to this argument for its second round // of inference. Also, we exclude inferences for silentNeverType (which is used as a wildcard // when constructing types from type parameters that had no inference candidates). - if (getObjectFlags(source) & ObjectFlags.ContainsAnyFunctionType || source === silentNeverType || (priority & InferencePriority.ReturnType && (source === autoType || source === autoArrayType))) { + if (getObjectFlags(source) & ObjectFlags.NonInferrableType || source === silentNeverType || (priority & InferencePriority.ReturnType && (source === autoType || source === autoArrayType))) { return; } const inference = getInferenceInfoForType(target); @@ -14991,7 +14987,7 @@ namespace ts { const sourceLen = sourceSignatures.length; const targetLen = targetSignatures.length; const len = sourceLen < targetLen ? sourceLen : targetLen; - const skipParameters = !!(getObjectFlags(source) & ObjectFlags.ContainsAnyFunctionType); + const skipParameters = !!(getObjectFlags(source) & ObjectFlags.NonInferrableType); for (let i = 0; i < len; i++) { inferFromSignature(getBaseSignature(sourceSignatures[sourceLen - len + i]), getBaseSignature(targetSignatures[targetLen - len + i]), skipParameters); } @@ -21120,7 +21116,7 @@ namespace ts { // returns a function type, we choose to defer processing. This narrowly permits function composition // operators to flow inferences through return types, but otherwise processes calls right away. We // use the resolvingSignature singleton to indicate that we deferred processing. This result will be - // propagated out and eventually turned into silentNeverType (a type that is assignable to anything and + // propagated out and eventually turned into nonInferrableType (a type that is assignable to anything and // from which we never make inferences). if (checkMode & CheckMode.SkipGenericFunctions && !node.typeArguments && callSignatures.some(isGenericFunctionReturningFunction)) { skippedGenericFunction(node, checkMode); @@ -21603,8 +21599,8 @@ namespace ts { const signature = getResolvedSignature(node, /*candidatesOutArray*/ undefined, checkMode); if (signature === resolvingSignature) { // CheckMode.SkipGenericFunctions is enabled and this is a call to a generic function that - // returns a function type. We defer checking and return anyFunctionType. - return silentNeverType; + // returns a function type. We defer checking and return nonInferrableType. + return nonInferrableType; } if (node.expression.kind === SyntaxKind.SuperKeyword) { @@ -22411,7 +22407,7 @@ namespace ts { const returnType = getReturnTypeFromBody(node, checkMode); const returnOnlySignature = createSignature(undefined, undefined, undefined, emptyArray, returnType, /*resolvedTypePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false); const returnOnlyType = createAnonymousType(node.symbol, emptySymbols, [returnOnlySignature], emptyArray, undefined, undefined); - returnOnlyType.objectFlags |= ObjectFlags.ContainsAnyFunctionType; + returnOnlyType.objectFlags |= ObjectFlags.NonInferrableType; return links.contextFreeType = returnOnlyType; } return anyFunctionType; diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 55492081050..97e6c3dcf56 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3944,7 +3944,7 @@ namespace ts { Instantiable = InstantiableNonPrimitive | InstantiablePrimitive, StructuredOrInstantiable = StructuredType | Instantiable, /* @internal */ - ObjectFlagsType = Nullable | Object | Union | Intersection, + ObjectFlagsType = Nullable | Never | Object | Union | Intersection, // 'Narrowable' types are types where narrowing actually narrows. // This *should* be every type other than null, undefined, void, and never Narrowable = Any | Unknown | StructuredOrInstantiable | StringLike | NumberLike | BigIntLike | BooleanLike | ESSymbol | UniqueESSymbol | NonPrimitive, @@ -4064,12 +4064,12 @@ namespace ts { /* @internal */ ContainsObjectLiteral = 1 << 18, // Type is or contains object literal type /* @internal */ - ContainsAnyFunctionType = 1 << 19, // Type is or contains the anyFunctionType + NonInferrableType = 1 << 19, // Type is or contains anyFunctionType or silentNeverType ClassOrInterface = Class | Interface, /* @internal */ RequiresWidening = ContainsWideningType | ContainsObjectLiteral, /* @internal */ - PropagatingFlags = ContainsWideningType | ContainsObjectLiteral | ContainsAnyFunctionType + PropagatingFlags = ContainsWideningType | ContainsObjectLiteral | NonInferrableType } /* @internal */