Merge pull request #29923 from Microsoft/freeTypeFlags

Free up some type flags
This commit is contained in:
Anders Hejlsberg 2019-02-15 09:10:21 -08:00 committed by GitHub
commit 691df0e4b5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 131 additions and 118 deletions

View File

@ -390,10 +390,10 @@ namespace ts {
const wildcardType = createIntrinsicType(TypeFlags.Any, "any");
const errorType = createIntrinsicType(TypeFlags.Any, "error");
const unknownType = createIntrinsicType(TypeFlags.Unknown, "unknown");
const undefinedType = createIntrinsicType(TypeFlags.Undefined, "undefined");
const undefinedWideningType = strictNullChecks ? undefinedType : createIntrinsicType(TypeFlags.Undefined | TypeFlags.ContainsWideningType, "undefined");
const nullType = createIntrinsicType(TypeFlags.Null, "null");
const nullWideningType = strictNullChecks ? nullType : createIntrinsicType(TypeFlags.Null | TypeFlags.ContainsWideningType, "null");
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 stringType = createIntrinsicType(TypeFlags.String, "string");
const numberType = createIntrinsicType(TypeFlags.Number, "number");
const bigintType = createIntrinsicType(TypeFlags.BigInt, "bigint");
@ -439,7 +439,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.flags |= TypeFlags.ContainsAnyFunctionType;
anyFunctionType.objectFlags |= ObjectFlags.ContainsAnyFunctionType;
const noConstraintType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined);
const circularConstraintType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined);
@ -2753,6 +2753,12 @@ namespace ts {
return type;
}
function createNullableType(kind: TypeFlags, intrinsicName: string, objectFlags: ObjectFlags): NullableType {
const type = createIntrinsicType(kind, intrinsicName);
type.objectFlags = objectFlags;
return type;
}
function createBooleanType(trueFalseTypes: ReadonlyArray<Type>): IntrinsicType & UnionType {
const type = <IntrinsicType & UnionType>getUnionType(trueFalseTypes);
type.flags |= TypeFlags.Boolean;
@ -5140,7 +5146,7 @@ namespace ts {
definedInConstructor = true;
}
}
const sourceTypes = some(constructorTypes, t => !!(t.flags & ~(TypeFlags.Nullable | TypeFlags.ContainsWideningType))) ? constructorTypes : types; // TODO: GH#18217
const sourceTypes = some(constructorTypes, t => !!(t.flags & ~TypeFlags.Nullable)) ? constructorTypes : types; // TODO: GH#18217
type = getUnionType(sourceTypes!, UnionReduction.Subtype);
}
const widened = getWidenedType(addOptionality(type, definedInMethod && !definedInConstructor));
@ -5305,7 +5311,7 @@ namespace ts {
function getTypeFromObjectBindingPattern(pattern: ObjectBindingPattern, includePatternInType: boolean, reportErrors: boolean): Type {
const members = createSymbolTable();
let stringIndexInfo: IndexInfo | undefined;
let objectFlags = ObjectFlags.ObjectLiteral;
let objectFlags = ObjectFlags.ObjectLiteral | ObjectFlags.ContainsObjectLiteral;
forEach(pattern.elements, e => {
const name = e.propertyName || <Identifier>e.name;
if (e.dotDotDotToken) {
@ -5327,7 +5333,6 @@ namespace ts {
members.set(symbol.escapedName, symbol);
});
const result = createAnonymousType(undefined, members, emptyArray, emptyArray, stringIndexInfo, undefined);
result.flags |= TypeFlags.ContainsObjectLiteral;
result.objectFlags |= objectFlags;
if (includePatternInType) {
result.pattern = pattern;
@ -8552,14 +8557,14 @@ namespace ts {
// It is only necessary to do so if a constituent type might be the undefined type, the null type, the type
// of an object literal or the anyFunctionType. This is because there are operations in the type checker
// that care about the presence of such types at arbitrary depth in a containing type.
function getPropagatingFlagsOfTypes(types: ReadonlyArray<Type>, excludeKinds: TypeFlags): TypeFlags {
let result: TypeFlags = 0;
function getPropagatingFlagsOfTypes(types: ReadonlyArray<Type>, excludeKinds: TypeFlags): ObjectFlags {
let result: ObjectFlags = 0;
for (const type of types) {
if (!(type.flags & excludeKinds)) {
result |= type.flags;
result |= getObjectFlags(type);
}
}
return result & TypeFlags.PropagatingFlags;
return result & ObjectFlags.PropagatingFlags;
}
function createTypeReference(target: GenericType, typeArguments: ReadonlyArray<Type> | undefined): TypeReference {
@ -8568,7 +8573,7 @@ namespace ts {
if (!type) {
type = <TypeReference>createObjectType(ObjectFlags.Reference, target.symbol);
target.instantiations.set(id, type);
type.flags |= typeArguments ? getPropagatingFlagsOfTypes(typeArguments, /*excludeKinds*/ 0) : 0;
type.objectFlags |= typeArguments ? getPropagatingFlagsOfTypes(typeArguments, /*excludeKinds*/ 0) : 0;
type.target = target;
type.typeArguments = typeArguments;
}
@ -9247,10 +9252,11 @@ namespace ts {
// intersections of unit types into 'never' upon construction, but deferring the reduction makes it
// easier to reason about their origin.
if (!(flags & TypeFlags.Never || flags & TypeFlags.Intersection && isEmptyIntersectionType(<IntersectionType>type))) {
includes |= flags & ~TypeFlags.ConstructionFlags;
if (type === wildcardType) includes |= TypeFlags.Wildcard;
includes |= flags & TypeFlags.IncludesMask;
if (flags & TypeFlags.StructuredOrInstantiable) includes |= TypeFlags.IncludesStructuredOrInstantiable;
if (type === wildcardType) includes |= TypeFlags.IncludesWildcard;
if (!strictNullChecks && flags & TypeFlags.Nullable) {
if (!(flags & TypeFlags.ContainsWideningType)) includes |= TypeFlags.NonWideningType;
if (!(getObjectFlags(type) & ObjectFlags.ContainsWideningType)) includes |= TypeFlags.IncludesNonWideningType;
}
else {
const len = typeSet.length;
@ -9361,27 +9367,27 @@ namespace ts {
const includes = addTypesToUnion(typeSet, 0, types);
if (unionReduction !== UnionReduction.None) {
if (includes & TypeFlags.AnyOrUnknown) {
return includes & TypeFlags.Any ? includes & TypeFlags.Wildcard ? wildcardType : anyType : unknownType;
return includes & TypeFlags.Any ? includes & TypeFlags.IncludesWildcard ? wildcardType : anyType : unknownType;
}
switch (unionReduction) {
case UnionReduction.Literal:
if (includes & TypeFlags.StringOrNumberLiteralOrUnique | TypeFlags.BooleanLiteral) {
if (includes & (TypeFlags.Literal | TypeFlags.UniqueESSymbol)) {
removeRedundantLiteralTypes(typeSet, includes);
}
break;
case UnionReduction.Subtype:
if (!removeSubtypes(typeSet, !(includes & TypeFlags.StructuredOrInstantiable))) {
if (!removeSubtypes(typeSet, !(includes & TypeFlags.IncludesStructuredOrInstantiable))) {
return errorType;
}
break;
}
if (typeSet.length === 0) {
return includes & TypeFlags.Null ? includes & TypeFlags.NonWideningType ? nullType : nullWideningType :
includes & TypeFlags.Undefined ? includes & TypeFlags.NonWideningType ? undefinedType : undefinedWideningType :
return includes & TypeFlags.Null ? includes & TypeFlags.IncludesNonWideningType ? nullType : nullWideningType :
includes & TypeFlags.Undefined ? includes & TypeFlags.IncludesNonWideningType ? undefinedType : undefinedWideningType :
neverType;
}
}
return getUnionTypeFromSortedList(typeSet, !(includes & TypeFlags.NotPrimitiveUnion), aliasSymbol, aliasTypeArguments);
return getUnionTypeFromSortedList(typeSet, includes & TypeFlags.NotPrimitiveUnion ? 0 : ObjectFlags.PrimitiveUnion, aliasSymbol, aliasTypeArguments);
}
function getUnionTypePredicate(signatures: ReadonlyArray<Signature>): TypePredicate | undefined {
@ -9421,7 +9427,7 @@ namespace ts {
}
// This function assumes the constituent type list is sorted and deduplicated.
function getUnionTypeFromSortedList(types: Type[], primitiveTypesOnly: boolean, aliasSymbol?: Symbol, aliasTypeArguments?: ReadonlyArray<Type>): Type {
function getUnionTypeFromSortedList(types: Type[], objectFlags: ObjectFlags, aliasSymbol?: Symbol, aliasTypeArguments?: ReadonlyArray<Type>): Type {
if (types.length === 0) {
return neverType;
}
@ -9431,11 +9437,10 @@ namespace ts {
const id = getTypeListId(types);
let type = unionTypes.get(id);
if (!type) {
const propagatedFlags = getPropagatingFlagsOfTypes(types, /*excludeKinds*/ TypeFlags.Nullable);
type = <UnionType>createType(TypeFlags.Union | propagatedFlags);
type = <UnionType>createType(TypeFlags.Union);
unionTypes.set(id, type);
type.objectFlags = objectFlags | getPropagatingFlagsOfTypes(types, /*excludeKinds*/ TypeFlags.Nullable);
type.types = types;
type.primitiveTypesOnly = primitiveTypesOnly;
/*
Note: This is the alias symbol (or lack thereof) that we see when we first encounter this union type.
For aliases of identical unions, eg `type T = A | B; type U = A | B`, the symbol of the first alias encountered is the aliasSymbol.
@ -9464,15 +9469,15 @@ namespace ts {
return addTypesToIntersection(typeSet, includes, (<IntersectionType>type).types);
}
if (isEmptyAnonymousObjectType(type)) {
if (!(includes & TypeFlags.EmptyObject)) {
includes |= TypeFlags.EmptyObject;
if (!(includes & TypeFlags.IncludesEmptyObject)) {
includes |= TypeFlags.IncludesEmptyObject;
typeSet.push(type);
}
}
else {
includes |= flags & ~TypeFlags.ConstructionFlags;
includes |= flags & TypeFlags.IncludesMask;
if (flags & TypeFlags.AnyOrUnknown) {
if (type === wildcardType) includes |= TypeFlags.Wildcard;
if (type === wildcardType) includes |= TypeFlags.IncludesWildcard;
}
else if ((strictNullChecks || !(flags & TypeFlags.Nullable)) && !contains(typeSet, type)) {
typeSet.push(type);
@ -9530,7 +9535,7 @@ namespace ts {
// other unions and return true. Otherwise, do nothing and return false.
function intersectUnionsOfPrimitiveTypes(types: Type[]) {
let unionTypes: UnionType[] | undefined;
const index = findIndex(types, t => !!(t.flags & TypeFlags.Union) && (<UnionType>t).primitiveTypesOnly);
const index = findIndex(types, t => !!(getObjectFlags(t) & ObjectFlags.PrimitiveUnion));
if (index < 0) {
return false;
}
@ -9539,7 +9544,7 @@ namespace ts {
// the unionTypes array.
while (i < types.length) {
const t = types[i];
if (t.flags & TypeFlags.Union && (<UnionType>t).primitiveTypesOnly) {
if (getObjectFlags(t) & ObjectFlags.PrimitiveUnion) {
(unionTypes || (unionTypes = [<UnionType>types[index]])).push(<UnionType>t);
orderedRemoveItemAt(types, i);
}
@ -9566,7 +9571,7 @@ namespace ts {
}
}
// Finally replace the first union with the result
types[index] = getUnionTypeFromSortedList(result, /*primitiveTypesOnly*/ true);
types[index] = getUnionTypeFromSortedList(result, ObjectFlags.PrimitiveUnion);
return true;
}
@ -9587,7 +9592,7 @@ namespace ts {
return neverType;
}
if (includes & TypeFlags.Any) {
return includes & TypeFlags.Wildcard ? wildcardType : anyType;
return includes & TypeFlags.IncludesWildcard ? wildcardType : anyType;
}
if (!strictNullChecks && includes & TypeFlags.Nullable) {
return includes & TypeFlags.Undefined ? undefinedType : nullType;
@ -9598,7 +9603,7 @@ namespace ts {
includes & TypeFlags.ESSymbol && includes & TypeFlags.UniqueESSymbol) {
removeRedundantPrimitiveTypes(typeSet, includes);
}
if (includes & TypeFlags.EmptyObject && includes & TypeFlags.Object) {
if (includes & TypeFlags.IncludesEmptyObject && includes & TypeFlags.Object) {
orderedRemoveItemAt(typeSet, findIndex(typeSet, isEmptyAnonymousObjectType));
}
if (typeSet.length === 0) {
@ -9624,9 +9629,9 @@ namespace ts {
const id = getTypeListId(typeSet);
let type = intersectionTypes.get(id);
if (!type) {
const propagatedFlags = getPropagatingFlagsOfTypes(typeSet, /*excludeKinds*/ TypeFlags.Nullable);
type = <IntersectionType>createType(TypeFlags.Intersection | propagatedFlags);
type = <IntersectionType>createType(TypeFlags.Intersection);
intersectionTypes.set(id, type);
type.objectFlags = getPropagatingFlagsOfTypes(typeSet, /*excludeKinds*/ TypeFlags.Nullable);
type.types = typeSet;
type.aliasSymbol = aliasSymbol; // See comment in `getUnionTypeFromSortedList`.
type.aliasTypeArguments = aliasTypeArguments;
@ -10285,7 +10290,7 @@ namespace ts {
* this function should be called in a left folding style, with left = previous result of getSpreadType
* and right = the new element to be spread.
*/
function getSpreadType(left: Type, right: Type, symbol: Symbol | undefined, typeFlags: TypeFlags, objectFlags: ObjectFlags, readonly: boolean): Type {
function getSpreadType(left: Type, right: Type, symbol: Symbol | undefined, objectFlags: ObjectFlags, readonly: boolean): Type {
if (left.flags & TypeFlags.Any || right.flags & TypeFlags.Any) {
return anyType;
}
@ -10299,10 +10304,10 @@ namespace ts {
return left;
}
if (left.flags & TypeFlags.Union) {
return mapType(left, t => getSpreadType(t, right, symbol, typeFlags, objectFlags, readonly));
return mapType(left, t => getSpreadType(t, right, symbol, objectFlags, readonly));
}
if (right.flags & TypeFlags.Union) {
return mapType(right, t => getSpreadType(left, t, symbol, typeFlags, objectFlags, readonly));
return mapType(right, t => getSpreadType(left, t, symbol, objectFlags, readonly));
}
if (right.flags & (TypeFlags.BooleanLike | TypeFlags.NumberLike | TypeFlags.BigIntLike | TypeFlags.StringLike | TypeFlags.EnumLike | TypeFlags.NonPrimitive | TypeFlags.Index)) {
return left;
@ -10319,7 +10324,7 @@ namespace ts {
const types = (<IntersectionType>left).types;
const lastLeft = types[types.length - 1];
if (isNonGenericObjectType(lastLeft) && isNonGenericObjectType(right)) {
return getIntersectionType(concatenate(types.slice(0, types.length - 1), [getSpreadType(lastLeft, right, symbol, typeFlags, objectFlags, readonly)]));
return getIntersectionType(concatenate(types.slice(0, types.length - 1), [getSpreadType(lastLeft, right, symbol, objectFlags, readonly)]));
}
}
return getIntersectionType([left, right]);
@ -10379,8 +10384,7 @@ namespace ts {
emptyArray,
getIndexInfoWithReadonly(stringIndexInfo, readonly),
getIndexInfoWithReadonly(numberIndexInfo, readonly));
spread.flags |= TypeFlags.ContainsObjectLiteral | typeFlags;
spread.objectFlags |= ObjectFlags.ObjectLiteral | ObjectFlags.ContainsSpread | objectFlags;
spread.objectFlags |= ObjectFlags.ObjectLiteral | ObjectFlags.ContainsObjectLiteral | ObjectFlags.ContainsSpread | objectFlags;
return spread;
}
@ -13865,7 +13869,7 @@ namespace ts {
resolved.stringIndexInfo,
resolved.numberIndexInfo);
regularNew.flags = resolved.flags;
regularNew.objectFlags |= ObjectFlags.ObjectLiteral | (getObjectFlags(resolved) & ObjectFlags.JSLiteral);
regularNew.objectFlags |= resolved.objectFlags & ~ObjectFlags.FreshLiteral;
(<FreshObjectLiteralType>type).regularType = regularNew;
return regularNew;
}
@ -13956,7 +13960,7 @@ namespace ts {
}
function getWidenedTypeWithContext(type: Type, context: WideningContext | undefined): Type {
if (type.flags & TypeFlags.RequiresWidening) {
if (getObjectFlags(type) & ObjectFlags.RequiresWidening) {
if (type.flags & TypeFlags.Nullable) {
return anyType;
}
@ -13994,7 +13998,7 @@ namespace ts {
*/
function reportWideningErrorsInType(type: Type): boolean {
let errorReported = false;
if (type.flags & TypeFlags.ContainsWideningType) {
if (getObjectFlags(type) & ObjectFlags.ContainsWideningType) {
if (type.flags & TypeFlags.Union) {
if (some((<UnionType>type).types, isEmptyObjectType)) {
errorReported = true;
@ -14017,7 +14021,7 @@ namespace ts {
if (isObjectLiteralType(type)) {
for (const p of getPropertiesOfObjectType(type)) {
const t = getTypeOfSymbol(p);
if (t.flags & TypeFlags.ContainsWideningType) {
if (getObjectFlags(t) & ObjectFlags.ContainsWideningType) {
if (!reportWideningErrorsInType(t)) {
error(p.valueDeclaration, Diagnostics.Object_literal_s_property_0_implicitly_has_an_1_type, symbolToString(p), typeToString(getWidenedType(t)));
}
@ -14092,7 +14096,7 @@ namespace ts {
}
function reportErrorsFromWidening(declaration: Declaration, type: Type) {
if (produceDiagnostics && noImplicitAny && type.flags & TypeFlags.ContainsWideningType) {
if (produceDiagnostics && noImplicitAny && getObjectFlags(type) & ObjectFlags.ContainsWideningType) {
// Report implicit any error within type if possible, otherwise report error on declaration
if (!reportWideningErrorsInType(type)) {
reportImplicitAny(declaration, type);
@ -14237,7 +14241,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 (getTypeOfSymbol(prop).flags & TypeFlags.ContainsAnyFunctionType) {
if (getObjectFlags(getTypeOfSymbol(prop)) & ObjectFlags.ContainsAnyFunctionType) {
return undefined;
}
}
@ -14395,7 +14399,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 (source.flags & TypeFlags.ContainsAnyFunctionType || source === silentNeverType || (priority & InferencePriority.ReturnType && (source === autoType || source === autoArrayType))) {
if (getObjectFlags(source) & ObjectFlags.ContainsAnyFunctionType || source === silentNeverType || (priority & InferencePriority.ReturnType && (source === autoType || source === autoArrayType))) {
return;
}
const inference = getInferenceInfoForType(target);
@ -14698,7 +14702,7 @@ namespace ts {
const sourceLen = sourceSignatures.length;
const targetLen = targetSignatures.length;
const len = sourceLen < targetLen ? sourceLen : targetLen;
const skipParameters = !!(source.flags & TypeFlags.ContainsAnyFunctionType);
const skipParameters = !!(getObjectFlags(source) & ObjectFlags.ContainsAnyFunctionType);
for (let i = 0; i < len; i++) {
inferFromSignature(getBaseSignature(sourceSignatures[sourceLen - len + i]), getBaseSignature(targetSignatures[targetLen - len + i]), skipParameters);
}
@ -15456,7 +15460,7 @@ namespace ts {
if (type.flags & TypeFlags.Union) {
const types = (<UnionType>type).types;
const filtered = filter(types, f);
return filtered === types ? type : getUnionTypeFromSortedList(filtered, (<UnionType>type).primitiveTypesOnly);
return filtered === types ? type : getUnionTypeFromSortedList(filtered, (<UnionType>type).objectFlags);
}
return f(type) ? type : neverType;
}
@ -18362,7 +18366,6 @@ namespace ts {
let propertiesTable: SymbolTable;
let propertiesArray: Symbol[] = [];
let spread: Type = emptyObjectType;
let propagatedFlags: TypeFlags = 0;
const contextualType = getApparentTypeOfContextualType(node);
const contextualTypeHasPattern = contextualType && contextualType.pattern &&
@ -18372,7 +18375,7 @@ namespace ts {
const isInJavascript = isInJSFile(node) && !isInJsonFile(node);
const enumTag = getJSDocEnumTag(node);
const isJSObjectLiteral = !contextualType && isInJavascript && !enumTag;
let typeFlags: TypeFlags = 0;
let objectFlags: ObjectFlags = freshObjectLiteralFlag;
let patternWithComputedProperties = false;
let hasComputedStringProperty = false;
let hasComputedNumberProperty = false;
@ -18400,7 +18403,7 @@ namespace ts {
checkTypeAssignableTo(type, getTypeFromTypeNode(enumTag.typeExpression), memberDecl);
}
}
typeFlags |= type.flags;
objectFlags |= getObjectFlags(type) & ObjectFlags.PropagatingFlags;
const nameType = computedNameType && isTypeUsableAsPropertyName(computedNameType) ? computedNameType : undefined;
const prop = nameType ?
createSymbol(SymbolFlags.Property | member.flags, getPropertyNameFromType(nameType), checkFlags | CheckFlags.Late) :
@ -18448,19 +18451,18 @@ namespace ts {
checkExternalEmitHelpers(memberDecl, ExternalEmitHelpers.Assign);
}
if (propertiesArray.length > 0) {
spread = getSpreadType(spread, createObjectLiteralType(), node.symbol, propagatedFlags, ObjectFlags.FreshLiteral, inConstContext);
spread = getSpreadType(spread, createObjectLiteralType(), node.symbol, objectFlags, inConstContext);
propertiesArray = [];
propertiesTable = createSymbolTable();
hasComputedStringProperty = false;
hasComputedNumberProperty = false;
typeFlags = 0;
}
const type = checkExpression(memberDecl.expression);
if (!isValidSpreadType(type)) {
error(memberDecl, Diagnostics.Spread_types_may_only_be_created_from_object_types);
return errorType;
}
spread = getSpreadType(spread, type, node.symbol, propagatedFlags, ObjectFlags.FreshLiteral, inConstContext);
spread = getSpreadType(spread, type, node.symbol, objectFlags, inConstContext);
offset = i + 1;
continue;
}
@ -18510,7 +18512,7 @@ namespace ts {
if (spread !== emptyObjectType) {
if (propertiesArray.length > 0) {
spread = getSpreadType(spread, createObjectLiteralType(), node.symbol, propagatedFlags, ObjectFlags.FreshLiteral, inConstContext);
spread = getSpreadType(spread, createObjectLiteralType(), node.symbol, objectFlags, inConstContext);
}
return spread;
}
@ -18521,8 +18523,7 @@ namespace ts {
const stringIndexInfo = hasComputedStringProperty ? getObjectLiteralIndexInfo(node, offset, propertiesArray, IndexKind.String) : undefined;
const numberIndexInfo = hasComputedNumberProperty ? getObjectLiteralIndexInfo(node, offset, propertiesArray, IndexKind.Number) : undefined;
const result = createAnonymousType(node.symbol, propertiesTable, emptyArray, emptyArray, stringIndexInfo, numberIndexInfo);
result.flags |= TypeFlags.ContainsObjectLiteral | typeFlags & TypeFlags.PropagatingFlags;
result.objectFlags |= ObjectFlags.ObjectLiteral | freshObjectLiteralFlag;
result.objectFlags |= objectFlags | ObjectFlags.ObjectLiteral | ObjectFlags.ContainsObjectLiteral;
if (isJSObjectLiteral) {
result.objectFlags |= ObjectFlags.JSLiteral;
}
@ -18532,7 +18533,6 @@ namespace ts {
if (inDestructuringPattern) {
result.pattern = node;
}
propagatedFlags |= result.flags & TypeFlags.PropagatingFlags;
return result;
}
}
@ -18623,7 +18623,6 @@ namespace ts {
let hasSpreadAnyType = false;
let typeToIntersect: Type | undefined;
let explicitlySpecifyChildrenAttribute = false;
let typeFlags: TypeFlags = 0;
let objectFlags: ObjectFlags = ObjectFlags.JsxAttributes;
const jsxChildrenPropertyName = getJsxElementChildrenPropertyName(getJsxNamespaceAt(openingLikeElement));
@ -18631,7 +18630,7 @@ namespace ts {
const member = attributeDecl.symbol;
if (isJsxAttribute(attributeDecl)) {
const exprType = checkJsxAttribute(attributeDecl, checkMode);
typeFlags |= exprType.flags & TypeFlags.PropagatingFlags;
objectFlags |= getObjectFlags(exprType) & ObjectFlags.PropagatingFlags;
const attributeSymbol = createSymbol(SymbolFlags.Property | SymbolFlags.Transient | member.flags, member.escapedName);
attributeSymbol.declarations = member.declarations;
@ -18649,7 +18648,7 @@ namespace ts {
else {
Debug.assert(attributeDecl.kind === SyntaxKind.JsxSpreadAttribute);
if (attributesTable.size > 0) {
spread = getSpreadType(spread, createJsxAttributesType(), attributes.symbol, typeFlags, objectFlags, /*readonly*/ false);
spread = getSpreadType(spread, createJsxAttributesType(), attributes.symbol, objectFlags, /*readonly*/ false);
attributesTable = createSymbolTable();
}
const exprType = checkExpressionCached(attributeDecl.expression, checkMode);
@ -18657,7 +18656,7 @@ namespace ts {
hasSpreadAnyType = true;
}
if (isValidSpreadType(exprType)) {
spread = getSpreadType(spread, exprType, attributes.symbol, typeFlags, objectFlags, /*readonly*/ false);
spread = getSpreadType(spread, exprType, attributes.symbol, objectFlags, /*readonly*/ false);
}
else {
typeToIntersect = typeToIntersect ? getIntersectionType([typeToIntersect, exprType]) : exprType;
@ -18667,7 +18666,7 @@ namespace ts {
if (!hasSpreadAnyType) {
if (attributesTable.size > 0) {
spread = getSpreadType(spread, createJsxAttributesType(), attributes.symbol, typeFlags, objectFlags, /*readonly*/ false);
spread = getSpreadType(spread, createJsxAttributesType(), attributes.symbol, objectFlags, /*readonly*/ false);
}
}
@ -18699,7 +18698,7 @@ namespace ts {
const childPropMap = createSymbolTable();
childPropMap.set(jsxChildrenPropertyName, childrenPropSymbol);
spread = getSpreadType(spread, createAnonymousType(attributes.symbol, childPropMap, emptyArray, emptyArray, /*stringIndexInfo*/ undefined, /*numberIndexInfo*/ undefined),
attributes.symbol, typeFlags, objectFlags, /*readonly*/ false);
attributes.symbol, objectFlags, /*readonly*/ false);
}
}
@ -18720,8 +18719,7 @@ namespace ts {
function createJsxAttributesType() {
objectFlags |= freshObjectLiteralFlag;
const result = createAnonymousType(attributes.symbol, attributesTable, emptyArray, emptyArray, /*stringIndexInfo*/ undefined, /*numberIndexInfo*/ undefined);
result.flags |= TypeFlags.ContainsObjectLiteral | typeFlags;
result.objectFlags |= ObjectFlags.ObjectLiteral | objectFlags;
result.objectFlags |= objectFlags | ObjectFlags.ObjectLiteral | ObjectFlags.ContainsObjectLiteral;
return result;
}
}
@ -21386,7 +21384,7 @@ namespace ts {
const anonymousSymbol = createSymbol(SymbolFlags.TypeLiteral, InternalSymbolName.Type);
const defaultContainingObject = createAnonymousType(anonymousSymbol, memberTable, emptyArray, emptyArray, /*stringIndexInfo*/ undefined, /*numberIndexInfo*/ undefined);
anonymousSymbol.type = defaultContainingObject;
synthType.syntheticType = isValidSpreadType(type) ? getSpreadType(type, defaultContainingObject, anonymousSymbol, /*typeFLags*/ 0, /*objectFlags*/ 0, /*readonly*/ false) : defaultContainingObject;
synthType.syntheticType = isValidSpreadType(type) ? getSpreadType(type, defaultContainingObject, anonymousSymbol, /*objectFlags*/ 0, /*readonly*/ false) : defaultContainingObject;
}
else {
synthType.syntheticType = type;
@ -22064,7 +22062,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.flags |= TypeFlags.ContainsAnyFunctionType;
returnOnlyType.objectFlags |= ObjectFlags.ContainsAnyFunctionType;
return links.contextFreeType = returnOnlyType;
}
return anyFunctionType;

View File

@ -3817,39 +3817,33 @@ namespace ts {
}
export const enum TypeFlags {
Any = 1 << 0,
Unknown = 1 << 1,
String = 1 << 2,
Number = 1 << 3,
Boolean = 1 << 4,
Enum = 1 << 5,
BigInt = 1 << 6,
StringLiteral = 1 << 7,
NumberLiteral = 1 << 8,
BooleanLiteral = 1 << 9,
EnumLiteral = 1 << 10, // Always combined with StringLiteral, NumberLiteral, or Union
BigIntLiteral = 1 << 11,
ESSymbol = 1 << 12, // Type of symbol primitive introduced in ES6
UniqueESSymbol = 1 << 13, // unique symbol
Void = 1 << 14,
Undefined = 1 << 15,
Null = 1 << 16,
Never = 1 << 17, // Never type
TypeParameter = 1 << 18, // Type parameter
Object = 1 << 19, // Object type
Union = 1 << 20, // Union (T | U)
Intersection = 1 << 21, // Intersection (T & U)
Index = 1 << 22, // keyof T
IndexedAccess = 1 << 23, // T[K]
Conditional = 1 << 24, // T extends U ? X : Y
Substitution = 1 << 25, // Type parameter substitution
NonPrimitive = 1 << 26, // intrinsic object type
/* @internal */
ContainsWideningType = 1 << 27, // Type is or contains undefined or null widening type
/* @internal */
ContainsObjectLiteral = 1 << 28, // Type is or contains object literal type
/* @internal */
ContainsAnyFunctionType = 1 << 29, // Type is or contains the anyFunctionType
Any = 1 << 0,
Unknown = 1 << 1,
String = 1 << 2,
Number = 1 << 3,
Boolean = 1 << 4,
Enum = 1 << 5,
BigInt = 1 << 6,
StringLiteral = 1 << 7,
NumberLiteral = 1 << 8,
BooleanLiteral = 1 << 9,
EnumLiteral = 1 << 10, // Always combined with StringLiteral, NumberLiteral, or Union
BigIntLiteral = 1 << 11,
ESSymbol = 1 << 12, // Type of symbol primitive introduced in ES6
UniqueESSymbol = 1 << 13, // unique symbol
Void = 1 << 14,
Undefined = 1 << 15,
Null = 1 << 16,
Never = 1 << 17, // Never type
TypeParameter = 1 << 18, // Type parameter
Object = 1 << 19, // Object type
Union = 1 << 20, // Union (T | U)
Intersection = 1 << 21, // Intersection (T & U)
Index = 1 << 22, // keyof T
IndexedAccess = 1 << 23, // T[K]
Conditional = 1 << 24, // T extends U ? X : Y
Substitution = 1 << 25, // Type parameter substitution
NonPrimitive = 1 << 26, // intrinsic object type
/* @internal */
AnyOrUnknown = Any | Unknown,
@ -3883,29 +3877,29 @@ namespace ts {
InstantiablePrimitive = Index,
Instantiable = InstantiableNonPrimitive | InstantiablePrimitive,
StructuredOrInstantiable = StructuredType | Instantiable,
/* @internal */
ObjectFlagsType = Nullable | 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,
NotUnionOrUnit = Any | Unknown | ESSymbol | Object | NonPrimitive,
/* @internal */
NotPrimitiveUnion = Any | Unknown | Enum | Void | Never | StructuredOrInstantiable,
// The following flags are aggregated during union and intersection type construction
/* @internal */
RequiresWidening = ContainsWideningType | ContainsObjectLiteral,
/* @internal */
PropagatingFlags = ContainsWideningType | ContainsObjectLiteral | ContainsAnyFunctionType,
IncludesMask = Any | Unknown | Primitive | Never | Object | Union,
// The following flags are used for different purposes during union and intersection type construction
/* @internal */
NonWideningType = ContainsWideningType,
IncludesStructuredOrInstantiable = TypeParameter,
/* @internal */
Wildcard = ContainsObjectLiteral,
IncludesNonWideningType = Intersection,
/* @internal */
EmptyObject = ContainsAnyFunctionType,
IncludesWildcard = Index,
/* @internal */
ConstructionFlags = NonWideningType | Wildcard | EmptyObject,
IncludesEmptyObject = IndexedAccess,
// The following flag is used for different purposes by maybeTypeOfKind
/* @internal */
GenericMappedType = ContainsWideningType
GenericMappedType = Never,
}
export type DestructuringPattern = BindingPattern | ObjectLiteralExpression | ArrayLiteralExpression;
@ -3932,6 +3926,12 @@ namespace ts {
// Intrinsic types (TypeFlags.Intrinsic)
export interface IntrinsicType extends Type {
intrinsicName: string; // Name of intrinsic type
objectFlags: ObjectFlags;
}
/* @internal */
export interface NullableType extends IntrinsicType {
objectFlags: ObjectFlags;
}
/* @internal */
@ -3991,9 +3991,24 @@ namespace ts {
MarkerType = 1 << 13, // Marker type used for variance probing
JSLiteral = 1 << 14, // Object type declared in JS - disables errors on read/write of nonexisting members
FreshLiteral = 1 << 15, // Fresh object literal
ClassOrInterface = Class | Interface
/* @internal */
PrimitiveUnion = 1 << 16, // Union of only primitive types
/* @internal */
ContainsWideningType = 1 << 17, // Type is or contains undefined or null widening type
/* @internal */
ContainsObjectLiteral = 1 << 18, // Type is or contains object literal type
/* @internal */
ContainsAnyFunctionType = 1 << 19, // Type is or contains the anyFunctionType
ClassOrInterface = Class | Interface,
/* @internal */
RequiresWidening = ContainsWideningType | ContainsObjectLiteral,
/* @internal */
PropagatingFlags = ContainsWideningType | ContainsObjectLiteral | ContainsAnyFunctionType
}
/* @internal */
export type ObjectFlagsType = NullableType | ObjectType | UnionType | IntersectionType;
// Object types (TypeFlags.ObjectType)
export interface ObjectType extends Type {
objectFlags: ObjectFlags;
@ -4074,6 +4089,8 @@ namespace ts {
export interface UnionOrIntersectionType extends Type {
types: Type[]; // Constituent types
/* @internal */
objectFlags: ObjectFlags;
/* @internal */
propertyCache: SymbolTable; // Cache of resolved properties
/* @internal */
resolvedProperties: Symbol[];
@ -4088,8 +4105,6 @@ namespace ts {
}
export interface UnionType extends UnionOrIntersectionType {
/* @internal */
primitiveTypesOnly: boolean;
}
export interface IntersectionType extends UnionOrIntersectionType {

View File

@ -4515,7 +4515,7 @@ namespace ts {
}
export function getObjectFlags(type: Type): ObjectFlags {
return type.flags & TypeFlags.Object ? (<ObjectType>type).objectFlags : 0;
return type.flags & TypeFlags.ObjectFlagsType ? (<ObjectFlagsType>type).objectFlags : 0;
}
export function typeHasCallOrConstructSignatures(type: Type, checker: TypeChecker) {