Skip to content

Commit 077a10b

Browse files
committed
OptionalType => Type
1 parent 35bbd6d commit 077a10b

File tree

3 files changed

+79
-93
lines changed

3 files changed

+79
-93
lines changed

src/helper/factory.ts

Lines changed: 28 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -4,87 +4,77 @@ import { ResolvedFields, FieldsResolver, resolveFields, FieldResolver } from './
44
import { getSequenceCounter, resetSequence } from './sequence.js';
55
import { Merge, StrictlyPick } from './util.js';
66

7-
export type Traits<OptionalType extends Record<string, unknown>, TransientFields extends Record<string, unknown>> = {
7+
export type Traits<Type extends Record<string, unknown>, TransientFields extends Record<string, unknown>> = {
88
[traitName: string]: {
9-
defaultFields: FieldsResolver<OptionalType & TransientFields>;
9+
defaultFields: FieldsResolver<Type & TransientFields>;
1010
};
1111
};
1212

1313
export interface TypeFactoryDefineOptions<
14-
OptionalType extends Record<string, unknown>,
14+
Type extends Record<string, unknown>,
1515
TransientFields extends Record<string, unknown>,
16-
_DefaultFieldsResolver extends FieldsResolver<OptionalType & TransientFields>,
17-
_Traits extends Traits<OptionalType, TransientFields>,
16+
_DefaultFieldsResolver extends FieldsResolver<Type & TransientFields>,
17+
_Traits extends Traits<Type, TransientFields>,
1818
> {
1919
defaultFields: _DefaultFieldsResolver;
2020
traits?: _Traits;
2121
}
2222

2323
export interface TypeFactoryInterface<
24-
OptionalType extends Record<string, unknown>,
24+
Type extends Record<string, unknown>,
2525
TransientFields extends Record<string, unknown>,
2626
// NOTE: The constraints of _DefaultFieldsResolver are loose so that `Merge<_DefaultFieldsResolver, _Traits[T]['defaultFields']>` is accepted.
27-
_DefaultFieldsResolver extends Partial<
28-
Record<keyof OptionalType, FieldResolver<OptionalType & TransientFields, unknown>>
29-
>,
30-
_Traits extends Traits<OptionalType, TransientFields>,
27+
_DefaultFieldsResolver extends Partial<Record<keyof Type, FieldResolver<Type & TransientFields, unknown>>>,
28+
_Traits extends Traits<Type, TransientFields>,
3129
> {
32-
build(): Promise<StrictlyPick<Merge<ResolvedFields<_DefaultFieldsResolver>, ResolvedFields<{}>>, keyof OptionalType>>;
33-
build<T extends FieldsResolver<OptionalType & TransientFields>>(
30+
build(): Promise<StrictlyPick<Merge<ResolvedFields<_DefaultFieldsResolver>, ResolvedFields<{}>>, keyof Type>>;
31+
build<T extends FieldsResolver<Type & TransientFields>>(
3432
inputFieldsResolver: T,
35-
): Promise<StrictlyPick<Merge<ResolvedFields<_DefaultFieldsResolver>, ResolvedFields<T>>, keyof OptionalType>>;
33+
): Promise<StrictlyPick<Merge<ResolvedFields<_DefaultFieldsResolver>, ResolvedFields<T>>, keyof Type>>;
3634
buildList(
3735
count: number,
38-
): Promise<StrictlyPick<Merge<ResolvedFields<_DefaultFieldsResolver>, ResolvedFields<{}>>, keyof OptionalType>[]>;
39-
buildList<T extends FieldsResolver<OptionalType & TransientFields>>(
36+
): Promise<StrictlyPick<Merge<ResolvedFields<_DefaultFieldsResolver>, ResolvedFields<{}>>, keyof Type>[]>;
37+
buildList<T extends FieldsResolver<Type & TransientFields>>(
4038
count: number,
4139
inputFieldsResolver: T,
42-
): Promise<StrictlyPick<Merge<ResolvedFields<_DefaultFieldsResolver>, ResolvedFields<T>>, keyof OptionalType>[]>;
40+
): Promise<StrictlyPick<Merge<ResolvedFields<_DefaultFieldsResolver>, ResolvedFields<T>>, keyof Type>[]>;
4341
use<T extends keyof _Traits>(
4442
traitName: T,
45-
): TypeFactoryInterface<
46-
OptionalType,
47-
TransientFields,
48-
Merge<_DefaultFieldsResolver, _Traits[T]['defaultFields']>,
49-
_Traits
50-
>;
43+
): TypeFactoryInterface<Type, TransientFields, Merge<_DefaultFieldsResolver, _Traits[T]['defaultFields']>, _Traits>;
5144
resetSequence(): void;
5245
}
5346

