Skip to content

Commit

Permalink
feat: Dealing with empty arrays and empty tuple types #4
Browse files Browse the repository at this point in the history
  • Loading branch information
kakasoo committed Jan 26, 2025
1 parent 6f95218 commit 45ce3a8
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 5 deletions.
1 change: 0 additions & 1 deletion src/functions/DeepStrictObjectKeys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ export function deepStrictObjectKeys<
new Set(
Object.entries(target).flatMap(([key, value]) => {
if (target instanceof Array) {
console.log('value: ', value);
return deepStrictObjectKeys(value, joiner).map((el) => `${joiner.array}.${el}`);
} else if (target !== null && typeof target === 'object') {
return deepStrictObjectKeys(value, joiner).flatMap((el) => `${joiner.object}.${el}`);
Expand Down
10 changes: 6 additions & 4 deletions src/types/DeepStrictObjectKeys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ import type { IsAny } from './IsAny';
import type { IsUnion } from './IsUnion';
import type { ValueType } from './ValueType';

type a = DeepStrictObjectKeys.Infer<{ a: Date }>;

namespace DeepStrictObjectKeys {
export type Infer<
Target extends object,
Expand Down Expand Up @@ -69,5 +67,9 @@ export type DeepStrictObjectKeys<
DeepStrictUnbrand<Target> extends Array<infer Element>
? Element extends object
? `${Joiner['array']}.${DeepStrictObjectKeys<Element, Joiner, IsSafe>}`
: `${Joiner['array']}.${keyof Element extends string ? keyof Element : never}`
: DeepStrictObjectKeys.Infer<DeepStrictUnbrand<Target>, Joiner, IsSafe>;
: `${Joiner['array']}`
: DeepStrictUnbrand<Target> extends readonly (infer Element)[] // TODO: support tuple types
? Element extends object
? `${Joiner['array']}.${DeepStrictObjectKeys<Element, Joiner, IsSafe>}`
: `${Joiner['array']}`
: DeepStrictObjectKeys.Infer<DeepStrictUnbrand<Target>, Joiner, IsSafe>;
84 changes: 84 additions & 0 deletions test/types/DeepStrictObjectKeys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,34 @@ import test, { describe } from 'node:test';
import typia, { tags } from 'typia';
import { DeepStrictObjectKeys, Equal } from '../../src';

describe('empty array', () => {
test('normal: isNotSafe', () => {
type Question = DeepStrictObjectKeys<
[],
{
array: '[*]';
object: '.';
},
false
>;
type Answer = Equal<Question, never>;
ok(typia.random<Answer>());
});

test('normal: isNotSafe', () => {
type Question = DeepStrictObjectKeys<
[],
{
array: '[*]';
object: '.';
},
true
>;
type Answer = Equal<Question, never>;
ok(typia.random<Answer>());
});
});

describe('Date props', () => {
test('normal: isNotSafe', () => {
type Question = DeepStrictObjectKeys<
Expand Down Expand Up @@ -578,3 +606,59 @@ describe('a key in a two-dimensional array', () => {
ok(typia.random<Answer>());
});
});

describe('readonly empty array. (tuple)', () => {
test('normal: isNotSafe', () => {
type Question = DeepStrictObjectKeys<
readonly [],
{
array: '[*]';
object: '.';
},
false
>;
type Answer = Equal<Question, never>;
ok(typia.random<Answer>());
});

test('normal: isSafe', () => {
type Question = DeepStrictObjectKeys<
readonly [],
{
array: '[*]';
object: '.';
},
true
>;
type Answer = Equal<Question, never>;
ok(typia.random<Answer>());
});
});

describe('readonly not empty array. (tuple)', () => {
test('normal: isNotSafe', () => {
type Question = DeepStrictObjectKeys<
readonly [1],
{
array: '[*]';
object: '.';
},
false
>;
type Answer = Equal<Question, '[*]'>;
ok(typia.random<Answer>());
});

test('normal: isSafe', () => {
type Question = DeepStrictObjectKeys<
readonly [1],
{
array: '[*]';
object: '.';
},
true
>;
type Answer = Equal<Question, '[*]'>;
ok(typia.random<Answer>());
});
});

0 comments on commit 45ce3a8

Please sign in to comment.