TypeScript Set and WeakMap

TypeScript inherits the Set and WeakMap data structures from JavaScript, providing more powerful type support.

These data structures are very useful in scenarios such as handling unique value sets, key-value pair mappings, and caching.


SVG Diagram: Set and Map Data Structures Background Title Set and Map Data Structures Set A collection of values Values are unique and non-repeating Iterable add/has/delete WeakSet Weak references to objects Does not affect GC Not iterable add/has/delete Map A collection of key-value pairs Keys can be of any type Iterable set/get/has WeakMap Weak references to keys Keys must be objects Does not affect GC Not iterable Bottom section: Application Scenarios Application Scenarios Scenario Set: Deduplication, unique value sets Map: Key-value mapping, caching WeakMap/WeakSet: Memory optimization Arrow markers

Why Do You Need Set and WeakMap

In development, we often need to handle unique value sets and key-value pair mappings.

Set provides automatic deduplication for collections, making it more convenient than arrays for handling unique values.

WeakSet and WeakMap use weak references and do not prevent garbage collection, making them suitable for scenarios that need to avoid memory leaks, such as caching DOM nodes.

Concept Explanation:Set is a collection of values, with unique values; Map is a collection of key-value pairs, where keys can be of any type. WeakSet and WeakMap use weak references and do not affect garbage collection.


Set

Set is a collection of values; values are unique and duplicates are not allowed.

Example

// Create a Set, specifying the element type as number
var numbers = new Set<number>();

// Add elements
numbers.add(1);
numbers.add(2);
numbers.add(3);
numbers.add(1); // Duplicate values will be ignored and not added

// Check size and containment
console.log("Set size: " + numbers.size);
console.log("Contains 2: " + numbers.has(2));

// Iterate over the Set
numbers.forEach(function(value) {
    console.log("Value: " + value);
});

// Convert to array
var arr = Array.from(numbers);
console.log("Converted to array: " + arr);

Output:

Set 大小: 3
是否包含 2: true
值: 1
值: 2
值: 3
转换为数组: 1,2,3

Deduplication:Set automatically ignores duplicate values, making it very suitable for array deduplication.


Set Type Annotation

You can explicitly specify the type of values in a Set.

Example

// String Set
// Only string type values can be added
var stringSet: Set<string> = new Set();
stringSet.add("a");
stringSet.add("b");

// Object Set
// Define the Person interface
interface Person {
    name: string;
}
// Create a Set that stores Person objects
var personSet: Set<Person> = new Set();
personSet.add({ name: "Alice" });
personSet.add({ name: "Bob" });

console.log("String Set: " + Array.from(stringSet));
console.log("Object Set size: " + personSet.size);

Generics:Use theSet<T>syntax to specify the type of elements in a Set.


WeakSet

WeakSet stores object references, and the references are weak references (they do not affect garbage collection).

Example

// WeakSet can only store objects, not primitive values
var weakSet = new WeakSet();

// Create objects
var obj1 = { name: "Alice" };
var obj2 = { name: "Bob" };

// Add objects to WeakSet
weakSet.add(obj1);
weakSet.add(obj2);

// Check if it contains
console.log("Contains obj1: " + weakSet.has(obj1));

// After removing references, the object may be garbage collected
weakSet.delete(obj1);
console.log("Contains obj1 after deletion: " + weakSet.has(obj1));

Note:WeakSet cannot be iterated, and the type annotation can only beobject. This makes WeakSet suitable for storing objects that need to be garbage collected.


Map

Map is a collection of key-value pairs, where keys can be of any type.

Example

// Create a Map with key type string and value type number
var map = new Map<string, number>();

// Set key-value pairs
map.set("one", 1);
map.set("two", 2);
map.set("three", 3);

// Get values
console.log("Get two: " + map.get("two"));
console.log("Map size: " + map.size);
console.log("Contains three: " + map.has("three"));

// Iterate over the Map
map.forEach(function(value, key) {
    console.log(key + ": " + value);
});

// Convert to array
console.log("Converted to array: " + Array.from(map.entries()));

Output:

获取 two: 2
Map 大小: 3
是否包含 three: true
one: 1
two: 2
three: 3
转换为数组: one,1,two,2,three,3

Advantages:Map keys can be of any type (objects, functions, etc.), which is more flexible than using objects as keys.


WeakMap

WeakMap keys are weak references and do not affect garbage collection.

Example

// WeakMap keys must be objects
// Key type is object, value type is string
var weakMap = new WeakMap<object, string>();

// Create an object as a key
var keyObj = { id: 1 };
// Set key-value pairs
weakMap.set(keyObj, "value1");

// Get the value
console.log("Get value: " + weakMap.get(keyObj));
console.log("Contains: " + weakMap.has(keyObj));

// Delete key-value pair
weakMap.delete(keyObj);
console.log("After deletion: " + weakMap.has(keyObj));

Application Scenarios:WeakMap is commonly used to cache DOM node data. When a DOM node is removed, the cached data is automatically cleaned up, avoiding memory leaks.


Practical Application Scenarios

Use Map to count the occurrences of array elements.

Example

// Use Map to count the occurrences of each element in an array
function countElements(arr: string[]): Map<string, number> {
    // Create a Map with string keys and number values
    var counts = new Map<string, number>();

    // Iterate over the array
    for (var _i = 0, arr_1 = arr; _i < arr_1.length; _i++) {
        var item = arr_1[_i];
        // Get the current count, or return 0 if it doesn't exist
        var currentCount = counts.get(item) || 0;
        // Update the count
        counts.set(item, currentCount + 1);
    }

    return counts;
}

// Test
var fruits = ["apple", "banana", "apple", "orange", "banana", "apple"];
var result = countElements(fruits);

// Iterate over the results
result.forEach(function(count, fruit) {
    console.log(fruit + ": " + count);
});

Output:

apple: 3
banana: 2
orange: 1

Practical:Map is an ideal choice for implementing caching, statistics, indexing, and other features.


Notes

  • Set uniqueness:Set automatically ignores duplicate values
  • WeakSet/WeakMap:Keys must be objects and cannot be iterated
  • Map key types:Map keys can be of any type
  • Memory management:WeakSet/WeakMap do not prevent garbage collection

Selection recommendations:Use Set for unique value collections, Map for key-value mappings, and WeakSet/WeakMap when you need to avoid memory leaks.


Summary

Set and Map are very useful data structures in TypeScript.

  • Set:A collection of values; values are unique with automatic deduplication
  • WeakSet:A collection of weak object references; not iterable; suitable for scenarios that require garbage collection
  • Map:A collection of key-value pairs; keys can be of any type
  • WeakMap:Keys use weak references; not iterable; suitable for caching and private data

Recommendation:Choose the appropriate data structure based on specific needs: use Set for deduplication, Map for mappings, and the Weak versions for memory optimization.

Other Extensions