Skip to content

Commit

Permalink
feat(DotPath): 支持数组
Browse files Browse the repository at this point in the history
  • Loading branch information
fjc0k committed Aug 7, 2023
1 parent 9d07028 commit fffd59c
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 4 deletions.
19 changes: 18 additions & 1 deletion src/types/DotPath.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { DotPath, DotPathValue } from './DotPath'
import { expectType } from '../dev'
import { DotPath, DotPathValue } from './DotPath'

describe('DotPath', () => {
test('表现正常', () => {
Expand All @@ -9,6 +9,14 @@ describe('DotPath', () => {
z: [0, '1'] as const,
哈哈: 1,
},
arr: [
{
id: 1,
},
{
id: 2,
},
],
},
}
// eslint-disable-next-line
Expand All @@ -24,5 +32,14 @@ describe('DotPath', () => {

const xyz哈哈 = get(obj, 'x.y.哈哈')
expectType<typeof xyz哈哈, number>()

const xyzArr = get(obj, 'x.arr')
expectType<typeof xyzArr, Array<{ id: number }>>()

const xyzArrItem = get(obj, 'x.arr.0')
expectType<typeof xyzArrItem, { id: number }>()

const xyzArrItemId = get(obj, 'x.arr.0.id')
expectType<typeof xyzArrItemId, number>()
})
})
17 changes: 14 additions & 3 deletions src/types/DotPath.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,31 @@
// ref: https://github.com/ahejlsberg/tsconf2020-demos/blob/master/template/main.ts#L108
type SubKeys<T, K extends string> = K extends keyof T
type SubKeys<T, K extends string | number> = K extends keyof T
? `${K}.${DotPath<T[K]>}`
: never

export type DotPath<T> = object extends T
? string
: T extends any[]
? '0' | SubKeys<T, 0>
: T extends readonly any[]
? Extract<keyof T, `${number}`> | SubKeys<T, Extract<keyof T, `${number}`>>
: T extends object
? Extract<keyof T, string> | SubKeys<T, Extract<keyof T, string>>
: never

export type DotPathValue<T, Path extends string> = Path extends keyof T
export type DotPathValue<T, Path extends string> = Path extends '0'
? // @ts-ignore
T[0]
: Path extends keyof T
? T[Path]
: Path extends `${infer K}.${infer R}`
? K extends keyof T
? K extends '0'
? DotPathValue<
// @ts-ignore
T[0],
R
>
: K extends keyof T
? DotPathValue<T[K], R>
: unknown
: unknown

0 comments on commit fffd59c

Please sign in to comment.