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 {
|
||||
|
||||
@@ -2,10 +2,9 @@ tests/cases/conformance/types/union/discriminatedUnionTypes2.ts(27,30): error TS
|
||||
Object literal may only specify known properties, and 'c' does not exist in type '{ a: null; b: string; }'.
|
||||
tests/cases/conformance/types/union/discriminatedUnionTypes2.ts(32,11): error TS2339: Property 'b' does not exist on type '{ a: 0; b: string; } | { a: T; c: number; }'.
|
||||
Property 'b' does not exist on type '{ a: T; c: number; }'.
|
||||
tests/cases/conformance/types/union/discriminatedUnionTypes2.ts(132,11): error TS2339: Property 'value' does not exist on type 'never'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/types/union/discriminatedUnionTypes2.ts (3 errors) ====
|
||||
==== tests/cases/conformance/types/union/discriminatedUnionTypes2.ts (2 errors) ====
|
||||
function f10(x : { kind: false, a: string } | { kind: true, b: string } | { kind: string, c: string }) {
|
||||
if (x.kind === false) {
|
||||
x.a;
|
||||
@@ -143,9 +142,7 @@ tests/cases/conformance/types/union/discriminatedUnionTypes2.ts(132,11): error T
|
||||
x.value; // number
|
||||
}
|
||||
else {
|
||||
x.value; // Error, x is never
|
||||
~~~~~
|
||||
!!! error TS2339: Property 'value' does not exist on type 'never'.
|
||||
x.value; // number
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -130,7 +130,7 @@ function foo1(x: RuntimeValue & { type: 'number' }) {
|
||||
x.value; // number
|
||||
}
|
||||
else {
|
||||
x.value; // Error, x is never
|
||||
x.value; // number
|
||||
}
|
||||
}
|
||||
|
||||
@@ -226,7 +226,7 @@ function foo1(x) {
|
||||
x.value; // number
|
||||
}
|
||||
else {
|
||||
x.value; // Error, x is never
|
||||
x.value; // number
|
||||
}
|
||||
}
|
||||
function foo2(x) {
|
||||
|
||||
@@ -317,9 +317,9 @@ function f(problem: abc & (b | c)) {
|
||||
>c : Symbol(c, Decl(discriminatedUnionTypes2.ts, 104, 1))
|
||||
|
||||
if (problem.type === 'b') {
|
||||
>problem.type : Symbol(type, Decl(discriminatedUnionTypes2.ts, 101, 10), Decl(discriminatedUnionTypes2.ts, 105, 10), Decl(discriminatedUnionTypes2.ts, 97, 10), Decl(discriminatedUnionTypes2.ts, 101, 10), Decl(discriminatedUnionTypes2.ts, 97, 10) ... and 5 more)
|
||||
>problem.type : Symbol(type, Decl(discriminatedUnionTypes2.ts, 101, 10), Decl(discriminatedUnionTypes2.ts, 105, 10))
|
||||
>problem : Symbol(problem, Decl(discriminatedUnionTypes2.ts, 112, 11))
|
||||
>type : Symbol(type, Decl(discriminatedUnionTypes2.ts, 101, 10), Decl(discriminatedUnionTypes2.ts, 105, 10), Decl(discriminatedUnionTypes2.ts, 97, 10), Decl(discriminatedUnionTypes2.ts, 101, 10), Decl(discriminatedUnionTypes2.ts, 97, 10) ... and 5 more)
|
||||
>type : Symbol(type, Decl(discriminatedUnionTypes2.ts, 101, 10), Decl(discriminatedUnionTypes2.ts, 105, 10))
|
||||
|
||||
problem.name;
|
||||
>problem.name : Symbol(name, Decl(discriminatedUnionTypes2.ts, 102, 14))
|
||||
@@ -356,9 +356,9 @@ function foo1(x: RuntimeValue & { type: 'number' }) {
|
||||
>type : Symbol(type, Decl(discriminatedUnionTypes2.ts, 126, 33))
|
||||
|
||||
if (x.type === 'number') {
|
||||
>x.type : Symbol(type, Decl(discriminatedUnionTypes2.ts, 122, 7), Decl(discriminatedUnionTypes2.ts, 126, 33), Decl(discriminatedUnionTypes2.ts, 123, 7), Decl(discriminatedUnionTypes2.ts, 126, 33), Decl(discriminatedUnionTypes2.ts, 124, 7) ... and 1 more)
|
||||
>x.type : Symbol(type, Decl(discriminatedUnionTypes2.ts, 122, 7), Decl(discriminatedUnionTypes2.ts, 126, 33))
|
||||
>x : Symbol(x, Decl(discriminatedUnionTypes2.ts, 126, 14))
|
||||
>type : Symbol(type, Decl(discriminatedUnionTypes2.ts, 122, 7), Decl(discriminatedUnionTypes2.ts, 126, 33), Decl(discriminatedUnionTypes2.ts, 123, 7), Decl(discriminatedUnionTypes2.ts, 126, 33), Decl(discriminatedUnionTypes2.ts, 124, 7) ... and 1 more)
|
||||
>type : Symbol(type, Decl(discriminatedUnionTypes2.ts, 122, 7), Decl(discriminatedUnionTypes2.ts, 126, 33))
|
||||
|
||||
x.value; // number
|
||||
>x.value : Symbol(value, Decl(discriminatedUnionTypes2.ts, 122, 23))
|
||||
@@ -366,8 +366,10 @@ function foo1(x: RuntimeValue & { type: 'number' }) {
|
||||
>value : Symbol(value, Decl(discriminatedUnionTypes2.ts, 122, 23))
|
||||
}
|
||||
else {
|
||||
x.value; // Error, x is never
|
||||
x.value; // number
|
||||
>x.value : Symbol(value, Decl(discriminatedUnionTypes2.ts, 122, 23))
|
||||
>x : Symbol(x, Decl(discriminatedUnionTypes2.ts, 126, 14))
|
||||
>value : Symbol(value, Decl(discriminatedUnionTypes2.ts, 122, 23))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -379,9 +381,9 @@ function foo2(x: RuntimeValue & ({ type: 'number' } | { type: 'string' })) {
|
||||
>type : Symbol(type, Decl(discriminatedUnionTypes2.ts, 135, 55))
|
||||
|
||||
if (x.type === 'number') {
|
||||
>x.type : Symbol(type, Decl(discriminatedUnionTypes2.ts, 122, 7), Decl(discriminatedUnionTypes2.ts, 135, 34), Decl(discriminatedUnionTypes2.ts, 122, 7), Decl(discriminatedUnionTypes2.ts, 135, 55), Decl(discriminatedUnionTypes2.ts, 123, 7) ... and 7 more)
|
||||
>x.type : Symbol(type, Decl(discriminatedUnionTypes2.ts, 122, 7), Decl(discriminatedUnionTypes2.ts, 135, 34), Decl(discriminatedUnionTypes2.ts, 123, 7), Decl(discriminatedUnionTypes2.ts, 135, 55))
|
||||
>x : Symbol(x, Decl(discriminatedUnionTypes2.ts, 135, 14))
|
||||
>type : Symbol(type, Decl(discriminatedUnionTypes2.ts, 122, 7), Decl(discriminatedUnionTypes2.ts, 135, 34), Decl(discriminatedUnionTypes2.ts, 122, 7), Decl(discriminatedUnionTypes2.ts, 135, 55), Decl(discriminatedUnionTypes2.ts, 123, 7) ... and 7 more)
|
||||
>type : Symbol(type, Decl(discriminatedUnionTypes2.ts, 122, 7), Decl(discriminatedUnionTypes2.ts, 135, 34), Decl(discriminatedUnionTypes2.ts, 123, 7), Decl(discriminatedUnionTypes2.ts, 135, 55))
|
||||
|
||||
x.value; // number
|
||||
>x.value : Symbol(value, Decl(discriminatedUnionTypes2.ts, 122, 23))
|
||||
|
||||
@@ -323,13 +323,13 @@ type abc = a | b | c;
|
||||
>abc : abc
|
||||
|
||||
function f(problem: abc & (b | c)) {
|
||||
>f : (problem: b | c | (a & b) | (a & c) | (b & c) | (c & b)) => void
|
||||
>problem : b | c | (a & b) | (a & c) | (b & c) | (c & b)
|
||||
>f : (problem: b | c) => void
|
||||
>problem : b | c
|
||||
|
||||
if (problem.type === 'b') {
|
||||
>problem.type === 'b' : boolean
|
||||
>problem.type : "b" | "c"
|
||||
>problem : b | c | (a & b) | (a & c) | (b & c) | (c & b)
|
||||
>problem : b | c
|
||||
>type : "b" | "c"
|
||||
>'b' : "b"
|
||||
|
||||
@@ -362,14 +362,14 @@ type RuntimeValue =
|
||||
>value : boolean
|
||||
|
||||
function foo1(x: RuntimeValue & { type: 'number' }) {
|
||||
>foo1 : (x: ({ type: "number"; value: number; } & { type: "number"; }) | ({ type: "string"; value: string; } & { type: "number"; }) | ({ type: "boolean"; value: boolean; } & { type: "number"; })) => void
|
||||
>x : ({ type: "number"; value: number; } & { type: "number"; }) | ({ type: "string"; value: string; } & { type: "number"; }) | ({ type: "boolean"; value: boolean; } & { type: "number"; })
|
||||
>foo1 : (x: { type: "number"; value: number; } & { type: "number"; }) => void
|
||||
>x : { type: "number"; value: number; } & { type: "number"; }
|
||||
>type : "number"
|
||||
|
||||
if (x.type === 'number') {
|
||||
>x.type === 'number' : boolean
|
||||
>x.type : "number"
|
||||
>x : ({ type: "number"; value: number; } & { type: "number"; }) | ({ type: "string"; value: string; } & { type: "number"; }) | ({ type: "boolean"; value: boolean; } & { type: "number"; })
|
||||
>x : { type: "number"; value: number; } & { type: "number"; }
|
||||
>type : "number"
|
||||
>'number' : "number"
|
||||
|
||||
@@ -379,23 +379,23 @@ function foo1(x: RuntimeValue & { type: 'number' }) {
|
||||
>value : number
|
||||
}
|
||||
else {
|
||||
x.value; // Error, x is never
|
||||
>x.value : any
|
||||
>x : never
|
||||
>value : any
|
||||
x.value; // number
|
||||
>x.value : number
|
||||
>x : { type: "number"; value: number; } & { type: "number"; }
|
||||
>value : number
|
||||
}
|
||||
}
|
||||
|
||||
function foo2(x: RuntimeValue & ({ type: 'number' } | { type: 'string' })) {
|
||||
>foo2 : (x: ({ type: "number"; value: number; } & { type: "number"; }) | ({ type: "number"; value: number; } & { type: "string"; }) | ({ type: "string"; value: string; } & { type: "number"; }) | ({ type: "string"; value: string; } & { type: "string"; }) | ({ type: "boolean"; value: boolean; } & { type: "number"; }) | ({ type: "boolean"; value: boolean; } & { type: "string"; })) => void
|
||||
>x : ({ type: "number"; value: number; } & { type: "number"; }) | ({ type: "number"; value: number; } & { type: "string"; }) | ({ type: "string"; value: string; } & { type: "number"; }) | ({ type: "string"; value: string; } & { type: "string"; }) | ({ type: "boolean"; value: boolean; } & { type: "number"; }) | ({ type: "boolean"; value: boolean; } & { type: "string"; })
|
||||
>foo2 : (x: ({ type: "number"; value: number; } & { type: "number"; }) | ({ type: "string"; value: string; } & { type: "string"; })) => void
|
||||
>x : ({ type: "number"; value: number; } & { type: "number"; }) | ({ type: "string"; value: string; } & { type: "string"; })
|
||||
>type : "number"
|
||||
>type : "string"
|
||||
|
||||
if (x.type === 'number') {
|
||||
>x.type === 'number' : boolean
|
||||
>x.type : "string" | "number"
|
||||
>x : ({ type: "number"; value: number; } & { type: "number"; }) | ({ type: "number"; value: number; } & { type: "string"; }) | ({ type: "string"; value: string; } & { type: "number"; }) | ({ type: "string"; value: string; } & { type: "string"; }) | ({ type: "boolean"; value: boolean; } & { type: "number"; }) | ({ type: "boolean"; value: boolean; } & { type: "string"; })
|
||||
>x : ({ type: "number"; value: number; } & { type: "number"; }) | ({ type: "string"; value: string; } & { type: "string"; })
|
||||
>type : "string" | "number"
|
||||
>'number' : "number"
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
tests/cases/conformance/types/intersection/intersectionReduction.ts(40,1): error TS2322: Type 'any' is not assignable to type 'never'.
|
||||
tests/cases/conformance/types/intersection/intersectionReduction.ts(41,1): error TS2322: Type 'any' is not assignable to type 'never'.
|
||||
tests/cases/conformance/types/intersection/intersectionReduction.ts(38,4): error TS2339: Property 'kind' does not exist on type 'never'.
|
||||
tests/cases/conformance/types/intersection/intersectionReduction.ts(80,1): error TS2322: Type 'any' is not assignable to type 'never'.
|
||||
tests/cases/conformance/types/intersection/intersectionReduction.ts(81,1): error TS2322: Type 'any' is not assignable to type 'never'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/types/intersection/intersectionReduction.ts (2 errors) ====
|
||||
==== tests/cases/conformance/types/intersection/intersectionReduction.ts (3 errors) ====
|
||||
declare const sym1: unique symbol;
|
||||
declare const sym2: unique symbol;
|
||||
|
||||
@@ -35,6 +36,48 @@ tests/cases/conformance/types/intersection/intersectionReduction.ts(41,1): error
|
||||
type X6 = X | symbol & string;
|
||||
type X7 = X | void & string;
|
||||
|
||||
type A = { kind: 'a', foo: string };
|
||||
type B = { kind: 'b', foo: number };
|
||||
type C = { kind: 'c', foo: number };
|
||||
|
||||
declare let ab: A & B;
|
||||
ab.kind; // Error
|
||||
~~~~
|
||||
!!! error TS2339: Property 'kind' does not exist on type 'never'.
|
||||
|
||||
declare let x: A | (B & C); // A
|
||||
let a: A = x;
|
||||
|
||||
type AB = A & B; // never
|
||||
type BC = B & C; // never
|
||||
|
||||
type U1 = Partial<A & B>; // never
|
||||
type U2 = Readonly<A & B>; // never
|
||||
type U3 = (A & B)['kind']; // never
|
||||
type U4 = A & B | B & C; // never
|
||||
type U5 = A | B & C; // A
|
||||
|
||||
type K1 = keyof (A & B); // string | number | symbol
|
||||
type K2 = keyof A | keyof B; // 'kind' | 'foo'
|
||||
|
||||
type Merge1<T, U> = { [P in keyof (T & U)]: P extends keyof T ? T[P] : U[P & keyof U] }
|
||||
type Merge2<T, U> = { [P in keyof T | keyof U]: P extends keyof T ? T[P] : U[P & keyof U] }
|
||||
|
||||
type M1 = { a: 1, b: 2 } & { a: 2, c: 3 }; // never
|
||||
type M2 = Merge1<{ a: 1, b: 2 }, { a: 2, c: 3 }>; // {}
|
||||
type M3 = Merge2<{ a: 1, b: 2 }, { a: 2, c: 3 }>; // { a: 1, b: 2, c: 3 }
|
||||
|
||||
type D = { kind: 'd', foo: unknown };
|
||||
type E = { kind: 'e', foo: unknown };
|
||||
|
||||
declare function f10<T>(x: { foo: T }): T;
|
||||
|
||||
declare let a1: A | D;
|
||||
declare let a2: A | D & E;
|
||||
|
||||
let r1 = f10(a1); // unknown
|
||||
let r2 = f10(a2); // string
|
||||
|
||||
// Repro from #31663
|
||||
|
||||
const x1 = { a: 'foo', b: 42 };
|
||||
@@ -63,4 +106,16 @@ tests/cases/conformance/types/intersection/intersectionReduction.ts(41,1): error
|
||||
|
||||
t1 = t2;
|
||||
t2 = t1;
|
||||
|
||||
// Repro from #36736
|
||||
|
||||
const f1 = (t: "a" | ("b" & "c")): "a" => t;
|
||||
|
||||
type Container<Type extends string> = {
|
||||
type: Type;
|
||||
}
|
||||
|
||||
const f2 = (t: Container<"a"> | (Container<"b"> & Container<"c">)): Container<"a"> => t;
|
||||
const f3 = (t: Container<"a"> | (Container<"b"> & { dataB: boolean } & Container<"a">)): Container<"a"> => t;
|
||||
const f4 = (t: number | (Container<"b"> & { dataB: boolean } & Container<"a">)): number => t;
|
||||
|
||||
@@ -31,6 +31,46 @@ type X5 = X | number & object;
|
||||
type X6 = X | symbol & string;
|
||||
type X7 = X | void & string;
|
||||
|
||||
type A = { kind: 'a', foo: string };
|
||||
type B = { kind: 'b', foo: number };
|
||||
type C = { kind: 'c', foo: number };
|
||||
|
||||
declare let ab: A & B;
|
||||
ab.kind; // Error
|
||||
|
||||
declare let x: A | (B & C); // A
|
||||
let a: A = x;
|
||||
|
||||
type AB = A & B; // never
|
||||
type BC = B & C; // never
|
||||
|
||||
type U1 = Partial<A & B>; // never
|
||||
type U2 = Readonly<A & B>; // never
|
||||
type U3 = (A & B)['kind']; // never
|
||||
type U4 = A & B | B & C; // never
|
||||
type U5 = A | B & C; // A
|
||||
|
||||
type K1 = keyof (A & B); // string | number | symbol
|
||||
type K2 = keyof A | keyof B; // 'kind' | 'foo'
|
||||
|
||||
type Merge1<T, U> = { [P in keyof (T & U)]: P extends keyof T ? T[P] : U[P & keyof U] }
|
||||
type Merge2<T, U> = { [P in keyof T | keyof U]: P extends keyof T ? T[P] : U[P & keyof U] }
|
||||
|
||||
type M1 = { a: 1, b: 2 } & { a: 2, c: 3 }; // never
|
||||
type M2 = Merge1<{ a: 1, b: 2 }, { a: 2, c: 3 }>; // {}
|
||||
type M3 = Merge2<{ a: 1, b: 2 }, { a: 2, c: 3 }>; // { a: 1, b: 2, c: 3 }
|
||||
|
||||
type D = { kind: 'd', foo: unknown };
|
||||
type E = { kind: 'e', foo: unknown };
|
||||
|
||||
declare function f10<T>(x: { foo: T }): T;
|
||||
|
||||
declare let a1: A | D;
|
||||
declare let a2: A | D & E;
|
||||
|
||||
let r1 = f10(a1); // unknown
|
||||
let r2 = f10(a2); // string
|
||||
|
||||
// Repro from #31663
|
||||
|
||||
const x1 = { a: 'foo', b: 42 };
|
||||
@@ -55,9 +95,25 @@ s2 = s1;
|
||||
|
||||
t1 = t2;
|
||||
t2 = t1;
|
||||
|
||||
// Repro from #36736
|
||||
|
||||
const f1 = (t: "a" | ("b" & "c")): "a" => t;
|
||||
|
||||
type Container<Type extends string> = {
|
||||
type: Type;
|
||||
}
|
||||
|
||||
const f2 = (t: Container<"a"> | (Container<"b"> & Container<"c">)): Container<"a"> => t;
|
||||
const f3 = (t: Container<"a"> | (Container<"b"> & { dataB: boolean } & Container<"a">)): Container<"a"> => t;
|
||||
const f4 = (t: number | (Container<"b"> & { dataB: boolean } & Container<"a">)): number => t;
|
||||
|
||||
|
||||
//// [intersectionReduction.js]
|
||||
ab.kind; // Error
|
||||
var a = x;
|
||||
var r1 = f10(a1); // unknown
|
||||
var r2 = f10(a2); // string
|
||||
// Repro from #31663
|
||||
var x1 = { a: 'foo', b: 42 };
|
||||
var x2 = { a: 'foo', b: true };
|
||||
@@ -67,3 +123,8 @@ s1 = s2;
|
||||
s2 = s1;
|
||||
t1 = t2;
|
||||
t2 = t1;
|
||||
// Repro from #36736
|
||||
var f1 = function (t) { return t; };
|
||||
var f2 = function (t) { return t; };
|
||||
var f3 = function (t) { return t; };
|
||||
var f4 = function (t) { return t; };
|
||||
|
||||
@@ -93,64 +93,283 @@ type X7 = X | void & string;
|
||||
>X7 : Symbol(X7, Decl(intersectionReduction.ts, 29, 30))
|
||||
>X : Symbol(X, Decl(intersectionReduction.ts, 20, 24))
|
||||
|
||||
type A = { kind: 'a', foo: string };
|
||||
>A : Symbol(A, Decl(intersectionReduction.ts, 30, 28))
|
||||
>kind : Symbol(kind, Decl(intersectionReduction.ts, 32, 10))
|
||||
>foo : Symbol(foo, Decl(intersectionReduction.ts, 32, 21))
|
||||
|
||||
type B = { kind: 'b', foo: number };
|
||||
>B : Symbol(B, Decl(intersectionReduction.ts, 32, 36))
|
||||
>kind : Symbol(kind, Decl(intersectionReduction.ts, 33, 10))
|
||||
>foo : Symbol(foo, Decl(intersectionReduction.ts, 33, 21))
|
||||
|
||||
type C = { kind: 'c', foo: number };
|
||||
>C : Symbol(C, Decl(intersectionReduction.ts, 33, 36))
|
||||
>kind : Symbol(kind, Decl(intersectionReduction.ts, 34, 10))
|
||||
>foo : Symbol(foo, Decl(intersectionReduction.ts, 34, 21))
|
||||
|
||||
declare let ab: A & B;
|
||||
>ab : Symbol(ab, Decl(intersectionReduction.ts, 36, 11))
|
||||
>A : Symbol(A, Decl(intersectionReduction.ts, 30, 28))
|
||||
>B : Symbol(B, Decl(intersectionReduction.ts, 32, 36))
|
||||
|
||||
ab.kind; // Error
|
||||
>ab : Symbol(ab, Decl(intersectionReduction.ts, 36, 11))
|
||||
|
||||
declare let x: A | (B & C); // A
|
||||
>x : Symbol(x, Decl(intersectionReduction.ts, 39, 11))
|
||||
>A : Symbol(A, Decl(intersectionReduction.ts, 30, 28))
|
||||
>B : Symbol(B, Decl(intersectionReduction.ts, 32, 36))
|
||||
>C : Symbol(C, Decl(intersectionReduction.ts, 33, 36))
|
||||
|
||||
let a: A = x;
|
||||
>a : Symbol(a, Decl(intersectionReduction.ts, 40, 3))
|
||||
>A : Symbol(A, Decl(intersectionReduction.ts, 30, 28))
|
||||
>x : Symbol(x, Decl(intersectionReduction.ts, 39, 11))
|
||||
|
||||
type AB = A & B; // never
|
||||
>AB : Symbol(AB, Decl(intersectionReduction.ts, 40, 13))
|
||||
>A : Symbol(A, Decl(intersectionReduction.ts, 30, 28))
|
||||
>B : Symbol(B, Decl(intersectionReduction.ts, 32, 36))
|
||||
|
||||
type BC = B & C; // never
|
||||
>BC : Symbol(BC, Decl(intersectionReduction.ts, 42, 16))
|
||||
>B : Symbol(B, Decl(intersectionReduction.ts, 32, 36))
|
||||
>C : Symbol(C, Decl(intersectionReduction.ts, 33, 36))
|
||||
|
||||
type U1 = Partial<A & B>; // never
|
||||
>U1 : Symbol(U1, Decl(intersectionReduction.ts, 43, 16))
|
||||
>Partial : Symbol(Partial, Decl(lib.es5.d.ts, --, --))
|
||||
>A : Symbol(A, Decl(intersectionReduction.ts, 30, 28))
|
||||
>B : Symbol(B, Decl(intersectionReduction.ts, 32, 36))
|
||||
|
||||
type U2 = Readonly<A & B>; // never
|
||||
>U2 : Symbol(U2, Decl(intersectionReduction.ts, 45, 25))
|
||||
>Readonly : Symbol(Readonly, Decl(lib.es5.d.ts, --, --))
|
||||
>A : Symbol(A, Decl(intersectionReduction.ts, 30, 28))
|
||||
>B : Symbol(B, Decl(intersectionReduction.ts, 32, 36))
|
||||
|
||||
type U3 = (A & B)['kind']; // never
|
||||
>U3 : Symbol(U3, Decl(intersectionReduction.ts, 46, 26))
|
||||
>A : Symbol(A, Decl(intersectionReduction.ts, 30, 28))
|
||||
>B : Symbol(B, Decl(intersectionReduction.ts, 32, 36))
|
||||
|
||||
type U4 = A & B | B & C; // never
|
||||
>U4 : Symbol(U4, Decl(intersectionReduction.ts, 47, 26))
|
||||
>A : Symbol(A, Decl(intersectionReduction.ts, 30, 28))
|
||||
>B : Symbol(B, Decl(intersectionReduction.ts, 32, 36))
|
||||
>B : Symbol(B, Decl(intersectionReduction.ts, 32, 36))
|
||||
>C : Symbol(C, Decl(intersectionReduction.ts, 33, 36))
|
||||
|
||||
type U5 = A | B & C; // A
|
||||
>U5 : Symbol(U5, Decl(intersectionReduction.ts, 48, 24))
|
||||
>A : Symbol(A, Decl(intersectionReduction.ts, 30, 28))
|
||||
>B : Symbol(B, Decl(intersectionReduction.ts, 32, 36))
|
||||
>C : Symbol(C, Decl(intersectionReduction.ts, 33, 36))
|
||||
|
||||
type K1 = keyof (A & B); // string | number | symbol
|
||||
>K1 : Symbol(K1, Decl(intersectionReduction.ts, 49, 20))
|
||||
>A : Symbol(A, Decl(intersectionReduction.ts, 30, 28))
|
||||
>B : Symbol(B, Decl(intersectionReduction.ts, 32, 36))
|
||||
|
||||
type K2 = keyof A | keyof B; // 'kind' | 'foo'
|
||||
>K2 : Symbol(K2, Decl(intersectionReduction.ts, 51, 24))
|
||||
>A : Symbol(A, Decl(intersectionReduction.ts, 30, 28))
|
||||
>B : Symbol(B, Decl(intersectionReduction.ts, 32, 36))
|
||||
|
||||
type Merge1<T, U> = { [P in keyof (T & U)]: P extends keyof T ? T[P] : U[P & keyof U] }
|
||||
>Merge1 : Symbol(Merge1, Decl(intersectionReduction.ts, 52, 28))
|
||||
>T : Symbol(T, Decl(intersectionReduction.ts, 54, 12))
|
||||
>U : Symbol(U, Decl(intersectionReduction.ts, 54, 14))
|
||||
>P : Symbol(P, Decl(intersectionReduction.ts, 54, 23))
|
||||
>T : Symbol(T, Decl(intersectionReduction.ts, 54, 12))
|
||||
>U : Symbol(U, Decl(intersectionReduction.ts, 54, 14))
|
||||
>P : Symbol(P, Decl(intersectionReduction.ts, 54, 23))
|
||||
>T : Symbol(T, Decl(intersectionReduction.ts, 54, 12))
|
||||
>T : Symbol(T, Decl(intersectionReduction.ts, 54, 12))
|
||||
>P : Symbol(P, Decl(intersectionReduction.ts, 54, 23))
|
||||
>U : Symbol(U, Decl(intersectionReduction.ts, 54, 14))
|
||||
>P : Symbol(P, Decl(intersectionReduction.ts, 54, 23))
|
||||
>U : Symbol(U, Decl(intersectionReduction.ts, 54, 14))
|
||||
|
||||
type Merge2<T, U> = { [P in keyof T | keyof U]: P extends keyof T ? T[P] : U[P & keyof U] }
|
||||
>Merge2 : Symbol(Merge2, Decl(intersectionReduction.ts, 54, 87))
|
||||
>T : Symbol(T, Decl(intersectionReduction.ts, 55, 12))
|
||||
>U : Symbol(U, Decl(intersectionReduction.ts, 55, 14))
|
||||
>P : Symbol(P, Decl(intersectionReduction.ts, 55, 23))
|
||||
>T : Symbol(T, Decl(intersectionReduction.ts, 55, 12))
|
||||
>U : Symbol(U, Decl(intersectionReduction.ts, 55, 14))
|
||||
>P : Symbol(P, Decl(intersectionReduction.ts, 55, 23))
|
||||
>T : Symbol(T, Decl(intersectionReduction.ts, 55, 12))
|
||||
>T : Symbol(T, Decl(intersectionReduction.ts, 55, 12))
|
||||
>P : Symbol(P, Decl(intersectionReduction.ts, 55, 23))
|
||||
>U : Symbol(U, Decl(intersectionReduction.ts, 55, 14))
|
||||
>P : Symbol(P, Decl(intersectionReduction.ts, 55, 23))
|
||||
>U : Symbol(U, Decl(intersectionReduction.ts, 55, 14))
|
||||
|
||||
type M1 = { a: 1, b: 2 } & { a: 2, c: 3 }; // never
|
||||
>M1 : Symbol(M1, Decl(intersectionReduction.ts, 55, 91))
|
||||
>a : Symbol(a, Decl(intersectionReduction.ts, 57, 11))
|
||||
>b : Symbol(b, Decl(intersectionReduction.ts, 57, 17))
|
||||
>a : Symbol(a, Decl(intersectionReduction.ts, 57, 28))
|
||||
>c : Symbol(c, Decl(intersectionReduction.ts, 57, 34))
|
||||
|
||||
type M2 = Merge1<{ a: 1, b: 2 }, { a: 2, c: 3 }>; // {}
|
||||
>M2 : Symbol(M2, Decl(intersectionReduction.ts, 57, 42))
|
||||
>Merge1 : Symbol(Merge1, Decl(intersectionReduction.ts, 52, 28))
|
||||
>a : Symbol(a, Decl(intersectionReduction.ts, 58, 18))
|
||||
>b : Symbol(b, Decl(intersectionReduction.ts, 58, 24))
|
||||
>a : Symbol(a, Decl(intersectionReduction.ts, 58, 34))
|
||||
>c : Symbol(c, Decl(intersectionReduction.ts, 58, 40))
|
||||
|
||||
type M3 = Merge2<{ a: 1, b: 2 }, { a: 2, c: 3 }>; // { a: 1, b: 2, c: 3 }
|
||||
>M3 : Symbol(M3, Decl(intersectionReduction.ts, 58, 49))
|
||||
>Merge2 : Symbol(Merge2, Decl(intersectionReduction.ts, 54, 87))
|
||||
>a : Symbol(a, Decl(intersectionReduction.ts, 59, 18))
|
||||
>b : Symbol(b, Decl(intersectionReduction.ts, 59, 24))
|
||||
>a : Symbol(a, Decl(intersectionReduction.ts, 59, 34))
|
||||
>c : Symbol(c, Decl(intersectionReduction.ts, 59, 40))
|
||||
|
||||
type D = { kind: 'd', foo: unknown };
|
||||
>D : Symbol(D, Decl(intersectionReduction.ts, 59, 49))
|
||||
>kind : Symbol(kind, Decl(intersectionReduction.ts, 61, 10))
|
||||
>foo : Symbol(foo, Decl(intersectionReduction.ts, 61, 21))
|
||||
|
||||
type E = { kind: 'e', foo: unknown };
|
||||
>E : Symbol(E, Decl(intersectionReduction.ts, 61, 37))
|
||||
>kind : Symbol(kind, Decl(intersectionReduction.ts, 62, 10))
|
||||
>foo : Symbol(foo, Decl(intersectionReduction.ts, 62, 21))
|
||||
|
||||
declare function f10<T>(x: { foo: T }): T;
|
||||
>f10 : Symbol(f10, Decl(intersectionReduction.ts, 62, 37))
|
||||
>T : Symbol(T, Decl(intersectionReduction.ts, 64, 21))
|
||||
>x : Symbol(x, Decl(intersectionReduction.ts, 64, 24))
|
||||
>foo : Symbol(foo, Decl(intersectionReduction.ts, 64, 28))
|
||||
>T : Symbol(T, Decl(intersectionReduction.ts, 64, 21))
|
||||
>T : Symbol(T, Decl(intersectionReduction.ts, 64, 21))
|
||||
|
||||
declare let a1: A | D;
|
||||
>a1 : Symbol(a1, Decl(intersectionReduction.ts, 66, 11))
|
||||
>A : Symbol(A, Decl(intersectionReduction.ts, 30, 28))
|
||||
>D : Symbol(D, Decl(intersectionReduction.ts, 59, 49))
|
||||
|
||||
declare let a2: A | D & E;
|
||||
>a2 : Symbol(a2, Decl(intersectionReduction.ts, 67, 11))
|
||||
>A : Symbol(A, Decl(intersectionReduction.ts, 30, 28))
|
||||
>D : Symbol(D, Decl(intersectionReduction.ts, 59, 49))
|
||||
>E : Symbol(E, Decl(intersectionReduction.ts, 61, 37))
|
||||
|
||||
let r1 = f10(a1); // unknown
|
||||
>r1 : Symbol(r1, Decl(intersectionReduction.ts, 69, 3))
|
||||
>f10 : Symbol(f10, Decl(intersectionReduction.ts, 62, 37))
|
||||
>a1 : Symbol(a1, Decl(intersectionReduction.ts, 66, 11))
|
||||
|
||||
let r2 = f10(a2); // string
|
||||
>r2 : Symbol(r2, Decl(intersectionReduction.ts, 70, 3))
|
||||
>f10 : Symbol(f10, Decl(intersectionReduction.ts, 62, 37))
|
||||
>a2 : Symbol(a2, Decl(intersectionReduction.ts, 67, 11))
|
||||
|
||||
// Repro from #31663
|
||||
|
||||
const x1 = { a: 'foo', b: 42 };
|
||||
>x1 : Symbol(x1, Decl(intersectionReduction.ts, 34, 5))
|
||||
>a : Symbol(a, Decl(intersectionReduction.ts, 34, 12))
|
||||
>b : Symbol(b, Decl(intersectionReduction.ts, 34, 22))
|
||||
>x1 : Symbol(x1, Decl(intersectionReduction.ts, 74, 5))
|
||||
>a : Symbol(a, Decl(intersectionReduction.ts, 74, 12))
|
||||
>b : Symbol(b, Decl(intersectionReduction.ts, 74, 22))
|
||||
|
||||
const x2 = { a: 'foo', b: true };
|
||||
>x2 : Symbol(x2, Decl(intersectionReduction.ts, 35, 5))
|
||||
>a : Symbol(a, Decl(intersectionReduction.ts, 35, 12))
|
||||
>b : Symbol(b, Decl(intersectionReduction.ts, 35, 22))
|
||||
>x2 : Symbol(x2, Decl(intersectionReduction.ts, 75, 5))
|
||||
>a : Symbol(a, Decl(intersectionReduction.ts, 75, 12))
|
||||
>b : Symbol(b, Decl(intersectionReduction.ts, 75, 22))
|
||||
|
||||
declare let k: 'a' | 'b';
|
||||
>k : Symbol(k, Decl(intersectionReduction.ts, 37, 11))
|
||||
>k : Symbol(k, Decl(intersectionReduction.ts, 77, 11))
|
||||
|
||||
x1[k] = 'bar' as any; // Error
|
||||
>x1 : Symbol(x1, Decl(intersectionReduction.ts, 34, 5))
|
||||
>k : Symbol(k, Decl(intersectionReduction.ts, 37, 11))
|
||||
>x1 : Symbol(x1, Decl(intersectionReduction.ts, 74, 5))
|
||||
>k : Symbol(k, Decl(intersectionReduction.ts, 77, 11))
|
||||
|
||||
x2[k] = 'bar' as any; // Error
|
||||
>x2 : Symbol(x2, Decl(intersectionReduction.ts, 35, 5))
|
||||
>k : Symbol(k, Decl(intersectionReduction.ts, 37, 11))
|
||||
>x2 : Symbol(x2, Decl(intersectionReduction.ts, 75, 5))
|
||||
>k : Symbol(k, Decl(intersectionReduction.ts, 77, 11))
|
||||
|
||||
const enum Tag1 {}
|
||||
>Tag1 : Symbol(Tag1, Decl(intersectionReduction.ts, 40, 21))
|
||||
>Tag1 : Symbol(Tag1, Decl(intersectionReduction.ts, 80, 21))
|
||||
|
||||
const enum Tag2 {}
|
||||
>Tag2 : Symbol(Tag2, Decl(intersectionReduction.ts, 42, 18))
|
||||
>Tag2 : Symbol(Tag2, Decl(intersectionReduction.ts, 82, 18))
|
||||
|
||||
declare let s1: string & Tag1;
|
||||
>s1 : Symbol(s1, Decl(intersectionReduction.ts, 45, 11))
|
||||
>Tag1 : Symbol(Tag1, Decl(intersectionReduction.ts, 40, 21))
|
||||
>s1 : Symbol(s1, Decl(intersectionReduction.ts, 85, 11))
|
||||
>Tag1 : Symbol(Tag1, Decl(intersectionReduction.ts, 80, 21))
|
||||
|
||||
declare let s2: string & Tag2;
|
||||
>s2 : Symbol(s2, Decl(intersectionReduction.ts, 46, 11))
|
||||
>Tag2 : Symbol(Tag2, Decl(intersectionReduction.ts, 42, 18))
|
||||
>s2 : Symbol(s2, Decl(intersectionReduction.ts, 86, 11))
|
||||
>Tag2 : Symbol(Tag2, Decl(intersectionReduction.ts, 82, 18))
|
||||
|
||||
declare let t1: string & Tag1 | undefined;
|
||||
>t1 : Symbol(t1, Decl(intersectionReduction.ts, 48, 11))
|
||||
>Tag1 : Symbol(Tag1, Decl(intersectionReduction.ts, 40, 21))
|
||||
>t1 : Symbol(t1, Decl(intersectionReduction.ts, 88, 11))
|
||||
>Tag1 : Symbol(Tag1, Decl(intersectionReduction.ts, 80, 21))
|
||||
|
||||
declare let t2: string & Tag2 | undefined;
|
||||
>t2 : Symbol(t2, Decl(intersectionReduction.ts, 49, 11))
|
||||
>Tag2 : Symbol(Tag2, Decl(intersectionReduction.ts, 42, 18))
|
||||
>t2 : Symbol(t2, Decl(intersectionReduction.ts, 89, 11))
|
||||
>Tag2 : Symbol(Tag2, Decl(intersectionReduction.ts, 82, 18))
|
||||
|
||||
s1 = s2;
|
||||
>s1 : Symbol(s1, Decl(intersectionReduction.ts, 45, 11))
|
||||
>s2 : Symbol(s2, Decl(intersectionReduction.ts, 46, 11))
|
||||
>s1 : Symbol(s1, Decl(intersectionReduction.ts, 85, 11))
|
||||
>s2 : Symbol(s2, Decl(intersectionReduction.ts, 86, 11))
|
||||
|
||||
s2 = s1;
|
||||
>s2 : Symbol(s2, Decl(intersectionReduction.ts, 46, 11))
|
||||
>s1 : Symbol(s1, Decl(intersectionReduction.ts, 45, 11))
|
||||
>s2 : Symbol(s2, Decl(intersectionReduction.ts, 86, 11))
|
||||
>s1 : Symbol(s1, Decl(intersectionReduction.ts, 85, 11))
|
||||
|
||||
t1 = t2;
|
||||
>t1 : Symbol(t1, Decl(intersectionReduction.ts, 48, 11))
|
||||
>t2 : Symbol(t2, Decl(intersectionReduction.ts, 49, 11))
|
||||
>t1 : Symbol(t1, Decl(intersectionReduction.ts, 88, 11))
|
||||
>t2 : Symbol(t2, Decl(intersectionReduction.ts, 89, 11))
|
||||
|
||||
t2 = t1;
|
||||
>t2 : Symbol(t2, Decl(intersectionReduction.ts, 49, 11))
|
||||
>t1 : Symbol(t1, Decl(intersectionReduction.ts, 48, 11))
|
||||
>t2 : Symbol(t2, Decl(intersectionReduction.ts, 89, 11))
|
||||
>t1 : Symbol(t1, Decl(intersectionReduction.ts, 88, 11))
|
||||
|
||||
// Repro from #36736
|
||||
|
||||
const f1 = (t: "a" | ("b" & "c")): "a" => t;
|
||||
>f1 : Symbol(f1, Decl(intersectionReduction.ts, 99, 5))
|
||||
>t : Symbol(t, Decl(intersectionReduction.ts, 99, 12))
|
||||
>t : Symbol(t, Decl(intersectionReduction.ts, 99, 12))
|
||||
|
||||
type Container<Type extends string> = {
|
||||
>Container : Symbol(Container, Decl(intersectionReduction.ts, 99, 44))
|
||||
>Type : Symbol(Type, Decl(intersectionReduction.ts, 101, 15))
|
||||
|
||||
type: Type;
|
||||
>type : Symbol(type, Decl(intersectionReduction.ts, 101, 39))
|
||||
>Type : Symbol(Type, Decl(intersectionReduction.ts, 101, 15))
|
||||
}
|
||||
|
||||
const f2 = (t: Container<"a"> | (Container<"b"> & Container<"c">)): Container<"a"> => t;
|
||||
>f2 : Symbol(f2, Decl(intersectionReduction.ts, 105, 5))
|
||||
>t : Symbol(t, Decl(intersectionReduction.ts, 105, 12))
|
||||
>Container : Symbol(Container, Decl(intersectionReduction.ts, 99, 44))
|
||||
>Container : Symbol(Container, Decl(intersectionReduction.ts, 99, 44))
|
||||
>Container : Symbol(Container, Decl(intersectionReduction.ts, 99, 44))
|
||||
>Container : Symbol(Container, Decl(intersectionReduction.ts, 99, 44))
|
||||
>t : Symbol(t, Decl(intersectionReduction.ts, 105, 12))
|
||||
|
||||
const f3 = (t: Container<"a"> | (Container<"b"> & { dataB: boolean } & Container<"a">)): Container<"a"> => t;
|
||||
>f3 : Symbol(f3, Decl(intersectionReduction.ts, 106, 5))
|
||||
>t : Symbol(t, Decl(intersectionReduction.ts, 106, 12))
|
||||
>Container : Symbol(Container, Decl(intersectionReduction.ts, 99, 44))
|
||||
>Container : Symbol(Container, Decl(intersectionReduction.ts, 99, 44))
|
||||
>dataB : Symbol(dataB, Decl(intersectionReduction.ts, 106, 51))
|
||||
>Container : Symbol(Container, Decl(intersectionReduction.ts, 99, 44))
|
||||
>Container : Symbol(Container, Decl(intersectionReduction.ts, 99, 44))
|
||||
>t : Symbol(t, Decl(intersectionReduction.ts, 106, 12))
|
||||
|
||||
const f4 = (t: number | (Container<"b"> & { dataB: boolean } & Container<"a">)): number => t;
|
||||
>f4 : Symbol(f4, Decl(intersectionReduction.ts, 107, 5))
|
||||
>t : Symbol(t, Decl(intersectionReduction.ts, 107, 12))
|
||||
>Container : Symbol(Container, Decl(intersectionReduction.ts, 99, 44))
|
||||
>dataB : Symbol(dataB, Decl(intersectionReduction.ts, 107, 43))
|
||||
>Container : Symbol(Container, Decl(intersectionReduction.ts, 99, 44))
|
||||
>t : Symbol(t, Decl(intersectionReduction.ts, 107, 12))
|
||||
|
||||
|
||||
@@ -88,6 +88,123 @@ type X6 = X | symbol & string;
|
||||
type X7 = X | void & string;
|
||||
>X7 : X
|
||||
|
||||
type A = { kind: 'a', foo: string };
|
||||
>A : A
|
||||
>kind : "a"
|
||||
>foo : string
|
||||
|
||||
type B = { kind: 'b', foo: number };
|
||||
>B : B
|
||||
>kind : "b"
|
||||
>foo : number
|
||||
|
||||
type C = { kind: 'c', foo: number };
|
||||
>C : C
|
||||
>kind : "c"
|
||||
>foo : number
|
||||
|
||||
declare let ab: A & B;
|
||||
>ab : never
|
||||
|
||||
ab.kind; // Error
|
||||
>ab.kind : any
|
||||
>ab : never
|
||||
>kind : any
|
||||
|
||||
declare let x: A | (B & C); // A
|
||||
>x : A
|
||||
|
||||
let a: A = x;
|
||||
>a : A
|
||||
>x : A
|
||||
|
||||
type AB = A & B; // never
|
||||
>AB : never
|
||||
|
||||
type BC = B & C; // never
|
||||
>BC : never
|
||||
|
||||
type U1 = Partial<A & B>; // never
|
||||
>U1 : never
|
||||
|
||||
type U2 = Readonly<A & B>; // never
|
||||
>U2 : never
|
||||
|
||||
type U3 = (A & B)['kind']; // never
|
||||
>U3 : never
|
||||
|
||||
type U4 = A & B | B & C; // never
|
||||
>U4 : never
|
||||
|
||||
type U5 = A | B & C; // A
|
||||
>U5 : A
|
||||
|
||||
type K1 = keyof (A & B); // string | number | symbol
|
||||
>K1 : string | number | symbol
|
||||
|
||||
type K2 = keyof A | keyof B; // 'kind' | 'foo'
|
||||
>K2 : "kind" | "foo"
|
||||
|
||||
type Merge1<T, U> = { [P in keyof (T & U)]: P extends keyof T ? T[P] : U[P & keyof U] }
|
||||
>Merge1 : Merge1<T, U>
|
||||
|
||||
type Merge2<T, U> = { [P in keyof T | keyof U]: P extends keyof T ? T[P] : U[P & keyof U] }
|
||||
>Merge2 : Merge2<T, U>
|
||||
|
||||
type M1 = { a: 1, b: 2 } & { a: 2, c: 3 }; // never
|
||||
>M1 : never
|
||||
>a : 1
|
||||
>b : 2
|
||||
>a : 2
|
||||
>c : 3
|
||||
|
||||
type M2 = Merge1<{ a: 1, b: 2 }, { a: 2, c: 3 }>; // {}
|
||||
>M2 : Merge1<{ a: 1; b: 2; }, { a: 2; c: 3; }>
|
||||
>a : 1
|
||||
>b : 2
|
||||
>a : 2
|
||||
>c : 3
|
||||
|
||||
type M3 = Merge2<{ a: 1, b: 2 }, { a: 2, c: 3 }>; // { a: 1, b: 2, c: 3 }
|
||||
>M3 : Merge2<{ a: 1; b: 2; }, { a: 2; c: 3; }>
|
||||
>a : 1
|
||||
>b : 2
|
||||
>a : 2
|
||||
>c : 3
|
||||
|
||||
type D = { kind: 'd', foo: unknown };
|
||||
>D : D
|
||||
>kind : "d"
|
||||
>foo : unknown
|
||||
|
||||
type E = { kind: 'e', foo: unknown };
|
||||
>E : E
|
||||
>kind : "e"
|
||||
>foo : unknown
|
||||
|
||||
declare function f10<T>(x: { foo: T }): T;
|
||||
>f10 : <T>(x: { foo: T; }) => T
|
||||
>x : { foo: T; }
|
||||
>foo : T
|
||||
|
||||
declare let a1: A | D;
|
||||
>a1 : A | D
|
||||
|
||||
declare let a2: A | D & E;
|
||||
>a2 : A
|
||||
|
||||
let r1 = f10(a1); // unknown
|
||||
>r1 : unknown
|
||||
>f10(a1) : unknown
|
||||
>f10 : <T>(x: { foo: T; }) => T
|
||||
>a1 : A | D
|
||||
|
||||
let r2 = f10(a2); // string
|
||||
>r2 : string
|
||||
>f10(a2) : string
|
||||
>f10 : <T>(x: { foo: T; }) => T
|
||||
>a2 : A
|
||||
|
||||
// Repro from #31663
|
||||
|
||||
const x1 = { a: 'foo', b: 42 };
|
||||
@@ -163,3 +280,38 @@ t2 = t1;
|
||||
>t2 : undefined
|
||||
>t1 : undefined
|
||||
|
||||
// Repro from #36736
|
||||
|
||||
const f1 = (t: "a" | ("b" & "c")): "a" => t;
|
||||
>f1 : (t: "a") => "a"
|
||||
>(t: "a" | ("b" & "c")): "a" => t : (t: "a") => "a"
|
||||
>t : "a"
|
||||
>t : "a"
|
||||
|
||||
type Container<Type extends string> = {
|
||||
>Container : Container<Type>
|
||||
|
||||
type: Type;
|
||||
>type : Type
|
||||
}
|
||||
|
||||
const f2 = (t: Container<"a"> | (Container<"b"> & Container<"c">)): Container<"a"> => t;
|
||||
>f2 : (t: Container<"a">) => Container<"a">
|
||||
>(t: Container<"a"> | (Container<"b"> & Container<"c">)): Container<"a"> => t : (t: Container<"a">) => Container<"a">
|
||||
>t : Container<"a">
|
||||
>t : Container<"a">
|
||||
|
||||
const f3 = (t: Container<"a"> | (Container<"b"> & { dataB: boolean } & Container<"a">)): Container<"a"> => t;
|
||||
>f3 : (t: Container<"a">) => Container<"a">
|
||||
>(t: Container<"a"> | (Container<"b"> & { dataB: boolean } & Container<"a">)): Container<"a"> => t : (t: Container<"a">) => Container<"a">
|
||||
>t : Container<"a">
|
||||
>dataB : boolean
|
||||
>t : Container<"a">
|
||||
|
||||
const f4 = (t: number | (Container<"b"> & { dataB: boolean } & Container<"a">)): number => t;
|
||||
>f4 : (t: number) => number
|
||||
>(t: number | (Container<"b"> & { dataB: boolean } & Container<"a">)): number => t : (t: number) => number
|
||||
>t : number
|
||||
>dataB : boolean
|
||||
>t : number
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
tests/cases/conformance/types/intersection/intersectionReductionStrict.ts(40,1): error TS2322: Type 'any' is not assignable to type 'never'.
|
||||
tests/cases/conformance/types/intersection/intersectionReductionStrict.ts(41,1): error TS2322: Type 'any' is not assignable to type 'never'.
|
||||
tests/cases/conformance/types/intersection/intersectionReductionStrict.ts(38,4): error TS2339: Property 'kind' does not exist on type 'never'.
|
||||
tests/cases/conformance/types/intersection/intersectionReductionStrict.ts(69,1): error TS2322: Type 'any' is not assignable to type 'never'.
|
||||
tests/cases/conformance/types/intersection/intersectionReductionStrict.ts(70,1): error TS2322: Type 'any' is not assignable to type 'never'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/types/intersection/intersectionReductionStrict.ts (2 errors) ====
|
||||
==== tests/cases/conformance/types/intersection/intersectionReductionStrict.ts (3 errors) ====
|
||||
declare const sym1: unique symbol;
|
||||
declare const sym2: unique symbol;
|
||||
|
||||
@@ -35,6 +36,37 @@ tests/cases/conformance/types/intersection/intersectionReductionStrict.ts(41,1):
|
||||
type X6 = X | symbol & string;
|
||||
type X7 = X | void & string;
|
||||
|
||||
type A = { kind: 'a', foo: string };
|
||||
type B = { kind: 'b', foo: number };
|
||||
type C = { kind: 'c', foo: number };
|
||||
|
||||
declare let ab: A & B;
|
||||
ab.kind; // Error
|
||||
~~~~
|
||||
!!! error TS2339: Property 'kind' does not exist on type 'never'.
|
||||
|
||||
declare let x: A | (B & C); // A
|
||||
let a: A = x;
|
||||
|
||||
type AB = A & B; // never
|
||||
type BC = B & C; // never
|
||||
|
||||
type U1 = Partial<A & B>; // never
|
||||
type U2 = Readonly<A & B>; // never
|
||||
type U3 = (A & B)['kind']; // never
|
||||
type U4 = A & B | B & C; // never
|
||||
type U5 = A | B & C; // A
|
||||
|
||||
type K1 = keyof (A & B); // string | number | symbol
|
||||
type K2 = keyof A | keyof B; // 'kind' | 'foo'
|
||||
|
||||
type Merge1<T, U> = { [P in keyof (T & U)]: P extends keyof T ? T[P] : U[P & keyof U] }
|
||||
type Merge2<T, U> = { [P in keyof T | keyof U]: P extends keyof T ? T[P] : U[P & keyof U] }
|
||||
|
||||
type M1 = { a: 1, b: 2 } & { a: 2, c: 3 }; // never
|
||||
type M2 = Merge1<{ a: 1, b: 2 }, { a: 2, c: 3 }>; // {}
|
||||
type M3 = Merge2<{ a: 1, b: 2 }, { a: 2, c: 3 }>; // { a: 1, b: 2, c: 3 }
|
||||
|
||||
// Repro from #31663
|
||||
|
||||
const x1 = { a: 'foo', b: 42 };
|
||||
@@ -63,4 +95,16 @@ tests/cases/conformance/types/intersection/intersectionReductionStrict.ts(41,1):
|
||||
|
||||
t1 = t2;
|
||||
t2 = t1;
|
||||
|
||||
// Repro from #36736
|
||||
|
||||
const f1 = (t: "a" | ("b" & "c")): "a" => t;
|
||||
|
||||
type Container<Type extends string> = {
|
||||
type: Type;
|
||||
}
|
||||
|
||||
const f2 = (t: Container<"a"> | (Container<"b"> & Container<"c">)): Container<"a"> => t;
|
||||
const f3 = (t: Container<"a"> | (Container<"b"> & { dataB: boolean } & Container<"a">)): Container<"a"> => t;
|
||||
const f4 = (t: number | (Container<"b"> & { dataB: boolean } & Container<"a">)): number => t;
|
||||
|
||||
@@ -31,6 +31,35 @@ type X5 = X | number & object;
|
||||
type X6 = X | symbol & string;
|
||||
type X7 = X | void & string;
|
||||
|
||||
type A = { kind: 'a', foo: string };
|
||||
type B = { kind: 'b', foo: number };
|
||||
type C = { kind: 'c', foo: number };
|
||||
|
||||
declare let ab: A & B;
|
||||
ab.kind; // Error
|
||||
|
||||
declare let x: A | (B & C); // A
|
||||
let a: A = x;
|
||||
|
||||
type AB = A & B; // never
|
||||
type BC = B & C; // never
|
||||
|
||||
type U1 = Partial<A & B>; // never
|
||||
type U2 = Readonly<A & B>; // never
|
||||
type U3 = (A & B)['kind']; // never
|
||||
type U4 = A & B | B & C; // never
|
||||
type U5 = A | B & C; // A
|
||||
|
||||
type K1 = keyof (A & B); // string | number | symbol
|
||||
type K2 = keyof A | keyof B; // 'kind' | 'foo'
|
||||
|
||||
type Merge1<T, U> = { [P in keyof (T & U)]: P extends keyof T ? T[P] : U[P & keyof U] }
|
||||
type Merge2<T, U> = { [P in keyof T | keyof U]: P extends keyof T ? T[P] : U[P & keyof U] }
|
||||
|
||||
type M1 = { a: 1, b: 2 } & { a: 2, c: 3 }; // never
|
||||
type M2 = Merge1<{ a: 1, b: 2 }, { a: 2, c: 3 }>; // {}
|
||||
type M3 = Merge2<{ a: 1, b: 2 }, { a: 2, c: 3 }>; // { a: 1, b: 2, c: 3 }
|
||||
|
||||
// Repro from #31663
|
||||
|
||||
const x1 = { a: 'foo', b: 42 };
|
||||
@@ -55,10 +84,24 @@ s2 = s1;
|
||||
|
||||
t1 = t2;
|
||||
t2 = t1;
|
||||
|
||||
// Repro from #36736
|
||||
|
||||
const f1 = (t: "a" | ("b" & "c")): "a" => t;
|
||||
|
||||
type Container<Type extends string> = {
|
||||
type: Type;
|
||||
}
|
||||
|
||||
const f2 = (t: Container<"a"> | (Container<"b"> & Container<"c">)): Container<"a"> => t;
|
||||
const f3 = (t: Container<"a"> | (Container<"b"> & { dataB: boolean } & Container<"a">)): Container<"a"> => t;
|
||||
const f4 = (t: number | (Container<"b"> & { dataB: boolean } & Container<"a">)): number => t;
|
||||
|
||||
|
||||
//// [intersectionReductionStrict.js]
|
||||
"use strict";
|
||||
ab.kind; // Error
|
||||
var a = x;
|
||||
// Repro from #31663
|
||||
var x1 = { a: 'foo', b: 42 };
|
||||
var x2 = { a: 'foo', b: true };
|
||||
@@ -68,3 +111,8 @@ s1 = s2;
|
||||
s2 = s1;
|
||||
t1 = t2;
|
||||
t2 = t1;
|
||||
// Repro from #36736
|
||||
var f1 = function (t) { return t; };
|
||||
var f2 = function (t) { return t; };
|
||||
var f3 = function (t) { return t; };
|
||||
var f4 = function (t) { return t; };
|
||||
|
||||
@@ -93,64 +93,244 @@ type X7 = X | void & string;
|
||||
>X7 : Symbol(X7, Decl(intersectionReductionStrict.ts, 29, 30))
|
||||
>X : Symbol(X, Decl(intersectionReductionStrict.ts, 20, 24))
|
||||
|
||||
type A = { kind: 'a', foo: string };
|
||||
>A : Symbol(A, Decl(intersectionReductionStrict.ts, 30, 28))
|
||||
>kind : Symbol(kind, Decl(intersectionReductionStrict.ts, 32, 10))
|
||||
>foo : Symbol(foo, Decl(intersectionReductionStrict.ts, 32, 21))
|
||||
|
||||
type B = { kind: 'b', foo: number };
|
||||
>B : Symbol(B, Decl(intersectionReductionStrict.ts, 32, 36))
|
||||
>kind : Symbol(kind, Decl(intersectionReductionStrict.ts, 33, 10))
|
||||
>foo : Symbol(foo, Decl(intersectionReductionStrict.ts, 33, 21))
|
||||
|
||||
type C = { kind: 'c', foo: number };
|
||||
>C : Symbol(C, Decl(intersectionReductionStrict.ts, 33, 36))
|
||||
>kind : Symbol(kind, Decl(intersectionReductionStrict.ts, 34, 10))
|
||||
>foo : Symbol(foo, Decl(intersectionReductionStrict.ts, 34, 21))
|
||||
|
||||
declare let ab: A & B;
|
||||
>ab : Symbol(ab, Decl(intersectionReductionStrict.ts, 36, 11))
|
||||
>A : Symbol(A, Decl(intersectionReductionStrict.ts, 30, 28))
|
||||
>B : Symbol(B, Decl(intersectionReductionStrict.ts, 32, 36))
|
||||
|
||||
ab.kind; // Error
|
||||
>ab : Symbol(ab, Decl(intersectionReductionStrict.ts, 36, 11))
|
||||
|
||||
declare let x: A | (B & C); // A
|
||||
>x : Symbol(x, Decl(intersectionReductionStrict.ts, 39, 11))
|
||||
>A : Symbol(A, Decl(intersectionReductionStrict.ts, 30, 28))
|
||||
>B : Symbol(B, Decl(intersectionReductionStrict.ts, 32, 36))
|
||||
>C : Symbol(C, Decl(intersectionReductionStrict.ts, 33, 36))
|
||||
|
||||
let a: A = x;
|
||||
>a : Symbol(a, Decl(intersectionReductionStrict.ts, 40, 3))
|
||||
>A : Symbol(A, Decl(intersectionReductionStrict.ts, 30, 28))
|
||||
>x : Symbol(x, Decl(intersectionReductionStrict.ts, 39, 11))
|
||||
|
||||
type AB = A & B; // never
|
||||
>AB : Symbol(AB, Decl(intersectionReductionStrict.ts, 40, 13))
|
||||
>A : Symbol(A, Decl(intersectionReductionStrict.ts, 30, 28))
|
||||
>B : Symbol(B, Decl(intersectionReductionStrict.ts, 32, 36))
|
||||
|
||||
type BC = B & C; // never
|
||||
>BC : Symbol(BC, Decl(intersectionReductionStrict.ts, 42, 16))
|
||||
>B : Symbol(B, Decl(intersectionReductionStrict.ts, 32, 36))
|
||||
>C : Symbol(C, Decl(intersectionReductionStrict.ts, 33, 36))
|
||||
|
||||
type U1 = Partial<A & B>; // never
|
||||
>U1 : Symbol(U1, Decl(intersectionReductionStrict.ts, 43, 16))
|
||||
>Partial : Symbol(Partial, Decl(lib.es5.d.ts, --, --))
|
||||
>A : Symbol(A, Decl(intersectionReductionStrict.ts, 30, 28))
|
||||
>B : Symbol(B, Decl(intersectionReductionStrict.ts, 32, 36))
|
||||
|
||||
type U2 = Readonly<A & B>; // never
|
||||
>U2 : Symbol(U2, Decl(intersectionReductionStrict.ts, 45, 25))
|
||||
>Readonly : Symbol(Readonly, Decl(lib.es5.d.ts, --, --))
|
||||
>A : Symbol(A, Decl(intersectionReductionStrict.ts, 30, 28))
|
||||
>B : Symbol(B, Decl(intersectionReductionStrict.ts, 32, 36))
|
||||
|
||||
type U3 = (A & B)['kind']; // never
|
||||
>U3 : Symbol(U3, Decl(intersectionReductionStrict.ts, 46, 26))
|
||||
>A : Symbol(A, Decl(intersectionReductionStrict.ts, 30, 28))
|
||||
>B : Symbol(B, Decl(intersectionReductionStrict.ts, 32, 36))
|
||||
|
||||
type U4 = A & B | B & C; // never
|
||||
>U4 : Symbol(U4, Decl(intersectionReductionStrict.ts, 47, 26))
|
||||
>A : Symbol(A, Decl(intersectionReductionStrict.ts, 30, 28))
|
||||
>B : Symbol(B, Decl(intersectionReductionStrict.ts, 32, 36))
|
||||
>B : Symbol(B, Decl(intersectionReductionStrict.ts, 32, 36))
|
||||
>C : Symbol(C, Decl(intersectionReductionStrict.ts, 33, 36))
|
||||
|
||||
type U5 = A | B & C; // A
|
||||
>U5 : Symbol(U5, Decl(intersectionReductionStrict.ts, 48, 24))
|
||||
>A : Symbol(A, Decl(intersectionReductionStrict.ts, 30, 28))
|
||||
>B : Symbol(B, Decl(intersectionReductionStrict.ts, 32, 36))
|
||||
>C : Symbol(C, Decl(intersectionReductionStrict.ts, 33, 36))
|
||||
|
||||
type K1 = keyof (A & B); // string | number | symbol
|
||||
>K1 : Symbol(K1, Decl(intersectionReductionStrict.ts, 49, 20))
|
||||
>A : Symbol(A, Decl(intersectionReductionStrict.ts, 30, 28))
|
||||
>B : Symbol(B, Decl(intersectionReductionStrict.ts, 32, 36))
|
||||
|
||||
type K2 = keyof A | keyof B; // 'kind' | 'foo'
|
||||
>K2 : Symbol(K2, Decl(intersectionReductionStrict.ts, 51, 24))
|
||||
>A : Symbol(A, Decl(intersectionReductionStrict.ts, 30, 28))
|
||||
>B : Symbol(B, Decl(intersectionReductionStrict.ts, 32, 36))
|
||||
|
||||
type Merge1<T, U> = { [P in keyof (T & U)]: P extends keyof T ? T[P] : U[P & keyof U] }
|
||||
>Merge1 : Symbol(Merge1, Decl(intersectionReductionStrict.ts, 52, 28))
|
||||
>T : Symbol(T, Decl(intersectionReductionStrict.ts, 54, 12))
|
||||
>U : Symbol(U, Decl(intersectionReductionStrict.ts, 54, 14))
|
||||
>P : Symbol(P, Decl(intersectionReductionStrict.ts, 54, 23))
|
||||
>T : Symbol(T, Decl(intersectionReductionStrict.ts, 54, 12))
|
||||
>U : Symbol(U, Decl(intersectionReductionStrict.ts, 54, 14))
|
||||
>P : Symbol(P, Decl(intersectionReductionStrict.ts, 54, 23))
|
||||
>T : Symbol(T, Decl(intersectionReductionStrict.ts, 54, 12))
|
||||
>T : Symbol(T, Decl(intersectionReductionStrict.ts, 54, 12))
|
||||
>P : Symbol(P, Decl(intersectionReductionStrict.ts, 54, 23))
|
||||
>U : Symbol(U, Decl(intersectionReductionStrict.ts, 54, 14))
|
||||
>P : Symbol(P, Decl(intersectionReductionStrict.ts, 54, 23))
|
||||
>U : Symbol(U, Decl(intersectionReductionStrict.ts, 54, 14))
|
||||
|
||||
type Merge2<T, U> = { [P in keyof T | keyof U]: P extends keyof T ? T[P] : U[P & keyof U] }
|
||||
>Merge2 : Symbol(Merge2, Decl(intersectionReductionStrict.ts, 54, 87))
|
||||
>T : Symbol(T, Decl(intersectionReductionStrict.ts, 55, 12))
|
||||
>U : Symbol(U, Decl(intersectionReductionStrict.ts, 55, 14))
|
||||
>P : Symbol(P, Decl(intersectionReductionStrict.ts, 55, 23))
|
||||
>T : Symbol(T, Decl(intersectionReductionStrict.ts, 55, 12))
|
||||
>U : Symbol(U, Decl(intersectionReductionStrict.ts, 55, 14))
|
||||
>P : Symbol(P, Decl(intersectionReductionStrict.ts, 55, 23))
|
||||
>T : Symbol(T, Decl(intersectionReductionStrict.ts, 55, 12))
|
||||
>T : Symbol(T, Decl(intersectionReductionStrict.ts, 55, 12))
|
||||
>P : Symbol(P, Decl(intersectionReductionStrict.ts, 55, 23))
|
||||
>U : Symbol(U, Decl(intersectionReductionStrict.ts, 55, 14))
|
||||
>P : Symbol(P, Decl(intersectionReductionStrict.ts, 55, 23))
|
||||
>U : Symbol(U, Decl(intersectionReductionStrict.ts, 55, 14))
|
||||
|
||||
type M1 = { a: 1, b: 2 } & { a: 2, c: 3 }; // never
|
||||
>M1 : Symbol(M1, Decl(intersectionReductionStrict.ts, 55, 91))
|
||||
>a : Symbol(a, Decl(intersectionReductionStrict.ts, 57, 11))
|
||||
>b : Symbol(b, Decl(intersectionReductionStrict.ts, 57, 17))
|
||||
>a : Symbol(a, Decl(intersectionReductionStrict.ts, 57, 28))
|
||||
>c : Symbol(c, Decl(intersectionReductionStrict.ts, 57, 34))
|
||||
|
||||
type M2 = Merge1<{ a: 1, b: 2 }, { a: 2, c: 3 }>; // {}
|
||||
>M2 : Symbol(M2, Decl(intersectionReductionStrict.ts, 57, 42))
|
||||
>Merge1 : Symbol(Merge1, Decl(intersectionReductionStrict.ts, 52, 28))
|
||||
>a : Symbol(a, Decl(intersectionReductionStrict.ts, 58, 18))
|
||||
>b : Symbol(b, Decl(intersectionReductionStrict.ts, 58, 24))
|
||||
>a : Symbol(a, Decl(intersectionReductionStrict.ts, 58, 34))
|
||||
>c : Symbol(c, Decl(intersectionReductionStrict.ts, 58, 40))
|
||||
|
||||
type M3 = Merge2<{ a: 1, b: 2 }, { a: 2, c: 3 }>; // { a: 1, b: 2, c: 3 }
|
||||
>M3 : Symbol(M3, Decl(intersectionReductionStrict.ts, 58, 49))
|
||||
>Merge2 : Symbol(Merge2, Decl(intersectionReductionStrict.ts, 54, 87))
|
||||
>a : Symbol(a, Decl(intersectionReductionStrict.ts, 59, 18))
|
||||
>b : Symbol(b, Decl(intersectionReductionStrict.ts, 59, 24))
|
||||
>a : Symbol(a, Decl(intersectionReductionStrict.ts, 59, 34))
|
||||
>c : Symbol(c, Decl(intersectionReductionStrict.ts, 59, 40))
|
||||
|
||||
// Repro from #31663
|
||||
|
||||
const x1 = { a: 'foo', b: 42 };
|
||||
>x1 : Symbol(x1, Decl(intersectionReductionStrict.ts, 34, 5))
|
||||
>a : Symbol(a, Decl(intersectionReductionStrict.ts, 34, 12))
|
||||
>b : Symbol(b, Decl(intersectionReductionStrict.ts, 34, 22))
|
||||
>x1 : Symbol(x1, Decl(intersectionReductionStrict.ts, 63, 5))
|
||||
>a : Symbol(a, Decl(intersectionReductionStrict.ts, 63, 12))
|
||||
>b : Symbol(b, Decl(intersectionReductionStrict.ts, 63, 22))
|
||||
|
||||
const x2 = { a: 'foo', b: true };
|
||||
>x2 : Symbol(x2, Decl(intersectionReductionStrict.ts, 35, 5))
|
||||
>a : Symbol(a, Decl(intersectionReductionStrict.ts, 35, 12))
|
||||
>b : Symbol(b, Decl(intersectionReductionStrict.ts, 35, 22))
|
||||
>x2 : Symbol(x2, Decl(intersectionReductionStrict.ts, 64, 5))
|
||||
>a : Symbol(a, Decl(intersectionReductionStrict.ts, 64, 12))
|
||||
>b : Symbol(b, Decl(intersectionReductionStrict.ts, 64, 22))
|
||||
|
||||
declare let k: 'a' | 'b';
|
||||
>k : Symbol(k, Decl(intersectionReductionStrict.ts, 37, 11))
|
||||
>k : Symbol(k, Decl(intersectionReductionStrict.ts, 66, 11))
|
||||
|
||||
x1[k] = 'bar' as any; // Error
|
||||
>x1 : Symbol(x1, Decl(intersectionReductionStrict.ts, 34, 5))
|
||||
>k : Symbol(k, Decl(intersectionReductionStrict.ts, 37, 11))
|
||||
>x1 : Symbol(x1, Decl(intersectionReductionStrict.ts, 63, 5))
|
||||
>k : Symbol(k, Decl(intersectionReductionStrict.ts, 66, 11))
|
||||
|
||||
x2[k] = 'bar' as any; // Error
|
||||
>x2 : Symbol(x2, Decl(intersectionReductionStrict.ts, 35, 5))
|
||||
>k : Symbol(k, Decl(intersectionReductionStrict.ts, 37, 11))
|
||||
>x2 : Symbol(x2, Decl(intersectionReductionStrict.ts, 64, 5))
|
||||
>k : Symbol(k, Decl(intersectionReductionStrict.ts, 66, 11))
|
||||
|
||||
const enum Tag1 {}
|
||||
>Tag1 : Symbol(Tag1, Decl(intersectionReductionStrict.ts, 40, 21))
|
||||
>Tag1 : Symbol(Tag1, Decl(intersectionReductionStrict.ts, 69, 21))
|
||||
|
||||
const enum Tag2 {}
|
||||
>Tag2 : Symbol(Tag2, Decl(intersectionReductionStrict.ts, 42, 18))
|
||||
>Tag2 : Symbol(Tag2, Decl(intersectionReductionStrict.ts, 71, 18))
|
||||
|
||||
declare let s1: string & Tag1;
|
||||
>s1 : Symbol(s1, Decl(intersectionReductionStrict.ts, 45, 11))
|
||||
>Tag1 : Symbol(Tag1, Decl(intersectionReductionStrict.ts, 40, 21))
|
||||
>s1 : Symbol(s1, Decl(intersectionReductionStrict.ts, 74, 11))
|
||||
>Tag1 : Symbol(Tag1, Decl(intersectionReductionStrict.ts, 69, 21))
|
||||
|
||||
declare let s2: string & Tag2;
|
||||
>s2 : Symbol(s2, Decl(intersectionReductionStrict.ts, 46, 11))
|
||||
>Tag2 : Symbol(Tag2, Decl(intersectionReductionStrict.ts, 42, 18))
|
||||
>s2 : Symbol(s2, Decl(intersectionReductionStrict.ts, 75, 11))
|
||||
>Tag2 : Symbol(Tag2, Decl(intersectionReductionStrict.ts, 71, 18))
|
||||
|
||||
declare let t1: string & Tag1 | undefined;
|
||||
>t1 : Symbol(t1, Decl(intersectionReductionStrict.ts, 48, 11))
|
||||
>Tag1 : Symbol(Tag1, Decl(intersectionReductionStrict.ts, 40, 21))
|
||||
>t1 : Symbol(t1, Decl(intersectionReductionStrict.ts, 77, 11))
|
||||
>Tag1 : Symbol(Tag1, Decl(intersectionReductionStrict.ts, 69, 21))
|
||||
|
||||
declare let t2: string & Tag2 | undefined;
|
||||
>t2 : Symbol(t2, Decl(intersectionReductionStrict.ts, 49, 11))
|
||||
>Tag2 : Symbol(Tag2, Decl(intersectionReductionStrict.ts, 42, 18))
|
||||
>t2 : Symbol(t2, Decl(intersectionReductionStrict.ts, 78, 11))
|
||||
>Tag2 : Symbol(Tag2, Decl(intersectionReductionStrict.ts, 71, 18))
|
||||
|
||||
s1 = s2;
|
||||
>s1 : Symbol(s1, Decl(intersectionReductionStrict.ts, 45, 11))
|
||||
>s2 : Symbol(s2, Decl(intersectionReductionStrict.ts, 46, 11))
|
||||
>s1 : Symbol(s1, Decl(intersectionReductionStrict.ts, 74, 11))
|
||||
>s2 : Symbol(s2, Decl(intersectionReductionStrict.ts, 75, 11))
|
||||
|
||||
s2 = s1;
|
||||
>s2 : Symbol(s2, Decl(intersectionReductionStrict.ts, 46, 11))
|
||||
>s1 : Symbol(s1, Decl(intersectionReductionStrict.ts, 45, 11))
|
||||
>s2 : Symbol(s2, Decl(intersectionReductionStrict.ts, 75, 11))
|
||||
>s1 : Symbol(s1, Decl(intersectionReductionStrict.ts, 74, 11))
|
||||
|
||||
t1 = t2;
|
||||
>t1 : Symbol(t1, Decl(intersectionReductionStrict.ts, 48, 11))
|
||||
>t2 : Symbol(t2, Decl(intersectionReductionStrict.ts, 49, 11))
|
||||
>t1 : Symbol(t1, Decl(intersectionReductionStrict.ts, 77, 11))
|
||||
>t2 : Symbol(t2, Decl(intersectionReductionStrict.ts, 78, 11))
|
||||
|
||||
t2 = t1;
|
||||
>t2 : Symbol(t2, Decl(intersectionReductionStrict.ts, 49, 11))
|
||||
>t1 : Symbol(t1, Decl(intersectionReductionStrict.ts, 48, 11))
|
||||
>t2 : Symbol(t2, Decl(intersectionReductionStrict.ts, 78, 11))
|
||||
>t1 : Symbol(t1, Decl(intersectionReductionStrict.ts, 77, 11))
|
||||
|
||||
// Repro from #36736
|
||||
|
||||
const f1 = (t: "a" | ("b" & "c")): "a" => t;
|
||||
>f1 : Symbol(f1, Decl(intersectionReductionStrict.ts, 88, 5))
|
||||
>t : Symbol(t, Decl(intersectionReductionStrict.ts, 88, 12))
|
||||
>t : Symbol(t, Decl(intersectionReductionStrict.ts, 88, 12))
|
||||
|
||||
type Container<Type extends string> = {
|
||||
>Container : Symbol(Container, Decl(intersectionReductionStrict.ts, 88, 44))
|
||||
>Type : Symbol(Type, Decl(intersectionReductionStrict.ts, 90, 15))
|
||||
|
||||
type: Type;
|
||||
>type : Symbol(type, Decl(intersectionReductionStrict.ts, 90, 39))
|
||||
>Type : Symbol(Type, Decl(intersectionReductionStrict.ts, 90, 15))
|
||||
}
|
||||
|
||||
const f2 = (t: Container<"a"> | (Container<"b"> & Container<"c">)): Container<"a"> => t;
|
||||
>f2 : Symbol(f2, Decl(intersectionReductionStrict.ts, 94, 5))
|
||||
>t : Symbol(t, Decl(intersectionReductionStrict.ts, 94, 12))
|
||||
>Container : Symbol(Container, Decl(intersectionReductionStrict.ts, 88, 44))
|
||||
>Container : Symbol(Container, Decl(intersectionReductionStrict.ts, 88, 44))
|
||||
>Container : Symbol(Container, Decl(intersectionReductionStrict.ts, 88, 44))
|
||||
>Container : Symbol(Container, Decl(intersectionReductionStrict.ts, 88, 44))
|
||||
>t : Symbol(t, Decl(intersectionReductionStrict.ts, 94, 12))
|
||||
|
||||
const f3 = (t: Container<"a"> | (Container<"b"> & { dataB: boolean } & Container<"a">)): Container<"a"> => t;
|
||||
>f3 : Symbol(f3, Decl(intersectionReductionStrict.ts, 95, 5))
|
||||
>t : Symbol(t, Decl(intersectionReductionStrict.ts, 95, 12))
|
||||
>Container : Symbol(Container, Decl(intersectionReductionStrict.ts, 88, 44))
|
||||
>Container : Symbol(Container, Decl(intersectionReductionStrict.ts, 88, 44))
|
||||
>dataB : Symbol(dataB, Decl(intersectionReductionStrict.ts, 95, 51))
|
||||
>Container : Symbol(Container, Decl(intersectionReductionStrict.ts, 88, 44))
|
||||
>Container : Symbol(Container, Decl(intersectionReductionStrict.ts, 88, 44))
|
||||
>t : Symbol(t, Decl(intersectionReductionStrict.ts, 95, 12))
|
||||
|
||||
const f4 = (t: number | (Container<"b"> & { dataB: boolean } & Container<"a">)): number => t;
|
||||
>f4 : Symbol(f4, Decl(intersectionReductionStrict.ts, 96, 5))
|
||||
>t : Symbol(t, Decl(intersectionReductionStrict.ts, 96, 12))
|
||||
>Container : Symbol(Container, Decl(intersectionReductionStrict.ts, 88, 44))
|
||||
>dataB : Symbol(dataB, Decl(intersectionReductionStrict.ts, 96, 43))
|
||||
>Container : Symbol(Container, Decl(intersectionReductionStrict.ts, 88, 44))
|
||||
>t : Symbol(t, Decl(intersectionReductionStrict.ts, 96, 12))
|
||||
|
||||
|
||||
@@ -88,6 +88,90 @@ type X6 = X | symbol & string;
|
||||
type X7 = X | void & string;
|
||||
>X7 : X
|
||||
|
||||
type A = { kind: 'a', foo: string };
|
||||
>A : A
|
||||
>kind : "a"
|
||||
>foo : string
|
||||
|
||||
type B = { kind: 'b', foo: number };
|
||||
>B : B
|
||||
>kind : "b"
|
||||
>foo : number
|
||||
|
||||
type C = { kind: 'c', foo: number };
|
||||
>C : C
|
||||
>kind : "c"
|
||||
>foo : number
|
||||
|
||||
declare let ab: A & B;
|
||||
>ab : never
|
||||
|
||||
ab.kind; // Error
|
||||
>ab.kind : any
|
||||
>ab : never
|
||||
>kind : any
|
||||
|
||||
declare let x: A | (B & C); // A
|
||||
>x : A
|
||||
|
||||
let a: A = x;
|
||||
>a : A
|
||||
>x : A
|
||||
|
||||
type AB = A & B; // never
|
||||
>AB : never
|
||||
|
||||
type BC = B & C; // never
|
||||
>BC : never
|
||||
|
||||
type U1 = Partial<A & B>; // never
|
||||
>U1 : never
|
||||
|
||||
type U2 = Readonly<A & B>; // never
|
||||
>U2 : never
|
||||
|
||||
type U3 = (A & B)['kind']; // never
|
||||
>U3 : never
|
||||
|
||||
type U4 = A & B | B & C; // never
|
||||
>U4 : never
|
||||
|
||||
type U5 = A | B & C; // A
|
||||
>U5 : A
|
||||
|
||||
type K1 = keyof (A & B); // string | number | symbol
|
||||
>K1 : string | number | symbol
|
||||
|
||||
type K2 = keyof A | keyof B; // 'kind' | 'foo'
|
||||
>K2 : "kind" | "foo"
|
||||
|
||||
type Merge1<T, U> = { [P in keyof (T & U)]: P extends keyof T ? T[P] : U[P & keyof U] }
|
||||
>Merge1 : Merge1<T, U>
|
||||
|
||||
type Merge2<T, U> = { [P in keyof T | keyof U]: P extends keyof T ? T[P] : U[P & keyof U] }
|
||||
>Merge2 : Merge2<T, U>
|
||||
|
||||
type M1 = { a: 1, b: 2 } & { a: 2, c: 3 }; // never
|
||||
>M1 : never
|
||||
>a : 1
|
||||
>b : 2
|
||||
>a : 2
|
||||
>c : 3
|
||||
|
||||
type M2 = Merge1<{ a: 1, b: 2 }, { a: 2, c: 3 }>; // {}
|
||||
>M2 : Merge1<{ a: 1; b: 2; }, { a: 2; c: 3; }>
|
||||
>a : 1
|
||||
>b : 2
|
||||
>a : 2
|
||||
>c : 3
|
||||
|
||||
type M3 = Merge2<{ a: 1, b: 2 }, { a: 2, c: 3 }>; // { a: 1, b: 2, c: 3 }
|
||||
>M3 : Merge2<{ a: 1; b: 2; }, { a: 2; c: 3; }>
|
||||
>a : 1
|
||||
>b : 2
|
||||
>a : 2
|
||||
>c : 3
|
||||
|
||||
// Repro from #31663
|
||||
|
||||
const x1 = { a: 'foo', b: 42 };
|
||||
@@ -163,3 +247,38 @@ t2 = t1;
|
||||
>t2 : undefined
|
||||
>t1 : undefined
|
||||
|
||||
// Repro from #36736
|
||||
|
||||
const f1 = (t: "a" | ("b" & "c")): "a" => t;
|
||||
>f1 : (t: "a") => "a"
|
||||
>(t: "a" | ("b" & "c")): "a" => t : (t: "a") => "a"
|
||||
>t : "a"
|
||||
>t : "a"
|
||||
|
||||
type Container<Type extends string> = {
|
||||
>Container : Container<Type>
|
||||
|
||||
type: Type;
|
||||
>type : Type
|
||||
}
|
||||
|
||||
const f2 = (t: Container<"a"> | (Container<"b"> & Container<"c">)): Container<"a"> => t;
|
||||
>f2 : (t: Container<"a">) => Container<"a">
|
||||
>(t: Container<"a"> | (Container<"b"> & Container<"c">)): Container<"a"> => t : (t: Container<"a">) => Container<"a">
|
||||
>t : Container<"a">
|
||||
>t : Container<"a">
|
||||
|
||||
const f3 = (t: Container<"a"> | (Container<"b"> & { dataB: boolean } & Container<"a">)): Container<"a"> => t;
|
||||
>f3 : (t: Container<"a">) => Container<"a">
|
||||
>(t: Container<"a"> | (Container<"b"> & { dataB: boolean } & Container<"a">)): Container<"a"> => t : (t: Container<"a">) => Container<"a">
|
||||
>t : Container<"a">
|
||||
>dataB : boolean
|
||||
>t : Container<"a">
|
||||
|
||||
const f4 = (t: number | (Container<"b"> & { dataB: boolean } & Container<"a">)): number => t;
|
||||
>f4 : (t: number) => number
|
||||
>(t: number | (Container<"b"> & { dataB: boolean } & Container<"a">)): number => t : (t: number) => number
|
||||
>t : number
|
||||
>dataB : boolean
|
||||
>t : number
|
||||
|
||||
|
||||
@@ -565,7 +565,7 @@ let overwriteId: { id: string, a: number, c: number, d: string } =
|
||||
>d : string
|
||||
|
||||
f({ a: 1, id: true }, { c: 1, d: 'no' })
|
||||
>f({ a: 1, id: true }, { c: 1, d: 'no' }) : { a: number; id: boolean; } & { c: number; d: string; } & { id: string; }
|
||||
>f({ a: 1, id: true }, { c: 1, d: 'no' }) : never
|
||||
>f : <T, U>(t: T, u: U) => T & U & { id: string; }
|
||||
>{ a: 1, id: true } : { a: number; id: true; }
|
||||
>a : number
|
||||
|
||||
@@ -6,9 +6,10 @@ tests/cases/conformance/types/mapped/recursiveMappedTypes.ts(11,6): error TS2456
|
||||
tests/cases/conformance/types/mapped/recursiveMappedTypes.ts(12,11): error TS2313: Type parameter 'K' has a circular constraint.
|
||||
tests/cases/conformance/types/mapped/recursiveMappedTypes.ts(20,19): error TS2589: Type instantiation is excessively deep and possibly infinite.
|
||||
tests/cases/conformance/types/mapped/recursiveMappedTypes.ts(66,25): error TS2313: Type parameter 'P' has a circular constraint.
|
||||
tests/cases/conformance/types/mapped/recursiveMappedTypes.ts(79,1): error TS2615: Type of property '"each"' circularly references itself in mapped type '{ type: never; minimum_count: never; maximum_count: never; collapsable?: never; each: never; }'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/types/mapped/recursiveMappedTypes.ts (8 errors) ====
|
||||
==== tests/cases/conformance/types/mapped/recursiveMappedTypes.ts (9 errors) ====
|
||||
// Recursive mapped types simply appear empty
|
||||
|
||||
type Recurse = {
|
||||
@@ -106,4 +107,6 @@ tests/cases/conformance/types/mapped/recursiveMappedTypes.ts(66,25): error TS231
|
||||
|
||||
declare let x: ListChild;
|
||||
x.type;
|
||||
~~~~~~
|
||||
!!! error TS2615: Type of property '"each"' circularly references itself in mapped type '{ type: never; minimum_count: never; maximum_count: never; collapsable?: never; each: never; }'.
|
||||
|
||||
@@ -93,6 +93,6 @@ if (!hasKind(x, "B")) {
|
||||
}
|
||||
else {
|
||||
let d = x;
|
||||
>d : A & B
|
||||
>x : A & B
|
||||
>d : never
|
||||
>x : never
|
||||
}
|
||||
|
||||
@@ -88,6 +88,6 @@ if (!hasKind(x, "B")) {
|
||||
}
|
||||
else {
|
||||
let d = x;
|
||||
>d : A & B
|
||||
>x : A & B
|
||||
>d : never
|
||||
>x : never
|
||||
}
|
||||
|
||||
@@ -92,6 +92,6 @@ if (!hasKind(x, "B")) {
|
||||
}
|
||||
else {
|
||||
let d = x;
|
||||
>d : A & B
|
||||
>x : A & B
|
||||
>d : never
|
||||
>x : never
|
||||
}
|
||||
|
||||
@@ -15,5 +15,4 @@ tests/cases/conformance/jsx/file.tsx(12,10): error TS2322: Type 'true' is not as
|
||||
var SFCComp = SFC1 || SFC2;
|
||||
<SFCComp x />
|
||||
~
|
||||
!!! error TS2322: Type 'true' is not assignable to type 'never'.
|
||||
!!! related TS6500 tests/cases/conformance/jsx/file.tsx:3:23: The expected type comes from property 'x' which is declared here on type 'IntrinsicAttributes & { x: number; } & { x: boolean; }'
|
||||
!!! error TS2322: Type 'true' is not assignable to type 'never'.
|
||||
@@ -15,5 +15,4 @@ tests/cases/conformance/jsx/file.tsx(12,10): error TS2322: Type 'string' is not
|
||||
var SFCComp = SFC1 || SFC2;
|
||||
<SFCComp x={"hi"}/>
|
||||
~
|
||||
!!! error TS2322: Type 'string' is not assignable to type 'never'.
|
||||
!!! related TS6500 tests/cases/conformance/jsx/file.tsx:3:23: The expected type comes from property 'x' which is declared here on type 'IntrinsicAttributes & { x: number; } & { x: boolean; }'
|
||||
!!! error TS2322: Type 'string' is not assignable to type 'never'.
|
||||
@@ -0,0 +1,14 @@
|
||||
tests/cases/conformance/expressions/typeGuards/typeGuardsWithInstanceOf.ts(7,20): error TS2339: Property 'global' does not exist on type 'never'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/expressions/typeGuards/typeGuardsWithInstanceOf.ts (1 errors) ====
|
||||
interface I { global: string; }
|
||||
var result: I;
|
||||
var result2: I;
|
||||
|
||||
if (!(result instanceof RegExp)) {
|
||||
result = result2;
|
||||
} else if (!result.global) {
|
||||
~~~~~~
|
||||
!!! error TS2339: Property 'global' does not exist on type 'never'.
|
||||
}
|
||||
@@ -20,7 +20,5 @@ if (!(result instanceof RegExp)) {
|
||||
>result2 : Symbol(result2, Decl(typeGuardsWithInstanceOf.ts, 2, 3))
|
||||
|
||||
} else if (!result.global) {
|
||||
>result.global : Symbol(global, Decl(typeGuardsWithInstanceOf.ts, 0, 13), Decl(lib.es5.d.ts, --, --))
|
||||
>result : Symbol(result, Decl(typeGuardsWithInstanceOf.ts, 1, 3))
|
||||
>global : Symbol(global, Decl(typeGuardsWithInstanceOf.ts, 0, 13), Decl(lib.es5.d.ts, --, --))
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ if (!(result instanceof RegExp)) {
|
||||
|
||||
} else if (!result.global) {
|
||||
>!result.global : boolean
|
||||
>result.global : never
|
||||
>result : I & RegExp
|
||||
>global : never
|
||||
>result.global : any
|
||||
>result : never
|
||||
>global : any
|
||||
}
|
||||
|
||||
@@ -32,6 +32,46 @@ type X5 = X | number & object;
|
||||
type X6 = X | symbol & string;
|
||||
type X7 = X | void & string;
|
||||
|
||||
type A = { kind: 'a', foo: string };
|
||||
type B = { kind: 'b', foo: number };
|
||||
type C = { kind: 'c', foo: number };
|
||||
|
||||
declare let ab: A & B;
|
||||
ab.kind; // Error
|
||||
|
||||
declare let x: A | (B & C); // A
|
||||
let a: A = x;
|
||||
|
||||
type AB = A & B; // never
|
||||
type BC = B & C; // never
|
||||
|
||||
type U1 = Partial<A & B>; // never
|
||||
type U2 = Readonly<A & B>; // never
|
||||
type U3 = (A & B)['kind']; // never
|
||||
type U4 = A & B | B & C; // never
|
||||
type U5 = A | B & C; // A
|
||||
|
||||
type K1 = keyof (A & B); // string | number | symbol
|
||||
type K2 = keyof A | keyof B; // 'kind' | 'foo'
|
||||
|
||||
type Merge1<T, U> = { [P in keyof (T & U)]: P extends keyof T ? T[P] : U[P & keyof U] }
|
||||
type Merge2<T, U> = { [P in keyof T | keyof U]: P extends keyof T ? T[P] : U[P & keyof U] }
|
||||
|
||||
type M1 = { a: 1, b: 2 } & { a: 2, c: 3 }; // never
|
||||
type M2 = Merge1<{ a: 1, b: 2 }, { a: 2, c: 3 }>; // {}
|
||||
type M3 = Merge2<{ a: 1, b: 2 }, { a: 2, c: 3 }>; // { a: 1, b: 2, c: 3 }
|
||||
|
||||
type D = { kind: 'd', foo: unknown };
|
||||
type E = { kind: 'e', foo: unknown };
|
||||
|
||||
declare function f10<T>(x: { foo: T }): T;
|
||||
|
||||
declare let a1: A | D;
|
||||
declare let a2: A | D & E;
|
||||
|
||||
let r1 = f10(a1); // unknown
|
||||
let r2 = f10(a2); // string
|
||||
|
||||
// Repro from #31663
|
||||
|
||||
const x1 = { a: 'foo', b: 42 };
|
||||
@@ -56,3 +96,15 @@ s2 = s1;
|
||||
|
||||
t1 = t2;
|
||||
t2 = t1;
|
||||
|
||||
// Repro from #36736
|
||||
|
||||
const f1 = (t: "a" | ("b" & "c")): "a" => t;
|
||||
|
||||
type Container<Type extends string> = {
|
||||
type: Type;
|
||||
}
|
||||
|
||||
const f2 = (t: Container<"a"> | (Container<"b"> & Container<"c">)): Container<"a"> => t;
|
||||
const f3 = (t: Container<"a"> | (Container<"b"> & { dataB: boolean } & Container<"a">)): Container<"a"> => t;
|
||||
const f4 = (t: number | (Container<"b"> & { dataB: boolean } & Container<"a">)): number => t;
|
||||
|
||||
@@ -32,6 +32,35 @@ type X5 = X | number & object;
|
||||
type X6 = X | symbol & string;
|
||||
type X7 = X | void & string;
|
||||
|
||||
type A = { kind: 'a', foo: string };
|
||||
type B = { kind: 'b', foo: number };
|
||||
type C = { kind: 'c', foo: number };
|
||||
|
||||
declare let ab: A & B;
|
||||
ab.kind; // Error
|
||||
|
||||
declare let x: A | (B & C); // A
|
||||
let a: A = x;
|
||||
|
||||
type AB = A & B; // never
|
||||
type BC = B & C; // never
|
||||
|
||||
type U1 = Partial<A & B>; // never
|
||||
type U2 = Readonly<A & B>; // never
|
||||
type U3 = (A & B)['kind']; // never
|
||||
type U4 = A & B | B & C; // never
|
||||
type U5 = A | B & C; // A
|
||||
|
||||
type K1 = keyof (A & B); // string | number | symbol
|
||||
type K2 = keyof A | keyof B; // 'kind' | 'foo'
|
||||
|
||||
type Merge1<T, U> = { [P in keyof (T & U)]: P extends keyof T ? T[P] : U[P & keyof U] }
|
||||
type Merge2<T, U> = { [P in keyof T | keyof U]: P extends keyof T ? T[P] : U[P & keyof U] }
|
||||
|
||||
type M1 = { a: 1, b: 2 } & { a: 2, c: 3 }; // never
|
||||
type M2 = Merge1<{ a: 1, b: 2 }, { a: 2, c: 3 }>; // {}
|
||||
type M3 = Merge2<{ a: 1, b: 2 }, { a: 2, c: 3 }>; // { a: 1, b: 2, c: 3 }
|
||||
|
||||
// Repro from #31663
|
||||
|
||||
const x1 = { a: 'foo', b: 42 };
|
||||
@@ -56,3 +85,15 @@ s2 = s1;
|
||||
|
||||
t1 = t2;
|
||||
t2 = t1;
|
||||
|
||||
// Repro from #36736
|
||||
|
||||
const f1 = (t: "a" | ("b" & "c")): "a" => t;
|
||||
|
||||
type Container<Type extends string> = {
|
||||
type: Type;
|
||||
}
|
||||
|
||||
const f2 = (t: Container<"a"> | (Container<"b"> & Container<"c">)): Container<"a"> => t;
|
||||
const f3 = (t: Container<"a"> | (Container<"b"> & { dataB: boolean } & Container<"a">)): Container<"a"> => t;
|
||||
const f4 = (t: number | (Container<"b"> & { dataB: boolean } & Container<"a">)): number => t;
|
||||
|
||||
@@ -131,7 +131,7 @@ function foo1(x: RuntimeValue & { type: 'number' }) {
|
||||
x.value; // number
|
||||
}
|
||||
else {
|
||||
x.value; // Error, x is never
|
||||
x.value; // number
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
/// <reference path='fourslash.ts'/>
|
||||
// #32708
|
||||
|
||||
////interface I<T> {
|
||||
//// /** only once please */
|
||||
//// t: T
|
||||
////}
|
||||
////interface C<T> extends I<T> {
|
||||
//// t: T
|
||||
////}
|
||||
////declare var cnsb: C<number> & C<string> & C<boolean>;
|
||||
////cnsb.t/**/
|
||||
|
||||
verify.quickInfoAt("", "(property) C<T>.t: never", "only once please");
|
||||
@@ -1,22 +0,0 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
//@Filename: file.tsx
|
||||
// @jsx: preserve
|
||||
// @skipLibCheck: true
|
||||
|
||||
//// declare module JSX {
|
||||
//// interface Element { }
|
||||
//// interface IntrinsicElements {
|
||||
//// }
|
||||
//// interface ElementAttributesProperty { props; }
|
||||
//// }
|
||||
//// function SFC1(prop: { x: number }) {
|
||||
//// return <div>hello </div>;
|
||||
//// };
|
||||
//// function SFC2(prop: { x: boolean }) {
|
||||
//// return <h1>World </h1>;
|
||||
//// }
|
||||
//// var SFCComp = SFC1 || SFC2;
|
||||
//// <SFCComp /**/ />
|
||||
|
||||
verify.completions({ marker: "", exact: ["x"] });
|
||||
Reference in New Issue
Block a user