demo/typescript.js
function getIntersectionType(types) {
            if (types.length === 0) {
                return emptyObjectType;
            }
            var typeSet = [];
            addTypesToSet(typeSet, types, 32768 /* Intersection */);
            if (containsTypeAny(typeSet)) {
                return anyType;
            }
            if (typeSet.length === 1) {
                return typeSet[0];
            }
            var id = getTypeListId(typeSet);
            var type = intersectionTypes[id];
            if (!type) {
                type = intersectionTypes[id] = createObjectType(32768 /* Intersection */ | getPropagatingFlagsOfTypes(typeSet));
                type.types = typeSet;
            }
            return type;
        }
function getIntersectionType(types) {
            if (types.length === 0) {
                return emptyObjectType;
            }
            var typeSet = [];
            addTypesToSet(typeSet, types, 32768 /* Intersection */);
            if (containsTypeAny(typeSet)) {
                return anyType;
            }
            if (typeSet.length === 1) {
                return typeSet[0];
            }
            var id = getTypeListId(typeSet);
            var type = intersectionTypes[id];
            if (!type) {
                type = intersectionTypes[id] = createObjectType(32768 /* Intersection */ | getPropagatingFlagsOfTypes(typeSet));
                type.types = typeSet;
            }
            return type;
        }
We do not perform structural deduplication on intersection types. Intersection types are created only by the & type operator and we can't reduce those because we want to support recursive intersection types. For example, a type alias of the form "type List<T> = T & { next: List<T> }" cannot be reduced during its declaration. Also, unlike union types, the order of the constituent types is preserved in order that overload resolution for intersections of types with signatures can be deterministic.