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: 14 additions & 1 deletion src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23593,7 +23593,20 @@ namespace ts {
// If the signature's 'this' type is voidType, then the check is skipped -- anything is compatible.
// If the expression is a new expression, then the check is skipped.
const thisArgumentNode = getThisArgumentOfCall(node);
const thisArgumentType = thisArgumentNode ? checkExpression(thisArgumentNode) : voidType;
let thisArgumentType: Type;
if (thisArgumentNode) {
thisArgumentType = checkExpression(thisArgumentNode);
if (isOptionalChainRoot(thisArgumentNode.parent)) {
thisArgumentType = getNonNullableType(thisArgumentType);
}
else if (isOptionalChain(thisArgumentNode.parent)) {
thisArgumentType = removeOptionalTypeMarker(thisArgumentType);
}
}
else {
thisArgumentType = voidType;
}

const errorNode = reportErrors ? (thisArgumentNode || node) : undefined;
const headMessage = Diagnostics.The_this_context_of_type_0_is_not_assignable_to_method_s_this_of_type_1;
if (!checkTypeRelatedTo(thisArgumentType, thisType, relation, errorNode, headMessage, containingMessageChain, errorOutputContainer)) {
Expand Down
10 changes: 10 additions & 0 deletions tests/baselines/reference/thisTypeOptionalCall.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
//// [thisTypeOptionalCall.ts]
function maybeBind<T, A extends any[], R>(obj: T, fn: ((this: T, ...args: A) => R) | undefined): ((...args: A) => R) | undefined {
return fn?.bind(obj);
}

//// [thisTypeOptionalCall.js]
function maybeBind(obj, fn) {
var _a;
return (_a = fn) === null || _a === void 0 ? void 0 : _a.bind(obj);
}
24 changes: 24 additions & 0 deletions tests/baselines/reference/thisTypeOptionalCall.symbols
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
=== tests/cases/conformance/types/thisType/thisTypeOptionalCall.ts ===
function maybeBind<T, A extends any[], R>(obj: T, fn: ((this: T, ...args: A) => R) | undefined): ((...args: A) => R) | undefined {
>maybeBind : Symbol(maybeBind, Decl(thisTypeOptionalCall.ts, 0, 0))
>T : Symbol(T, Decl(thisTypeOptionalCall.ts, 0, 19))
>A : Symbol(A, Decl(thisTypeOptionalCall.ts, 0, 21))
>R : Symbol(R, Decl(thisTypeOptionalCall.ts, 0, 38))
>obj : Symbol(obj, Decl(thisTypeOptionalCall.ts, 0, 42))
>T : Symbol(T, Decl(thisTypeOptionalCall.ts, 0, 19))
>fn : Symbol(fn, Decl(thisTypeOptionalCall.ts, 0, 49))
>this : Symbol(this, Decl(thisTypeOptionalCall.ts, 0, 56))
>T : Symbol(T, Decl(thisTypeOptionalCall.ts, 0, 19))
>args : Symbol(args, Decl(thisTypeOptionalCall.ts, 0, 64))
>A : Symbol(A, Decl(thisTypeOptionalCall.ts, 0, 21))
>R : Symbol(R, Decl(thisTypeOptionalCall.ts, 0, 38))
>args : Symbol(args, Decl(thisTypeOptionalCall.ts, 0, 99))
>A : Symbol(A, Decl(thisTypeOptionalCall.ts, 0, 21))
>R : Symbol(R, Decl(thisTypeOptionalCall.ts, 0, 38))

return fn?.bind(obj);
>fn?.bind : Symbol(Function.bind, Decl(lib.es5.d.ts, --, --))
>fn : Symbol(fn, Decl(thisTypeOptionalCall.ts, 0, 49))
>bind : Symbol(Function.bind, Decl(lib.es5.d.ts, --, --))
>obj : Symbol(obj, Decl(thisTypeOptionalCall.ts, 0, 42))
}
16 changes: 16 additions & 0 deletions tests/baselines/reference/thisTypeOptionalCall.types
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
=== tests/cases/conformance/types/thisType/thisTypeOptionalCall.ts ===
function maybeBind<T, A extends any[], R>(obj: T, fn: ((this: T, ...args: A) => R) | undefined): ((...args: A) => R) | undefined {
>maybeBind : <T, A extends any[], R>(obj: T, fn: ((this: T, ...args: A) => R) | undefined) => ((...args: A) => R) | undefined
>obj : T
>fn : ((this: T, ...args: A) => R) | undefined
>this : T
>args : A
>args : A

return fn?.bind(obj);
>fn?.bind(obj) : any
>fn?.bind : ((this: Function, thisArg: any, ...argArray: any[]) => any) | undefined
>fn : ((this: T, ...args: A) => R) | undefined
>bind : ((this: Function, thisArg: any, ...argArray: any[]) => any) | undefined
>obj : T
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// @strictNullChecks: true
// @noImplicitAny: true
// @noImplicitThis: true
// @strictBindCallApply: false

function maybeBind<T, A extends any[], R>(obj: T, fn: ((this: T, ...args: A) => R) | undefined): ((...args: A) => R) | undefined {
return fn?.bind(obj);
}