mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-30 10:29:18 -05:00
Fixed the issue with some longer variadic tuples with any rest being incorrectly assignable to shorter variadic tuples (#50218)
This commit is contained in:
committed by
GitHub
parent
fdcb2ffd1b
commit
46b015f2bf
@@ -20592,28 +20592,35 @@ namespace ts {
|
||||
}
|
||||
const sourceTypeArguments = getTypeArguments(source);
|
||||
const targetTypeArguments = getTypeArguments(target);
|
||||
const startCount = Math.min(isTupleType(source) ? getStartElementCount(source.target, ElementFlags.NonRest) : 0, getStartElementCount(target.target, ElementFlags.NonRest));
|
||||
const endCount = Math.min(isTupleType(source) ? getEndElementCount(source.target, ElementFlags.NonRest) : 0, targetRestFlag ? getEndElementCount(target.target, ElementFlags.NonRest) : 0);
|
||||
const targetStartCount = getStartElementCount(target.target, ElementFlags.NonRest);
|
||||
const targetEndCount = getEndElementCount(target.target, ElementFlags.NonRest);
|
||||
const targetHasRestElement = target.target.hasRestElement;
|
||||
let canExcludeDiscriminants = !!excludedProperties;
|
||||
for (let i = 0; i < targetArity; i++) {
|
||||
const sourceIndex = i < targetArity - endCount ? i : i + sourceArity - targetArity;
|
||||
const sourceFlags = isTupleType(source) && (i < startCount || i >= targetArity - endCount) ? source.target.elementFlags[sourceIndex] : ElementFlags.Rest;
|
||||
const targetFlags = target.target.elementFlags[i];
|
||||
for (let sourcePosition = 0; sourcePosition < sourceArity; sourcePosition++) {
|
||||
const sourceFlags = isTupleType(source) ? source.target.elementFlags[sourcePosition] : ElementFlags.Rest;
|
||||
const sourcePositionFromEnd = sourceArity - 1 - sourcePosition;
|
||||
|
||||
const targetPosition = targetHasRestElement && sourcePosition >= targetStartCount
|
||||
? targetArity - 1 - Math.min(sourcePositionFromEnd, targetEndCount)
|
||||
: sourcePosition;
|
||||
|
||||
const targetFlags = target.target.elementFlags[targetPosition];
|
||||
|
||||
if (targetFlags & ElementFlags.Variadic && !(sourceFlags & ElementFlags.Variadic)) {
|
||||
if (reportErrors) {
|
||||
reportError(Diagnostics.Source_provides_no_match_for_variadic_element_at_position_0_in_target, i);
|
||||
reportError(Diagnostics.Source_provides_no_match_for_variadic_element_at_position_0_in_target, targetPosition);
|
||||
}
|
||||
return Ternary.False;
|
||||
}
|
||||
if (sourceFlags & ElementFlags.Variadic && !(targetFlags & ElementFlags.Variable)) {
|
||||
if (reportErrors) {
|
||||
reportError(Diagnostics.Variadic_element_at_position_0_in_source_does_not_match_element_at_position_1_in_target, sourceIndex, i);
|
||||
reportError(Diagnostics.Variadic_element_at_position_0_in_source_does_not_match_element_at_position_1_in_target, sourcePosition, targetPosition);
|
||||
}
|
||||
return Ternary.False;
|
||||
}
|
||||
if (targetFlags & ElementFlags.Required && !(sourceFlags & ElementFlags.Required)) {
|
||||
if (reportErrors) {
|
||||
reportError(Diagnostics.Source_provides_no_match_for_required_element_at_position_0_in_target, i);
|
||||
reportError(Diagnostics.Source_provides_no_match_for_required_element_at_position_0_in_target, targetPosition);
|
||||
}
|
||||
return Ternary.False;
|
||||
}
|
||||
@@ -20622,24 +20629,24 @@ namespace ts {
|
||||
if (sourceFlags & ElementFlags.Variable || targetFlags & ElementFlags.Variable) {
|
||||
canExcludeDiscriminants = false;
|
||||
}
|
||||
if (canExcludeDiscriminants && excludedProperties?.has(("" + i) as __String)) {
|
||||
if (canExcludeDiscriminants && excludedProperties?.has(("" + sourcePosition) as __String)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
const sourceType = !isTupleType(source) ? sourceTypeArguments[0] :
|
||||
i < startCount || i >= targetArity - endCount ? removeMissingType(sourceTypeArguments[sourceIndex], !!(sourceFlags & targetFlags & ElementFlags.Optional)) :
|
||||
getElementTypeOfSliceOfTupleType(source, startCount, endCount) || neverType;
|
||||
const targetType = targetTypeArguments[i];
|
||||
|
||||
const sourceType = removeMissingType(sourceTypeArguments[sourcePosition], !!(sourceFlags & targetFlags & ElementFlags.Optional));
|
||||
const targetType = targetTypeArguments[targetPosition];
|
||||
|
||||
const targetCheckType = sourceFlags & ElementFlags.Variadic && targetFlags & ElementFlags.Rest ? createArrayType(targetType) :
|
||||
removeMissingType(targetType, !!(targetFlags & ElementFlags.Optional));
|
||||
const related = isRelatedTo(sourceType, targetCheckType, RecursionFlags.Both, reportErrors, /*headMessage*/ undefined, intersectionState);
|
||||
if (!related) {
|
||||
if (reportErrors && (targetArity > 1 || sourceArity > 1)) {
|
||||
if (i < startCount || i >= targetArity - endCount || sourceArity - startCount - endCount === 1) {
|
||||
reportIncompatibleError(Diagnostics.Type_at_position_0_in_source_is_not_compatible_with_type_at_position_1_in_target, sourceIndex, i);
|
||||
if (targetHasRestElement && sourcePosition >= targetStartCount && sourcePositionFromEnd >= targetEndCount && targetStartCount !== sourceArity - targetEndCount - 1) {
|
||||
reportIncompatibleError(Diagnostics.Type_at_positions_0_through_1_in_source_is_not_compatible_with_type_at_position_2_in_target, targetStartCount, sourceArity - targetEndCount - 1, targetPosition);
|
||||
}
|
||||
else {
|
||||
reportIncompatibleError(Diagnostics.Type_at_positions_0_through_1_in_source_is_not_compatible_with_type_at_position_2_in_target, startCount, sourceArity - endCount - 1, i);
|
||||
reportIncompatibleError(Diagnostics.Type_at_position_0_in_source_is_not_compatible_with_type_at_position_1_in_target, sourcePosition, targetPosition);
|
||||
}
|
||||
}
|
||||
return Ternary.False;
|
||||
|
||||
@@ -5930,9 +5930,12 @@ namespace ts {
|
||||
|
||||
export interface TupleType extends GenericType {
|
||||
elementFlags: readonly ElementFlags[];
|
||||
minLength: number; // Number of required or variadic elements
|
||||
fixedLength: number; // Number of initial required or optional elements
|
||||
hasRestElement: boolean; // True if tuple has any rest or variadic elements
|
||||
/** Number of required or variadic elements */
|
||||
minLength: number;
|
||||
/** Number of initial required or optional elements */
|
||||
fixedLength: number;
|
||||
/** True if tuple has any rest or variadic elements */
|
||||
hasRestElement: boolean;
|
||||
combinedFlags: ElementFlags;
|
||||
readonly: boolean;
|
||||
labeledElementDeclarations?: readonly (NamedTupleMember | ParameterDeclaration)[];
|
||||
|
||||
Reference in New Issue
Block a user