diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 027007fb15b62..d51ed96aa6675 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -36664,7 +36664,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const declaration = signature.parameters[i].valueDeclaration as ParameterDeclaration; const typeNode = getEffectiveTypeAnnotationNode(declaration); if (typeNode) { - const source = addOptionality(getTypeFromTypeNode(typeNode), /*isProperty*/ false, isOptionalDeclaration(declaration)); + const source = addOptionality(getTypeFromTypeNode(typeNode), /*isProperty*/ false, hasInitializer(declaration) || isOptionalDeclaration(declaration)); const target = getTypeAtPosition(context, i); inferTypes(inferenceContext.inferences, source, target); } diff --git a/tests/baselines/reference/inferFromAnnotatedParameterWithInitializer.symbols b/tests/baselines/reference/inferFromAnnotatedParameterWithInitializer.symbols new file mode 100644 index 0000000000000..35b6f88fcf3a1 --- /dev/null +++ b/tests/baselines/reference/inferFromAnnotatedParameterWithInitializer.symbols @@ -0,0 +1,73 @@ +//// [tests/cases/compiler/inferFromAnnotatedParameterWithInitializer.ts] //// + +=== inferFromAnnotatedParameterWithInitializer.ts === +// https://github.com/microsoft/TypeScript/issues/57706 + +declare function infer1(fn: Factory): T; +>infer1 : Symbol(infer1, Decl(inferFromAnnotatedParameterWithInitializer.ts, 0, 0)) +>T : Symbol(T, Decl(inferFromAnnotatedParameterWithInitializer.ts, 2, 24)) +>fn : Symbol(fn, Decl(inferFromAnnotatedParameterWithInitializer.ts, 2, 27)) +>Factory : Symbol(Factory, Decl(inferFromAnnotatedParameterWithInitializer.ts, 3, 47)) +>T : Symbol(T, Decl(inferFromAnnotatedParameterWithInitializer.ts, 2, 24)) +>T : Symbol(T, Decl(inferFromAnnotatedParameterWithInitializer.ts, 2, 24)) + +declare function infer2(fn: Factory2): T; +>infer2 : Symbol(infer2, Decl(inferFromAnnotatedParameterWithInitializer.ts, 2, 46)) +>T : Symbol(T, Decl(inferFromAnnotatedParameterWithInitializer.ts, 3, 24)) +>fn : Symbol(fn, Decl(inferFromAnnotatedParameterWithInitializer.ts, 3, 27)) +>Factory2 : Symbol(Factory2, Decl(inferFromAnnotatedParameterWithInitializer.ts, 5, 53)) +>T : Symbol(T, Decl(inferFromAnnotatedParameterWithInitializer.ts, 3, 24)) +>T : Symbol(T, Decl(inferFromAnnotatedParameterWithInitializer.ts, 3, 24)) + +export type Factory = (arg1: T, arg2: any) => any; +>Factory : Symbol(Factory, Decl(inferFromAnnotatedParameterWithInitializer.ts, 3, 47)) +>T : Symbol(T, Decl(inferFromAnnotatedParameterWithInitializer.ts, 5, 20)) +>arg1 : Symbol(arg1, Decl(inferFromAnnotatedParameterWithInitializer.ts, 5, 26)) +>T : Symbol(T, Decl(inferFromAnnotatedParameterWithInitializer.ts, 5, 20)) +>arg2 : Symbol(arg2, Decl(inferFromAnnotatedParameterWithInitializer.ts, 5, 34)) + +export type Factory2 = (...args: [T, any]) => any; +>Factory2 : Symbol(Factory2, Decl(inferFromAnnotatedParameterWithInitializer.ts, 5, 53)) +>T : Symbol(T, Decl(inferFromAnnotatedParameterWithInitializer.ts, 6, 21)) +>args : Symbol(args, Decl(inferFromAnnotatedParameterWithInitializer.ts, 6, 27)) +>T : Symbol(T, Decl(inferFromAnnotatedParameterWithInitializer.ts, 6, 21)) + +const f1 = (msg: string = "hello", test: any) => {}; +>f1 : Symbol(f1, Decl(inferFromAnnotatedParameterWithInitializer.ts, 8, 5)) +>msg : Symbol(msg, Decl(inferFromAnnotatedParameterWithInitializer.ts, 8, 12)) +>test : Symbol(test, Decl(inferFromAnnotatedParameterWithInitializer.ts, 8, 34)) + +const a1 = infer1(f1); +>a1 : Symbol(a1, Decl(inferFromAnnotatedParameterWithInitializer.ts, 9, 5)) +>infer1 : Symbol(infer1, Decl(inferFromAnnotatedParameterWithInitializer.ts, 0, 0)) +>f1 : Symbol(f1, Decl(inferFromAnnotatedParameterWithInitializer.ts, 8, 5)) + +const a2 = infer2(f1); +>a2 : Symbol(a2, Decl(inferFromAnnotatedParameterWithInitializer.ts, 10, 5)) +>infer2 : Symbol(infer2, Decl(inferFromAnnotatedParameterWithInitializer.ts, 2, 46)) +>f1 : Symbol(f1, Decl(inferFromAnnotatedParameterWithInitializer.ts, 8, 5)) + +const f2 = (msg: string = "hello") => {}; +>f2 : Symbol(f2, Decl(inferFromAnnotatedParameterWithInitializer.ts, 12, 5)) +>msg : Symbol(msg, Decl(inferFromAnnotatedParameterWithInitializer.ts, 12, 12)) + +const b1 = infer1(f2); +>b1 : Symbol(b1, Decl(inferFromAnnotatedParameterWithInitializer.ts, 13, 5)) +>infer1 : Symbol(infer1, Decl(inferFromAnnotatedParameterWithInitializer.ts, 0, 0)) +>f2 : Symbol(f2, Decl(inferFromAnnotatedParameterWithInitializer.ts, 12, 5)) + +const b2 = infer2(f2); +>b2 : Symbol(b2, Decl(inferFromAnnotatedParameterWithInitializer.ts, 14, 5)) +>infer2 : Symbol(infer2, Decl(inferFromAnnotatedParameterWithInitializer.ts, 2, 46)) +>f2 : Symbol(f2, Decl(inferFromAnnotatedParameterWithInitializer.ts, 12, 5)) + +const c1 = infer1((msg: string = "hello") => {}); +>c1 : Symbol(c1, Decl(inferFromAnnotatedParameterWithInitializer.ts, 16, 5)) +>infer1 : Symbol(infer1, Decl(inferFromAnnotatedParameterWithInitializer.ts, 0, 0)) +>msg : Symbol(msg, Decl(inferFromAnnotatedParameterWithInitializer.ts, 16, 19)) + +const c2 = infer2((msg: string = "hello") => {}); +>c2 : Symbol(c2, Decl(inferFromAnnotatedParameterWithInitializer.ts, 17, 5)) +>infer2 : Symbol(infer2, Decl(inferFromAnnotatedParameterWithInitializer.ts, 2, 46)) +>msg : Symbol(msg, Decl(inferFromAnnotatedParameterWithInitializer.ts, 17, 19)) + diff --git a/tests/baselines/reference/inferFromAnnotatedParameterWithInitializer.types b/tests/baselines/reference/inferFromAnnotatedParameterWithInitializer.types new file mode 100644 index 0000000000000..836152fe6d5a6 --- /dev/null +++ b/tests/baselines/reference/inferFromAnnotatedParameterWithInitializer.types @@ -0,0 +1,119 @@ +//// [tests/cases/compiler/inferFromAnnotatedParameterWithInitializer.ts] //// + +=== inferFromAnnotatedParameterWithInitializer.ts === +// https://github.com/microsoft/TypeScript/issues/57706 + +declare function infer1(fn: Factory): T; +>infer1 : (fn: Factory) => T +> : ^ ^^ ^^ ^^^^^ +>fn : Factory +> : ^^^^^^^^^^ + +declare function infer2(fn: Factory2): T; +>infer2 : (fn: Factory2) => T +> : ^ ^^ ^^ ^^^^^ +>fn : Factory2 +> : ^^^^^^^^^^^ + +export type Factory = (arg1: T, arg2: any) => any; +>Factory : Factory +> : ^^^^^^^^^^ +>arg1 : T +> : ^ +>arg2 : any + +export type Factory2 = (...args: [T, any]) => any; +>Factory2 : Factory2 +> : ^^^^^^^^^^^ +>args : [T, any] +> : ^^^^^^^^ + +const f1 = (msg: string = "hello", test: any) => {}; +>f1 : (msg: string | undefined, test: any) => void +> : ^ ^^ ^^^^^^^^^^^^^^ ^^ ^^^^^^^^^ +>(msg: string = "hello", test: any) => {} : (msg: string | undefined, test: any) => void +> : ^ ^^ ^^^^^^^^^^^^^^ ^^ ^^^^^^^^^ +>msg : string +> : ^^^^^^ +>"hello" : "hello" +> : ^^^^^^^ +>test : any + +const a1 = infer1(f1); +>a1 : string | undefined +> : ^^^^^^^^^^^^^^^^^^ +>infer1(f1) : string | undefined +> : ^^^^^^^^^^^^^^^^^^ +>infer1 : (fn: Factory) => T +> : ^ ^^ ^^ ^^^^^^ +>f1 : (msg: string | undefined, test: any) => void +> : ^ ^^ ^^^^^^^^^^^^^^ ^^ ^^^^^^^^^ + +const a2 = infer2(f1); +>a2 : string | undefined +> : ^^^^^^^^^^^^^^^^^^ +>infer2(f1) : string | undefined +> : ^^^^^^^^^^^^^^^^^^ +>infer2 : (fn: Factory2) => T +> : ^ ^^ ^^ ^^^^^^ +>f1 : (msg: string | undefined, test: any) => void +> : ^ ^^ ^^^^^^^^^^^^^^ ^^ ^^^^^^^^^ + +const f2 = (msg: string = "hello") => {}; +>f2 : (msg?: string) => void +> : ^ ^^^ ^^^^^^^^^ +>(msg: string = "hello") => {} : (msg?: string) => void +> : ^ ^^^ ^^^^^^^^^ +>msg : string +> : ^^^^^^ +>"hello" : "hello" +> : ^^^^^^^ + +const b1 = infer1(f2); +>b1 : string | undefined +> : ^^^^^^^^^^^^^^^^^^ +>infer1(f2) : string | undefined +> : ^^^^^^^^^^^^^^^^^^ +>infer1 : (fn: Factory) => T +> : ^ ^^ ^^ ^^^^^^ +>f2 : (msg?: string) => void +> : ^ ^^^ ^^^^^^^^^ + +const b2 = infer2(f2); +>b2 : string | undefined +> : ^^^^^^^^^^^^^^^^^^ +>infer2(f2) : string | undefined +> : ^^^^^^^^^^^^^^^^^^ +>infer2 : (fn: Factory2) => T +> : ^ ^^ ^^ ^^^^^^ +>f2 : (msg?: string) => void +> : ^ ^^^ ^^^^^^^^^ + +const c1 = infer1((msg: string = "hello") => {}); +>c1 : string | undefined +> : ^^^^^^^^^^^^^^^^^^ +>infer1((msg: string = "hello") => {}) : string | undefined +> : ^^^^^^^^^^^^^^^^^^ +>infer1 : (fn: Factory) => T +> : ^ ^^ ^^ ^^^^^^ +>(msg: string = "hello") => {} : (msg?: string) => void +> : ^ ^^^ ^^^^^^^^^ +>msg : string +> : ^^^^^^ +>"hello" : "hello" +> : ^^^^^^^ + +const c2 = infer2((msg: string = "hello") => {}); +>c2 : string | undefined +> : ^^^^^^^^^^^^^^^^^^ +>infer2((msg: string = "hello") => {}) : string | undefined +> : ^^^^^^^^^^^^^^^^^^ +>infer2 : (fn: Factory2) => T +> : ^ ^^ ^^ ^^^^^^ +>(msg: string = "hello") => {} : (msg?: string) => void +> : ^ ^^^ ^^^^^^^^^ +>msg : string +> : ^^^^^^ +>"hello" : "hello" +> : ^^^^^^^ + diff --git a/tests/cases/compiler/inferFromAnnotatedParameterWithInitializer.ts b/tests/cases/compiler/inferFromAnnotatedParameterWithInitializer.ts new file mode 100644 index 0000000000000..b7628aa30a525 --- /dev/null +++ b/tests/cases/compiler/inferFromAnnotatedParameterWithInitializer.ts @@ -0,0 +1,21 @@ +// @strict: true +// @noEmit: true + +// https://github.com/microsoft/TypeScript/issues/57706 + +declare function infer1(fn: Factory): T; +declare function infer2(fn: Factory2): T; + +export type Factory = (arg1: T, arg2: any) => any; +export type Factory2 = (...args: [T, any]) => any; + +const f1 = (msg: string = "hello", test: any) => {}; +const a1 = infer1(f1); +const a2 = infer2(f1); + +const f2 = (msg: string = "hello") => {}; +const b1 = infer1(f2); +const b2 = infer2(f2); + +const c1 = infer1((msg: string = "hello") => {}); +const c2 = infer2((msg: string = "hello") => {});