diff --git a/src/type.ts b/src/type.ts index dfcb538..c70207c 100644 --- a/src/type.ts +++ b/src/type.ts @@ -1,3 +1,6 @@ +/** + * + */ // biome-ignore lint/complexity/noBannedTypes: export type DictionaryLeaf = string | number | boolean | {} | [] | Function | null | undefined | symbol | bigint @@ -12,10 +15,15 @@ type DictionaryArray = DictionaryValue[] | readonly DictionaryValue[] */ export type Dictionary = DictionaryObject | DictionaryArray -/** - * TODO: 深い階層のキーに対応する - */ -export type DeepKeyOf<_D extends Dictionary> = string +export type DeepKeyOf = FixArrayIndex, A> + +type DeepKeyOfInternal = { + [K in keyof D]: D[K] extends DictionaryLeaf | Dictionary + ? `${Exclude}${D[K] extends Dictionary ? `.${DeepKeyOfInternal}` : ''}` + : never +}[keyof D] + +type A = Exclude /** * @@ -54,6 +62,12 @@ export type Pick> = Dictionary */ export type ArrayIndex = 'dot' | 'bracket' +type FixBracket = T extends `${infer L}[${infer R}]` ? `${L}.${R}` : T + +type FixDot = T extends `${infer L}.${infer R}` ? `${L}[${R}]` : T + +type FixArrayIndex = A extends 'dot' ? FixDot : FixBracket + export interface CommonOption { /** * Specify the array index style. diff --git a/test/fold.spec-d.ts b/test/fold.spec-d.ts new file mode 100644 index 0000000..e69de29 diff --git a/test/type.spec-d.ts b/test/type.spec-d.ts new file mode 100644 index 0000000..c6a8c31 --- /dev/null +++ b/test/type.spec-d.ts @@ -0,0 +1,37 @@ +import { describe, it, assertType } from 'vitest' +import type { DeepKeyOf } from '../src/type' + +describe('DeepKeyOf', () => { + it('should returns nested object keys', () => { + type D = { + a: { + b: { + c: number + } + d: string + } + } + + assertType<'a.b.c' | 'a.d'>('' as DeepKeyOf) + }) + + it('should returns nested array keys', () => { + type D = { + a: { + b: [number, { c: string }] + } + } + + assertType<'a.b[0]' | 'a.b[1]c'>('' as DeepKeyOf) + }) + + it('should returns nested array keys (dot)', () => { + type D = { + a: { + b: [number, { c: string }] + } + } + + assertType<'a.b.0' | 'a.b.1.c'>('' as DeepKeyOf) + }) +})