Features
Support paths up to a depth of 40 (limited by TypeScript's recursion depth) by utilizing cyclic constraints to only lookup up
the next 3 (default) levels. This should
heavily improve performance and reduce the amount of generated types.
Fixes
Breaking Changes
In general the depth
limit of Path
is no longer the max depth, but instead a 'lookahead' depth. E.g. if you have a depth limit of 3,
and are currently (while typing) at a depth of 2, the paths for the next 3 levels will be shown in autocompletion. You can no longer
constrain the max depth of the path, but only the lookahead depth. If this is a problem for you, please open an issue.
Value of Array Member, Optional Properties and Union Types
In 1.0.0 you received the full type for nested unions.
type A = { a: number | { nested: string } }
type NestedType = PathValue<A, 'a.nested'> // string
This is incorrect behavior, because a
could also be a number and not an object with a nested
property. This is now fixed.
PathValue
was split into two different types:
GetPathValue
for reading valuesSetPathValue
for setting values
the resulting types differ when accessing values in an object or setting them.
type A = {
a: number | { nested: string }
b: Record<string, number>
c: string[]
d?: { nested: string }
}
type NestedType1 = GetPathValue<A, 'a.nested'> // string | undefined
type NestedType2 = GetPathValue<A, 'b.key'> // number | undefined
type NestedType3 = GetPathValue<A, 'c.5'> // string | undefined
type NestedType4 = GetPathValue<A, 'd.nested'> // string | undefined
type NestedType5 = SetPathValue<A, 'a.nested', string> // string
type NestedType6 = SetPathValue<A, 'b.key', number> // number
type NestedType7 = SetPathValue<A, 'c.5', string> // string
type NestedType8 = SetPathValue<A, 'd.nested', string> // string
These type are used by their respective functions getByPath
and setByPath
and should more accurately represent the types of accessed values but can potentially break old code.
Custom Implementation
Implementation of custom getByPath
and setByPath
functions need to be updated for the new types.
If you implemented them to change the depth limit you might not need them anymore, as the (max) depth is now 40 (limited by TypeScript's recursion limit).
You still want to keep them, if you want to change the shown paths in autocompletion or have other use cases.
You only need to change the typing.
Old:
function getByPathDepth5<T extends SearchableObject, P extends Path<T, 5> & string>(
object: T,
path: P,
): PathValue<T, P, 5> {
return getByPath(object, path) as PathValue<T, P, 5>
}
function setByPathDepth5<
T extends SearchableObject,
P extends Path<T, 5> & string,
V extends PathValue<T, P, 5>,
>(object: T, path: P, value: V): void {
setByPath(object, path, value as PathValue<T, P>)
}
New:
function getByPathDepth5<T extends SearchableObject, P extends Path<T, P, { depth: 5 }> & string>(
object: T,
path: P,
): GetPathValue<T, P> {
return getByPath(object, path) as GetPathValue<T, P>
}
function setByPathDepth5<
T extends SearchableObject,
P extends Path<T, P, { onlyWriteable: true; depth: 5 }> & string,
>(object: T, path: P, value: SetPathValue<T, P>): void {
setByPath(object, path, value as SetPathValue<T, P>)
}
Full Changelog: 1.0.6...2.0.0