Merge pull request #29576 from Microsoft/fixContextuallyTypedParameters
Fix inference for contextually typed parameters with initializers
This commit is contained in:
commit
eb513a2035
9 changed files with 489 additions and 30 deletions
|
@ -4866,17 +4866,8 @@ namespace ts {
|
|||
function getTypeForBindingElement(declaration: BindingElement): Type | undefined {
|
||||
const pattern = declaration.parent;
|
||||
let parentType = getTypeForBindingElementParent(pattern.parent);
|
||||
// If parent has the unknown (error) type, then so does this binding element
|
||||
if (parentType === errorType) {
|
||||
return errorType;
|
||||
}
|
||||
// If no type was specified or inferred for parent,
|
||||
// infer from the initializer of the binding element if one is present.
|
||||
// Otherwise, go with the undefined type of the parent.
|
||||
if (!parentType) {
|
||||
return declaration.initializer ? checkDeclarationInitializer(declaration) : parentType;
|
||||
}
|
||||
if (isTypeAny(parentType)) {
|
||||
// If no type or an any type was inferred for parent, infer that for the binding element
|
||||
if (!parentType || isTypeAny(parentType)) {
|
||||
return parentType;
|
||||
}
|
||||
// Relax null check on ambient destructuring parameters, since the parameters have no implementation and are just documentation
|
||||
|
@ -4962,6 +4953,12 @@ 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
|
||||
|
@ -5045,8 +5042,9 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
|
||||
// Use the type of the initializer expression if one is present
|
||||
if (declaration.initializer) {
|
||||
// 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)) {
|
||||
const type = checkDeclarationInitializer(declaration);
|
||||
return addOptionality(type, isOptional);
|
||||
}
|
||||
|
@ -5057,8 +5055,9 @@ namespace ts {
|
|||
return trueType;
|
||||
}
|
||||
|
||||
// If the declaration specifies a binding pattern, use the type implied by the binding pattern
|
||||
if (isBindingPattern(declaration.name)) {
|
||||
// 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)) {
|
||||
return getTypeFromBindingPattern(declaration.name, /*includePatternInType*/ false, /*reportErrors*/ true);
|
||||
}
|
||||
|
||||
|
@ -5695,17 +5694,21 @@ namespace ts {
|
|||
}
|
||||
|
||||
function reportCircularityError(symbol: Symbol) {
|
||||
const declaration = <VariableLikeDeclaration>symbol.valueDeclaration;
|
||||
// Check if variable has type annotation that circularly references the variable itself
|
||||
if (getEffectiveTypeAnnotationNode(<VariableLikeDeclaration>symbol.valueDeclaration)) {
|
||||
if (getEffectiveTypeAnnotationNode(declaration)) {
|
||||
error(symbol.valueDeclaration, Diagnostics._0_is_referenced_directly_or_indirectly_in_its_own_type_annotation,
|
||||
symbolToString(symbol));
|
||||
return errorType;
|
||||
}
|
||||
// Otherwise variable has initializer that circularly references the variable itself
|
||||
if (noImplicitAny) {
|
||||
// Check if variable has initializer that circularly references the variable itself
|
||||
if (noImplicitAny && (declaration.kind !== SyntaxKind.Parameter || (<HasInitializer>declaration).initializer)) {
|
||||
error(symbol.valueDeclaration, Diagnostics._0_implicitly_has_type_any_because_it_does_not_have_a_type_annotation_and_is_referenced_directly_or_indirectly_in_its_own_initializer,
|
||||
symbolToString(symbol));
|
||||
}
|
||||
// Circularities could also result from parameters in function expressions that end up
|
||||
// having themselves as contextual types following type argument inference. In those cases
|
||||
// we have already reported an implicit any error so we don't report anything here.
|
||||
return anyType;
|
||||
}
|
||||
|
||||
|
@ -25680,7 +25683,7 @@ namespace ts {
|
|||
const parent = node.parent.parent;
|
||||
const parentType = getTypeForBindingElementParent(parent);
|
||||
const name = node.propertyName || node.name;
|
||||
if (!isBindingPattern(name) && parentType) {
|
||||
if (parentType && !isBindingPattern(name)) {
|
||||
const exprType = getLiteralTypeFromPropertyName(name);
|
||||
if (isTypeUsableAsPropertyName(exprType)) {
|
||||
const nameText = getPropertyNameFromType(exprType);
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
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 (3 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;
|
||||
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
|
||||
~~~
|
||||
!!! error TS7031: Binding element 'foo' implicitly has an 'any' type.
|
||||
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 f22 = id2(function (foo = 42) { return foo });
|
||||
const f25 = id5(function (foo = 42) { return foo });
|
||||
|
||||
// Repro from #28816
|
||||
|
||||
function id<T>(input: T): T { return input }
|
||||
|
||||
function getFoo ({ foo = 42 }) {
|
||||
return foo;
|
||||
}
|
||||
|
||||
const newGetFoo = id(getFoo);
|
||||
const newGetFoo2 = id(function getFoo ({ foo = 42 }) {
|
||||
~~~
|
||||
!!! error TS7031: Binding element 'foo' implicitly has an 'any' type.
|
||||
return foo;
|
||||
});
|
||||
|
|
@ -0,0 +1,114 @@
|
|||
//// [contextuallyTypedParametersWithInitializers.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;
|
||||
|
||||
const f10 = function ({ foo = 42 }) { return foo };
|
||||
const f11 = id1(function ({ foo = 42 }) { return foo }); // Implicit any error
|
||||
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 f22 = id2(function (foo = 42) { return foo });
|
||||
const f25 = id5(function (foo = 42) { return foo });
|
||||
|
||||
// Repro from #28816
|
||||
|
||||
function id<T>(input: T): T { return input }
|
||||
|
||||
function getFoo ({ foo = 42 }) {
|
||||
return foo;
|
||||
}
|
||||
|
||||
const newGetFoo = id(getFoo);
|
||||
const newGetFoo2 = id(function getFoo ({ foo = 42 }) {
|
||||
return foo;
|
||||
});
|
||||
|
||||
|
||||
//// [contextuallyTypedParametersWithInitializers.js]
|
||||
"use strict";
|
||||
var f10 = function (_a) {
|
||||
var _b = _a.foo, foo = _b === void 0 ? 42 : _b;
|
||||
return foo;
|
||||
};
|
||||
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;
|
||||
});
|
||||
var f13 = id3(function (_a) {
|
||||
var _b = _a.foo, foo = _b === void 0 ? 42 : _b;
|
||||
return foo;
|
||||
});
|
||||
var f14 = id4(function (_a) {
|
||||
var _b = _a.foo, foo = _b === void 0 ? 42 : _b;
|
||||
return foo;
|
||||
});
|
||||
var f20 = function (foo) {
|
||||
if (foo === void 0) { foo = 42; }
|
||||
return 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;
|
||||
});
|
||||
var f25 = id5(function (foo) {
|
||||
if (foo === void 0) { foo = 42; }
|
||||
return foo;
|
||||
});
|
||||
// Repro from #28816
|
||||
function id(input) { return input; }
|
||||
function getFoo(_a) {
|
||||
var _b = _a.foo, foo = _b === void 0 ? 42 : _b;
|
||||
return foo;
|
||||
}
|
||||
var newGetFoo = id(getFoo);
|
||||
var newGetFoo2 = id(function getFoo(_a) {
|
||||
var _b = _a.foo, foo = _b === void 0 ? 42 : _b;
|
||||
return foo;
|
||||
});
|
||||
|
||||
|
||||
//// [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;
|
|
@ -0,0 +1,128 @@
|
|||
=== tests/cases/compiler/contextuallyTypedParametersWithInitializers.ts ===
|
||||
declare function id1<T>(input: T): T;
|
||||
>id1 : Symbol(id1, Decl(contextuallyTypedParametersWithInitializers.ts, 0, 0))
|
||||
>T : Symbol(T, Decl(contextuallyTypedParametersWithInitializers.ts, 0, 21))
|
||||
>input : Symbol(input, Decl(contextuallyTypedParametersWithInitializers.ts, 0, 24))
|
||||
>T : Symbol(T, Decl(contextuallyTypedParametersWithInitializers.ts, 0, 21))
|
||||
>T : Symbol(T, Decl(contextuallyTypedParametersWithInitializers.ts, 0, 21))
|
||||
|
||||
declare function id2<T extends (x: any) => any>(input: T): T;
|
||||
>id2 : Symbol(id2, Decl(contextuallyTypedParametersWithInitializers.ts, 0, 37))
|
||||
>T : Symbol(T, Decl(contextuallyTypedParametersWithInitializers.ts, 1, 21))
|
||||
>x : Symbol(x, Decl(contextuallyTypedParametersWithInitializers.ts, 1, 32))
|
||||
>input : Symbol(input, Decl(contextuallyTypedParametersWithInitializers.ts, 1, 48))
|
||||
>T : Symbol(T, Decl(contextuallyTypedParametersWithInitializers.ts, 1, 21))
|
||||
>T : Symbol(T, Decl(contextuallyTypedParametersWithInitializers.ts, 1, 21))
|
||||
|
||||
declare function id3<T extends (x: { foo: any }) => any>(input: T): T;
|
||||
>id3 : Symbol(id3, Decl(contextuallyTypedParametersWithInitializers.ts, 1, 61))
|
||||
>T : Symbol(T, Decl(contextuallyTypedParametersWithInitializers.ts, 2, 21))
|
||||
>x : Symbol(x, Decl(contextuallyTypedParametersWithInitializers.ts, 2, 32))
|
||||
>foo : Symbol(foo, Decl(contextuallyTypedParametersWithInitializers.ts, 2, 36))
|
||||
>input : Symbol(input, Decl(contextuallyTypedParametersWithInitializers.ts, 2, 57))
|
||||
>T : Symbol(T, Decl(contextuallyTypedParametersWithInitializers.ts, 2, 21))
|
||||
>T : Symbol(T, Decl(contextuallyTypedParametersWithInitializers.ts, 2, 21))
|
||||
|
||||
declare function id4<T extends (x: { foo?: number }) => any>(input: T): T;
|
||||
>id4 : Symbol(id4, Decl(contextuallyTypedParametersWithInitializers.ts, 2, 70))
|
||||
>T : Symbol(T, Decl(contextuallyTypedParametersWithInitializers.ts, 3, 21))
|
||||
>x : Symbol(x, Decl(contextuallyTypedParametersWithInitializers.ts, 3, 32))
|
||||
>foo : Symbol(foo, Decl(contextuallyTypedParametersWithInitializers.ts, 3, 36))
|
||||
>input : Symbol(input, Decl(contextuallyTypedParametersWithInitializers.ts, 3, 61))
|
||||
>T : Symbol(T, Decl(contextuallyTypedParametersWithInitializers.ts, 3, 21))
|
||||
>T : Symbol(T, Decl(contextuallyTypedParametersWithInitializers.ts, 3, 21))
|
||||
|
||||
declare function id5<T extends (x?: number) => any>(input: T): T;
|
||||
>id5 : Symbol(id5, Decl(contextuallyTypedParametersWithInitializers.ts, 3, 74))
|
||||
>T : Symbol(T, Decl(contextuallyTypedParametersWithInitializers.ts, 4, 21))
|
||||
>x : Symbol(x, Decl(contextuallyTypedParametersWithInitializers.ts, 4, 32))
|
||||
>input : Symbol(input, Decl(contextuallyTypedParametersWithInitializers.ts, 4, 52))
|
||||
>T : Symbol(T, Decl(contextuallyTypedParametersWithInitializers.ts, 4, 21))
|
||||
>T : Symbol(T, Decl(contextuallyTypedParametersWithInitializers.ts, 4, 21))
|
||||
|
||||
const f10 = function ({ foo = 42 }) { return foo };
|
||||
>f10 : Symbol(f10, Decl(contextuallyTypedParametersWithInitializers.ts, 6, 5))
|
||||
>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
|
||||
>f11 : Symbol(f11, Decl(contextuallyTypedParametersWithInitializers.ts, 7, 5))
|
||||
>id1 : Symbol(id1, Decl(contextuallyTypedParametersWithInitializers.ts, 0, 0))
|
||||
>foo : Symbol(foo, Decl(contextuallyTypedParametersWithInitializers.ts, 7, 27))
|
||||
>foo : Symbol(foo, Decl(contextuallyTypedParametersWithInitializers.ts, 7, 27))
|
||||
|
||||
const f12 = id2(function ({ foo = 42 }) { return foo });
|
||||
>f12 : Symbol(f12, Decl(contextuallyTypedParametersWithInitializers.ts, 8, 5))
|
||||
>id2 : Symbol(id2, Decl(contextuallyTypedParametersWithInitializers.ts, 0, 37))
|
||||
>foo : Symbol(foo, Decl(contextuallyTypedParametersWithInitializers.ts, 8, 27))
|
||||
>foo : Symbol(foo, Decl(contextuallyTypedParametersWithInitializers.ts, 8, 27))
|
||||
|
||||
const f13 = id3(function ({ foo = 42 }) { return foo });
|
||||
>f13 : Symbol(f13, Decl(contextuallyTypedParametersWithInitializers.ts, 9, 5))
|
||||
>id3 : Symbol(id3, Decl(contextuallyTypedParametersWithInitializers.ts, 1, 61))
|
||||
>foo : Symbol(foo, Decl(contextuallyTypedParametersWithInitializers.ts, 9, 27))
|
||||
>foo : Symbol(foo, Decl(contextuallyTypedParametersWithInitializers.ts, 9, 27))
|
||||
|
||||
const f14 = id4(function ({ foo = 42 }) { return foo });
|
||||
>f14 : Symbol(f14, Decl(contextuallyTypedParametersWithInitializers.ts, 10, 5))
|
||||
>id4 : Symbol(id4, Decl(contextuallyTypedParametersWithInitializers.ts, 2, 70))
|
||||
>foo : Symbol(foo, Decl(contextuallyTypedParametersWithInitializers.ts, 10, 27))
|
||||
>foo : Symbol(foo, Decl(contextuallyTypedParametersWithInitializers.ts, 10, 27))
|
||||
|
||||
const f20 = function (foo = 42) { return foo };
|
||||
>f20 : Symbol(f20, Decl(contextuallyTypedParametersWithInitializers.ts, 12, 5))
|
||||
>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
|
||||
>f21 : Symbol(f21, Decl(contextuallyTypedParametersWithInitializers.ts, 13, 5))
|
||||
>id1 : Symbol(id1, Decl(contextuallyTypedParametersWithInitializers.ts, 0, 0))
|
||||
>foo : Symbol(foo, Decl(contextuallyTypedParametersWithInitializers.ts, 13, 26))
|
||||
>foo : Symbol(foo, Decl(contextuallyTypedParametersWithInitializers.ts, 13, 26))
|
||||
|
||||
const f22 = id2(function (foo = 42) { return foo });
|
||||
>f22 : Symbol(f22, Decl(contextuallyTypedParametersWithInitializers.ts, 14, 5))
|
||||
>id2 : Symbol(id2, Decl(contextuallyTypedParametersWithInitializers.ts, 0, 37))
|
||||
>foo : Symbol(foo, Decl(contextuallyTypedParametersWithInitializers.ts, 14, 26))
|
||||
>foo : Symbol(foo, Decl(contextuallyTypedParametersWithInitializers.ts, 14, 26))
|
||||
|
||||
const f25 = id5(function (foo = 42) { return foo });
|
||||
>f25 : Symbol(f25, Decl(contextuallyTypedParametersWithInitializers.ts, 15, 5))
|
||||
>id5 : Symbol(id5, Decl(contextuallyTypedParametersWithInitializers.ts, 3, 74))
|
||||
>foo : Symbol(foo, Decl(contextuallyTypedParametersWithInitializers.ts, 15, 26))
|
||||
>foo : Symbol(foo, Decl(contextuallyTypedParametersWithInitializers.ts, 15, 26))
|
||||
|
||||
// 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))
|
||||
|
||||
function getFoo ({ foo = 42 }) {
|
||||
>getFoo : Symbol(getFoo, Decl(contextuallyTypedParametersWithInitializers.ts, 19, 44))
|
||||
>foo : Symbol(foo, Decl(contextuallyTypedParametersWithInitializers.ts, 21, 18))
|
||||
|
||||
return foo;
|
||||
>foo : Symbol(foo, Decl(contextuallyTypedParametersWithInitializers.ts, 21, 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))
|
||||
|
||||
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))
|
||||
|
||||
return foo;
|
||||
>foo : Symbol(foo, Decl(contextuallyTypedParametersWithInitializers.ts, 26, 40))
|
||||
|
||||
});
|
||||
|
|
@ -0,0 +1,140 @@
|
|||
=== tests/cases/compiler/contextuallyTypedParametersWithInitializers.ts ===
|
||||
declare function id1<T>(input: T): T;
|
||||
>id1 : <T>(input: T) => T
|
||||
>input : T
|
||||
|
||||
declare function id2<T extends (x: any) => any>(input: T): T;
|
||||
>id2 : <T extends (x: any) => any>(input: T) => T
|
||||
>x : any
|
||||
>input : T
|
||||
|
||||
declare function id3<T extends (x: { foo: any }) => any>(input: T): T;
|
||||
>id3 : <T extends (x: { foo: any; }) => any>(input: T) => T
|
||||
>x : { foo: any; }
|
||||
>foo : any
|
||||
>input : T
|
||||
|
||||
declare function id4<T extends (x: { foo?: number }) => any>(input: T): T;
|
||||
>id4 : <T extends (x: { foo?: number | undefined; }) => any>(input: T) => T
|
||||
>x : { foo?: number | undefined; }
|
||||
>foo : number | undefined
|
||||
>input : T
|
||||
|
||||
declare function id5<T extends (x?: number) => any>(input: T): T;
|
||||
>id5 : <T extends (x?: number | undefined) => any>(input: T) => T
|
||||
>x : number | undefined
|
||||
>input : T
|
||||
|
||||
const f10 = function ({ foo = 42 }) { return foo };
|
||||
>f10 : ({ foo }: { foo?: number | undefined; }) => number
|
||||
>function ({ foo = 42 }) { return foo } : ({ foo }: { foo?: number | undefined; }) => number
|
||||
>foo : number
|
||||
>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
|
||||
>id1 : <T>(input: T) => T
|
||||
>function ({ foo = 42 }) { return foo } : ({ foo }: any) => any
|
||||
>foo : any
|
||||
>42 : 42
|
||||
>foo : any
|
||||
|
||||
const f12 = id2(function ({ foo = 42 }) { return foo });
|
||||
>f12 : ({ foo }: any) => any
|
||||
>id2(function ({ foo = 42 }) { return foo }) : ({ foo }: any) => any
|
||||
>id2 : <T extends (x: any) => any>(input: T) => T
|
||||
>function ({ foo = 42 }) { return foo } : ({ foo }: any) => any
|
||||
>foo : any
|
||||
>42 : 42
|
||||
>foo : any
|
||||
|
||||
const f13 = id3(function ({ foo = 42 }) { return foo });
|
||||
>f13 : ({ foo }: { foo: any; }) => any
|
||||
>id3(function ({ foo = 42 }) { return foo }) : ({ foo }: { foo: any; }) => any
|
||||
>id3 : <T extends (x: { foo: any; }) => any>(input: T) => T
|
||||
>function ({ foo = 42 }) { return foo } : ({ foo }: { foo: any; }) => any
|
||||
>foo : any
|
||||
>42 : 42
|
||||
>foo : any
|
||||
|
||||
const f14 = id4(function ({ foo = 42 }) { return foo });
|
||||
>f14 : ({ foo }: { foo?: number | undefined; }) => number
|
||||
>id4(function ({ foo = 42 }) { return foo }) : ({ foo }: { foo?: number | undefined; }) => number
|
||||
>id4 : <T extends (x: { foo?: number | undefined; }) => any>(input: T) => T
|
||||
>function ({ foo = 42 }) { return foo } : ({ foo }: { foo?: number | undefined; }) => number
|
||||
>foo : number
|
||||
>42 : 42
|
||||
>foo : number
|
||||
|
||||
const f20 = function (foo = 42) { return foo };
|
||||
>f20 : (foo?: number) => number
|
||||
>function (foo = 42) { return foo } : (foo?: number) => number
|
||||
>foo : number
|
||||
>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
|
||||
>id1 : <T>(input: T) => T
|
||||
>function (foo = 42) { return foo } : (foo?: any) => any
|
||||
>foo : any
|
||||
>42 : 42
|
||||
>foo : any
|
||||
|
||||
const f22 = id2(function (foo = 42) { return foo });
|
||||
>f22 : (foo?: any) => any
|
||||
>id2(function (foo = 42) { return foo }) : (foo?: any) => any
|
||||
>id2 : <T extends (x: any) => any>(input: T) => T
|
||||
>function (foo = 42) { return foo } : (foo?: any) => any
|
||||
>foo : any
|
||||
>42 : 42
|
||||
>foo : any
|
||||
|
||||
const f25 = id5(function (foo = 42) { return foo });
|
||||
>f25 : (foo?: number | undefined) => number
|
||||
>id5(function (foo = 42) { return foo }) : (foo?: number | undefined) => number
|
||||
>id5 : <T extends (x?: number | undefined) => any>(input: T) => T
|
||||
>function (foo = 42) { return foo } : (foo?: number | undefined) => number
|
||||
>foo : number | undefined
|
||||
>42 : 42
|
||||
>foo : number
|
||||
|
||||
// Repro from #28816
|
||||
|
||||
function id<T>(input: T): T { return input }
|
||||
>id : <T>(input: T) => T
|
||||
>input : T
|
||||
>input : T
|
||||
|
||||
function getFoo ({ foo = 42 }) {
|
||||
>getFoo : ({ foo }: { foo?: number | undefined; }) => number
|
||||
>foo : number
|
||||
>42 : 42
|
||||
|
||||
return foo;
|
||||
>foo : number
|
||||
}
|
||||
|
||||
const newGetFoo = id(getFoo);
|
||||
>newGetFoo : ({ foo }: { foo?: number | undefined; }) => number
|
||||
>id(getFoo) : ({ foo }: { foo?: number | undefined; }) => number
|
||||
>id : <T>(input: T) => T
|
||||
>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
|
||||
>id : <T>(input: T) => T
|
||||
>function getFoo ({ foo = 42 }) { return foo;} : ({ foo }: any) => any
|
||||
>getFoo : ({ foo }: any) => any
|
||||
>foo : any
|
||||
>42 : 42
|
||||
|
||||
return foo;
|
||||
>foo : any
|
||||
|
||||
});
|
||||
|
|
@ -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?: number) => number
|
||||
>x : number
|
||||
>(x=0)=>{return x;} : (x?: any) => any
|
||||
>x : any
|
||||
>0 : 0
|
||||
>x : number
|
||||
>x : any
|
||||
|
||||
var y = x:number => x*x;
|
||||
>y : any
|
||||
|
|
|
@ -653,8 +653,8 @@ foo(
|
|||
>116 : 116
|
||||
|
||||
(a = 0) => 117,
|
||||
>(a = 0) => 117 : (a?: number) => number
|
||||
>a : number
|
||||
>(a = 0) => 117 : (a?: any) => number
|
||||
>a : any
|
||||
>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?: number, ...c: number[]) => number
|
||||
>(a, b? = 0, ...c: number[]) => 120 : (a: any, b?: any, ...c: number[]) => number
|
||||
>a : any
|
||||
>b : number
|
||||
>b : any
|
||||
>0 : 0
|
||||
>c : number[]
|
||||
>120 : 120
|
||||
|
|
|
@ -88,8 +88,8 @@
|
|||
>116 : 116
|
||||
|
||||
(a = 0) => 117,
|
||||
>(a = 0) => 117 : (a?: number) => number
|
||||
>a : number
|
||||
>(a = 0) => 117 : (a?: any) => number
|
||||
>a : any
|
||||
>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?: number, ...c: number[]) => number
|
||||
>(a, b? = 0, ...c: number[]) => 120 : (a: any, b?: any, ...c: number[]) => number
|
||||
>a : any
|
||||
>b : number
|
||||
>b : any
|
||||
>0 : 0
|
||||
>c : number[]
|
||||
>120 : 120
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
// @strict: true
|
||||
// @declaration: true
|
||||
|
||||
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;
|
||||
|
||||
const f10 = function ({ foo = 42 }) { return foo };
|
||||
const f11 = id1(function ({ foo = 42 }) { return foo }); // Implicit any error
|
||||
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 f22 = id2(function (foo = 42) { return foo });
|
||||
const f25 = id5(function (foo = 42) { return foo });
|
||||
|
||||
// Repro from #28816
|
||||
|
||||
function id<T>(input: T): T { return input }
|
||||
|
||||
function getFoo ({ foo = 42 }) {
|
||||
return foo;
|
||||
}
|
||||
|
||||
const newGetFoo = id(getFoo);
|
||||
const newGetFoo2 = id(function getFoo ({ foo = 42 }) {
|
||||
return foo;
|
||||
});
|
Loading…
Reference in a new issue