mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-20 22:51:17 -05:00
Preserve literal types in contextual unions (#19966)
* Cherrypick non-comparability related changes from prolific literals PR * Renames and other style changes * Accept changes to new tests * Exclude the domain root from contextual typing literals except for type variables * Readd simple preservation fix * Add huge map test * Revert changes to widening on destructuring initalizers * Use tristate for subtype-reduction type * Rename type and argument * Move longer-running test to user suite
This commit is contained in:
@@ -4338,7 +4338,7 @@ namespace ts {
|
||||
type = getTypeWithFacts(type, TypeFacts.NEUndefined);
|
||||
}
|
||||
return declaration.initializer ?
|
||||
getUnionType([type, checkExpressionCached(declaration.initializer)], /*subtypeReduction*/ true) :
|
||||
getUnionType([type, checkExpressionCached(declaration.initializer)], UnionReduction.Subtype) :
|
||||
type;
|
||||
}
|
||||
|
||||
@@ -4506,7 +4506,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
const type = jsDocType || getUnionType(types, /*subtypeReduction*/ true);
|
||||
const type = jsDocType || getUnionType(types, UnionReduction.Subtype);
|
||||
return getWidenedType(addOptionality(type, definedInMethod && !definedInConstructor));
|
||||
}
|
||||
|
||||
@@ -5339,7 +5339,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
if (memberTypeList.length) {
|
||||
const enumType = getUnionType(memberTypeList, /*subtypeReduction*/ false, symbol, /*aliasTypeArguments*/ undefined);
|
||||
const enumType = getUnionType(memberTypeList, UnionReduction.Literal, symbol, /*aliasTypeArguments*/ undefined);
|
||||
if (enumType.flags & TypeFlags.Union) {
|
||||
enumType.flags |= TypeFlags.EnumLiteral;
|
||||
enumType.symbol = symbol;
|
||||
@@ -5902,7 +5902,7 @@ namespace ts {
|
||||
if (unionSignatures.length > 1) {
|
||||
let thisParameter = signature.thisParameter;
|
||||
if (forEach(unionSignatures, sig => sig.thisParameter)) {
|
||||
const thisType = getUnionType(map(unionSignatures, sig => getTypeOfSymbol(sig.thisParameter) || anyType), /*subtypeReduction*/ true);
|
||||
const thisType = getUnionType(map(unionSignatures, sig => getTypeOfSymbol(sig.thisParameter) || anyType), UnionReduction.Subtype);
|
||||
thisParameter = createSymbolWithType(signature.thisParameter, thisType);
|
||||
}
|
||||
s = cloneSignature(signature);
|
||||
@@ -5928,7 +5928,7 @@ namespace ts {
|
||||
indexTypes.push(indexInfo.type);
|
||||
isAnyReadonly = isAnyReadonly || indexInfo.isReadonly;
|
||||
}
|
||||
return createIndexInfo(getUnionType(indexTypes, /*subtypeReduction*/ true), isAnyReadonly);
|
||||
return createIndexInfo(getUnionType(indexTypes, UnionReduction.Subtype), isAnyReadonly);
|
||||
}
|
||||
|
||||
function resolveUnionTypeMembers(type: UnionType) {
|
||||
@@ -6616,7 +6616,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
if (propTypes.length) {
|
||||
return getUnionType(propTypes, /*subtypeReduction*/ true);
|
||||
return getUnionType(propTypes, UnionReduction.Subtype);
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
@@ -7003,7 +7003,7 @@ namespace ts {
|
||||
type = instantiateType(getReturnTypeOfSignature(signature.target), signature.mapper);
|
||||
}
|
||||
else if (signature.unionSignatures) {
|
||||
type = getUnionType(map(signature.unionSignatures, getReturnTypeOfSignature), /*subtypeReduction*/ true);
|
||||
type = getUnionType(map(signature.unionSignatures, getReturnTypeOfSignature), UnionReduction.Subtype);
|
||||
}
|
||||
else {
|
||||
type = getReturnTypeFromBody(<FunctionLikeDeclaration>signature.declaration);
|
||||
@@ -7845,7 +7845,7 @@ namespace ts {
|
||||
// expression constructs such as array literals and the || and ?: operators). Named types can
|
||||
// circularly reference themselves and therefore cannot be subtype reduced during their declaration.
|
||||
// For example, "type Item = string | (() => Item" is a named type that circularly references itself.
|
||||
function getUnionType(types: Type[], subtypeReduction?: boolean, aliasSymbol?: Symbol, aliasTypeArguments?: Type[]): Type {
|
||||
function getUnionType(types: Type[], unionReduction: UnionReduction = UnionReduction.Literal, aliasSymbol?: Symbol, aliasTypeArguments?: Type[]): Type {
|
||||
if (types.length === 0) {
|
||||
return neverType;
|
||||
}
|
||||
@@ -7857,11 +7857,15 @@ namespace ts {
|
||||
if (typeSet.containsAny) {
|
||||
return anyType;
|
||||
}
|
||||
if (subtypeReduction) {
|
||||
removeSubtypes(typeSet);
|
||||
}
|
||||
else if (typeSet.containsLiteralOrUniqueESSymbol) {
|
||||
removeRedundantLiteralTypes(typeSet);
|
||||
switch (unionReduction) {
|
||||
case UnionReduction.Literal:
|
||||
if (typeSet.containsLiteralOrUniqueESSymbol) {
|
||||
removeRedundantLiteralTypes(typeSet);
|
||||
}
|
||||
break;
|
||||
case UnionReduction.Subtype:
|
||||
removeSubtypes(typeSet);
|
||||
break;
|
||||
}
|
||||
if (typeSet.length === 0) {
|
||||
return typeSet.containsNull ? typeSet.containsNonWideningType ? nullType : nullWideningType :
|
||||
@@ -7937,7 +7941,7 @@ namespace ts {
|
||||
function getTypeFromUnionTypeNode(node: UnionTypeNode): Type {
|
||||
const links = getNodeLinks(node);
|
||||
if (!links.resolvedType) {
|
||||
links.resolvedType = getUnionType(map(node.types, getTypeFromTypeNode), /*subtypeReduction*/ false,
|
||||
links.resolvedType = getUnionType(map(node.types, getTypeFromTypeNode), UnionReduction.Literal,
|
||||
getAliasSymbolForTypeNode(node), getAliasTypeArgumentsForTypeNode(node));
|
||||
}
|
||||
return links.resolvedType;
|
||||
@@ -8012,7 +8016,7 @@ namespace ts {
|
||||
// the form X & A & Y | X & B & Y and recursively reduce until no union type constituents remain.
|
||||
const unionType = <UnionType>typeSet[unionIndex];
|
||||
return getUnionType(map(unionType.types, t => getIntersectionType(replaceElement(typeSet, unionIndex, t))),
|
||||
/*subtypeReduction*/ false, aliasSymbol, aliasTypeArguments);
|
||||
UnionReduction.Literal, aliasSymbol, aliasTypeArguments);
|
||||
}
|
||||
const id = getTypeListId(typeSet);
|
||||
let type = intersectionTypes.get(id);
|
||||
@@ -8851,7 +8855,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
if (type.flags & TypeFlags.Union && !(type.flags & TypeFlags.Primitive)) {
|
||||
return getUnionType(instantiateTypes((<UnionType>type).types, mapper), /*subtypeReduction*/ false, type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper));
|
||||
return getUnionType(instantiateTypes((<UnionType>type).types, mapper), UnionReduction.Literal, type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper));
|
||||
}
|
||||
if (type.flags & TypeFlags.Intersection) {
|
||||
return getIntersectionType(instantiateTypes((<IntersectionType>type).types, mapper), type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper));
|
||||
@@ -10713,7 +10717,7 @@ namespace ts {
|
||||
const primaryTypes = filter(types, t => !(t.flags & TypeFlags.Nullable));
|
||||
return primaryTypes.length ?
|
||||
getNullableType(getSupertypeOrUnion(primaryTypes), getFalsyFlagsOfTypes(types) & TypeFlags.Nullable) :
|
||||
getUnionType(types, /*subtypeReduction*/ true);
|
||||
getUnionType(types, UnionReduction.Subtype);
|
||||
}
|
||||
|
||||
// Return the leftmost type for which no type to the right is a subtype.
|
||||
@@ -11004,7 +11008,7 @@ namespace ts {
|
||||
// Widening an empty object literal transitions from a highly restrictive type to
|
||||
// a highly inclusive one. For that reason we perform subtype reduction here if the
|
||||
// union includes empty object types (e.g. reducing {} | string to just {}).
|
||||
return getUnionType(widenedTypes, some(widenedTypes, isEmptyObjectType));
|
||||
return getUnionType(widenedTypes, some(widenedTypes, isEmptyObjectType) ? UnionReduction.Subtype : UnionReduction.Literal);
|
||||
}
|
||||
if (isArrayType(type) || isTupleType(type)) {
|
||||
return createTypeReference((<TypeReference>type).target, sameMap((<TypeReference>type).typeArguments, getWidenedType));
|
||||
@@ -11251,7 +11255,7 @@ namespace ts {
|
||||
function inferTargetType(sourceType: Type): Type {
|
||||
inference.candidates = undefined;
|
||||
inferTypes(inferences, sourceType, templateType, 0, mappedTypeStack);
|
||||
return inference.candidates ? getUnionType(inference.candidates, /*subtypeReduction*/ true) : emptyObjectType;
|
||||
return inference.candidates ? getUnionType(inference.candidates, UnionReduction.Subtype) : emptyObjectType;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11610,7 +11614,7 @@ namespace ts {
|
||||
if (candidates.length > 1) {
|
||||
const objectLiterals = filter(candidates, isObjectLiteralType);
|
||||
if (objectLiterals.length) {
|
||||
const objectLiteralsType = getWidenedType(getUnionType(objectLiterals, /*subtypeReduction*/ true));
|
||||
const objectLiteralsType = getWidenedType(getUnionType(objectLiterals, UnionReduction.Subtype));
|
||||
return concatenate(filter(candidates, t => !isObjectLiteralType(t)), [objectLiteralsType]);
|
||||
}
|
||||
}
|
||||
@@ -11637,7 +11641,7 @@ namespace ts {
|
||||
// union types were requested or if all inferences were made from the return type position, infer a
|
||||
// union type. Otherwise, infer a common supertype.
|
||||
const unwidenedType = inference.priority & InferencePriority.Contravariant ? getCommonSubtype(baseCandidates) :
|
||||
context.flags & InferenceFlags.InferUnionTypes || inference.priority & InferencePriority.ReturnType ? getUnionType(baseCandidates, /*subtypeReduction*/ true) :
|
||||
context.flags & InferenceFlags.InferUnionTypes || inference.priority & InferencePriority.ReturnType ? getUnionType(baseCandidates, UnionReduction.Subtype) :
|
||||
getCommonSupertype(baseCandidates);
|
||||
inferredType = getWidenedType(unwidenedType);
|
||||
}
|
||||
@@ -12211,7 +12215,7 @@ namespace ts {
|
||||
// Apply a mapping function to a type and return the resulting type. If the source type
|
||||
// is a union type, the mapping function is applied to each constituent type and a union
|
||||
// of the resulting types is returned.
|
||||
function mapType(type: Type, mapper: (t: Type) => Type): Type {
|
||||
function mapType(type: Type, mapper: (t: Type) => Type, noReductions?: boolean): Type {
|
||||
if (!(type.flags & TypeFlags.Union)) {
|
||||
return mapper(type);
|
||||
}
|
||||
@@ -12232,7 +12236,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
}
|
||||
return mappedTypes ? getUnionType(mappedTypes) : mappedType;
|
||||
return mappedTypes ? getUnionType(mappedTypes, noReductions ? UnionReduction.None : UnionReduction.Literal) : mappedType;
|
||||
}
|
||||
|
||||
function extractTypesOfKind(type: Type, kind: TypeFlags) {
|
||||
@@ -12291,7 +12295,7 @@ namespace ts {
|
||||
return elementType.flags & TypeFlags.Never ?
|
||||
autoArrayType :
|
||||
createArrayType(elementType.flags & TypeFlags.Union ?
|
||||
getUnionType((<UnionType>elementType).types, /*subtypeReduction*/ true) :
|
||||
getUnionType((<UnionType>elementType).types, UnionReduction.Subtype) :
|
||||
elementType);
|
||||
}
|
||||
|
||||
@@ -12324,7 +12328,7 @@ namespace ts {
|
||||
// At flow control branch or loop junctions, if the type along every antecedent code path
|
||||
// is an evolving array type, we construct a combined evolving array type. Otherwise we
|
||||
// finalize all evolving array types.
|
||||
function getUnionOrEvolvingArrayType(types: Type[], subtypeReduction: boolean) {
|
||||
function getUnionOrEvolvingArrayType(types: Type[], subtypeReduction: UnionReduction) {
|
||||
return isEvolvingArrayTypeList(types) ?
|
||||
getEvolvingArrayType(getUnionType(map(types, getElementTypeOfEvolvingArrayType))) :
|
||||
getUnionType(sameMap(types, finalizeEvolvingArrayType), subtypeReduction);
|
||||
@@ -12616,7 +12620,7 @@ namespace ts {
|
||||
seenIncomplete = true;
|
||||
}
|
||||
}
|
||||
return createFlowType(getUnionOrEvolvingArrayType(antecedentTypes, subtypeReduction), seenIncomplete);
|
||||
return createFlowType(getUnionOrEvolvingArrayType(antecedentTypes, subtypeReduction ? UnionReduction.Subtype : UnionReduction.Literal), seenIncomplete);
|
||||
}
|
||||
|
||||
function getTypeAtFlowLoopLabel(flow: FlowLabel): FlowType {
|
||||
@@ -12645,7 +12649,7 @@ namespace ts {
|
||||
// path that leads to the top.
|
||||
for (let i = flowLoopStart; i < flowLoopCount; i++) {
|
||||
if (flowLoopNodes[i] === flow && flowLoopKeys[i] === key && flowLoopTypes[i].length) {
|
||||
return createFlowType(getUnionOrEvolvingArrayType(flowLoopTypes[i], /*subtypeReduction*/ false), /*incomplete*/ true);
|
||||
return createFlowType(getUnionOrEvolvingArrayType(flowLoopTypes[i], UnionReduction.Literal), /*incomplete*/ true);
|
||||
}
|
||||
}
|
||||
// Add the flow loop junction and reference to the in-process stack and analyze
|
||||
@@ -12687,7 +12691,7 @@ namespace ts {
|
||||
}
|
||||
// The result is incomplete if the first antecedent (the non-looping control flow path)
|
||||
// is incomplete.
|
||||
const result = getUnionOrEvolvingArrayType(antecedentTypes, subtypeReduction);
|
||||
const result = getUnionOrEvolvingArrayType(antecedentTypes, subtypeReduction ? UnionReduction.Subtype : UnionReduction.Literal);
|
||||
if (isIncomplete(firstAntecedentType)) {
|
||||
return createFlowType(result, /*incomplete*/ true);
|
||||
}
|
||||
@@ -14052,11 +14056,11 @@ namespace ts {
|
||||
return mapType(type, t => {
|
||||
const prop = t.flags & TypeFlags.StructuredType ? getPropertyOfType(t, name) : undefined;
|
||||
return prop ? getTypeOfSymbol(prop) : undefined;
|
||||
});
|
||||
}, /*noReductions*/ true);
|
||||
}
|
||||
|
||||
function getIndexTypeOfContextualType(type: Type, kind: IndexKind) {
|
||||
return mapType(type, t => getIndexTypeOfStructuredType(t, kind));
|
||||
return mapType(type, t => getIndexTypeOfStructuredType(t, kind), /*noReductions*/ true);
|
||||
}
|
||||
|
||||
// Return true if the given contextual type is a tuple-like type
|
||||
@@ -14463,7 +14467,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
return createArrayType(elementTypes.length ?
|
||||
getUnionType(elementTypes, /*subtypeReduction*/ true) :
|
||||
getUnionType(elementTypes, UnionReduction.Subtype) :
|
||||
strictNullChecks ? implicitNeverType : undefinedWideningType);
|
||||
}
|
||||
|
||||
@@ -14542,7 +14546,7 @@ namespace ts {
|
||||
propTypes.push(getTypeOfSymbol(properties[i]));
|
||||
}
|
||||
}
|
||||
const unionType = propTypes.length ? getUnionType(propTypes, /*subtypeReduction*/ true) : undefinedType;
|
||||
const unionType = propTypes.length ? getUnionType(propTypes, UnionReduction.Subtype) : undefinedType;
|
||||
return createIndexInfo(unionType, /*isReadonly*/ false);
|
||||
}
|
||||
|
||||
@@ -14889,7 +14893,7 @@ namespace ts {
|
||||
const childrenPropSymbol = createSymbol(SymbolFlags.Property | SymbolFlags.Transient, jsxChildrenPropertyName);
|
||||
childrenPropSymbol.type = childrenTypes.length === 1 ?
|
||||
childrenTypes[0] :
|
||||
createArrayType(getUnionType(childrenTypes, /*subtypeReduction*/ false));
|
||||
createArrayType(getUnionType(childrenTypes));
|
||||
attributesTable.set(jsxChildrenPropertyName, childrenPropSymbol);
|
||||
}
|
||||
}
|
||||
@@ -15025,7 +15029,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
return getUnionType(map(instantiatedSignatures, getReturnTypeOfSignature), /*subtypeReduction*/ true);
|
||||
return getUnionType(map(instantiatedSignatures, getReturnTypeOfSignature), UnionReduction.Subtype);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -15217,7 +15221,7 @@ namespace ts {
|
||||
const types = (elementType as UnionType).types;
|
||||
return getUnionType(types.map(type => {
|
||||
return resolveCustomJsxElementAttributesType(openingLikeElement, shouldIncludeAllStatelessAttributesType, type, elementClassType);
|
||||
}), /*subtypeReduction*/ true);
|
||||
}), UnionReduction.Subtype);
|
||||
}
|
||||
|
||||
// If the elemType is a string type, we have to return anyType to prevent an error downstream as we will try to find construct or call signature of the type
|
||||
@@ -17968,7 +17972,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
// Return a union of the return expression types.
|
||||
type = getUnionType(types, /*subtypeReduction*/ true);
|
||||
type = getUnionType(types, UnionReduction.Subtype);
|
||||
}
|
||||
|
||||
if (!contextualSignature) {
|
||||
@@ -18876,7 +18880,7 @@ namespace ts {
|
||||
leftType;
|
||||
case SyntaxKind.BarBarToken:
|
||||
return getTypeFacts(leftType) & TypeFacts.Falsy ?
|
||||
getUnionType([removeDefinitelyFalsyTypes(leftType), rightType], /*subtypeReduction*/ true) :
|
||||
getUnionType([removeDefinitelyFalsyTypes(leftType), rightType], UnionReduction.Subtype) :
|
||||
leftType;
|
||||
case SyntaxKind.EqualsToken:
|
||||
checkAssignmentOperator(rightType);
|
||||
@@ -19036,7 +19040,7 @@ namespace ts {
|
||||
checkExpression(node.condition);
|
||||
const type1 = checkExpression(node.whenTrue, checkMode);
|
||||
const type2 = checkExpression(node.whenFalse, checkMode);
|
||||
return getUnionType([type1, type2], /*subtypeReduction*/ true);
|
||||
return getUnionType([type1, type2], UnionReduction.Subtype);
|
||||
}
|
||||
|
||||
function checkTemplateExpression(node: TemplateExpression): Type {
|
||||
@@ -20477,7 +20481,7 @@ namespace ts {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return typeAsPromise.promisedTypeOfPromise = getUnionType(map(onfulfilledParameterSignatures, getTypeOfFirstParameterOfSignature), /*subtypeReduction*/ true);
|
||||
return typeAsPromise.promisedTypeOfPromise = getUnionType(map(onfulfilledParameterSignatures, getTypeOfFirstParameterOfSignature), UnionReduction.Subtype);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -21908,7 +21912,7 @@ namespace ts {
|
||||
const arrayTypes = (<UnionType>inputType).types;
|
||||
const filteredTypes = filter(arrayTypes, t => !(t.flags & TypeFlags.StringLike));
|
||||
if (filteredTypes !== arrayTypes) {
|
||||
arrayType = getUnionType(filteredTypes, /*subtypeReduction*/ true);
|
||||
arrayType = getUnionType(filteredTypes, UnionReduction.Subtype);
|
||||
}
|
||||
}
|
||||
else if (arrayType.flags & TypeFlags.StringLike) {
|
||||
@@ -21958,7 +21962,7 @@ namespace ts {
|
||||
return stringType;
|
||||
}
|
||||
|
||||
return getUnionType([arrayElementType, stringType], /*subtypeReduction*/ true);
|
||||
return getUnionType([arrayElementType, stringType], UnionReduction.Subtype);
|
||||
}
|
||||
|
||||
return arrayElementType;
|
||||
@@ -22056,7 +22060,7 @@ namespace ts {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const returnType = getUnionType(map(signatures, getReturnTypeOfSignature), /*subtypeReduction*/ true);
|
||||
const returnType = getUnionType(map(signatures, getReturnTypeOfSignature), UnionReduction.Subtype);
|
||||
const iteratedType = getIteratedTypeOfIterator(returnType, errorNode, /*isAsyncIterator*/ !!asyncMethodType);
|
||||
if (checkAssignability && errorNode && iteratedType) {
|
||||
// If `checkAssignability` was specified, we were called from
|
||||
@@ -22131,7 +22135,7 @@ namespace ts {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
let nextResult = getUnionType(map(nextMethodSignatures, getReturnTypeOfSignature), /*subtypeReduction*/ true);
|
||||
let nextResult = getUnionType(map(nextMethodSignatures, getReturnTypeOfSignature), UnionReduction.Subtype);
|
||||
if (isTypeAny(nextResult)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -2787,7 +2787,7 @@ namespace ts {
|
||||
/* @internal */ getNullType(): Type;
|
||||
/* @internal */ getESSymbolType(): Type;
|
||||
/* @internal */ getNeverType(): Type;
|
||||
/* @internal */ getUnionType(types: Type[], subtypeReduction?: boolean): Type;
|
||||
/* @internal */ getUnionType(types: Type[], subtypeReduction?: UnionReduction): Type;
|
||||
/* @internal */ createArrayType(elementType: Type): Type;
|
||||
/* @internal */ createPromiseType(type: Type): Type;
|
||||
|
||||
@@ -2842,6 +2842,13 @@ namespace ts {
|
||||
/* @internal */ getAccessibleSymbolChain(symbol: Symbol, enclosingDeclaration: Node | undefined, meaning: SymbolFlags, useOnlyExternalAliasing: boolean): Symbol[] | undefined;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export const enum UnionReduction {
|
||||
None = 0,
|
||||
Literal,
|
||||
Subtype
|
||||
}
|
||||
|
||||
export enum NodeBuilderFlags {
|
||||
None = 0,
|
||||
// Options
|
||||
|
||||
@@ -305,7 +305,7 @@ namespace ts.codefix {
|
||||
}
|
||||
}
|
||||
if (types.length) {
|
||||
const type = checker.getWidenedType(checker.getUnionType(types, /*subtypeReduction*/ true));
|
||||
const type = checker.getWidenedType(checker.getUnionType(types, UnionReduction.Subtype));
|
||||
paramTypes[parameterIndex] = isRestParameter ? checker.createArrayType(type) : type;
|
||||
}
|
||||
}
|
||||
@@ -542,12 +542,12 @@ namespace ts.codefix {
|
||||
return checker.getStringType();
|
||||
}
|
||||
else if (usageContext.candidateTypes) {
|
||||
return checker.getWidenedType(checker.getUnionType(map(usageContext.candidateTypes, t => checker.getBaseTypeOfLiteralType(t)), /*subtypeReduction*/ true));
|
||||
return checker.getWidenedType(checker.getUnionType(map(usageContext.candidateTypes, t => checker.getBaseTypeOfLiteralType(t)), UnionReduction.Subtype));
|
||||
}
|
||||
else if (usageContext.properties && hasCallContext(usageContext.properties.get("then" as __String))) {
|
||||
const paramType = getParameterTypeFromCallContexts(0, usageContext.properties.get("then" as __String).callContexts, /*isRestParameter*/ false, checker);
|
||||
const types = paramType.getCallSignatures().map(c => c.getReturnType());
|
||||
return checker.createPromiseType(types.length ? checker.getUnionType(types, /*subtypeReduction*/ true) : checker.getAnyType());
|
||||
return checker.createPromiseType(types.length ? checker.getUnionType(types, UnionReduction.Subtype) : checker.getAnyType());
|
||||
}
|
||||
else if (usageContext.properties && hasCallContext(usageContext.properties.get("push" as __String))) {
|
||||
return checker.createArrayType(getParameterTypeFromCallContexts(0, usageContext.properties.get("push" as __String).callContexts, /*isRestParameter*/ false, checker));
|
||||
@@ -610,7 +610,7 @@ namespace ts.codefix {
|
||||
}
|
||||
|
||||
if (types.length) {
|
||||
const type = checker.getWidenedType(checker.getUnionType(types, /*subtypeReduction*/ true));
|
||||
const type = checker.getWidenedType(checker.getUnionType(types, UnionReduction.Subtype));
|
||||
return isRestParameter ? checker.createArrayType(type) : type;
|
||||
}
|
||||
return undefined;
|
||||
|
||||
Reference in New Issue
Block a user