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

Narrowing breaking changes #7662

Closed
mhegazy opened this issue Mar 23, 2016 · 7 comments
Closed

Narrowing breaking changes #7662

mhegazy opened this issue Mar 23, 2016 · 7 comments

Comments

@mhegazy
Copy link

@mhegazy mhegazy commented Mar 23, 2016

This is a place holder for changes to the type narrowing behavior in TypeScript 2.0:

  • Generic type parameters are now narrowed
function g<T>(obj: T) {
    var t: T;
    if (obj instanceof RegExp) {
         t = obj; // RegExp is not assignable to T
    }
}

See the explanation by @Arnavion in #7719 (comment)

  • Type narrowing does not work for catprued variables in functions and class expressions
export class Class {
    constructor(public p) { }
}

var c: Class | string;
var x: Class;

if (c instanceof Class) {
    function inner() {
        x = c; // Error, type of c is not narrowed, c is Class | string
    }
    x = c; // OK, c is Class
}
@mhegazy mhegazy added this to the TypeScript 2.0 milestone Mar 23, 2016
@mhegazy mhegazy closed this Mar 23, 2016
@ivogabe
Copy link
Contributor

@ivogabe ivogabe commented Mar 24, 2016

In the first example obj should be narrowed to T & RegExp, that seems more correct. Is that doable?

@mhegazy
Copy link
Author

@mhegazy mhegazy commented Mar 24, 2016

narrowing makes the type more "specific", this seems like expanding the domain of the type.

@ivogabe
Copy link
Contributor

@ivogabe ivogabe commented Mar 24, 2016

I thought that "more specific than" means "subtype of". That would mean that narrowed types are always a subtype of their original type and also always assignable to the original type. RegExp is not a subtype of all possible types for T, since it is a type argument, but T & RegExp is a subtype of it. Or is there something that I missed?

@mhegazy
Copy link
Author

@mhegazy mhegazy commented May 13, 2016

Type parameter narrowing is tracked by #8563

@Strate
Copy link

@Strate Strate commented Jun 10, 2016

Can typescript track that variable isn't changed after bypassing to callback and keep that narrow inside callback?
i.e:

{
  let aOrB: A|B = getAOrB()
  if (isA(aOrB)) {
    performOperationA(() => aOrB /* is A here */)
  } else {
    performOperationB(() => aOrB /* is B here */)
  }
  // there is no write-aware operations on aOrB after this point,
  // seems that typescript may be able to catch this case and keep var narrow inside callbacks.
}
@mhegazy
Copy link
Author

@mhegazy mhegazy commented Jun 10, 2016

Can typescript track that variable isn't changed after bypassing to callback and keep that narrow inside callback?

it can be done, but that is not trivial amount of computing, and would impact compilation times for all projects.

@Arnavion
Copy link
Contributor

@Arnavion Arnavion commented Jun 10, 2016

@Strate In that case you can yourself use const instead of let and get that behavior.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
4 participants
You can’t perform that action at this time.