mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Reduce intersections by discriminants (#36696)
* Treat never-like intersections as never * Accept new baselines * Fix compiler issues revealed by increased intersection correctness * Delete fourslash tests that are no longer applicable * Include isNeverLikeIntersection check in getNormalizedType * Erase never-like types in several more places * Check that base types are not never-like * Add comments * Revert isNeverLikeType check in getIndexType (keyof shouldn't resolve member types) * Introduce getReducedType for union and intersection types * Don't reduce in getApparentType * Avoid relationship check in resolveMappedTypeMembers * Accept new baselines * Don't call getReducedType in getIndexType * Ensure reduced and unreduced forms of a type can compare identical * Reduce types before converting them to string representation * Accept new baselines * Reduce intersections before obtaining keyof X * Add tests * Accept new baselines * Fix comment in tests * Don't infer from empty intersection types * Add tests * Accept new baselines * Defer instantiation of mapped type property types * Accept new baselines * Include more precise type in diagnostic * Accept new baselines * Minor optimization * Improve error message * Optional properties in intersections are never discriminants
This commit is contained in:
+113
-37
@@ -4077,6 +4077,8 @@ namespace ts {
|
||||
return undefined!; // TODO: GH#18217
|
||||
}
|
||||
|
||||
type = getReducedType(type);
|
||||
|
||||
if (type.flags & TypeFlags.Any) {
|
||||
context.approximateLength += 3;
|
||||
return createKeywordTypeNode(SyntaxKind.AnyKeyword);
|
||||
@@ -7145,6 +7147,7 @@ namespace ts {
|
||||
let type: Type | undefined;
|
||||
if (pattern.kind === SyntaxKind.ObjectBindingPattern) {
|
||||
if (declaration.dotDotDotToken) {
|
||||
parentType = getReducedType(parentType);
|
||||
if (parentType.flags & TypeFlags.Unknown || !isValidSpreadType(parentType)) {
|
||||
error(declaration, Diagnostics.Rest_types_may_only_be_created_from_object_types);
|
||||
return errorType;
|
||||
@@ -8022,13 +8025,17 @@ namespace ts {
|
||||
}
|
||||
|
||||
function getTypeOfSymbol(symbol: Symbol): Type {
|
||||
if (getCheckFlags(symbol) & CheckFlags.DeferredType) {
|
||||
const checkFlags = getCheckFlags(symbol);
|
||||
if (checkFlags & CheckFlags.DeferredType) {
|
||||
return getTypeOfSymbolWithDeferredType(symbol);
|
||||
}
|
||||
if (getCheckFlags(symbol) & CheckFlags.Instantiated) {
|
||||
if (checkFlags & CheckFlags.Instantiated) {
|
||||
return getTypeOfInstantiatedSymbol(symbol);
|
||||
}
|
||||
if (getCheckFlags(symbol) & CheckFlags.ReverseMapped) {
|
||||
if (checkFlags & CheckFlags.Mapped) {
|
||||
return getTypeOfMappedSymbol(symbol as MappedSymbol);
|
||||
}
|
||||
if (checkFlags & CheckFlags.ReverseMapped) {
|
||||
return getTypeOfReverseMappedSymbol(symbol as ReverseMappedSymbol);
|
||||
}
|
||||
if (symbol.flags & (SymbolFlags.Variable | SymbolFlags.Property)) {
|
||||
@@ -8329,7 +8336,7 @@ namespace ts {
|
||||
error(baseTypeNode.expression, Diagnostics.No_base_constructor_has_the_specified_number_of_type_arguments);
|
||||
return type.resolvedBaseTypes = emptyArray;
|
||||
}
|
||||
baseType = getReturnTypeOfSignature(constructors[0]);
|
||||
baseType = getReducedType(getReturnTypeOfSignature(constructors[0]));
|
||||
}
|
||||
|
||||
if (baseType === errorType) {
|
||||
@@ -8376,8 +8383,8 @@ namespace ts {
|
||||
}
|
||||
// TODO: Given that we allow type parmeters here now, is this `!isGenericMappedType(type)` check really needed?
|
||||
// There's no reason a `T` should be allowed while a `Readonly<T>` should not.
|
||||
return !!(type.flags & (TypeFlags.Object | TypeFlags.NonPrimitive | TypeFlags.Any)) && !isGenericMappedType(type) ||
|
||||
!!(type.flags & TypeFlags.Intersection) && every((<IntersectionType>type).types, isValidBaseType);
|
||||
return !!(type.flags & (TypeFlags.Object | TypeFlags.NonPrimitive | TypeFlags.Any) && !isGenericMappedType(type) ||
|
||||
type.flags & TypeFlags.Intersection && every((<IntersectionType>type).types, isValidBaseType));
|
||||
}
|
||||
|
||||
function resolveBaseTypesOfInterface(type: InterfaceType): void {
|
||||
@@ -8385,7 +8392,7 @@ namespace ts {
|
||||
for (const declaration of type.symbol.declarations) {
|
||||
if (declaration.kind === SyntaxKind.InterfaceDeclaration && getInterfaceBaseTypeNodes(<InterfaceDeclaration>declaration)) {
|
||||
for (const node of getInterfaceBaseTypeNodes(<InterfaceDeclaration>declaration)!) {
|
||||
const baseType = getTypeFromTypeNode(node);
|
||||
const baseType = getReducedType(getTypeFromTypeNode(node));
|
||||
if (baseType !== errorType) {
|
||||
if (isValidBaseType(baseType)) {
|
||||
if (type !== baseType && !hasBaseType(baseType, type)) {
|
||||
@@ -9619,7 +9626,6 @@ namespace ts {
|
||||
// mapped type is itself an instantiated type, combine the iteration mapper with the
|
||||
// instantiation mapper.
|
||||
const templateMapper = combineTypeMappers(type.mapper, createTypeMapper([typeParameter], [t]));
|
||||
const propType = instantiateType(templateType, templateMapper);
|
||||
// If the current iteration type constituent is a string literal type, create a property.
|
||||
// Otherwise, for type string create a string index signature.
|
||||
if (isTypeUsableAsPropertyName(t)) {
|
||||
@@ -9629,13 +9635,11 @@ namespace ts {
|
||||
!(templateModifiers & MappedTypeModifiers.ExcludeOptional) && modifiersProp && modifiersProp.flags & SymbolFlags.Optional);
|
||||
const isReadonly = !!(templateModifiers & MappedTypeModifiers.IncludeReadonly ||
|
||||
!(templateModifiers & MappedTypeModifiers.ExcludeReadonly) && modifiersProp && isReadonlySymbol(modifiersProp));
|
||||
const prop = createSymbol(SymbolFlags.Property | (isOptional ? SymbolFlags.Optional : 0), propName, isReadonly ? CheckFlags.Readonly : 0);
|
||||
// When creating an optional property in strictNullChecks mode, if 'undefined' isn't assignable to the
|
||||
// type, we include 'undefined' in the type. Similarly, when creating a non-optional property in strictNullChecks
|
||||
// mode, if the underlying property is optional we remove 'undefined' from the type.
|
||||
prop.type = strictNullChecks && isOptional && !maybeTypeOfKind(propType, TypeFlags.Undefined | TypeFlags.Void) ? getOptionalType(propType) :
|
||||
strictNullChecks && !isOptional && modifiersProp && modifiersProp.flags & SymbolFlags.Optional ? getTypeWithFacts(propType, TypeFacts.NEUndefined) :
|
||||
propType;
|
||||
const stripOptional = strictNullChecks && !isOptional && modifiersProp && modifiersProp.flags & SymbolFlags.Optional;
|
||||
const prop = <MappedSymbol>createSymbol(SymbolFlags.Property | (isOptional ? SymbolFlags.Optional : 0), propName,
|
||||
CheckFlags.Mapped | (isReadonly ? CheckFlags.Readonly : 0) | (stripOptional ? CheckFlags.StripOptional : 0));
|
||||
prop.mappedType = type;
|
||||
prop.mapper = templateMapper;
|
||||
if (modifiersProp) {
|
||||
prop.syntheticOrigin = modifiersProp;
|
||||
prop.declarations = modifiersProp.declarations;
|
||||
@@ -9643,16 +9647,41 @@ namespace ts {
|
||||
prop.nameType = t;
|
||||
members.set(propName, prop);
|
||||
}
|
||||
else if (t.flags & (TypeFlags.Any | TypeFlags.String)) {
|
||||
stringIndexInfo = createIndexInfo(propType, !!(templateModifiers & MappedTypeModifiers.IncludeReadonly));
|
||||
}
|
||||
else if (t.flags & (TypeFlags.Number | TypeFlags.Enum)) {
|
||||
numberIndexInfo = createIndexInfo(numberIndexInfo ? getUnionType([numberIndexInfo.type, propType]) : propType,
|
||||
!!(templateModifiers & MappedTypeModifiers.IncludeReadonly));
|
||||
else if (t.flags & (TypeFlags.Any | TypeFlags.String | TypeFlags.Number | TypeFlags.Enum)) {
|
||||
const propType = instantiateType(templateType, templateMapper);
|
||||
if (t.flags & (TypeFlags.Any | TypeFlags.String)) {
|
||||
stringIndexInfo = createIndexInfo(propType, !!(templateModifiers & MappedTypeModifiers.IncludeReadonly));
|
||||
}
|
||||
else {
|
||||
numberIndexInfo = createIndexInfo(numberIndexInfo ? getUnionType([numberIndexInfo.type, propType]) : propType,
|
||||
!!(templateModifiers & MappedTypeModifiers.IncludeReadonly));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getTypeOfMappedSymbol(symbol: MappedSymbol) {
|
||||
if (!symbol.type) {
|
||||
if (!pushTypeResolution(symbol, TypeSystemPropertyName.Type)) {
|
||||
return errorType;
|
||||
}
|
||||
const templateType = getTemplateTypeFromMappedType(<MappedType>symbol.mappedType.target || symbol.mappedType);
|
||||
const propType = instantiateType(templateType, symbol.mapper);
|
||||
// When creating an optional property in strictNullChecks mode, if 'undefined' isn't assignable to the
|
||||
// type, we include 'undefined' in the type. Similarly, when creating a non-optional property in strictNullChecks
|
||||
// mode, if the underlying property is optional we remove 'undefined' from the type.
|
||||
let type = strictNullChecks && symbol.flags & SymbolFlags.Optional && !maybeTypeOfKind(propType, TypeFlags.Undefined | TypeFlags.Void) ? getOptionalType(propType) :
|
||||
symbol.checkFlags & CheckFlags.StripOptional ? getTypeWithFacts(propType, TypeFacts.NEUndefined) :
|
||||
propType;
|
||||
if (!popTypeResolution()) {
|
||||
error(currentNode, Diagnostics.Type_of_property_0_circularly_references_itself_in_mapped_type_1, symbolToString(symbol), typeToString(symbol.mappedType));
|
||||
type = errorType;
|
||||
}
|
||||
symbol.type = type;
|
||||
}
|
||||
return symbol.type;
|
||||
}
|
||||
|
||||
function getTypeParameterFromMappedType(type: MappedType) {
|
||||
return type.typeParameter ||
|
||||
(type.typeParameter = getDeclaredTypeOfTypeParameter(getSymbolOfNode(type.declaration.typeParameter)));
|
||||
@@ -9800,7 +9829,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function getPropertiesOfType(type: Type): Symbol[] {
|
||||
type = getApparentType(type);
|
||||
type = getApparentType(getReducedType(type));
|
||||
return type.flags & TypeFlags.UnionOrIntersection ?
|
||||
getPropertiesOfUnionOrIntersectionType(<UnionType>type) :
|
||||
getPropertiesOfObjectType(type);
|
||||
@@ -10141,7 +10170,7 @@ namespace ts {
|
||||
/**
|
||||
* For a type parameter, return the base constraint of the type parameter. For the string, number,
|
||||
* boolean, and symbol primitive types, return the corresponding object types. Otherwise return the
|
||||
* type itself. Note that the apparent type of a union type is the union type itself.
|
||||
* type itself.
|
||||
*/
|
||||
function getApparentType(type: Type): Type {
|
||||
const t = type.flags & TypeFlags.Instantiable ? getBaseConstraintOfType(type) || unknownType : type;
|
||||
@@ -10169,7 +10198,7 @@ namespace ts {
|
||||
let checkFlags = 0;
|
||||
for (const current of containingType.types) {
|
||||
const type = getApparentType(current);
|
||||
if (type !== errorType) {
|
||||
if (!(type === errorType || type.flags & TypeFlags.Never)) {
|
||||
const prop = getPropertyOfType(type, name);
|
||||
const modifiers = prop ? getDeclarationModifierFlagsFromSymbol(prop) : 0;
|
||||
if (prop && !(modifiers & excludeModifiers)) {
|
||||
@@ -10240,6 +10269,9 @@ namespace ts {
|
||||
if (isLiteralType(type)) {
|
||||
checkFlags |= CheckFlags.HasLiteralType;
|
||||
}
|
||||
if (type.flags & TypeFlags.Never) {
|
||||
checkFlags |= CheckFlags.HasNeverType;
|
||||
}
|
||||
propTypes.push(type);
|
||||
}
|
||||
addRange(propTypes, indexTypes);
|
||||
@@ -10291,6 +10323,44 @@ namespace ts {
|
||||
return property && !(getCheckFlags(property) & CheckFlags.ReadPartial) ? property : undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* no constituent property has type 'never', but the intersection of the constituent property types is 'never'.
|
||||
*/
|
||||
function getReducedType(type: Type): Type {
|
||||
if (type.flags & TypeFlags.Union && (<UnionType>type).objectFlags & ObjectFlags.ContainsIntersections) {
|
||||
return (<UnionType>type).resolvedReducedType || ((<UnionType>type).resolvedReducedType = getReducedUnionType(<UnionType>type));
|
||||
}
|
||||
else if (type.flags & TypeFlags.Intersection) {
|
||||
if (!((<IntersectionType>type).objectFlags & ObjectFlags.IsNeverIntersectionComputed)) {
|
||||
(<IntersectionType>type).objectFlags |= ObjectFlags.IsNeverIntersectionComputed |
|
||||
(some(getPropertiesOfUnionOrIntersectionType(<IntersectionType>type), isDiscriminantWithNeverType) ? ObjectFlags.IsNeverIntersection : 0);
|
||||
}
|
||||
return (<IntersectionType>type).objectFlags & ObjectFlags.IsNeverIntersection ? neverType : type;
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
function getReducedUnionType(unionType: UnionType) {
|
||||
const reducedTypes = sameMap(unionType.types, getReducedType);
|
||||
if (reducedTypes === unionType.types) {
|
||||
return unionType;
|
||||
}
|
||||
const reduced = getUnionType(reducedTypes);
|
||||
if (reduced.flags & TypeFlags.Union) {
|
||||
(<UnionType>reduced).resolvedReducedType = reduced;
|
||||
}
|
||||
return reduced;
|
||||
}
|
||||
|
||||
function isDiscriminantWithNeverType(prop: Symbol) {
|
||||
return !(prop.flags & SymbolFlags.Optional) &&
|
||||
(getCheckFlags(prop) & (CheckFlags.Discriminant | CheckFlags.HasNeverType)) === CheckFlags.Discriminant &&
|
||||
!!(getTypeOfSymbol(prop).flags & TypeFlags.Never);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the symbol for the property with the given name in the given type. Creates synthetic union properties when
|
||||
* necessary, maps primitive types and type parameters are to their apparent types, and augments with properties from
|
||||
@@ -10300,7 +10370,7 @@ namespace ts {
|
||||
* @param name a name of property to look up in a given type
|
||||
*/
|
||||
function getPropertyOfType(type: Type, name: __String): Symbol | undefined {
|
||||
type = getApparentType(type);
|
||||
type = getApparentType(getReducedType(type));
|
||||
if (type.flags & TypeFlags.Object) {
|
||||
const resolved = resolveStructuredTypeMembers(<ObjectType>type);
|
||||
const symbol = resolved.members.get(name);
|
||||
@@ -10338,7 +10408,7 @@ namespace ts {
|
||||
* maps primitive types and type parameters are to their apparent types.
|
||||
*/
|
||||
function getSignaturesOfType(type: Type, kind: SignatureKind): readonly Signature[] {
|
||||
return getSignaturesOfStructuredType(getApparentType(type), kind);
|
||||
return getSignaturesOfStructuredType(getApparentType(getReducedType(type)), kind);
|
||||
}
|
||||
|
||||
function getIndexInfoOfStructuredType(type: Type, kind: IndexKind): IndexInfo | undefined {
|
||||
@@ -10356,13 +10426,13 @@ namespace ts {
|
||||
// Return the indexing info of the given kind in the given type. Creates synthetic union index types when necessary and
|
||||
// maps primitive types and type parameters are to their apparent types.
|
||||
function getIndexInfoOfType(type: Type, kind: IndexKind): IndexInfo | undefined {
|
||||
return getIndexInfoOfStructuredType(getApparentType(type), kind);
|
||||
return getIndexInfoOfStructuredType(getApparentType(getReducedType(type)), kind);
|
||||
}
|
||||
|
||||
// Return the index type of the given kind in the given type. Creates synthetic union index types when necessary and
|
||||
// maps primitive types and type parameters are to their apparent types.
|
||||
function getIndexTypeOfType(type: Type, kind: IndexKind): Type | undefined {
|
||||
return getIndexTypeOfStructuredType(getApparentType(type), kind);
|
||||
return getIndexTypeOfStructuredType(getApparentType(getReducedType(type)), kind);
|
||||
}
|
||||
|
||||
function getImplicitIndexTypeOfType(type: Type, kind: IndexKind): Type | undefined {
|
||||
@@ -11932,7 +12002,9 @@ namespace ts {
|
||||
neverType;
|
||||
}
|
||||
}
|
||||
return getUnionTypeFromSortedList(typeSet, includes & TypeFlags.NotPrimitiveUnion ? 0 : ObjectFlags.PrimitiveUnion, aliasSymbol, aliasTypeArguments);
|
||||
const objectFlags = (includes & TypeFlags.NotPrimitiveUnion ? 0 : ObjectFlags.PrimitiveUnion) |
|
||||
(includes & TypeFlags.Intersection ? ObjectFlags.ContainsIntersections : 0);
|
||||
return getUnionTypeFromSortedList(typeSet, objectFlags, aliasSymbol, aliasTypeArguments);
|
||||
}
|
||||
|
||||
function getUnionTypePredicate(signatures: readonly Signature[]): TypePredicate | undefined {
|
||||
@@ -12300,6 +12372,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function getIndexType(type: Type, stringsOnly = keyofStringsOnly, noIndexSignatures?: boolean): Type {
|
||||
type = getReducedType(type);
|
||||
return type.flags & TypeFlags.Union ? getIntersectionType(map((<IntersectionType>type).types, t => getIndexType(t, stringsOnly, noIndexSignatures))) :
|
||||
type.flags & TypeFlags.Intersection ? getUnionType(map((<IntersectionType>type).types, t => getIndexType(t, stringsOnly, noIndexSignatures))) :
|
||||
maybeTypeOfKind(type, TypeFlags.InstantiableNonPrimitive) ? getIndexTypeForGenericType(<InstantiableType | UnionOrIntersectionType>type, stringsOnly) :
|
||||
@@ -12716,7 +12789,7 @@ namespace ts {
|
||||
// In the following we resolve T[K] to the type of the property in T selected by K.
|
||||
// We treat boolean as different from other unions to improve errors;
|
||||
// skipping straight to getPropertyTypeForIndexType gives errors with 'boolean' instead of 'true'.
|
||||
const apparentObjectType = getApparentType(objectType);
|
||||
const apparentObjectType = getApparentType(getReducedType(objectType));
|
||||
if (indexType.flags & TypeFlags.Union && !(indexType.flags & TypeFlags.Boolean)) {
|
||||
const propTypes: Type[] = [];
|
||||
let wasMissingProp = false;
|
||||
@@ -13697,7 +13770,7 @@ namespace ts {
|
||||
if (typeVariable) {
|
||||
const mappedTypeVariable = instantiateType(typeVariable, mapper);
|
||||
if (typeVariable !== mappedTypeVariable) {
|
||||
return mapType(mappedTypeVariable, t => {
|
||||
return mapType(getReducedType(mappedTypeVariable), t => {
|
||||
if (t.flags & (TypeFlags.AnyOrUnknown | TypeFlags.InstantiableNonPrimitive | TypeFlags.Object | TypeFlags.Intersection) && t !== wildcardType && t !== errorType) {
|
||||
const replacementMapper = createReplacementMapper(typeVariable, t, mapper);
|
||||
return isArrayType(t) ? instantiateMappedArrayType(t, type, replacementMapper) :
|
||||
@@ -14849,7 +14922,8 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!(source.flags === target.flags && source.flags & TypeFlags.Substructure)) return false;
|
||||
if (!(source.flags & TypeFlags.UnionOrIntersection) && !(target.flags & TypeFlags.UnionOrIntersection) &&
|
||||
source.flags !== target.flags && !(source.flags & TypeFlags.Substructure)) return false;
|
||||
}
|
||||
if (source.flags & TypeFlags.Object && target.flags & TypeFlags.Object) {
|
||||
const related = relation.get(getRelationKey(source, target, IntersectionState.None, relation));
|
||||
@@ -14868,15 +14942,16 @@ namespace ts {
|
||||
}
|
||||
|
||||
function getNormalizedType(type: Type, writing: boolean): Type {
|
||||
do {
|
||||
while (true) {
|
||||
const t = isFreshLiteralType(type) ? (<FreshableType>type).regularType :
|
||||
getObjectFlags(type) & ObjectFlags.Reference && (<TypeReference>type).node ? createTypeReference((<TypeReference>type).target, getTypeArguments(<TypeReference>type)) :
|
||||
type.flags & TypeFlags.UnionOrIntersection ? getReducedType(type) :
|
||||
type.flags & TypeFlags.Substitution ? writing ? (<SubstitutionType>type).typeVariable : (<SubstitutionType>type).substitute :
|
||||
type.flags & TypeFlags.Simplifiable ? getSimplifiedType(type, writing) :
|
||||
type;
|
||||
if (t === type) break;
|
||||
type = t;
|
||||
} while (true);
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
@@ -18164,6 +18239,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
else {
|
||||
source = getReducedType(source);
|
||||
if (!(priority & InferencePriority.NoConstraints && source.flags & (TypeFlags.Intersection | TypeFlags.Instantiable))) {
|
||||
const apparentSource = getApparentType(source);
|
||||
// getApparentType can return _any_ type, since an indexed access or conditional may simplify to any other type.
|
||||
@@ -22584,7 +22660,7 @@ namespace ts {
|
||||
hasComputedStringProperty = false;
|
||||
hasComputedNumberProperty = false;
|
||||
}
|
||||
const type = checkExpression(memberDecl.expression);
|
||||
const type = getReducedType(checkExpression(memberDecl.expression));
|
||||
if (!isValidSpreadType(type)) {
|
||||
error(memberDecl, Diagnostics.Spread_types_may_only_be_created_from_object_types);
|
||||
return errorType;
|
||||
@@ -22792,7 +22868,7 @@ namespace ts {
|
||||
spread = getSpreadType(spread, createJsxAttributesType(), attributes.symbol, objectFlags, /*readonly*/ false);
|
||||
attributesTable = createSymbolTable();
|
||||
}
|
||||
const exprType = checkExpressionCached(attributeDecl.expression, checkMode);
|
||||
const exprType = getReducedType(checkExpressionCached(attributeDecl.expression, checkMode));
|
||||
if (isTypeAny(exprType)) {
|
||||
hasSpreadAnyType = true;
|
||||
}
|
||||
@@ -32676,7 +32752,7 @@ namespace ts {
|
||||
}
|
||||
checkTypeReferenceNode(typeRefNode);
|
||||
if (produceDiagnostics) {
|
||||
const t = getTypeFromTypeNode(typeRefNode);
|
||||
const t = getReducedType(getTypeFromTypeNode(typeRefNode));
|
||||
if (t !== errorType) {
|
||||
if (isValidBaseType(t)) {
|
||||
const genericDiag = t.symbol && t.symbol.flags & SymbolFlags.Class ?
|
||||
|
||||
@@ -2365,6 +2365,10 @@
|
||||
"category": "Error",
|
||||
"code": 2614
|
||||
},
|
||||
"Type of property '{0}' circularly references itself in mapped type '{1}'.": {
|
||||
"category": "Error",
|
||||
"code": 2615
|
||||
},
|
||||
|
||||
"Cannot augment module '{0}' with value exports because it resolves to a non-module entity.": {
|
||||
"category": "Error",
|
||||
|
||||
@@ -1795,9 +1795,7 @@ namespace ts {
|
||||
|
||||
const target = getTargetOfBindingOrAssignmentElement(bindingElement);
|
||||
if (target && isPropertyName(target)) {
|
||||
return isComputedPropertyName(target) && isStringOrNumericLiteral(target.expression)
|
||||
? target.expression
|
||||
: target;
|
||||
return target;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -976,7 +976,7 @@ namespace ts {
|
||||
);
|
||||
}
|
||||
|
||||
function visitArrayAssignmentTarget(node: AssignmentPattern) {
|
||||
function visitArrayAssignmentTarget(node: BindingOrAssignmentElement) {
|
||||
const target = getTargetOfBindingOrAssignmentElement(node);
|
||||
if (target && isPrivateIdentifierPropertyAccessExpression(target)) {
|
||||
const wrapped = wrapPrivateIdentifierForDestructuringTarget(target);
|
||||
|
||||
+21
-4
@@ -4155,6 +4155,9 @@ namespace ts {
|
||||
OptionalParameter = 1 << 14, // Optional parameter
|
||||
RestParameter = 1 << 15, // Rest parameter
|
||||
DeferredType = 1 << 16, // Calculation of the type of this symbol is deferred due to processing costs, should be fetched with `getTypeOfSymbolWithDeferredType`
|
||||
HasNeverType = 1 << 17, // Synthetic property with at least one never type in constituents
|
||||
Mapped = 1 << 18, // Property of mapped type
|
||||
StripOptional = 1 << 19, // Strip optionality in mapped property
|
||||
Synthetic = SyntheticProperty | SyntheticMethod,
|
||||
Discriminant = HasNonUniformType | HasLiteralType,
|
||||
Partial = ReadPartial | WritePartial
|
||||
@@ -4165,6 +4168,12 @@ namespace ts {
|
||||
checkFlags: CheckFlags;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export interface MappedSymbol extends TransientSymbol {
|
||||
mappedType: MappedType;
|
||||
mapper: TypeMapper;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export interface ReverseMappedSymbol extends TransientSymbol {
|
||||
propertyType: Type;
|
||||
@@ -4362,16 +4371,16 @@ namespace ts {
|
||||
NotPrimitiveUnion = Any | Unknown | Enum | Void | Never | StructuredOrInstantiable,
|
||||
// The following flags are aggregated during union and intersection type construction
|
||||
/* @internal */
|
||||
IncludesMask = Any | Unknown | Primitive | Never | Object | Union | NonPrimitive,
|
||||
IncludesMask = Any | Unknown | Primitive | Never | Object | Union | Intersection | NonPrimitive,
|
||||
// The following flags are used for different purposes during union and intersection type construction
|
||||
/* @internal */
|
||||
IncludesStructuredOrInstantiable = TypeParameter,
|
||||
/* @internal */
|
||||
IncludesNonWideningType = Intersection,
|
||||
IncludesNonWideningType = Index,
|
||||
/* @internal */
|
||||
IncludesWildcard = Index,
|
||||
IncludesWildcard = IndexedAccess,
|
||||
/* @internal */
|
||||
IncludesEmptyObject = IndexedAccess,
|
||||
IncludesEmptyObject = Conditional,
|
||||
}
|
||||
|
||||
export type DestructuringPattern = BindingPattern | ObjectLiteralExpression | ArrayLiteralExpression;
|
||||
@@ -4487,6 +4496,12 @@ namespace ts {
|
||||
CouldContainTypeVariablesComputed = 1 << 26, // CouldContainTypeVariables flag has been computed
|
||||
/* @internal */
|
||||
CouldContainTypeVariables = 1 << 27, // Type could contain a type variable
|
||||
/* @internal */
|
||||
ContainsIntersections = 1 << 28, // Union contains intersections
|
||||
/* @internal */
|
||||
IsNeverIntersectionComputed = 1 << 28, // IsNeverLike flag has been computed
|
||||
/* @internal */
|
||||
IsNeverIntersection = 1 << 29, // Intersection reduces to never
|
||||
ClassOrInterface = Class | Interface,
|
||||
/* @internal */
|
||||
RequiresWidening = ContainsWideningType | ContainsObjectOrArrayLiteral,
|
||||
@@ -4608,6 +4623,8 @@ namespace ts {
|
||||
}
|
||||
|
||||
export interface UnionType extends UnionOrIntersectionType {
|
||||
/* @internal */
|
||||
resolvedReducedType: Type;
|
||||
}
|
||||
|
||||
export interface IntersectionType extends UnionOrIntersectionType {
|
||||
|
||||
Reference in New Issue
Block a user