Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ThisParameterType always unknown when strictFunctionTypes is disabled #32964

Closed
fatcerberus opened this issue Aug 18, 2019 · 4 comments · Fixed by #36013
Closed

ThisParameterType always unknown when strictFunctionTypes is disabled #32964

fatcerberus opened this issue Aug 18, 2019 · 4 comments · Fixed by #36013
Assignees

Comments

@fatcerberus
Copy link

@fatcerberus fatcerberus commented Aug 18, 2019

TypeScript Version: 3.5.1

Search Terms: thisparametertype unknown

Code

interface Foo { blub: string };
function fn(this: Foo) {}

// with strictFunctionTypes ENABLED, this evaluates to Foo.
// with strictFunctionTypes DISABLED, it evaluates to unknown.
type Test = ThisParameterType<typeof fn>; 

Expected behavior:
ThisParameterType<typeof fn> should be Foo, regardless of strictFunctionTypes setting.

Actual behavior:
ThisParameterType<> evaluates to unknown, always, when strictFunctionTypes is disabled.

Playground Link:
https://www.typescriptlang.org/play/#code/JYOwLgpgTgZghgYwgAgGIHt3IN7IEYA2ArngFzIDOYUoA5sgL4DcAUDESAmMOiMjCAAUYABbAK5DOgCUOBixYB6RcgDuwUZWrAuqDlx4gAKgE8ADhArIAogDkAggCEAMtYAiAGmSjxyCADc4YjhIKzAsKQA6JRV1TSoaXX1uXlMLKzcASQBlJ1dPZA0-QODQ7ywOAGsQdFUQaLBzFCNLMGQAXmQjMQoABTgoOABbCEgoNIgAHkaLdBh+EAA+JmQWIA

Related Issues:
404: related issue not found

@fatcerberus

This comment has been minimized.

Copy link
Author

@fatcerberus fatcerberus commented Aug 18, 2019

Thanks to @webstrand, the definition of ThisParameterType:

type ThisParameterType<T> = 
    T extends (this: unknown, ...args: any[]) => any 
        ? unknown 
        : T extends (this: infer U, ...args: any[]) => any 
            ? U
            : unknown;

The first conditional seems to be checking for functions without a this binding, but because function types are bivariant by default, this catches all functions and defaults to unknown. The correct behavior of this type requires strict contravariance, i.e. --strictFunctionTypes.

@jack-williams

This comment has been minimized.

Copy link
Collaborator

@jack-williams jack-williams commented Aug 19, 2019

What goes wrong if you delete the first conditional?

@fatcerberus

This comment has been minimized.

Copy link
Author

@fatcerberus fatcerberus commented Aug 20, 2019

Seems to work fine: 🏈 Playground link

I was a bit baffled myself why it's implemented as a two-level conditional like this when both Parameters and ReturnType are only one level.

@ahejlsberg

This comment has been minimized.

Copy link
Member

@ahejlsberg ahejlsberg commented Jan 3, 2020

ThisParameterType was written as a two-level conditional in an earlier time when the default inference for type parameters was any. We've since changed the default inference to unknown, so we can and should simplify the type. Particularly seeing as it doesn't work in its current form with --strictFunctionTypes disabled.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
4 participants
You can’t perform that action at this time.