UNPKG

idx

Version:

Utility function for traversing properties on objects and arrays.

94 lines (85 loc) 2.52 kB
/** * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ /** * DeepRequiredArray * Nested array condition handler */ interface DeepRequiredArray<T> extends Array<DeepRequired<NonNullable<T>>> {} /** * Return type of calling `idx()`. `idx` always returns an optional value * @template T Value can be null or undefined */ export type IDXOptional<T> = T | null | undefined; /** * DeepRequiredObject * Nested object condition handler */ type DeepRequiredObject<T extends object> = { [P in keyof T]-?: DeepRequired<NonNullable<T[P]>>; }; /** * Function that has deeply required return type */ type FunctionWithRequiredReturnType< T extends (...args: any[]) => any > = T extends (...args: infer A) => infer R ? (...args: A) => DeepRequired<R> : never; /** * DeepRequired * Required that works for deeply nested structure */ type DeepRequired<T> = T extends any[] ? DeepRequiredArray<T[number]> : T extends (...args: any[]) => any ? FunctionWithRequiredReturnType<T> : T extends object ? DeepRequiredObject<T> : NonNullable<T>; /** * UnboxDeepRequired * Unbox type wrapped with DeepRequired */ type UnboxDeepRequired<T> = T extends DeepRequired<infer R> ? R : T; /** * Traverses properties on objects and arrays. If an intermediate property is * either null or undefined, it is instead returned. The purpose of this method * is to simplify extracting properties from a chain of maybe-typed properties. * * Consider the following type: * * const props: { * user?: { * name: string, * friends?: Array<User>, * } * }; * * Getting to the friends of my first friend would resemble: * * props.user && * props.user.friends && * props.user.friends[0] && * props.user.friends[0].friends * * Instead, `idx` allows us to safely write: * * idx(props, _ => _.user.friends[0].friends) * * The second argument must be a function that returns one or more nested member * expressions. Any other expression has undefined behavior. * * @param prop - Parent object * @param accessor - Accessor function * @return the property accessed if accessor function could reach to property, * null or undefined otherwise */ declare function idx<T1, T2>( prop: T1, accessor: (prop: NonNullable<DeepRequired<T1>>) => T2, ): IDXOptional<UnboxDeepRequired<T2>>; export default idx;