Skip to content

Commit bb7befa

Browse files
committed
add override utility
1 parent 03d65bd commit bb7befa

File tree

6 files changed

+99
-1
lines changed

6 files changed

+99
-1
lines changed

src/structs/utilities.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Struct, Context, Validator } from '../struct'
22
import { object, optional, type } from './types'
3-
import { ObjectSchema, Assign, ObjectType, PartialObjectSchema } from '../utils'
3+
import { ObjectSchema, Assign, ObjectType, PartialObjectSchema, OverrideSourceType } from '../utils'
44

55
/**
66
* Create a new struct that combines the properties properties from multiple
@@ -59,6 +59,17 @@ export function assign(...Structs: Struct<any>[]): any {
5959
return isType ? type(schema) : object(schema)
6060
}
6161

62+
/**
63+
* Create a new struct based on target struct and overridden by source struct.
64+
*/
65+
66+
export function override<A extends ObjectSchema, B extends OverrideSourceType<A>>(
67+
target: Struct<ObjectType<A>, A>,
68+
source: B,
69+
): Struct<ObjectType<Assign<A, B>>, Assign<A, B>> {
70+
return assign(target, type(source))
71+
}
72+
6273
/**
6374
* Define a new struct type with a custom validation function.
6475
*/

src/utils.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,12 @@ export type ObjectType<S extends ObjectSchema> = Simplify<
291291
Optionalize<{ [K in keyof S]: Infer<S[K]> }>
292292
>
293293

294+
/**
295+
* A schema for source type of override utility.
296+
*/
297+
298+
export type OverrideSourceType<T extends ObjectSchema> = Partial<Record<keyof T, AnyStruct>> & ObjectSchema
299+
294300
/**
295301
* Omit properties from a type that extend from a specific type.
296302
*/
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { object, override, string, number } from '../../../src'
2+
3+
const Target = object({ a: string() })
4+
5+
export const Struct = override(Target, { a: number(), b: number() })
6+
7+
export const data = {
8+
a: 'invalid',
9+
b: 2,
10+
c: 5,
11+
}
12+
13+
export const failures = [
14+
{
15+
value: 'invalid',
16+
type: 'number',
17+
refinement: undefined,
18+
path: ['a'],
19+
branch: [data, data.a],
20+
},
21+
{
22+
branch: [data, data.c],
23+
path: ['c'],
24+
refinement: undefined,
25+
type: 'never',
26+
value: 5,
27+
},
28+
]
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { type, override, string, number } from '../../../src'
2+
3+
const Target = type({ a: string() })
4+
5+
export const Struct = override(Target, { a: number(), b: number() })
6+
7+
export const data = {
8+
a: 'invalid',
9+
b: 2,
10+
c: 5,
11+
}
12+
13+
export const failures = [
14+
{
15+
value: 'invalid',
16+
type: 'number',
17+
refinement: undefined,
18+
path: ['a'],
19+
branch: [data, data.a],
20+
},
21+
]
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { type, override, string, number } from '../../../src'
2+
3+
const Target = type({ a: string() })
4+
5+
export const Struct = override(Target, { a: number(), b: number() })
6+
7+
export const data = {
8+
a: 1,
9+
b: 2,
10+
}
11+
12+
export const output = {
13+
a: 1,
14+
b: 2,
15+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { type, override, string, number } from '../../../src'
2+
3+
const Target = type({ a: string() })
4+
5+
export const Struct = override(Target, { b: number() })
6+
7+
export const data = {
8+
a: '1',
9+
b: 2,
10+
c: 3,
11+
}
12+
13+
export const output = {
14+
a: '1',
15+
b: 2,
16+
c: 3,
17+
}

0 commit comments

Comments
 (0)