Introduce TypeFlags.Instatiable

This commit is contained in:
Anders Hejlsberg
2017-12-13 09:14:57 -08:00
parent 43e195d966
commit 61225cc57c
2 changed files with 29 additions and 23 deletions

View File

@@ -6099,7 +6099,7 @@ namespace ts {
// First, if the constraint type is a type parameter, obtain the base constraint. Then,
// if the key type is a 'keyof X', obtain 'keyof C' where C is the base constraint of X.
// Finally, iterate over the constituents of the resulting iteration type.
const keyType = constraintType.flags & TypeFlags.TypeVariable ? getApparentType(constraintType) : constraintType;
const keyType = constraintType.flags & TypeFlags.InstantiableNonPrimitive ? getApparentType(constraintType) : constraintType;
const iterationType = keyType.flags & TypeFlags.Index ? getIndexType(getApparentType((<IndexType>keyType).type)) : keyType;
forEachType(iterationType, addMemberForKeyType);
}
@@ -6315,7 +6315,7 @@ namespace ts {
}
function getBaseConstraintOfType(type: Type): Type {
if (type.flags & (TypeFlags.TypeVariable | TypeFlags.UnionOrIntersection)) {
if (type.flags & (TypeFlags.InstantiableNonPrimitive | TypeFlags.UnionOrIntersection)) {
const constraint = getResolvedBaseConstraint(<TypeVariable | UnionOrIntersectionType>type);
if (constraint !== noConstraintType && constraint !== circularConstraintType) {
return constraint;
@@ -6324,6 +6324,9 @@ namespace ts {
else if (type.flags & TypeFlags.Index) {
return stringType;
}
else if (type.flags & TypeFlags.Extends) {
return booleanType;
}
return undefined;
}
@@ -6461,7 +6464,7 @@ namespace ts {
* type itself. Note that the apparent type of a union type is the union type itself.
*/
function getApparentType(type: Type): Type {
const t = type.flags & TypeFlags.TypeVariable ? getBaseConstraintOfType(type) || emptyObjectType : type;
const t = type.flags & TypeFlags.Instantiable ? getBaseConstraintOfType(type) || emptyObjectType : type;
return t.flags & TypeFlags.Intersection ? getApparentTypeOfIntersectionType(<IntersectionType>t) :
t.flags & TypeFlags.StringLike ? globalStringType :
t.flags & TypeFlags.NumberLike ? globalNumberType :
@@ -8011,10 +8014,10 @@ namespace ts {
}
function getIndexType(type: Type): Type {
return maybeTypeOfKind(type, TypeFlags.TypeVariable) ? getIndexTypeForGenericType(<TypeVariable | UnionOrIntersectionType>type) :
return maybeTypeOfKind(type, TypeFlags.InstantiableNonPrimitive) ? getIndexTypeForGenericType(<TypeVariable | UnionOrIntersectionType>type) :
getObjectFlags(type) & ObjectFlags.Mapped ? getConstraintTypeFromMappedType(<MappedType>type) :
type.flags & TypeFlags.Any || getIndexInfoOfType(type, IndexKind.String) ? stringType :
getLiteralTypeFromPropertyNames(type);
type.flags & TypeFlags.Any || getIndexInfoOfType(type, IndexKind.String) ? stringType :
getLiteralTypeFromPropertyNames(type);
}
function getIndexTypeOrString(type: Type): Type {
@@ -8109,11 +8112,11 @@ namespace ts {
}
function isGenericObjectType(type: Type): boolean {
return maybeTypeOfKind(type, TypeFlags.TypeVariable | TypeFlags.GenericMappedType);
return maybeTypeOfKind(type, TypeFlags.InstantiableNonPrimitive | TypeFlags.GenericMappedType);
}
function isGenericIndexType(type: Type): boolean {
return maybeTypeOfKind(type, TypeFlags.TypeVariable | TypeFlags.Index);
return maybeTypeOfKind(type, TypeFlags.InstantiableNonPrimitive | TypeFlags.Index);
}
// Return true if the given type is a non-generic object type with a string index signature and no
@@ -8224,7 +8227,7 @@ namespace ts {
}
function isGenericConditionType(type: Type) {
return maybeTypeOfKind(type, TypeFlags.TypeVariable | TypeFlags.Extends);
return maybeTypeOfKind(type, TypeFlags.InstantiableNonPrimitive | TypeFlags.Extends);
}
function createConditionalType(conditionType: Type, whenTrueType: Type, whenFalseType: Type, aliasSymbol: Symbol, aliasTypeArguments: Type[]) {
@@ -8265,7 +8268,7 @@ namespace ts {
}
function isGenericExtendsType(type: Type) {
return maybeTypeOfKind(type, TypeFlags.TypeVariable | TypeFlags.GenericMappedType | TypeFlags.Index | TypeFlags.Extends);
return maybeTypeOfKind(type, TypeFlags.Instantiable | TypeFlags.GenericMappedType);
}
function createExtendsType(checkType: Type, extendsType: Type) {
@@ -9042,7 +9045,7 @@ namespace ts {
function isTypeDerivedFrom(source: Type, target: Type): boolean {
return source.flags & TypeFlags.Union ? every((<UnionType>source).types, t => isTypeDerivedFrom(t, target)) :
target.flags & TypeFlags.Union ? some((<UnionType>target).types, t => isTypeDerivedFrom(source, t)) :
source.flags & TypeFlags.TypeVariable ? isTypeDerivedFrom(getBaseConstraintOfType(source) || emptyObjectType, target) :
source.flags & TypeFlags.InstantiableNonPrimitive ? isTypeDerivedFrom(getBaseConstraintOfType(source) || emptyObjectType, target) :
target === globalObjectType || target === globalFunctionType ? isTypeSubtypeOf(source, target) :
hasBaseType(source, getTargetType(target));
}
@@ -9379,7 +9382,7 @@ namespace ts {
return related === RelationComparisonResult.Succeeded;
}
}
if (source.flags & TypeFlags.StructuredOrTypeVariable || target.flags & TypeFlags.StructuredOrTypeVariable) {
if (source.flags & TypeFlags.StructuredOrInstantiable || target.flags & TypeFlags.StructuredOrInstantiable) {
return checkTypeRelatedTo(source, target, relation, /*errorNode*/ undefined);
}
return false;
@@ -9585,7 +9588,7 @@ namespace ts {
// breaking the intersection apart.
result = someTypeRelatedToType(<IntersectionType>source, target, /*reportErrors*/ false);
}
if (!result && (source.flags & TypeFlags.StructuredOrTypeVariable || target.flags & TypeFlags.StructuredOrTypeVariable)) {
if (!result && (source.flags & TypeFlags.StructuredOrInstantiable || target.flags & TypeFlags.StructuredOrInstantiable)) {
if (result = recursiveTypeRelatedTo(source, target, reportErrors)) {
errorInfo = saveErrorInfo;
}
@@ -11230,7 +11233,7 @@ namespace ts {
// results for union and intersection types for performance reasons.
function couldContainTypeVariables(type: Type): boolean {
const objectFlags = getObjectFlags(type);
return !!(type.flags & (TypeFlags.TypeVariable | TypeFlags.Index) ||
return !!(type.flags & TypeFlags.Instantiable ||
objectFlags & ObjectFlags.Reference && forEach((<TypeReference>type).typeArguments, couldContainTypeVariables) ||
objectFlags & ObjectFlags.Anonymous && type.symbol && type.symbol.flags & (SymbolFlags.Function | SymbolFlags.Method | SymbolFlags.TypeLiteral | SymbolFlags.Class) ||
objectFlags & ObjectFlags.Mapped ||
@@ -12026,7 +12029,7 @@ namespace ts {
if (flags & TypeFlags.NonPrimitive) {
return strictNullChecks ? TypeFacts.ObjectStrictFacts : TypeFacts.ObjectFacts;
}
if (flags & TypeFlags.TypeVariable) {
if (flags & TypeFlags.Instantiable) {
return getTypeFacts(getBaseConstraintOfType(type) || emptyObjectType);
}
if (flags & TypeFlags.UnionOrIntersection) {
@@ -12878,7 +12881,7 @@ namespace ts {
if (isTypeSubtypeOf(targetType, type)) {
return targetType;
}
if (type.flags & TypeFlags.TypeVariable) {
if (type.flags & TypeFlags.Instantiable) {
const constraint = getBaseConstraintOfType(type) || anyType;
if (isTypeSubtypeOf(targetType, constraint)) {
return getIntersectionType([type, targetType]);
@@ -13141,7 +13144,7 @@ namespace ts {
}
function typeHasNullableConstraint(type: Type) {
return type.flags & TypeFlags.TypeVariable && maybeTypeOfKind(getBaseConstraintOfType(type) || emptyObjectType, TypeFlags.Nullable);
return type.flags & TypeFlags.InstantiableNonPrimitive && maybeTypeOfKind(getBaseConstraintOfType(type) || emptyObjectType, TypeFlags.Nullable);
}
function getDeclaredOrApparentType(symbol: Symbol, node: Node) {
@@ -18535,7 +18538,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.TypeVariable)) {
if (!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;
@@ -19132,7 +19135,7 @@ namespace ts {
!(t.flags & TypeFlags.BooleanLiteral && containsType(types, trueType) && containsType(types, falseType)) &&
isLiteralOfContextualType(candidateType, t));
}
if (contextualType.flags & TypeFlags.TypeVariable) {
if (contextualType.flags & TypeFlags.InstantiableNonPrimitive) {
// If the contextual type is a type variable constrained to a primitive type, consider
// this a literal context for literals of that primitive type. For example, given a
// type parameter 'T extends string', infer string literal types for T.
@@ -21878,7 +21881,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 (!isTypeAssignableToKind(rightType, TypeFlags.NonPrimitive | TypeFlags.TypeVariable)) {
if (!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);
}

View File

@@ -3391,12 +3391,15 @@ namespace ts {
ESSymbolLike = ESSymbol | UniqueESSymbol,
UnionOrIntersection = Union | Intersection,
StructuredType = Object | Union | Intersection,
TypeVariable = TypeParameter | IndexedAccess | Conditional,
StructuredOrTypeVariable = StructuredType | TypeVariable | Index | Extends,
TypeVariable = TypeParameter | IndexedAccess,
InstantiableNonPrimitive = TypeVariable | Conditional,
InstantiablePrimitive = Index | Extends,
Instantiable = InstantiableNonPrimitive | InstantiablePrimitive,
StructuredOrInstantiable = StructuredType | Instantiable,
// 'Narrowable' types are types where narrowing actually narrows.
// This *should* be every type other than null, undefined, void, and never
Narrowable = Any | StructuredOrTypeVariable | StringLike | NumberLike | BooleanLike | ESSymbol | UniqueESSymbol | NonPrimitive,
Narrowable = Any | StructuredOrInstantiable | StringLike | NumberLike | BooleanLike | ESSymbol | UniqueESSymbol | NonPrimitive,
NotUnionOrUnit = Any | ESSymbol | Object | NonPrimitive,
/* @internal */
RequiresWidening = ContainsWideningType | ContainsObjectLiteral,