5447
export function defineTypeFactoryInternal<
55-
OptionalType extends Record<string, unknown>,
48+
Type extends Record<string, unknown>,
5649
TransientFields extends Record<string, unknown>,
57-
_DefaultFieldsResolver extends FieldsResolver<OptionalType & TransientFields>,
58-
_Traits extends Traits<OptionalType, TransientFields>,
50+
_DefaultFieldsResolver extends FieldsResolver<Type & TransientFields>,
51+
_Traits extends Traits<Type, TransientFields>,
5952
>(
60-
typeFieldNames: readonly (keyof OptionalType)[],
53+
typeFieldNames: readonly (keyof Type)[],
6154
{
6255
defaultFields: defaultFieldsResolver,
6356
traits,
64-
}: TypeFactoryDefineOptions<OptionalType, TransientFields, _DefaultFieldsResolver, _Traits>,
65-
): TypeFactoryInterface<OptionalType, TransientFields, _DefaultFieldsResolver, _Traits> {
57+
}: TypeFactoryDefineOptions<Type, TransientFields, _DefaultFieldsResolver, _Traits>,
58+
): TypeFactoryInterface<Type, TransientFields, _DefaultFieldsResolver, _Traits> {
6659
const seqKey = {};
6760
const getSeq = () => getSequenceCounter(seqKey);
6861
return {
69-
async build<T extends FieldsResolver<OptionalType & TransientFields>>(
62+
async build<T extends FieldsResolver<Type & TransientFields>>(
7063
inputFieldsResolver?: T,
71-
): Promise<StrictlyPick<Merge<ResolvedFields<_DefaultFieldsResolver>, ResolvedFields<T>>, keyof OptionalType>> {
64+
): Promise<StrictlyPick<Merge<ResolvedFields<_DefaultFieldsResolver>, ResolvedFields<T>>, keyof Type>> {
7265
const seq = getSeq();
73-
return resolveFields<OptionalType, TransientFields, _DefaultFieldsResolver, T>(
66+
return resolveFields<Type, TransientFields, _DefaultFieldsResolver, T>(
7467
typeFieldNames,
7568
seq,
7669
defaultFieldsResolver,
7770
inputFieldsResolver ?? ({} as T),
7871
);
7972
},
80-
async buildList<T extends FieldsResolver<OptionalType & TransientFields>>(
73+
async buildList<T extends FieldsResolver<Type & TransientFields>>(
8174
count: number,
8275
inputFieldsResolver?: T,
83-
): Promise<StrictlyPick<Merge<ResolvedFields<_DefaultFieldsResolver>, ResolvedFields<T>>, keyof OptionalType>[]> {
84-
const array: StrictlyPick<
85-
Merge<ResolvedFields<_DefaultFieldsResolver>, ResolvedFields<T>>,
86-
keyof OptionalType
87-
>[] = [];
76+
): Promise<StrictlyPick<Merge<ResolvedFields<_DefaultFieldsResolver>, ResolvedFields<T>>, keyof Type>[]> {
77+
const array: StrictlyPick<Merge<ResolvedFields<_DefaultFieldsResolver>, ResolvedFields<T>>, keyof Type>[] = [];
8878
for (let i = 0; i < count; i++) {
8979
if (inputFieldsResolver) {
9080
// eslint-disable-next-line no-await-in-loop, @typescript-eslint/no-explicit-any
@@ -99,7 +89,7 @@ export function defineTypeFactoryInternal<
9989
use<T extends keyof _Traits>(
10090
traitName: T,
10191
): TypeFactoryInterface<
102-
OptionalType,
92+
Type,
10393
TransientFields,
10494
Merge<_DefaultFieldsResolver, _Traits[T]['defaultFields']>,
10595
_Traits

src/helper/field-resolver.test.ts

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -10,75 +10,75 @@ import {
1010
import { DeepOptional, DeepReadonly } from './util.js';
1111

1212
it('Dynamic', async () => {
13-
type OptionalTypeWithTransientFields = { id: string | undefined; a: number | undefined };
13+
type TypeWithTransientFields = { id: string | undefined; a: number | undefined };
1414
type Field = string;
15-
const readonlyOptionalType: DeepReadonly<DeepOptional<OptionalTypeWithTransientFields>> = {
15+
const readonlyType: DeepReadonly<DeepOptional<TypeWithTransientFields>> = {
1616
id: '',
1717
a: 1,
1818
};
19-
const get = async <FieldName extends keyof OptionalTypeWithTransientFields>(fieldName: FieldName) =>
20-
Promise.resolve(readonlyOptionalType[fieldName]);
19+
const get = async <FieldName extends keyof TypeWithTransientFields>(fieldName: FieldName) =>
20+
Promise.resolve(readonlyType[fieldName]);
2121

22-
const dynamic1 = new Dynamic<OptionalTypeWithTransientFields, Field>(({ seq }) => `Book-${seq}`);
22+
const dynamic1 = new Dynamic<TypeWithTransientFields, Field>(({ seq }) => `Book-${seq}`);
2323
expect(await dynamic1.get({ seq: 0, get })).toBe('Book-0');
2424

2525
const dynamic2 = new Dynamic(async ({ seq }) => Promise.resolve(`Book-${seq}`));
2626
expect(await dynamic2.get({ seq: 0, get })).toBe('Book-0');
2727
});
2828

2929
it('dynamic', async () => {
30-
type OptionalTypeWithTransientFields = { id: string | undefined; a: number | undefined };
30+
type TypeWithTransientFields = { id: string | undefined; a: number | undefined };
3131
type Field = string;
32-
const readonlyOptionalType: DeepReadonly<DeepOptional<OptionalTypeWithTransientFields>> = {
32+
const readonlyType: DeepReadonly<DeepOptional<TypeWithTransientFields>> = {
3333
id: '',
3434
a: 1,
3535
};
36-
const get = async <FieldName extends keyof OptionalTypeWithTransientFields>(fieldName: FieldName) =>
37-
Promise.resolve(readonlyOptionalType[fieldName]);
36+
const get = async <FieldName extends keyof TypeWithTransientFields>(fieldName: FieldName) =>
37+
Promise.resolve(readonlyType[fieldName]);
3838

39-
const l1 = dynamic<OptionalTypeWithTransientFields, Field>(({ seq }) => `Book-${seq}`);
39+
const l1 = dynamic<TypeWithTransientFields, Field>(({ seq }) => `Book-${seq}`);
4040
expect(l1).instanceOf(Dynamic);
4141
expect(await l1.get({ seq: 0, get })).toBe('Book-0');
4242

43-
const l2 = dynamic<OptionalTypeWithTransientFields, Field>(async ({ seq }) => Promise.resolve(`Book-${seq}`));
43+
const l2 = dynamic<TypeWithTransientFields, Field>(async ({ seq }) => Promise.resolve(`Book-${seq}`));
4444
expect(l2).instanceOf(Dynamic);
4545
expect(await l2.get({ seq: 0, get })).toBe('Book-0');
4646
});
4747

4848
it('FieldResolver', () => {
49-
type OptionalTypeWithTransientFields = { a: number };
50-
expectTypeOf<FieldResolver<OptionalTypeWithTransientFields, OptionalTypeWithTransientFields['a']>>().toEqualTypeOf<
49+
type TypeWithTransientFields = { a: number };
50+
expectTypeOf<FieldResolver<TypeWithTransientFields, TypeWithTransientFields['a']>>().toEqualTypeOf<
5151
number | Dynamic<{ a: number }, number>
5252
>();
5353
});
5454

5555
it('FieldsResolver', () => {
56-
type OptionalTypeWithTransientFields = { a: number | undefined; b: OptionalSubType[] | undefined };
56+
type TypeWithTransientFields = { a: number | undefined; b: OptionalSubType[] | undefined };
5757
type OptionalSubType = { c: number | undefined };
58-
expectTypeOf<FieldsResolver<OptionalTypeWithTransientFields>>().toEqualTypeOf<{
59-
a?: number | undefined | Dynamic<OptionalTypeWithTransientFields, number | undefined>;
58+
expectTypeOf<FieldsResolver<TypeWithTransientFields>>().toEqualTypeOf<{
59+
a?: number | undefined | Dynamic<TypeWithTransientFields, number | undefined>;
6060
b?:
6161
| readonly { readonly c: number | undefined }[]
6262
| undefined
63-
| Dynamic<OptionalTypeWithTransientFields, readonly { readonly c: number | undefined }[] | undefined>;
63+
| Dynamic<TypeWithTransientFields, readonly { readonly c: number | undefined }[] | undefined>;
6464
}>();
6565
});
6666

6767
it('ResolvedField', () => {
68-
type OptionalTypeWithTransientFields = { a: number | undefined };
68+
type TypeWithTransientFields = { a: number | undefined };
6969
expectTypeOf<ResolvedField<number>>().toEqualTypeOf<number>();
70-
expectTypeOf<
71-
ResolvedField<Dynamic<OptionalTypeWithTransientFields, OptionalTypeWithTransientFields['a']>>
72-
>().toEqualTypeOf<number | undefined>();
70+
expectTypeOf<ResolvedField<Dynamic<TypeWithTransientFields, TypeWithTransientFields['a']>>>().toEqualTypeOf<
71+
number | undefined
72+
>();
7373
});
7474

7575
it('ResolvedFields', () => {
76-
type OptionalTypeWithTransientFields = { a: number | undefined };
76+
type TypeWithTransientFields = { a: number | undefined };
7777
expectTypeOf<
7878
ResolvedFields<{
79-
a: FieldResolver<OptionalTypeWithTransientFields, number>;
80-
b: FieldResolver<OptionalTypeWithTransientFields, undefined>;
81-
c: FieldResolver<OptionalTypeWithTransientFields, number | undefined>;
79+
a: FieldResolver<TypeWithTransientFields, number>;
80+
b: FieldResolver<TypeWithTransientFields, undefined>;
81+
c: FieldResolver<TypeWithTransientFields, number | undefined>;
8282
}>
8383
>().toEqualTypeOf<{
8484
a: number;

src/helper/field-resolver.ts

Lines changed: 26 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,34 @@
11
import { DeepReadonly, Merge, StrictlyPick } from './util.js';
22

3-
export type FieldResolverOptions<OptionalTypeWithTransientFields> = {
3+
export type FieldResolverOptions<TypeWithTransientFields> = {
44
seq: number;
5-
get: <FieldName extends keyof OptionalTypeWithTransientFields>(
5+
get: <FieldName extends keyof TypeWithTransientFields>(
66
fieldName: FieldName,
7-
) => Promise<DeepReadonly<OptionalTypeWithTransientFields[FieldName]> | undefined>;
7+
) => Promise<DeepReadonly<TypeWithTransientFields[FieldName]> | undefined>;
88
};
99

10-
export class Dynamic<OptionalTypeWithTransientFields, Field> {
10+
export class Dynamic<TypeWithTransientFields, Field> {
1111
constructor(
12-
private readonly factory: (
13-
options: FieldResolverOptions<OptionalTypeWithTransientFields>,
14-
) => Field | Promise<Field>,
12+
private readonly factory: (options: FieldResolverOptions<TypeWithTransientFields>) => Field | Promise<Field>,
1513
) {}
16-
async get(options: FieldResolverOptions<OptionalTypeWithTransientFields>): Promise<Field> {
14+
async get(options: FieldResolverOptions<TypeWithTransientFields>): Promise<Field> {
1715
return this.factory(options);
1816
}
1917
}
2018
/** Wrapper to delay field generation until needed. */
21-
export function dynamic<OptionalTypeWithTransientFields, Field>(
22-
factory: (options: FieldResolverOptions<OptionalTypeWithTransientFields>) => Field | Promise<Field>,
23-
): Dynamic<OptionalTypeWithTransientFields, Field> {
19+
export function dynamic<TypeWithTransientFields, Field>(
20+
factory: (options: FieldResolverOptions<TypeWithTransientFields>) => Field | Promise<Field>,
21+
): Dynamic<TypeWithTransientFields, Field> {
2422
return new Dynamic(factory);
2523
}
2624

27-
export type FieldResolver<OptionalTypeWithTransientFields, Field> =
28-
| Field
29-
| Dynamic<OptionalTypeWithTransientFields, Field>;
25+
export type FieldResolver<TypeWithTransientFields, Field> = Field | Dynamic<TypeWithTransientFields, Field>;
3026

3127
/** The type of `defaultFields` or `inputFields` option. */
32-
export type FieldsResolver<OptionalTypeWithTransientFields> = {
33-
[FieldName in keyof OptionalTypeWithTransientFields]?: FieldResolver<
34-
OptionalTypeWithTransientFields,
35-
DeepReadonly<OptionalTypeWithTransientFields[FieldName]>
28+
export type FieldsResolver<TypeWithTransientFields> = {
29+
[FieldName in keyof TypeWithTransientFields]?: FieldResolver<
30+
TypeWithTransientFields,
31+
DeepReadonly<TypeWithTransientFields[FieldName]>
3632
>;
3733
};
3834

@@ -46,26 +42,26 @@ export type ResolvedFields<FieldsResolver extends Record<string, FieldResolver<u
4642
};
4743

4844
export async function resolveFields<
49-
OptionalType extends Record<string, unknown>,
45+
Type extends Record<string, unknown>,
5046
TransientFields extends Record<string, unknown>,
51-
_DefaultFieldsResolver extends FieldsResolver<OptionalType & TransientFields>,
52-
_InputFieldsResolver extends FieldsResolver<OptionalType & TransientFields>,
47+
_DefaultFieldsResolver extends FieldsResolver<Type & TransientFields>,
48+
_InputFieldsResolver extends FieldsResolver<Type & TransientFields>,
5349
>(
54-
fieldNames: readonly (keyof OptionalType)[],
50+
fieldNames: readonly (keyof Type)[],
5551
seq: number,
5652
defaultFieldsResolver: _DefaultFieldsResolver,
5753
inputFieldsResolver: _InputFieldsResolver,
5854
): Promise<
59-
StrictlyPick<Merge<ResolvedFields<_DefaultFieldsResolver>, ResolvedFields<_InputFieldsResolver>>, keyof OptionalType>
55+
StrictlyPick<Merge<ResolvedFields<_DefaultFieldsResolver>, ResolvedFields<_InputFieldsResolver>>, keyof Type>
6056
> {
61-
type OptionalTypeWithTransientFields = OptionalType & TransientFields;
57+
type TypeWithTransientFields = Type & TransientFields;
6258

6359
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Use any type as it is impossible to match types.
6460
const fields = {} as any;
6561

6662
async function resolveField<
67-
_FieldResolverOptions extends FieldResolverOptions<OptionalTypeWithTransientFields>,
68-
_FieldResolver extends FieldResolver<OptionalTypeWithTransientFields, unknown>,
63+
_FieldResolverOptions extends FieldResolverOptions<TypeWithTransientFields>,
64+
_FieldResolver extends FieldResolver<TypeWithTransientFields, unknown>,
6965
>(options: _FieldResolverOptions, fieldResolver: _FieldResolver): Promise<ResolvedField<_FieldResolver>> {
7066
if (fieldResolver instanceof Dynamic) {
7167
return fieldResolver.get(options);
@@ -74,12 +70,12 @@ export async function resolveFields<
7470
}
7571
}
7672

77-
async function resolveFieldAndUpdateCache<FieldName extends keyof OptionalTypeWithTransientFields>(
73+
async function resolveFieldAndUpdateCache<FieldName extends keyof TypeWithTransientFields>(
7874
fieldName: FieldName,
79-
): Promise<DeepReadonly<OptionalTypeWithTransientFields[FieldName]> | undefined> {
75+
): Promise<DeepReadonly<TypeWithTransientFields[FieldName]> | undefined> {
8076
if (fieldName in fields) return fields[fieldName];
8177

82-
let fieldResolver: FieldResolver<OptionalType & TransientFields, unknown>;
78+
let fieldResolver: FieldResolver<Type & TransientFields, unknown>;
8379
if (fieldName in inputFieldsResolver) {
8480
fieldResolver = inputFieldsResolver[fieldName as keyof _InputFieldsResolver];
8581
} else if (fieldName in defaultFieldsResolver) {
@@ -93,7 +89,7 @@ export async function resolveFields<
9389
return fields[fieldName];
9490
}
9591

96-
const options: FieldResolverOptions<OptionalTypeWithTransientFields> = {
92+
const options: FieldResolverOptions<TypeWithTransientFields> = {
9793
seq,
9894
get: resolveFieldAndUpdateCache,
9995
};

0 commit comments

Comments
 (0)