diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index dfd479127202c..f2a6da6d4ab5e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -38546,21 +38546,24 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return signature.parameters.length > 0 ? getTypeAtPosition(signature, 0) : fallbackType; } - function inferFromAnnotatedParametersAndReturn(signature: Signature, context: Signature, inferenceContext: InferenceContext) { - const len = signature.parameters.length - (signatureHasRestParameter(signature) ? 1 : 0); - for (let i = 0; i < len; i++) { - const declaration = signature.parameters[i].valueDeclaration as ParameterDeclaration; - const typeNode = getEffectiveTypeAnnotationNode(declaration); - if (typeNode) { - const source = addOptionality(getTypeFromTypeNode(typeNode), /*isProperty*/ false, isOptionalDeclaration(declaration)); - const target = getTypeAtPosition(context, i); - inferTypes(inferenceContext.inferences, source, target); + function inferFromAnnotatedParametersAndReturn(node: FunctionExpression | ArrowFunction | MethodDeclaration, contextualSignature: Signature, inferenceContext: InferenceContext) { + if (node.parameters.length) { + const len = node.parameters.length - (last(node.parameters).dotDotDotToken ? 1 : 0); + const thisParameterOffset = first(node.parameters).symbol.escapedName === InternalSymbolName.This ? 1 : 0; + for (let i = thisParameterOffset; i < len; i++) { + const declaration = node.parameters[i]; + const typeNode = getEffectiveTypeAnnotationNode(declaration); + if (typeNode) { + const source = addOptionality(getTypeFromTypeNode(typeNode), /*isProperty*/ false, isOptionalDeclaration(declaration)); + const target = getTypeAtPosition(contextualSignature, i - thisParameterOffset); + inferTypes(inferenceContext.inferences, source, target); + } } } - const typeNode = signature.declaration && getEffectiveReturnTypeNode(signature.declaration); - if (typeNode) { - const source = getTypeFromTypeNode(typeNode); - const target = getReturnTypeOfSignature(context); + const returnTypeNode = node.type; + if (returnTypeNode) { + const source = getTypeFromTypeNode(returnTypeNode); + const target = getReturnTypeOfSignature(contextualSignature); inferTypes(inferenceContext.inferences, source, target); } } @@ -39536,6 +39539,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return links.contextFreeType = returnOnlyType; } } + if (checkMode & CheckMode.Inferential) { + const contextualSignature = getContextualSignature(node); + if (contextualSignature) { + inferFromAnnotatedParametersAndReturn(node, contextualSignature, getInferenceContext(node)!); + } + } return anyFunctionType; } @@ -39569,7 +39578,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const inferenceContext = getInferenceContext(node); let instantiatedContextualSignature: Signature | undefined; if (checkMode && checkMode & CheckMode.Inferential) { - inferFromAnnotatedParametersAndReturn(signature, contextualSignature, inferenceContext!); + inferFromAnnotatedParametersAndReturn(node, contextualSignature, inferenceContext!); const restType = getEffectiveRestType(contextualSignature); if (restType && restType.flags & TypeFlags.TypeParameter) { instantiatedContextualSignature = instantiateSignature(contextualSignature, inferenceContext!.nonFixingMapper); @@ -39587,7 +39596,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { else if (contextualSignature && !node.typeParameters && contextualSignature.parameters.length > node.parameters.length) { const inferenceContext = getInferenceContext(node); if (checkMode && checkMode & CheckMode.Inferential) { - inferFromAnnotatedParametersAndReturn(signature, contextualSignature, inferenceContext!); + inferFromAnnotatedParametersAndReturn(node, contextualSignature, inferenceContext!); } } if (contextualSignature && !getReturnTypeFromAnnotation(node) && !signature.resolvedReturnType) { diff --git a/tests/baselines/reference/contextSensitiveAnnotatedParametersInference1.symbols b/tests/baselines/reference/contextSensitiveAnnotatedParametersInference1.symbols new file mode 100644 index 0000000000000..7c47e93f14e12 --- /dev/null +++ b/tests/baselines/reference/contextSensitiveAnnotatedParametersInference1.symbols @@ -0,0 +1,70 @@ +//// [tests/cases/compiler/contextSensitiveAnnotatedParametersInference1.ts] //// + +=== contextSensitiveAnnotatedParametersInference1.ts === +declare function test(obj: { +>test : Symbol(test, Decl(contextSensitiveAnnotatedParametersInference1.ts, 0, 0)) +>T : Symbol(T, Decl(contextSensitiveAnnotatedParametersInference1.ts, 0, 22)) +>A : Symbol(A, Decl(contextSensitiveAnnotatedParametersInference1.ts, 0, 24)) +>B : Symbol(B, Decl(contextSensitiveAnnotatedParametersInference1.ts, 0, 27)) +>obj : Symbol(obj, Decl(contextSensitiveAnnotatedParametersInference1.ts, 0, 31)) + + ctx: T; +>ctx : Symbol(ctx, Decl(contextSensitiveAnnotatedParametersInference1.ts, 0, 37)) +>T : Symbol(T, Decl(contextSensitiveAnnotatedParametersInference1.ts, 0, 22)) + + a: (a: A, ctx: T) => void; +>a : Symbol(a, Decl(contextSensitiveAnnotatedParametersInference1.ts, 1, 9)) +>a : Symbol(a, Decl(contextSensitiveAnnotatedParametersInference1.ts, 2, 6)) +>A : Symbol(A, Decl(contextSensitiveAnnotatedParametersInference1.ts, 0, 24)) +>ctx : Symbol(ctx, Decl(contextSensitiveAnnotatedParametersInference1.ts, 2, 11)) +>T : Symbol(T, Decl(contextSensitiveAnnotatedParametersInference1.ts, 0, 22)) + + b: (b: B, ctx: T, a: A) => void; +>b : Symbol(b, Decl(contextSensitiveAnnotatedParametersInference1.ts, 2, 28)) +>b : Symbol(b, Decl(contextSensitiveAnnotatedParametersInference1.ts, 3, 6)) +>B : Symbol(B, Decl(contextSensitiveAnnotatedParametersInference1.ts, 0, 27)) +>ctx : Symbol(ctx, Decl(contextSensitiveAnnotatedParametersInference1.ts, 3, 11)) +>T : Symbol(T, Decl(contextSensitiveAnnotatedParametersInference1.ts, 0, 22)) +>a : Symbol(a, Decl(contextSensitiveAnnotatedParametersInference1.ts, 3, 19)) +>A : Symbol(A, Decl(contextSensitiveAnnotatedParametersInference1.ts, 0, 24)) + +}): void; + +test({ +>test : Symbol(test, Decl(contextSensitiveAnnotatedParametersInference1.ts, 0, 0)) + + ctx: 'foo', +>ctx : Symbol(ctx, Decl(contextSensitiveAnnotatedParametersInference1.ts, 6, 6)) + + a: (a: string, ctx) => {}, +>a : Symbol(a, Decl(contextSensitiveAnnotatedParametersInference1.ts, 7, 13)) +>a : Symbol(a, Decl(contextSensitiveAnnotatedParametersInference1.ts, 8, 6)) +>ctx : Symbol(ctx, Decl(contextSensitiveAnnotatedParametersInference1.ts, 8, 16)) + + b: (b: string, ctx, a) => {}, +>b : Symbol(b, Decl(contextSensitiveAnnotatedParametersInference1.ts, 8, 28)) +>b : Symbol(b, Decl(contextSensitiveAnnotatedParametersInference1.ts, 9, 6)) +>ctx : Symbol(ctx, Decl(contextSensitiveAnnotatedParametersInference1.ts, 9, 16)) +>a : Symbol(a, Decl(contextSensitiveAnnotatedParametersInference1.ts, 9, 21)) + +}); + +test({ +>test : Symbol(test, Decl(contextSensitiveAnnotatedParametersInference1.ts, 0, 0)) + + ctx: 'foo', +>ctx : Symbol(ctx, Decl(contextSensitiveAnnotatedParametersInference1.ts, 12, 6)) + + b: (b: string, ctx, a) => {}, +>b : Symbol(b, Decl(contextSensitiveAnnotatedParametersInference1.ts, 13, 13)) +>b : Symbol(b, Decl(contextSensitiveAnnotatedParametersInference1.ts, 14, 6)) +>ctx : Symbol(ctx, Decl(contextSensitiveAnnotatedParametersInference1.ts, 14, 16)) +>a : Symbol(a, Decl(contextSensitiveAnnotatedParametersInference1.ts, 14, 21)) + + a: (a: string, ctx) => {}, +>a : Symbol(a, Decl(contextSensitiveAnnotatedParametersInference1.ts, 14, 31)) +>a : Symbol(a, Decl(contextSensitiveAnnotatedParametersInference1.ts, 15, 6)) +>ctx : Symbol(ctx, Decl(contextSensitiveAnnotatedParametersInference1.ts, 15, 16)) + +}); + diff --git a/tests/baselines/reference/contextSensitiveAnnotatedParametersInference1.types b/tests/baselines/reference/contextSensitiveAnnotatedParametersInference1.types new file mode 100644 index 0000000000000..2709d3f579023 --- /dev/null +++ b/tests/baselines/reference/contextSensitiveAnnotatedParametersInference1.types @@ -0,0 +1,109 @@ +//// [tests/cases/compiler/contextSensitiveAnnotatedParametersInference1.ts] //// + +=== contextSensitiveAnnotatedParametersInference1.ts === +declare function test(obj: { +>test : (obj: { ctx: T; a: (a: A, ctx: T) => void; b: (b: B, ctx: T, a: A) => void; }) => void +> : ^ ^^ ^^ ^^ ^^ ^^^^^ +>obj : { ctx: T; a: (a: A, ctx: T) => void; b: (b: B, ctx: T, a: A) => void; } +> : ^^^^^^^ ^^^^^ ^^^^^ ^^^ + + ctx: T; +>ctx : T +> : ^ + + a: (a: A, ctx: T) => void; +>a : (a: A, ctx: T) => void +> : ^ ^^ ^^ ^^ ^^^^^ +>a : A +> : ^ +>ctx : T +> : ^ + + b: (b: B, ctx: T, a: A) => void; +>b : (b: B, ctx: T, a: A) => void +> : ^ ^^ ^^ ^^ ^^ ^^ ^^^^^ +>b : B +> : ^ +>ctx : T +> : ^ +>a : A +> : ^ + +}): void; + +test({ +>test({ ctx: 'foo', a: (a: string, ctx) => {}, b: (b: string, ctx, a) => {},}) : void +> : ^^^^ +>test : (obj: { ctx: T; a: (a: A, ctx: T) => void; b: (b: B, ctx: T, a: A) => void; }) => void +> : ^ ^^ ^^ ^^ ^^ ^^^^^ +>{ ctx: 'foo', a: (a: string, ctx) => {}, b: (b: string, ctx, a) => {},} : { ctx: string; a: (a: string, ctx: string) => void; b: (b: string, ctx: string, a: string) => void; } +> : ^^^^^^^^^^^^^^^^^^^ ^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^ ^^ ^^ ^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^ + + ctx: 'foo', +>ctx : string +> : ^^^^^^ +>'foo' : "foo" +> : ^^^^^ + + a: (a: string, ctx) => {}, +>a : (a: string, ctx: string) => void +> : ^ ^^ ^^ ^^^^^^^^^^^^^^^^^ +>(a: string, ctx) => {} : (a: string, ctx: string) => void +> : ^ ^^ ^^ ^^^^^^^^^^^^^^^^^ +>a : string +> : ^^^^^^ +>ctx : string +> : ^^^^^^ + + b: (b: string, ctx, a) => {}, +>b : (b: string, ctx: string, a: string) => void +> : ^ ^^ ^^ ^^^^^^^^^^ ^^^^^^^^^^^^^^^^^ +>(b: string, ctx, a) => {} : (b: string, ctx: string, a: string) => void +> : ^ ^^ ^^ ^^^^^^^^^^ ^^^^^^^^^^^^^^^^^ +>b : string +> : ^^^^^^ +>ctx : string +> : ^^^^^^ +>a : string +> : ^^^^^^ + +}); + +test({ +>test({ ctx: 'foo', b: (b: string, ctx, a) => {}, a: (a: string, ctx) => {},}) : void +> : ^^^^ +>test : (obj: { ctx: T; a: (a: A, ctx: T) => void; b: (b: B, ctx: T, a: A) => void; }) => void +> : ^ ^^ ^^ ^^ ^^ ^^^^^ +>{ ctx: 'foo', b: (b: string, ctx, a) => {}, a: (a: string, ctx) => {},} : { ctx: string; b: (b: string, ctx: string, a: string) => void; a: (a: string, ctx: string) => void; } +> : ^^^^^^^^^^^^^^^^^^^ ^^ ^^ ^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^ ^^ ^^ ^^^^^^^^^^^^^^^^^^^^ + + ctx: 'foo', +>ctx : string +> : ^^^^^^ +>'foo' : "foo" +> : ^^^^^ + + b: (b: string, ctx, a) => {}, +>b : (b: string, ctx: string, a: string) => void +> : ^ ^^ ^^ ^^^^^^^^^^ ^^^^^^^^^^^^^^^^^ +>(b: string, ctx, a) => {} : (b: string, ctx: string, a: string) => void +> : ^ ^^ ^^ ^^^^^^^^^^ ^^^^^^^^^^^^^^^^^ +>b : string +> : ^^^^^^ +>ctx : string +> : ^^^^^^ +>a : string +> : ^^^^^^ + + a: (a: string, ctx) => {}, +>a : (a: string, ctx: string) => void +> : ^ ^^ ^^ ^^^^^^^^^^^^^^^^^ +>(a: string, ctx) => {} : (a: string, ctx: string) => void +> : ^ ^^ ^^ ^^^^^^^^^^^^^^^^^ +>a : string +> : ^^^^^^ +>ctx : string +> : ^^^^^^ + +}); + diff --git a/tests/baselines/reference/contextSensitiveAnnotatedParametersInference2.symbols b/tests/baselines/reference/contextSensitiveAnnotatedParametersInference2.symbols new file mode 100644 index 0000000000000..89129c6fb6830 --- /dev/null +++ b/tests/baselines/reference/contextSensitiveAnnotatedParametersInference2.symbols @@ -0,0 +1,91 @@ +//// [tests/cases/compiler/contextSensitiveAnnotatedParametersInference2.ts] //// + +=== contextSensitiveAnnotatedParametersInference2.ts === +// https://github.com/microsoft/TypeScript/issues/60047 + +type Map = { +>Map : Symbol(Map, Decl(contextSensitiveAnnotatedParametersInference2.ts, 0, 0)) +>T : Symbol(T, Decl(contextSensitiveAnnotatedParametersInference2.ts, 2, 9)) + + [P in keyof T]: T[P] extends boolean ? "boolean" : "other"; +>P : Symbol(P, Decl(contextSensitiveAnnotatedParametersInference2.ts, 3, 3)) +>T : Symbol(T, Decl(contextSensitiveAnnotatedParametersInference2.ts, 2, 9)) +>T : Symbol(T, Decl(contextSensitiveAnnotatedParametersInference2.ts, 2, 9)) +>P : Symbol(P, Decl(contextSensitiveAnnotatedParametersInference2.ts, 3, 3)) + +}; + +export function buildCommand>(builderArgs: { +>buildCommand : Symbol(buildCommand, Decl(contextSensitiveAnnotatedParametersInference2.ts, 4, 2)) +>F : Symbol(F, Decl(contextSensitiveAnnotatedParametersInference2.ts, 6, 29)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) +>builderArgs : Symbol(builderArgs, Decl(contextSensitiveAnnotatedParametersInference2.ts, 6, 64)) + + func: (p: F) => void; +>func : Symbol(func, Decl(contextSensitiveAnnotatedParametersInference2.ts, 6, 78)) +>p : Symbol(p, Decl(contextSensitiveAnnotatedParametersInference2.ts, 7, 9)) +>F : Symbol(F, Decl(contextSensitiveAnnotatedParametersInference2.ts, 6, 29)) + + params: Map>; +>params : Symbol(params, Decl(contextSensitiveAnnotatedParametersInference2.ts, 7, 23)) +>Map : Symbol(Map, Decl(contextSensitiveAnnotatedParametersInference2.ts, 0, 0)) +>NoInfer : Symbol(NoInfer, Decl(lib.es5.d.ts, --, --)) +>F : Symbol(F, Decl(contextSensitiveAnnotatedParametersInference2.ts, 6, 29)) + +}) {} + +type Foo = { foo: boolean }; +>Foo : Symbol(Foo, Decl(contextSensitiveAnnotatedParametersInference2.ts, 9, 5)) +>foo : Symbol(foo, Decl(contextSensitiveAnnotatedParametersInference2.ts, 11, 12)) + +buildCommand({ +>buildCommand : Symbol(buildCommand, Decl(contextSensitiveAnnotatedParametersInference2.ts, 4, 2)) + + func: function (p: Foo) {}, +>func : Symbol(func, Decl(contextSensitiveAnnotatedParametersInference2.ts, 13, 14)) +>p : Symbol(p, Decl(contextSensitiveAnnotatedParametersInference2.ts, 14, 18)) +>Foo : Symbol(Foo, Decl(contextSensitiveAnnotatedParametersInference2.ts, 9, 5)) + + params: { +>params : Symbol(params, Decl(contextSensitiveAnnotatedParametersInference2.ts, 14, 29)) + + foo: "boolean", +>foo : Symbol(foo, Decl(contextSensitiveAnnotatedParametersInference2.ts, 15, 11)) + + }, +}); + +buildCommand({ +>buildCommand : Symbol(buildCommand, Decl(contextSensitiveAnnotatedParametersInference2.ts, 4, 2)) + + func(p: Foo) {}, +>func : Symbol(func, Decl(contextSensitiveAnnotatedParametersInference2.ts, 20, 14)) +>p : Symbol(p, Decl(contextSensitiveAnnotatedParametersInference2.ts, 21, 7)) +>Foo : Symbol(Foo, Decl(contextSensitiveAnnotatedParametersInference2.ts, 9, 5)) + + params: { +>params : Symbol(params, Decl(contextSensitiveAnnotatedParametersInference2.ts, 21, 18)) + + foo: "boolean", +>foo : Symbol(foo, Decl(contextSensitiveAnnotatedParametersInference2.ts, 22, 11)) + + }, +}); + +buildCommand({ +>buildCommand : Symbol(buildCommand, Decl(contextSensitiveAnnotatedParametersInference2.ts, 4, 2)) + + func: (p: Foo) => {}, +>func : Symbol(func, Decl(contextSensitiveAnnotatedParametersInference2.ts, 27, 14)) +>p : Symbol(p, Decl(contextSensitiveAnnotatedParametersInference2.ts, 28, 9)) +>Foo : Symbol(Foo, Decl(contextSensitiveAnnotatedParametersInference2.ts, 9, 5)) + + params: { +>params : Symbol(params, Decl(contextSensitiveAnnotatedParametersInference2.ts, 28, 23)) + + foo: "boolean", +>foo : Symbol(foo, Decl(contextSensitiveAnnotatedParametersInference2.ts, 29, 11)) + + }, +}); + diff --git a/tests/baselines/reference/contextSensitiveAnnotatedParametersInference2.types b/tests/baselines/reference/contextSensitiveAnnotatedParametersInference2.types new file mode 100644 index 0000000000000..1b25763acb1a7 --- /dev/null +++ b/tests/baselines/reference/contextSensitiveAnnotatedParametersInference2.types @@ -0,0 +1,127 @@ +//// [tests/cases/compiler/contextSensitiveAnnotatedParametersInference2.ts] //// + +=== contextSensitiveAnnotatedParametersInference2.ts === +// https://github.com/microsoft/TypeScript/issues/60047 + +type Map = { +>Map : Map +> : ^^^^^^ + + [P in keyof T]: T[P] extends boolean ? "boolean" : "other"; +}; + +export function buildCommand>(builderArgs: { +>buildCommand : >(builderArgs: { func: (p: F) => void; params: Map>; }) => void +> : ^ ^^^^^^^^^ ^^ ^^ ^^^^^^^^^ +>builderArgs : { func: (p: F) => void; params: Map>; } +> : ^^^^^^^^ ^^^^^^^^^^ ^^^ + + func: (p: F) => void; +>func : (p: F) => void +> : ^ ^^ ^^^^^ +>p : F +> : ^ + + params: Map>; +>params : Map> +> : ^^^^^^^^^^^^^^^ + +}) {} + +type Foo = { foo: boolean }; +>Foo : Foo +> : ^^^ +>foo : boolean +> : ^^^^^^^ + +buildCommand({ +>buildCommand({ func: function (p: Foo) {}, params: { foo: "boolean", },}) : void +> : ^^^^ +>buildCommand : >(builderArgs: { func: (p: F) => void; params: Map>; }) => void +> : ^ ^^^^^^^^^ ^^ ^^ ^^^^^^^^^ +>{ func: function (p: Foo) {}, params: { foo: "boolean", },} : { func: (p: Foo) => void; params: { foo: "boolean"; }; } +> : ^^^^^^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + func: function (p: Foo) {}, +>func : (p: Foo) => void +> : ^ ^^ ^^^^^^^^^ +>function (p: Foo) {} : (p: Foo) => void +> : ^ ^^ ^^^^^^^^^ +>p : Foo +> : ^^^ + + params: { +>params : { foo: "boolean"; } +> : ^^^^^^^^^^^^^^^^^^^ +>{ foo: "boolean", } : { foo: "boolean"; } +> : ^^^^^^^^^^^^^^^^^^^ + + foo: "boolean", +>foo : "boolean" +> : ^^^^^^^^^ +>"boolean" : "boolean" +> : ^^^^^^^^^ + + }, +}); + +buildCommand({ +>buildCommand({ func(p: Foo) {}, params: { foo: "boolean", },}) : void +> : ^^^^ +>buildCommand : >(builderArgs: { func: (p: F) => void; params: Map>; }) => void +> : ^ ^^^^^^^^^ ^^ ^^ ^^^^^^^^^ +>{ func(p: Foo) {}, params: { foo: "boolean", },} : { func(p: Foo): void; params: { foo: "boolean"; }; } +> : ^^^^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + func(p: Foo) {}, +>func : (p: Foo) => void +> : ^ ^^ ^^^^^^^^^ +>p : Foo +> : ^^^ + + params: { +>params : { foo: "boolean"; } +> : ^^^^^^^^^^^^^^^^^^^ +>{ foo: "boolean", } : { foo: "boolean"; } +> : ^^^^^^^^^^^^^^^^^^^ + + foo: "boolean", +>foo : "boolean" +> : ^^^^^^^^^ +>"boolean" : "boolean" +> : ^^^^^^^^^ + + }, +}); + +buildCommand({ +>buildCommand({ func: (p: Foo) => {}, params: { foo: "boolean", },}) : void +> : ^^^^ +>buildCommand : >(builderArgs: { func: (p: F) => void; params: Map>; }) => void +> : ^ ^^^^^^^^^ ^^ ^^ ^^^^^^^^^ +>{ func: (p: Foo) => {}, params: { foo: "boolean", },} : { func: (p: Foo) => void; params: { foo: "boolean"; }; } +> : ^^^^^^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + func: (p: Foo) => {}, +>func : (p: Foo) => void +> : ^ ^^ ^^^^^^^^^ +>(p: Foo) => {} : (p: Foo) => void +> : ^ ^^ ^^^^^^^^^ +>p : Foo +> : ^^^ + + params: { +>params : { foo: "boolean"; } +> : ^^^^^^^^^^^^^^^^^^^ +>{ foo: "boolean", } : { foo: "boolean"; } +> : ^^^^^^^^^^^^^^^^^^^ + + foo: "boolean", +>foo : "boolean" +> : ^^^^^^^^^ +>"boolean" : "boolean" +> : ^^^^^^^^^ + + }, +}); + diff --git a/tests/cases/compiler/contextSensitiveAnnotatedParametersInference1.ts b/tests/cases/compiler/contextSensitiveAnnotatedParametersInference1.ts new file mode 100644 index 0000000000000..ea27840069acc --- /dev/null +++ b/tests/cases/compiler/contextSensitiveAnnotatedParametersInference1.ts @@ -0,0 +1,20 @@ +// @strict: true +// @noEmit: true + +declare function test(obj: { + ctx: T; + a: (a: A, ctx: T) => void; + b: (b: B, ctx: T, a: A) => void; +}): void; + +test({ + ctx: 'foo', + a: (a: string, ctx) => {}, + b: (b: string, ctx, a) => {}, +}); + +test({ + ctx: 'foo', + b: (b: string, ctx, a) => {}, + a: (a: string, ctx) => {}, +}); diff --git a/tests/cases/compiler/contextSensitiveAnnotatedParametersInference2.ts b/tests/cases/compiler/contextSensitiveAnnotatedParametersInference2.ts new file mode 100644 index 0000000000000..6aa088c3636e8 --- /dev/null +++ b/tests/cases/compiler/contextSensitiveAnnotatedParametersInference2.ts @@ -0,0 +1,36 @@ +// @strict: true +// @noEmit: true + +// https://github.com/microsoft/TypeScript/issues/60047 + +type Map = { + [P in keyof T]: T[P] extends boolean ? "boolean" : "other"; +}; + +export function buildCommand>(builderArgs: { + func: (p: F) => void; + params: Map>; +}) {} + +type Foo = { foo: boolean }; + +buildCommand({ + func: function (p: Foo) {}, + params: { + foo: "boolean", + }, +}); + +buildCommand({ + func(p: Foo) {}, + params: { + foo: "boolean", + }, +}); + +buildCommand({ + func: (p: Foo) => {}, + params: { + foo: "boolean", + }, +}); diff --git a/tests/cases/fourslash/completionsObjectLiteralInferenceSourceInPartiallyAnnotatedSignature1.ts b/tests/cases/fourslash/completionsObjectLiteralInferenceSourceInPartiallyAnnotatedSignature1.ts new file mode 100644 index 0000000000000..eda003f839f07 --- /dev/null +++ b/tests/cases/fourslash/completionsObjectLiteralInferenceSourceInPartiallyAnnotatedSignature1.ts @@ -0,0 +1,15 @@ +/// + +// @strict: true +// @lib: esnext + +//// declare function registerPlugin>( +//// callback: (app: any, options: Opt) => void, +//// opts: NoInfer, +//// ): Promise; +//// +//// registerPlugin((app, opts: { something: string }) => {}, { +//// /*1*/ +//// }); + +verify.completions({ marker: "1", includes: [`something`] });