mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-06-16 07:13:43 -05:00
Support recursive type aliases for object types
This commit is contained in:
@@ -1032,6 +1032,7 @@ import {
|
||||
TupleTypeReference,
|
||||
Type,
|
||||
TypeAliasDeclaration,
|
||||
TypeAliasInstantiationType,
|
||||
TypeAssertion,
|
||||
TypeChecker,
|
||||
TypeCheckerHost,
|
||||
@@ -6530,9 +6531,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
return factory.createKeywordTypeNode(SyntaxKind.AnyKeyword);
|
||||
}
|
||||
|
||||
if (!(context.flags & NodeBuilderFlags.NoTypeReduction)) {
|
||||
type = getReducedType(type);
|
||||
}
|
||||
type = context.flags & NodeBuilderFlags.NoTypeReduction ? getResolvedType(type) : getReducedType(type);
|
||||
|
||||
if (type.flags & TypeFlags.Any) {
|
||||
if (type.aliasSymbol) {
|
||||
@@ -13747,6 +13746,15 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
}
|
||||
}
|
||||
|
||||
function resolveTypeAliasInstantiationMembers(type: TypeAliasInstantiationType) {
|
||||
const resolved = resolveStructuredTypeMembers(getResolvedTypeAliasInstantiation(type));
|
||||
type.members = resolved.members;
|
||||
type.properties = resolved.properties;
|
||||
type.callSignatures = resolved.callSignatures;
|
||||
type.constructSignatures = resolved.constructSignatures;
|
||||
type.indexInfos = resolved.indexInfos;
|
||||
}
|
||||
|
||||
type ReplaceableIndexedAccessType = IndexedAccessType & { objectType: TypeParameter; indexType: TypeParameter; };
|
||||
function replaceIndexedAccess(instantiable: Type, type: ReplaceableIndexedAccessType, replacement: Type) {
|
||||
// map type.indexType to 0
|
||||
@@ -14090,6 +14098,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
else if ((type as MappedType).objectFlags & ObjectFlags.Mapped) {
|
||||
resolveMappedTypeMembers(type as MappedType);
|
||||
}
|
||||
else if ((type as MappedType).objectFlags & ObjectFlags.TypeAliasInstantiation) {
|
||||
resolveTypeAliasInstantiationMembers(type as TypeAliasInstantiationType);
|
||||
}
|
||||
else {
|
||||
Debug.fail("Unhandled object type " + Debug.formatObjectFlags(type.objectFlags));
|
||||
}
|
||||
@@ -14824,7 +14835,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
/**
|
||||
* Return the reduced form of the given type. For a union type, it is a union of the normalized constituent types.
|
||||
* For an intersection of types containing one or more mututally exclusive discriminant properties, it is 'never'.
|
||||
* For all other types, it is simply the type itself. Discriminant properties are considered mutually exclusive when
|
||||
* For all other types, it is the resolved type itself. Discriminant properties are considered mutually exclusive when
|
||||
* no constituent property has type 'never', but the intersection of the constituent property types is 'never'.
|
||||
*/
|
||||
function getReducedType(type: Type): Type {
|
||||
@@ -14838,7 +14849,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
}
|
||||
return (type as IntersectionType).objectFlags & ObjectFlags.IsNeverIntersection ? neverType : type;
|
||||
}
|
||||
return type;
|
||||
return getResolvedType(type);
|
||||
}
|
||||
|
||||
function getReducedUnionType(unionType: UnionType) {
|
||||
@@ -14846,7 +14857,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
if (reducedTypes === unionType.types) {
|
||||
return unionType;
|
||||
}
|
||||
const reduced = getUnionType(reducedTypes);
|
||||
const reduced = getResolvedType(getUnionType(reducedTypes));
|
||||
if (reduced.flags & TypeFlags.Union) {
|
||||
(reduced as UnionType).resolvedReducedType = reduced;
|
||||
}
|
||||
@@ -15965,7 +15976,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
return errorType;
|
||||
}
|
||||
}
|
||||
if (node.kind === SyntaxKind.TypeReference && isDeferredTypeReferenceNode(node as TypeReferenceNode, length(node.typeArguments) !== typeParameters.length)) {
|
||||
if (node.kind === SyntaxKind.TypeReference && (getAliasSymbolForTypeNode(node) || isDeferredTypeReferenceNode(node as TypeReferenceNode, length(node.typeArguments) !== typeParameters.length))) {
|
||||
return createDeferredTypeReference(type as GenericType, node as TypeReferenceNode, /*mapper*/ undefined);
|
||||
}
|
||||
// In a type reference, the outer type parameters of the referenced class or interface are automatically
|
||||
@@ -15977,24 +15988,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
return checkNoTypeArguments(node, symbol) ? type : errorType;
|
||||
}
|
||||
|
||||
function getTypeAliasInstantiation(symbol: Symbol, typeArguments: readonly Type[] | undefined, aliasSymbol?: Symbol, aliasTypeArguments?: readonly Type[]): Type {
|
||||
const type = getDeclaredTypeOfSymbol(symbol);
|
||||
if (type === intrinsicMarkerType) {
|
||||
const typeKind = intrinsicTypeKinds.get(symbol.escapedName as string);
|
||||
if (typeKind !== undefined && typeArguments && typeArguments.length === 1) {
|
||||
return typeKind === IntrinsicTypeKind.NoInfer ? getNoInferType(typeArguments[0]) : getStringMappingType(symbol, typeArguments[0]);
|
||||
}
|
||||
}
|
||||
const links = getSymbolLinks(symbol);
|
||||
const typeParameters = links.typeParameters!;
|
||||
const id = getTypeListId(typeArguments) + getAliasId(aliasSymbol, aliasTypeArguments);
|
||||
let instantiation = links.instantiations!.get(id);
|
||||
if (!instantiation) {
|
||||
links.instantiations!.set(id, instantiation = instantiateTypeWithAlias(type, createTypeMapper(typeParameters, fillMissingTypeArguments(typeArguments, typeParameters, getMinTypeArgumentCount(typeParameters), isInJSFile(symbol.valueDeclaration))), aliasSymbol, aliasTypeArguments));
|
||||
}
|
||||
return instantiation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get type from reference to type alias. When a type alias is generic, the declared type of the type alias may include
|
||||
* references to the type parameters of the alias. We replace those with the actual type arguments by instantiating the
|
||||
@@ -16048,10 +16041,18 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
const resolved = resolveAlias(aliasSymbol);
|
||||
if (resolved && resolved.flags & SymbolFlags.TypeAlias) {
|
||||
newAliasSymbol = resolved;
|
||||
aliasTypeArguments = typeArgumentsFromTypeReferenceNode(node) || (typeParameters ? [] : undefined);
|
||||
aliasTypeArguments = typeArgumentsFromTypeReferenceNode(node) ?? [];
|
||||
}
|
||||
}
|
||||
}
|
||||
// If we have an instantiation of a generic type alias for a type reference, an anonymous type, or a
|
||||
// mapped type, and the instantiation occurs in a context where resolving type arguments might cause a
|
||||
// circular reference, we create a deferred type alias instantiation. This acts as a proxy for the
|
||||
// actual instantiation, which is obtained using getResolvedType.
|
||||
if (getObjectFlags(type) & (ObjectFlags.Reference | ObjectFlags.Anonymous | ObjectFlags.Mapped) && node.kind === SyntaxKind.TypeReference &&
|
||||
isDeferredTypeReferenceNode(node as TypeReferenceNode, length(node.typeArguments) !== typeParameters.length)) {
|
||||
return createDeferredTypeAliasInstantiation(symbol, node, newAliasSymbol, aliasTypeArguments);
|
||||
}
|
||||
return getTypeAliasInstantiation(symbol, typeArgumentsFromTypeReferenceNode(node), newAliasSymbol, aliasTypeArguments);
|
||||
}
|
||||
return checkNoTypeArguments(node, symbol) ? type : errorType;
|
||||
@@ -16062,6 +16063,49 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
return !!(declaration && getContainingFunction(declaration));
|
||||
}
|
||||
|
||||
function getTypeAliasInstantiation(symbol: Symbol, typeArguments: readonly Type[] | undefined, aliasSymbol?: Symbol, aliasTypeArguments?: readonly Type[]): Type {
|
||||
const type = getDeclaredTypeOfSymbol(symbol);
|
||||
if (type === intrinsicMarkerType) {
|
||||
const typeKind = intrinsicTypeKinds.get(symbol.escapedName as string);
|
||||
if (typeKind !== undefined && typeArguments && typeArguments.length === 1) {
|
||||
return typeKind === IntrinsicTypeKind.NoInfer ? getNoInferType(typeArguments[0]) : getStringMappingType(symbol, typeArguments[0]);
|
||||
}
|
||||
}
|
||||
const links = getSymbolLinks(symbol);
|
||||
const typeParameters = links.typeParameters!;
|
||||
const id = getTypeListId(typeArguments) + getAliasId(aliasSymbol, aliasTypeArguments);
|
||||
let instantiation = links.instantiations!.get(id);
|
||||
if (!instantiation) {
|
||||
links.instantiations!.set(id, instantiation = instantiateTypeWithAlias(type, createTypeMapper(typeParameters, fillMissingTypeArguments(typeArguments, typeParameters, getMinTypeArgumentCount(typeParameters), isInJSFile(symbol.valueDeclaration))), aliasSymbol, aliasTypeArguments));
|
||||
}
|
||||
return instantiation;
|
||||
}
|
||||
|
||||
function createDeferredTypeAliasInstantiation(typeAlias: Symbol, node: NodeWithTypeArguments, aliasSymbol?: Symbol, aliasTypeArguments?: readonly Type[]): TypeAliasInstantiationType {
|
||||
const type = getDeclaredTypeOfSymbol(typeAlias);
|
||||
const result = createObjectType(ObjectFlags.TypeAliasInstantiation, type.symbol) as TypeAliasInstantiationType;
|
||||
result.typeAlias = typeAlias;
|
||||
result.node = node;
|
||||
result.aliasSymbol = aliasSymbol;
|
||||
result.aliasTypeArguments = aliasTypeArguments;
|
||||
return result;
|
||||
}
|
||||
|
||||
function getResolvedType(type: Type): Type {
|
||||
return type.flags & TypeFlags.Object && (type as ObjectType).objectFlags & ObjectFlags.TypeAliasInstantiation ?
|
||||
getResolvedTypeAliasInstantiation(type as TypeAliasInstantiationType) :
|
||||
type;
|
||||
}
|
||||
|
||||
function getResolvedTypeAliasInstantiation(type: TypeAliasInstantiationType): AnonymousType {
|
||||
if (!type.resolvedType) {
|
||||
const typeArguments = typeArgumentsFromTypeReferenceNode(type.node);
|
||||
const mappedTypeArguments = type.mapper ? instantiateTypes(typeArguments, type.mapper) : typeArguments;
|
||||
type.resolvedType = getTypeAliasInstantiation(type.typeAlias, mappedTypeArguments, type.aliasSymbol, type.aliasTypeArguments) as ObjectType;
|
||||
}
|
||||
return type.resolvedType;
|
||||
}
|
||||
|
||||
function getTypeReferenceName(node: TypeReferenceType): EntityNameOrEntityNameExpression | undefined {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.TypeReference:
|
||||
@@ -16674,14 +16718,14 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
return isNamedTupleMember(member) || isParameter(member) ? member : undefined;
|
||||
}
|
||||
|
||||
// Return true if the given type reference node is directly aliased or if it needs to be deferred
|
||||
// because it is possibly contained in a circular chain of eagerly resolved types.
|
||||
// Return true if the given type reference node needs to be deferred because it is possibly contained
|
||||
// in a circular chain of eagerly resolved types.
|
||||
function isDeferredTypeReferenceNode(node: TypeReferenceNode | ArrayTypeNode | TupleTypeNode, hasDefaultTypeArguments?: boolean) {
|
||||
return !!getAliasSymbolForTypeNode(node) || isResolvedByTypeAlias(node) && (
|
||||
node.kind === SyntaxKind.ArrayType ? mayResolveTypeAlias(node.elementType) :
|
||||
node.kind === SyntaxKind.TupleType ? some(node.elements, mayResolveTypeAlias) :
|
||||
hasDefaultTypeArguments || some(node.typeArguments, mayResolveTypeAlias)
|
||||
);
|
||||
return isResolvedByTypeAlias(node) && (
|
||||
node.kind === SyntaxKind.ArrayType ? mayResolveTypeAlias(node.elementType) :
|
||||
node.kind === SyntaxKind.TupleType ? some(node.elements, mayResolveTypeAlias) :
|
||||
hasDefaultTypeArguments || some(node.typeArguments, mayResolveTypeAlias)
|
||||
);
|
||||
}
|
||||
|
||||
// Return true when the given node is transitively contained in type constructs that eagerly
|
||||
@@ -16746,7 +16790,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
if (target === emptyGenericType) {
|
||||
links.resolvedType = emptyObjectType;
|
||||
}
|
||||
else if (!(node.kind === SyntaxKind.TupleType && some(node.elements, e => !!(getTupleElementFlags(e) & ElementFlags.Variadic))) && isDeferredTypeReferenceNode(node)) {
|
||||
else if (!(node.kind === SyntaxKind.TupleType && some(node.elements, e => !!(getTupleElementFlags(e) & ElementFlags.Variadic))) && (getAliasSymbolForTypeNode(node) || isDeferredTypeReferenceNode(node))) {
|
||||
links.resolvedType = node.kind === SyntaxKind.TupleType && node.elements.length === 0 ? target :
|
||||
createDeferredTypeReference(target, node, /*mapper*/ undefined);
|
||||
}
|
||||
@@ -18391,14 +18435,14 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
}
|
||||
return (type as SubstitutionType).objectFlags & ObjectFlags.IsGenericType;
|
||||
}
|
||||
return (type.flags & TypeFlags.InstantiableNonPrimitive || isGenericMappedType(type) || isGenericTupleType(type) ? ObjectFlags.IsGenericObjectType : 0) |
|
||||
return (type.flags & TypeFlags.InstantiableNonPrimitive || isGenericMappedType(getResolvedType(type)) || isGenericTupleType(type) ? ObjectFlags.IsGenericObjectType : 0) |
|
||||
(type.flags & (TypeFlags.InstantiableNonPrimitive | TypeFlags.Index | TypeFlags.TemplateLiteral | TypeFlags.StringMapping) && !isPatternLiteralType(type) ? ObjectFlags.IsGenericIndexType : 0);
|
||||
}
|
||||
|
||||
function getSimplifiedType(type: Type, writing: boolean): Type {
|
||||
return type.flags & TypeFlags.IndexedAccess ? getSimplifiedIndexedAccessType(type as IndexedAccessType, writing) :
|
||||
type.flags & TypeFlags.Conditional ? getSimplifiedConditionalType(type as ConditionalType, writing) :
|
||||
type;
|
||||
getResolvedType(type);
|
||||
}
|
||||
|
||||
function distributeIndexOverObjectType(objectType: Type, indexType: Type, writing: boolean) {
|
||||
@@ -19623,6 +19667,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
function getObjectTypeInstantiation(type: AnonymousType | DeferredTypeReference, mapper: TypeMapper, aliasSymbol?: Symbol, aliasTypeArguments?: readonly Type[]) {
|
||||
const declaration = type.objectFlags & ObjectFlags.Reference ? (type as TypeReference).node! :
|
||||
type.objectFlags & ObjectFlags.InstantiationExpressionType ? (type as InstantiationExpressionType).node :
|
||||
type.objectFlags & ObjectFlags.TypeAliasInstantiation ? (type as TypeAliasInstantiationType).node :
|
||||
type.symbol.declarations![0];
|
||||
const links = getNodeLinks(declaration);
|
||||
const target = type.objectFlags & ObjectFlags.Reference ? links.resolvedType! as DeferredTypeReference :
|
||||
@@ -19639,8 +19684,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
outerTypeParameters = addRange(outerTypeParameters, templateTagParameters);
|
||||
}
|
||||
typeParameters = outerTypeParameters || emptyArray;
|
||||
const allDeclarations = type.objectFlags & (ObjectFlags.Reference | ObjectFlags.InstantiationExpressionType) ? [declaration] : type.symbol.declarations!;
|
||||
typeParameters = (target.objectFlags & (ObjectFlags.Reference | ObjectFlags.InstantiationExpressionType) || target.symbol.flags & SymbolFlags.Method || target.symbol.flags & SymbolFlags.TypeLiteral) && !target.aliasTypeArguments ?
|
||||
const allDeclarations = type.objectFlags & (ObjectFlags.Reference | ObjectFlags.InstantiationExpressionType | ObjectFlags.TypeAliasInstantiation) ? [declaration] : type.symbol.declarations!;
|
||||
typeParameters = (target.objectFlags & (ObjectFlags.Reference | ObjectFlags.InstantiationExpressionType | ObjectFlags.TypeAliasInstantiation) || target.symbol.flags & SymbolFlags.Method || target.symbol.flags & SymbolFlags.TypeLiteral) && !target.aliasTypeArguments ?
|
||||
filter(typeParameters, tp => some(allDeclarations, d => isTypeParameterPossiblyReferenced(tp, d))) :
|
||||
typeParameters;
|
||||
links.outerTypeParameters = typeParameters;
|
||||
@@ -19843,7 +19888,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
}
|
||||
|
||||
function instantiateAnonymousType(type: AnonymousType, mapper: TypeMapper, aliasSymbol?: Symbol, aliasTypeArguments?: readonly Type[]): AnonymousType {
|
||||
Debug.assert(type.symbol, "anonymous type must have symbol to be instantiated");
|
||||
const result = createObjectType(type.objectFlags & ~(ObjectFlags.CouldContainTypeVariablesComputed | ObjectFlags.CouldContainTypeVariables) | ObjectFlags.Instantiated, type.symbol) as AnonymousType;
|
||||
if (type.objectFlags & ObjectFlags.Mapped) {
|
||||
(result as MappedType).declaration = (type as MappedType).declaration;
|
||||
@@ -19854,9 +19898,13 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
mapper = combineTypeMappers(makeUnaryTypeMapper(origTypeParameter, freshTypeParameter), mapper);
|
||||
freshTypeParameter.mapper = mapper;
|
||||
}
|
||||
if (type.objectFlags & ObjectFlags.InstantiationExpressionType) {
|
||||
else if (type.objectFlags & ObjectFlags.InstantiationExpressionType) {
|
||||
(result as InstantiationExpressionType).node = (type as InstantiationExpressionType).node;
|
||||
}
|
||||
else if (type.objectFlags & ObjectFlags.TypeAliasInstantiation) {
|
||||
(result as TypeAliasInstantiationType).typeAlias = (type as TypeAliasInstantiationType).typeAlias;
|
||||
(result as TypeAliasInstantiationType).node = (type as TypeAliasInstantiationType).node;
|
||||
}
|
||||
result.target = type;
|
||||
result.mapper = mapper;
|
||||
result.aliasSymbol = aliasSymbol || type.aliasSymbol;
|
||||
@@ -19924,7 +19972,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
}
|
||||
if (flags & TypeFlags.Object) {
|
||||
const objectFlags = (type as ObjectType).objectFlags;
|
||||
if (objectFlags & (ObjectFlags.Reference | ObjectFlags.Anonymous | ObjectFlags.Mapped)) {
|
||||
if (objectFlags & (ObjectFlags.Reference | ObjectFlags.Anonymous | ObjectFlags.Mapped | ObjectFlags.TypeAliasInstantiation)) {
|
||||
if (objectFlags & ObjectFlags.Reference && !(type as TypeReference).node) {
|
||||
const resolvedTypeArguments = (type as TypeReference).resolvedTypeArguments;
|
||||
const newTypeArguments = instantiateTypes(resolvedTypeArguments, mapper);
|
||||
@@ -21170,6 +21218,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
const t = isFreshLiteralType(type) ? (type as FreshableType).regularType :
|
||||
isGenericTupleType(type) ? getNormalizedTupleType(type, writing) :
|
||||
getObjectFlags(type) & ObjectFlags.Reference ? (type as TypeReference).node ? createTypeReference((type as TypeReference).target, getTypeArguments(type as TypeReference)) : getSingleBaseForNonAugmentingSubtype(type) || type :
|
||||
getObjectFlags(type) & ObjectFlags.TypeAliasInstantiation ? getResolvedTypeAliasInstantiation(type as TypeAliasInstantiationType) :
|
||||
type.flags & TypeFlags.UnionOrIntersection ? getNormalizedUnionOrIntersectionType(type as UnionOrIntersectionType, writing) :
|
||||
type.flags & TypeFlags.Substitution ? writing ? (type as SubstitutionType).baseType : getSubstitutionIntersection(type as SubstitutionType) :
|
||||
type.flags & TypeFlags.Simplifiable ? getSimplifiedType(type, writing) :
|
||||
@@ -24018,7 +24067,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
type = getMappedTargetWithSymbol(type);
|
||||
}
|
||||
if (type.flags & TypeFlags.Intersection) {
|
||||
return some((type as IntersectionType).types, t => isDeeplyNestedType(t, stack, depth, maxDepth));
|
||||
return some((type as IntersectionType).types, t => isDeeplyNestedType(getResolvedType(t), stack, depth, maxDepth));
|
||||
}
|
||||
const identity = getRecursionIdentity(type);
|
||||
let count = 0;
|
||||
@@ -24062,7 +24111,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
type = getMappedTargetWithSymbol(type);
|
||||
}
|
||||
if (type.flags & TypeFlags.Intersection) {
|
||||
return some((type as IntersectionType).types, t => hasMatchingRecursionIdentity(t, identity));
|
||||
return some((type as IntersectionType).types, t => hasMatchingRecursionIdentity(getResolvedType(t), identity));
|
||||
}
|
||||
return getRecursionIdentity(type) === identity;
|
||||
}
|
||||
@@ -25124,7 +25173,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
type.flags & TypeFlags.Object && !isNonGenericTopLevelType(type) && (
|
||||
objectFlags & ObjectFlags.Reference && ((type as TypeReference).node || some(getTypeArguments(type as TypeReference), couldContainTypeVariables)) ||
|
||||
objectFlags & ObjectFlags.Anonymous && type.symbol && type.symbol.flags & (SymbolFlags.Function | SymbolFlags.Method | SymbolFlags.Class | SymbolFlags.TypeLiteral | SymbolFlags.ObjectLiteral) && type.symbol.declarations ||
|
||||
objectFlags & (ObjectFlags.Mapped | ObjectFlags.ReverseMapped | ObjectFlags.ObjectRestType | ObjectFlags.InstantiationExpressionType)
|
||||
objectFlags & (ObjectFlags.Mapped | ObjectFlags.ReverseMapped | ObjectFlags.ObjectRestType | ObjectFlags.InstantiationExpressionType | ObjectFlags.TypeAliasInstantiation)
|
||||
) ||
|
||||
type.flags & TypeFlags.UnionOrIntersection && !(type.flags & TypeFlags.EnumLiteral) && !isNonGenericTopLevelType(type) && some((type as UnionOrIntersectionType).types, couldContainTypeVariables));
|
||||
if (type.flags & TypeFlags.ObjectFlagsType) {
|
||||
@@ -25504,6 +25553,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
propagationType = savePropagationType;
|
||||
return;
|
||||
}
|
||||
source = getResolvedType(source);
|
||||
target = getResolvedType(target);
|
||||
if (source.aliasSymbol && source.aliasSymbol === target.aliasSymbol) {
|
||||
if (source.aliasTypeArguments) {
|
||||
// Source and target are types originating in the same generic type alias declaration.
|
||||
@@ -28874,11 +28925,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
location = location.parent;
|
||||
}
|
||||
if (isExpressionNode(location) && (!isAssignmentTarget(location) || isWriteAccess(location))) {
|
||||
const type = removeOptionalTypeMarker(
|
||||
const type = getResolvedType(removeOptionalTypeMarker(
|
||||
isWriteAccess(location) && location.kind === SyntaxKind.PropertyAccessExpression ?
|
||||
checkPropertyAccessExpression(location as PropertyAccessExpression, /*checkMode*/ undefined, /*writeOnly*/ true) :
|
||||
getTypeOfExpression(location as Expression),
|
||||
);
|
||||
));
|
||||
if (getExportSymbolOfValueSymbolIfExported(getNodeLinks(location).resolvedSymbol) === symbol) {
|
||||
return type;
|
||||
}
|
||||
|
||||
@@ -6280,27 +6280,28 @@ export const enum ObjectFlags {
|
||||
Tuple = 1 << 3, // Synthesized generic tuple type
|
||||
Anonymous = 1 << 4, // Anonymous
|
||||
Mapped = 1 << 5, // Mapped
|
||||
Instantiated = 1 << 6, // Instantiated anonymous or mapped type
|
||||
ObjectLiteral = 1 << 7, // Originates in an object literal
|
||||
EvolvingArray = 1 << 8, // Evolving array type
|
||||
ObjectLiteralPatternWithComputedProperties = 1 << 9, // Object literal pattern with computed properties
|
||||
ReverseMapped = 1 << 10, // Object contains a property from a reverse-mapped type
|
||||
JsxAttributes = 1 << 11, // Jsx attributes type
|
||||
JSLiteral = 1 << 12, // Object type declared in JS - disables errors on read/write of nonexisting members
|
||||
FreshLiteral = 1 << 13, // Fresh object literal
|
||||
ArrayLiteral = 1 << 14, // Originates in an array literal
|
||||
TypeAliasInstantiation = 1 << 6, // Deferred type alias instantiation
|
||||
Instantiated = 1 << 7, // Instantiated anonymous or mapped type
|
||||
ObjectLiteral = 1 << 8, // Originates in an object literal
|
||||
EvolvingArray = 1 << 9, // Evolving array type
|
||||
ObjectLiteralPatternWithComputedProperties = 1 << 10, // Object literal pattern with computed properties
|
||||
ReverseMapped = 1 << 11, // Object contains a property from a reverse-mapped type
|
||||
JsxAttributes = 1 << 12, // Jsx attributes type
|
||||
JSLiteral = 1 << 13, // Object type declared in JS - disables errors on read/write of nonexisting members
|
||||
FreshLiteral = 1 << 14, // Fresh object literal
|
||||
ArrayLiteral = 1 << 15, // Originates in an array literal
|
||||
/** @internal */
|
||||
PrimitiveUnion = 1 << 15, // Union of only primitive types
|
||||
PrimitiveUnion = 1 << 16, // Union of only primitive types
|
||||
/** @internal */
|
||||
ContainsWideningType = 1 << 16, // Type is or contains undefined or null widening type
|
||||
ContainsWideningType = 1 << 17, // Type is or contains undefined or null widening type
|
||||
/** @internal */
|
||||
ContainsObjectOrArrayLiteral = 1 << 17, // Type is or contains object literal type
|
||||
ContainsObjectOrArrayLiteral = 1 << 18, // Type is or contains object literal type
|
||||
/** @internal */
|
||||
NonInferrableType = 1 << 18, // Type is or contains anyFunctionType or silentNeverType
|
||||
NonInferrableType = 1 << 19, // Type is or contains anyFunctionType or silentNeverType
|
||||
/** @internal */
|
||||
CouldContainTypeVariablesComputed = 1 << 19, // CouldContainTypeVariables flag has been computed
|
||||
CouldContainTypeVariablesComputed = 1 << 20, // CouldContainTypeVariables flag has been computed
|
||||
/** @internal */
|
||||
CouldContainTypeVariables = 1 << 20, // Type could contain a type variable
|
||||
CouldContainTypeVariables = 1 << 21, // Type could contain a type variable
|
||||
|
||||
ClassOrInterface = Class | Interface,
|
||||
/** @internal */
|
||||
@@ -6314,43 +6315,43 @@ export const enum ObjectFlags {
|
||||
ObjectTypeKindMask = ClassOrInterface | Reference | Tuple | Anonymous | Mapped | ReverseMapped | EvolvingArray,
|
||||
|
||||
// Flags that require TypeFlags.Object
|
||||
ContainsSpread = 1 << 21, // Object literal contains spread operation
|
||||
ObjectRestType = 1 << 22, // Originates in object rest declaration
|
||||
InstantiationExpressionType = 1 << 23, // Originates in instantiation expression
|
||||
ContainsSpread = 1 << 22, // Object literal contains spread operation
|
||||
ObjectRestType = 1 << 23, // Originates in object rest declaration
|
||||
InstantiationExpressionType = 1 << 24, // Originates in instantiation expression
|
||||
/** @internal */
|
||||
IsClassInstanceClone = 1 << 24, // Type is a clone of a class instance type
|
||||
IsClassInstanceClone = 1 << 25, // Type is a clone of a class instance type
|
||||
// Flags that require TypeFlags.Object and ObjectFlags.Reference
|
||||
/** @internal */
|
||||
IdenticalBaseTypeCalculated = 1 << 25, // has had `getSingleBaseForNonAugmentingSubtype` invoked on it already
|
||||
IdenticalBaseTypeCalculated = 1 << 26, // has had `getSingleBaseForNonAugmentingSubtype` invoked on it already
|
||||
/** @internal */
|
||||
IdenticalBaseTypeExists = 1 << 26, // has a defined cachedEquivalentBaseType member
|
||||
IdenticalBaseTypeExists = 1 << 27, // has a defined cachedEquivalentBaseType member
|
||||
|
||||
// Flags that require TypeFlags.UnionOrIntersection or TypeFlags.Substitution
|
||||
/** @internal */
|
||||
IsGenericTypeComputed = 1 << 21, // IsGenericObjectType flag has been computed
|
||||
IsGenericTypeComputed = 1 << 22, // IsGenericObjectType flag has been computed
|
||||
/** @internal */
|
||||
IsGenericObjectType = 1 << 22, // Union or intersection contains generic object type
|
||||
IsGenericObjectType = 1 << 23, // Union or intersection contains generic object type
|
||||
/** @internal */
|
||||
IsGenericIndexType = 1 << 23, // Union or intersection contains generic index type
|
||||
IsGenericIndexType = 1 << 24, // Union or intersection contains generic index type
|
||||
/** @internal */
|
||||
IsGenericType = IsGenericObjectType | IsGenericIndexType,
|
||||
|
||||
// Flags that require TypeFlags.Union
|
||||
/** @internal */
|
||||
ContainsIntersections = 1 << 24, // Union contains intersections
|
||||
ContainsIntersections = 1 << 25, // Union contains intersections
|
||||
/** @internal */
|
||||
IsUnknownLikeUnionComputed = 1 << 25, // IsUnknownLikeUnion flag has been computed
|
||||
IsUnknownLikeUnionComputed = 1 << 26, // IsUnknownLikeUnion flag has been computed
|
||||
/** @internal */
|
||||
IsUnknownLikeUnion = 1 << 26, // Union of null, undefined, and empty object type
|
||||
IsUnknownLikeUnion = 1 << 27, // Union of null, undefined, and empty object type
|
||||
/** @internal */
|
||||
|
||||
// Flags that require TypeFlags.Intersection
|
||||
/** @internal */
|
||||
IsNeverIntersectionComputed = 1 << 24, // IsNeverLike flag has been computed
|
||||
IsNeverIntersectionComputed = 1 << 25, // IsNeverLike flag has been computed
|
||||
/** @internal */
|
||||
IsNeverIntersection = 1 << 25, // Intersection reduces to never
|
||||
IsNeverIntersection = 1 << 26, // Intersection reduces to never
|
||||
/** @internal */
|
||||
IsConstrainedTypeVariable = 1 << 26, // T & C, where T's constraint and C are primitives, object, or {}
|
||||
IsConstrainedTypeVariable = 1 << 27, // T & C, where T's constraint and C are primitives, object, or {}
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
@@ -6544,6 +6545,13 @@ export interface MappedType extends AnonymousType {
|
||||
containsError?: boolean;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export interface TypeAliasInstantiationType extends AnonymousType {
|
||||
typeAlias: Symbol; // Type alias symbol
|
||||
node: NodeWithTypeArguments; // Type alias instantiation node
|
||||
resolvedType?: ObjectType; // Resolved type alias instantiation
|
||||
}
|
||||
|
||||
export interface EvolvingArrayType extends ObjectType {
|
||||
elementType: Type; // Element expressions of evolving array type
|
||||
finalArrayType?: Type; // Final array type of evolving array type
|
||||
|
||||
Reference in New Issue
Block a user