UNPKG

idx

Version:

Utility function for traversing properties on objects and arrays.

107 lines (91 loc) 2.76 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. */ import idx, {IDXOptional} from './idx'; /** * Test functions are not run in runtime. They are only type checked with * TypeScript compiler */ declare function it(description: string, test: () => void): void; interface Item<T = any> { t?: T; inner?: { item?: string; }; } interface MethodReturnType<T = any> { optional?: {member?: Item<T>}; } interface DeepStructure<T = any> { str?: string; undef?: undefined; null?: null; generic?: T; arr?: {inner?: string}[]; foo?: { bar?: { baz?: { arr?: Item<T>[]; }; }; }; requiredInner?: { inner: boolean; }; method?(): MethodReturnType<T>; args?(a: string, b: number, c?: boolean): Item<T>; requiredReturnType?(): {inner: number}; } let deep: DeepStructure = {}; it('can access deep properties without null type assertion', () => { let str: IDXOptional<string> = idx(deep, _ => _.str); let undef: undefined | null = idx(deep, _ => _.undef); let null_: undefined | null = idx(deep, _ => _.null); let arr: IDXOptional<Item[]> = idx(deep, _ => _.foo.bar.baz.arr); }); it('can call deep methods without null type assertion', () => { let member: IDXOptional<Item> = idx(deep, _ => _.method().optional.member); member = idx(deep, _ => _.args('', 1, true)); member = idx(deep, _ => _.args('', 1)); }); it('can tap into optional structures (array and objects)', () => { let str: IDXOptional<string> = idx( deep, _ => _.foo.bar.baz.arr[0].inner.item, ); }); it('returns optional object while maintaining the original type of the object structure', () => { let req = idx(deep, _ => _.requiredInner); if (req) { req.inner.valueOf(); // can safely call because inner is not optional } }); it('returns optional array while maintaining the original type of array item type', () => { // inner property type did not become `string | null | undefined` let arr: IDXOptional<Array<{inner?: string}>> = idx(deep, _ => _.arr); }); it('maintains the return type of method calls', () => { let req = idx(deep, _ => _.requiredReturnType()); if (req) { req.inner.toFixed(); // can safely call because inner is not optional } }); it('can unbox enums', () => { enum Enum { ONE = 'ONE', } type WithEnum = { foo?: { enum?: Enum; }; }; let e: IDXOptional<Enum> = idx({} as WithEnum, _ => _.foo.enum); }); it('can unbox function', () => { const returnValue = idx(deep, _ => _.method()); const control: MethodReturnType = {optional: {}}; const treatment: typeof returnValue = {optional: {}}; });