Skip to content

Instantly share code, notes, and snippets.

@VitorLuizC
Created November 28, 2021 07:02
Show Gist options
  • Save VitorLuizC/3e3e3c7dcef8aca8a34c593e25d6fea0 to your computer and use it in GitHub Desktop.
Save VitorLuizC/3e3e3c7dcef8aca8a34c593e25d6fea0 to your computer and use it in GitHub Desktop.
import type SplitPath from './Split.js';
import test from 'ava';
type Assert<TypeA, TypeB> = [TypeB] extends [TypeA] ? true : false;
test("returns 'never' for invalid paths", (context) => {
const assertions: true[] = [
true as Assert<SplitPath<''>, never>,
true as Assert<SplitPath<'.'>, never>,
true as Assert<SplitPath<'a.'>, never>,
true as Assert<SplitPath<'.b'>, never>,
true as Assert<SplitPath<'.[0]'>, never>,
true as Assert<SplitPath<'[0].'>, never>,
true as Assert<SplitPath<'[0].[0]'>, never>,
];
assertions.forEach((assertion) => context.true(assertion));
});
test('splits path into an array with its parts', (context) => {
const assertions: true[] = [
true as Assert<SplitPath<'[0]'>, ['[0]']>,
true as Assert<SplitPath<'a'>, ['a']>,
true as Assert<SplitPath<'a.b'>, ['a', 'b']>,
true as Assert<SplitPath<'[0].b'>, ['[0]', 'b']>,
true as Assert<SplitPath<'a[0].c'>, ['a', '[0]', 'c']>,
true as Assert<SplitPath<'[0].b[0]'>, ['[0]', 'b', '[0]']>,
true as Assert<SplitPath<'[0].b[0].d.e'>, ['[0]', 'b', '[0]', 'd', 'e']>,
];
assertions.forEach((assertion) => context.true(assertion));
});
type Position = `[${number}]`;
type SplitPathBeforePosition<PathBeforePosition extends string> =
PathBeforePosition extends '' ? readonly [] : SplitPath<PathBeforePosition>;
type SplitPathAfterPosition<PathAfterPosition extends string> =
PathAfterPosition extends ''
? readonly []
: PathAfterPosition extends `.${infer PathAfterPositionAndDot}`
? SplitPath<PathAfterPositionAndDot>
: SplitPath<PathAfterPosition>;
type SplitPathWithPosition<
PathBeforePosition extends string,
PathAfterPosition extends string,
> = readonly [
...SplitPathBeforePosition<PathBeforePosition>,
Position,
...SplitPathAfterPosition<PathAfterPosition>
];
type SplitPath<Path extends string> = Path extends '' | '.'
? never
: Path extends `${infer P}${Position}${infer P2}`
? SplitPathWithPosition<P, P2>
: Path extends `${infer Key}.${infer PathAfterDot}`
? readonly [Key, ...SplitPath<PathAfterDot>]
: readonly [Path];
export default SplitPath;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment