Merge pull request #26676 from Microsoft/complexRestParameterTypes
Improve checking of complex rest parameter types
This commit is contained in:
commit
d066e1e9e3
|
@ -7823,8 +7823,12 @@ namespace ts {
|
|||
}
|
||||
|
||||
function tryGetRestTypeOfSignature(signature: Signature): Type | undefined {
|
||||
const type = getTypeOfRestParameter(signature);
|
||||
return type && getIndexTypeOfType(type, IndexKind.Number);
|
||||
if (signature.hasRestParameter) {
|
||||
const sigRestType = getTypeOfSymbol(signature.parameters[signature.parameters.length - 1]);
|
||||
const restType = isTupleType(sigRestType) ? getRestTypeOfTupleType(sigRestType) : sigRestType;
|
||||
return restType && getIndexTypeOfType(restType, IndexKind.Number);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function getSignatureInstantiation(signature: Signature, typeArguments: Type[] | undefined, isJavascript: boolean): Signature {
|
||||
|
@ -10720,9 +10724,10 @@ namespace ts {
|
|||
}
|
||||
|
||||
const sourceCount = getParameterCount(source);
|
||||
const sourceGenericRestType = getGenericRestType(source);
|
||||
const targetGenericRestType = sourceGenericRestType ? getGenericRestType(target) : undefined;
|
||||
if (sourceGenericRestType && !(targetGenericRestType && sourceCount === targetCount)) {
|
||||
const sourceRestType = getNonArrayRestType(source);
|
||||
const targetRestType = getNonArrayRestType(target);
|
||||
if (sourceRestType && targetRestType && sourceCount !== targetCount) {
|
||||
// We're not able to relate misaligned complex rest parameters
|
||||
return Ternary.False;
|
||||
}
|
||||
|
||||
|
@ -10748,11 +10753,12 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
|
||||
const paramCount = Math.max(sourceCount, targetCount);
|
||||
const lastIndex = paramCount - 1;
|
||||
const paramCount = sourceRestType || targetRestType ? Math.min(sourceCount, targetCount) : Math.max(sourceCount, targetCount);
|
||||
const restIndex = sourceRestType || targetRestType ? paramCount - 1 : -1;
|
||||
|
||||
for (let i = 0; i < paramCount; i++) {
|
||||
const sourceType = i === lastIndex && sourceGenericRestType || getTypeAtPosition(source, i);
|
||||
const targetType = i === lastIndex && targetGenericRestType || getTypeAtPosition(target, i);
|
||||
const sourceType = i === restIndex ? getRestTypeAtPosition(source, i) : getTypeAtPosition(source, i);
|
||||
const targetType = i === restIndex ? getRestTypeAtPosition(target, i) : getTypeAtPosition(target, i);
|
||||
// In order to ensure that any generic type Foo<T> is at least co-variant with respect to T no matter
|
||||
// how Foo uses T, we need to relate parameters bi-variantly (given that parameters are input positions,
|
||||
// they naturally relate only contra-variantly). However, if the source and target parameters both have
|
||||
|
@ -12704,6 +12710,11 @@ namespace ts {
|
|||
return type.target.hasRestElement ? type.typeArguments![type.target.typeParameters!.length - 1] : undefined;
|
||||
}
|
||||
|
||||
function getRestArrayTypeOfTupleType(type: TupleTypeReference) {
|
||||
const restType = getRestTypeOfTupleType(type);
|
||||
return restType && createArrayType(restType);
|
||||
}
|
||||
|
||||
function getLengthOfTupleType(type: TupleTypeReference) {
|
||||
return getTypeReferenceArity(type) - (type.target.hasRestElement ? 1 : 0);
|
||||
}
|
||||
|
@ -13049,19 +13060,16 @@ namespace ts {
|
|||
function forEachMatchingParameterType(source: Signature, target: Signature, callback: (s: Type, t: Type) => void) {
|
||||
const sourceCount = getParameterCount(source);
|
||||
const targetCount = getParameterCount(target);
|
||||
const sourceHasRest = hasEffectiveRestParameter(source);
|
||||
const targetHasRest = hasEffectiveRestParameter(target);
|
||||
const maxCount = sourceHasRest && targetHasRest ? Math.max(sourceCount, targetCount) :
|
||||
sourceHasRest ? targetCount :
|
||||
targetHasRest ? sourceCount :
|
||||
const sourceRestType = getEffectiveRestType(source);
|
||||
const targetRestType = getEffectiveRestType(target);
|
||||
const paramCount = targetRestType ? Math.min(targetCount - 1, sourceCount) :
|
||||
sourceRestType ? targetCount :
|
||||
Math.min(sourceCount, targetCount);
|
||||
const targetGenericRestType = getGenericRestType(target);
|
||||
const paramCount = targetGenericRestType ? Math.min(targetCount - 1, maxCount) : maxCount;
|
||||
for (let i = 0; i < paramCount; i++) {
|
||||
callback(getTypeAtPosition(source, i), getTypeAtPosition(target, i));
|
||||
}
|
||||
if (targetGenericRestType) {
|
||||
callback(getRestTypeAtPosition(source, paramCount), targetGenericRestType);
|
||||
if (targetRestType) {
|
||||
callback(getRestTypeAtPosition(source, paramCount), targetRestType);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -13521,32 +13529,37 @@ namespace ts {
|
|||
}
|
||||
|
||||
function inferFromProperties(source: Type, target: Type) {
|
||||
if (isTupleType(source) && isTupleType(target)) {
|
||||
const sourceLength = getLengthOfTupleType(source);
|
||||
const targetLength = getLengthOfTupleType(target);
|
||||
const sourceRestType = getRestTypeOfTupleType(source);
|
||||
const targetRestType = getRestTypeOfTupleType(target);
|
||||
const fixedLength = targetLength < sourceLength || sourceRestType ? targetLength : sourceLength;
|
||||
for (let i = 0; i < fixedLength; i++) {
|
||||
inferFromTypes(i < sourceLength ? source.typeArguments![i] : sourceRestType!, target.typeArguments![i]);
|
||||
if (isTupleType(source)) {
|
||||
if (isTupleType(target)) {
|
||||
const sourceLength = getLengthOfTupleType(source);
|
||||
const targetLength = getLengthOfTupleType(target);
|
||||
const sourceRestType = getRestTypeOfTupleType(source);
|
||||
const targetRestType = getRestTypeOfTupleType(target);
|
||||
const fixedLength = targetLength < sourceLength || sourceRestType ? targetLength : sourceLength;
|
||||
for (let i = 0; i < fixedLength; i++) {
|
||||
inferFromTypes(i < sourceLength ? source.typeArguments![i] : sourceRestType!, target.typeArguments![i]);
|
||||
}
|
||||
if (targetRestType) {
|
||||
const types = fixedLength < sourceLength ? source.typeArguments!.slice(fixedLength, sourceLength) : [];
|
||||
if (sourceRestType) {
|
||||
types.push(sourceRestType);
|
||||
}
|
||||
if (types.length) {
|
||||
inferFromTypes(getUnionType(types), targetRestType);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (targetRestType) {
|
||||
const types = fixedLength < sourceLength ? source.typeArguments!.slice(fixedLength, sourceLength) : [];
|
||||
if (sourceRestType) {
|
||||
types.push(sourceRestType);
|
||||
}
|
||||
if (types.length) {
|
||||
inferFromTypes(getUnionType(types), targetRestType);
|
||||
}
|
||||
if (isArrayType(target)) {
|
||||
inferFromIndexTypes(source, target);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
const properties = getPropertiesOfObjectType(target);
|
||||
for (const targetProp of properties) {
|
||||
const sourceProp = getPropertyOfType(source, targetProp.escapedName);
|
||||
if (sourceProp) {
|
||||
inferFromTypes(getTypeOfSymbol(sourceProp), getTypeOfSymbol(targetProp));
|
||||
}
|
||||
const properties = getPropertiesOfObjectType(target);
|
||||
for (const targetProp of properties) {
|
||||
const sourceProp = getPropertyOfType(source, targetProp.escapedName);
|
||||
if (sourceProp) {
|
||||
inferFromTypes(getTypeOfSymbol(sourceProp), getTypeOfSymbol(targetProp));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18693,8 +18706,8 @@ namespace ts {
|
|||
inferTypes(context.inferences, thisArgumentType, thisType);
|
||||
}
|
||||
|
||||
const genericRestType = getGenericRestType(signature);
|
||||
const argCount = genericRestType ? Math.min(getParameterCount(signature) - 1, args.length) : args.length;
|
||||
const restType = getNonArrayRestType(signature);
|
||||
const argCount = restType ? Math.min(getParameterCount(signature) - 1, args.length) : args.length;
|
||||
for (let i = 0; i < argCount; i++) {
|
||||
const arg = args[i];
|
||||
if (arg.kind !== SyntaxKind.OmittedExpression) {
|
||||
|
@ -18707,14 +18720,21 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
|
||||
if (genericRestType) {
|
||||
const spreadType = getSpreadArgumentType(args, argCount, args.length, genericRestType, context);
|
||||
inferTypes(context.inferences, spreadType, genericRestType);
|
||||
if (restType) {
|
||||
const spreadType = getSpreadArgumentType(args, argCount, args.length, restType, context);
|
||||
inferTypes(context.inferences, spreadType, restType);
|
||||
}
|
||||
|
||||
return getInferredTypes(context);
|
||||
}
|
||||
|
||||
function getArrayifiedType(type: Type) {
|
||||
if (forEachType(type, t => !(t.flags & (TypeFlags.Any | TypeFlags.Instantiable) || isArrayType(t) || isTupleType(t)))) {
|
||||
return createArrayType(getIndexTypeOfType(type, IndexKind.Number) || errorType);
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
function getSpreadArgumentType(args: ReadonlyArray<Expression>, index: number, argCount: number, restType: TypeParameter, context: InferenceContext | undefined) {
|
||||
if (index >= argCount - 1) {
|
||||
const arg = args[argCount - 1];
|
||||
|
@ -18723,7 +18743,7 @@ namespace ts {
|
|||
// and the argument are ...x forms.
|
||||
return arg.kind === SyntaxKind.SyntheticExpression ?
|
||||
createArrayType((<SyntheticExpression>arg).type) :
|
||||
checkExpressionWithContextualType((<SpreadElement>arg).expression, restType, context);
|
||||
getArrayifiedType(checkExpressionWithContextualType((<SpreadElement>arg).expression, restType, context));
|
||||
}
|
||||
}
|
||||
const contextualType = getIndexTypeOfType(restType, IndexKind.Number) || anyType;
|
||||
|
@ -18828,28 +18848,27 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
const headMessage = Diagnostics.Argument_of_type_0_is_not_assignable_to_parameter_of_type_1;
|
||||
const restIndex = signature.hasRestParameter ? signature.parameters.length - 1 : -1;
|
||||
const restType = restIndex >= 0 ? getTypeOfSymbol(signature.parameters[restIndex]) : anyType;
|
||||
for (let i = 0; i < args.length; i++) {
|
||||
const restType = getNonArrayRestType(signature);
|
||||
const argCount = restType ? Math.min(getParameterCount(signature) - 1, args.length) : args.length;
|
||||
for (let i = 0; i < argCount; i++) {
|
||||
const arg = args[i];
|
||||
if (arg.kind !== SyntaxKind.OmittedExpression) {
|
||||
if (i === restIndex && (restType.flags & TypeFlags.TypeParameter || isSpreadArgument(arg) && !isArrayType(restType))) {
|
||||
const spreadType = getSpreadArgumentType(args, i, args.length, restType, /*context*/ undefined);
|
||||
return checkTypeRelatedTo(spreadType, restType, relation, arg, headMessage);
|
||||
}
|
||||
else {
|
||||
const paramType = getTypeAtPosition(signature, i);
|
||||
const argType = checkExpressionWithContextualType(arg, paramType, excludeArgument && excludeArgument[i] ? identityMapper : undefined);
|
||||
// If one or more arguments are still excluded (as indicated by a non-null excludeArgument parameter),
|
||||
// we obtain the regular type of any object literal arguments because we may not have inferred complete
|
||||
// parameter types yet and therefore excess property checks may yield false positives (see #17041).
|
||||
const checkArgType = excludeArgument ? getRegularTypeOfObjectLiteral(argType) : argType;
|
||||
if (!checkTypeRelatedTo(checkArgType, paramType, relation, reportErrors ? arg : undefined, headMessage)) {
|
||||
return false;
|
||||
}
|
||||
const paramType = getTypeAtPosition(signature, i);
|
||||
const argType = checkExpressionWithContextualType(arg, paramType, excludeArgument && excludeArgument[i] ? identityMapper : undefined);
|
||||
// If one or more arguments are still excluded (as indicated by a non-null excludeArgument parameter),
|
||||
// we obtain the regular type of any object literal arguments because we may not have inferred complete
|
||||
// parameter types yet and therefore excess property checks may yield false positives (see #17041).
|
||||
const checkArgType = excludeArgument ? getRegularTypeOfObjectLiteral(argType) : argType;
|
||||
if (!checkTypeRelatedTo(checkArgType, paramType, relation, reportErrors ? arg : undefined, headMessage)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (restType) {
|
||||
const spreadType = getSpreadArgumentType(args, argCount, args.length, restType, /*context*/ undefined);
|
||||
const errorNode = reportErrors ? argCount < args.length ? args[argCount] : node : undefined;
|
||||
return checkTypeRelatedTo(spreadType, restType, relation, errorNode, headMessage);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -19189,7 +19208,7 @@ namespace ts {
|
|||
checkCandidate = getSignatureInstantiation(candidate, typeArgumentTypes, isInJavaScriptFile(candidate.declaration));
|
||||
// If the original signature has a generic rest type, instantiation may produce a
|
||||
// signature with different arity and we need to perform another arity check.
|
||||
if (getGenericRestType(candidate) && !hasCorrectArity(node, args, checkCandidate, signatureHelpTrailingComma)) {
|
||||
if (getNonArrayRestType(candidate) && !hasCorrectArity(node, args, checkCandidate, signatureHelpTrailingComma)) {
|
||||
candidateForArgumentArityError = checkCandidate;
|
||||
continue;
|
||||
}
|
||||
|
@ -20167,14 +20186,11 @@ namespace ts {
|
|||
|
||||
function getRestTypeAtPosition(source: Signature, pos: number): Type {
|
||||
const paramCount = getParameterCount(source);
|
||||
const hasRest = hasEffectiveRestParameter(source);
|
||||
if (hasRest && pos === paramCount - 1) {
|
||||
const genericRestType = getGenericRestType(source);
|
||||
if (genericRestType) {
|
||||
return genericRestType;
|
||||
}
|
||||
const restType = getEffectiveRestType(source);
|
||||
if (restType && pos === paramCount - 1) {
|
||||
return restType;
|
||||
}
|
||||
const start = hasRest ? Math.min(pos, paramCount - 1) : pos;
|
||||
const start = restType ? Math.min(pos, paramCount - 1) : pos;
|
||||
const types = [];
|
||||
const names = [];
|
||||
for (let i = start; i < paramCount; i++) {
|
||||
|
@ -20183,18 +20199,7 @@ namespace ts {
|
|||
}
|
||||
const minArgumentCount = getMinArgumentCount(source);
|
||||
const minLength = minArgumentCount < start ? 0 : minArgumentCount - start;
|
||||
return createTupleType(types, minLength, hasRest, names);
|
||||
}
|
||||
|
||||
function getTypeOfRestParameter(signature: Signature) {
|
||||
if (signature.hasRestParameter) {
|
||||
const restType = getTypeOfSymbol(signature.parameters[signature.parameters.length - 1]);
|
||||
if (isTupleType(restType)) {
|
||||
return getRestTypeOfTupleType(restType);
|
||||
}
|
||||
return restType;
|
||||
}
|
||||
return undefined;
|
||||
return createTupleType(types, minLength, !!restType, names);
|
||||
}
|
||||
|
||||
function getParameterCount(signature: Signature) {
|
||||
|
@ -20221,16 +20226,6 @@ namespace ts {
|
|||
return signature.minArgumentCount;
|
||||
}
|
||||
|
||||
function getGenericRestType(signature: Signature) {
|
||||
if (signature.hasRestParameter) {
|
||||
const restType = getTypeOfSymbol(signature.parameters[signature.parameters.length - 1]);
|
||||
if (restType.flags & TypeFlags.Instantiable) {
|
||||
return restType;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function hasEffectiveRestParameter(signature: Signature) {
|
||||
if (signature.hasRestParameter) {
|
||||
const restType = getTypeOfSymbol(signature.parameters[signature.parameters.length - 1]);
|
||||
|
@ -20239,6 +20234,19 @@ namespace ts {
|
|||
return false;
|
||||
}
|
||||
|
||||
function getEffectiveRestType(signature: Signature) {
|
||||
if (signature.hasRestParameter) {
|
||||
const restType = getTypeOfSymbol(signature.parameters[signature.parameters.length - 1]);
|
||||
return isTupleType(restType) ? getRestArrayTypeOfTupleType(restType) : restType;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function getNonArrayRestType(signature: Signature) {
|
||||
const restType = getEffectiveRestType(signature);
|
||||
return restType && !isArrayType(restType) && !isTypeAny(restType) ? restType : undefined;
|
||||
}
|
||||
|
||||
function getTypeOfFirstParameterOfSignature(signature: Signature) {
|
||||
return getTypeOfFirstParameterOfSignatureWithFallback(signature, neverType);
|
||||
}
|
||||
|
@ -21928,10 +21936,6 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
|
||||
function isRestParameterType(type: Type) {
|
||||
return isArrayType(type) || isTupleType(type) || type.flags & TypeFlags.Instantiable && isTypeAssignableTo(type, anyArrayType);
|
||||
}
|
||||
|
||||
function checkParameter(node: ParameterDeclaration) {
|
||||
// Grammar checking
|
||||
// It is a SyntaxError if the Identifier "eval" or the Identifier "arguments" occurs as the
|
||||
|
@ -21963,7 +21967,7 @@ namespace ts {
|
|||
|
||||
// Only check rest parameter type if it's not a binding pattern. Since binding patterns are
|
||||
// not allowed in a rest parameter, we already have an error from checkGrammarParameterList.
|
||||
if (node.dotDotDotToken && !isBindingPattern(node.name) && !isRestParameterType(getTypeOfSymbol(node.symbol))) {
|
||||
if (node.dotDotDotToken && !isBindingPattern(node.name) && !isTypeAssignableTo(getTypeOfSymbol(node.symbol), anyArrayType)) {
|
||||
error(node, Diagnostics.A_rest_parameter_must_be_of_an_array_type);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration4.ts(13,13): error TS2370: A rest parameter must be of an array type.
|
||||
tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration4.ts(14,17): error TS1047: A rest parameter cannot be optional.
|
||||
tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration4.ts(15,16): error TS1048: A rest parameter cannot have an initializer.
|
||||
tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration4.ts(20,19): error TS2345: Argument of type 'true' is not assignable to parameter of type 'string | number'.
|
||||
|
@ -16,7 +15,7 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration4.ts(
|
|||
tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration4.ts(34,28): error TS2304: Cannot find name 'E'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration4.ts (11 errors) ====
|
||||
==== tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration4.ts (10 errors) ====
|
||||
// If the parameter is a rest parameter, the parameter type is any[]
|
||||
// A type annotation for a rest parameter must denote an array type.
|
||||
|
||||
|
@ -30,8 +29,6 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration4.ts(
|
|||
function a0(...x: [number, number, string]) { } // Error, rest parameter must be array type
|
||||
function a1(...x: (number|string)[]) { }
|
||||
function a2(...a: someArray) { } // Error, rest parameter must be array type
|
||||
~~~~~~~~~~~~~~~
|
||||
!!! error TS2370: A rest parameter must be of an array type.
|
||||
function a3(...b?) { } // Error, can't be optional
|
||||
~
|
||||
!!! error TS1047: A rest parameter cannot be optional.
|
||||
|
|
148
tests/baselines/reference/genericRestParameters3.errors.txt
Normal file
148
tests/baselines/reference/genericRestParameters3.errors.txt
Normal file
|
@ -0,0 +1,148 @@
|
|||
tests/cases/conformance/types/rest/genericRestParameters3.ts(11,11): error TS2345: Argument of type '[10]' is not assignable to parameter of type '[string] | [number, boolean]'.
|
||||
Type '[10]' is not assignable to type '[string]'.
|
||||
Type '10' is not assignable to type 'string'.
|
||||
tests/cases/conformance/types/rest/genericRestParameters3.ts(12,1): error TS2345: Argument of type '[]' is not assignable to parameter of type '[string] | [number, boolean]'.
|
||||
Type '[]' is not assignable to type '[number, boolean]'.
|
||||
Property '0' is missing in type '[]'.
|
||||
tests/cases/conformance/types/rest/genericRestParameters3.ts(16,1): error TS2322: Type '(x: string, ...args: [string] | [number, boolean]) => void' is not assignable to type '(...args: [string, string] | [string, number, boolean]) => void'.
|
||||
tests/cases/conformance/types/rest/genericRestParameters3.ts(17,1): error TS2322: Type '(x: string, y: string) => void' is not assignable to type '(x: string, ...args: [string] | [number, boolean]) => void'.
|
||||
Types of parameters 'y' and 'args' are incompatible.
|
||||
Type '[string] | [number, boolean]' is not assignable to type '[string]'.
|
||||
Type '[number, boolean]' is not assignable to type '[string]'.
|
||||
Types of property '0' are incompatible.
|
||||
Type 'number' is not assignable to type 'string'.
|
||||
tests/cases/conformance/types/rest/genericRestParameters3.ts(18,1): error TS2322: Type '(x: string, y: number, z: boolean) => void' is not assignable to type '(x: string, ...args: [string] | [number, boolean]) => void'.
|
||||
Types of parameters 'y' and 'args' are incompatible.
|
||||
Type '[string] | [number, boolean]' is not assignable to type '[number, boolean]'.
|
||||
Type '[string]' is not assignable to type '[number, boolean]'.
|
||||
Property '1' is missing in type '[string]'.
|
||||
tests/cases/conformance/types/rest/genericRestParameters3.ts(19,1): error TS2322: Type '(...args: [string, string] | [string, number, boolean]) => void' is not assignable to type '(x: string, ...args: [string] | [number, boolean]) => void'.
|
||||
tests/cases/conformance/types/rest/genericRestParameters3.ts(29,1): error TS2554: Expected 1 arguments, but got 0.
|
||||
tests/cases/conformance/types/rest/genericRestParameters3.ts(30,21): error TS2345: Argument of type '100' is not assignable to parameter of type '(...args: CoolArray<any>) => void'.
|
||||
tests/cases/conformance/types/rest/genericRestParameters3.ts(31,21): error TS2345: Argument of type '<T extends any[]>(cb: (...args: T) => void) => void' is not assignable to parameter of type '(...args: CoolArray<any>) => void'.
|
||||
Types of parameters 'cb' and 'args' are incompatible.
|
||||
Type 'CoolArray<any>' is not assignable to type '[(...args: any[]) => void]'.
|
||||
Property '0' is missing in type 'CoolArray<any>'.
|
||||
tests/cases/conformance/types/rest/genericRestParameters3.ts(38,32): error TS2345: Argument of type '[10, 20]' is not assignable to parameter of type 'CoolArray<number>'.
|
||||
Property 'hello' is missing in type '[10, 20]'.
|
||||
tests/cases/conformance/types/rest/genericRestParameters3.ts(43,1): error TS2345: Argument of type '[]' is not assignable to parameter of type 'CoolArray<never>'.
|
||||
Property 'hello' is missing in type '[]'.
|
||||
tests/cases/conformance/types/rest/genericRestParameters3.ts(44,5): error TS2345: Argument of type '[number]' is not assignable to parameter of type 'CoolArray<{}>'.
|
||||
Property 'hello' is missing in type '[number]'.
|
||||
tests/cases/conformance/types/rest/genericRestParameters3.ts(45,5): error TS2345: Argument of type '[number, number]' is not assignable to parameter of type 'CoolArray<{}>'.
|
||||
Property 'hello' is missing in type '[number, number]'.
|
||||
tests/cases/conformance/types/rest/genericRestParameters3.ts(46,5): error TS2345: Argument of type 'number[]' is not assignable to parameter of type 'CoolArray<number>'.
|
||||
Property 'hello' is missing in type 'number[]'.
|
||||
tests/cases/conformance/types/rest/genericRestParameters3.ts(53,5): error TS2345: Argument of type '["what"]' is not assignable to parameter of type '[] | [number, string]'.
|
||||
Type '["what"]' is not assignable to type '[number, string]'.
|
||||
Property '1' is missing in type '["what"]'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/types/rest/genericRestParameters3.ts (15 errors) ====
|
||||
declare let f1: (x: string, ...args: [string] | [number, boolean]) => void;
|
||||
declare let f2: (x: string, y: string) => void;
|
||||
declare let f3: (x: string, y: number, z: boolean) => void;
|
||||
declare let f4: (...args: [string, string] | [string, number, boolean]) => void;
|
||||
|
||||
declare const tt: [string] | [number, boolean];
|
||||
|
||||
f1("foo", "abc");
|
||||
f1("foo", 10, true);
|
||||
f1("foo", ...tt);
|
||||
f1("foo", 10); // Error
|
||||
~~
|
||||
!!! error TS2345: Argument of type '[10]' is not assignable to parameter of type '[string] | [number, boolean]'.
|
||||
!!! error TS2345: Type '[10]' is not assignable to type '[string]'.
|
||||
!!! error TS2345: Type '10' is not assignable to type 'string'.
|
||||
f1("foo"); // Error
|
||||
~~~~~~~~~
|
||||
!!! error TS2345: Argument of type '[]' is not assignable to parameter of type '[string] | [number, boolean]'.
|
||||
!!! error TS2345: Type '[]' is not assignable to type '[number, boolean]'.
|
||||
!!! error TS2345: Property '0' is missing in type '[]'.
|
||||
|
||||
f2 = f1;
|
||||
f3 = f1;
|
||||
f4 = f1; // Error, misaligned complex rest types
|
||||
~~
|
||||
!!! error TS2322: Type '(x: string, ...args: [string] | [number, boolean]) => void' is not assignable to type '(...args: [string, string] | [string, number, boolean]) => void'.
|
||||
f1 = f2; // Error
|
||||
~~
|
||||
!!! error TS2322: Type '(x: string, y: string) => void' is not assignable to type '(x: string, ...args: [string] | [number, boolean]) => void'.
|
||||
!!! error TS2322: Types of parameters 'y' and 'args' are incompatible.
|
||||
!!! error TS2322: Type '[string] | [number, boolean]' is not assignable to type '[string]'.
|
||||
!!! error TS2322: Type '[number, boolean]' is not assignable to type '[string]'.
|
||||
!!! error TS2322: Types of property '0' are incompatible.
|
||||
!!! error TS2322: Type 'number' is not assignable to type 'string'.
|
||||
f1 = f3; // Error
|
||||
~~
|
||||
!!! error TS2322: Type '(x: string, y: number, z: boolean) => void' is not assignable to type '(x: string, ...args: [string] | [number, boolean]) => void'.
|
||||
!!! error TS2322: Types of parameters 'y' and 'args' are incompatible.
|
||||
!!! error TS2322: Type '[string] | [number, boolean]' is not assignable to type '[number, boolean]'.
|
||||
!!! error TS2322: Type '[string]' is not assignable to type '[number, boolean]'.
|
||||
!!! error TS2322: Property '1' is missing in type '[string]'.
|
||||
f1 = f4; // Error, misaligned complex rest types
|
||||
~~
|
||||
!!! error TS2322: Type '(...args: [string, string] | [string, number, boolean]) => void' is not assignable to type '(x: string, ...args: [string] | [number, boolean]) => void'.
|
||||
|
||||
// Repro from #26110
|
||||
|
||||
interface CoolArray<E> extends Array<E> {
|
||||
hello: number;
|
||||
}
|
||||
|
||||
declare function foo<T extends any[]>(cb: (...args: T) => void): void;
|
||||
|
||||
foo<CoolArray<any>>(); // Error
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2554: Expected 1 arguments, but got 0.
|
||||
foo<CoolArray<any>>(100); // Error
|
||||
~~~
|
||||
!!! error TS2345: Argument of type '100' is not assignable to parameter of type '(...args: CoolArray<any>) => void'.
|
||||
foo<CoolArray<any>>(foo); // Error
|
||||
~~~
|
||||
!!! error TS2345: Argument of type '<T extends any[]>(cb: (...args: T) => void) => void' is not assignable to parameter of type '(...args: CoolArray<any>) => void'.
|
||||
!!! error TS2345: Types of parameters 'cb' and 'args' are incompatible.
|
||||
!!! error TS2345: Type 'CoolArray<any>' is not assignable to type '[(...args: any[]) => void]'.
|
||||
!!! error TS2345: Property '0' is missing in type 'CoolArray<any>'.
|
||||
|
||||
function bar<T extends any[]>(...args: T): T {
|
||||
return args;
|
||||
}
|
||||
|
||||
let a = bar(10, 20);
|
||||
let b = bar<CoolArray<number>>(10, 20); // Error
|
||||
~~
|
||||
!!! error TS2345: Argument of type '[10, 20]' is not assignable to parameter of type 'CoolArray<number>'.
|
||||
!!! error TS2345: Property 'hello' is missing in type '[10, 20]'.
|
||||
|
||||
declare function baz<T>(...args: CoolArray<T>): void;
|
||||
declare const ca: CoolArray<number>;
|
||||
|
||||
baz(); // Error
|
||||
~~~~~
|
||||
!!! error TS2345: Argument of type '[]' is not assignable to parameter of type 'CoolArray<never>'.
|
||||
!!! error TS2345: Property 'hello' is missing in type '[]'.
|
||||
baz(1); // Error
|
||||
~
|
||||
!!! error TS2345: Argument of type '[number]' is not assignable to parameter of type 'CoolArray<{}>'.
|
||||
!!! error TS2345: Property 'hello' is missing in type '[number]'.
|
||||
baz(1, 2); // Error
|
||||
~
|
||||
!!! error TS2345: Argument of type '[number, number]' is not assignable to parameter of type 'CoolArray<{}>'.
|
||||
!!! error TS2345: Property 'hello' is missing in type '[number, number]'.
|
||||
baz(...ca); // Error
|
||||
~~~~~
|
||||
!!! error TS2345: Argument of type 'number[]' is not assignable to parameter of type 'CoolArray<number>'.
|
||||
!!! error TS2345: Property 'hello' is missing in type 'number[]'.
|
||||
|
||||
// Repro from #26491
|
||||
|
||||
declare function hmm<A extends [] | [number, string]>(...args: A): void;
|
||||
hmm(); // okay, A = []
|
||||
hmm(1, "s"); // okay, A = [1, "s"]
|
||||
hmm("what"); // no error? A = [] | [number, string] ?
|
||||
~~~~~~
|
||||
!!! error TS2345: Argument of type '["what"]' is not assignable to parameter of type '[] | [number, string]'.
|
||||
!!! error TS2345: Type '["what"]' is not assignable to type '[number, string]'.
|
||||
!!! error TS2345: Property '1' is missing in type '["what"]'.
|
||||
|
106
tests/baselines/reference/genericRestParameters3.js
Normal file
106
tests/baselines/reference/genericRestParameters3.js
Normal file
|
@ -0,0 +1,106 @@
|
|||
//// [genericRestParameters3.ts]
|
||||
declare let f1: (x: string, ...args: [string] | [number, boolean]) => void;
|
||||
declare let f2: (x: string, y: string) => void;
|
||||
declare let f3: (x: string, y: number, z: boolean) => void;
|
||||
declare let f4: (...args: [string, string] | [string, number, boolean]) => void;
|
||||
|
||||
declare const tt: [string] | [number, boolean];
|
||||
|
||||
f1("foo", "abc");
|
||||
f1("foo", 10, true);
|
||||
f1("foo", ...tt);
|
||||
f1("foo", 10); // Error
|
||||
f1("foo"); // Error
|
||||
|
||||
f2 = f1;
|
||||
f3 = f1;
|
||||
f4 = f1; // Error, misaligned complex rest types
|
||||
f1 = f2; // Error
|
||||
f1 = f3; // Error
|
||||
f1 = f4; // Error, misaligned complex rest types
|
||||
|
||||
// Repro from #26110
|
||||
|
||||
interface CoolArray<E> extends Array<E> {
|
||||
hello: number;
|
||||
}
|
||||
|
||||
declare function foo<T extends any[]>(cb: (...args: T) => void): void;
|
||||
|
||||
foo<CoolArray<any>>(); // Error
|
||||
foo<CoolArray<any>>(100); // Error
|
||||
foo<CoolArray<any>>(foo); // Error
|
||||
|
||||
function bar<T extends any[]>(...args: T): T {
|
||||
return args;
|
||||
}
|
||||
|
||||
let a = bar(10, 20);
|
||||
let b = bar<CoolArray<number>>(10, 20); // Error
|
||||
|
||||
declare function baz<T>(...args: CoolArray<T>): void;
|
||||
declare const ca: CoolArray<number>;
|
||||
|
||||
baz(); // Error
|
||||
baz(1); // Error
|
||||
baz(1, 2); // Error
|
||||
baz(...ca); // Error
|
||||
|
||||
// Repro from #26491
|
||||
|
||||
declare function hmm<A extends [] | [number, string]>(...args: A): void;
|
||||
hmm(); // okay, A = []
|
||||
hmm(1, "s"); // okay, A = [1, "s"]
|
||||
hmm("what"); // no error? A = [] | [number, string] ?
|
||||
|
||||
|
||||
//// [genericRestParameters3.js]
|
||||
"use strict";
|
||||
f1("foo", "abc");
|
||||
f1("foo", 10, true);
|
||||
f1.apply(void 0, ["foo"].concat(tt));
|
||||
f1("foo", 10); // Error
|
||||
f1("foo"); // Error
|
||||
f2 = f1;
|
||||
f3 = f1;
|
||||
f4 = f1; // Error, misaligned complex rest types
|
||||
f1 = f2; // Error
|
||||
f1 = f3; // Error
|
||||
f1 = f4; // Error, misaligned complex rest types
|
||||
foo(); // Error
|
||||
foo(100); // Error
|
||||
foo(foo); // Error
|
||||
function bar() {
|
||||
var args = [];
|
||||
for (var _i = 0; _i < arguments.length; _i++) {
|
||||
args[_i] = arguments[_i];
|
||||
}
|
||||
return args;
|
||||
}
|
||||
var a = bar(10, 20);
|
||||
var b = bar(10, 20); // Error
|
||||
baz(); // Error
|
||||
baz(1); // Error
|
||||
baz(1, 2); // Error
|
||||
baz.apply(void 0, ca); // Error
|
||||
hmm(); // okay, A = []
|
||||
hmm(1, "s"); // okay, A = [1, "s"]
|
||||
hmm("what"); // no error? A = [] | [number, string] ?
|
||||
|
||||
|
||||
//// [genericRestParameters3.d.ts]
|
||||
declare let f1: (x: string, ...args: [string] | [number, boolean]) => void;
|
||||
declare let f2: (x: string, y: string) => void;
|
||||
declare let f3: (x: string, y: number, z: boolean) => void;
|
||||
declare let f4: (...args: [string, string] | [string, number, boolean]) => void;
|
||||
declare const tt: [string] | [number, boolean];
|
||||
interface CoolArray<E> extends Array<E> {
|
||||
hello: number;
|
||||
}
|
||||
declare function foo<T extends any[]>(cb: (...args: T) => void): void;
|
||||
declare function bar<T extends any[]>(...args: T): T;
|
||||
declare let a: [number, number];
|
||||
declare let b: any;
|
||||
declare function baz<T>(...args: CoolArray<T>): void;
|
||||
declare const ca: CoolArray<number>;
|
||||
declare function hmm<A extends [] | [number, string]>(...args: A): void;
|
157
tests/baselines/reference/genericRestParameters3.symbols
Normal file
157
tests/baselines/reference/genericRestParameters3.symbols
Normal file
|
@ -0,0 +1,157 @@
|
|||
=== tests/cases/conformance/types/rest/genericRestParameters3.ts ===
|
||||
declare let f1: (x: string, ...args: [string] | [number, boolean]) => void;
|
||||
>f1 : Symbol(f1, Decl(genericRestParameters3.ts, 0, 11))
|
||||
>x : Symbol(x, Decl(genericRestParameters3.ts, 0, 17))
|
||||
>args : Symbol(args, Decl(genericRestParameters3.ts, 0, 27))
|
||||
|
||||
declare let f2: (x: string, y: string) => void;
|
||||
>f2 : Symbol(f2, Decl(genericRestParameters3.ts, 1, 11))
|
||||
>x : Symbol(x, Decl(genericRestParameters3.ts, 1, 17))
|
||||
>y : Symbol(y, Decl(genericRestParameters3.ts, 1, 27))
|
||||
|
||||
declare let f3: (x: string, y: number, z: boolean) => void;
|
||||
>f3 : Symbol(f3, Decl(genericRestParameters3.ts, 2, 11))
|
||||
>x : Symbol(x, Decl(genericRestParameters3.ts, 2, 17))
|
||||
>y : Symbol(y, Decl(genericRestParameters3.ts, 2, 27))
|
||||
>z : Symbol(z, Decl(genericRestParameters3.ts, 2, 38))
|
||||
|
||||
declare let f4: (...args: [string, string] | [string, number, boolean]) => void;
|
||||
>f4 : Symbol(f4, Decl(genericRestParameters3.ts, 3, 11))
|
||||
>args : Symbol(args, Decl(genericRestParameters3.ts, 3, 17))
|
||||
|
||||
declare const tt: [string] | [number, boolean];
|
||||
>tt : Symbol(tt, Decl(genericRestParameters3.ts, 5, 13))
|
||||
|
||||
f1("foo", "abc");
|
||||
>f1 : Symbol(f1, Decl(genericRestParameters3.ts, 0, 11))
|
||||
|
||||
f1("foo", 10, true);
|
||||
>f1 : Symbol(f1, Decl(genericRestParameters3.ts, 0, 11))
|
||||
|
||||
f1("foo", ...tt);
|
||||
>f1 : Symbol(f1, Decl(genericRestParameters3.ts, 0, 11))
|
||||
>tt : Symbol(tt, Decl(genericRestParameters3.ts, 5, 13))
|
||||
|
||||
f1("foo", 10); // Error
|
||||
>f1 : Symbol(f1, Decl(genericRestParameters3.ts, 0, 11))
|
||||
|
||||
f1("foo"); // Error
|
||||
>f1 : Symbol(f1, Decl(genericRestParameters3.ts, 0, 11))
|
||||
|
||||
f2 = f1;
|
||||
>f2 : Symbol(f2, Decl(genericRestParameters3.ts, 1, 11))
|
||||
>f1 : Symbol(f1, Decl(genericRestParameters3.ts, 0, 11))
|
||||
|
||||
f3 = f1;
|
||||
>f3 : Symbol(f3, Decl(genericRestParameters3.ts, 2, 11))
|
||||
>f1 : Symbol(f1, Decl(genericRestParameters3.ts, 0, 11))
|
||||
|
||||
f4 = f1; // Error, misaligned complex rest types
|
||||
>f4 : Symbol(f4, Decl(genericRestParameters3.ts, 3, 11))
|
||||
>f1 : Symbol(f1, Decl(genericRestParameters3.ts, 0, 11))
|
||||
|
||||
f1 = f2; // Error
|
||||
>f1 : Symbol(f1, Decl(genericRestParameters3.ts, 0, 11))
|
||||
>f2 : Symbol(f2, Decl(genericRestParameters3.ts, 1, 11))
|
||||
|
||||
f1 = f3; // Error
|
||||
>f1 : Symbol(f1, Decl(genericRestParameters3.ts, 0, 11))
|
||||
>f3 : Symbol(f3, Decl(genericRestParameters3.ts, 2, 11))
|
||||
|
||||
f1 = f4; // Error, misaligned complex rest types
|
||||
>f1 : Symbol(f1, Decl(genericRestParameters3.ts, 0, 11))
|
||||
>f4 : Symbol(f4, Decl(genericRestParameters3.ts, 3, 11))
|
||||
|
||||
// Repro from #26110
|
||||
|
||||
interface CoolArray<E> extends Array<E> {
|
||||
>CoolArray : Symbol(CoolArray, Decl(genericRestParameters3.ts, 18, 8))
|
||||
>E : Symbol(E, Decl(genericRestParameters3.ts, 22, 20))
|
||||
>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
|
||||
>E : Symbol(E, Decl(genericRestParameters3.ts, 22, 20))
|
||||
|
||||
hello: number;
|
||||
>hello : Symbol(CoolArray.hello, Decl(genericRestParameters3.ts, 22, 41))
|
||||
}
|
||||
|
||||
declare function foo<T extends any[]>(cb: (...args: T) => void): void;
|
||||
>foo : Symbol(foo, Decl(genericRestParameters3.ts, 24, 1))
|
||||
>T : Symbol(T, Decl(genericRestParameters3.ts, 26, 21))
|
||||
>cb : Symbol(cb, Decl(genericRestParameters3.ts, 26, 38))
|
||||
>args : Symbol(args, Decl(genericRestParameters3.ts, 26, 43))
|
||||
>T : Symbol(T, Decl(genericRestParameters3.ts, 26, 21))
|
||||
|
||||
foo<CoolArray<any>>(); // Error
|
||||
>foo : Symbol(foo, Decl(genericRestParameters3.ts, 24, 1))
|
||||
>CoolArray : Symbol(CoolArray, Decl(genericRestParameters3.ts, 18, 8))
|
||||
|
||||
foo<CoolArray<any>>(100); // Error
|
||||
>foo : Symbol(foo, Decl(genericRestParameters3.ts, 24, 1))
|
||||
>CoolArray : Symbol(CoolArray, Decl(genericRestParameters3.ts, 18, 8))
|
||||
|
||||
foo<CoolArray<any>>(foo); // Error
|
||||
>foo : Symbol(foo, Decl(genericRestParameters3.ts, 24, 1))
|
||||
>CoolArray : Symbol(CoolArray, Decl(genericRestParameters3.ts, 18, 8))
|
||||
>foo : Symbol(foo, Decl(genericRestParameters3.ts, 24, 1))
|
||||
|
||||
function bar<T extends any[]>(...args: T): T {
|
||||
>bar : Symbol(bar, Decl(genericRestParameters3.ts, 30, 25))
|
||||
>T : Symbol(T, Decl(genericRestParameters3.ts, 32, 13))
|
||||
>args : Symbol(args, Decl(genericRestParameters3.ts, 32, 30))
|
||||
>T : Symbol(T, Decl(genericRestParameters3.ts, 32, 13))
|
||||
>T : Symbol(T, Decl(genericRestParameters3.ts, 32, 13))
|
||||
|
||||
return args;
|
||||
>args : Symbol(args, Decl(genericRestParameters3.ts, 32, 30))
|
||||
}
|
||||
|
||||
let a = bar(10, 20);
|
||||
>a : Symbol(a, Decl(genericRestParameters3.ts, 36, 3))
|
||||
>bar : Symbol(bar, Decl(genericRestParameters3.ts, 30, 25))
|
||||
|
||||
let b = bar<CoolArray<number>>(10, 20); // Error
|
||||
>b : Symbol(b, Decl(genericRestParameters3.ts, 37, 3))
|
||||
>bar : Symbol(bar, Decl(genericRestParameters3.ts, 30, 25))
|
||||
>CoolArray : Symbol(CoolArray, Decl(genericRestParameters3.ts, 18, 8))
|
||||
|
||||
declare function baz<T>(...args: CoolArray<T>): void;
|
||||
>baz : Symbol(baz, Decl(genericRestParameters3.ts, 37, 39))
|
||||
>T : Symbol(T, Decl(genericRestParameters3.ts, 39, 21))
|
||||
>args : Symbol(args, Decl(genericRestParameters3.ts, 39, 24))
|
||||
>CoolArray : Symbol(CoolArray, Decl(genericRestParameters3.ts, 18, 8))
|
||||
>T : Symbol(T, Decl(genericRestParameters3.ts, 39, 21))
|
||||
|
||||
declare const ca: CoolArray<number>;
|
||||
>ca : Symbol(ca, Decl(genericRestParameters3.ts, 40, 13))
|
||||
>CoolArray : Symbol(CoolArray, Decl(genericRestParameters3.ts, 18, 8))
|
||||
|
||||
baz(); // Error
|
||||
>baz : Symbol(baz, Decl(genericRestParameters3.ts, 37, 39))
|
||||
|
||||
baz(1); // Error
|
||||
>baz : Symbol(baz, Decl(genericRestParameters3.ts, 37, 39))
|
||||
|
||||
baz(1, 2); // Error
|
||||
>baz : Symbol(baz, Decl(genericRestParameters3.ts, 37, 39))
|
||||
|
||||
baz(...ca); // Error
|
||||
>baz : Symbol(baz, Decl(genericRestParameters3.ts, 37, 39))
|
||||
>ca : Symbol(ca, Decl(genericRestParameters3.ts, 40, 13))
|
||||
|
||||
// Repro from #26491
|
||||
|
||||
declare function hmm<A extends [] | [number, string]>(...args: A): void;
|
||||
>hmm : Symbol(hmm, Decl(genericRestParameters3.ts, 45, 11))
|
||||
>A : Symbol(A, Decl(genericRestParameters3.ts, 49, 21))
|
||||
>args : Symbol(args, Decl(genericRestParameters3.ts, 49, 54))
|
||||
>A : Symbol(A, Decl(genericRestParameters3.ts, 49, 21))
|
||||
|
||||
hmm(); // okay, A = []
|
||||
>hmm : Symbol(hmm, Decl(genericRestParameters3.ts, 45, 11))
|
||||
|
||||
hmm(1, "s"); // okay, A = [1, "s"]
|
||||
>hmm : Symbol(hmm, Decl(genericRestParameters3.ts, 45, 11))
|
||||
|
||||
hmm("what"); // no error? A = [] | [number, string] ?
|
||||
>hmm : Symbol(hmm, Decl(genericRestParameters3.ts, 45, 11))
|
||||
|
182
tests/baselines/reference/genericRestParameters3.types
Normal file
182
tests/baselines/reference/genericRestParameters3.types
Normal file
|
@ -0,0 +1,182 @@
|
|||
=== tests/cases/conformance/types/rest/genericRestParameters3.ts ===
|
||||
declare let f1: (x: string, ...args: [string] | [number, boolean]) => void;
|
||||
>f1 : (x: string, ...args: [string] | [number, boolean]) => void
|
||||
>x : string
|
||||
>args : [string] | [number, boolean]
|
||||
|
||||
declare let f2: (x: string, y: string) => void;
|
||||
>f2 : (x: string, y: string) => void
|
||||
>x : string
|
||||
>y : string
|
||||
|
||||
declare let f3: (x: string, y: number, z: boolean) => void;
|
||||
>f3 : (x: string, y: number, z: boolean) => void
|
||||
>x : string
|
||||
>y : number
|
||||
>z : boolean
|
||||
|
||||
declare let f4: (...args: [string, string] | [string, number, boolean]) => void;
|
||||
>f4 : (...args: [string, string] | [string, number, boolean]) => void
|
||||
>args : [string, string] | [string, number, boolean]
|
||||
|
||||
declare const tt: [string] | [number, boolean];
|
||||
>tt : [string] | [number, boolean]
|
||||
|
||||
f1("foo", "abc");
|
||||
>f1("foo", "abc") : void
|
||||
>f1 : (x: string, ...args: [string] | [number, boolean]) => void
|
||||
>"foo" : "foo"
|
||||
>"abc" : "abc"
|
||||
|
||||
f1("foo", 10, true);
|
||||
>f1("foo", 10, true) : void
|
||||
>f1 : (x: string, ...args: [string] | [number, boolean]) => void
|
||||
>"foo" : "foo"
|
||||
>10 : 10
|
||||
>true : true
|
||||
|
||||
f1("foo", ...tt);
|
||||
>f1("foo", ...tt) : void
|
||||
>f1 : (x: string, ...args: [string] | [number, boolean]) => void
|
||||
>"foo" : "foo"
|
||||
>...tt : string | number | boolean
|
||||
>tt : [string] | [number, boolean]
|
||||
|
||||
f1("foo", 10); // Error
|
||||
>f1("foo", 10) : void
|
||||
>f1 : (x: string, ...args: [string] | [number, boolean]) => void
|
||||
>"foo" : "foo"
|
||||
>10 : 10
|
||||
|
||||
f1("foo"); // Error
|
||||
>f1("foo") : void
|
||||
>f1 : (x: string, ...args: [string] | [number, boolean]) => void
|
||||
>"foo" : "foo"
|
||||
|
||||
f2 = f1;
|
||||
>f2 = f1 : (x: string, ...args: [string] | [number, boolean]) => void
|
||||
>f2 : (x: string, y: string) => void
|
||||
>f1 : (x: string, ...args: [string] | [number, boolean]) => void
|
||||
|
||||
f3 = f1;
|
||||
>f3 = f1 : (x: string, ...args: [string] | [number, boolean]) => void
|
||||
>f3 : (x: string, y: number, z: boolean) => void
|
||||
>f1 : (x: string, ...args: [string] | [number, boolean]) => void
|
||||
|
||||
f4 = f1; // Error, misaligned complex rest types
|
||||
>f4 = f1 : (x: string, ...args: [string] | [number, boolean]) => void
|
||||
>f4 : (...args: [string, string] | [string, number, boolean]) => void
|
||||
>f1 : (x: string, ...args: [string] | [number, boolean]) => void
|
||||
|
||||
f1 = f2; // Error
|
||||
>f1 = f2 : (x: string, y: string) => void
|
||||
>f1 : (x: string, ...args: [string] | [number, boolean]) => void
|
||||
>f2 : (x: string, y: string) => void
|
||||
|
||||
f1 = f3; // Error
|
||||
>f1 = f3 : (x: string, y: number, z: boolean) => void
|
||||
>f1 : (x: string, ...args: [string] | [number, boolean]) => void
|
||||
>f3 : (x: string, y: number, z: boolean) => void
|
||||
|
||||
f1 = f4; // Error, misaligned complex rest types
|
||||
>f1 = f4 : (...args: [string, string] | [string, number, boolean]) => void
|
||||
>f1 : (x: string, ...args: [string] | [number, boolean]) => void
|
||||
>f4 : (...args: [string, string] | [string, number, boolean]) => void
|
||||
|
||||
// Repro from #26110
|
||||
|
||||
interface CoolArray<E> extends Array<E> {
|
||||
hello: number;
|
||||
>hello : number
|
||||
}
|
||||
|
||||
declare function foo<T extends any[]>(cb: (...args: T) => void): void;
|
||||
>foo : <T extends any[]>(cb: (...args: T) => void) => void
|
||||
>cb : (...args: T) => void
|
||||
>args : T
|
||||
|
||||
foo<CoolArray<any>>(); // Error
|
||||
>foo<CoolArray<any>>() : any
|
||||
>foo : <T extends any[]>(cb: (...args: T) => void) => void
|
||||
|
||||
foo<CoolArray<any>>(100); // Error
|
||||
>foo<CoolArray<any>>(100) : any
|
||||
>foo : <T extends any[]>(cb: (...args: T) => void) => void
|
||||
>100 : 100
|
||||
|
||||
foo<CoolArray<any>>(foo); // Error
|
||||
>foo<CoolArray<any>>(foo) : any
|
||||
>foo : <T extends any[]>(cb: (...args: T) => void) => void
|
||||
>foo : <T extends any[]>(cb: (...args: T) => void) => void
|
||||
|
||||
function bar<T extends any[]>(...args: T): T {
|
||||
>bar : <T extends any[]>(...args: T) => T
|
||||
>args : T
|
||||
|
||||
return args;
|
||||
>args : T
|
||||
}
|
||||
|
||||
let a = bar(10, 20);
|
||||
>a : [number, number]
|
||||
>bar(10, 20) : [number, number]
|
||||
>bar : <T extends any[]>(...args: T) => T
|
||||
>10 : 10
|
||||
>20 : 20
|
||||
|
||||
let b = bar<CoolArray<number>>(10, 20); // Error
|
||||
>b : any
|
||||
>bar<CoolArray<number>>(10, 20) : any
|
||||
>bar : <T extends any[]>(...args: T) => T
|
||||
>10 : 10
|
||||
>20 : 20
|
||||
|
||||
declare function baz<T>(...args: CoolArray<T>): void;
|
||||
>baz : <T>(...args: CoolArray<T>) => void
|
||||
>args : CoolArray<T>
|
||||
|
||||
declare const ca: CoolArray<number>;
|
||||
>ca : CoolArray<number>
|
||||
|
||||
baz(); // Error
|
||||
>baz() : any
|
||||
>baz : <T>(...args: CoolArray<T>) => void
|
||||
|
||||
baz(1); // Error
|
||||
>baz(1) : any
|
||||
>baz : <T>(...args: CoolArray<T>) => void
|
||||
>1 : 1
|
||||
|
||||
baz(1, 2); // Error
|
||||
>baz(1, 2) : any
|
||||
>baz : <T>(...args: CoolArray<T>) => void
|
||||
>1 : 1
|
||||
>2 : 2
|
||||
|
||||
baz(...ca); // Error
|
||||
>baz(...ca) : any
|
||||
>baz : <T>(...args: CoolArray<T>) => void
|
||||
>...ca : number
|
||||
>ca : CoolArray<number>
|
||||
|
||||
// Repro from #26491
|
||||
|
||||
declare function hmm<A extends [] | [number, string]>(...args: A): void;
|
||||
>hmm : <A extends [] | [number, string]>(...args: A) => void
|
||||
>args : A
|
||||
|
||||
hmm(); // okay, A = []
|
||||
>hmm() : void
|
||||
>hmm : <A extends [] | [number, string]>(...args: A) => void
|
||||
|
||||
hmm(1, "s"); // okay, A = [1, "s"]
|
||||
>hmm(1, "s") : void
|
||||
>hmm : <A extends [] | [number, string]>(...args: A) => void
|
||||
>1 : 1
|
||||
>"s" : "s"
|
||||
|
||||
hmm("what"); // no error? A = [] | [number, string] ?
|
||||
>hmm("what") : any
|
||||
>hmm : <A extends [] | [number, string]>(...args: A) => void
|
||||
>"what" : "what"
|
||||
|
|
@ -1,40 +1,12 @@
|
|||
tests/cases/conformance/types/objectTypeLiteral/callSignatures/restParametersOfNonArrayTypes2.ts(7,14): error TS2370: A rest parameter must be of an array type.
|
||||
tests/cases/conformance/types/objectTypeLiteral/callSignatures/restParametersOfNonArrayTypes2.ts(8,22): error TS2370: A rest parameter must be of an array type.
|
||||
tests/cases/conformance/types/objectTypeLiteral/callSignatures/restParametersOfNonArrayTypes2.ts(9,11): error TS1014: A rest parameter must be last in a parameter list.
|
||||
tests/cases/conformance/types/objectTypeLiteral/callSignatures/restParametersOfNonArrayTypes2.ts(9,11): error TS2370: A rest parameter must be of an array type.
|
||||
tests/cases/conformance/types/objectTypeLiteral/callSignatures/restParametersOfNonArrayTypes2.ts(9,26): error TS2370: A rest parameter must be of an array type.
|
||||
tests/cases/conformance/types/objectTypeLiteral/callSignatures/restParametersOfNonArrayTypes2.ts(12,9): error TS2370: A rest parameter must be of an array type.
|
||||
tests/cases/conformance/types/objectTypeLiteral/callSignatures/restParametersOfNonArrayTypes2.ts(16,6): error TS2370: A rest parameter must be of an array type.
|
||||
tests/cases/conformance/types/objectTypeLiteral/callSignatures/restParametersOfNonArrayTypes2.ts(17,9): error TS1014: A rest parameter must be last in a parameter list.
|
||||
tests/cases/conformance/types/objectTypeLiteral/callSignatures/restParametersOfNonArrayTypes2.ts(17,9): error TS2370: A rest parameter must be of an array type.
|
||||
tests/cases/conformance/types/objectTypeLiteral/callSignatures/restParametersOfNonArrayTypes2.ts(17,24): error TS2370: A rest parameter must be of an array type.
|
||||
tests/cases/conformance/types/objectTypeLiteral/callSignatures/restParametersOfNonArrayTypes2.ts(21,6): error TS2370: A rest parameter must be of an array type.
|
||||
tests/cases/conformance/types/objectTypeLiteral/callSignatures/restParametersOfNonArrayTypes2.ts(22,9): error TS2370: A rest parameter must be of an array type.
|
||||
tests/cases/conformance/types/objectTypeLiteral/callSignatures/restParametersOfNonArrayTypes2.ts(26,9): error TS2370: A rest parameter must be of an array type.
|
||||
tests/cases/conformance/types/objectTypeLiteral/callSignatures/restParametersOfNonArrayTypes2.ts(27,21): error TS1014: A rest parameter must be last in a parameter list.
|
||||
tests/cases/conformance/types/objectTypeLiteral/callSignatures/restParametersOfNonArrayTypes2.ts(27,21): error TS2370: A rest parameter must be of an array type.
|
||||
tests/cases/conformance/types/objectTypeLiteral/callSignatures/restParametersOfNonArrayTypes2.ts(27,36): error TS2370: A rest parameter must be of an array type.
|
||||
tests/cases/conformance/types/objectTypeLiteral/callSignatures/restParametersOfNonArrayTypes2.ts(28,9): error TS2370: A rest parameter must be of an array type.
|
||||
tests/cases/conformance/types/objectTypeLiteral/callSignatures/restParametersOfNonArrayTypes2.ts(34,15): error TS2370: A rest parameter must be of an array type.
|
||||
tests/cases/conformance/types/objectTypeLiteral/callSignatures/restParametersOfNonArrayTypes2.ts(35,23): error TS2370: A rest parameter must be of an array type.
|
||||
tests/cases/conformance/types/objectTypeLiteral/callSignatures/restParametersOfNonArrayTypes2.ts(36,11): error TS1014: A rest parameter must be last in a parameter list.
|
||||
tests/cases/conformance/types/objectTypeLiteral/callSignatures/restParametersOfNonArrayTypes2.ts(36,11): error TS2370: A rest parameter must be of an array type.
|
||||
tests/cases/conformance/types/objectTypeLiteral/callSignatures/restParametersOfNonArrayTypes2.ts(36,35): error TS2370: A rest parameter must be of an array type.
|
||||
tests/cases/conformance/types/objectTypeLiteral/callSignatures/restParametersOfNonArrayTypes2.ts(39,9): error TS2370: A rest parameter must be of an array type.
|
||||
tests/cases/conformance/types/objectTypeLiteral/callSignatures/restParametersOfNonArrayTypes2.ts(43,6): error TS2370: A rest parameter must be of an array type.
|
||||
tests/cases/conformance/types/objectTypeLiteral/callSignatures/restParametersOfNonArrayTypes2.ts(44,9): error TS1014: A rest parameter must be last in a parameter list.
|
||||
tests/cases/conformance/types/objectTypeLiteral/callSignatures/restParametersOfNonArrayTypes2.ts(44,9): error TS2370: A rest parameter must be of an array type.
|
||||
tests/cases/conformance/types/objectTypeLiteral/callSignatures/restParametersOfNonArrayTypes2.ts(44,33): error TS2370: A rest parameter must be of an array type.
|
||||
tests/cases/conformance/types/objectTypeLiteral/callSignatures/restParametersOfNonArrayTypes2.ts(48,6): error TS2370: A rest parameter must be of an array type.
|
||||
tests/cases/conformance/types/objectTypeLiteral/callSignatures/restParametersOfNonArrayTypes2.ts(49,9): error TS2370: A rest parameter must be of an array type.
|
||||
tests/cases/conformance/types/objectTypeLiteral/callSignatures/restParametersOfNonArrayTypes2.ts(53,9): error TS2370: A rest parameter must be of an array type.
|
||||
tests/cases/conformance/types/objectTypeLiteral/callSignatures/restParametersOfNonArrayTypes2.ts(54,21): error TS1014: A rest parameter must be last in a parameter list.
|
||||
tests/cases/conformance/types/objectTypeLiteral/callSignatures/restParametersOfNonArrayTypes2.ts(54,21): error TS2370: A rest parameter must be of an array type.
|
||||
tests/cases/conformance/types/objectTypeLiteral/callSignatures/restParametersOfNonArrayTypes2.ts(54,45): error TS2370: A rest parameter must be of an array type.
|
||||
tests/cases/conformance/types/objectTypeLiteral/callSignatures/restParametersOfNonArrayTypes2.ts(55,9): error TS2370: A rest parameter must be of an array type.
|
||||
|
||||
|
||||
==== tests/cases/conformance/types/objectTypeLiteral/callSignatures/restParametersOfNonArrayTypes2.ts (34 errors) ====
|
||||
==== tests/cases/conformance/types/objectTypeLiteral/callSignatures/restParametersOfNonArrayTypes2.ts (6 errors) ====
|
||||
// Rest parameters must be an array type if they have a type annotation,
|
||||
// user defined subtypes of array do not count, all of these are errors
|
||||
|
||||
|
@ -42,120 +14,64 @@ tests/cases/conformance/types/objectTypeLiteral/callSignatures/restParametersOfN
|
|||
interface MyThing2<T> extends Array<T> { }
|
||||
|
||||
function foo(...x: MyThing) { }
|
||||
~~~~~~~~~~~~~
|
||||
!!! error TS2370: A rest parameter must be of an array type.
|
||||
var f = function foo(...x: MyThing) { }
|
||||
~~~~~~~~~~~~~
|
||||
!!! error TS2370: A rest parameter must be of an array type.
|
||||
var f2 = (...x: MyThing, ...y: MyThing) => { }
|
||||
~~~
|
||||
!!! error TS1014: A rest parameter must be last in a parameter list.
|
||||
~~~~~~~~~~~~~
|
||||
!!! error TS2370: A rest parameter must be of an array type.
|
||||
~~~~~~~~~~~~~
|
||||
!!! error TS2370: A rest parameter must be of an array type.
|
||||
|
||||
class C {
|
||||
foo(...x: MyThing) { }
|
||||
~~~~~~~~~~~~~
|
||||
!!! error TS2370: A rest parameter must be of an array type.
|
||||
}
|
||||
|
||||
interface I {
|
||||
(...x: MyThing);
|
||||
~~~~~~~~~~~~~
|
||||
!!! error TS2370: A rest parameter must be of an array type.
|
||||
foo(...x: MyThing, ...y: MyThing);
|
||||
~~~
|
||||
!!! error TS1014: A rest parameter must be last in a parameter list.
|
||||
~~~~~~~~~~~~~
|
||||
!!! error TS2370: A rest parameter must be of an array type.
|
||||
~~~~~~~~~~~~~
|
||||
!!! error TS2370: A rest parameter must be of an array type.
|
||||
}
|
||||
|
||||
var a: {
|
||||
(...x: MyThing);
|
||||
~~~~~~~~~~~~~
|
||||
!!! error TS2370: A rest parameter must be of an array type.
|
||||
foo(...x: MyThing);
|
||||
~~~~~~~~~~~~~
|
||||
!!! error TS2370: A rest parameter must be of an array type.
|
||||
}
|
||||
|
||||
var b = {
|
||||
foo(...x: MyThing) { },
|
||||
~~~~~~~~~~~~~
|
||||
!!! error TS2370: A rest parameter must be of an array type.
|
||||
a: function foo(...x: MyThing, ...y: MyThing) { },
|
||||
~~~
|
||||
!!! error TS1014: A rest parameter must be last in a parameter list.
|
||||
~~~~~~~~~~~~~
|
||||
!!! error TS2370: A rest parameter must be of an array type.
|
||||
~~~~~~~~~~~~~
|
||||
!!! error TS2370: A rest parameter must be of an array type.
|
||||
b: (...x: MyThing) => { }
|
||||
~~~~~~~~~~~~~
|
||||
!!! error TS2370: A rest parameter must be of an array type.
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
function foo2(...x: MyThing2<string>) { }
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2370: A rest parameter must be of an array type.
|
||||
var f3 = function foo(...x: MyThing2<string>) { }
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2370: A rest parameter must be of an array type.
|
||||
var f4 = (...x: MyThing2<string>, ...y: MyThing2<string>) => { }
|
||||
~~~
|
||||
!!! error TS1014: A rest parameter must be last in a parameter list.
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2370: A rest parameter must be of an array type.
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2370: A rest parameter must be of an array type.
|
||||
|
||||
class C2 {
|
||||
foo(...x: MyThing2<string>) { }
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2370: A rest parameter must be of an array type.
|
||||
}
|
||||
|
||||
interface I2 {
|
||||
(...x: MyThing2<string>);
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2370: A rest parameter must be of an array type.
|
||||
foo(...x: MyThing2<string>, ...y: MyThing2<string>);
|
||||
~~~
|
||||
!!! error TS1014: A rest parameter must be last in a parameter list.
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2370: A rest parameter must be of an array type.
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2370: A rest parameter must be of an array type.
|
||||
}
|
||||
|
||||
var a2: {
|
||||
(...x: MyThing2<string>);
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2370: A rest parameter must be of an array type.
|
||||
foo(...x: MyThing2<string>);
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2370: A rest parameter must be of an array type.
|
||||
}
|
||||
|
||||
var b2 = {
|
||||
foo(...x: MyThing2<string>) { },
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2370: A rest parameter must be of an array type.
|
||||
a: function foo(...x: MyThing2<string>, ...y: MyThing2<string>) { },
|
||||
~~~
|
||||
!!! error TS1014: A rest parameter must be last in a parameter list.
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2370: A rest parameter must be of an array type.
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2370: A rest parameter must be of an array type.
|
||||
b: (...x: MyThing2<string>) => { }
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2370: A rest parameter must be of an array type.
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
tests/cases/conformance/types/rest/restTuplesFromContextualTypes.ts(56,7): error TS2345: Argument of type '(a: number, b: any, ...x: any[]) => void' is not assignable to parameter of type '(x: number, ...args: T) => void'.
|
||||
Types of parameters 'b' and 'args' are incompatible.
|
||||
Type 'T' is not assignable to type '[any, ...any[]]'.
|
||||
Type 'any[]' is not assignable to type '[any, ...any[]]'.
|
||||
Property '0' is missing in type 'any[]'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/types/rest/restTuplesFromContextualTypes.ts (1 errors) ====
|
||||
declare const t1: [number, boolean, string];
|
||||
|
||||
(function (a, b, c){})(...t1);
|
||||
(function (...x){})(...t1);
|
||||
(function (a, ...x){})(...t1);
|
||||
(function (a, b, ...x){})(...t1);
|
||||
(function (a, b, c, ...x){})(...t1);
|
||||
|
||||
declare function f1(cb: (...args: typeof t1) => void): void;
|
||||
|
||||
f1((a, b, c) => {})
|
||||
f1((...x) => {})
|
||||
f1((a, ...x) => {})
|
||||
f1((a, b, ...x) => {})
|
||||
f1((a, b, c, ...x) => {})
|
||||
|
||||
declare const t2: [number, boolean, ...string[]];
|
||||
|
||||
(function (a, b, c){})(...t2);
|
||||
(function (...x){})(...t2);
|
||||
(function (a, ...x){})(...t2);
|
||||
(function (a, b, ...x){})(...t2);
|
||||
(function (a, b, c, ...x){})(...t2);
|
||||
|
||||
declare function f2(cb: (...args: typeof t2) => void): void;
|
||||
|
||||
f2((a, b, c) => {})
|
||||
f2((...x) => {})
|
||||
f2((a, ...x) => {})
|
||||
f2((a, b, ...x) => {})
|
||||
f2((a, b, c, ...x) => {})
|
||||
|
||||
declare const t3: [boolean, ...string[]];
|
||||
|
||||
(function (a, b, c){})(1, ...t3);
|
||||
(function (...x){})(1, ...t3);
|
||||
(function (a, ...x){})(1, ...t3);
|
||||
(function (a, b, ...x){})(1, ...t3);
|
||||
(function (a, b, c, ...x){})(1, ...t3);
|
||||
|
||||
declare function f3(cb: (x: number, ...args: typeof t3) => void): void;
|
||||
|
||||
f3((a, b, c) => {})
|
||||
f3((...x) => {})
|
||||
f3((a, ...x) => {})
|
||||
f3((a, b, ...x) => {})
|
||||
f3((a, b, c, ...x) => {})
|
||||
|
||||
function f4<T extends any[]>(t: T) {
|
||||
(function(...x){})(...t);
|
||||
(function(a, ...x){})(1, ...t);
|
||||
(function(a, ...x){})(1, 2, ...t);
|
||||
function f(cb: (x: number, ...args: T) => void) {}
|
||||
f((...x) => {});
|
||||
f((a, ...x) => {});
|
||||
f((a, b, ...x) => {});
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2345: Argument of type '(a: number, b: any, ...x: any[]) => void' is not assignable to parameter of type '(x: number, ...args: T) => void'.
|
||||
!!! error TS2345: Types of parameters 'b' and 'args' are incompatible.
|
||||
!!! error TS2345: Type 'T' is not assignable to type '[any, ...any[]]'.
|
||||
!!! error TS2345: Type 'any[]' is not assignable to type '[any, ...any[]]'.
|
||||
!!! error TS2345: Property '0' is missing in type 'any[]'.
|
||||
}
|
||||
|
||||
// Repro from #25288
|
||||
|
||||
declare var tuple: [number, string];
|
||||
(function foo(a, b){}(...tuple));
|
||||
|
||||
// Repro from #25289
|
||||
|
||||
declare function take(cb: (a: number, b: string) => void): void;
|
||||
|
||||
(function foo(...rest){}(1, ''));
|
||||
take(function(...rest){});
|
||||
|
56
tests/cases/conformance/types/rest/genericRestParameters3.ts
Normal file
56
tests/cases/conformance/types/rest/genericRestParameters3.ts
Normal file
|
@ -0,0 +1,56 @@
|
|||
// @strict: true
|
||||
// @declaration: true
|
||||
|
||||
declare let f1: (x: string, ...args: [string] | [number, boolean]) => void;
|
||||
declare let f2: (x: string, y: string) => void;
|
||||
declare let f3: (x: string, y: number, z: boolean) => void;
|
||||
declare let f4: (...args: [string, string] | [string, number, boolean]) => void;
|
||||
|
||||
declare const tt: [string] | [number, boolean];
|
||||
|
||||
f1("foo", "abc");
|
||||
f1("foo", 10, true);
|
||||
f1("foo", ...tt);
|
||||
f1("foo", 10); // Error
|
||||
f1("foo"); // Error
|
||||
|
||||
f2 = f1;
|
||||
f3 = f1;
|
||||
f4 = f1; // Error, misaligned complex rest types
|
||||
f1 = f2; // Error
|
||||
f1 = f3; // Error
|
||||
f1 = f4; // Error, misaligned complex rest types
|
||||
|
||||
// Repro from #26110
|
||||
|
||||
interface CoolArray<E> extends Array<E> {
|
||||
hello: number;
|
||||
}
|
||||
|
||||
declare function foo<T extends any[]>(cb: (...args: T) => void): void;
|
||||
|
||||
foo<CoolArray<any>>(); // Error
|
||||
foo<CoolArray<any>>(100); // Error
|
||||
foo<CoolArray<any>>(foo); // Error
|
||||
|
||||
function bar<T extends any[]>(...args: T): T {
|
||||
return args;
|
||||
}
|
||||
|
||||
let a = bar(10, 20);
|
||||
let b = bar<CoolArray<number>>(10, 20); // Error
|
||||
|
||||
declare function baz<T>(...args: CoolArray<T>): void;
|
||||
declare const ca: CoolArray<number>;
|
||||
|
||||
baz(); // Error
|
||||
baz(1); // Error
|
||||
baz(1, 2); // Error
|
||||
baz(...ca); // Error
|
||||
|
||||
// Repro from #26491
|
||||
|
||||
declare function hmm<A extends [] | [number, string]>(...args: A): void;
|
||||
hmm(); // okay, A = []
|
||||
hmm(1, "s"); // okay, A = [1, "s"]
|
||||
hmm("what"); // no error? A = [] | [number, string] ?
|
Loading…
Reference in a new issue