Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Get type #153

Merged
merged 30 commits into from Feb 12, 2021
Merged

Add Get type #153

merged 30 commits into from Feb 12, 2021

Conversation

mmkal
Copy link
Contributor

@mmkal mmkal commented Nov 25, 2020

Gets a deeply-nested property from an object, like lodash's get function.

Use-case: retrieve a property from deep inside an API response or other complex object.

I couldn't find anything like this, so thought I'd put up a proposal since I've written shoddy versions of it a few times now.

import { Get } from 'type-fest'

interface ApiResponse {
  hits: {
    hits: Array<{
      _id: string
      _source: {
        name: Array<{
          given: string[]
          family: string
        }>
        birthDate: string
      }
    }>
  }
}
type Name = Get<ApiResponse, 'hits.hits[0]._source.name'> // Array<{ given: string[]; family: string }>

This works by first splitting the path based on . and [...] characters into a tuple of string keys.
Then it recursively uses the head key to get the next property of the current object, until there are no keys
left. Number keys extract the item type from arrays, or are converted to strings to extract types from tuples
and dictionaries with number keys.

Todo:

  • propagate nullable props
  • add tests for nullable props (likely not blocked by Run tsd in test script #162 but I don't think tests are being run by CI properly right now so maybe)
  • make bad paths return unknown, not undefined
  • add test for readonly props/arrays
  • rename Numbers to StringDigit or similar

Follow-ups:

  • Extract KeyPath type like in Add KeyPath and PathValue types #158
  • Set type - Set<{ foo: number }, 'bar.baz', string> = { foo: number; bar: { baz: string } }
  • (maybe) support foo\\.bar.baz to allow for dots within keys, similar to dot-prop.

Fixes #147

source/split.d.ts Outdated Show resolved Hide resolved
test-d/get.ts Outdated Show resolved Hide resolved
ts41/get.d.ts Outdated Show resolved Hide resolved
ts41/split.d.ts Outdated Show resolved Hide resolved
ts41/get.d.ts Outdated Show resolved Hide resolved
ts41/get.d.ts Outdated Show resolved Hide resolved
ts41/get.d.ts Outdated Show resolved Hide resolved
ts41/get.d.ts Outdated Show resolved Hide resolved
test-d/get.ts Outdated Show resolved Hide resolved
ts41/get.d.ts Outdated Show resolved Hide resolved
ts41/get.d.ts Outdated Show resolved Hide resolved
readme.md Outdated Show resolved Hide resolved
ts41/get.d.ts Outdated Show resolved Hide resolved
@sindresorhus sindresorhus changed the title Deep property get Add Get type Nov 26, 2020
@sindresorhus
Copy link
Owner

@mmkal
Copy link
Contributor Author

mmkal commented Nov 26, 2020

@sindresorhus thanks for reviewing, have updated based on comments. One note - in the latest revision I changed the nevers to undefineds since that's the standard behaviour - never would imply "throwing"

get({ foo: 'bar' }, 'some.nonsense.string') // returns undefined, rather than throws

Edit: hadn't seen the issue/playground - will take a look and see if there are any simplifications/improvements to be made.

source/utilities.d.ts Outdated Show resolved Hide resolved
test-d/get.ts Outdated Show resolved Hide resolved
test-d/get.ts Outdated Show resolved Hide resolved
ts41/get.d.ts Show resolved Hide resolved
ts41/get.d.ts Outdated Show resolved Hide resolved
ts41/get.d.ts Outdated Show resolved Hide resolved
ts41/get.d.ts Outdated Show resolved Hide resolved
ts41/get.d.ts Show resolved Hide resolved
@sindresorhus
Copy link
Owner

sindresorhus commented Nov 27, 2020

ts41/get.d.ts Outdated Show resolved Hide resolved
ts41/utilities.d.ts Show resolved Hide resolved
source/utilities.d.ts Outdated Show resolved Hide resolved
@voxpelli voxpelli self-requested a review December 7, 2020 13:30
package.json Outdated Show resolved Hide resolved
ts41/get.d.ts Outdated Show resolved Hide resolved
@sindresorhus
Copy link
Owner

@mmkal This looks good to me when #153 (comment) is fixed.

@voxpelli LGTY?

@mmkal
Copy link
Contributor Author

mmkal commented Jan 1, 2021

Sounds good - will be able to work on it in a couple of days. Happy new year!

ts41/get.d.ts Outdated Show resolved Hide resolved
ts41/get.d.ts Outdated Show resolved Hide resolved
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Proposal: Key path type
4 participants