FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

Covariant checking for callback parameters by ahejlsberg · Pull Request #15104 · microsoft/TypeScript · GitHub

Covariant checking for callback parameters - #15104

Merged
Anders Hejlsberg (ahejlsberg) merged 9 commits into
masterfrom
covariantCallbacks
Apr 18, 2017
Merged

Covariant checking for callback parameters#15104
Anders Hejlsberg (ahejlsberg) merged 9 commits into
masterfrom
covariantCallbacks

Conversation

Anders Hejlsberg (ahejlsberg) commented Apr 10, 2017
edited
Loading

Copy link
Copy Markdown
Member

In order to ensure that any generic type Foo<T> is at least co-variant with respect to T no matter how Foo uses T, TypeScript relates parameters bi-variantly (given that parameters are input positions, they naturally relate only contra-variantly). However, when source and target parameters both have function types with a single call signature, we know we are relating two callback parameters. In that case it is sufficient to only relate the parameters of the signatures co-variantly because, similar to return values, callback parameters are output positions. With this PR we introduce that change. This means that a Promise<T> or Observable<T>, where T is used only in callback parameter positions, will be co-variant (as opposed to bi-variant) with respect to T, which solves a commonly reported issue.

This change finds several issues in our real world code suites that all appear to be legitimate inconsistencies.

Fixes #11022.
Fixes #14770.

Copy link
Copy Markdown
Member Author

Mohamed Hegazy (@mhegazy) Want to take a look?

Ashley Claymore (acutmore) commented May 5, 2017
edited
Loading

Copy link
Copy Markdown
Contributor

Shawn Talbert (@ShawnTalbert) If not clear. This PR does not introduce any new syntax. Instead changes type assignability of generics where the type is only user in a function parameter position e.g Promise / Observable

interface Box<T> {
   foo(cb: (t: T => void)): void;
}

Before:

declare const bA: Box<Animal>;
const bC: Box<Cat> = bA; // no error 😿 

After:

declare const bA: Box<Animal>;
const bC: Box<Cat> = bA; // error 😺 

Copy link
Copy Markdown

Yes, wrong issue, sorry

Copy link
Copy Markdown

It appears that the solution was amended to ignore union with null/undefined. Should that be dependent on --strictNullChecks? At the moment, this does not seem to address #13513.

Anders Hejlsberg (ahejlsberg) commented May 8, 2017
edited
Loading

Copy link
Copy Markdown
Member Author

Brian McBarron (@bmcbarron) #13513 is fixed by this PR in --strictNullChecks mode. Without --strictNullChecks, undefined is assignable to any type and is effectively ignored in union types, but that has always been the case and isn't going to change.

Adam Schroder (schotime) commented Aug 17, 2017
edited
Loading

Copy link
Copy Markdown

This doesn't fix this problem unfortunately and this is usually the case if the callbacks are stored in different files and imported.

class Animal {}
class Cat extends Animal {
    public meow() {}
}

let promise: Promise<Animal> = null;
promise.then((cat: Cat) => { //Should error here but does not
  cat.meow();
});

This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Breaking Change Would introduce errors in existing code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants


Back | FazBrowse Home | New Git URL