getDependenciesApi().has
1. Overview
- What it does: Checks if a dependency exists by name. Returns
true if the dependency is registered, false if not.
- When to use:
- For checking dependency existence before use
- For conditional logic based on dependency availability
- For avoiding
ReferenceError from getDependenciesApi().get()
2. Signature
import { getDependenciesApi } from "@real-router/core/api";
const depsApi = getDependenciesApi(router);
depsApi.has(name: keyof Dependencies): boolean
Usage Examples
import { getDependenciesApi } from "@real-router/core/api";
const depsApi = getDependenciesApi(router);
// Basic check
if (depsApi.has("analytics")) {
const analytics = depsApi.get("analytics");
analytics.trackEvent("Router started");
}
// Conditional initialization
if (!depsApi.has("cache")) {
depsApi.set("cache", new CacheService());
}
// Feature detection
const features = {
hasAnalytics: depsApi.has("analytics"),
hasDevTools: depsApi.has("devTools"),
hasCache: depsApi.has("cache"),
};
3. Parameters
name (required)
- Type:
keyof Dependencies
- Purpose: Name of dependency to check
- Allowed values: Any string (including empty, Unicode, emoji)
- On error:
TypeError if not a string
Behavior for Different Values
| Value |
Result |
| Existing key |
true |
| Non-existing key |
false |
Key with value 0 |
true |
Key with value null |
true |
Key with value false |
true |
"" (empty string) |
Valid key |
"用户" (Unicode) |
Valid key |
"🚀" (emoji) |
Valid key |
123 (number) |
TypeError |
null |
TypeError |
undefined |
TypeError |
4. Return Value
- Type:
boolean
true: Dependency exists (including falsy values: 0, null, false)
false: Dependency is not registered
Important: Falsy Values
has() returns true for any registered value, including falsy:
const depsApi = getDependenciesApi(router);
depsApi.set("count", 0);
depsApi.set("disabled", false);
depsApi.set("empty", null);
depsApi.has("count"); // true (value is 0)
depsApi.has("disabled"); // true (value is false)
depsApi.has("empty"); // true (value is null)
5. Possible Errors
| Condition |
Error Type |
Message |
name not string |
TypeError |
[router.hasDependency]: dependency name must be a string, got {type} |
Error Examples
const depsApi = getDependenciesApi(router);
// TypeError: not a string
depsApi.has(123);
// TypeError: [router.hasDependency]: dependency name must be a string, got number
depsApi.has(null);
// TypeError: [router.hasDependency]: dependency name must be a string, got object
depsApi.has(undefined);
// TypeError: [router.hasDependency]: dependency name must be a string, got undefined
6. Related Methods
Comparison with get
const depsApi = getDependenciesApi(router);
// get — throws ReferenceError
try {
const service = depsApi.get("maybeNotExist");
} catch (e) {
// Handle error
}
// has — safe check
if (depsApi.has("maybeNotExist")) {
const service = depsApi.get("maybeNotExist");
// Guaranteed no error
}
7. Behavior
Main Scenarios
- true for existing: Dependency is registered
- false for non-existing: Dependency not found
- true for falsy values: 0, null, false -- still exist
- Read-only: Does not check disposed state
- Works after dispose: Returns
false since deps were cleared
Test Examples
const depsApi = getDependenciesApi(router);
// true if exists
expect(depsApi.has("foo")).toBe(true);
// false if doesn't exist
expect(depsApi.has("nonexistent")).toBe(false);
// false after removal
depsApi.remove("foo");
expect(depsApi.has("foo")).toBe(false);
Falsy Values
const depsApi = getDependenciesApi(router);
// 0 -- exists
depsApi.set("foo", 0);
expect(depsApi.has("foo")).toBe(true);
// null -- exists
depsApi.set("bar", null);
expect(depsApi.has("bar")).toBe(true);
// false -- exists
depsApi.set("foo", false);
expect(depsApi.has("foo")).toBe(true);
Non-String Parameters
const depsApi = getDependenciesApi(router);
// Numbers throw TypeError
expect(() => depsApi.has(123)).toThrowError(TypeError);
// null throws TypeError
expect(() => depsApi.has(null)).toThrowError(TypeError);
// undefined throws TypeError
expect(() => depsApi.has(undefined)).toThrowError(TypeError);
Case Sensitivity
const depsApi = getDependenciesApi(router);
depsApi.set("API", api1);
depsApi.set("api", api2);
expect(depsApi.has("API")).toBe(true);
expect(depsApi.has("api")).toBe(true);
expect(depsApi.has("Api")).toBe(false); // Case-sensitive
Empty String
const depsApi = getDependenciesApi(router);
expect(depsApi.has("")).toBe(false);
depsApi.set("", "empty-key-value");
expect(depsApi.has("")).toBe(true);
Integration with Other Methods
const depsApi = getDependenciesApi(router);
// With set
expect(depsApi.has("bar")).toBe(false);
depsApi.set("bar", "new value");
expect(depsApi.has("bar")).toBe(true);
// With reset
depsApi.setAll({ foo: 1, bar: "value" });
expect(depsApi.has("foo")).toBe(true);
expect(depsApi.has("bar")).toBe(true);
depsApi.reset();
expect(depsApi.has("foo")).toBe(false);
expect(depsApi.has("bar")).toBe(false);
After Dispose
router.dispose();
const depsApi = getDependenciesApi(router);
// Read-only methods still work after dispose
expect(depsApi.has("foo")).toBe(false); // false since deps were cleared
expect(depsApi.getAll()).toStrictEqual({});
Unicode and Special Characters
const depsApi = getDependenciesApi(router);
depsApi.set("api:v2", "value");
expect(depsApi.has("api:v2")).toBe(true);
depsApi.set("用户", "user");
expect(depsApi.has("用户")).toBe(true);
depsApi.set("🚀", "rocket");
expect(depsApi.has("🚀")).toBe(true);
Edge Cases
- Empty string
"": Valid key
- Unicode and emoji: Supported
- Special characters:
"api:v2", "key.with.dots" -- work fine
- Case-sensitive:
"API" != "api"
- Non-strings:
TypeError (no type coercion)
- Falsy values:
0, null, false -- return true
Guarantees
- Always returns
boolean
- Throws
TypeError for non-string names
- Works with falsy values (0, null, false)
- Case-sensitive checking
- Unicode, emoji, special characters support
- Uses
Object.hasOwn() for prototype pollution protection
- Works after dispose (returns false)
8. Migration
Old API (removed)
router.hasDependency(name);
New API
import { getDependenciesApi } from "@real-router/core/api";
const depsApi = getDependenciesApi(router);
depsApi.has(name);
Migration Examples
// Old
if (router.hasDependency("analytics")) {
const analytics = router.getDependency("analytics");
analytics.trackEvent("started");
}
// New
const depsApi = getDependenciesApi(router);
if (depsApi.has("analytics")) {
const analytics = depsApi.get("analytics");
analytics.trackEvent("started");
}
| Aspect |
Old (router.hasDependency) |
New (getDependenciesApi(router).has) |
| Import |
None (method on router) |
import { getDependenciesApi } |
| Tree-shaking |
Always included |
Tree-shakeable |
| API style |
Facade method |
Standalone function |
| Behavior |
Identical |
Identical |