demo/typescript.js
function getUnionType(types, noSubtypeReduction) {
            if (types.length === 0) {
                return emptyObjectType;
            }
            var typeSet = [];
            addTypesToSet(typeSet, types, 16384 /* Union */);
            if (containsTypeAny(typeSet)) {
                return anyType;
            }
            if (noSubtypeReduction) {
                removeAllButLast(typeSet, undefinedType);
                removeAllButLast(typeSet, nullType);
            }
            else {
                removeSubtypes(typeSet);
            }
            if (typeSet.length === 1) {
                return typeSet[0];
            }
            var id = getTypeListId(typeSet);
            var type = unionTypes[id];
            if (!type) {
                type = unionTypes[id] = createObjectType(16384 /* Union */ | getPropagatingFlagsOfTypes(typeSet));
                type.types = typeSet;
            }
            return type;
        }
function getUnionType(types, noSubtypeReduction) {
            if (types.length === 0) {
                return emptyObjectType;
            }
            var typeSet = [];
            addTypesToSet(typeSet, types, 16384 /* Union */);
            if (containsTypeAny(typeSet)) {
                return anyType;
            }
            if (noSubtypeReduction) {
                removeAllButLast(typeSet, undefinedType);
                removeAllButLast(typeSet, nullType);
            }
            else {
                removeSubtypes(typeSet);
            }
            if (typeSet.length === 1) {
                return typeSet[0];
            }
            var id = getTypeListId(typeSet);
            var type = unionTypes[id];
            if (!type) {
                type = unionTypes[id] = createObjectType(16384 /* Union */ | getPropagatingFlagsOfTypes(typeSet));
                type.types = typeSet;
            }
            return type;
        }
We reduce the constituent type set to only include types that aren't subtypes of other types, unless the noSubtypeReduction flag is specified, in which case we perform a simple deduplication based on object identity. Subtype reduction is possible only when union types are known not to circularly reference themselves (as is the case with union types created by expression constructs such as array literals and the || and ?: operators). Named types can circularly reference themselves and therefore cannot be deduplicated during their declaration. For example, "type Item = string | (() => Item" is a named type that circularly references itself.