Skip to content

Commit 35da6f7

Browse files
authored
Paths: Add more test cases for generic types (#1370)
1 parent 6af847a commit 35da6f7

File tree

1 file changed

+50
-6
lines changed

1 file changed

+50
-6
lines changed

test-d/paths.ts

Lines changed: 50 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -526,13 +526,57 @@ declare const indexSignatureDepthLeaves: Paths<{a: {[x: string]: {b: string; c:
526526
expectType<`a.${string}.b` | `a.${string}.c` | 'd'>(indexSignatureDepthLeaves);
527527

528528
// Generic types
529-
type SomeTypeWithConstraint<T, _U extends Paths<T>> = never;
529+
type PathsConstraint<T, _U extends Paths<T>> = never;
530530

531-
type Foo<T> = {bar: {baz: T}};
532-
type Test1<T> = SomeTypeWithConstraint<Foo<T>, 'bar.baz'>;
531+
type Generic1<T> = {bar: {baz: T}};
532+
type Test1<T> = PathsConstraint<Generic1<T>, 'bar.baz'>;
533533

534-
type Bar<T, U> = {bar: {baz: {qux: T}; fizz: {buzz: U} | U | T}};
535-
type Test2<T, U> = SomeTypeWithConstraint<
536-
Bar<T, U>,
534+
type Generic2<T, U> = {bar: {baz: {qux: T}; fizz: {buzz: U} | U | T}};
535+
type Test2<T, U> = PathsConstraint<
536+
Generic2<T, U>,
537537
'bar' | 'bar.baz' | 'bar.baz.qux' | 'bar.fizz' | 'bar.fizz.buzz'
538538
>;
539+
540+
type LeavesOnlyPathsConstraint<T, _U extends Paths<T, {leavesOnly: true}>> = never;
541+
542+
type Generic3<T> = {bar: {baz: T; qux: string}};
543+
type Test3<T> = LeavesOnlyPathsConstraint<Generic3<T>, 'bar.qux'>;
544+
// @ts-expect-error
545+
type Test4<T> = LeavesOnlyPathsConstraint<Generic3<T>, 'bar'>; // 'bar' is not a leaf
546+
// @ts-expect-error
547+
type Test5<T> = LeavesOnlyPathsConstraint<Generic3<T>, 'bar.baz'>; // 'bar.baz' is not a leaf, because `T` is not known.
548+
549+
type DepthPathsConstraint<T, _U extends Paths<T, {depth: 1}>> = never;
550+
551+
type Generic4<T> = {bar: {baz: T}; qux: [T]};
552+
type Test6<T> = DepthPathsConstraint<Generic4<T>, 'bar.baz' | 'qux.0'>;
553+
// @ts-expect-error
554+
type Test7<T> = DepthPathsConstraint<Generic4<T>, 'bar'>; // 'bar' is not at depth `1`
555+
// @ts-expect-error
556+
type Test8<T> = DepthPathsConstraint<Generic4<T>, 'qux'>; // 'qux' is not at depth `1`
557+
558+
type BracketNotationPathsConstraint<T, _U extends Paths<T, {bracketNotation: true}>> = never;
559+
560+
type Generic5<T> = {1: {2: T}; 3: [T]};
561+
type Test9<T> = BracketNotationPathsConstraint<Generic5<T>, '[1]' | '[1][2]' | '[3]' | '[3][0]'>;
562+
563+
type MaxRecursionDepthPathsConstraint<T, _U extends Paths<T, {maxRecursionDepth: 2}>> = never;
564+
565+
type Generic6<T> = {foo: {bar: T}; baz: T; fizz: {buzz: {qux: {quxx: T}}}};
566+
type Test10<T> = MaxRecursionDepthPathsConstraint<
567+
Generic6<T>,
568+
'foo' | 'foo.bar' | 'baz' | 'fizz' | 'fizz.buzz' | 'fizz.buzz.qux'
569+
>;
570+
// @ts-expect-error
571+
type Test11<T> = MaxRecursionDepthPathsConstraint<Generic6<T>, 'fizz.buzz.qux.quxx'>; // 'fizz.buzz.qux.quxx' is at depth `3`
572+
573+
type LeavesOnlyAndDepthPathsConstraint<T, _U extends Paths<T, {leavesOnly: true; depth: 1}>> = never;
574+
575+
type Generic7<T> = {foo: {bar: T; baz: string; fizz: {buzz: number}}; qux: string};
576+
type Test12<T> = LeavesOnlyAndDepthPathsConstraint<Generic7<T>, 'foo.baz'>;
577+
// @ts-expect-error
578+
type Test13<T> = LeavesOnlyAndDepthPathsConstraint<Generic7<T>, 'qux'>; // 'qux' is a leaf, but not at depth `1`.
579+
// @ts-expect-error
580+
type Test14<T> = LeavesOnlyAndDepthPathsConstraint<Generic7<T>, 'foo.fizz'>; // 'foo.fizz' is at depth `1`, but not a leaf.
581+
// @ts-expect-error
582+
type Test15<T> = LeavesOnlyAndDepthPathsConstraint<Generic7<T>, 'foo.bar'>; // 'foo.bar' is at depth `1`, but not a leaf because `T` is not known.

0 commit comments

Comments
 (0)