Skip to content

Reducing union types when inferring type parameters in function invocations #4115

Closed

Description

Spec 3.4 says:

Union types are reduced to the smallest possible set of constituent types using these rules

But in compiler they are not reduced in case of inferring type parameters in function invocations. For example:

var o = {};

// According to spec, type of p should be reduced to {}
function f<T>(p: T | typeof o): T 
{
    var t: T;
    var temp = t || o; // here union type is reduced, and it is really {}
    return null;
}

// Another function where type of p is really {}. According to spec, it should be equal to f, shouldn't it?
function f2<T>(p: typeof o): T 
{
    return null;
}

// But really they are different
var e = f(5); // number
var e2 = f2(5); // {}

Could you please clarify, when union type are really reduced and when they are not.

Activity

  1. JsonFreeman commented on Aug 1, 2015

    @JsonFreeman
    Contributor

    I imagine you are using the latest from master. Constituents in a union type are no longer reduced, at least not by the subtype relation. I believe this change is reflected in spec update #4033.

  2. JsonFreeman commented on Aug 1, 2015

    @JsonFreeman
    Contributor

    And the code change for removing subtype reduction is #3823.

  3. ahejlsberg commented on Aug 1, 2015

    @ahejlsberg
    Member

    Union types are reduced to the smallest possible set of constituent types using these rules

    That paragraph has been removed from the spec.

    I have yet to add a description of the new deduplication algorithm, but basically a type S is considered a duplicate of a type T if:

    • S and T are identical,
    • S is undefined,
    • S is null and T is not undefined,
    • S is an object literal type, T is an object type, and S has a property set that is a duplicate of T's,
    • S and T are array types, and S has an element type that is a duplicate of T's.
    • S and T are tuple types, and S has element types that are duplicates of T's.

    In other words, we get rid of types that are identical to other types in the set, except they may have nulls or undefineds where the other types don't.

    The implementation of this algorithm is in the removeDuplicateTypes function in checker.ts.

  4. osdm commented on Aug 2, 2015

    @osdm
    Author
  5. locked and limited conversation to collaborators on Jun 19, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    QuestionAn issue which isn't directly actionable in code

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions