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

Comments

Projects
None yet
4 participants
@mhegazy
Contributor

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

This comment has been minimized.

Show comment
Hide comment
@ivogabe

ivogabe Mar 24, 2016

Contributor

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

Contributor

ivogabe commented Mar 24, 2016

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

@mhegazy

This comment has been minimized.

Show comment
Hide comment
@mhegazy

mhegazy Mar 24, 2016

Contributor

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

Contributor

mhegazy commented Mar 24, 2016

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

@ivogabe

This comment has been minimized.

Show comment
Hide comment
@ivogabe

ivogabe Mar 24, 2016

Contributor

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?

Contributor

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

This comment has been minimized.

Show comment
Hide comment
@mhegazy

mhegazy May 13, 2016

Contributor

Type parameter narrowing is tracked by #8563

Contributor

mhegazy commented May 13, 2016

Type parameter narrowing is tracked by #8563

@Strate

This comment has been minimized.

Show comment
Hide comment
@Strate

Strate 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.
}

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

This comment has been minimized.

Show comment
Hide comment
@mhegazy

mhegazy Jun 10, 2016

Contributor

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.

Contributor

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

This comment has been minimized.

Show comment
Hide comment
@Arnavion

Arnavion Jun 10, 2016

Contributor

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

Contributor

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.