Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 8 additions & 7 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19099,10 +19099,13 @@ namespace ts {

// Return the contextual type for a given expression node. During overload resolution, a contextual type may temporarily
// be "pushed" onto a node using the contextualType property.
function getApparentTypeOfContextualType(node: Expression, contextFlags?: ContextFlags): Type | undefined {
const contextualType = instantiateContextualType(getContextualType(node, contextFlags), node, contextFlags);
if (contextualType) {
const apparentType = mapType(contextualType, getApparentType, /*noReductions*/ true);
function getApparentTypeOfContextualType(node: Expression | MethodDeclaration, contextFlags?: ContextFlags): Type | undefined {
const contextualType = isObjectLiteralMethod(node) ?
getContextualTypeForObjectLiteralMethod(node, contextFlags) :
getContextualType(node, contextFlags);
const instantiatedType = instantiateContextualType(contextualType, node, contextFlags);
if (instantiatedType) {
const apparentType = mapType(instantiatedType, getApparentType, /*noReductions*/ true);
if (apparentType.flags & TypeFlags.Union) {
if (isObjectLiteralExpression(node)) {
return discriminateContextualTypeByObjectMembers(node, apparentType as UnionType);
Expand Down Expand Up @@ -19426,9 +19429,7 @@ namespace ts {
if (typeTagSignature) {
return typeTagSignature;
}
const type = isObjectLiteralMethod(node) ?
getContextualTypeForObjectLiteralMethod(node, ContextFlags.Signature) :
getApparentTypeOfContextualType(node, ContextFlags.Signature);
const type = getApparentTypeOfContextualType(node, ContextFlags.Signature);
if (!type) {
return undefined;
}
Expand Down
14 changes: 14 additions & 0 deletions tests/baselines/reference/instantiateContextualTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,16 @@ class Interesting {
declare function invoke<T>(f: () => T): T;

let xx: 0 | 1 | 2 = invoke(() => 1);

// Repro from #32416

declare function assignPartial<T>(target: T, partial: Partial<T>): T;

let obj = {
foo(bar: string) {}
}

assignPartial(obj, { foo(...args) {} }); // args has type [string]


//// [instantiateContextualTypes.js]
Expand Down Expand Up @@ -222,3 +232,7 @@ class Interesting {
}
}
let xx = invoke(() => 1);
let obj = {
foo(bar) { }
};
assignPartial(obj, { foo(...args) { } }); // args has type [string]
26 changes: 26 additions & 0 deletions tests/baselines/reference/instantiateContextualTypes.symbols
Original file line number Diff line number Diff line change
Expand Up @@ -481,3 +481,29 @@ let xx: 0 | 1 | 2 = invoke(() => 1);
>xx : Symbol(xx, Decl(instantiateContextualTypes.ts, 172, 3))
>invoke : Symbol(invoke, Decl(instantiateContextualTypes.ts, 166, 1))

// Repro from #32416

declare function assignPartial<T>(target: T, partial: Partial<T>): T;
>assignPartial : Symbol(assignPartial, Decl(instantiateContextualTypes.ts, 172, 36))
>T : Symbol(T, Decl(instantiateContextualTypes.ts, 176, 31))
>target : Symbol(target, Decl(instantiateContextualTypes.ts, 176, 34))
>T : Symbol(T, Decl(instantiateContextualTypes.ts, 176, 31))
>partial : Symbol(partial, Decl(instantiateContextualTypes.ts, 176, 44))
>Partial : Symbol(Partial, Decl(lib.es5.d.ts, --, --))
>T : Symbol(T, Decl(instantiateContextualTypes.ts, 176, 31))
>T : Symbol(T, Decl(instantiateContextualTypes.ts, 176, 31))

let obj = {
>obj : Symbol(obj, Decl(instantiateContextualTypes.ts, 178, 3))

foo(bar: string) {}
>foo : Symbol(foo, Decl(instantiateContextualTypes.ts, 178, 11))
>bar : Symbol(bar, Decl(instantiateContextualTypes.ts, 179, 6))
}

assignPartial(obj, { foo(...args) {} }); // args has type [string]
>assignPartial : Symbol(assignPartial, Decl(instantiateContextualTypes.ts, 172, 36))
>obj : Symbol(obj, Decl(instantiateContextualTypes.ts, 178, 3))
>foo : Symbol(foo, Decl(instantiateContextualTypes.ts, 182, 20))
>args : Symbol(args, Decl(instantiateContextualTypes.ts, 182, 25))

24 changes: 24 additions & 0 deletions tests/baselines/reference/instantiateContextualTypes.types
Original file line number Diff line number Diff line change
Expand Up @@ -422,3 +422,27 @@ let xx: 0 | 1 | 2 = invoke(() => 1);
>() => 1 : () => 1
>1 : 1

// Repro from #32416

declare function assignPartial<T>(target: T, partial: Partial<T>): T;
>assignPartial : <T>(target: T, partial: Partial<T>) => T
>target : T
>partial : Partial<T>

let obj = {
>obj : { foo(bar: string): void; }
>{ foo(bar: string) {}} : { foo(bar: string): void; }

foo(bar: string) {}
>foo : (bar: string) => void
>bar : string
}

assignPartial(obj, { foo(...args) {} }); // args has type [string]
>assignPartial(obj, { foo(...args) {} }) : { foo(bar: string): void; }
>assignPartial : <T>(target: T, partial: Partial<T>) => T
>obj : { foo(bar: string): void; }
>{ foo(...args) {} } : { foo(bar: string): void; }
>foo : (bar: string) => void
>args : [string]

10 changes: 10 additions & 0 deletions tests/cases/compiler/instantiateContextualTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -174,3 +174,13 @@ class Interesting {
declare function invoke<T>(f: () => T): T;

let xx: 0 | 1 | 2 = invoke(() => 1);

// Repro from #32416

declare function assignPartial<T>(target: T, partial: Partial<T>): T;

let obj = {
foo(bar: string) {}
}

assignPartial(obj, { foo(...args) {} }); // args has type [string]