Fix contextually typed parameter issues (#36476)

* Fix multiple issues with contextually typed parameters

* Accept new baselines

* Fix lint error

* Add tests

* Address CR feedback

* Add fourslash tests
This commit is contained in:
Anders Hejlsberg 2020-01-30 10:50:39 -08:00 committed by GitHub
parent 140fee96d7
commit 8a0b8822b2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 861 additions and 179 deletions

View File

@ -7159,12 +7159,6 @@ namespace ts {
return strictNullChecks && optional ? getOptionalType(type) : type;
}
function isParameterOfContextuallyTypedFunction(node: Declaration) {
return node.kind === SyntaxKind.Parameter &&
(node.parent.kind === SyntaxKind.FunctionExpression || node.parent.kind === SyntaxKind.ArrowFunction) &&
!!getContextualType(<Expression>node.parent);
}
// Return the inferred type for a variable, parameter, or property declaration
function getTypeForVariableLikeDeclaration(declaration: ParameterDeclaration | PropertyDeclaration | PropertySignature | VariableDeclaration | BindingElement, includeOptionality: boolean): Type | undefined {
// A variable declared in a for..in statement is of type string, or of type keyof T when the
@ -7236,7 +7230,7 @@ namespace ts {
}
}
// Use contextual parameter type if one is available
const type = declaration.symbol.escapedName === InternalSymbolName.This ? getContextualThisParameterType(func) : getContextuallyTypedParameterType(declaration, /*forCache*/ true);
const type = declaration.symbol.escapedName === InternalSymbolName.This ? getContextualThisParameterType(func) : getContextuallyTypedParameterType(declaration);
if (type) {
return addOptionality(type, isOptional);
}
@ -7250,7 +7244,7 @@ namespace ts {
// Use the type of the initializer expression if one is present and the declaration is
// not a parameter of a contextually typed function
if (declaration.initializer && !isParameterOfContextuallyTypedFunction(declaration)) {
if (declaration.initializer) {
const type = widenTypeInferredFromInitializer(declaration, checkDeclarationInitializer(declaration));
return addOptionality(type, isOptional);
}
@ -7263,7 +7257,7 @@ namespace ts {
// If the declaration specifies a binding pattern and is not a parameter of a contextually
// typed function, use the type implied by the binding pattern
if (isBindingPattern(declaration.name) && !isParameterOfContextuallyTypedFunction(declaration)) {
if (isBindingPattern(declaration.name)) {
return getTypeFromBindingPattern(declaration.name, /*includePatternInType*/ false, /*reportErrors*/ true);
}
@ -13798,31 +13792,32 @@ namespace ts {
}
function isContextSensitiveFunctionLikeDeclaration(node: FunctionLikeDeclaration): boolean {
if (isFunctionDeclaration(node) && (!isInJSFile(node) || !getTypeForDeclarationFromJSDocComment(node))) {
return false;
}
return (!isFunctionDeclaration(node) || isInJSFile(node) && !!getTypeForDeclarationFromJSDocComment(node)) &&
(hasContextSensitiveParameters(node) || hasContextSensitiveReturnExpression(node));
}
function hasContextSensitiveParameters(node: FunctionLikeDeclaration) {
// Functions with type parameters are not context sensitive.
if (node.typeParameters) {
return false;
}
// Functions with any parameters that lack type annotations are context sensitive.
if (some(node.parameters, p => !getEffectiveTypeAnnotationNode(p))) {
return true;
}
if (node.kind !== SyntaxKind.ArrowFunction) {
// If the first parameter is not an explicit 'this' parameter, then the function has
// an implicit 'this' parameter which is subject to contextual typing.
const parameter = firstOrUndefined(node.parameters);
if (!(parameter && parameterIsThisKeyword(parameter))) {
if (!node.typeParameters) {
// Functions with any parameters that lack type annotations are context sensitive.
if (some(node.parameters, p => !getEffectiveTypeAnnotationNode(p))) {
return true;
}
if (node.kind !== SyntaxKind.ArrowFunction) {
// If the first parameter is not an explicit 'this' parameter, then the function has
// an implicit 'this' parameter which is subject to contextual typing.
const parameter = firstOrUndefined(node.parameters);
if (!(parameter && parameterIsThisKeyword(parameter))) {
return true;
}
}
}
return hasContextSensitiveReturnExpression(node);
return false;
}
function hasContextSensitiveReturnExpression(node: FunctionLikeDeclaration) {
// TODO(anhans): A block should be context-sensitive if it has a context-sensitive return value.
return !!node.body && node.body.kind !== SyntaxKind.Block && isContextSensitive(node.body);
return !getEffectiveReturnTypeNode(node) && !!node.body && node.body.kind !== SyntaxKind.Block && isContextSensitive(node.body);
}
function isContextSensitiveFunctionOrObjectLiteralMethod(func: Node): func is FunctionExpression | ArrowFunction | MethodDeclaration {
@ -21270,7 +21265,7 @@ namespace ts {
}
// Return contextual type of parameter or undefined if no contextual type is available
function getContextuallyTypedParameterType(parameter: ParameterDeclaration, forCache: boolean): Type | undefined {
function getContextuallyTypedParameterType(parameter: ParameterDeclaration): Type | undefined {
const func = parameter.parent;
if (!isContextSensitiveFunctionOrObjectLiteralMethod(func)) {
return undefined;
@ -21291,21 +21286,8 @@ namespace ts {
links.resolvedSignature = cached;
return type;
}
let contextualSignature = getContextualSignature(func);
const contextualSignature = getContextualSignature(func);
if (contextualSignature) {
if (forCache) {
// Calling the below guarantees the types are primed and assigned in the same way
// as when the parameter is reached via `checkFunctionExpressionOrObjectLiteralMethod`.
// This should prevent any uninstantiated inference variables in the contextual signature
// from leaking, and should lock in cached parameter types via `assignContextualParameterTypes`
// which we will then immediately use the results of below.
contextuallyCheckFunctionExpressionOrObjectLiteralMethod(func);
const type = getTypeOfSymbol(getMergedSymbol(func.symbol));
if (isTypeAny(type)) {
return type;
}
contextualSignature = getSignaturesOfType(type, SignatureKind.Call)[0];
}
const index = func.parameters.indexOf(parameter) - (getThisParameter(func) ? 1 : 0);
return parameter.dotDotDotToken && lastOrUndefined(func.parameters) === parameter ?
getRestTypeAtPosition(contextualSignature, index) :
@ -21320,7 +21302,7 @@ namespace ts {
}
switch (declaration.kind) {
case SyntaxKind.Parameter:
return getContextuallyTypedParameterType(declaration, /*forCache*/ false);
return getContextuallyTypedParameterType(declaration);
case SyntaxKind.BindingElement:
return getContextualTypeForBindingElement(declaration);
// By default, do nothing and return undefined - only parameters and binding elements have context implied by a parent
@ -26103,15 +26085,15 @@ namespace ts {
if (!parameter) {
signature.thisParameter = createSymbolWithType(context.thisParameter, /*type*/ undefined);
}
assignTypeToParameterAndFixTypeParameters(signature.thisParameter!, getTypeOfSymbol(context.thisParameter));
assignParameterType(signature.thisParameter!, getTypeOfSymbol(context.thisParameter));
}
}
const len = signature.parameters.length - (signatureHasRestParameter(signature) ? 1 : 0);
for (let i = 0; i < len; i++) {
const parameter = signature.parameters[i];
if (!getEffectiveTypeAnnotationNode(<ParameterDeclaration>parameter.valueDeclaration)) {
const contextualParameterType = getTypeAtPosition(context, i);
assignTypeToParameterAndFixTypeParameters(parameter, contextualParameterType);
const contextualParameterType = tryGetTypeAtPosition(context, i);
assignParameterType(parameter, contextualParameterType);
}
}
if (signatureHasRestParameter(signature)) {
@ -26119,7 +26101,31 @@ namespace ts {
const parameter = last(signature.parameters);
if (isTransientSymbol(parameter) || !getEffectiveTypeAnnotationNode(<ParameterDeclaration>parameter.valueDeclaration)) {
const contextualParameterType = getRestTypeAtPosition(context, len);
assignTypeToParameterAndFixTypeParameters(parameter, contextualParameterType);
assignParameterType(parameter, contextualParameterType);
}
}
}
function assignNonContextualParameterTypes(signature: Signature) {
if (signature.thisParameter) {
assignParameterType(signature.thisParameter);
}
for (const parameter of signature.parameters) {
assignParameterType(parameter);
}
}
function assignParameterType(parameter: Symbol, type?: Type) {
const links = getSymbolLinks(parameter);
if (!links.type) {
const declaration = parameter.valueDeclaration as ParameterDeclaration;
links.type = type || getWidenedTypeForVariableLikeDeclaration(declaration, /*includeOptionality*/ true);
if (declaration.name.kind !== SyntaxKind.Identifier) {
// if inference didn't come up with anything but unknown, fall back to the binding pattern if present.
if (links.type === unknownType) {
links.type = getTypeFromBindingPattern(declaration.name);
}
assignBindingElementTypes(declaration.name);
}
}
}
@ -26139,21 +26145,6 @@ namespace ts {
}
}
function assignTypeToParameterAndFixTypeParameters(parameter: Symbol, contextualType: Type) {
const links = getSymbolLinks(parameter);
if (!links.type) {
links.type = contextualType;
const decl = parameter.valueDeclaration as ParameterDeclaration;
if (decl.name.kind !== SyntaxKind.Identifier) {
// if inference didn't come up with anything but unknown, fall back to the binding pattern if present.
if (links.type === unknownType) {
links.type = getTypeFromBindingPattern(decl.name);
}
assignBindingElementTypes(decl.name);
}
}
}
function createPromiseType(promisedType: Type): Type {
// creates a `Promise<T>` type where `T` is the promisedType argument
const globalPromiseType = getGlobalPromiseType(/*reportErrors*/ true);
@ -26539,14 +26530,14 @@ namespace ts {
}
}
function checkFunctionExpressionOrObjectLiteralMethod(node: FunctionExpression | MethodDeclaration, checkMode?: CheckMode): Type {
function checkFunctionExpressionOrObjectLiteralMethod(node: FunctionExpression | ArrowFunction | MethodDeclaration, checkMode?: CheckMode): Type {
Debug.assert(node.kind !== SyntaxKind.MethodDeclaration || isObjectLiteralMethod(node));
checkNodeDeferred(node);
// The identityMapper object is used to indicate that function expressions are wildcards
if (checkMode && checkMode & CheckMode.SkipContextSensitive && isContextSensitive(node)) {
// Skip parameters, return signature with return type that retains noncontextual parts so inferences can still be drawn in an early stage
if (!getEffectiveReturnTypeNode(node) && hasContextSensitiveReturnExpression(node)) {
if (!getEffectiveReturnTypeNode(node) && !hasContextSensitiveParameters(node)) {
// Return plain anyFunctionType if there is no possibility we'll make inferences from the return type
const contextualSignature = getContextualSignature(node);
if (contextualSignature && couldContainTypeVariables(getReturnTypeOfSignature(contextualSignature))) {
@ -26570,14 +26561,9 @@ namespace ts {
checkGrammarForGenerator(node);
}
const type = getTypeOfSymbol(getMergedSymbol(node.symbol));
if (isTypeAny(type)) {
return type;
}
contextuallyCheckFunctionExpressionOrObjectLiteralMethod(node, checkMode);
return type;
return getTypeOfSymbol(getSymbolOfNode(node));
}
function contextuallyCheckFunctionExpressionOrObjectLiteralMethod(node: FunctionExpression | ArrowFunction | MethodDeclaration, checkMode?: CheckMode) {
@ -26590,13 +26576,12 @@ namespace ts {
// already assigned contextual types.
if (!(links.flags & NodeCheckFlags.ContextChecked)) {
links.flags |= NodeCheckFlags.ContextChecked;
if (contextualSignature) {
const type = getTypeOfSymbol(getMergedSymbol(node.symbol));
if (isTypeAny(type)) {
return;
}
const signature = getSignaturesOfType(type, SignatureKind.Call)[0];
if (isContextSensitive(node)) {
const signature = firstOrUndefined(getSignaturesOfType(getTypeOfSymbol(getSymbolOfNode(node)), SignatureKind.Call));
if (!signature) {
return;
}
if (isContextSensitive(node)) {
if (contextualSignature) {
const inferenceContext = getInferenceContext(node);
if (checkMode && checkMode & CheckMode.Inferential) {
inferFromAnnotatedParameters(signature, contextualSignature, inferenceContext!);
@ -26605,11 +26590,15 @@ namespace ts {
instantiateSignature(contextualSignature, inferenceContext.mapper) : contextualSignature;
assignContextualParameterTypes(signature, instantiatedContextualSignature);
}
if (!getReturnTypeFromAnnotation(node) && !signature.resolvedReturnType) {
const returnType = getReturnTypeFromBody(node, checkMode);
if (!signature.resolvedReturnType) {
signature.resolvedReturnType = returnType;
}
else {
// Force resolution of all parameter types such that the absence of a contextual type is consistently reflected.
assignNonContextualParameterTypes(signature);
}
}
if (contextualSignature && !getReturnTypeFromAnnotation(node) && !signature.resolvedReturnType) {
const returnType = getReturnTypeFromBody(node, checkMode);
if (!signature.resolvedReturnType) {
signature.resolvedReturnType = returnType;
}
}
checkSignatureDeclaration(node);
@ -28332,7 +28321,7 @@ namespace ts {
return checkClassExpression(<ClassExpression>node);
case SyntaxKind.FunctionExpression:
case SyntaxKind.ArrowFunction:
return checkFunctionExpressionOrObjectLiteralMethod(<FunctionExpression>node, checkMode);
return checkFunctionExpressionOrObjectLiteralMethod(<FunctionExpression | ArrowFunction>node, checkMode);
case SyntaxKind.TypeOfExpression:
return checkTypeOfExpression(<TypeOfExpression>node);
case SyntaxKind.TypeAssertionExpression:

View File

@ -1,9 +1,8 @@
tests/cases/compiler/contextuallyTypedParametersWithInitializers.ts(8,29): error TS7031: Binding element 'foo' implicitly has an 'any' type.
tests/cases/compiler/contextuallyTypedParametersWithInitializers.ts(14,27): error TS7006: Parameter 'foo' implicitly has an 'any' type.
tests/cases/compiler/contextuallyTypedParametersWithInitializers.ts(27,42): error TS7031: Binding element 'foo' implicitly has an 'any' type.
tests/cases/compiler/contextuallyTypedParametersWithInitializers.ts(24,24): error TS7006: Parameter 'x' implicitly has an 'any' type.
tests/cases/compiler/contextuallyTypedParametersWithInitializers.ts(40,5): error TS7006: Parameter 'x' implicitly has an 'any' type.
==== tests/cases/compiler/contextuallyTypedParametersWithInitializers.ts (3 errors) ====
==== tests/cases/compiler/contextuallyTypedParametersWithInitializers.ts (2 errors) ====
declare function id1<T>(input: T): T;
declare function id2<T extends (x: any) => any>(input: T): T;
declare function id3<T extends (x: { foo: any }) => any>(input: T): T;
@ -11,20 +10,45 @@ tests/cases/compiler/contextuallyTypedParametersWithInitializers.ts(27,42): erro
declare function id5<T extends (x?: number) => any>(input: T): T;
const f10 = function ({ foo = 42 }) { return foo };
const f11 = id1(function ({ foo = 42 }) { return foo }); // Implicit any error
~~~
!!! error TS7031: Binding element 'foo' implicitly has an 'any' type.
const f11 = id1(function ({ foo = 42 }) { return foo });
const f12 = id2(function ({ foo = 42 }) { return foo });
const f13 = id3(function ({ foo = 42 }) { return foo });
const f14 = id4(function ({ foo = 42 }) { return foo });
const f20 = function (foo = 42) { return foo };
const f21 = id1(function (foo = 42) { return foo }); // Implicit any error
~~~~~~~~
!!! error TS7006: Parameter 'foo' implicitly has an 'any' type.
const f21 = id1(function (foo = 42) { return foo });
const f22 = id2(function (foo = 42) { return foo });
const f25 = id5(function (foo = 42) { return foo });
const f1 = (x = 1) => 0; // number
const f2: any = (x = 1) => 0; // number
const f3: unknown = (x = 1) => 0; // number
const f4: Function = (x = 1) => 0; // number
const f5: (...args: any[]) => any = (x = 1) => 0; // any
const f6: () => any = (x = 1) => 0; // number
const f7: () => any = (x?) => 0; // Implicit any error
~~
!!! error TS7006: Parameter 'x' implicitly has an 'any' type.
const f8: () => any = (...x) => 0; // []
declare function g1<T>(x: T): T;
declare function g2<T extends any>(x: T): T;
declare function g3<T extends unknown>(x: T): T;
declare function g4<T extends Function>(x: T): T;
declare function g5<T extends (...args: any[]) => any>(x: T): T;
declare function g6<T extends () => any>(x: T): T;
g1((x = 1) => 0); // number
g2((x = 1) => 0); // number
g3((x = 1) => 0); // number
g4((x = 1) => 0); // number
g5((x = 1) => 0); // any
g6((x = 1) => 0); // number
g6((x?) => 0); // Implicit any error
~~
!!! error TS7006: Parameter 'x' implicitly has an 'any' type.
g6((...x) => 0); // []
// Repro from #28816
function id<T>(input: T): T { return input }
@ -35,8 +59,35 @@ tests/cases/compiler/contextuallyTypedParametersWithInitializers.ts(27,42): erro
const newGetFoo = id(getFoo);
const newGetFoo2 = id(function getFoo ({ foo = 42 }) {
~~~
!!! error TS7031: Binding element 'foo' implicitly has an 'any' type.
return foo;
});
// Repro from comment in #30840
declare function memoize<F extends Function>(func: F): F;
function add(x: number, y = 0): number {
return x + y;
}
const memoizedAdd = memoize(add);
const add2 = (x: number, y = 0): number => x + y;
const memoizedAdd2 = memoize(add2);
const memoizedAdd3 = memoize((x: number, y = 0): number => x + y);
// Repro from #36052
declare function execute(script: string | Function): Promise<string>;
export function executeSomething() {
return execute((root: HTMLElement, debug = true) => {
if (debug) {
root.innerHTML = '';
}
});
}
const fz1 = (debug = true) => false;
const fz2: Function = (debug = true) => false;

View File

@ -6,16 +6,41 @@ declare function id4<T extends (x: { foo?: number }) => any>(input: T): T;
declare function id5<T extends (x?: number) => any>(input: T): T;
const f10 = function ({ foo = 42 }) { return foo };
const f11 = id1(function ({ foo = 42 }) { return foo }); // Implicit any error
const f11 = id1(function ({ foo = 42 }) { return foo });
const f12 = id2(function ({ foo = 42 }) { return foo });
const f13 = id3(function ({ foo = 42 }) { return foo });
const f14 = id4(function ({ foo = 42 }) { return foo });
const f20 = function (foo = 42) { return foo };
const f21 = id1(function (foo = 42) { return foo }); // Implicit any error
const f21 = id1(function (foo = 42) { return foo });
const f22 = id2(function (foo = 42) { return foo });
const f25 = id5(function (foo = 42) { return foo });
const f1 = (x = 1) => 0; // number
const f2: any = (x = 1) => 0; // number
const f3: unknown = (x = 1) => 0; // number
const f4: Function = (x = 1) => 0; // number
const f5: (...args: any[]) => any = (x = 1) => 0; // any
const f6: () => any = (x = 1) => 0; // number
const f7: () => any = (x?) => 0; // Implicit any error
const f8: () => any = (...x) => 0; // []
declare function g1<T>(x: T): T;
declare function g2<T extends any>(x: T): T;
declare function g3<T extends unknown>(x: T): T;
declare function g4<T extends Function>(x: T): T;
declare function g5<T extends (...args: any[]) => any>(x: T): T;
declare function g6<T extends () => any>(x: T): T;
g1((x = 1) => 0); // number
g2((x = 1) => 0); // number
g3((x = 1) => 0); // number
g4((x = 1) => 0); // number
g5((x = 1) => 0); // any
g6((x = 1) => 0); // number
g6((x?) => 0); // Implicit any error
g6((...x) => 0); // []
// Repro from #28816
function id<T>(input: T): T { return input }
@ -28,10 +53,40 @@ const newGetFoo = id(getFoo);
const newGetFoo2 = id(function getFoo ({ foo = 42 }) {
return foo;
});
// Repro from comment in #30840
declare function memoize<F extends Function>(func: F): F;
function add(x: number, y = 0): number {
return x + y;
}
const memoizedAdd = memoize(add);
const add2 = (x: number, y = 0): number => x + y;
const memoizedAdd2 = memoize(add2);
const memoizedAdd3 = memoize((x: number, y = 0): number => x + y);
// Repro from #36052
declare function execute(script: string | Function): Promise<string>;
export function executeSomething() {
return execute((root: HTMLElement, debug = true) => {
if (debug) {
root.innerHTML = '';
}
});
}
const fz1 = (debug = true) => false;
const fz2: Function = (debug = true) => false;
//// [contextuallyTypedParametersWithInitializers.js]
"use strict";
exports.__esModule = true;
var f10 = function (_a) {
var _b = _a.foo, foo = _b === void 0 ? 42 : _b;
return foo;
@ -39,7 +94,7 @@ var f10 = function (_a) {
var f11 = id1(function (_a) {
var _b = _a.foo, foo = _b === void 0 ? 42 : _b;
return foo;
}); // Implicit any error
});
var f12 = id2(function (_a) {
var _b = _a.foo, foo = _b === void 0 ? 42 : _b;
return foo;
@ -59,7 +114,7 @@ var f20 = function (foo) {
var f21 = id1(function (foo) {
if (foo === void 0) { foo = 42; }
return foo;
}); // Implicit any error
});
var f22 = id2(function (foo) {
if (foo === void 0) { foo = 42; }
return foo;
@ -68,6 +123,70 @@ var f25 = id5(function (foo) {
if (foo === void 0) { foo = 42; }
return foo;
});
var f1 = function (x) {
if (x === void 0) { x = 1; }
return 0;
}; // number
var f2 = function (x) {
if (x === void 0) { x = 1; }
return 0;
}; // number
var f3 = function (x) {
if (x === void 0) { x = 1; }
return 0;
}; // number
var f4 = function (x) {
if (x === void 0) { x = 1; }
return 0;
}; // number
var f5 = function (x) {
if (x === void 0) { x = 1; }
return 0;
}; // any
var f6 = function (x) {
if (x === void 0) { x = 1; }
return 0;
}; // number
var f7 = function (x) { return 0; }; // Implicit any error
var f8 = function () {
var x = [];
for (var _i = 0; _i < arguments.length; _i++) {
x[_i] = arguments[_i];
}
return 0;
}; // []
g1(function (x) {
if (x === void 0) { x = 1; }
return 0;
}); // number
g2(function (x) {
if (x === void 0) { x = 1; }
return 0;
}); // number
g3(function (x) {
if (x === void 0) { x = 1; }
return 0;
}); // number
g4(function (x) {
if (x === void 0) { x = 1; }
return 0;
}); // number
g5(function (x) {
if (x === void 0) { x = 1; }
return 0;
}); // any
g6(function (x) {
if (x === void 0) { x = 1; }
return 0;
}); // number
g6(function (x) { return 0; }); // Implicit any error
g6(function () {
var x = [];
for (var _i = 0; _i < arguments.length; _i++) {
x[_i] = arguments[_i];
}
return 0;
}); // []
// Repro from #28816
function id(input) { return input; }
function getFoo(_a) {
@ -79,36 +198,38 @@ var newGetFoo2 = id(function getFoo(_a) {
var _b = _a.foo, foo = _b === void 0 ? 42 : _b;
return foo;
});
function add(x, y) {
if (y === void 0) { y = 0; }
return x + y;
}
var memoizedAdd = memoize(add);
var add2 = function (x, y) {
if (y === void 0) { y = 0; }
return x + y;
};
var memoizedAdd2 = memoize(add2);
var memoizedAdd3 = memoize(function (x, y) {
if (y === void 0) { y = 0; }
return x + y;
});
function executeSomething() {
return execute(function (root, debug) {
if (debug === void 0) { debug = true; }
if (debug) {
root.innerHTML = '';
}
});
}
exports.executeSomething = executeSomething;
var fz1 = function (debug) {
if (debug === void 0) { debug = true; }
return false;
};
var fz2 = function (debug) {
if (debug === void 0) { debug = true; }
return false;
};
//// [contextuallyTypedParametersWithInitializers.d.ts]
declare function id1<T>(input: T): T;
declare function id2<T extends (x: any) => any>(input: T): T;
declare function id3<T extends (x: {
foo: any;
}) => any>(input: T): T;
declare function id4<T extends (x: {
foo?: number;
}) => any>(input: T): T;
declare function id5<T extends (x?: number) => any>(input: T): T;
declare const f10: ({ foo }: {
foo?: number | undefined;
}) => number;
declare const f11: ({ foo }: any) => any;
declare const f12: ({ foo }: any) => any;
declare const f13: ({ foo }: {
foo: any;
}) => any;
declare const f14: ({ foo }: {
foo?: number | undefined;
}) => number;
declare const f20: (foo?: number) => number;
declare const f21: (foo?: any) => any;
declare const f22: (foo?: any) => any;
declare const f25: (foo?: number | undefined) => number;
declare function id<T>(input: T): T;
declare function getFoo({ foo }: {
foo?: number | undefined;
}): number;
declare const newGetFoo: typeof getFoo;
declare const newGetFoo2: ({ foo }: any) => any;
export declare function executeSomething(): Promise<string>;

View File

@ -45,7 +45,7 @@ const f10 = function ({ foo = 42 }) { return foo };
>foo : Symbol(foo, Decl(contextuallyTypedParametersWithInitializers.ts, 6, 23))
>foo : Symbol(foo, Decl(contextuallyTypedParametersWithInitializers.ts, 6, 23))
const f11 = id1(function ({ foo = 42 }) { return foo }); // Implicit any error
const f11 = id1(function ({ foo = 42 }) { return foo });
>f11 : Symbol(f11, Decl(contextuallyTypedParametersWithInitializers.ts, 7, 5))
>id1 : Symbol(id1, Decl(contextuallyTypedParametersWithInitializers.ts, 0, 0))
>foo : Symbol(foo, Decl(contextuallyTypedParametersWithInitializers.ts, 7, 27))
@ -74,7 +74,7 @@ const f20 = function (foo = 42) { return foo };
>foo : Symbol(foo, Decl(contextuallyTypedParametersWithInitializers.ts, 12, 22))
>foo : Symbol(foo, Decl(contextuallyTypedParametersWithInitializers.ts, 12, 22))
const f21 = id1(function (foo = 42) { return foo }); // Implicit any error
const f21 = id1(function (foo = 42) { return foo });
>f21 : Symbol(f21, Decl(contextuallyTypedParametersWithInitializers.ts, 13, 5))
>id1 : Symbol(id1, Decl(contextuallyTypedParametersWithInitializers.ts, 0, 0))
>foo : Symbol(foo, Decl(contextuallyTypedParametersWithInitializers.ts, 13, 26))
@ -92,37 +92,228 @@ const f25 = id5(function (foo = 42) { return foo });
>foo : Symbol(foo, Decl(contextuallyTypedParametersWithInitializers.ts, 15, 26))
>foo : Symbol(foo, Decl(contextuallyTypedParametersWithInitializers.ts, 15, 26))
const f1 = (x = 1) => 0; // number
>f1 : Symbol(f1, Decl(contextuallyTypedParametersWithInitializers.ts, 17, 5))
>x : Symbol(x, Decl(contextuallyTypedParametersWithInitializers.ts, 17, 12))
const f2: any = (x = 1) => 0; // number
>f2 : Symbol(f2, Decl(contextuallyTypedParametersWithInitializers.ts, 18, 5))
>x : Symbol(x, Decl(contextuallyTypedParametersWithInitializers.ts, 18, 17))
const f3: unknown = (x = 1) => 0; // number
>f3 : Symbol(f3, Decl(contextuallyTypedParametersWithInitializers.ts, 19, 5))
>x : Symbol(x, Decl(contextuallyTypedParametersWithInitializers.ts, 19, 21))
const f4: Function = (x = 1) => 0; // number
>f4 : Symbol(f4, Decl(contextuallyTypedParametersWithInitializers.ts, 20, 5))
>Function : Symbol(Function, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
>x : Symbol(x, Decl(contextuallyTypedParametersWithInitializers.ts, 20, 22))
const f5: (...args: any[]) => any = (x = 1) => 0; // any
>f5 : Symbol(f5, Decl(contextuallyTypedParametersWithInitializers.ts, 21, 5))
>args : Symbol(args, Decl(contextuallyTypedParametersWithInitializers.ts, 21, 11))
>x : Symbol(x, Decl(contextuallyTypedParametersWithInitializers.ts, 21, 37))
const f6: () => any = (x = 1) => 0; // number
>f6 : Symbol(f6, Decl(contextuallyTypedParametersWithInitializers.ts, 22, 5))
>x : Symbol(x, Decl(contextuallyTypedParametersWithInitializers.ts, 22, 23))
const f7: () => any = (x?) => 0; // Implicit any error
>f7 : Symbol(f7, Decl(contextuallyTypedParametersWithInitializers.ts, 23, 5))
>x : Symbol(x, Decl(contextuallyTypedParametersWithInitializers.ts, 23, 23))
const f8: () => any = (...x) => 0; // []
>f8 : Symbol(f8, Decl(contextuallyTypedParametersWithInitializers.ts, 24, 5))
>x : Symbol(x, Decl(contextuallyTypedParametersWithInitializers.ts, 24, 23))
declare function g1<T>(x: T): T;
>g1 : Symbol(g1, Decl(contextuallyTypedParametersWithInitializers.ts, 24, 34))
>T : Symbol(T, Decl(contextuallyTypedParametersWithInitializers.ts, 26, 20))
>x : Symbol(x, Decl(contextuallyTypedParametersWithInitializers.ts, 26, 23))
>T : Symbol(T, Decl(contextuallyTypedParametersWithInitializers.ts, 26, 20))
>T : Symbol(T, Decl(contextuallyTypedParametersWithInitializers.ts, 26, 20))
declare function g2<T extends any>(x: T): T;
>g2 : Symbol(g2, Decl(contextuallyTypedParametersWithInitializers.ts, 26, 32))
>T : Symbol(T, Decl(contextuallyTypedParametersWithInitializers.ts, 27, 20))
>x : Symbol(x, Decl(contextuallyTypedParametersWithInitializers.ts, 27, 35))
>T : Symbol(T, Decl(contextuallyTypedParametersWithInitializers.ts, 27, 20))
>T : Symbol(T, Decl(contextuallyTypedParametersWithInitializers.ts, 27, 20))
declare function g3<T extends unknown>(x: T): T;
>g3 : Symbol(g3, Decl(contextuallyTypedParametersWithInitializers.ts, 27, 44))
>T : Symbol(T, Decl(contextuallyTypedParametersWithInitializers.ts, 28, 20))
>x : Symbol(x, Decl(contextuallyTypedParametersWithInitializers.ts, 28, 39))
>T : Symbol(T, Decl(contextuallyTypedParametersWithInitializers.ts, 28, 20))
>T : Symbol(T, Decl(contextuallyTypedParametersWithInitializers.ts, 28, 20))
declare function g4<T extends Function>(x: T): T;
>g4 : Symbol(g4, Decl(contextuallyTypedParametersWithInitializers.ts, 28, 48))
>T : Symbol(T, Decl(contextuallyTypedParametersWithInitializers.ts, 29, 20))
>Function : Symbol(Function, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
>x : Symbol(x, Decl(contextuallyTypedParametersWithInitializers.ts, 29, 40))
>T : Symbol(T, Decl(contextuallyTypedParametersWithInitializers.ts, 29, 20))
>T : Symbol(T, Decl(contextuallyTypedParametersWithInitializers.ts, 29, 20))
declare function g5<T extends (...args: any[]) => any>(x: T): T;
>g5 : Symbol(g5, Decl(contextuallyTypedParametersWithInitializers.ts, 29, 49))
>T : Symbol(T, Decl(contextuallyTypedParametersWithInitializers.ts, 30, 20))
>args : Symbol(args, Decl(contextuallyTypedParametersWithInitializers.ts, 30, 31))
>x : Symbol(x, Decl(contextuallyTypedParametersWithInitializers.ts, 30, 55))
>T : Symbol(T, Decl(contextuallyTypedParametersWithInitializers.ts, 30, 20))
>T : Symbol(T, Decl(contextuallyTypedParametersWithInitializers.ts, 30, 20))
declare function g6<T extends () => any>(x: T): T;
>g6 : Symbol(g6, Decl(contextuallyTypedParametersWithInitializers.ts, 30, 64))
>T : Symbol(T, Decl(contextuallyTypedParametersWithInitializers.ts, 31, 20))
>x : Symbol(x, Decl(contextuallyTypedParametersWithInitializers.ts, 31, 41))
>T : Symbol(T, Decl(contextuallyTypedParametersWithInitializers.ts, 31, 20))
>T : Symbol(T, Decl(contextuallyTypedParametersWithInitializers.ts, 31, 20))
g1((x = 1) => 0); // number
>g1 : Symbol(g1, Decl(contextuallyTypedParametersWithInitializers.ts, 24, 34))
>x : Symbol(x, Decl(contextuallyTypedParametersWithInitializers.ts, 33, 4))
g2((x = 1) => 0); // number
>g2 : Symbol(g2, Decl(contextuallyTypedParametersWithInitializers.ts, 26, 32))
>x : Symbol(x, Decl(contextuallyTypedParametersWithInitializers.ts, 34, 4))
g3((x = 1) => 0); // number
>g3 : Symbol(g3, Decl(contextuallyTypedParametersWithInitializers.ts, 27, 44))
>x : Symbol(x, Decl(contextuallyTypedParametersWithInitializers.ts, 35, 4))
g4((x = 1) => 0); // number
>g4 : Symbol(g4, Decl(contextuallyTypedParametersWithInitializers.ts, 28, 48))
>x : Symbol(x, Decl(contextuallyTypedParametersWithInitializers.ts, 36, 4))
g5((x = 1) => 0); // any
>g5 : Symbol(g5, Decl(contextuallyTypedParametersWithInitializers.ts, 29, 49))
>x : Symbol(x, Decl(contextuallyTypedParametersWithInitializers.ts, 37, 4))
g6((x = 1) => 0); // number
>g6 : Symbol(g6, Decl(contextuallyTypedParametersWithInitializers.ts, 30, 64))
>x : Symbol(x, Decl(contextuallyTypedParametersWithInitializers.ts, 38, 4))
g6((x?) => 0); // Implicit any error
>g6 : Symbol(g6, Decl(contextuallyTypedParametersWithInitializers.ts, 30, 64))
>x : Symbol(x, Decl(contextuallyTypedParametersWithInitializers.ts, 39, 4))
g6((...x) => 0); // []
>g6 : Symbol(g6, Decl(contextuallyTypedParametersWithInitializers.ts, 30, 64))
>x : Symbol(x, Decl(contextuallyTypedParametersWithInitializers.ts, 40, 4))
// Repro from #28816
function id<T>(input: T): T { return input }
>id : Symbol(id, Decl(contextuallyTypedParametersWithInitializers.ts, 15, 52))
>T : Symbol(T, Decl(contextuallyTypedParametersWithInitializers.ts, 19, 12))
>input : Symbol(input, Decl(contextuallyTypedParametersWithInitializers.ts, 19, 15))
>T : Symbol(T, Decl(contextuallyTypedParametersWithInitializers.ts, 19, 12))
>T : Symbol(T, Decl(contextuallyTypedParametersWithInitializers.ts, 19, 12))
>input : Symbol(input, Decl(contextuallyTypedParametersWithInitializers.ts, 19, 15))
>id : Symbol(id, Decl(contextuallyTypedParametersWithInitializers.ts, 40, 16))
>T : Symbol(T, Decl(contextuallyTypedParametersWithInitializers.ts, 44, 12))
>input : Symbol(input, Decl(contextuallyTypedParametersWithInitializers.ts, 44, 15))
>T : Symbol(T, Decl(contextuallyTypedParametersWithInitializers.ts, 44, 12))
>T : Symbol(T, Decl(contextuallyTypedParametersWithInitializers.ts, 44, 12))
>input : Symbol(input, Decl(contextuallyTypedParametersWithInitializers.ts, 44, 15))
function getFoo ({ foo = 42 }) {
>getFoo : Symbol(getFoo, Decl(contextuallyTypedParametersWithInitializers.ts, 19, 44))
>foo : Symbol(foo, Decl(contextuallyTypedParametersWithInitializers.ts, 21, 18))
>getFoo : Symbol(getFoo, Decl(contextuallyTypedParametersWithInitializers.ts, 44, 44))
>foo : Symbol(foo, Decl(contextuallyTypedParametersWithInitializers.ts, 46, 18))
return foo;
>foo : Symbol(foo, Decl(contextuallyTypedParametersWithInitializers.ts, 21, 18))
>foo : Symbol(foo, Decl(contextuallyTypedParametersWithInitializers.ts, 46, 18))
}
const newGetFoo = id(getFoo);
>newGetFoo : Symbol(newGetFoo, Decl(contextuallyTypedParametersWithInitializers.ts, 25, 5))
>id : Symbol(id, Decl(contextuallyTypedParametersWithInitializers.ts, 15, 52))
>getFoo : Symbol(getFoo, Decl(contextuallyTypedParametersWithInitializers.ts, 19, 44))
>newGetFoo : Symbol(newGetFoo, Decl(contextuallyTypedParametersWithInitializers.ts, 50, 5))
>id : Symbol(id, Decl(contextuallyTypedParametersWithInitializers.ts, 40, 16))
>getFoo : Symbol(getFoo, Decl(contextuallyTypedParametersWithInitializers.ts, 44, 44))
const newGetFoo2 = id(function getFoo ({ foo = 42 }) {
>newGetFoo2 : Symbol(newGetFoo2, Decl(contextuallyTypedParametersWithInitializers.ts, 26, 5))
>id : Symbol(id, Decl(contextuallyTypedParametersWithInitializers.ts, 15, 52))
>getFoo : Symbol(getFoo, Decl(contextuallyTypedParametersWithInitializers.ts, 26, 22))
>foo : Symbol(foo, Decl(contextuallyTypedParametersWithInitializers.ts, 26, 40))
>newGetFoo2 : Symbol(newGetFoo2, Decl(contextuallyTypedParametersWithInitializers.ts, 51, 5))
>id : Symbol(id, Decl(contextuallyTypedParametersWithInitializers.ts, 40, 16))
>getFoo : Symbol(getFoo, Decl(contextuallyTypedParametersWithInitializers.ts, 51, 22))
>foo : Symbol(foo, Decl(contextuallyTypedParametersWithInitializers.ts, 51, 40))
return foo;
>foo : Symbol(foo, Decl(contextuallyTypedParametersWithInitializers.ts, 26, 40))
>foo : Symbol(foo, Decl(contextuallyTypedParametersWithInitializers.ts, 51, 40))
});
// Repro from comment in #30840
declare function memoize<F extends Function>(func: F): F;
>memoize : Symbol(memoize, Decl(contextuallyTypedParametersWithInitializers.ts, 53, 3))
>F : Symbol(F, Decl(contextuallyTypedParametersWithInitializers.ts, 57, 25))
>Function : Symbol(Function, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
>func : Symbol(func, Decl(contextuallyTypedParametersWithInitializers.ts, 57, 45))
>F : Symbol(F, Decl(contextuallyTypedParametersWithInitializers.ts, 57, 25))
>F : Symbol(F, Decl(contextuallyTypedParametersWithInitializers.ts, 57, 25))
function add(x: number, y = 0): number {
>add : Symbol(add, Decl(contextuallyTypedParametersWithInitializers.ts, 57, 57))
>x : Symbol(x, Decl(contextuallyTypedParametersWithInitializers.ts, 59, 13))
>y : Symbol(y, Decl(contextuallyTypedParametersWithInitializers.ts, 59, 23))
return x + y;
>x : Symbol(x, Decl(contextuallyTypedParametersWithInitializers.ts, 59, 13))
>y : Symbol(y, Decl(contextuallyTypedParametersWithInitializers.ts, 59, 23))
}
const memoizedAdd = memoize(add);
>memoizedAdd : Symbol(memoizedAdd, Decl(contextuallyTypedParametersWithInitializers.ts, 62, 5))
>memoize : Symbol(memoize, Decl(contextuallyTypedParametersWithInitializers.ts, 53, 3))
>add : Symbol(add, Decl(contextuallyTypedParametersWithInitializers.ts, 57, 57))
const add2 = (x: number, y = 0): number => x + y;
>add2 : Symbol(add2, Decl(contextuallyTypedParametersWithInitializers.ts, 64, 5))
>x : Symbol(x, Decl(contextuallyTypedParametersWithInitializers.ts, 64, 14))
>y : Symbol(y, Decl(contextuallyTypedParametersWithInitializers.ts, 64, 24))
>x : Symbol(x, Decl(contextuallyTypedParametersWithInitializers.ts, 64, 14))
>y : Symbol(y, Decl(contextuallyTypedParametersWithInitializers.ts, 64, 24))
const memoizedAdd2 = memoize(add2);
>memoizedAdd2 : Symbol(memoizedAdd2, Decl(contextuallyTypedParametersWithInitializers.ts, 65, 5))
>memoize : Symbol(memoize, Decl(contextuallyTypedParametersWithInitializers.ts, 53, 3))
>add2 : Symbol(add2, Decl(contextuallyTypedParametersWithInitializers.ts, 64, 5))
const memoizedAdd3 = memoize((x: number, y = 0): number => x + y);
>memoizedAdd3 : Symbol(memoizedAdd3, Decl(contextuallyTypedParametersWithInitializers.ts, 67, 5))
>memoize : Symbol(memoize, Decl(contextuallyTypedParametersWithInitializers.ts, 53, 3))
>x : Symbol(x, Decl(contextuallyTypedParametersWithInitializers.ts, 67, 30))
>y : Symbol(y, Decl(contextuallyTypedParametersWithInitializers.ts, 67, 40))
>x : Symbol(x, Decl(contextuallyTypedParametersWithInitializers.ts, 67, 30))
>y : Symbol(y, Decl(contextuallyTypedParametersWithInitializers.ts, 67, 40))
// Repro from #36052
declare function execute(script: string | Function): Promise<string>;
>execute : Symbol(execute, Decl(contextuallyTypedParametersWithInitializers.ts, 67, 66))
>script : Symbol(script, Decl(contextuallyTypedParametersWithInitializers.ts, 71, 25))
>Function : Symbol(Function, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --))
export function executeSomething() {
>executeSomething : Symbol(executeSomething, Decl(contextuallyTypedParametersWithInitializers.ts, 71, 69))
return execute((root: HTMLElement, debug = true) => {
>execute : Symbol(execute, Decl(contextuallyTypedParametersWithInitializers.ts, 67, 66))
>root : Symbol(root, Decl(contextuallyTypedParametersWithInitializers.ts, 74, 20))
>HTMLElement : Symbol(HTMLElement, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --))
>debug : Symbol(debug, Decl(contextuallyTypedParametersWithInitializers.ts, 74, 38))
if (debug) {
>debug : Symbol(debug, Decl(contextuallyTypedParametersWithInitializers.ts, 74, 38))
root.innerHTML = '';
>root.innerHTML : Symbol(InnerHTML.innerHTML, Decl(lib.dom.d.ts, --, --))
>root : Symbol(root, Decl(contextuallyTypedParametersWithInitializers.ts, 74, 20))
>innerHTML : Symbol(InnerHTML.innerHTML, Decl(lib.dom.d.ts, --, --))
}
});
}
const fz1 = (debug = true) => false;
>fz1 : Symbol(fz1, Decl(contextuallyTypedParametersWithInitializers.ts, 81, 5))
>debug : Symbol(debug, Decl(contextuallyTypedParametersWithInitializers.ts, 81, 13))
const fz2: Function = (debug = true) => false;
>fz2 : Symbol(fz2, Decl(contextuallyTypedParametersWithInitializers.ts, 82, 5))
>Function : Symbol(Function, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
>debug : Symbol(debug, Decl(contextuallyTypedParametersWithInitializers.ts, 82, 23))

View File

@ -32,14 +32,14 @@ const f10 = function ({ foo = 42 }) { return foo };
>42 : 42
>foo : number
const f11 = id1(function ({ foo = 42 }) { return foo }); // Implicit any error
>f11 : ({ foo }: any) => any
>id1(function ({ foo = 42 }) { return foo }) : ({ foo }: any) => any
const f11 = id1(function ({ foo = 42 }) { return foo });
>f11 : ({ foo }: { foo?: number | undefined; }) => number
>id1(function ({ foo = 42 }) { return foo }) : ({ foo }: { foo?: number | undefined; }) => number
>id1 : <T>(input: T) => T
>function ({ foo = 42 }) { return foo } : ({ foo }: any) => any
>foo : any
>function ({ foo = 42 }) { return foo } : ({ foo }: { foo?: number | undefined; }) => number
>foo : number
>42 : 42
>foo : any
>foo : number
const f12 = id2(function ({ foo = 42 }) { return foo });
>f12 : ({ foo }: any) => any
@ -75,14 +75,14 @@ const f20 = function (foo = 42) { return foo };
>42 : 42
>foo : number
const f21 = id1(function (foo = 42) { return foo }); // Implicit any error
>f21 : (foo?: any) => any
>id1(function (foo = 42) { return foo }) : (foo?: any) => any
const f21 = id1(function (foo = 42) { return foo });
>f21 : (foo?: number) => number
>id1(function (foo = 42) { return foo }) : (foo?: number) => number
>id1 : <T>(input: T) => T
>function (foo = 42) { return foo } : (foo?: any) => any
>foo : any
>function (foo = 42) { return foo } : (foo?: number) => number
>foo : number
>42 : 42
>foo : any
>foo : number
const f22 = id2(function (foo = 42) { return foo });
>f22 : (foo?: any) => any
@ -102,6 +102,148 @@ const f25 = id5(function (foo = 42) { return foo });
>42 : 42
>foo : number
const f1 = (x = 1) => 0; // number
>f1 : (x?: number) => number
>(x = 1) => 0 : (x?: number) => number
>x : number
>1 : 1
>0 : 0
const f2: any = (x = 1) => 0; // number
>f2 : any
>(x = 1) => 0 : (x?: number) => number
>x : number
>1 : 1
>0 : 0
const f3: unknown = (x = 1) => 0; // number
>f3 : unknown
>(x = 1) => 0 : (x?: number) => number
>x : number
>1 : 1
>0 : 0
const f4: Function = (x = 1) => 0; // number
>f4 : Function
>(x = 1) => 0 : (x?: number) => number
>x : number
>1 : 1
>0 : 0
const f5: (...args: any[]) => any = (x = 1) => 0; // any
>f5 : (...args: any[]) => any
>args : any[]
>(x = 1) => 0 : (x?: any) => number
>x : any
>1 : 1
>0 : 0
const f6: () => any = (x = 1) => 0; // number
>f6 : () => any
>(x = 1) => 0 : (x?: number) => number
>x : number
>1 : 1
>0 : 0
const f7: () => any = (x?) => 0; // Implicit any error
>f7 : () => any
>(x?) => 0 : (x?: any) => number
>x : any
>0 : 0
const f8: () => any = (...x) => 0; // []
>f8 : () => any
>(...x) => 0 : () => number
>x : []
>0 : 0
declare function g1<T>(x: T): T;
>g1 : <T>(x: T) => T
>x : T
declare function g2<T extends any>(x: T): T;
>g2 : <T extends any>(x: T) => T
>x : T
declare function g3<T extends unknown>(x: T): T;
>g3 : <T extends unknown>(x: T) => T
>x : T
declare function g4<T extends Function>(x: T): T;
>g4 : <T extends Function>(x: T) => T
>x : T
declare function g5<T extends (...args: any[]) => any>(x: T): T;
>g5 : <T extends (...args: any[]) => any>(x: T) => T
>args : any[]
>x : T
declare function g6<T extends () => any>(x: T): T;
>g6 : <T extends () => any>(x: T) => T
>x : T
g1((x = 1) => 0); // number
>g1((x = 1) => 0) : (x?: number) => 0
>g1 : <T>(x: T) => T
>(x = 1) => 0 : (x?: number) => 0
>x : number
>1 : 1
>0 : 0
g2((x = 1) => 0); // number
>g2((x = 1) => 0) : (x?: number) => 0
>g2 : <T extends any>(x: T) => T
>(x = 1) => 0 : (x?: number) => 0
>x : number
>1 : 1
>0 : 0
g3((x = 1) => 0); // number
>g3((x = 1) => 0) : (x?: number) => 0
>g3 : <T extends unknown>(x: T) => T
>(x = 1) => 0 : (x?: number) => 0
>x : number
>1 : 1
>0 : 0
g4((x = 1) => 0); // number
>g4((x = 1) => 0) : (x?: number) => 0
>g4 : <T extends Function>(x: T) => T
>(x = 1) => 0 : (x?: number) => 0
>x : number
>1 : 1
>0 : 0
g5((x = 1) => 0); // any
>g5((x = 1) => 0) : (x?: any) => number
>g5 : <T extends (...args: any[]) => any>(x: T) => T
>(x = 1) => 0 : (x?: any) => number
>x : any
>1 : 1
>0 : 0
g6((x = 1) => 0); // number
>g6((x = 1) => 0) : (x?: number) => number
>g6 : <T extends () => any>(x: T) => T
>(x = 1) => 0 : (x?: number) => number
>x : number
>1 : 1
>0 : 0
g6((x?) => 0); // Implicit any error
>g6((x?) => 0) : (x?: any) => number
>g6 : <T extends () => any>(x: T) => T
>(x?) => 0 : (x?: any) => number
>x : any
>0 : 0
g6((...x) => 0); // []
>g6((...x) => 0) : () => number
>g6 : <T extends () => any>(x: T) => T
>(...x) => 0 : () => number
>x : []
>0 : 0
// Repro from #28816
function id<T>(input: T): T { return input }
@ -125,16 +267,111 @@ const newGetFoo = id(getFoo);
>getFoo : ({ foo }: { foo?: number | undefined; }) => number
const newGetFoo2 = id(function getFoo ({ foo = 42 }) {
>newGetFoo2 : ({ foo }: any) => any
>id(function getFoo ({ foo = 42 }) { return foo;}) : ({ foo }: any) => any
>newGetFoo2 : ({ foo }: { foo?: number | undefined; }) => number
>id(function getFoo ({ foo = 42 }) { return foo;}) : ({ foo }: { foo?: number | undefined; }) => number
>id : <T>(input: T) => T
>function getFoo ({ foo = 42 }) { return foo;} : ({ foo }: any) => any
>getFoo : ({ foo }: any) => any
>foo : any
>function getFoo ({ foo = 42 }) { return foo;} : ({ foo }: { foo?: number | undefined; }) => number
>getFoo : ({ foo }: { foo?: number | undefined; }) => number
>foo : number
>42 : 42
return foo;
>foo : any
>foo : number
});
// Repro from comment in #30840
declare function memoize<F extends Function>(func: F): F;
>memoize : <F extends Function>(func: F) => F
>func : F
function add(x: number, y = 0): number {
>add : (x: number, y?: number) => number
>x : number
>y : number
>0 : 0
return x + y;
>x + y : number
>x : number
>y : number
}
const memoizedAdd = memoize(add);
>memoizedAdd : (x: number, y?: number) => number
>memoize(add) : (x: number, y?: number) => number
>memoize : <F extends Function>(func: F) => F
>add : (x: number, y?: number) => number
const add2 = (x: number, y = 0): number => x + y;
>add2 : (x: number, y?: number) => number
>(x: number, y = 0): number => x + y : (x: number, y?: number) => number
>x : number
>y : number
>0 : 0
>x + y : number
>x : number
>y : number
const memoizedAdd2 = memoize(add2);
>memoizedAdd2 : (x: number, y?: number) => number
>memoize(add2) : (x: number, y?: number) => number
>memoize : <F extends Function>(func: F) => F
>add2 : (x: number, y?: number) => number
const memoizedAdd3 = memoize((x: number, y = 0): number => x + y);
>memoizedAdd3 : (x: number, y?: number) => number
>memoize((x: number, y = 0): number => x + y) : (x: number, y?: number) => number
>memoize : <F extends Function>(func: F) => F
>(x: number, y = 0): number => x + y : (x: number, y?: number) => number
>x : number
>y : number
>0 : 0
>x + y : number
>x : number
>y : number
// Repro from #36052
declare function execute(script: string | Function): Promise<string>;
>execute : (script: string | Function) => Promise<string>
>script : string | Function
export function executeSomething() {
>executeSomething : () => Promise<string>
return execute((root: HTMLElement, debug = true) => {
>execute((root: HTMLElement, debug = true) => { if (debug) { root.innerHTML = ''; } }) : Promise<string>
>execute : (script: string | Function) => Promise<string>
>(root: HTMLElement, debug = true) => { if (debug) { root.innerHTML = ''; } } : (root: HTMLElement, debug?: boolean) => void
>root : HTMLElement
>debug : boolean
>true : true
if (debug) {
>debug : boolean
root.innerHTML = '';
>root.innerHTML = '' : ""
>root.innerHTML : string
>root : HTMLElement
>innerHTML : string
>'' : ""
}
});
}
const fz1 = (debug = true) => false;
>fz1 : (debug?: boolean) => boolean
>(debug = true) => false : (debug?: boolean) => boolean
>debug : boolean
>true : true
>false : false
const fz2: Function = (debug = true) => false;
>fz2 : Function
>(debug = true) => false : (debug?: boolean) => boolean
>debug : boolean
>true : true
>false : false

View File

@ -18,7 +18,6 @@ trans(([b,c]) => 'foo');
trans(({d: [e,f]}) => 'foo');
>trans : Symbol(trans, Decl(fallbackToBindingPatternForTypeInference.ts, 0, 0))
>d : Symbol(d)
>e : Symbol(e, Decl(fallbackToBindingPatternForTypeInference.ts, 3, 12))
>f : Symbol(f, Decl(fallbackToBindingPatternForTypeInference.ts, 3, 14))

View File

@ -25,10 +25,10 @@ foo((x?)=>{return x;})
foo((x=0)=>{return x;})
>foo((x=0)=>{return x;}) : any
>foo : any
>(x=0)=>{return x;} : (x?: any) => any
>x : any
>(x=0)=>{return x;} : (x?: number) => number
>x : number
>0 : 0
>x : any
>x : number
var y = x:number => x*x;
>y : any

View File

@ -653,8 +653,8 @@ foo(
>116 : 116
(a = 0) => 117,
>(a = 0) => 117 : (a?: any) => number
>a : any
>(a = 0) => 117 : (a?: number) => number
>a : number
>0 : 0
>117 : 117
@ -670,9 +670,9 @@ foo(
>119 : 119
(a, b? = 0, ...c: number[]) => 120,
>(a, b? = 0, ...c: number[]) => 120 : (a: any, b?: any, ...c: number[]) => number
>(a, b? = 0, ...c: number[]) => 120 : (a: any, b?: number, ...c: number[]) => number
>a : any
>b : any
>b : number
>0 : 0
>c : number[]
>120 : 120

View File

@ -88,8 +88,8 @@
>116 : 116
(a = 0) => 117,
>(a = 0) => 117 : (a?: any) => number
>a : any
>(a = 0) => 117 : (a?: number) => number
>a : number
>0 : 0
>117 : 117
@ -105,9 +105,9 @@
>119 : 119
(a, b? = 0, ...c: number[]) => 120,
>(a, b? = 0, ...c: number[]) => 120 : (a: any, b?: any, ...c: number[]) => number
>(a, b? = 0, ...c: number[]) => 120 : (a: any, b?: number, ...c: number[]) => number
>a : any
>b : any
>b : number
>0 : 0
>c : number[]
>120 : 120

View File

@ -8,16 +8,41 @@ declare function id4<T extends (x: { foo?: number }) => any>(input: T): T;
declare function id5<T extends (x?: number) => any>(input: T): T;
const f10 = function ({ foo = 42 }) { return foo };
const f11 = id1(function ({ foo = 42 }) { return foo }); // Implicit any error
const f11 = id1(function ({ foo = 42 }) { return foo });
const f12 = id2(function ({ foo = 42 }) { return foo });
const f13 = id3(function ({ foo = 42 }) { return foo });
const f14 = id4(function ({ foo = 42 }) { return foo });
const f20 = function (foo = 42) { return foo };
const f21 = id1(function (foo = 42) { return foo }); // Implicit any error
const f21 = id1(function (foo = 42) { return foo });
const f22 = id2(function (foo = 42) { return foo });
const f25 = id5(function (foo = 42) { return foo });
const f1 = (x = 1) => 0; // number
const f2: any = (x = 1) => 0; // number
const f3: unknown = (x = 1) => 0; // number
const f4: Function = (x = 1) => 0; // number
const f5: (...args: any[]) => any = (x = 1) => 0; // any
const f6: () => any = (x = 1) => 0; // number
const f7: () => any = (x?) => 0; // Implicit any error
const f8: () => any = (...x) => 0; // []
declare function g1<T>(x: T): T;
declare function g2<T extends any>(x: T): T;
declare function g3<T extends unknown>(x: T): T;
declare function g4<T extends Function>(x: T): T;
declare function g5<T extends (...args: any[]) => any>(x: T): T;
declare function g6<T extends () => any>(x: T): T;
g1((x = 1) => 0); // number
g2((x = 1) => 0); // number
g3((x = 1) => 0); // number
g4((x = 1) => 0); // number
g5((x = 1) => 0); // any
g6((x = 1) => 0); // number
g6((x?) => 0); // Implicit any error
g6((...x) => 0); // []
// Repro from #28816
function id<T>(input: T): T { return input }
@ -30,3 +55,32 @@ const newGetFoo = id(getFoo);
const newGetFoo2 = id(function getFoo ({ foo = 42 }) {
return foo;
});
// Repro from comment in #30840
declare function memoize<F extends Function>(func: F): F;
function add(x: number, y = 0): number {
return x + y;
}
const memoizedAdd = memoize(add);
const add2 = (x: number, y = 0): number => x + y;
const memoizedAdd2 = memoize(add2);
const memoizedAdd3 = memoize((x: number, y = 0): number => x + y);
// Repro from #36052
declare function execute(script: string | Function): Promise<string>;
export function executeSomething() {
return execute((root: HTMLElement, debug = true) => {
if (debug) {
root.innerHTML = '';
}
});
}
const fz1 = (debug = true) => false;
const fz2: Function = (debug = true) => false;

View File

@ -0,0 +1,40 @@
/// <reference path='fourslash.ts' />
////declare function foo1<T>(obj: T, settings: (row: T) => { value: string, func?: Function }): void;
////
////foo1(new Error(),
//// o/*1*/ => ({
//// value: o.name,
//// func: x => 'foo'
//// })
////);
////
////declare function foo2<T>(settings: (row: T) => { value: string, func?: Function }, obj: T): void;
////
////foo2(o/*2*/ => ({
//// value: o.name,
//// func: x => 'foo'
//// }),
//// new Error(),
////);
////
////declare function foof<T extends { name: string }, U extends keyof T>(settings: (row: T) => { value: T[U], func?: Function }, obj: T, key: U): U;
////
////function q<T extends { name: string }>(x: T): T["name"] {
//// return foof/*3*/(o => ({ value: o.name, func: x => 'foo' }), x, "name");
////}
////
////foof/*4*/(o => ({ value: o.name, func: x => 'foo' }), new Error(), "name");
verify.quickInfos({
1: "(parameter) o: Error",
2: "(parameter) o: Error",
3: `function foof<T, "name">(settings: (row: T) => {
value: T["name"];
func?: Function;
}, obj: T, key: "name"): "name"`,
4: `function foof<Error, "name">(settings: (row: Error) => {
value: string;
func?: Function;
}, obj: Error, key: "name"): "name"`
});